/////////////////////////////////////////////////////////////////////////////////////////////// #region IComparer<string> Members // // NOTE: This comparer tests for matching only. If the text does not match the sub-string // pattern, a non-zero value will be returned; however, callers should NOT rely // on the exact non-match value because it is meaningless. // public int Compare( string left, string right ) { ListOps.GetElementsToCompare( interpreter, ascending, indexText, leftOnly, true, cultureInfo, ref left, ref right); /* throw */ bool match = false; Result error = null; if (StringOps.Match( interpreter, MatchMode.SubString, left, right, noCase, ref match, ref error) == ReturnCode.Ok) { int result = ConversionOps.ToInt(!match); ListOps.UpdateDuplicateCount(this, duplicates, left, right, unique, result, ref levels); /* throw */ return(result); } if (error != null) { throw new ScriptException(error); } else { throw new ScriptException(); } }
/////////////////////////////////////////////////////////////////////// public override int GetChars( byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex ) { int oldCharIndex = charIndex; while (byteCount > 0) { // // NOTE: Non-lossy, one-to-one mapping (LITTLE-ENDIAN). // chars[charIndex++] = ConversionOps.ToChar( bytes[byteIndex++], bytes[byteIndex++]); // // NOTE: We just used two bytes. // byteCount -= 2; } return(charIndex - oldCharIndex); }
/////////////////////////////////////////////////////////////////////// public override int GetBytes( char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex ) { if (!MathOps.CanDouble(charCount)) { throw new ArgumentOutOfRangeException("charCount"); } int oldByteIndex = byteIndex; while (charCount-- > 0) { // // NOTE: Non-lossy, one-to-two mapping (LITTLE-ENDIAN). // bytes[byteIndex++] = ConversionOps.ToLowByte(chars[charIndex]); bytes[byteIndex++] = ConversionOps.ToHighByte(chars[charIndex]); // // NOTE: We just used one character. // charIndex++; } return(byteIndex - oldByteIndex); }
/////////////////////////////////////////////////////////////////////// public int RemoveAll( IntPtr value, int limit ) { int removed = 0; StringList list = new StringList(); foreach (KeyValuePair <string, IntPtr> pair in this) { if (pair.Value == value) { list.Add(pair.Key); } } foreach (string element in list) { if ((limit == 0) || (removed < limit)) { removed += ConversionOps.ToInt(this.Remove(element)); } } return(removed); }
///////////////////////////////////////////////////////////////////////////////// #region AppDomain EventHandler (ProcessExit / DomainUnload) private static void NativeStack_Exited( object sender, EventArgs e ) { lock (syncRoot) /* TRANSACTIONAL */ { if (ThreadContextBuffer != UIntPtr.Zero) { Marshal.FreeCoTaskMem(ConversionOps.ToIntPtr( ThreadContextBuffer)); ThreadContextBuffer = UIntPtr.Zero; AppDomain appDomain = AppDomainOps.GetCurrent(); if (appDomain != null) { if (!AppDomainOps.IsDefault(appDomain)) { appDomain.DomainUnload -= NativeStack_Exited; } else { appDomain.ProcessExit -= NativeStack_Exited; } } } } }
/////////////////////////////////////////////////////////////////// public override void Write( byte[] buffer, int offset, int count ) { CheckDisposed(); if (!canWrite) { throw new NotSupportedException(); } if (buffer == null) { throw new ArgumentNullException(); } if ((offset < 0) || (count < 0)) { throw new ArgumentOutOfRangeException(); } int length = buffer.Length; if ((offset + count) > length) { throw new ArgumentException(); } for (int index = offset; count > 0; index++, count--) { DebugOps.TraceWrite(ConversionOps.ToChar(buffer[index])); } }
/////////////////////////////////////////////////////////////////////////////////////////////// private static void RemoveEndOfLine( byte[] buffer, /* in */ CharList endOfLine, /* in */ bool useAnyEndOfLineChar, /* in */ ref int bufferLength /* in, out */ ) { if ((buffer != null) && (endOfLine != null) && (bufferLength > 0)) { if (useAnyEndOfLineChar) { int bufferIndex = bufferLength - 1; while (bufferIndex >= 0) { if (endOfLine.Contains(ConversionOps.ToChar(buffer[bufferIndex]))) { bufferIndex--; } else { break; } } bufferLength = bufferIndex + 1; } else { int eolLength = endOfLine.Count; if (bufferLength >= eolLength) { bool match = true; int bufferIndex = bufferLength - eolLength; int eolIndex = 0; while ((bufferIndex < bufferLength) && (eolIndex < eolLength)) { if (buffer[bufferIndex] != ConversionOps.ToByte(endOfLine[eolIndex])) { match = false; break; } bufferIndex++; eolIndex++; } if (match) { bufferLength -= eolLength; } } } } }
/////////////////////////////////////////////////////////////////////// public ByteList( IEnumerable <char> collection ) : this() { foreach (char item in collection) { this.Add(ConversionOps.ToByte(item)); } }
/////////////////////////////////////////////////////////////////////// public static ReturnCode SelectRandomValue( Interpreter interpreter, /* in: may be NULL. */ Array array, /* in */ ref object value, /* out */ ref Result error /* out */ ) { if (array == null) { error = "invalid array"; return(ReturnCode.Error); } if (array.Rank != 1) { error = "array must be one-dimensional"; return(ReturnCode.Error); } if (array.Length == 0) { error = "array cannot be empty"; return(ReturnCode.Error); } try { ulong randomNumber; if (interpreter != null) { randomNumber = interpreter.GetRandomNumber(); /* throw */ } else { randomNumber = RuntimeOps.GetRandomNumber(); /* throw */ } int index = ConversionOps.ToInt(randomNumber % ConversionOps.ToULong(array.LongLength)); value = array.GetValue(index); /* throw */ return(ReturnCode.Ok); } catch (Exception e) { error = e; } return(ReturnCode.Error); }
public static int Combine( int X, int Y ) { byte[] bytes = new byte[sizeof(int) * 2]; Array.Copy(BitConverter.GetBytes(X), 0, bytes, 0, sizeof(int)); Array.Copy(BitConverter.GetBytes(Y), 0, bytes, sizeof(int), sizeof(int)); return(ConversionOps.ToInt(MathOps.HashFnv1UInt(bytes, true))); }
/////////////////////////////////////////////////////////////////////// private static bool ParseGroupIndex( string text, int startIndex, int characters, ref int stopIndex, ref int groupIndex ) { int length; long number = 0; length = Parser.ParseDecimal( text, startIndex, characters, ref number); if (length > 0) { // // NOTE: Set the stopping index based on the number of // digits parsed above. The calling method will // need to subtract one from this value prior to // returning to its caller because the index will // be incremented again after that point. // stopIndex = startIndex + length; // // NOTE: Always convert the number to a 32-bit integer, // which may by lossy; however, we do not care // because group indexes cannot exceed 32-bits. // groupIndex = ConversionOps.ToInt(number); // // NOTE: An integer value was parsed; therefore, we // return success. // return(true); } // // NOTE: For some reason, we were not able to parse any // integer value. // return(false); }
/////////////////////////////////////////////////////////////////////// public override int GetBytes( char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex ) { int oldByteIndex = byteIndex; while (charCount-- > 0) { // // NOTE: *WARNING* Lossy, one-to-one mapping. // bytes[byteIndex++] = ConversionOps.ToByte(chars[charIndex++]); } return(byteIndex - oldByteIndex); }
/////////////////////////////////////////////////////////////////////////////////////////////// public static int GetMicroseconds( int milliseconds, int?minimumMicroseconds, int?maximumMicroseconds ) /* LOSSY */ { long result = GetMicroseconds(milliseconds); if (IsValidValue(minimumMicroseconds, true)) { int localMinimumMicroseconds = (int)minimumMicroseconds; if (!IsValidValue(result, true) || (result < localMinimumMicroseconds)) { result = localMinimumMicroseconds; } } if (IsValidValue(maximumMicroseconds, true)) { int localMaximumMicroseconds = (int)maximumMicroseconds; if (!IsValidValue(result, true) || (result > localMaximumMicroseconds)) { result = localMaximumMicroseconds; } } if (!IsValidValue(result, true)) { result = 0; } return(ConversionOps.ToInt(result)); }
/////////////////////////////////////////////////////////////////////////////////////////////// #region IComparer<string> Members // // NOTE: This comparer tests for matching only. If the text does not match the pattern, a // non-zero value will be returned; however, callers should NOT rely on the exact // non-match value because it is meaningless. // public int Compare( string left, string right ) { bool match = false; Result error = null; if (StringOps.Match( null, mode, left, right, noCase, this, regExOptions, ref match, ref error) == ReturnCode.Ok) { return(ConversionOps.ToInt(!match)); } if (error != null) { throw new ScriptException(error); } else { throw new ScriptException(); } }
public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 2) { string subCommand = arguments[1]; bool tried = false; code = ScriptOps.TryExecuteSubCommandFromEnsemble( interpreter, this, clientData, arguments, true, false, ref subCommand, ref tried, ref result); if ((code == ReturnCode.Ok) && !tried) { switch (subCommand) { case "compare": { if (arguments.Count == 4) { Guid guid1 = Guid.Empty; code = Value.GetGuid(arguments[2], interpreter.CultureInfo, ref guid1, ref result); if (code == ReturnCode.Ok) { Guid guid2 = Guid.Empty; code = Value.GetGuid(arguments[3], interpreter.CultureInfo, ref guid2, ref result); if (code == ReturnCode.Ok) { result = guid1.CompareTo(guid2); } } } else { result = "wrong # args: should be \"guid compare guid1 guid2\""; code = ReturnCode.Error; } break; } case "isnull": { if (arguments.Count == 3) { Guid guid = Guid.Empty; code = Value.GetGuid(arguments[2], interpreter.CultureInfo, ref guid, ref result); if (code == ReturnCode.Ok) { result = ConversionOps.ToInt(guid.CompareTo(Guid.Empty) == 0); } } else { result = "wrong # args: should be \"guid isnull guid\""; code = ReturnCode.Error; } break; } case "isvalid": { if (arguments.Count == 3) { Guid guid = Guid.Empty; Result localResult = null; result = ConversionOps.ToInt(Value.GetGuid(arguments[2], interpreter.CultureInfo, ref guid, ref localResult) == ReturnCode.Ok); } else { result = "wrong # args: should be \"guid isvalid guid\""; code = ReturnCode.Error; } break; } case "new": { if (arguments.Count == 2) { result = Guid.NewGuid(); } else { result = "wrong # args: should be \"guid new\""; code = ReturnCode.Error; } break; } case "null": { if (arguments.Count == 2) { result = Guid.Empty; } else { result = "wrong # args: should be \"guid null\""; code = ReturnCode.Error; } break; } default: { result = ScriptOps.BadSubCommand( interpreter, null, null, subCommand, this, null, null); code = ReturnCode.Error; break; } } } } else { result = "wrong # args: should be \"guid option ?arg ...?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
/////////////////////////////////////////////////////////////////////// #region IExecute Members public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code; // // NOTE: *WARNING* We do NOT actually support namespaces. This // command exists for the sole purpose of improving source // code compatibility with simple stand alone scripts that // may simply wrap themselves in a "namespace eval" block, // etc. Any other (more involved) use may not work at all // or may cause undesired and/or unpredictable results. // if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 2) { string subCommand = arguments[1]; bool tried = false; code = ScriptOps.TryExecuteSubCommandFromEnsemble( interpreter, this, clientData, arguments, true, false, ref subCommand, ref tried, ref result); if ((code == ReturnCode.Ok) && !tried) { switch (subCommand) { case "children": { if ((arguments.Count >= 2) && (arguments.Count <= 4)) { string name = null; if (arguments.Count >= 3) { name = arguments[2]; } string pattern = null; if (arguments.Count >= 4) { pattern = arguments[3]; } IEnumerable <INamespace> children = NamespaceOps.Children( interpreter, name, pattern, false, ref result); if (children != null) { StringList list = new StringList(); foreach (INamespace child in children) { list.Add(child.QualifiedName); } result = list; } else { code = ReturnCode.Error; } } else { result = "wrong # args: should be \"namespace children ?name? ?pattern?\""; code = ReturnCode.Error; } break; } case "code": { if (arguments.Count == 3) { string text = arguments[2]; if (!NamespaceOps.IsSubCommand(interpreter, text, "inscope")) { INamespace currentNamespace = null; code = interpreter.GetCurrentNamespaceViaResolvers( null, LookupFlags.Default, ref currentNamespace, ref result); if (code == ReturnCode.Ok) { StringList list = new StringList(); list.Add(NamespaceOps.MakeAbsoluteName( this.Name)); list.Add("inscope"); list.Add(NamespaceOps.MakeAbsoluteName( currentNamespace.QualifiedName)); list.Add(text); result = list; } } else { result = text; /* COMPAT: Tcl. */ } } else { result = "wrong # args: should be \"namespace code script\""; code = ReturnCode.Error; } break; } case "current": { if (arguments.Count == 2) { INamespace currentNamespace = null; code = interpreter.GetCurrentNamespaceViaResolvers( null, LookupFlags.Default, ref currentNamespace, ref result); if (code == ReturnCode.Ok) { if (currentNamespace != null) { result = currentNamespace.QualifiedName; } else { result = "current namespace is invalid"; code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"namespace current\""; code = ReturnCode.Error; } break; } case "delete": { if (arguments.Count >= 2) { for (int index = 2; index < arguments.Count; index++) { code = interpreter.DeleteNamespace( VariableFlags.None, arguments[index], false, ref result); if (code != ReturnCode.Ok) { break; } } if (code == ReturnCode.Ok) { result = String.Empty; } } else { result = "wrong # args: should be \"namespace delete ?name name ...?\""; code = ReturnCode.Error; } break; } case "enable": { if ((arguments.Count >= 2) && (arguments.Count <= 4)) { if (arguments.Count >= 3) { bool enabled = false; code = Value.GetBoolean2( arguments[2], ValueFlags.AnyBoolean, interpreter.CultureInfo, ref enabled, ref result); bool force = false; if ((code == ReturnCode.Ok) && (arguments.Count >= 4)) { code = Value.GetBoolean2( arguments[3], ValueFlags.AnyBoolean, interpreter.CultureInfo, ref force, ref result); } if (code == ReturnCode.Ok) { code = NamespaceOps.Enable( interpreter, enabled, force, ref result); } } if (code == ReturnCode.Ok) { result = interpreter.AreNamespacesEnabled(); } } else { result = "wrong # args: should be \"namespace enable ?enabled? ?force?\""; code = ReturnCode.Error; } break; } case "eval": { if (arguments.Count >= 4) { string namespaceName = NamespaceOps.MapName( interpreter, arguments[2]); INamespace @namespace = NamespaceOps.Lookup( interpreter, namespaceName, false, true, ref result); if (@namespace != null) { string name = StringList.MakeList("namespace eval", @namespace.QualifiedName); ICallFrame frame = interpreter.NewNamespaceCallFrame( name, CallFrameFlags.Evaluate | CallFrameFlags.UseNamespace, arguments, @namespace, false); interpreter.PushNamespaceCallFrame(frame); if (arguments.Count == 4) { code = interpreter.EvaluateScript(arguments[3], ref result); } else { code = interpreter.EvaluateScript(arguments, 3, ref result); } if (code == ReturnCode.Error) { Engine.AddErrorInformation(interpreter, result, String.Format("{0} (in namespace eval \"{1}\" script line {2})", Environment.NewLine, NamespaceOps.MaybeQualifiedName(@namespace, true), Interpreter.GetErrorLine(interpreter))); } /* IGNORED */ interpreter.PopNamespaceCallFrame(frame); /* NO RESULT */ Engine.CleanupNamespacesOrComplain(interpreter); } else { code = ReturnCode.Error; } } else { result = "wrong # args: should be \"namespace eval name arg ?arg ...?\""; code = ReturnCode.Error; } break; } case "exists": { if (arguments.Count == 3) { result = ConversionOps.ToInt(NamespaceOps.Lookup( interpreter, arguments[2], false, false) != null); } else { result = "wrong # args: should be \"namespace exists name\""; code = ReturnCode.Error; } break; } case "export": { if (arguments.Count >= 2) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-clear", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; if (arguments.Count > 2) { code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, false, ref argumentIndex, ref result); } else { code = ReturnCode.Ok; } if (code == ReturnCode.Ok) { bool clear = false; if (options.IsPresent("-clear")) { clear = true; } StringList patterns = new StringList(); if (argumentIndex != Index.Invalid) { patterns.AddObjects(ArgumentList.GetRange(arguments, argumentIndex)); } code = NamespaceOps.Export(interpreter, null, patterns, clear, ref result); } } else { result = "wrong # args: should be \"namespace export ?-clear? ?pattern pattern ...?\""; code = ReturnCode.Error; } break; } case "forget": { if (arguments.Count >= 2) { if (arguments.Count >= 3) { code = NamespaceOps.Forget(interpreter, new StringList(ArgumentList.GetRange(arguments, 2)), ref result); if (code == ReturnCode.Ok) { result = String.Empty; } } else { result = String.Empty; code = ReturnCode.Ok; } } else { result = "wrong # args: should be \"namespace forget ?pattern pattern ...?\""; code = ReturnCode.Error; } break; } case "import": { if (arguments.Count >= 2) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-force", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; if (arguments.Count > 2) { code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, false, ref argumentIndex, ref result); } else { code = ReturnCode.Ok; } if (code == ReturnCode.Ok) { bool force = false; if (options.IsPresent("-force")) { force = true; } StringList patterns = new StringList(); if (argumentIndex != Index.Invalid) { patterns.AddObjects(ArgumentList.GetRange(arguments, argumentIndex)); } code = NamespaceOps.Import(interpreter, patterns, force, ref result); } } else { result = "wrong # args: should be \"namespace import ?-force? ?pattern pattern ...?\""; code = ReturnCode.Error; } break; } case "info": { if (arguments.Count == 3) { code = NamespaceOps.InfoSubCommand( interpreter, arguments[2], ref result); } else { result = "wrong # args: should be \"namespace info name\""; code = ReturnCode.Error; } break; } case "inscope": { if (arguments.Count >= 4) { string namespaceName = NamespaceOps.MapName( interpreter, arguments[2]); INamespace @namespace = NamespaceOps.Lookup( interpreter, namespaceName, false, false, ref result); if (@namespace != null) { if (arguments.Count > 4) { IScriptLocation location = null; #if DEBUGGER && BREAKPOINTS code = ScriptOps.GetLocation( interpreter, arguments, 3, ref location, ref result); if (code == ReturnCode.Ok) #endif { string name = StringList.MakeList("namespace inscope", @namespace.QualifiedName); ICallFrame frame = interpreter.NewNamespaceCallFrame( name, CallFrameFlags.InScope | CallFrameFlags.UseNamespace, arguments, @namespace, false); interpreter.PushNamespaceCallFrame(frame); StringList list = new StringList(arguments, 4); code = interpreter.EvaluateScript( ListOps.Concat(arguments[3], list.ToString()), location, ref result); if (code == ReturnCode.Error) { Engine.AddErrorInformation(interpreter, result, String.Format("{0} (in namespace inscope \"{1}\" script line {2})", Environment.NewLine, NamespaceOps.MaybeQualifiedName(@namespace, true), Interpreter.GetErrorLine(interpreter))); } /* IGNORED */ interpreter.PopNamespaceCallFrame(frame); /* NO RESULT */ Engine.CleanupNamespacesOrComplain(interpreter); } } else { string name = StringList.MakeList("namespace inscope", @namespace.QualifiedName); ICallFrame frame = interpreter.NewNamespaceCallFrame( name, CallFrameFlags.InScope | CallFrameFlags.UseNamespace, arguments, @namespace, false); interpreter.PushNamespaceCallFrame(frame); code = interpreter.EvaluateScript(arguments[3], ref result); if (code == ReturnCode.Error) { Engine.AddErrorInformation(interpreter, result, String.Format("{0} (in namespace inscope \"{1}\" script line {2})", Environment.NewLine, NamespaceOps.MaybeQualifiedName(@namespace, true), Interpreter.GetErrorLine(interpreter))); } /* IGNORED */ interpreter.PopNamespaceCallFrame(frame); /* NO RESULT */ Engine.CleanupNamespacesOrComplain(interpreter); } } else { code = ReturnCode.Error; } } else { result = "wrong # args: should be \"namespace inscope name arg ?arg...?\""; code = ReturnCode.Error; } break; } case "mappings": { if (arguments.Count == 2) { lock (interpreter.SyncRoot) /* TRANSACTIONAL */ { StringDictionary namespaceMappings = interpreter.NamespaceMappings; if (namespaceMappings != null) { result = namespaceMappings.KeysAndValuesToString(null, false); code = ReturnCode.Ok; } else { result = "namespace mappings not available"; code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"namespace mappings\""; code = ReturnCode.Error; } break; } case "name": { if (arguments.Count == 3) { string name = arguments[2]; if (!NamespaceOps.IsQualifiedName(name)) { result = NamespaceOps.MakeQualifiedName(interpreter, name, true); code = ReturnCode.Ok; } else { result = "only non-qualified names are allowed"; code = ReturnCode.Error; } } else { result = "wrong # args: should be \"namespace name name\""; code = ReturnCode.Error; } break; } case "origin": { if (arguments.Count == 3) { code = NamespaceOps.Origin(interpreter, null, arguments[2], ref result); } else { result = "wrong # args: should be \"namespace origin name\""; code = ReturnCode.Error; } break; } case "parent": { if ((arguments.Count == 2) || (arguments.Count == 3)) { code = NamespaceOps.Parent( interpreter, (arguments.Count == 3) ? arguments[2] : null, ref result); } else { result = "wrong # args: should be \"namespace parent ?name?\""; code = ReturnCode.Error; } break; } case "qualifiers": { if (arguments.Count == 3) { string qualifiers = null; string tail = null; code = NamespaceOps.SplitName( arguments[2], ref qualifiers, ref tail, ref result); if (code == ReturnCode.Ok) { result = qualifiers; } } else { result = "wrong # args: should be \"namespace qualifiers string\""; code = ReturnCode.Error; } break; } case "rename": { if (arguments.Count == 4) { code = interpreter.RenameNamespace( arguments[2], arguments[3], RenameGlobalOk, RenameInUseOk, ref result); } else { result = "wrong # args: should be \"namespace rename oldName newName\""; code = ReturnCode.Error; } break; } case "tail": { if (arguments.Count == 3) { string qualifiers = null; string tail = null; code = NamespaceOps.SplitName( arguments[2], ref qualifiers, ref tail, ref result); if (code == ReturnCode.Ok) { result = tail; } } else { result = "wrong # args: should be \"namespace tail string\""; code = ReturnCode.Error; } break; } case "unknown": { if ((arguments.Count == 2) || (arguments.Count == 3)) { INamespace currentNamespace = null; code = interpreter.GetCurrentNamespaceViaResolvers( null, LookupFlags.Default, ref currentNamespace, ref result); if (code == ReturnCode.Ok) { if (currentNamespace != null) { if (arguments.Count == 3) { string unknown = StringOps.NullIfEmpty(arguments[2]); if (String.IsNullOrEmpty(unknown) && NamespaceOps.IsGlobal(interpreter, currentNamespace)) { currentNamespace.Unknown = interpreter.GlobalUnknown; } else { currentNamespace.Unknown = unknown; } result = unknown; } else { result = currentNamespace.Unknown; } } else { if (arguments.Count == 3) { string unknown = StringOps.NullIfEmpty(arguments[2]); if (String.IsNullOrEmpty(unknown)) { interpreter.GlobalUnknown = TclVars.Unknown; } else { interpreter.GlobalUnknown = unknown; } result = unknown; } else { result = interpreter.GlobalUnknown; } } } } else { result = "wrong # args: should be \"namespace unknown ?script?\""; code = ReturnCode.Error; } break; } case "which": { if (arguments.Count >= 2) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-command", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-variable", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; if (arguments.Count > 2) { code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, OptionBehaviorFlags.LastIsNonOption, false, ref argumentIndex, ref result); } else { code = ReturnCode.Ok; } if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 1) == arguments.Count)) { string name = arguments[argumentIndex]; bool isCommand = false; if (options.IsPresent("-command")) { isCommand = true; } bool isVariable = false; if (options.IsPresent("-variable")) { isVariable = true; } if (!isCommand || !isVariable) { NamespaceFlags flags = NamespaceFlags.None; if (isCommand) { flags |= NamespaceFlags.Command; } else if (isVariable) { flags |= NamespaceFlags.Variable; } else { flags |= NamespaceFlags.Command; } code = NamespaceOps.Which(interpreter, null, name, flags, ref result); } else { result = "wrong # args: should be \"namespace which ?-command? ?-variable? name\""; code = ReturnCode.Error; } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"namespace which ?-command? ?-variable? name\""; } code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"namespace which ?-command? ?-variable? name\""; code = ReturnCode.Error; } break; } default: { result = ScriptOps.BadSubCommand( interpreter, null, null, subCommand, this, null, null); code = ReturnCode.Error; break; } } } } else { result = "wrong # args: should be \"namespace subcommand ?arg ...?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
/////////////////////////////////////////////////////////////////////////////////////////////// public static int DaysInYear( int year ) { return(DaysInNormalYear + ConversionOps.ToInt(DateTime.IsLeapYear(year))); }
/////////////////////////////////////////////////////////////////////////////////////////////// #region IExecuteArgument Members public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Argument value, ref Result error ) { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { if (arguments != null) { try { string name = null; Variant operand1 = null; Variant operand2 = null; code = Value.GetOperandsFromArguments(interpreter, this, arguments, ValueFlags.AnyVariant, interpreter.CultureInfo, ref name, ref operand1, ref operand2, ref error); if (code == ReturnCode.Ok) { code = Value.FixupVariants( this, operand1, operand2, null, null, false, true, ref error); if (code == ReturnCode.Ok) { if (operand1.IsWideInteger()) { value = MathOps.LeftRotate((long)operand1.Value, (int)operand2.Value); } else if (operand1.IsInteger()) { value = MathOps.LeftRotate((int)operand1.Value, (int)operand2.Value); } else if (operand1.IsBoolean()) { value = MathOps.LeftRotate(ConversionOps.ToInt((bool)operand1.Value), ConversionOps.ToInt((bool)operand2.Value)); } else { error = String.Format( "unsupported operand type for operator {0}", FormatOps.OperatorName(name, this.Lexeme)); code = ReturnCode.Error; } } } } catch (Exception e) { Engine.SetExceptionErrorCode(interpreter, e); error = String.Format( "caught math exception: {0}", e); code = ReturnCode.Error; } } else { error = "invalid argument list"; code = ReturnCode.Error; } } else { error = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
///////////////////////////////////////////////////////////////////////////////// private static UIntPtr GetNativeRegister( IntPtr thread, uint flags, int offset, int size ) { // // NOTE: Are we able to query the thread context (i.e. we know // what platform we are on and the appropriate constants // have been setup)? // if (!CanQueryThread) { if (Interlocked.Increment(ref CannotQueryThread) == 1) { TraceOps.DebugTrace( "GetNativeRegister: cannot query thread", typeof(NativeStack).Name, TracePriority.NativeError); } return(UIntPtr.Zero); } // // NOTE: We do not allow anybody to attempt to read outside what // we think the bounds of the CONTEXT structure are. // if ((offset < 0) || (offset > (CONTEXT_SIZE - IntPtr.Size))) { return(UIntPtr.Zero); } try { lock (syncRoot) /* TRANSACTIONAL */ { // // NOTE: Perform one-time allocation of the fixed-size // thread context buffer, on demand and schedule // to have it freed prior to process exit. // if (ThreadContextBuffer == UIntPtr.Zero) { // // NOTE: Schedule the fixed-size thread context // buffer to be freed either upon the // AppDomain being unloaded (if we are not // in the default AppDomain) or when the // process exits. This should gracefully // handle both embedding and stand-alone // scenarios. // AppDomain appDomain = AppDomainOps.GetCurrent(); if (appDomain != null) { if (!AppDomainOps.IsDefault(appDomain)) { appDomain.DomainUnload += NativeStack_Exited; } else { appDomain.ProcessExit += NativeStack_Exited; } } // // NOTE: Now that we are sure that we have // succeeded in scheduling the cleanup for // this buffer, allocate it. // // NOTE: For safety, we now allocate at least a // whole page for this buffer. // // ThreadContextBuffer = ConversionOps.ToUIntPtr( // Marshal.AllocCoTaskMem((int)CONTEXT_SIZE)); // ThreadContextBuffer = ConversionOps.ToUIntPtr( Marshal.AllocCoTaskMem((int)Math.Max( CONTEXT_SIZE, PlatformOps.GetPageSize()))); } // // NOTE: Make sure we were able to allocate the // thread context buffer. // if (ThreadContextBuffer == UIntPtr.Zero) { return(UIntPtr.Zero); } // // NOTE: Internally convert our buffer UIntPtr to // IntPtr, as required by Marshal class. // This is absolutely required because // otherwise we end up calling the generic // version of the WriteInt32 and ReadInt32 // methods (that take an object instead of // an IntPtr) and getting the wrong results. // IntPtr threadContext = ConversionOps.ToIntPtr( ThreadContextBuffer); // // NOTE: Write flags that tell GetThreadContext // which fields of the thread context buffer // we would like it to populate. For now, // we mainly want to support the control // registers (primarily for ESP and EBP). // Marshal.WriteInt32( threadContext, (int)CONTEXT_FLAGS_OFFSET, (int)flags); // // NOTE: Query the Win32 API to obtain the // requested thread context. In theory, // this could fail or throw an exception // at this point. In that case, we would // return zero from this function and the // stack checking code would assume that // native stack checking is unavailable // and should not be relied upon. // if (UnsafeNativeMethods.GetThreadContext( thread, threadContext)) { if (size == IntPtr.Size) { return(ConversionOps.ToUIntPtr( Marshal.ReadIntPtr(threadContext, offset))); } else { switch (size) { case sizeof(long): { return(ConversionOps.ToUIntPtr( Marshal.ReadInt64(threadContext, offset))); } case sizeof(int): { return(ConversionOps.ToUIntPtr( Marshal.ReadInt32(threadContext, offset))); } case sizeof(short): { return(ConversionOps.ToUIntPtr( Marshal.ReadInt16(threadContext, offset))); } case sizeof(byte): { return(ConversionOps.ToUIntPtr( Marshal.ReadByte(threadContext, offset))); } } } } } } catch (Exception e) { if (Interlocked.Increment(ref ContextException) == 1) { TraceOps.DebugTrace( e, typeof(NativeStack).Name, TracePriority.NativeError); } } return(UIntPtr.Zero); }
/////////////////////////////////////////////////////////////////////// private ReturnCode PrivateResolve( ref Result error, ref Exception exception ) { lock (syncRoot) /* TRANSACTIONAL */ { if (type == null) { error = "invalid type"; return(ReturnCode.Error); } if (!ConversionOps.IsDelegateType(type, false)) { error = "type is not a delegate type"; return(ReturnCode.Error); } if (module == null) { error = "invalid module"; return(ReturnCode.Error); } if (String.IsNullOrEmpty(functionName)) { error = "invalid export name"; return(ReturnCode.Error); } if (module.Load(ref moduleLoaded, ref error) == ReturnCode.Ok) { try { int lastError; address = NativeOps.GetProcAddress( module.Module, functionName, out lastError); /* throw */ if (address != IntPtr.Zero) { // // NOTE: The GetDelegateForFunctionPointer method // of the Marshal class is how we get the // delegate we need to invoke the library // function itself and this is why we went // through all the trouble to creating and // populating the delegate type dynamically. // To see exactly how this is accomplished, // please refer to CreateNativeDelegateType // in DelegateOps). // @delegate = Marshal.GetDelegateForFunctionPointer( address, type); /* throw */ return(ReturnCode.Ok); } else { error = String.Format( "GetProcAddress({1}, \"{2}\") failed with " + "error {0}: {3}", lastError, module, functionName, NativeOps.GetDynamicLoadingError( lastError)); } } catch (Exception e) { error = e; exception = e; } } } return(ReturnCode.Error); }
/////////////////////////////////////////////////////////////////////////////////////////////// #region IExecuteArgument Members public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Argument value, ref Result error ) { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { if (arguments != null) { if (arguments.Count == (this.Arguments + 1)) { Variant variant1 = null; code = Value.GetVariant(interpreter, (IGetValue)arguments[1], ValueFlags.AnyVariant, interpreter.CultureInfo, ref variant1, ref error); if (code == ReturnCode.Ok) { try { if (variant1.IsDateTime()) { value = ConversionOps.ToInt((DateTime)variant1.Value); /* LOSSY */ } else if (variant1.IsDouble()) { variant1.Value = Math.Truncate((double)variant1.Value); if (variant1.ConvertTo(typeof(int))) { value = (int)variant1.Value; } else { error = "integer value too large to represent"; code = ReturnCode.Error; } } else if (variant1.IsDecimal()) { variant1.Value = Math.Truncate((decimal)variant1.Value); if (variant1.ConvertTo(typeof(int))) { value = (int)variant1.Value; } else { error = "integer value too large to represent"; code = ReturnCode.Error; } } else if (variant1.IsWideInteger()) { value = ConversionOps.ToInt((long)variant1.Value); /* LOSSY */ } else if (variant1.IsInteger()) { value = (int)variant1.Value; /* NOP */ } else if (variant1.IsBoolean()) { value = ConversionOps.ToInt((bool)variant1.Value); } else { error = String.Format( "expected integer but got \"{0}\"", arguments[1]); code = ReturnCode.Error; } } catch (Exception e) { Engine.SetExceptionErrorCode(interpreter, e); error = String.Format( "caught math exception: {0}", e); code = ReturnCode.Error; } } } else { if (arguments.Count > (this.Arguments + 1)) { error = String.Format( "too many arguments for math function \"{0}\"", base.Name); } else { error = String.Format( "too few arguments for math function \"{0}\"", base.Name); } code = ReturnCode.Error; } } else { error = "invalid argument list"; code = ReturnCode.Error; } } else { error = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
/////////////////////////////////////////////////////////////////////////////////////////////// #region IExecuteArgument Members public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Argument value, ref Result error ) { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { if (arguments != null) { try { string name = null; Variant operand1 = null; Variant operand2 = null; code = Value.GetOperandsFromArguments(interpreter, this, arguments, ValueFlags.AnyVariant, interpreter.CultureInfo, ref name, ref operand1, ref operand2, ref error); if (code == ReturnCode.Ok) { code = Value.FixupVariants( this, operand1, operand2, null, null, false, false, ref error); if (code == ReturnCode.Ok) { if (operand1.IsDouble()) { value = ((double)operand1.Value >= (double)operand2.Value); } else if (operand1.IsDecimal()) { value = ((decimal)operand1.Value >= (decimal)operand2.Value); } else if (operand1.IsWideInteger()) { value = ((long)operand1.Value >= (long)operand2.Value); } else if (operand1.IsInteger()) { value = ((int)operand1.Value >= (int)operand2.Value); } else if (operand1.IsBoolean()) { value = (ConversionOps.ToInt((bool)operand1.Value) >= ConversionOps.ToInt((bool)operand2.Value)); } else { error = String.Format( "unsupported operand type for operator {0}", FormatOps.OperatorName(name, this.Lexeme)); code = ReturnCode.Error; } } else { // // NOTE: Fine, try to treat the operands as strings. // code = Value.FixupStringVariants( this, operand1, operand2, ref error); if (code == ReturnCode.Ok) { if (operand1.IsString()) { value = (String.Compare( (string)operand1.Value, (string)operand2.Value, StringOps.UserStringComparisonType) >= 0); } else { error = String.Format( "unsupported operand type for operator {0}", FormatOps.OperatorName(name, this.Lexeme)); code = ReturnCode.Error; } } } } } catch (Exception e) { Engine.SetExceptionErrorCode(interpreter, e); error = String.Format( "caught math exception: {0}", e); code = ReturnCode.Error; } } else { error = "invalid argument list"; code = ReturnCode.Error; } } else { error = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 3) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.Unsupported, Index.Invalid, Index.Invalid, "-about", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-all", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-debug", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-ecma", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-compiled", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-explicit", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-reverse", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-expanded", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-indexes", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-indices", null), /* COMPAT: Tcl. */ new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-inline", null), new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-limit", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-line", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-lineanchor", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-linestop", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-nocase", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-noculture", null), new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-start", null), new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-length", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; code = interpreter.GetOptions(options, arguments, 0, 1, Index.Invalid, false, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 1) < arguments.Count)) { bool all = false; bool debug = false; bool indexes = false; bool inline = false; string pattern = arguments[argumentIndex]; string input = arguments[argumentIndex + 1]; RegexOptions regExOptions = StringOps.DefaultRegExOptions; Variant value = null; int limit = Count.Invalid; if (options.IsPresent("-limit", ref value)) { limit = (int)value.Value; } int length = input.Length; if (options.IsPresent("-length", ref value)) { length = (int)value.Value; if ((length < 0) || (length > input.Length)) { length = input.Length; } } int startIndex = 0; if (options.IsPresent("-start", ref value)) { // // NOTE: Handle "end-X", etc. // code = Value.GetIndex( value.ToString(), length, ValueFlags.AnyIndex, interpreter.CultureInfo, ref startIndex, ref result); if (code == ReturnCode.Ok) { if (startIndex < 0) { startIndex = 0; } if (startIndex > length) { startIndex = length; } } } if (code == ReturnCode.Ok) { if (options.IsPresent("-all")) { all = true; } if (options.IsPresent("-debug")) { debug = true; } if (options.IsPresent("-indexes") || options.IsPresent("-indices")) { indexes = true; } if (options.IsPresent("-inline")) { inline = true; } if (options.IsPresent("-ecma")) { regExOptions |= RegexOptions.ECMAScript; } if (options.IsPresent("-compiled")) { regExOptions |= RegexOptions.Compiled; } if (options.IsPresent("-explicit")) { regExOptions |= RegexOptions.ExplicitCapture; } if (options.IsPresent("-reverse")) { regExOptions |= RegexOptions.RightToLeft; } if (options.IsPresent("-expanded")) { regExOptions |= RegexOptions.IgnorePatternWhitespace; } if (options.IsPresent("-line")) { regExOptions &= ~RegexOptions.Singleline; regExOptions |= RegexOptions.Multiline; } if (options.IsPresent("-lineanchor")) { regExOptions |= RegexOptions.Multiline; } if (options.IsPresent("-linestop")) { regExOptions &= ~RegexOptions.Singleline; } if (options.IsPresent("-nocase")) { regExOptions |= RegexOptions.IgnoreCase; } if (options.IsPresent("-noculture")) { regExOptions |= RegexOptions.CultureInvariant; } if (!inline || ((argumentIndex + 2) >= arguments.Count)) { Regex regEx = null; try { regEx = new Regex(pattern, regExOptions); } catch (Exception e) { Engine.SetExceptionErrorCode(interpreter, e); result = String.Format( "couldn't compile regular expression pattern: {0}", e.Message); code = ReturnCode.Error; } // // NOTE: If the result is still Ok, then we know that the regular // expression pattern was compiled and the regEx object was // created successfully. // if (code == ReturnCode.Ok) { // // NOTE: Inline matches list, only created and populated when // we are operating in inline mode. // StringList matches = null; if (inline) { // // NOTE: Inline mode, create an empty inline matches // list. // matches = new StringList(); } /* * The following loop is to handle multiple matches within the * same source string; each iteration handles one match. If "-all" * hasn't been specified then the loop body only gets executed once. * We terminate the loop when the starting offset is past the end of the * string. */ int matchIndex = startIndex; int matchLength = length; int matchCount = 0; Match match = null; while (true) { // // NOTE: Perform the regular expresssion matching. This cannot // raise an exception because we know the input argument // is valid. // if (matchLength < 0) { matchLength = 0; } if ((matchIndex + matchLength) > input.Length) { matchLength = input.Length - matchIndex; } if (debug) { TraceOps.DebugWriteTo(interpreter, String.Format( "{0}: Trying index {1}, length {2}", this.Name, matchIndex, matchLength), false); } if (match != null) { match = match.NextMatch(); } else { match = regEx.Match(input, matchIndex, matchLength); } // // NOTE: Did the overall match succeed? // if (match.Success) { if (debug) { TraceOps.DebugWriteTo(interpreter, String.Format( "{0}: Match success {1}", this.Name, FormatOps.DisplayRegExMatch(match)), false); } // // NOTE: We found another match. // matchCount++; // // NOTE: Check if we should return this match. // if ((limit < 0) || ((limit >= 0) && (matchCount <= limit))) { // // NOTE: Advance the argument index just beyond the // pattern and input arguments. // int nextArgumentIndex = argumentIndex + 2; // // NOTE: Process each match group and either set the // corresponding variable value or add it to the // inline result. // foreach (Group group in match.Groups) { // // NOTE: Having a null group should not happen; but, // just in case it does, skip over them. // if (group == null) { continue; } // // NOTE: Set the value for this match group based on // whether we are operating in indexes mode. // string matchValue; if (group.Success) { if (indexes) { // // NOTE: Return the first and last indexes of // this match group. // matchValue = StringList.MakeList( group.Index, group.Index + group.Length - 1); } else { // // NOTE: Return the value of this match group. // matchValue = group.Value; } } else { if (indexes) { // // NOTE: Return invalid indexes for this match // group (we did not match this group). // matchValue = StringList.MakeList( Index.Invalid, Index.Invalid); } else { // // NOTE: Return an empty value for this match // group (we did not match this group). // matchValue = String.Empty; } } // // NOTE: Are we using inline mode? // if (inline) { // // NOTE: Inline mode, add match value to inline // matches list. // matches.Add(matchValue); } else { // // NOTE: If they supplied a variable name for this match // group, attempt to set the variable now. // if (nextArgumentIndex < arguments.Count) { // // NOTE: Potentially re-entrant here due to variable // traces. // code = interpreter.SetVariableValue(VariableFlags.None, arguments[nextArgumentIndex], matchValue, null, ref result); if (code != ReturnCode.Ok) { result = String.Format("couldn't set variable \"{0}\"", arguments[nextArgumentIndex]); break; } // // NOTE: Advance to the next match variable name, if any. // nextArgumentIndex++; } } } // // NOTE: If the inner loop failed to set a match variable, break // out of the outer loop as well. // if (code != ReturnCode.Ok) { break; } // // NOTE: If we are not in inline mode, fill in any remaining match variables // with an empty string or "-1 -1" if we are in indexes mode. // if (!inline) { for (; nextArgumentIndex < arguments.Count; nextArgumentIndex++) { // // NOTE: Potentially re-entrant here due to variable // traces. // string matchValue; if (indexes) { // // NOTE: Return invalid indexes for this match // group (we did not match this group). // matchValue = StringList.MakeList( Index.Invalid, Index.Invalid); } else { // // NOTE: Return an empty value for this match // group (we did not match this group). // matchValue = String.Empty; } code = interpreter.SetVariableValue(VariableFlags.None, arguments[nextArgumentIndex], matchValue, null, ref result); if (code != ReturnCode.Ok) { result = String.Format("couldn't set variable \"{0}\"", arguments[nextArgumentIndex]); break; } } } } } else { if (debug) { TraceOps.DebugWriteTo(interpreter, String.Format( "{0}: Match failure", this.Name), false); } // // NOTE: We are done matching. // break; } // // NOTE: Only keep going if we want all matches. // if (!all) { break; } // // NOTE: Adjust the match index and length to remove what we have // already matched. // Group groupZero = RegExOps.GetMatchGroup(match, 0); if (groupZero == null) { result = String.Format( "cannot advance beyond {0} / {1}: group zero missing", matchIndex, matchLength); code = ReturnCode.Error; break; } if ((groupZero.Index + groupZero.Length) == matchIndex) { matchIndex++; } else { matchIndex = (groupZero.Index + groupZero.Length); } // // NOTE: Did we run out of input string to match against? // if (matchIndex >= length) { break; } } // // NOTE: If we did not encounter an error above (setting a match variable), // we will now set the overall command result based on whether or not // we are using inline mode. // if (code == ReturnCode.Ok) { if (inline) { result = matches; } else { result = (all ? matchCount : ConversionOps.ToInt(matchCount != 0)); } } } } else { result = "regexp match variables not allowed when using -inline"; code = ReturnCode.Error; } } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"regexp ?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?\""; } code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"regexp ?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
/////////////////////////////////////////////////////////////////////////////////////////////// #region IExecuteArgument Members public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Argument value, ref Result error ) { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { if (arguments != null) { try { string name = null; Variant operand1 = null; Variant operand2 = null; code = Value.GetOperandsFromArguments(interpreter, this, arguments, ValueFlags.AnyVariant, interpreter.CultureInfo, ref name, ref operand1, ref operand2, ref error); if (code == ReturnCode.Ok) { if (operand1 != null) { // // BUGBUG: This is not correct. We need to use the smallest type // possible here (this will have to be corrected in // GetVariant). // if (operand1.IsWideInteger()) { value = ~(long)operand1.Value; } else if (operand1.IsInteger()) { value = ~(int)operand1.Value; } else if (operand1.IsBoolean()) { value = ~ConversionOps.ToInt((bool)operand1.Value); } else { error = String.Format( "unsupported operand type for operator {0}", FormatOps.OperatorName(name, this.Lexeme)); code = ReturnCode.Error; } } else { error = String.Format( "operand for operator {0} is invalid", FormatOps.OperatorName(name, this.Lexeme)); code = ReturnCode.Error; } } } catch (Exception e) { Engine.SetExceptionErrorCode(interpreter, e); error = String.Format( "caught math exception: {0}", e); code = ReturnCode.Error; } } else { error = "invalid argument list"; code = ReturnCode.Error; } } else { error = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
/////////////////////////////////////////////////////////////////////////////////////////////// #region IExecuteArgument Members public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Argument value, ref Result error ) { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { if (arguments != null) { if (arguments.Count == (this.Arguments + 1)) { Variant variant1 = null; code = Value.GetVariant(interpreter, (IGetValue)arguments[1], ValueFlags.AnyVariant, interpreter.CultureInfo, ref variant1, ref error); if (code == ReturnCode.Ok) { try { if (variant1.IsDouble()) { value = Interpreter.FixIntermediatePrecision( Math.Log((double)variant1.Value, 2)); } else if (variant1.IsDecimal()) { if (variant1.ConvertTo(typeof(double))) { value = Interpreter.FixIntermediatePrecision( Math.Log((double)variant1.Value, 2)); } else { error = String.Format( "could not convert decimal \"{0}\" to double", arguments[1]); code = ReturnCode.Error; } } else if (variant1.IsWideInteger()) { value = MathOps.Log2((long)variant1.Value); } else if (variant1.IsInteger()) { value = MathOps.Log2((int)variant1.Value); } else if (variant1.IsBoolean()) { value = MathOps.Log2( ConversionOps.ToInt((bool)variant1.Value)); } else { error = String.Format( "unsupported variant type for function \"{0}\"", base.Name); code = ReturnCode.Error; } } catch (Exception e) { Engine.SetExceptionErrorCode(interpreter, e); error = String.Format( "caught math exception: {0}", e); code = ReturnCode.Error; } } } else { if (arguments.Count > (this.Arguments + 1)) { error = String.Format( "too many arguments for math function \"{0}\"", base.Name); } else { error = String.Format( "too few arguments for math function \"{0}\"", base.Name); } code = ReturnCode.Error; } } else { error = "invalid argument list"; code = ReturnCode.Error; } } else { error = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
/////////////////////////////////////////////////////////////////////////////////////////////// public ReturnCode Read( /* throw */ int count, CharList endOfLine, bool useAnyEndOfLineChar, ref ByteList list, ref Result error ) { CheckDisposed(); ReturnCode code = ReturnCode.Error; if (stream != null) { // // NOTE: Allocate enough for the whole file. // if (list == null) { long length = 0; // // NOTE: Only attempt to query the length of // seekable streams. // if (stream.CanSeek) { length = stream.Length; } if (length > 0) { list = new ByteList((int)Math.Min(length, MaximumBufferSize)); } else { list = new ByteList(); } } // // NOTE: Read from the stream in a loop until we hit a terminator // (typically "end of line" or "end of file"). // int readCount = 0; bool eolFound = false; int eolLength = (endOfLine != null) ? endOfLine.Count : 0; int eolIndex = 0; do { int value = ReadByte(stream); // // NOTE: Did we hit the end of the stream? // if (value != EndOfFile) { byte byteValue = ConversionOps.ToByte(value); // // NOTE: Did they supply a valid end-of-line sequence to check // against? // if ((endOfLine != null) && (eolLength > 0)) { // // NOTE: Does the caller want to stop reading as soon as any of // the supplied end-of-line characters are detected? // if (useAnyEndOfLineChar) { // // NOTE: Does the byte match any of the supplied end-of-line // characters? // if (endOfLine.Contains(ConversionOps.ToChar(byteValue))) { eolFound = true; } } else { // // NOTE: Does the byte we just read match the next character in // the end-of-line sequence we were expecting to see? // if (byteValue == endOfLine[eolIndex]) { // // NOTE: Have we just match the last character of the end-of-line // sequence? If so, we have found the end-of-line and we // are done. // if (++eolIndex == eolLength) { eolFound = true; /* NOTE: Hit end-of-line sequence. */ } } else if (eolIndex > 0) { // // NOTE: Any bytes previously matched against end-of-line sequence // characters no longer count because the end-of-line sequence // characters must appear consecutively. // eolIndex = 0; } } } // // NOTE: Add the byte (which could potentially be part of an end-of-line // sequence) to the buffer. // list.Add(byteValue); // // NOTE: We just read another byte, keep track. // readCount++; // // NOTE: Now that we have added the byte to the buffer, check to see if we // hit the end-of-line (above). If so, remove the end-of-line seuqnece // from the end of the buffer and bail out. // if (eolFound) { int bufferLength = list.Count; RemoveEndOfLine(list.ToArray(), endOfLine, useAnyEndOfLineChar, ref bufferLength); while (list.Count > bufferLength) { list.RemoveAt(list.Count - 1); } break; } } else { hitEndOfStream = true; /* NOTE: No more data. */ break; } }while ((count == Count.Invalid) || (readCount < count)); TranslateEndOfLine(StreamDirection.Input, list, ref list); // TEST: Test this. code = ReturnCode.Ok; } else { error = "invalid stream"; } return(code); }
/////////////////////////////////////////////////////////////////////////////////////////////// #region IExecuteArgument Members public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Argument value, ref Result error ) { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 2) { Variant variant1 = null; code = Value.GetVariant(interpreter, (IGetValue)arguments[1], ValueFlags.AnyVariant, interpreter.CultureInfo, ref variant1, ref error); if (code == ReturnCode.Ok) { for (int argumentIndex = 2; argumentIndex < arguments.Count; argumentIndex++) { Variant variant2 = null; code = Value.GetVariant(interpreter, (IGetValue)arguments[argumentIndex], ValueFlags.AnyVariant, interpreter.CultureInfo, ref variant2, ref error); if (code != ReturnCode.Ok) { break; } code = Value.FixupVariants( this, variant1, variant2, null, null, false, false, ref error); if (code != ReturnCode.Ok) { break; } try { if (variant1.IsDouble()) { variant1.Value = Interpreter.FixIntermediatePrecision( Math.Max((double)variant1.Value, (double)variant2.Value)); } else if (variant1.IsDecimal()) { variant1.Value = Interpreter.FixIntermediatePrecision( Math.Max((decimal)variant1.Value, (decimal)variant2.Value)); } else if (variant1.IsWideInteger()) { variant1.Value = Math.Max( (long)variant1.Value, (long)variant2.Value); } else if (variant1.IsInteger()) { variant1.Value = Math.Max( (int)variant1.Value, (int)variant2.Value); } else if (variant1.IsBoolean()) { variant1.Value = Math.Max( ConversionOps.ToInt((bool)variant1.Value), ConversionOps.ToInt((bool)variant2.Value)); } else { error = String.Format( "unsupported variant type for function \"{0}\"", base.Name); code = ReturnCode.Error; } } catch (Exception e) { Engine.SetExceptionErrorCode(interpreter, e); error = String.Format( "caught math exception: {0}", e); code = ReturnCode.Error; break; } } if (code == ReturnCode.Ok) { value = Argument.GetOrCreate( interpreter, variant1, interpreter.HasNoCacheArgument()); } } } else { error = String.Format( "too few arguments for math function \"{0}\"", base.Name); code = ReturnCode.Error; } } else { error = "invalid argument list"; code = ReturnCode.Error; } } else { error = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
///////////////////////////////////////////////////////////////////////////////// public static UIntPtr GetNativeStackMaximum() { UIntPtr result = UIntPtr.Zero; // // NOTE: Are we able to query the thread environment block (i.e. we // know what platform we are on and the appropriate constants // have been setup)? // if (CanQueryThread) { try { IntPtr teb = IntPtr.Zero; if (NtCurrentTeb != null) { teb = NtCurrentTeb(); } else { teb = SafeNativeMethods.NtCurrentTeb(); } if (teb != IntPtr.Zero) { IntPtr stackBase = Marshal.ReadIntPtr( teb, (int)TebStackBaseOffset); IntPtr deallocationStack = Marshal.ReadIntPtr( teb, (int)TebDeallocationStack); if (stackBase.ToInt64() > deallocationStack.ToInt64()) { result = new UIntPtr(ConversionOps.ToULong( stackBase.ToInt64() - deallocationStack.ToInt64())); } } else { if (Interlocked.Increment(ref InvalidTeb) == 1) { TraceOps.DebugTrace( "GetNativeStackMaximum: invalid TEB", typeof(NativeStack).Name, TracePriority.NativeError); } } } catch (Exception e) { if (Interlocked.Increment(ref TebException) == 1) { TraceOps.DebugTrace( e, typeof(NativeStack).Name, TracePriority.NativeError); } } } else { if (Interlocked.Increment(ref CannotQueryThread) == 1) { TraceOps.DebugTrace( "GetNativeStackMaximum: cannot query thread", typeof(NativeStack).Name, TracePriority.NativeError); } } return(result); }
/////////////////////////////////////////////////////////////////////// public static ReturnCode Wait( Interpreter interpreter, long microseconds, bool timeout, bool strict, ref Result error ) /* THREAD-SAFE */ { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { int waitCount; if ((waitCount = interpreter.EnterWait()) > 0) { if (microseconds == 0) { #if WINFORMS // // NOTE: If necessary, process all Windows messages // from the queue. // if (!strict) { code = WindowOps.ProcessEvents( interpreter, ref error); } if (code == ReturnCode.Ok) #endif { // // NOTE: Yield to other running threads. This // also gives them an opportunity to cancel // the script in progress on this thread. // HostOps.Yield(); } } else { // // NOTE: Keep track of how many iterations through // the loop we take. // int iterations = 0; // // HACK: Account for our processing overhead; use half // of the requested delay. // int milliseconds = ConversionOps.ToInt( PerformanceOps.GetMilliseconds(microseconds) / WaitDivisor); if (milliseconds < 0) { milliseconds = 0; } if (milliseconds > WaitMaximumSleepTime) { milliseconds = WaitMaximumSleepTime; } // // NOTE: For more precise timing, use the high-resolution // CPU performance counter. // long startCount = PerformanceOps.GetCount(); // // BUGFIX: Make sure the slop time does not exceed the // actual wait. // long slopMicroseconds = Math.Min( microseconds / WaitSlopDivisor, WaitSlopMinimumTime); // // NOTE: Delay for approximately the specified number of // microseconds, optionally timing out if we cannot // obtain the interpreter lock before the time period // elapses. // while (((code = Interpreter.EventReady(interpreter, timeout ? milliseconds : _Timeout.Infinite, ref error)) == ReturnCode.Ok) && !PerformanceOps.HasElapsed(startCount, microseconds, slopMicroseconds)) { #if WINFORMS if (!strict) { code = WindowOps.ProcessEvents(interpreter, ref error); if (code != ReturnCode.Ok) { break; } } #endif HostOps.SleepOrMaybeComplain(interpreter, milliseconds); iterations++; } long stopCount = PerformanceOps.GetCount(); double elapsedMicroseconds = PerformanceOps.GetMicroseconds( startCount, stopCount, 1); TraceOps.DebugTrace(String.Format( "Wait: code = {0}, iterations = {1}, microseconds = {2}, " + "elapsedMicroseconds = {3}, sleepMilliseconds = {4}, " + "slopMicroseconds = {5}, differenceMicroseconds = {6}, " + "waitCount = {7}, error = {8}", code, iterations, microseconds, elapsedMicroseconds, milliseconds, slopMicroseconds, elapsedMicroseconds - (double)microseconds, waitCount, FormatOps.WrapOrNull(true, true, error)), typeof(EventOps).Name, TracePriority.EventDebug); } /* IGNORED */ interpreter.ExitWait(); } else { error = "wait subsystem locked"; code = ReturnCode.Error; } } else { error = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
/////////////////////////////////////////////////////////////////////////////////////////////// #region IExecuteArgument Members public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Argument value, ref Result error ) { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { if (arguments != null) { try { string name = null; Variant operand1 = null; Variant operand2 = null; code = Value.GetOperandsFromArguments(interpreter, this, arguments, ValueFlags.AnyVariant, interpreter.CultureInfo, ref name, ref operand1, ref operand2, ref error); if (code == ReturnCode.Ok) { if (arguments.Count == 3) { code = Value.FixupVariants( this, operand1, operand2, null, null, false, false, ref error); if (code == ReturnCode.Ok) { if (operand1.IsDouble()) { value = Interpreter.FixIntermediatePrecision( (double)operand1.Value + (double)operand2.Value); } else if (operand1.IsDecimal()) { value = Interpreter.FixIntermediatePrecision( (decimal)operand1.Value + (decimal)operand2.Value); } else if (operand1.IsWideInteger()) { value = ((long)operand1.Value + (long)operand2.Value); } else if (operand1.IsInteger()) { value = ((int)operand1.Value + (int)operand2.Value); } else if (operand1.IsBoolean()) { value = (ConversionOps.ToInt((bool)operand1.Value) + ConversionOps.ToInt((bool)operand2.Value)); } else { error = String.Format( "unsupported operand type for operator {0}", FormatOps.OperatorName(name, this.Lexeme)); code = ReturnCode.Error; } } } else if (arguments.Count == 2) { if (operand1.IsDouble()) { value = Interpreter.FixIntermediatePrecision( +(double)operand1.Value); } else if (operand1.IsDecimal()) { value = Interpreter.FixIntermediatePrecision( +(decimal)operand1.Value); } else if (operand1.IsWideInteger()) { value = (+(long)operand1.Value); } else if (operand1.IsInteger()) { value = (+(int)operand1.Value); } else if (operand1.IsBoolean()) { value = (+ConversionOps.ToInt((bool)operand1.Value)); } else { error = String.Format( "unsupported operand type for operator {0}", FormatOps.OperatorName(name, this.Lexeme)); code = ReturnCode.Error; } } else { error = String.Format( "wrong # args: should be \"{0} operand\" or \"{1}\"", name, String.Format(ExpressionParser.IsOperatorNameOnly( name) ? "operand1 {0} operand2" : "{0} operand1 operand2", name)); code = ReturnCode.Error; } } } catch (Exception e) { Engine.SetExceptionErrorCode(interpreter, e); error = String.Format( "caught math exception: {0}", e); code = ReturnCode.Error; } } else { error = "invalid argument list"; code = ReturnCode.Error; } } else { error = "invalid interpreter"; code = ReturnCode.Error; } return(code); }