Пример #1
0
        /// <summary> This procedure is invoked to process the "eval" Tcl command.
        /// See the user documentation for details on what it does.
        ///
        /// </summary>
        /// <param name="interp">the current interpreter.
        /// </param>
        /// <param name="argv">command arguments.
        /// </param>
        /// <exception cref=""> TclException if script causes error.
        /// </exception>

        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv)
        {
            if (argv.Length < 2)
            {
                throw new TclNumArgsException(interp, 1, argv, "arg ?arg ...?");
            }

            try
            {
                if (argv.Length == 2)
                {
                    interp.Eval(argv[1], 0);
                }
                else
                {
                    string s = Util.concat(1, argv.Length - 1, argv);
                    interp.Eval(s, 0);
                }
            }
            catch (TclException e)
            {
                if (e.GetCompletionCode() == TCL.CompletionCode.ERROR)
                {
                    interp.AddErrorInfo("\n    (\"eval\" body line " + interp._errorLine + ")");
                }
                throw;
            }
            return(TCL.CompletionCode.RETURN);
        }
Пример #2
0
        internal static void eval(Interp interp, Interp slaveInterp, int objIx, TclObject[] objv)
        {
            TCL.CompletionCode result;

            slaveInterp.preserve();
            slaveInterp.allowExceptions();

            try
            {
                if (objIx + 1 == objv.Length)
                {
                    slaveInterp.Eval(objv[objIx], 0);
                }
                else
                {
                    TclObject obj = TclList.NewInstance();
                    for (int ix = objIx; ix < objv.Length; ix++)
                    {
                        TclList.Append(interp, obj, objv[ix]);
                    }
                    obj.Preserve();
                    slaveInterp.Eval(obj, 0);
                    obj.Release();
                }
                result = slaveInterp._returnCode;
            }
            catch (TclException e)
            {
                result = e.GetCompletionCode();
            }

            slaveInterp.release();
            interp.transferResult(slaveInterp, result);
        }
Пример #3
0
 public override void ProcessIdleEvent()
 {
     try
     {
         SupportClass.VectorRemoveElement(EnclosingInstance._assocData.Handlers, this);
         Interp.Eval(Command, TCL.EVAL_GLOBAL);
     }
     catch (TclException e) { Interp.AddErrorInfo("\n    (\"after\" script)"); Interp.BackgroundError(); }
     finally { Command.Release(); Command = null; }
 }
Пример #4
0
 public static int Tcl_Eval(Interp interp, string s)
 {
     try
     {
         interp.Eval(s);
         return(0);
     }
     catch
     {
         return(1);
     };
 }
Пример #5
0
        /// <summary> This procedure is invoked to process the "while" Tcl command.
        /// See the user documentation for details on what it does.
        ///
        /// </summary>
        /// <param name="interp">the current interpreter.
        /// </param>
        /// <param name="argv">command arguments.
        /// </param>
        /// <exception cref=""> TclException if script causes error.
        /// </exception>

        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv)
        {
            if (argv.Length != 3)
            {
                throw new TclNumArgsException(interp, 1, argv, "test command");
            }

            string    test    = argv[1].ToString();
            TclObject command = argv[2];

            {
                while (interp._expr.EvalBoolean(interp, test))
                {
                    try
                    {
                        interp.Eval(command, 0);
                    }
                    catch (TclException e)
                    {
                        switch (e.GetCompletionCode())
                        {
                        case TCL.CompletionCode.BREAK:
                            goto loop_brk;


                        case TCL.CompletionCode.CONTINUE:
                            continue;


                        case TCL.CompletionCode.ERROR:
                            interp.AddErrorInfo("\n    (\"while\" body line " + interp._errorLine + ")");
                            throw;


                        default:
                            throw;
                        }
                    }
                }
            }

loop_brk:
            ;


            interp.ResetResult();
            return(TCL.CompletionCode.RETURN);
        }
