Пример #1
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        #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();
            }
        }
Пример #2
0
        ///////////////////////////////////////////////////////////////////////

        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);
        }
Пример #3
0
        ///////////////////////////////////////////////////////////////////////

        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);
        }
Пример #4
0
        ///////////////////////////////////////////////////////////////////////

        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);
        }
Пример #5
0
        /////////////////////////////////////////////////////////////////////////////////

        #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;
                        }
                    }
                }
            }
        }
Пример #6
0
            ///////////////////////////////////////////////////////////////////

            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]));
                }
            }
Пример #7
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        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;
                        }
                    }
                }
            }
        }
Пример #8
0
        ///////////////////////////////////////////////////////////////////////

        public ByteList(
            IEnumerable <char> collection
            )
            : this()
        {
            foreach (char item in collection)
            {
                this.Add(ConversionOps.ToByte(item));
            }
        }
Пример #9
0
        ///////////////////////////////////////////////////////////////////////

        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);
        }
Пример #10
0
            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)));
            }
Пример #11
0
        ///////////////////////////////////////////////////////////////////////

        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);
        }
Пример #12
0
        ///////////////////////////////////////////////////////////////////////

        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);
        }
Пример #13
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        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));
        }
Пример #14
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        #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();
            }
        }
Пример #15
0
        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);
        }
Пример #16
0
        ///////////////////////////////////////////////////////////////////////

        #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);
        }
Пример #17
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        public static int DaysInYear(
            int year
            )
        {
            return(DaysInNormalYear + ConversionOps.ToInt(DateTime.IsLeapYear(year)));
        }
Пример #18
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        #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);
        }
Пример #19
0
        /////////////////////////////////////////////////////////////////////////////////

        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);
        }
Пример #20
0
        ///////////////////////////////////////////////////////////////////////

        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);
        }
Пример #21
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        #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);
        }
Пример #22
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        #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);
        }
Пример #23
0
        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);
        }
Пример #24
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        #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);
        }
Пример #25
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        #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);
        }
Пример #26
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        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);
        }
Пример #27
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        #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);
        }
Пример #28
0
        /////////////////////////////////////////////////////////////////////////////////

        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);
        }
Пример #29
0
        ///////////////////////////////////////////////////////////////////////

        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);
        }
Пример #30
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        #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);
        }