Exemplo n.º 1
0
        /// <summary> Creates an exception with the appropiate Tcl error message to
        /// indicate an error with variable access.
        /// 
        /// </summary>
        /// <param name="interp">currrent interpreter.
        /// </param>
        /// <param name="name1">first part of a variable name.
        /// </param>
        /// <param name="name2">second part of a variable name. May be null.
        /// </param>
        /// <param name="operation">either "read" or "set".
        /// </param>
        /// <param name="reason">a string message to explain why the operation fails..
        /// </param>

        internal TclVarException(Interp interp, string name1, string name2, string operation, string reason)
            : base(TCL.CompletionCode.ERROR)
        {
            if (interp != null)
            {
                interp.ResetResult();
                if ((System.Object)name2 == null)
                {
                    interp.SetResult("can't " + operation + " \"" + name1 + "\": " + reason);
                }
                else
                {
                    interp.SetResult("can't " + operation + " \"" + name1 + "(" + name2 + ")\": " + reason);
                }
            }
        }
Exemplo n.º 2
0
        /// <summary> See Tcl user documentation for details.</summary>
        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv)
        {
            string sep = null;

            if (argv.Length == 2)
            {
                sep = null;
            }
            else if (argv.Length == 3)
            {

                sep = argv[2].ToString();
            }
            else
            {
                throw new TclNumArgsException(interp, 1, argv, "list ?joinString?");
            }
            TclObject list = argv[1];
            int size = TclList.getLength(interp, list);

            if (size == 0)
            {
                interp.ResetResult();
                return TCL.CompletionCode.RETURN;
            }


            StringBuilder sbuf = new StringBuilder(TclList.index(interp, list, 0).ToString());

            for (int i = 1; i < size; i++)
            {
                if ((System.Object)sep == null)
                {
                    sbuf.Append(' ');
                }
                else
                {
                    sbuf.Append(sep);
                }

                sbuf.Append(TclList.index(interp, list, i).ToString());
            }
            interp.SetResult(sbuf.ToString());
            return TCL.CompletionCode.RETURN;
        }
Exemplo n.º 3
0
        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv)
        {
            int flags;

            if (argv.Length == 1)
            {
                flags = TCL.ALL_EVENTS | TCL.DONT_WAIT;
            }
            else if (argv.Length == 2)
            {
                TclIndex.Get(interp, argv[1], validOpts, "option", 0);

                /*
                * Since we just have one valid option, if the above call returns
                * without an exception, we've got "idletasks" (or abreviations).
                */

                flags = TCL.IDLE_EVENTS | TCL.DONT_WAIT;
            }
            else
            {
                throw new TclNumArgsException(interp, 1, argv, "?idletasks?");
            }

            while (interp.GetNotifier().doOneEvent(flags) != 0)
            {
                /* Empty loop body */
            }

            /*
            * Must clear the interpreter's result because event handlers could
            * have executed commands.
            */

            interp.ResetResult();
            return TCL.CompletionCode.RETURN;
        }
Exemplo n.º 4
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;
        }