Пример #6
0
        public void traceProc(Interp interp, string part1, string part2, TCL.VarFlag flags)
        {
            if (((this.flags & flags) != 0) && ((flags & TCL.VarFlag.INTERP_DESTROYED) == 0))
            {
                StringBuilder sbuf = new StringBuilder(command);

                try
                {
                    Util.appendElement(interp, sbuf, part1);
                    if ((System.Object)part2 != null)
                    {
                        Util.appendElement(interp, sbuf, part2);
                    }
                    else
                    {
                        Util.appendElement(interp, sbuf, "");
                    }

                    if ((flags & TCL.VarFlag.TRACE_READS) != 0)
                    {
                        Util.appendElement(interp, sbuf, "r");
                    }
                    else if ((flags & TCL.VarFlag.TRACE_WRITES) != 0)
                    {
                        Util.appendElement(interp, sbuf, "w");
                    }
                    else if ((flags & TCL.VarFlag.TRACE_UNSETS) != 0)
                    {
                        Util.appendElement(interp, sbuf, "u");
                    }
                }
                catch (TclException e)
                {
                    throw new TclRuntimeError("unexpected TclException: " + e.Message, e);
                }

                // Execute the command.

                interp.Eval(sbuf.ToString(), 0);
            }
        }
Пример #7
0
        /// <summary> This procedure is invoked to process the "catch" Tcl command.
        /// See the user documentation for details on what it does.
        ///
        /// </summary>
        /// <param name="interp">the current interpreter.
        /// </param>
        /// <param name="argv">command arguments.
        /// </param>
        /// <exception cref=""> TclException if wrong number of arguments.
        /// </exception>

        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv)
        {
            if (argv.Length != 2 && argv.Length != 3)
            {
                throw new TclNumArgsException(interp, 1, argv, "command ?varName?");
            }

            TclObject result;

            TCL.CompletionCode code = TCL.CompletionCode.OK;

            try
            {
                interp.Eval(argv[1], 0);
            }
            catch (TclException e)
            {
                code = e.GetCompletionCode();
            }

            result = interp.GetResult();

            if (argv.Length == 3)
            {
                try
                {
                    interp.SetVar(argv[2], result, 0);
                }
                catch (TclException e)
                {
                    throw new TclException(interp, "couldn't save command result in variable");
                }
            }

            interp.ResetResult();
            interp.SetResult(TclInteger.NewInstance((int)code));
            return(TCL.CompletionCode.RETURN);
        }
Пример #8
0
 public static int Tcl_EvalObjEx(Interp interp, TclObject tobj, int flags)
 {
     try
     {
         interp.Eval(tobj, flags);
         return(0);
     }
     catch (TclException e)
     {
         if (e.GetCompletionCode() == TCL.CompletionCode.RETURN)
         {
             return(TCL_RETURN);
         }
         else if (e.GetCompletionCode() == TCL.CompletionCode.BREAK || interp.GetResult().ToString() == "invoked \"break\" outside of a loop")
         {
             return(TCL_BREAK);
         }
         else
         {
             return(TCL_ERROR);
         }
     };
 }
Пример #9
0
        /// <summary> See Tcl user documentation for details.</summary>

        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv)
        {
            if ((argv.Length < 2) || (argv.Length > 3))
            {
                throw new TclNumArgsException(interp, 1, argv, "script ?count?");
            }

            int count;

            if (argv.Length == 2)
            {
                count = 1;
            }
            else
            {
                count = TclInteger.Get(interp, argv[2]);
            }

            long startTime = System.DateTime.Now.Ticks;

            for (int i = 0; i < count; i++)
            {
                interp.Eval(argv[1], 0);
            }
            long endTime = System.DateTime.Now.Ticks;
            long uSecs   = (((endTime - startTime) / 10) / count);

            if (uSecs == 1)
            {
                interp.SetResult(TclString.NewInstance("1 microsecond per iteration"));
            }
            else
            {
                interp.SetResult(TclString.NewInstance(uSecs + " microseconds per iteration"));
            }
            return(TCL.CompletionCode.RETURN);
        }
Пример #10
0
        /// <summary> Compares the order of two items in the array.
        ///
        /// </summary>
        /// <param name="obj1">first item.
        /// </param>
        /// <param name="obj2">second item.
        /// </param>
        /// <returns> 0 if they are equal, 1 if obj1 > obj2, -1 otherwise.
        ///
        /// </returns>
        /// <exception cref=""> TclException if an error occurs during sorting.
        /// </exception>
        private int compare(TclObject obj1, TclObject obj2)
        {
            int index;
            int code = 0;

            if (sortIndex != -1)
            {
                // The "-index" option was specified.  Treat each object as a
                // list, extract the requested element from each list, and
                // compare the elements, not the lists.  The special index "end"
                // is signaled here with a negative index (other than -1).

                TclObject obj;
                if (sortIndex < -1)
                {
                    index = TclList.getLength(sortInterp, obj1) - 1;
                }
                else
                {
                    index = sortIndex;
                }

                obj = TclList.index(sortInterp, obj1, index);
                if (obj == null)
                {
                    throw new TclException(sortInterp, "element " + index + " missing from sublist \"" + obj1 + "\"");
                }
                obj1 = obj;

                if (sortIndex < -1)
                {
                    index = TclList.getLength(sortInterp, obj2) - 1;
                }
                else
                {
                    index = sortIndex;
                }

                obj = TclList.index(sortInterp, obj2, index);
                if (obj == null)
                {
                    throw new TclException(sortInterp, "element " + index + " missing from sublist \"" + obj2 + "\"");
                }
                obj2 = obj;
            }

            switch (sortMode)
            {
            case ASCII:
                // ATK C# CompareTo use option
                // similar to -dictionary but a > A
                code = System.Globalization.CultureInfo.InvariantCulture.CompareInfo.Compare(obj1.ToString(), obj2.ToString(), System.Globalization.CompareOptions.Ordinal);
                // code = obj1.ToString().CompareTo(obj2.ToString());
                break;

            case DICTIONARY:

                code = doDictionary(obj1.ToString(), obj2.ToString());
                break;

            case INTEGER:
                try
                {
                    int int1 = TclInteger.Get(sortInterp, obj1);
                    int int2 = TclInteger.Get(sortInterp, obj2);

                    if (int1 > int2)
                    {
                        code = 1;
                    }
                    else if (int2 > int1)
                    {
                        code = -1;
                    }
                }
                catch (TclException e1)
                {
                    sortInterp.AddErrorInfo("\n    (converting list element from string to integer)");
                    throw e1;
                }
                break;

            case REAL:
                try
                {
                    double f1 = TclDouble.Get(sortInterp, obj1);
                    double f2 = TclDouble.Get(sortInterp, obj2);

                    if (f1 > f2)
                    {
                        code = 1;
                    }
                    else if (f2 > f1)
                    {
                        code = -1;
                    }
                }
                catch (TclException e2)
                {
                    sortInterp.AddErrorInfo("\n    (converting list element from string to real)");
                    throw e2;
                }
                break;

            case COMMAND:
                StringBuilder sbuf = new StringBuilder(sortCommand);

                Util.appendElement(sortInterp, sbuf, obj1.ToString());

                Util.appendElement(sortInterp, sbuf, obj2.ToString());
                try
                {
                    sortInterp.Eval(sbuf.ToString(), 0);
                }
                catch (TclException e3)
                {
                    sortInterp.AddErrorInfo("\n    (user-defined comparison command)");
                    throw e3;
                }

                try
                {
                    code = TclInteger.Get(sortInterp, sortInterp.GetResult());
                }
                catch (TclException e)
                {
                    sortInterp.ResetResult();
                    TclException e4 = new TclException(sortInterp, "comparison command returned non-numeric result");
                    throw e4;
                }
                break;


            default:

                throw new TclRuntimeError("Unknown sortMode " + sortMode);
            }

            if (sortIncreasing)
            {
                return(code);
            }
            else
            {
                return(-code);
            }
        }