Exemplo n.º 5
0
        /// <summary> 
        /// Tcl_LappendObjCmd -> LappendCmd.cmdProc
        /// 
        /// This procedure is invoked to process the "lappend" Tcl command.
        /// See the user documentation for details on what it does.
        /// </summary>

        public TCL.CompletionCode CmdProc(Interp interp, TclObject[] objv)
        {
            TclObject varValue, newValue = null;
            int i;//int numElems, i, j;
            bool createdNewObj, createVar;

            if (objv.Length < 2)
            {
                throw new TclNumArgsException(interp, 1, objv, "varName ?value value ...?");
            }
            if (objv.Length == 2)
            {
                try
                {
                    newValue = interp.GetVar(objv[1], 0);
                }
                catch (TclException e)
                {
                    // The variable doesn't exist yet. Just create it with an empty
                    // initial value.
                    varValue = TclList.NewInstance();

                    try
                    {
                        newValue = interp.SetVar(objv[1], varValue, 0);
                    }
                    finally
                    {
                        if (newValue == null)
                            varValue.Release(); // free unneeded object
                    }

                    interp.ResetResult();
                    return TCL.CompletionCode.RETURN;
                }
            }
            else
            {
                // We have arguments to append. We used to call Tcl_SetVar2 to
                // append each argument one at a time to ensure that traces were run
                // for each append step. We now append the arguments all at once
                // because it's faster. Note that a read trace and a write trace for
                // the variable will now each only be called once. Also, if the
                // variable's old value is unshared we modify it directly, otherwise
                // we create a new copy to modify: this is "copy on write".

                createdNewObj = false;
                createVar = true;

                try
                {
                    varValue = interp.GetVar(objv[1], 0);
                }
                catch (TclException e)
                {
                    // We couldn't read the old value: either the var doesn't yet
                    // exist or it's an array element. If it's new, we will try to
                    // create it with Tcl_ObjSetVar2 below.

                    // FIXME : not sure we even need this parse for anything!
                    // If we do not need to parse could we at least speed it up a bit

                    string varName;
                    int nameBytes;


                    varName = objv[1].ToString();
                    nameBytes = varName.Length; // Number of Unicode chars in string

                    for (i = 0; i < nameBytes; i++)
                    {
                        if (varName[i] == '(')
                        {
                            i = nameBytes - 1;
                            if (varName[i] == ')')
                            {
                                // last char is ')' => array ref
                                createVar = false;
                            }
                            break;
                        }
                    }
                    varValue = TclList.NewInstance();
                    createdNewObj = true;
                }

                // We only take this branch when the catch branch was not run
                if (createdNewObj == false && varValue.Shared)
                {
                    varValue = varValue.duplicate();
                    createdNewObj = true;
                }

                // Insert the new elements at the end of the list.

                for (i = 2; i < objv.Length; i++)
                    TclList.Append(interp, varValue, objv[i]);

                // No need to call varValue.invalidateStringRep() since it
                // is called during the TclList.append operation.

                // Now store the list object back into the variable. If there is an
                // error setting the new value, decrement its ref count if it
                // was new and we didn't create the variable.

                try
                {

                    newValue = interp.SetVar(objv[1].ToString(), varValue, 0);
                }
                catch (TclException e)
                {
                    if (createdNewObj && !createVar)
                    {
                        varValue.Release(); // free unneeded obj
                    }
                    throw;
                }
            }

            // Set the interpreter's object result to refer to the variable's value
            // object.

            interp.SetResult(newValue);
            return TCL.CompletionCode.RETURN;
        }
Exemplo n.º 6
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;
        }
Exemplo n.º 7
0
        internal void transferResult(Interp sourceInterp, TCL.CompletionCode result)
        {
            if (sourceInterp == this)
            {
                return;
            }

            if (result == TCL.CompletionCode.ERROR)
            {
                TclObject obj;

                // An error occurred, so transfer error information from the source
                // interpreter to the target interpreter.  Setting the flags tells
                // the target interp that it has inherited a partial traceback
                // chain, not just a simple error message.

                if (!sourceInterp._errAlreadyLogged)
                {
                    sourceInterp.AddErrorInfo("");
                }
                sourceInterp._errAlreadyLogged = true;

                ResetResult();

                obj = sourceInterp.GetVar("errorInfo", TCL.VarFlag.GLOBAL_ONLY);
                SetVar("errorInfo", obj, TCL.VarFlag.GLOBAL_ONLY);

                obj = sourceInterp.GetVar("errorCode", TCL.VarFlag.GLOBAL_ONLY);
                SetVar("errorCode", obj, TCL.VarFlag.GLOBAL_ONLY);

                _errInProgress = true;
                _errCodeSet = true;
            }

            _returnCode = result;
            SetResult(sourceInterp.GetResult());
            sourceInterp.ResetResult();

            if (result != TCL.CompletionCode.OK)
            {

                throw new TclException(this, GetResult().ToString(), result);
            }
        }