Пример #11
0
        /// <summary> See Tcl user documentation for details.</summary>
        /// <exception cref=""> TclException If incorrect number of arguments.
        /// </exception>
        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv)
        {
            int  i;
            bool value;

            i = 1;
            while (true)
            {
                /*
                 * At this point in the loop, argv and argc refer to an
                 * expression to test, either for the main expression or
                 * an expression following an "elseif".  The arguments
                 * after the expression must be "then" (optional) and a
                 * script to execute if the expression is true.
                 */

                if (i >= argv.Length)
                {
                    throw new TclException(interp, "wrong # args: no expression after \"" + argv[i - 1] + "\" argument");
                }
                try
                {
                    value = interp._expr.EvalBoolean(interp, argv[i].ToString());
                }
                catch (TclException e)
                {
                    switch (e.GetCompletionCode())
                    {
                    case TCL.CompletionCode.ERROR:
                        interp.AddErrorInfo("\n    (\"if\" test expression)");
                        break;
                    }
                    throw;
                }

                i++;

                if ((i < argv.Length) && (argv[i].ToString().Equals("then")))
                {
                    i++;
                }
                if (i >= argv.Length)
                {
                    throw new TclException(interp, "wrong # args: no script following \"" + argv[i - 1] + "\" argument");
                }
                if (value)
                {
                    try
                    {
                        interp.Eval(argv[i], 0);
                    }
                    catch (TclException e)
                    {
                        switch (e.GetCompletionCode())
                        {
                        case TCL.CompletionCode.ERROR:
                            interp.AddErrorInfo("\n    (\"if\" then script line " + interp._errorLine + ")");
                            break;
                        }
                        throw;
                    }
                    return(TCL.CompletionCode.RETURN);
                }

                /*
                 * The expression evaluated to false.  Skip the command, then
                 * see if there is an "else" or "elseif" clause.
                 */

                i++;
                if (i >= argv.Length)
                {
                    interp.ResetResult();
                    return(TCL.CompletionCode.RETURN);
                }

                if (argv[i].ToString().Equals("elseif"))
                {
                    i++;
                    continue;
                }
                break;
            }

            /*
             * Couldn't find a "then" or "elseif" clause to execute.
             * Check now for an "else" clause.  We know that there's at
             * least one more argument when we get here.
             */


            if (argv[i].ToString().Equals("else"))
            {
                i++;
                if (i >= argv.Length)
                {
                    throw new TclException(interp, "wrong # args: no script following \"else\" argument");
                }
                else if (i != (argv.Length - 1))
                {
                    throw new TclException(interp, "wrong # args: extra words after \"else\" clause in " + "\"if\" command");
                }
            }
            try
            {
                interp.Eval(argv[i], 0);
            }
            catch (TclException e)
            {
                switch (e.GetCompletionCode())
                {
                case TCL.CompletionCode.ERROR:
                    interp.AddErrorInfo("\n    (\"if\" else script line " + interp._errorLine + ")");
                    break;
                }
                throw;
            }
            return(TCL.CompletionCode.RETURN);
        }
Пример #12
0
        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] objv)
        {
            string    optLevel;
            int       result;
            CallFrame savedVarFrame, frame;
            int       objc = objv.Length;
            int       objv_index;
            TclObject cmd;

            if (objv.Length < 2)
            {
                throw new TclNumArgsException(interp, 1, objv, "?level? command ?arg ...?");
            }

            // Find the level to use for executing the command.


            optLevel = objv[1].ToString();
            // Java does not support passing a reference by refernece so use an array
            CallFrame[] frameArr = new CallFrame[1];
            result = CallFrame.GetFrame(interp, optLevel, frameArr);
            frame  = frameArr[0];

            objc -= (result + 1);
            if (objc == 0)
            {
                throw new TclNumArgsException(interp, 1, objv, "?level? command ?arg ...?");
            }
            objv_index = (result + 1);

            // Modify the interpreter state to execute in the given frame.

            savedVarFrame   = interp.VarFrame;
            interp.VarFrame = frame;

            // Execute the residual arguments as a command.

            if (objc == 1)
            {
                cmd = objv[objv_index];
            }
            else
            {
                cmd = TclString.NewInstance(Util.concat(objv_index, objv.Length - 1, objv));
            }
            cmd.Preserve();

            try
            {
                interp.Eval(cmd, 0);
            }
            catch (TclException e)
            {
                if (e.GetCompletionCode() == TCL.CompletionCode.ERROR)
                {
                    interp.AddErrorInfo("\n    (\"uplevel\" body line " + interp._errorLine + ")");
                }
                throw;
            }
            finally
            {
                interp.VarFrame = savedVarFrame;
                cmd.Release();
            }
            return(TCL.CompletionCode.RETURN);
        }
Пример #13
0
        /*
         * This procedure is invoked to process the "for" Tcl command.
         * See the user documentation for details on what it does.
         *
         * @param interp the current interpreter.
         * @param argv command arguments.
         * @exception TclException if script causes error.
         */

        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv)
        {
            if (argv.Length != 5)
            {
                throw new TclNumArgsException(interp, 1, argv, "start test next command");
            }

            TclObject start = argv[1];

            string    test    = argv[2].ToString();
            TclObject next    = argv[3];
            TclObject command = argv[4];

            bool done = false;

            try
            {
                interp.Eval(start, 0);
            }
            catch (TclException e)
            {
                interp.AddErrorInfo("\n    (\"for\" initial command)");
                throw;
            }

            while (!done)
            {
                if (!interp._expr.EvalBoolean(interp, test))
                {
                    break;
                }

                try
                {
                    interp.Eval(command, 0);
                }
                catch (TclException e)
                {
                    switch (e.GetCompletionCode())
                    {
                    case TCL.CompletionCode.BREAK:
                        done = true;
                        break;


                    case TCL.CompletionCode.CONTINUE:
                        break;


                    case TCL.CompletionCode.ERROR:
                        interp.AddErrorInfo("\n    (\"for\" body line " + interp._errorLine + ")");
                        throw;


                    default:
                        throw;
                    }
                }

                if (!done)
                {
                    try
                    {
                        interp.Eval(next, 0);
                    }
                    catch (TclException e)
                    {
                        switch (e.GetCompletionCode())
                        {
                        case TCL.CompletionCode.BREAK:
                            done = true;
                            break;


                        case TCL.CompletionCode.CONTINUE:
                            break;


                        default:
                            interp.AddErrorInfo("\n    (\"for\" loop-end command)");
                            throw;
                        }
                    }
                }
            }

            interp.ResetResult();
            return(TCL.CompletionCode.RETURN);
        }
Пример #14
0
        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv)
        {
            int    i, mode, body;
            bool   matched;
            string inString;

            TclObject[] switchArgv = null;

            mode = EXACT;
            for (i = 1; i < argv.Length; i++)
            {
                if (!argv[i].ToString().StartsWith("-"))
                {
                    break;
                }
                int opt = TclIndex.Get(interp, argv[i], validCmds, "option", 1);
                if (opt == LAST)
                {
                    i++;
                    break;
                }
                else if (opt > LAST)
                {
                    throw new TclException(interp, "SwitchCmd.cmdProc: bad option " + opt + " index to validCmds");
                }
                else
                {
                    mode = opt;
                }
            }

            if (argv.Length - i < 2)
            {
                throw new TclNumArgsException(interp, 1, argv, "?switches? string pattern body ... ?default body?");
            }

            inString = argv[i].ToString();
            i++;

            // If all of the pattern/command pairs are lumped into a single
            // argument, split them out again.

            if (argv.Length - i == 1)
            {
                switchArgv = TclList.getElements(interp, argv[i]);
                i          = 0;
            }
            else
            {
                switchArgv = argv;
            }

            for (; i < switchArgv.Length; i += 2)
            {
                if (i == (switchArgv.Length - 1))
                {
                    throw new TclException(interp, "extra switch pattern with no body");
                }

                // See if the pattern matches the string.

                matched = false;

                string pattern = switchArgv[i].ToString();

                if ((i == switchArgv.Length - 2) && pattern.Equals("default"))
                {
                    matched = true;
                }
                else
                {
                    switch (mode)
                    {
                    case EXACT:
                        matched = inString.Equals(pattern);
                        break;

                    case GLOB:
                        matched = Util.StringMatch(inString, pattern);
                        break;

                    case REGEXP:
                        matched = Util.regExpMatch(interp, inString, switchArgv[i]);
                        break;
                    }
                }
                if (!matched)
                {
                    continue;
                }

                // We've got a match.  Find a body to execute, skipping bodies
                // that are "-".

                for (body = i + 1; ; body += 2)
                {
                    if (body >= switchArgv.Length)
                    {
                        throw new TclException(interp, "no body specified for pattern \"" + switchArgv[i] + "\"");
                    }

                    if (!switchArgv[body].ToString().Equals("-"))
                    {
                        break;
                    }
                }

                try
                {
                    interp.Eval(switchArgv[body], 0);
                    return(TCL.CompletionCode.RETURN);
                }
                catch (TclException e)
                {
                    if (e.GetCompletionCode() == TCL.CompletionCode.ERROR)
                    {
                        interp.AddErrorInfo("\n    (\"" + switchArgv[i] + "\" arm line " + interp._errorLine + ")");
                    }
                    throw;
                }
            }

            // Nothing matched:  return nothing.
            return(TCL.CompletionCode.RETURN);
        }
Пример #15
0
        internal static string pkgRequire(Interp interp, string pkgName, string version, bool exact)
        {
            VersionSatisfiesResult vsres;
            Package       pkg;
            PkgAvail      avail, best;
            string        script;
            StringBuilder sbuf;
            int           pass, result;

            // Do extra check to make sure that version is not
            // null when the exact flag is set to true.

            if ((System.Object)version == null && exact)
            {
                throw new TclException(interp, "conflicting arguments : version == null and exact == true");
            }

            // Before we can compare versions the version string
            // must be verified but if it is null we are just looking
            // for the latest version so skip the check in this case.

            if ((System.Object)version != null)
            {
                checkVersion(interp, version);
            }

            // It can take up to three passes to find the package:  one pass to
            // run the "package unknown" script, one to run the "package ifneeded"
            // script for a specific version, and a final pass to lookup the
            // package loaded by the "package ifneeded" script.

            vsres = new VersionSatisfiesResult();
            for (pass = 1; ; pass++)
            {
                pkg = findPackage(interp, pkgName);
                if ((System.Object)pkg.version != null)
                {
                    break;
                }

                // The package isn't yet present.  Search the list of available
                // versions and invoke the script for the best available version.

                best = null;
                for (avail = pkg.avail; avail != null; avail = avail.next)
                {
                    if ((best != null) && (compareVersions(avail.version, best.version, null) <= 0))
                    {
                        continue;
                    }
                    if ((System.Object)version != null)
                    {
                        result = compareVersions(avail.version, version, vsres);
                        if ((result != 0) && exact)
                        {
                            continue;
                        }
                        if (!vsres.satisfies)
                        {
                            continue;
                        }
                    }
                    best = avail;
                }
                if (best != null)
                {
                    // We found an ifneeded script for the package.  Be careful while
                    // executing it:  this could cause reentrancy, so (a) protect the
                    // script itself from deletion and (b) don't assume that best
                    // will still exist when the script completes.

                    script = best.script;
                    try
                    {
                        interp.Eval(script, TCL.EVAL_GLOBAL);
                    }
                    catch (TclException e)
                    {
                        interp.AddErrorInfo("\n    (\"package ifneeded\" script)");

                        // Throw the error with new info added to errorInfo.

                        throw;
                    }
                    interp.ResetResult();
                    pkg = findPackage(interp, pkgName);
                    break;
                }

                // Package not in the database.  If there is a "package unknown"
                // command, invoke it (but only on the first pass;  after that,
                // we should not get here in the first place).

                if (pass > 1)
                {
                    break;
                }
                script = interp._packageUnknown;
                if ((System.Object)script != null)
                {
                    sbuf = new StringBuilder();
                    try
                    {
                        Util.appendElement(interp, sbuf, script);
                        Util.appendElement(interp, sbuf, pkgName);
                        if ((System.Object)version == null)
                        {
                            Util.appendElement(interp, sbuf, "");
                        }
                        else
                        {
                            Util.appendElement(interp, sbuf, version);
                        }
                        if (exact)
                        {
                            Util.appendElement(interp, sbuf, "-exact");
                        }
                    }
                    catch (TclException e)
                    {
                        throw new TclRuntimeError("unexpected TclException: " + e.Message);
                    }
                    try
                    {
                        interp.Eval(sbuf.ToString(), TCL.EVAL_GLOBAL);
                    }
                    catch (TclException e)
                    {
                        interp.AddErrorInfo("\n    (\"package unknown\" script)");

                        // Throw the first exception.

                        throw;
                    }
                    interp.ResetResult();
                }
            }
            if ((System.Object)pkg.version == null)
            {
                sbuf = new StringBuilder();
                sbuf.Append("can't find package " + pkgName);
                if ((System.Object)version != null)
                {
                    sbuf.Append(" " + version);
                }
                throw new TclException(interp, sbuf.ToString());
            }

            // At this point we know that the package is present.  Make sure that the
            // provided version meets the current requirement.

            if ((System.Object)version == null)
            {
                return(pkg.version);
            }

            result = compareVersions(pkg.version, version, vsres);
            if ((vsres.satisfies && !exact) || (result == 0))
            {
                return(pkg.version);
            }

            // If we have a version conflict we throw a TclException.

            throw new TclException(interp, "version conflict for package \"" + pkgName + "\": have " + pkg.version + ", need " + version);
        }
Пример #16
0
        /// <summary> This procedure is invoked to process the "subst" Tcl command.
        /// See the user documentation for details on what it does.
        ///
        /// </summary>
        /// <param name="interp">the current interpreter.
        /// </param>
        /// <param name="argv">command arguments.
        /// </param>
        /// <exception cref=""> TclException if wrong # of args or invalid argument(s).
        /// </exception>

        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv)
        {
            int           currentObjIndex, len, i;
            int           objc          = argv.Length - 1;
            bool          doBackslashes = true;
            bool          doCmds        = true;
            bool          doVars        = true;
            StringBuilder result        = new StringBuilder();
            string        s;
            char          c;

            for (currentObjIndex = 1; currentObjIndex < objc; currentObjIndex++)
            {
                if (!argv[currentObjIndex].ToString().StartsWith("-"))
                {
                    break;
                }
                int opt = TclIndex.Get(interp, argv[currentObjIndex], validCmds, "switch", 0);
                switch (opt)
                {
                case OPT_NOBACKSLASHES:
                    doBackslashes = false;
                    break;

                case OPT_NOCOMMANDS:
                    doCmds = false;
                    break;

                case OPT_NOVARS:
                    doVars = false;
                    break;

                default:
                    throw new TclException(interp, "SubstCmd.cmdProc: bad option " + opt + " index to cmds");
                }
            }
            if (currentObjIndex != objc)
            {
                throw new TclNumArgsException(interp, currentObjIndex, argv, "?-nobackslashes? ?-nocommands? ?-novariables? string");
            }

            /*
             * Scan through the string one character at a time, performing
             * command, variable, and backslash substitutions.
             */


            s   = argv[currentObjIndex].ToString();
            len = s.Length;
            i   = 0;
            while (i < len)
            {
                c = s[i];

                if ((c == '[') && doCmds)
                {
                    ParseResult res;
                    try
                    {
                        interp._evalFlags = Parser.TCL_BRACKET_TERM;
                        interp.Eval(s.Substring(i + 1, (len) - (i + 1)));
                        TclObject interp_result = interp.GetResult();
                        interp_result.Preserve();
                        res = new ParseResult(interp_result, i + interp._termOffset);
                    }
                    catch (TclException e)
                    {
                        i = e.errIndex + 1;
                        throw;
                    }
                    i = res.nextIndex + 2;

                    result.Append(res.Value.ToString());
                    res.Release();
                }
                else if (c == '\r')
                {
                    /*
                     * (ToDo) may not be portable on Mac
                     */

                    i++;
                }
                else if ((c == '$') && doVars)
                {
                    ParseResult vres = Parser.parseVar(interp, s.Substring(i, (len) - (i)));
                    i += vres.nextIndex;

                    result.Append(vres.Value.ToString());
                    vres.Release();
                }
                else if ((c == '\\') && doBackslashes)
                {
                    BackSlashResult bs = Tcl.Lang.Interp.backslash(s, i, len);
                    i = bs.NextIndex;
                    if (bs.IsWordSep)
                    {
                        break;
                    }
                    else
                    {
                        result.Append(bs.C);
                    }
                }
                else
                {
                    result.Append(c);
                    i++;
                }
            }

            interp.SetResult(result.ToString());
            return(TCL.CompletionCode.RETURN);
        }
Пример #17
0
        /// <summary> Executes a "case" statement. See Tcl user
        /// documentation for details.
        ///
        /// </summary>
        /// <param name="interp">the current interpreter.
        /// </param>
        /// <param name="argv">command arguments.
        /// </param>
        /// <exception cref=""> TclException If incorrect number of arguments.
        /// </exception>

        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv)
        {
            if (argv.Length < 3)
            {
                throw new TclNumArgsException(interp, 1, argv, "string ?in? patList body ... ?default body?");
            }

            int i;
            int body;

            TclObject[] caseArgv;
            string      inString;


            inString = argv[1].ToString();
            caseArgv = argv;
            body     = -1;


            if (argv[2].ToString().Equals("in"))
            {
                i = 3;
            }
            else
            {
                i = 2;
            }

            /*
             * If all of the pattern/command pairs are lumped into a single
             * argument, split them out again.
             */

            if (argv.Length - i == 1)
            {
                caseArgv = TclList.getElements(interp, argv[i]);
                i        = 0;
            }

            {
                for (; i < caseArgv.Length; i += 2)
                {
                    int j;

                    if (i == (caseArgv.Length - 1))
                    {
                        throw new TclException(interp, "extra case pattern with no body");
                    }

                    /*
                     * Check for special case of single pattern (no list) with
                     * no backslash sequences.
                     */


                    string caseString = caseArgv[i].ToString();
                    int    len        = caseString.Length;
                    for (j = 0; j < len; j++)
                    {
                        char c = caseString[j];
                        if (System.Char.IsWhiteSpace(c) || (c == '\\'))
                        {
                            break;
                        }
                    }
                    if (j == len)
                    {
                        if (caseString.Equals("default"))
                        {
                            body = i + 1;
                        }
                        if (Util.StringMatch(inString, caseString))
                        {
                            body = i + 1;
                            goto match_loop_brk;
                        }
                        continue;
                    }

                    /*
                     * Break up pattern lists, then check each of the patterns
                     * in the list.
                     */

                    int numPats = TclList.getLength(interp, caseArgv[i]);
                    for (j = 0; j < numPats; j++)
                    {
                        if (Util.StringMatch(inString, TclList.index(interp, caseArgv[i], j).ToString()))
                        {
                            body = i + 1;
                            goto match_loop_brk;
                        }
                    }
                }
            }

match_loop_brk:
            ;


            if (body != -1)
            {
                try
                {
                    interp.Eval(caseArgv[body], 0);
                }
                catch (TclException e)
                {
                    if (e.GetCompletionCode() == TCL.CompletionCode.ERROR)
                    {
                        interp.AddErrorInfo("\n    (\"" + caseArgv[body - 1] + "\" arm line " + interp._errorLine + ")");
                    }
                    throw;
                }
            }
            return(TCL.CompletionCode.RETURN);
        }
Пример #18
0
        /// <summary> Tcl_ForeachObjCmd -> ForeachCmd.cmdProc
        ///
        /// This procedure is invoked to process the "foreach" Tcl command.
        /// See the user documentation for details on what it does.
        ///
        /// </summary>
        /// <param name="interp">the current interpreter.
        /// </param>
        /// <param name="objv">command arguments.
        /// </param>
        /// <exception cref=""> TclException if script causes error.
        /// </exception>

        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] objv)
        {
            if (objv.Length < 4 || (objv.Length % 2) != 0)
            {
                throw new TclNumArgsException(interp, 1, objv, "varList list ?varList list ...? command");
            }

            // foreach {n1 n2} {1 2 3 4} {n3} {1 2} {puts $n1-$n2-$n3}
            //	name[0] = {n1 n2}	value[0] = {1 2 3 4}
            //	name[1] = {n3}		value[0] = {1 2}

            TclObject[] name  = new TclObject[(objv.Length - 2) / 2];
            TclObject[] value = new TclObject[(objv.Length - 2) / 2];

            int       c, i, j, base_;
            int       maxIter = 0;
            TclObject command = objv[objv.Length - 1];
            bool      done    = false;

            for (i = 0; i < objv.Length - 2; i += 2)
            {
                int x = i / 2;
                name[x]  = objv[i + 1];
                value[x] = objv[i + 2];

                int nSize = TclList.getLength(interp, name[x]);
                int vSize = TclList.getLength(interp, value[x]);

                if (nSize == 0)
                {
                    throw new TclException(interp, "foreach varlist is empty");
                }

                int iter = (vSize + nSize - 1) / nSize;
                if (maxIter < iter)
                {
                    maxIter = iter;
                }
            }

            for (c = 0; !done && c < maxIter; c++)
            {
                // Set up the variables

                for (i = 0; i < objv.Length - 2; i += 2)
                {
                    int x     = i / 2;
                    int nSize = TclList.getLength(interp, name[x]);
                    base_ = nSize * c;
                    for (j = 0; j < nSize; j++)
                    {
                        // Test and see if the name variable is an array.


                        Var[] result = Var.LookupVar(interp, name[x].ToString(), null, 0, null, false, false);
                        Var   var    = null;

                        if (result != null)
                        {
                            if (result[1] != null)
                            {
                                var = result[1];
                            }
                            else
                            {
                                var = result[0];
                            }
                        }

                        try
                        {
                            if (base_ + j >= TclList.getLength(interp, value[x]))
                            {
                                interp.SetVar(TclList.index(interp, name[x], j), TclString.NewInstance(""), 0);
                            }
                            else
                            {
                                interp.SetVar(TclList.index(interp, name[x], j), TclList.index(interp, value[x], base_ + j), 0);
                            }
                        }
                        catch (TclException e)
                        {
                            throw new TclException(interp, "couldn't set loop variable: \"" + TclList.index(interp, name[x], j) + "\"");
                        }
                    }
                }

                // Execute the script

                try
                {
                    interp.Eval(command, 0);
                }
                catch (TclException e)
                {
                    switch (e.GetCompletionCode())
                    {
                    case TCL.CompletionCode.BREAK:
                        done = true;
                        break;


                    case TCL.CompletionCode.CONTINUE:
                        continue;


                    case TCL.CompletionCode.ERROR:
                        interp.AddErrorInfo("\n    (\"foreach\" body line " + interp._errorLine + ")");
                        throw;


                    default:
                        throw;
                    }
                }
            }

            interp.ResetResult();
            return(TCL.CompletionCode.RETURN);
        }