示例#1
0
        ///////////////////////////////////////////////////////////////////////

        #region IExecute Members
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            if (interpreter == null)
            {
                result = "invalid interpreter";
                return(ReturnCode.Error);
            }

            if (arguments == null)
            {
                result = "invalid argument list";
                return(ReturnCode.Error);
            }

            if (arguments.Count < 2)
            {
                result = "wrong # args: should be \"source ?options? fileName\"";
                return(ReturnCode.Error);
            }

            ReturnCode code = ReturnCode.Ok;

            OptionDictionary options = new OptionDictionary(
                new IOption[] {
                new Option(null, OptionFlags.MustHaveEncodingValue,
                           Index.Invalid, Index.Invalid, "-encoding", null),
                new Option(null, OptionFlags.MustHaveBooleanValue,
                           Index.Invalid, Index.Invalid, "-withinfo", null),
                new Option(null, OptionFlags.None, Index.Invalid,
                           Index.Invalid, Option.EndOfOptions, null)
            });

            int argumentIndex = Index.Invalid;

            if (arguments.Count > 2)
            {
                if (interpreter.GetOptions(
                        options, arguments, 0, 1, Index.Invalid, false,
                        ref argumentIndex, ref result) != ReturnCode.Ok)
                {
                    return(ReturnCode.Error);
                }
            }
            else
            {
                argumentIndex = 1;
            }

            if ((argumentIndex == Index.Invalid) ||
                ((argumentIndex + 1) != arguments.Count))
            {
                if ((argumentIndex != Index.Invalid) &&
                    Option.LooksLikeOption(arguments[argumentIndex]))
                {
                    result = OptionDictionary.BadOption(
                        options, arguments[argumentIndex]);
                }
                else
                {
                    result = "wrong # args: should be \"source ?options? fileName\"";
                }

                return(ReturnCode.Error);
            }

            Variant  value    = null;
            Encoding encoding = null;

            if (options.IsPresent("-encoding", ref value))
            {
                encoding = (Encoding)value.Value;
            }

            bool withInfo = false;

            if (options.IsPresent("-withinfo", ref value))
            {
                withInfo = (bool)value.Value;
            }

            if (code == ReturnCode.Ok)
            {
                string name = StringList.MakeList(
                    "source", arguments[argumentIndex]);

                ICallFrame frame = interpreter.NewTrackingCallFrame(
                    name, CallFrameFlags.Source);

                interpreter.PushAutomaticCallFrame(frame);

                try
                {
#if ARGUMENT_CACHE
                    CacheFlags savedCacheFlags = CacheFlags.None;

                    if (withInfo)
                    {
                        interpreter.BeginNoArgumentCache(
                            ref savedCacheFlags);
                    }

                    try
                    {
#endif
#if DEBUGGER && BREAKPOINTS
                    InterpreterFlags savedInterpreterFlags =
                        InterpreterFlags.None;

                    if (withInfo)
                    {
                        interpreter.BeginArgumentLocation(
                            ref savedInterpreterFlags);
                    }

                    try
                    {
#endif

                    code = interpreter.EvaluateFile(
                        encoding, arguments[argumentIndex],
                        ref result);
#if DEBUGGER && BREAKPOINTS
                }
                finally
                {
                    if (withInfo)
                    {
                        interpreter.EndArgumentLocation(
                            ref savedInterpreterFlags);
                    }
                }
#endif
#if ARGUMENT_CACHE
                }
                finally
                {
                    if (withInfo)
                    {
                        interpreter.EndNoArgumentCache(
                            ref savedCacheFlags);
                    }
                }
#endif
                }
                finally
                {
                    //
                    // NOTE: Pop the original call frame that we pushed above
                    //       and any intervening scope call frames that may be
                    //       leftover (i.e. they were not explicitly closed).
                    //
                    /* IGNORED */
                    interpreter.PopScopeCallFramesAndOneMore();
                }
            }

            return(code);
        }
示例#2
0
文件: Subst.cs 项目: jdruin/F5Eagle
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            ReturnCode code;

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    if (arguments.Count >= 2)
                    {
                        OptionDictionary options = new OptionDictionary(
                            new IOption[] {
                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-nobackslashes", null),
                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-nocommands", null),
                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-novariables", 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))
                            {
                                SubstitutionFlags substitutionFlags = SubstitutionFlags.Default;

                                if (options.IsPresent("-nobackslashes"))
                                {
                                    substitutionFlags &= ~SubstitutionFlags.Backslashes;
                                }

                                if (options.IsPresent("-nocommands"))
                                {
                                    substitutionFlags &= ~SubstitutionFlags.Commands;
                                }

                                if (options.IsPresent("-novariables"))
                                {
                                    substitutionFlags &= ~SubstitutionFlags.Variables;
                                }

                                string name = StringList.MakeList("subst");

                                ICallFrame frame = interpreter.NewTrackingCallFrame(name,
                                                                                    CallFrameFlags.Substitute);

                                interpreter.PushAutomaticCallFrame(frame);

                                code = interpreter.SubstituteString(
                                    arguments[argumentIndex], substitutionFlags, ref result);

                                if (code == ReturnCode.Error)
                                {
                                    Engine.AddErrorInformation(interpreter, result,
                                                               String.Format("{0}    (\"subst\" body line {1})",
                                                                             Environment.NewLine, Interpreter.GetErrorLine(interpreter)));
                                }

                                //
                                // NOTE: Pop the original call frame that we pushed above and
                                //       any intervening scope call frames that may be leftover
                                //       (i.e. they were not explicitly closed).
                                //
                                /* IGNORED */
                                interpreter.PopScopeCallFramesAndOneMore();
                            }
                            else
                            {
                                if ((argumentIndex != Index.Invalid) &&
                                    Option.LooksLikeOption(arguments[argumentIndex]))
                                {
                                    result = OptionDictionary.BadOption(options, arguments[argumentIndex]);
                                }
                                else
                                {
                                    result = "wrong # args: should be \"subst ?-nobackslashes? ?-nocommands? ?-novariables? string\"";
                                }

                                code = ReturnCode.Error;
                            }
                        }
                    }
                    else
                    {
                        result = "wrong # args: should be \"subst ?-nobackslashes? ?-nocommands? ?-novariables? string\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
示例#3
0
        ///////////////////////////////////////////////////////////////////////

        #region IExecute Members
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            if (targetInterpreter == null)
            {
                result = "invalid interpreter";
                return(ReturnCode.Error);
            }

            ReturnCode   code;
            string       targetName      = null;
            ArgumentList targetArguments = null;

            code = targetInterpreter.GetAliasArguments(
                this, arguments, ref targetName, ref targetArguments,
                ref result);

            if (code == ReturnCode.Ok)
            {
                //
                // NOTE: Grab the target of the alias (this will be null if we
                //       are late-bound).
                //
                IExecute target     = null;
                bool     useUnknown = false;

                code = targetInterpreter.GetAliasTarget(this, targetName,
                                                        targetArguments, LookupFlags.Default, true, ref target,
                                                        ref useUnknown, ref result);

                //
                // NOTE: Do we have a valid target now (we may have already had
                //       one or we may have just succeeded in looking it up)?
                //
                if (code == ReturnCode.Ok)
                {
                    //
                    // NOTE: Create and push a new call frame to track the
                    //       activation of this alias.
                    //
                    string name = StringList.MakeList("alias", this.Name);

                    AliasFlags aliasFlags = this.AliasFlags;

                    ICallFrame frame = interpreter.NewTrackingCallFrame(name,
                                                                        CallFrameFlags.Alias);

                    interpreter.PushAutomaticCallFrame(frame);

                    ///////////////////////////////////////////////////////////

                    bool targetUsable;

                    if (useUnknown)
                    {
                        targetInterpreter.EnterUnknownLevel();
                    }

                    try
                    {
                        if (FlagOps.HasFlags(
                                aliasFlags, AliasFlags.Evaluate, true))
                        {
                            code = targetInterpreter.EvaluateScript(
                                targetArguments, 0, ref result);
                        }
                        else
                        {
                            //
                            // NOTE: Save the current engine flags and then
                            //       enable the external execution flags.
                            //
                            EngineFlags savedEngineFlags =
                                targetInterpreter.BeginExternalExecution();

                            code = targetInterpreter.Execute(
                                targetName, target, clientData,
                                targetArguments, ref result);

                            //
                            // NOTE: Restore the saved engine flags, masking
                            //       off the external execution flags as
                            //       necessary.
                            //
                            /* IGNORED */
                            targetInterpreter.EndAndCleanupExternalExecution(
                                savedEngineFlags);
                        }
                    }
                    finally
                    {
                        targetUsable = Engine.IsUsable(targetInterpreter);

                        if (useUnknown && targetUsable)
                        {
                            targetInterpreter.ExitUnknownLevel();
                        }
                    }

                    ///////////////////////////////////////////////////////////

                    //
                    // NOTE: Pop the original call frame that we pushed above
                    //       and any intervening scope call frames that may be
                    //       leftover (i.e. they were not explicitly closed).
                    //
                    /* IGNORED */
                    interpreter.PopScopeCallFramesAndOneMore();
                }
            }

            return(code);
        }
示例#4
0
        private void DoShowLocals()
        {
            ICallFrame[] frames;
            frames = dbg.GetCallFrames();
            int stackItems;

            if (frames.Length == 0)
            {
                io.PutString("No call frame.\n");
                stackItems = dbg.StackDepth;
            }
            else
            {
                ICallFrame cf = frames[0];
                if (cf.Locals.Length == 0)
                {
                    io.PutString("No local variables.\n");
                }
                else
                {
                    io.PutString(string.Format("{0} local variable{1}:\n",
                                               cf.Locals.Length,
                                               cf.Locals.Length == 1 ? "" : "s"));

                    var rtn = zm.DebugInfo != null?zm.DebugInfo.FindRoutine(dbg.CurrentPC) : null;

                    for (int i = 0; i < cf.Locals.Length; i++)
                    {
                        io.PutString("    ");
                        if (rtn != null && i < rtn.Locals.Length)
                        {
                            io.PutString(rtn.Locals[i]);
                        }
                        else
                        {
                            io.PutString(string.Format("local_{0}", i + 1));
                        }
                        io.PutString(string.Format(" = {0} (${0:x4})\n", cf.Locals[i]));
                    }
                }
                stackItems = dbg.StackDepth - cf.PrevStackDepth;
            }
            if (stackItems == 0)
            {
                io.PutString("No data on stack.\n");
            }
            else
            {
                io.PutString(string.Format("{0} word{1} on stack:\n",
                                           stackItems,
                                           stackItems == 1 ? "" : "s"));
                Stack <short> temp = new Stack <short>();
                for (int i = 0; i < stackItems; i++)
                {
                    short value = dbg.StackPop();
                    temp.Push(value);
                    io.PutString(string.Format("    ${0:x4} (${0})\n", value));
                }
                while (temp.Count > 0)
                {
                    dbg.StackPush(temp.Pop());
                }
            }
        }
示例#5
0
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            ReturnCode code;

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    if (arguments.Count >= 2)
                    {
                        string name = StringList.MakeList("eval");

                        ICallFrame frame = interpreter.NewTrackingCallFrame(name,
                                                                            CallFrameFlags.Evaluate);

                        interpreter.PushAutomaticCallFrame(frame);

                        if (arguments.Count == 2)
                        {
                            code = interpreter.EvaluateScript(arguments[1], ref result);
                        }
                        else
                        {
                            code = interpreter.EvaluateScript(arguments, 1, ref result);
                        }

                        if (code == ReturnCode.Error)
                        {
                            Engine.AddErrorInformation(interpreter, result,
                                                       String.Format("{0}    (\"eval\" body line {1})",
                                                                     Environment.NewLine, Interpreter.GetErrorLine(interpreter)));
                        }

                        //
                        // NOTE: Pop the original call frame that we pushed above and
                        //       any intervening scope call frames that may be leftover
                        //       (i.e. they were not explicitly closed).
                        //
                        /* IGNORED */
                        interpreter.PopScopeCallFramesAndOneMore();
                    }
                    else
                    {
                        result = "wrong # args: should be \"eval arg ?arg ...?\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
示例#6
0
文件: Upvar.cs 项目: jdruin/F5Eagle
        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)
                    {
                        ICallFrame otherFrame = null;

                        FrameResult frameResult = interpreter.GetCallFrame(
                            arguments[1], ref otherFrame, ref result);

                        if (frameResult != FrameResult.Invalid)
                        {
                            int count = arguments.Count - ((int)frameResult + 1);

                            if ((count & 1) == 0)
                            {
                                lock (interpreter.SyncRoot) /* TRANSACTIONAL */
                                {
                                    ICallFrame localFrame = null;

                                    code = interpreter.GetVariableFrameViaResolvers(
                                        LookupFlags.Default, ref localFrame, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        int argumentIndex = ((int)frameResult + 1); // skip "upvar ?level?"

                                        for (; count > 0; count -= 2, argumentIndex += 2)
                                        {
                                            string otherName = arguments[argumentIndex];
                                            string localName = arguments[argumentIndex + 1];

                                            code = ScriptOps.LinkVariable(
                                                interpreter, localFrame, localName,
                                                otherFrame, otherName, ref result);

                                            if (code != ReturnCode.Ok)
                                            {
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                result = "wrong # args: should be \"upvar ?level? otherVar localVar ?otherVar localVar ...?\"";
                                code   = ReturnCode.Error;
                            }
                        }
                        else
                        {
                            code = ReturnCode.Error;
                        }
                    }
                    else
                    {
                        result = "wrong # args: should be \"upvar ?level? otherVar localVar ?otherVar localVar ...?\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
示例#7
0
        ///////////////////////////////////////////////////////////////////////

        #region IExecute Members
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            if (interpreter == null)
            {
                result = "invalid interpreter";
                return(ReturnCode.Error);
            }

            if (arguments == null)
            {
                result = "invalid argument list";
                return(ReturnCode.Error);
            }

            if ((arguments.Count < 2) || (arguments.Count > 4))
            {
                result = ScriptOps.WrongNumberOfArguments(this, 1,
                                                          arguments, "script ?resultVarName? ?optionsVarName?");

                return(ReturnCode.Error);
            }

            string name = StringList.MakeList(this.Name);

            ICallFrame frame = interpreter.NewTrackingCallFrame(name,
                                                                CallFrameFlags.Catch);

            interpreter.PushAutomaticCallFrame(frame);

            EngineFlags engineFlags = interpreter.EngineFlags;

            if (Engine.HasNoResetError(engineFlags))
            {
                engineFlags |= EngineFlags.ErrorAlreadyLogged;
            }

            ReturnCode code;
            Result     localResult = null;
            int        errorLine   = 0;

            /* IGNORED */
            interpreter.EnterCatchLevel();

            try
            {
                code = interpreter.EvaluateScript(
                    arguments[1], engineFlags, ref localResult,
                    ref errorLine);
            }
            finally
            {
                if (interpreter.ExitCatchLevel() == 0)
                {
                    if (ScriptOps.HasFlags(interpreter,
                                           InterpreterFlags.CatchResetCancel, true))
                    {
                        ReturnCode resetCode;
                        Result     resetError = null;

                        resetCode = Engine.ResetCancel(
                            interpreter, CancelFlags.CatchBlock,
                            ref resetError);

                        if (resetCode != ReturnCode.Ok)
                        {
                            DebugOps.Complain(
                                interpreter, resetCode, resetError);
                        }
                    }

                    if (ScriptOps.HasFlags(interpreter,
                                           InterpreterFlags.CatchResetExit, true))
                    {
                        bool exit = interpreter.Exit;

                        if (exit)
                        {
                            interpreter.Exit = false;
                        }
                    }
                }
            }

            //
            // BUGFIX: Prevent messing up the custom errorInfo from the [error]
            //         command by checking to see if the "error already logged"
            //         flag has been set.
            //
            engineFlags = interpreter.EngineFlags;

            if ((code == ReturnCode.Error) &&
                !Engine.HasErrorAlreadyLogged(engineFlags) &&
                !Engine.HasNoResetError(engineFlags))
            {
                Engine.AddErrorInformation(interpreter, localResult,
                                           String.Format("{0}    (\"catch\" body line {1})",
                                                         Environment.NewLine, errorLine));
            }

            //
            // NOTE: Pop the original call frame that we pushed above and any
            //       intervening scope call frames that may be leftover (i.e.
            //       they were not explicitly closed).
            //
            /* IGNORED */
            interpreter.PopScopeCallFramesAndOneMore();

            //
            // NOTE: The result of this command is the integer conversion of
            //       the return code received from the evaluated script.
            //
            Engine.ResetResult(interpreter, ref result);
            result            = ConversionOps.ToInt(code);
            result.ReturnCode = code; /* NOTE: For ease of use. */

            //
            // NOTE: See if the caller wants to save the result and/or error
            //       message in a variable.
            //
            if (arguments.Count >= 3)
            {
                Result error = null;

                code = interpreter.SetVariableValue(
                    VariableFlags.NoReady, arguments[2], localResult, null,
                    ref error);

                if (code != ReturnCode.Ok)
                {
                    Engine.ResetResult(interpreter, ref result);

                    result = String.Format(
                        "couldn't save command result in variable: {0}",
                        error);

                    return(code);
                }
            }

            //
            // NOTE: See if the caller wants to save the "return options" in a
            //       variable.
            //
            if (arguments.Count >= 4)
            {
                StringList list  = new StringList();
                Result     error = null;

                if (result.ReturnCode == ReturnCode.Return)
                {
                    int level = 0;

                    code = interpreter.GetInfoLevel(
                        null, ref level, ref error);

                    if (code != ReturnCode.Ok)
                    {
                        Engine.ResetResult(interpreter, ref error);

                        result = String.Format(
                            "couldn't get current level: {0}", error);

                        return(code);
                    }

                    list.Add("-code",
                             ((int)interpreter.ReturnCode).ToString());

                    list.Add("-level", level.ToString());
                }
                else
                {
                    list.Add("-code", result.String);
                    list.Add("-level", Value.ZeroString);
                }

                if (result.ReturnCode == ReturnCode.Error)
                {
                    Result     errorCode = null;
                    Result     errorInfo = null;
                    ResultList errors    = null;

                    code = interpreter.CopyErrorInformation(
                        VariableFlags.None, true, ref errorCode, ref errorInfo,
                        ref errors);

                    if (code != ReturnCode.Ok)
                    {
                        Engine.ResetResult(interpreter, ref result);

                        result = errors;
                        return(code);
                    }

                    list.Add("-errorcode", errorCode);
                    list.Add("-errorinfo", errorInfo);
                    list.Add("-errorline", errorLine.ToString());
                }

                code = interpreter.SetVariableValue(
                    VariableFlags.NoReady, arguments[3], list.ToString(), null,
                    ref error);

                if (code != ReturnCode.Ok)
                {
                    Engine.ResetResult(interpreter, ref result);

                    result = String.Format(
                        "couldn't save return options in variable: {0}",
                        error);

                    return(code);
                }
            }

            //
            // NOTE: We are "catching" (masking) the error; therefore, do not
            //       propogate it.
            //
            return(ReturnCode.Ok);
        }
示例#8
0
文件: Global.cs 项目: jdruin/F5Eagle
        ///////////////////////////////////////////////////////////////////////

        #region IExecute Members
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            if (interpreter == null)
            {
                result = "invalid interpreter";
                return(ReturnCode.Error);
            }

            if (arguments == null)
            {
                result = "invalid argument list";
                return(ReturnCode.Error);
            }

            if (arguments.Count < 2)
            {
                result = "wrong # args: should be \"global varName ?varName ...?\"";
                return(ReturnCode.Error);
            }

            ICallFrame localFrame = null;

            if (interpreter.GetVariableFrameViaResolvers(
                    LookupFlags.Default, ref localFrame,
                    ref result) == ReturnCode.Ok)
            {
                if ((localFrame != null) &&
                    !interpreter.IsGlobalCallFrame(localFrame))
                {
                    bool useNamespaces = interpreter.AreNamespacesEnabled();

                    for (int argumentIndex = 1;
                         argumentIndex < arguments.Count;
                         argumentIndex++)
                    {
                        string     varName    = arguments[argumentIndex];
                        ICallFrame otherFrame = interpreter.CurrentGlobalFrame;

                        if (useNamespaces)
                        {
                            string         qualifiers     = null;
                            string         tail           = null;
                            NamespaceFlags namespaceFlags = NamespaceFlags.None;

                            if (NamespaceOps.SplitName(
                                    varName, ref qualifiers, ref tail,
                                    ref namespaceFlags,
                                    ref result) == ReturnCode.Ok)
                            {
                                //
                                // NOTE: For linking between call frames, use
                                //       the simple variable name only.
                                //
                                varName = tail;
                            }
                            else
                            {
                                return(ReturnCode.Error);
                            }

                            if (FlagOps.HasFlags(namespaceFlags,
                                                 NamespaceFlags.Qualified, true))
                            {
                                INamespace @namespace = NamespaceOps.Lookup(
                                    interpreter, qualifiers, false, false,
                                    ref result);

                                if (@namespace != null)
                                {
                                    otherFrame = @namespace.VariableFrame;
                                }
                                else
                                {
                                    return(ReturnCode.Error);
                                }
                            }
                        }

                        if (ScriptOps.LinkVariable(
                                interpreter, localFrame, varName, otherFrame,
                                varName, ref result) != ReturnCode.Ok)
                        {
                            return(ReturnCode.Error);
                        }
                    }

                    result = String.Empty;
                }
                else
                {
                    // already in global scope... this is a NOP.
                    result = String.Empty;
                }

                return(ReturnCode.Ok);
            }
            else
            {
                return(ReturnCode.Error);
            }
        }
示例#9
0
        ///////////////////////////////////////////////////////////////////////

        private /* protected virtual */ void Dispose(
            bool disposing
            )
        {
            if (!disposed)
            {
                if (disposing)
                {
                    ////////////////////////////////////
                    // dispose managed resources here...
                    ////////////////////////////////////

                    if (children != null)
                    {
                        foreach (INamespace child in children.Values)
                        {
                            if (child == null)
                            {
                                continue;
                            }

                            IDisposable disposable = child as IDisposable;

                            if (disposable != null)
                            {
                                disposable.Dispose();
                                disposable = null;
                            }
                        }

                        children.Clear();
                        children = null;
                    }

                    ///////////////////////////////////////////////////////////

                    if (exportNames != null)
                    {
                        exportNames.Clear();
                        exportNames = null;
                    }

                    ///////////////////////////////////////////////////////////

                    if (imports != null)
                    {
                        ReturnCode removeCode;
                        Result     removeError = null;

                        removeCode = RemoveImports(
                            null, false, ref removeError);

                        if (removeCode != ReturnCode.Ok)
                        {
                            DebugOps.Complain(
                                interpreter, removeCode, removeError);
                        }

                        imports.Clear();
                        imports = null;
                    }

                    ///////////////////////////////////////////////////////////

                    if (interpreter != null)
                    {
                        interpreter = null; /* NOT OWNED */
                    }
                    ///////////////////////////////////////////////////////////

                    parent  = null; /* NOT OWNED */
                    resolve = null; /* NOT OWNED */

                    ///////////////////////////////////////////////////////////

                    if (variableFrame != null)
                    {
                        variableFrame.Free(true);
                        variableFrame = null;
                    }

                    ///////////////////////////////////////////////////////////

                    unknown = null;

                    ///////////////////////////////////////////////////////////

                    qualifiedName  = null;
                    referenceCount = 0;
                    deleted        = false;

                    ///////////////////////////////////////////////////////////

                    kind        = IdentifierKind.None;
                    id          = Guid.Empty;
                    name        = null;
                    group       = null;
                    description = null;
                    clientData  = null;
                }

                //////////////////////////////////////
                // release unmanaged resources here...
                //////////////////////////////////////

                disposed = true;
            }
        }
示例#10
0
        ///////////////////////////////////////////////////////////////////////

        #region IExecute Members
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            if (interpreter == null)
            {
                result = "invalid interpreter";
                return(ReturnCode.Error);
            }

            if (arguments == null)
            {
                result = "invalid argument list";
                return(ReturnCode.Error);
            }

            if (arguments.Count < 2)
            {
                result = String.Format(
                    "wrong # args: should be \"{0} option ?arg ...?\"",
                    this.Name);

                return(ReturnCode.Error);
            }

            string subCommand = arguments[1];

            if (!String.Equals(
                    subCommand, this.Name,
                    StringOps.SystemStringComparisonType))
            {
                result = ScriptOps.BadSubCommand(
                    interpreter, null, null, subCommand, this, null, null);

                return(ReturnCode.Error);
            }

            //
            // NOTE: Evaluate the configured script command, maybe
            //       adding all the local arguments, and return the
            //       results verbatim.
            //
            string name = StringList.MakeList(this.Name);

            ICallFrame frame = interpreter.NewTrackingCallFrame(name,
                                                                CallFrameFlags.Evaluate | CallFrameFlags.SubCommand);

            interpreter.PushAutomaticCallFrame(frame);

            ReturnCode code = interpreter.EvaluateScript(
                ScriptOps.GetArgumentsForExecute(this, scriptCommand,
                                                 GetArgumentsForExecute(arguments), 0), 0, ref result);

            if (code == ReturnCode.Error)
            {
                Engine.AddErrorInformation(interpreter, result,
                                           String.Format("{0}    (\"{1}\" body line {2})",
                                                         Environment.NewLine, ScriptOps.GetNameForExecute(
                                                             arguments[0], this), Interpreter.GetErrorLine(
                                                             interpreter)));
            }

            //
            // NOTE: Pop the original call frame that we pushed above and
            //       any intervening scope call frames that may be leftover
            //       (i.e. they were not explicitly closed).
            //
            /* IGNORED */
            interpreter.PopScopeCallFramesAndOneMore();
            return(code);
        }
示例#11
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];
                                    }

                                    if ((arguments.Count < 3) ||
                                        NamespaceOps.IsGlobalName(name))
                                    {
                                        result = String.Empty;
                                        code   = ReturnCode.Ok;
                                    }
                                    else
                                    {
                                        if (NamespaceOps.IsAbsoluteName(name))
                                        {
                                            result = String.Format("namespace \"{0}\" not found", name);
                                        }
                                        else
                                        {
                                            result = String.Format("namespace \"{0}\" not found in \"{1}\"",
                                                                   name, TclVars.GlobalNamespace);
                                        }

                                        code = ReturnCode.Error;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"namespace children ?name? ?pattern?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "code":
                            {
                                if (arguments.Count == 3)
                                {
                                    //
                                    // NOTE: We are always in the global namespace, fake it.
                                    //
                                    result = new StringList(
                                        TclVars.GlobalNamespace + this.Name, "inscope",
                                        TclVars.GlobalNamespace, arguments[2]);

                                    code = ReturnCode.Ok;
                                }
                                else
                                {
                                    result = "wrong # args: should be \"namespace code script\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "current":
                            {
                                if (arguments.Count == 2)
                                {
                                    result = TclVars.GlobalNamespace;
                                    code   = ReturnCode.Ok;
                                }
                                else
                                {
                                    result = "wrong # args: should be \"namespace current\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "delete":
                            {
                                if (arguments.Count >= 2)
                                {
                                    code = ReturnCode.Ok;

                                    for (int index = 2; index < arguments.Count; index++)
                                    {
                                        if (!NamespaceOps.IsGlobalName(arguments[index]))
                                        {
                                            //
                                            // NOTE: We only know about the global namespace; an attempt
                                            //       to delete any other namespace is an error.
                                            //
                                            result = String.Format(
                                                "unknown namespace \"{0}\" in namespace delete command",
                                                arguments[index]);

                                            code = ReturnCode.Error;
                                            break;
                                        }
                                    }

                                    if (code == ReturnCode.Ok)
                                    {
                                        for (int index = 2; index < arguments.Count; /* index++ */)
                                        {
                                            //
                                            // NOTE: Delete the one-and-only namespace (global) now (actually,
                                            //       as soon as the evaluation stack unwinds).
                                            //
                                            code = interpreter.DeleteNamespace(
                                                VariableFlags.None, arguments[index], false, ref result);

                                            //
                                            // NOTE: Since we only know about the global namespace there
                                            //       is no point in attempting to delete it multiple times.
                                            //
                                            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 name = StringList.MakeList("namespace eval", arguments[2]);

                                    ICallFrame frame = interpreter.NewTrackingCallFrame(name,
                                                                                        CallFrameFlags.Namespace | CallFrameFlags.Evaluate);

                                    interpreter.PushAutomaticCallFrame(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, arguments[2], Interpreter.GetErrorLine(interpreter)));
                                    }

                                    //
                                    // NOTE: Pop the original call frame that we pushed above and
                                    //       any intervening scope call frames that may be leftover
                                    //       (i.e. they were not explicitly closed).
                                    //
                                    /* IGNORED */
                                    interpreter.PopScopeCallFramesAndOneMore();
                                }
                                else
                                {
                                    result = "wrong # args: should be \"namespace eval name arg ?arg ...?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "exists":
                            {
                                if (arguments.Count == 3)
                                {
                                    if (NamespaceOps.IsGlobalName(arguments[2]))
                                    {
                                        result = true;
                                    }
                                    else
                                    {
                                        result = false;
                                    }

                                    code = ReturnCode.Ok;
                                }
                                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;
                                    }

                                    //
                                    // NOTE: We do not support importing or exporting of namespace commands
                                    //       because we do not really support namespaces; therefore, we do
                                    //       nothing.
                                    //
                                    if (code == ReturnCode.Ok)
                                    {
                                        result = String.Empty;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"namespace export ?-clear? ?pattern pattern ...?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "forget":
                            {
                                if (arguments.Count >= 2)
                                {
                                    //
                                    // NOTE: We do not support importing or exporting of namespace commands
                                    //       because we do not really support namespaces; therefore, we do
                                    //       nothing.
                                    //
                                    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;
                                    }

                                    //
                                    // NOTE: We do not support importing or exporting of namespace commands
                                    //       because we do not really support namespaces; therefore, we do
                                    //       nothing.
                                    //
                                    if (code == ReturnCode.Ok)
                                    {
                                        result = String.Empty;
                                    }
                                }
                                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)
                                {
                                    if (NamespaceOps.IsGlobalName(arguments[2]))
                                    {
                                        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", arguments[2]);

                                                ICallFrame frame = interpreter.NewTrackingCallFrame(name,
                                                                                                    CallFrameFlags.Namespace | CallFrameFlags.InScope);

                                                interpreter.PushAutomaticCallFrame(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, arguments[2], Interpreter.GetErrorLine(interpreter)));
                                                }

                                                //
                                                // NOTE: Pop the original call frame that we pushed above and
                                                //       any intervening scope call frames that may be leftover
                                                //       (i.e. they were not explicitly closed).
                                                //
                                                /* IGNORED */
                                                interpreter.PopScopeCallFramesAndOneMore();
                                            }
                                        }
                                        else
                                        {
                                            string name = StringList.MakeList("namespace inscope", arguments[2]);

                                            ICallFrame frame = interpreter.NewTrackingCallFrame(name,
                                                                                                CallFrameFlags.Namespace | CallFrameFlags.InScope);

                                            interpreter.PushAutomaticCallFrame(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, arguments[2], Interpreter.GetErrorLine(interpreter)));
                                            }

                                            //
                                            // NOTE: Pop the original call frame that we pushed above and
                                            //       any intervening scope call frames that may be leftover
                                            //       (i.e. they were not explicitly closed).
                                            //
                                            /* IGNORED */
                                            interpreter.PopScopeCallFramesAndOneMore();
                                        }
                                    }
                                    else
                                    {
                                        result = String.Format(
                                            "unknown namespace \"{0}\" in inscope namespace command",
                                            arguments[2]);

                                        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)
                                {
                                    //
                                    // NOTE: We are always in the global namespace, fake it.
                                    //
                                    string name = arguments[2];

                                    if (!NamespaceOps.IsQualifiedName(name))
                                    {
                                        result = NamespaceOps.MakeAbsoluteName(name);
                                        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)
                                {
                                    string   executeName = arguments[2];
                                    IExecute execute     = null;

                                    code = interpreter.GetIExecuteViaResolvers(
                                        interpreter.GetResolveEngineFlags(true),
                                        executeName, null, LookupFlags.Default,
                                        ref execute, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        result = TclVars.GlobalNamespace + executeName;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"namespace origin name\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "parent":
                            {
                                if ((arguments.Count == 2) || (arguments.Count == 3))
                                {
                                    //
                                    // NOTE: Either they did not specify a namespace argument (use current
                                    //       namespace, which is always global and always exists) or they
                                    //       specified a namespace which should be the global one; otherwise,
                                    //       an error is reported because we do not really support namespaces.
                                    //
                                    if ((arguments.Count == 2) ||
                                        NamespaceOps.IsGlobalName(arguments[2]))
                                    {
                                        result = String.Empty;
                                        code   = ReturnCode.Ok;
                                    }
                                    else
                                    {
                                        //
                                        // NOTE: See if they prefixed the argument with "::" to figure out
                                        //       the appropriate error message (Tcl emulation).
                                        //
                                        if (NamespaceOps.IsAbsoluteName(arguments[2]))
                                        {
                                            result = String.Format("namespace \"{0}\" not found", arguments[2]);
                                        }
                                        else
                                        {
                                            result = String.Format("namespace \"{0}\" not found in \"{1}\"",
                                                                   arguments[2], TclVars.GlobalNamespace);
                                        }

                                        code = ReturnCode.Error;
                                    }
                                }
                                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)
                                {
                                    result = "not implemented";
                                    code   = ReturnCode.Error;
                                }
                                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":
                            {
                                //
                                // NOTE: The string is currently used as the name of the command
                                //       or procedure to execute when an unknown command is
                                //       encountered by the engine.
                                //
                                if ((arguments.Count == 2) || (arguments.Count == 3))
                                {
                                    if (arguments.Count == 3)
                                    {
                                        string unknown = StringOps.NullIfEmpty(arguments[2]);

                                        if (String.IsNullOrEmpty(unknown))
                                        {
                                            interpreter.NamespaceUnknown = interpreter.GlobalUnknown;
                                        }
                                        else
                                        {
                                            interpreter.NamespaceUnknown = unknown;
                                        }

                                        result = unknown;
                                    }
                                    else
                                    {
                                        result = interpreter.NamespaceUnknown;
                                    }

                                    code = ReturnCode.Ok;
                                }
                                else
                                {
                                    result = "wrong # args: should be \"namespace unknown ?script?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "which":
                            {
                                //
                                // TODO: *FIXME* Only the global namespace is supported here.
                                //
                                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)
                                            {
                                                if (!isCommand && !isVariable)
                                                {
                                                    isCommand = true;
                                                }

                                                if (isCommand)
                                                {
                                                    IExecute execute = null;

                                                    code = interpreter.GetIExecuteViaResolvers(
                                                        interpreter.GetResolveEngineFlags(true),
                                                        name, null, LookupFlags.Default, ref execute,
                                                        ref result);

                                                    if (code == ReturnCode.Ok)
                                                    {
                                                        result = TclVars.GlobalNamespace +
                                                                 ScriptOps.MakeCommandName(name);
                                                    }
                                                    else
                                                    {
                                                        result = String.Empty;
                                                        code   = ReturnCode.Ok;
                                                    }
                                                }
                                                else
                                                {
                                                    VariableFlags flags    = VariableFlags.NamespaceWhichMask;
                                                    IVariable     variable = null;

                                                    code = interpreter.GetVariableViaResolversWithSplit(
                                                        name, ref flags, ref variable, ref result);

                                                    if (code == ReturnCode.Ok)
                                                    {
                                                        result = TclVars.GlobalNamespace +
                                                                 ScriptOps.MakeVariableName(name);
                                                    }
                                                    else
                                                    {
                                                        result = String.Empty;
                                                        code   = ReturnCode.Ok;
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                result = "wrong # args: should be \"namespace which ?-command? ?-variable? name\"";         /* COMPAT: Tcl */
                                                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);
        }
示例#12
0
        ///////////////////////////////////////////////////////////////////////

        #region IExecute Members
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            if (interpreter == null)
            {
                result = "invalid interpreter";
                return(ReturnCode.Error);
            }

            if (arguments == null)
            {
                result = "invalid argument list";
                return(ReturnCode.Error);
            }

            if (arguments.Count < 2)
            {
                result = "wrong # args: should be \"variable ?name value...? name ?value?\"";
                return(ReturnCode.Error);
            }

            ICallFrame localFrame = null;

            if (interpreter.GetVariableFrameViaResolvers(
                    LookupFlags.Default, ref localFrame,
                    ref result) != ReturnCode.Ok)
            {
                return(ReturnCode.Error);
            }

            if (localFrame == null)
            {
                result = "local call frame is invalid";
                return(ReturnCode.Error);
            }

            if (!localFrame.IsVariable)
            {
                result = "local call frame does not support variables";
                return(ReturnCode.Error);
            }

            bool       useNamespaces    = interpreter.AreNamespacesEnabled();
            INamespace currentNamespace = null;

            if (useNamespaces &&
                interpreter.GetCurrentNamespaceViaResolvers(
                    null, LookupFlags.Default, ref currentNamespace,
                    ref result) != ReturnCode.Ok)
            {
                return(ReturnCode.Error);
            }

            ICallFrame otherFrame = null;

            if ((currentNamespace != null) &&
                !interpreter.IsGlobalNamespace(currentNamespace))
            {
                otherFrame = currentNamespace.VariableFrame;
            }
            else
            {
                otherFrame = interpreter.CurrentGlobalFrame;
            }

            for (int argumentIndex = 1;
                 argumentIndex < arguments.Count;
                 argumentIndex += 2)
            {
                string varName = arguments[argumentIndex];

                lock (interpreter.SyncRoot) /* TRANSACTIONAL */
                {
                    VariableFlags flags = VariableFlags.NoElement;

                    if (!useNamespaces)
                    {
                        flags |= VariableFlags.GlobalOnly;
                    }

                    IVariable otherVariable = null;
                    Result    error         = null;

                    if (interpreter.GetVariableViaResolversWithSplit(
                            varName, ref flags, ref otherVariable,
                            ref error) != ReturnCode.Ok)
                    {
                        if (FlagOps.HasFlags(
                                flags, VariableFlags.NotFound, true))
                        {
                            error = null;

                            if (interpreter.AddVariable2(
                                    VariableFlags.Undefined | flags,
                                    varName, null, true, ref otherVariable,
                                    ref error) != ReturnCode.Ok)
                            {
                                result = error;
                                return(ReturnCode.Error);
                            }
                        }
                        else
                        {
                            //
                            // NOTE: We did not search for the variable, let
                            //       the caller know why.
                            //
                            result = error;
                            return(ReturnCode.Error);
                        }
                    }

                    //
                    // NOTE: Create the variable link between the local frame
                    //       (i.e. a procedure, etc) and the other frame (i.e.
                    //       namespace or global).
                    //
                    if (CallFrameOps.IsLocal(localFrame))
                    {
                        error = null;

                        if (ScriptOps.LinkVariable(
                                interpreter, localFrame, varName, otherFrame,
                                varName, ref error) != ReturnCode.Ok)
                        {
                            result = error;
                            return(ReturnCode.Error);
                        }
                    }

                    //
                    // NOTE: If they provided a value, set it now.
                    //
                    // BUGFIX: This must be done after setting up the link
                    //         and not before; otherwise, the LinkVariable
                    //         method will detect a defined variable with
                    //         the same name in the local call frame and
                    //         refuse to overwrite it (by design).
                    //
                    if ((argumentIndex + 1) < arguments.Count)
                    {
                        error = null;

                        if (interpreter.SetVariableValue2(
                                VariableFlags.None, otherFrame, varName,
                                null, arguments[argumentIndex + 1].Value, null,
                                ref otherVariable, ref error) != ReturnCode.Ok)
                        {
                            result = error;
                            return(ReturnCode.Error);
                        }
                    }
                }
            }

            result = String.Empty;
            return(ReturnCode.Ok);
        }
示例#13
0
        ///////////////////////////////////////////////////////////////////////

        #region IExecute Members
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            ReturnCode code = ReturnCode.Ok;

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    IScriptLocation location = null;

                    code = ScriptOps.GetAndCheckProcedureLocation(
                        interpreter, this, ref location, ref result);

                    if (code == ReturnCode.Ok)
                    {
                        string       procedureName      = this.Name;
                        ArgumentList procedureArguments = this.Arguments;

                        if (procedureArguments != null)
                        {
                            bool hasArgs      = procedureArguments.IsVariadic(true);
                            int  totalArgs    = hasArgs ? procedureArguments.Count - 1 : procedureArguments.Count;
                            int  optionalArgs = procedureArguments.GetOptionalCount();

                            if ((arguments.Count > 0) &&
                                ((((arguments.Count - 1) >= (totalArgs - optionalArgs)) &&
                                  ((arguments.Count - 1) <= totalArgs)) ||
                                 (hasArgs && ((arguments.Count - 1) >= (totalArgs - optionalArgs)))))
                            {
                                ICallFrame frame = null;

                                try
                                {
                                    frame = interpreter.NewProcedureCallFrame(
                                        procedureName, CallFrameFlags.Procedure,
                                        null, this, arguments);

                                    VariableDictionary variables = frame.Variables;

                                    frame.ProcedureArguments = new ArgumentList(arguments[0]);

                                    for (int argumentIndex = 0; argumentIndex < procedureArguments.Count; argumentIndex++)
                                    {
                                        string varName = procedureArguments[argumentIndex].Name;

                                        if (!variables.ContainsKey(varName))
                                        {
                                            ArgumentFlags flags = ArgumentFlags.None;
                                            object        varValue;

                                            if (hasArgs && (argumentIndex == (procedureArguments.Count - 1)))
                                            {
                                                //
                                                // NOTE: This argument is part of an argument list.
                                                //
                                                flags |= ArgumentFlags.ArgumentList;

                                                //
                                                // NOTE: Build the list for the final formal argument value,
                                                //       which consists of all the remaining argument values.
                                                //
                                                ArgumentList argsArguments = new ArgumentList();

                                                for (int argsArgumentIndex = argumentIndex + 1;
                                                     argsArgumentIndex < arguments.Count; argsArgumentIndex++)
                                                {
                                                    //
                                                    // NOTE: Sync up the argument name and flags for use when
                                                    //       debugging (below).
                                                    //
                                                    Argument argsArgument = Argument.GetOrCreate(
                                                        interpreter, arguments[argsArgumentIndex].Flags | flags,
                                                        String.Format("{0}{1}{2}", varName, Characters.Space,
                                                                      argsArguments.Count), arguments[argsArgumentIndex],
                                                        interpreter.HasNoCacheArgument());

                                                    argsArguments.Add(argsArgument);
                                                }

                                                varValue = argsArguments;
                                            }
                                            else
                                            {
                                                if ((argumentIndex + 1) < arguments.Count)
                                                {
                                                    //
                                                    // NOTE: Sync up the argument name for use when
                                                    //       debugging (below) and use the value
                                                    //       supplied by the caller.
                                                    //
                                                    varValue = Argument.GetOrCreate(interpreter,
                                                                                    arguments[argumentIndex + 1].Flags | flags,
                                                                                    varName, arguments[argumentIndex + 1],
                                                                                    interpreter.HasNoCacheArgument());
                                                }
                                                else
                                                {
                                                    //
                                                    // NOTE: We cannot sync up the argument name here
                                                    //       because we are out-of-bounds on that list
                                                    //       and it cannot be extended (i.e. it would
                                                    //       break [info level]); therefore, we punt
                                                    //       on that for now.  Use the default value
                                                    //       for this argument, if any; otherwise, use
                                                    //       an empty string.
                                                    //
                                                    object @default = procedureArguments[argumentIndex].Default;
                                                    varValue = (@default != null) ? @default : Argument.NoValue;
                                                }
                                            }

                                            code = interpreter.SetVariableValue2(VariableFlags.Argument, frame,
                                                                                 varName, varValue, ref result);

                                            if (code != ReturnCode.Ok)
                                            {
                                                break;
                                            }

                                            //
                                            // BUGFIX: Now, also keep track of this argument in the procedure
                                            //         arguments list.  Primarily because we do not want to
                                            //         have to redo this logic later (i.e. for [scope]).
                                            //
                                            frame.ProcedureArguments.Add(Argument.GetOrCreate(
                                                                             interpreter, flags, varName, varValue,
                                                                             interpreter.HasNoCacheArgument()));
                                        }
                                    }

                                    //
                                    // NOTE: Make sure we succeeded in creating the call frame.
                                    //
                                    if (code == ReturnCode.Ok)
                                    {
                                        ICallFrame savedFrame = null;
                                        interpreter.PushProcedureCallFrame(frame, true, ref savedFrame);

                                        try
                                        {
#if DEBUGGER && DEBUGGER_EXECUTE
                                            if (DebuggerOps.CanHitBreakpoints(interpreter,
                                                                              EngineFlags.None, BreakpointType.BeforeProcedureBody))
                                            {
                                                code = interpreter.CheckBreakpoints(
                                                    code, BreakpointType.BeforeProcedureBody, procedureName,
                                                    null, null, this, null, clientData, arguments,
                                                    ref result);
                                            }
#endif

                                            if (code == ReturnCode.Ok)
                                            {
                                                bool locked = false;

                                                try
                                                {
                                                    bool atomic = EntityOps.IsAtomic(this);

                                                    if (atomic)
                                                    {
                                                        interpreter.InternalTryLock(ref locked); /* TRANSACTIONAL */
                                                    }
                                                    if (!atomic || locked)
                                                    {
#if ARGUMENT_CACHE || PARSE_CACHE
                                                        EngineFlags savedEngineFlags = EngineFlags.None;
                                                        bool        nonCaching       = EntityOps.IsNonCaching(this);

                                                        if (nonCaching)
                                                        {
                                                            interpreter.BeginProcedureBodyNoCaching(
                                                                ref savedEngineFlags);
                                                        }

                                                        try
                                                        {
#endif
                                                        string body = this.Body;

                                                        interpreter.ReturnCode = ReturnCode.Ok;

                                                        code = interpreter.EvaluateScript(
                                                            body, location, ref result);
#if ARGUMENT_CACHE || PARSE_CACHE
                                                    }
                                                    finally
                                                    {
                                                        if (nonCaching)
                                                        {
                                                            interpreter.EndProcedureBodyNoCaching(
                                                                ref savedEngineFlags);
                                                        }
                                                    }
#endif
                                                    }
                                                    else
                                                    {
                                                        result = "could not lock interpreter";
                                                        code   = ReturnCode.Error;
                                                    }
                                                }
                                                finally
                                                {
                                                    interpreter.InternalExitLock(ref locked); /* TRANSACTIONAL */
                                                }

#if DEBUGGER && DEBUGGER_EXECUTE
                                                if (DebuggerOps.CanHitBreakpoints(interpreter,
                                                                                  EngineFlags.None, BreakpointType.AfterProcedureBody))
                                                {
                                                    code = interpreter.CheckBreakpoints(
                                                        code, BreakpointType.AfterProcedureBody, procedureName,
                                                        null, null, this, null, clientData, arguments,
                                                        ref result);
                                                }
#endif

                                                //
                                                // BUGFIX: If an opaque object handle is being returned, add
                                                //         a reference to it now.
                                                //
                                                if ((code == ReturnCode.Ok) || (code == ReturnCode.Return))
                                                {
                                                    code = interpreter.AddObjectReference(
                                                        code, result, ObjectReferenceType.Return,
                                                        ref result);
                                                }

                                                if (code == ReturnCode.Return)
                                                {
                                                    code = Engine.UpdateReturnInformation(interpreter);
                                                }
                                                else if (code == ReturnCode.Error)
                                                {
                                                    Engine.AddErrorInformation(interpreter, result,
                                                                               String.Format("{0}    (procedure \"{1}\" line {2})",
                                                                                             Environment.NewLine, FormatOps.Ellipsis(procedureName),
                                                                                             Interpreter.GetErrorLine(interpreter)));
                                                }
                                            }
                                        }
                                        finally
                                        {
                                            /* IGNORED */
                                            interpreter.PopProcedureCallFrame(frame, ref savedFrame);
                                        }
                                    }
                                }
                                finally
                                {
                                    if (frame != null)
                                    {
                                        IDisposable disposable = frame as IDisposable;

                                        if (disposable != null)
                                        {
                                            disposable.Dispose();
                                            disposable = null;
                                        }

                                        frame = null;
                                    }
                                }
                            }
                            else
                            {
                                if (procedureArguments.Count > 0)
                                {
                                    result = String.Format(
                                        "wrong # args: should be \"{0} {1}\"",
                                        Parser.Quote(procedureName),
                                        procedureArguments.ToRawString(ToStringFlags.Decorated,
                                                                       Characters.Space.ToString()));
                                }
                                else
                                {
                                    result = String.Format(
                                        "wrong # args: should be \"{0}\"",
                                        Parser.Quote(procedureName));
                                }

                                code = ReturnCode.Error;
                            }
                        }
                        else
                        {
                            result = "invalid procedure argument list";
                            code   = ReturnCode.Error;
                        }
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
示例#14
0
文件: Test1.cs 项目: jdruin/F5Eagle
        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 == 5) || (arguments.Count == 6))
                    {
                        ///////////////////////////////////////////////////////////////////////////////////////////////
                        //
                        // test name description ?constraints? body result
                        //
                        ///////////////////////////////////////////////////////////////////////////////////////////////

                        string name = arguments[1];

#if DEBUGGER
                        if (DebuggerOps.CanHitBreakpoints(interpreter,
                                                          EngineFlags.None, BreakpointType.Test))
                        {
                            code = interpreter.CheckBreakpoints(
                                code, BreakpointType.Test, name,
                                null, null, this, null, clientData,
                                arguments, ref result);
                        }

                        if (code == ReturnCode.Ok)
#endif
                        {
                            string description = arguments[2];

                            string          constraints;
                            string          body;
                            IScriptLocation bodyLocation;
                            string          expectedResult;

                            if (arguments.Count == 6)
                            {
                                constraints    = arguments[3];
                                body           = arguments[4];
                                bodyLocation   = arguments[4];
                                expectedResult = arguments[5];
                            }
                            else
                            {
                                constraints    = null;
                                body           = arguments[3];
                                bodyLocation   = arguments[3];
                                expectedResult = arguments[4];
                            }

                            ReturnCodeList returnCodes = new ReturnCodeList(new ReturnCode[] {
                                ReturnCode.Ok, ReturnCode.Return
                            });

                            MatchMode mode = StringOps.DefaultResultMatchMode;

                            bool noCase = false;

                            ///////////////////////////////////////////////////////////////////////////////////////////////

                            int testLevels = interpreter.EnterTestLevel();

                            try
                            {
                                //
                                // NOTE: Create a place to put all the output of the this command.
                                //
                                StringBuilder testData = StringOps.NewStringBuilder();

                                //
                                // NOTE: Are we going to skip this test?
                                //
                                bool skip = false;
                                bool fail = true;

                                code = TestOps.CheckConstraints(
                                    interpreter, testLevels, name, constraints,
                                    false, false, testData, ref skip, ref fail,
                                    ref result);

                                //
                                // NOTE: Track the fact that we handled this test.
                                //
                                int[] testStatistics = null;

                                if (code == ReturnCode.Ok)
                                {
                                    testStatistics = interpreter.TestStatistics;

                                    if ((testStatistics != null) && (testLevels == 1) && skip)
                                    {
                                        Interlocked.Increment(ref testStatistics[
                                                                  (int)TestInformationType.Total]);
                                    }
                                }

                                if ((code == ReturnCode.Ok) && !skip)
                                {
                                    code = TestOps.RecordInformation(
                                        interpreter, TestInformationType.Counts, name,
                                        null, true, ref result);
                                }

                                //
                                // NOTE: Check test constraints to see if we should run the test.
                                //
                                if ((code == ReturnCode.Ok) && !skip)
                                {
                                    ReturnCode bodyCode   = ReturnCode.Ok;
                                    Result     bodyResult = null;

                                    //
                                    // NOTE: Only run the test body if the setup is successful.
                                    //
                                    if (body != null)
                                    {
                                        TestOps.AppendFormat(
                                            interpreter, testData, TestOutputType.Start,
                                            "---- {0} start", name);

                                        TestOps.AppendLine(
                                            interpreter, testData, TestOutputType.Start);

                                        int savedPreviousLevels = interpreter.BeginNestedExecution();

                                        try
                                        {
                                            ICallFrame frame = interpreter.NewTrackingCallFrame(
                                                StringList.MakeList(this.Name, "body", name),
                                                CallFrameFlags.Test);

                                            interpreter.PushAutomaticCallFrame(frame);

                                            try
                                            {
                                                bodyCode = interpreter.EvaluateScript(
                                                    body, bodyLocation, ref bodyResult);

                                                if ((bodyResult == null) && ScriptOps.HasFlags(
                                                        interpreter, InterpreterFlags.TestNullIsEmpty,
                                                        true))
                                                {
                                                    bodyResult = String.Empty;
                                                }

                                                if (bodyCode == ReturnCode.Error)
                                                {
                                                    /* IGNORED */
                                                    interpreter.CopyErrorInformation(
                                                        VariableFlags.None, ref bodyResult);
                                                }
                                            }
                                            finally
                                            {
                                                //
                                                // NOTE: Pop the original call frame that we pushed above
                                                //       and any intervening scope call frames that may be
                                                //       leftover (i.e. they were not explicitly closed).
                                                //
                                                /* IGNORED */
                                                interpreter.PopScopeCallFramesAndOneMore();
                                            }
                                        }
                                        catch (Exception e)
                                        {
                                            bodyResult = e;
                                            bodyCode   = ReturnCode.Error;
                                        }
                                        finally
                                        {
                                            interpreter.EndNestedExecution(savedPreviousLevels);
                                        }
                                    }

                                    //
                                    // NOTE: Did we fail to match the return code?
                                    //
                                    bool codeFailure = !returnCodes.Contains(bodyCode);

                                    //
                                    // NOTE: Does the actual result match the expected result?
                                    //
                                    bool       scriptFailure = false;
                                    ReturnCode scriptCode    = ReturnCode.Ok;
                                    Result     scriptResult  = null;

                                    if (!codeFailure)
                                    {
                                        if (expectedResult != null)
                                        {
                                            scriptCode = TestOps.Match(
                                                interpreter, mode, bodyResult,
                                                expectedResult, noCase, null,
                                                TestOps.RegExOptions, false,
                                                ref scriptFailure, ref scriptResult);

                                            if (scriptCode == ReturnCode.Ok)
                                            {
                                                scriptFailure = !scriptFailure;
                                            }
                                            else
                                            {
                                                scriptFailure = true;
                                            }
                                        }
                                    }

                                    //
                                    // NOTE: If any of the important things failed, the test fails.
                                    //
                                    if (!(codeFailure || scriptFailure))
                                    {
                                        //
                                        // PASS: Test ran with no errors and the results match
                                        //       what we expected.
                                        //
                                        if ((testStatistics != null) && (testLevels == 1))
                                        {
                                            Interlocked.Increment(ref testStatistics[
                                                                      (int)TestInformationType.Passed]);

                                            Interlocked.Increment(ref testStatistics[
                                                                      (int)TestInformationType.Total]);
                                        }

                                        TestOps.AppendFormat(
                                            interpreter, testData, TestOutputType.Pass,
                                            "++++ {0} PASSED", name);

                                        TestOps.AppendLine(
                                            interpreter, testData, TestOutputType.Pass);
                                    }
                                    else
                                    {
                                        //
                                        // FAIL: Test ran with errors or the result does not match
                                        //       what we expected.
                                        //
                                        if ((testStatistics != null) && (testLevels == 1))
                                        {
                                            if (fail)
                                            {
                                                Interlocked.Increment(ref testStatistics[
                                                                          (int)TestInformationType.Failed]);

                                                Interlocked.Increment(ref testStatistics[
                                                                          (int)TestInformationType.Total]);
                                            }
                                        }

                                        //
                                        // NOTE: Keep track of each test that fails.
                                        //
                                        if (testLevels == 1)
                                        {
                                            TestOps.RecordInformation(
                                                interpreter, TestInformationType.FailedNames,
                                                name, null, true);
                                        }

                                        TestOps.AppendLine(
                                            interpreter, testData, TestOutputType.Fail);

                                        TestOps.AppendFormat(
                                            interpreter, testData, TestOutputType.Fail,
                                            "==== {0} {1} {2}", name, description.Trim(),
                                            fail ? "FAILED" : "IGNORED");

                                        TestOps.AppendLine(
                                            interpreter, testData, TestOutputType.Fail);

                                        if (body != null)
                                        {
                                            TestOps.AppendLine(
                                                interpreter, testData, TestOutputType.Body,
                                                "==== Contents of test case:");

                                            TestOps.AppendLine(
                                                interpreter, testData, TestOutputType.Body,
                                                body);
                                        }

                                        if (scriptFailure)
                                        {
                                            if (scriptCode == ReturnCode.Ok)
                                            {
                                                TestOps.AppendLine(
                                                    interpreter, testData, TestOutputType.Reason,
                                                    "---- Result was:");

                                                TestOps.AppendLine(
                                                    interpreter, testData, TestOutputType.Reason,
                                                    bodyResult);

                                                TestOps.AppendFormat(
                                                    interpreter, testData, TestOutputType.Reason,
                                                    "---- Result should have been ({0} matching):",
                                                    mode);

                                                TestOps.AppendLine(
                                                    interpreter, testData, TestOutputType.Reason);

                                                TestOps.AppendLine(
                                                    interpreter, testData, TestOutputType.Reason,
                                                    expectedResult);
                                            }
                                            else
                                            {
                                                TestOps.Append(
                                                    interpreter, testData, TestOutputType.Reason,
                                                    "---- Error testing result: ");

                                                TestOps.AppendLine(
                                                    interpreter, testData, TestOutputType.Reason,
                                                    scriptResult);

                                                if ((scriptResult != null) &&
                                                    (scriptResult.ErrorInfo != null))
                                                {
                                                    TestOps.Append(
                                                        interpreter, testData, TestOutputType.Error,
                                                        "---- errorInfo(matchResult): ");

                                                    TestOps.AppendLine(
                                                        interpreter, testData, TestOutputType.Error,
                                                        scriptResult.ErrorInfo);

                                                    TestOps.Append(
                                                        interpreter, testData, TestOutputType.Error,
                                                        "---- errorCode(matchResult): ");

                                                    TestOps.AppendLine(
                                                        interpreter, testData, TestOutputType.Error,
                                                        scriptResult.ErrorCode);
                                                }
                                            }
                                        }

                                        if (codeFailure)
                                        {
                                            ReturnCodeDictionary returnCodeMessages =
                                                interpreter.TestReturnCodeMessages;

                                            string codeMessage;

                                            if ((returnCodeMessages == null) ||
                                                (!returnCodeMessages.TryGetValue(
                                                     bodyCode, out codeMessage) &&
                                                 !returnCodeMessages.TryGetValue(
                                                     ReturnCode.Invalid, out codeMessage)))
                                            {
                                                codeMessage = "Unknown";
                                            }

                                            TestOps.AppendFormat(
                                                interpreter, testData, TestOutputType.Reason,
                                                "---- {0}; Return code was: {1}",
                                                codeMessage, bodyCode);

                                            TestOps.AppendLine(
                                                interpreter, testData, TestOutputType.Reason);

                                            TestOps.Append(
                                                interpreter, testData, TestOutputType.Reason,
                                                "---- Return code should have been one of: ");

                                            TestOps.AppendLine(
                                                interpreter, testData, TestOutputType.Reason,
                                                returnCodes.ToString());

                                            if ((bodyResult != null) &&
                                                (bodyResult.ErrorInfo != null) &&
                                                !returnCodes.Contains(ReturnCode.Error))
                                            {
                                                TestOps.Append(
                                                    interpreter, testData, TestOutputType.Error,
                                                    "---- errorInfo(body): ");

                                                TestOps.AppendLine(
                                                    interpreter, testData, TestOutputType.Error,
                                                    bodyResult.ErrorInfo);

                                                TestOps.Append(
                                                    interpreter, testData, TestOutputType.Error,
                                                    "---- errorCode(body): ");

                                                TestOps.AppendLine(
                                                    interpreter, testData, TestOutputType.Error,
                                                    bodyResult.ErrorCode);
                                            }
                                        }

                                        TestOps.AppendFormat(
                                            interpreter, testData, TestOutputType.Fail,
                                            "==== {0} {1}", name, fail ? "FAILED" : "IGNORED");

                                        TestOps.AppendLine(
                                            interpreter, testData, TestOutputType.Fail);
                                    }
                                }

                                //
                                // NOTE: Did the above code succeed?
                                //
                                if (code == ReturnCode.Ok)
                                {
                                    //
                                    // NOTE: The result is the complete output produced by the
                                    //       entire test.
                                    //
                                    if (testData != null)
                                    {
                                        result = testData;
                                    }
                                    else
                                    {
                                        result = String.Empty;
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                Engine.SetExceptionErrorCode(interpreter, e);

                                result = e;
                                code   = ReturnCode.Error;
                            }
                            finally
                            {
                                interpreter.ExitTestLevel();
                            }
                        }
                    }
                    else
                    {
                        result = String.Format(
                            "wrong # args: should be \"{0} name description constraints body result\"",
                            this.Name);

                        code = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
示例#15
0
文件: Object.cs 项目: jdruin/F5Eagle
        ///////////////////////////////////////////////////////////////////////

        #region INotify Members
        public override ReturnCode Notify(
            Interpreter interpreter,
            IScriptEventArgs eventArgs,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            if (eventArgs == null)
            {
                return(ReturnCode.Ok);
            }

            if (!FlagOps.HasFlags(
                    eventArgs.NotifyTypes, NotifyType.CallFrame, false))
            {
                return(ReturnCode.Ok);
            }

            NotifyFlags notifyFlags = eventArgs.NotifyFlags;

            if (!FlagOps.HasFlags(notifyFlags,
                                  NotifyFlags.Popped | NotifyFlags.Deleted, false))
            {
                return(ReturnCode.Ok);
            }

            IClientData eventClientData = eventArgs.ClientData;

            if (eventClientData == null)
            {
                return(ReturnCode.Ok);
            }

            ICallFrame newFrame = eventClientData.Data as ICallFrame;

            if (newFrame == null)
            {
                return(ReturnCode.Ok);
            }

            //
            // NOTE: Make sure the variables in this frame actually BELONG
            //       to this frame.  Also, we do not handle the global call
            //       frame.
            //
            if (!FlagOps.HasFlags(notifyFlags, NotifyFlags.Force, true) &&
                !CallFrameOps.IsNonGlobalVariable(newFrame))
            {
                return(ReturnCode.Ok);
            }

            //
            // NOTE: If this is a [scope] created call frame, we do NOT want
            //       to change any reference counts unless the call frame is
            //       being deleted, not simply popped.
            //
            if (!FlagOps.HasFlags(notifyFlags, NotifyFlags.Deleted, true) &&
                CallFrameOps.IsScope(newFrame))
            {
                return(ReturnCode.Ok);
            }

            //
            // NOTE: Grab the variables for this call frame.  If there are
            //       none, we are done.
            //
            VariableDictionary variables = newFrame.Variables;

            if (variables == null)
            {
                return(ReturnCode.Ok);
            }

            //
            // NOTE: Process each variable in the call frame to adjust all
            //       all the reference counts.  After this point, we need
            //       the interpreter context for the event.
            //
            Interpreter eventInterpreter = eventArgs.Interpreter;

            if (eventInterpreter == null)
            {
                return(ReturnCode.Ok);
            }

            foreach (KeyValuePair <string, IVariable> pair in variables)
            {
                //
                // NOTE: Grab the variable and make sure the variable it is
                //       valid.
                //
                IVariable variable = pair.Value;

                if (variable == null)
                {
                    continue;
                }

                //
                // NOTE: For unset operations, ObjectTraceCallback uses only
                //       the "traceInfo.Variable" and "traceInfo.oldValue"
                //       members of the ITraceInfo object instance.  If the
                //       number of trace and/or watch levels exceeds one,
                //       force creation of a new TraceInfo object here;
                //       otherwise, we may interfere with the setting of an
                //       unrelated variable value.
                //
                ITraceInfo traceInfo = ScriptOps.NewTraceInfo(
                    interpreter, null, BreakpointType.BeforeVariableUnset,
                    newFrame, variable, pair.Key, null, VariableFlags.None,
                    variable.Value, null, null, null, null,
                    interpreter.NeedNewTraceInfo(VariableFlags.None),
                    false, !EntityOps.IsNoPostProcess(variable),
                    ReturnCode.Ok);

                //
                // HACK: Manually invoke the Interpreter.ObjectTraceCallback
                //       static (trace callback) method, in order to handle
                //       contained object reference(s), if any.  After this
                //       method returns, the entire call frame will be going
                //       away, along with any object references contained
                //       within it.
                //
                ReturnCode code = Interpreter.ObjectTraceCallback(
                    traceInfo.BreakpointType, eventInterpreter, traceInfo,
                    ref result);

                if (code != ReturnCode.Ok)
                {
                    return(code);
                }
            }

            return(ReturnCode.Ok);
        }
示例#16
0
文件: Try.cs 项目: jdruin/F5Eagle
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            ReturnCode code;

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    //
                    // try {<tryBody>}
                    // [finally {<finallyBody>}]
                    //
                    if ((arguments.Count == 2) || (arguments.Count == 4))
                    {
                        if ((arguments.Count < 3) || (String.Compare(arguments[2],
                                                                     Try.Finally, StringOps.SystemStringComparisonType) == 0))
                        {
                            string name = StringList.MakeList("try");

                            ICallFrame frame = interpreter.NewTrackingCallFrame(name,
                                                                                CallFrameFlags.Try);

                            interpreter.PushAutomaticCallFrame(frame);

                            ReturnCode tryCode;
                            Result     tryResult = null;

                            tryCode = interpreter.EvaluateScript(arguments[1], ref tryResult);

                            if (tryCode == ReturnCode.Error)
                            {
                                Engine.AddErrorInformation(interpreter, tryResult,
                                                           String.Format("{0}    (\"try\" body line {1})",
                                                                         Environment.NewLine, Interpreter.GetErrorLine(interpreter)));
                            }

                            //
                            // NOTE: Pop the original call frame that we pushed above and
                            //       any intervening scope call frames that may be leftover
                            //       (i.e. they were not explicitly closed).
                            //
                            /* IGNORED */
                            interpreter.PopScopeCallFramesAndOneMore();

                            Result     finallyResult = null;
                            ReturnCode finallyCode   = ReturnCode.Ok;

                            if (arguments.Count == 4)
                            {
                                name = StringList.MakeList("finally");

                                frame = interpreter.NewTrackingCallFrame(name,
                                                                         CallFrameFlags.Finally);

                                interpreter.PushAutomaticCallFrame(frame);

                                //
                                // BUGFIX: Preserve any and all existing error related
                                //         information during evaluation of the finally
                                //         block.
                                //
                                Engine.SetNoResetError(interpreter, true);

                                //
                                // NOTE: If there was an error during the try block as well,
                                //       keep them somewhat organized in the final error
                                //       information.
                                //
                                if (tryCode == ReturnCode.Error)
                                {
                                    Engine.AddErrorInformation(interpreter, null,
                                                               String.Format("{0}    ... continued ...",
                                                                             Environment.NewLine));
                                }

                                //
                                // NOTE: If the appropriate flag is set, call into the
                                //       Engine.ResetCancel method (with "force" enabled)
                                //       prior to evaluating the finally block script.
                                //       It should be noted here that even though the
                                //       return code of this call is checked by the code,
                                //       it basically cannot fail at this point.
                                //
                                Result canceledResult = null;
                                bool   canceled       = false;
                                bool   unwound        = false;
                                bool   resetCancel    = false;

                                //
                                // NOTE: If the appropriate flag is set, reset the Exit
                                //       property prior to evaluating the finally block
                                //       script.
                                //
                                bool exit      = false;
                                bool resetExit = false;

                                try
                                {
                                    if (ScriptOps.HasFlags(interpreter,
                                                           InterpreterFlags.FinallyResetCancel, true))
                                    {
                                        ReturnCode resetCode;
                                        Result     resetError = null;

                                        resetCode = Engine.ResetCancel(
                                            interpreter, CancelFlags.TryBlock, ref canceledResult,
                                            ref canceled, ref unwound, ref resetCancel,
                                            ref resetError);

                                        if (resetCode != ReturnCode.Ok)
                                        {
                                            DebugOps.Complain(interpreter, resetCode, resetError);
                                        }
                                    }

                                    if (ScriptOps.HasFlags(interpreter,
                                                           InterpreterFlags.FinallyResetExit, true))
                                    {
                                        exit = interpreter.Exit;

                                        if (exit)
                                        {
                                            interpreter.Exit = false;
                                            resetExit        = true;
                                        }
                                    }

                                    ReturnCode timeoutCode;
                                    Result     timeoutResult = null;

                                    timeoutCode = Interpreter.StartFinallyTimeoutThread(
                                        interpreter, false, true, ref timeoutResult);

                                    if (timeoutCode != ReturnCode.Ok)
                                    {
                                        DebugOps.Complain(interpreter, timeoutCode, timeoutResult);
                                    }

                                    try
                                    {
                                        //
                                        // NOTE: Evaluate the finally block.
                                        //
                                        finallyCode = interpreter.EvaluateScript(
                                            arguments[3], ref finallyResult);
                                    }
                                    finally
                                    {
                                        timeoutCode = Interpreter.InterruptFinallyTimeoutThread(
                                            interpreter, false, ref timeoutResult);

                                        if (timeoutCode != ReturnCode.Ok)
                                        {
                                            DebugOps.Complain(interpreter, timeoutCode, timeoutResult);
                                        }
                                    }
                                }
                                finally
                                {
                                    if (exit && resetExit)
                                    {
                                        if (ScriptOps.HasFlags(interpreter,
                                                               InterpreterFlags.FinallyRestoreExit, true))
                                        {
                                            interpreter.Exit = true;
                                        }
                                    }

                                    if ((canceled || unwound) && resetCancel)
                                    {
                                        if (ScriptOps.HasFlags(interpreter,
                                                               InterpreterFlags.FinallyRestoreCancel, true))
                                        {
                                            CancelFlags cancelFlags = CancelFlags.FinallyBlock;

                                            if (unwound)
                                            {
                                                cancelFlags |= CancelFlags.Unwind;
                                            }

                                            ReturnCode cancelCode;
                                            Result     cancelError = null;

                                            cancelCode = Engine.CancelEvaluate(
                                                interpreter, canceledResult, cancelFlags,
                                                ref cancelError);

                                            if (cancelCode != ReturnCode.Ok)
                                            {
                                                DebugOps.Complain(interpreter, cancelCode, cancelError);
                                            }
                                        }
                                    }
                                }

                                if (finallyCode == ReturnCode.Error)
                                {
                                    Engine.AddErrorInformation(interpreter, finallyResult,
                                                               String.Format("{0}    (\"finally\" body line {1})",
                                                                             Environment.NewLine, Interpreter.GetErrorLine(interpreter)));
                                }

                                //
                                // NOTE: Restore normal result reset semantics.
                                //
                                Engine.SetNoResetError(interpreter, false);

                                //
                                // NOTE: Pop the original call frame that we pushed above and
                                //       any intervening scope call frames that may be leftover
                                //       (i.e. they were not explicitly closed).
                                //
                                /* IGNORED */
                                interpreter.PopScopeCallFramesAndOneMore();
                            }

                            //
                            // NOTE: Initially, the overall command return code and result
                            //       is that of the try block; however, if the finally block
                            //       fails, that will be the return code and result.
                            //
                            if (finallyCode == ReturnCode.Ok)
                            {
                                result = tryResult;
                                code   = tryCode;
                            }
                            else
                            {
                                result = finallyResult;
                                code   = finallyCode;
                            }
                        }
                        else
                        {
                            result = String.Format(
                                "expected \"finally\" but got \"{0}\"",
                                arguments[2]);

                            code = ReturnCode.Error;
                        }
                    }
                    else
                    {
                        result = "wrong # args: should be \"try script ?finally script?\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    return(ReturnCode.Error);
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
示例#17
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);
        }
示例#18
0
        ///////////////////////////////////////////////////////////////////////

        #region IExecute Members
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            if (interpreter == null)
            {
                result = "invalid interpreter";
                return(ReturnCode.Error);
            }

            if (arguments == null)
            {
                result = "invalid argument list";
                return(ReturnCode.Error);
            }

            if (arguments.Count < 2)
            {
                result = "wrong # args: should be \"uplevel ?level? arg ?arg ...?\"";
                return(ReturnCode.Error);
            }

            ReturnCode code;
            int        currentLevel = 0;

            code = interpreter.GetInfoLevel(
                CallFrameOps.InfoLevelSubCommand, ref currentLevel,
                ref result);

            if (code != ReturnCode.Ok)
            {
                return(code);
            }

            bool       mark         = false;
            bool       absolute     = false;
            bool       super        = false;
            int        level        = 0;
            ICallFrame currentFrame = null;
            ICallFrame otherFrame   = null;

            FrameResult frameResult = interpreter.GetCallFrame(
                arguments[1], ref mark, ref absolute, ref super,
                ref level, ref currentFrame, ref otherFrame,
                ref result);

            if (frameResult == FrameResult.Invalid)
            {
                return(ReturnCode.Error);
            }

            int argumentIndex = ((int)frameResult + 1);

            //
            // BUGFIX: The argument count needs to be checked again here.
            //
            if (argumentIndex >= arguments.Count)
            {
                result = "wrong # args: should be \"uplevel ?level? arg ?arg ...?\"";
                return(ReturnCode.Error);
            }

            if (mark)
            {
                code = CallFrameOps.MarkMatching(
                    interpreter.CallStack, interpreter.CurrentFrame,
                    absolute, level, CallFrameFlags.Variables,
                    CallFrameFlags.Invisible | CallFrameFlags.NoVariables,
                    CallFrameFlags.Invisible, false, false, true,
                    ref result);
            }

            if (code == ReturnCode.Ok)
            {
                try
                {
                    string name = StringList.MakeList("uplevel", arguments[1]);

                    ICallFrame newFrame = interpreter.NewUplevelCallFrame(
                        name, currentLevel, CallFrameFlags.None, mark,
                        currentFrame, otherFrame);

                    ICallFrame savedFrame = null;

                    interpreter.PushUplevelCallFrame(
                        currentFrame, newFrame, true, ref savedFrame);

                    if ((argumentIndex + 1) >= arguments.Count)
                    {
                        code = interpreter.EvaluateScript(
                            arguments[argumentIndex], ref result);
                    }
                    else
                    {
                        code = interpreter.EvaluateScript(
                            arguments, argumentIndex, ref result);
                    }

                    if (code == ReturnCode.Error)
                    {
                        Engine.AddErrorInformation(interpreter, result,
                                                   String.Format("{0}    (\"uplevel\" body line {1})",
                                                                 Environment.NewLine, Interpreter.GetErrorLine(interpreter)));
                    }

                    //
                    // NOTE: Pop the original call frame that we pushed above and
                    //       any intervening scope call frames that may be leftover
                    //       (i.e. they were not explicitly closed).
                    //
                    /* IGNORED */
                    interpreter.PopUplevelCallFrame(
                        currentFrame, newFrame, ref savedFrame);
                }
                finally
                {
                    if (mark)
                    {
                        //
                        // NOTE: We should not get an error at this point from
                        //       unmarking the call frames; however, if we do get
                        //       one, we need to complain loudly about it because
                        //       that means the interpreter state has probably been
                        //       corrupted somehow.
                        //
                        ReturnCode markCode;
                        Result     markResult = null;

                        markCode = CallFrameOps.MarkMatching(
                            interpreter.CallStack, interpreter.CurrentFrame,
                            absolute, level, CallFrameFlags.Variables,
                            CallFrameFlags.NoVariables, CallFrameFlags.Invisible,
                            false, false, false, ref markResult);

                        if (markCode != ReturnCode.Ok)
                        {
                            DebugOps.Complain(interpreter, markCode, markResult);
                        }
                    }
                }
            }

            return(code);
        }
示例#19
0
        ///////////////////////////////////////////////////////////////////////

        public void Free(
            bool global
            )
        {
            TraceOps.DebugTrace(String.Format(
                                    "Free: called, global = {0}, interpreter = {1}, disposed = {2}",
                                    global, FormatOps.InterpreterNoThrow(interpreter), disposed),
                                typeof(VariableContext).Name, TracePriority.CleanupDebug);

            ///////////////////////////////////////////////////////////////////

            interpreter = null; /* NOT OWNED: Do not dispose. */
            threadId    = 0;

            ///////////////////////////////////////////////////////////////////

            if (traceInfo != null)
            {
                traceInfo = null;
            }

            ///////////////////////////////////////////////////////////////////

            //
            // HACK: *SPECIAL CASE* We cannot dispose the current call stack
            //       unless we are [also] disposing of the interpreter itself;
            //       therefore, use the special Free method here instead of the
            //       Dispose method.  The Free method is guaranteed to do the
            //       right thing with regard to the global call frame (assuming
            //       the "global" paramter is correct).
            //
            if (callStack != null)
            {
                callStack.Free(global);
                callStack = null;
            }

            ///////////////////////////////////////////////////////////////////

            //
            // HACK: *SPECIAL CASE* We cannot dispose the uplevel call frame
            //       unless we are [also] disposing of the interpreter itself.
            //
            if (uplevelFrame != null)
            {
                uplevelFrame.Free(global);
                uplevelFrame = null;
            }

            ///////////////////////////////////////////////////////////////////

            //
            // HACK: *SPECIAL CASE* We cannot dispose the procedure call frame
            //       unless we are [also] disposing of the interpreter itself.
            //
            if (procedureFrame != null)
            {
                procedureFrame.Free(global);
                procedureFrame = null;
            }

            ///////////////////////////////////////////////////////////////////

            //
            // HACK: *SPECIAL CASE* We cannot dispose the current call frame
            //       unless we are [also] disposing of the interpreter itself.
            //
            if (currentFrame != null)
            {
                currentFrame.Free(global);
                currentFrame = null;
            }

            ///////////////////////////////////////////////////////////////////

            //
            // HACK: *SPECIAL CASE* We cannot dispose the uplevel call frame
            //       unless we are [also] disposing of the interpreter itself.
            //       If this is really a named scope call frame -AND- we are
            //       being disposed, it should have already been cleaned up by
            //       this point; therefore, this should be a no-op.
            //
            if (globalScopeFrame != null)
            {
                globalScopeFrame.Free(global);
                globalScopeFrame = null;
            }

            ///////////////////////////////////////////////////////////////////

            //
            // HACK: *SPECIAL CASE* We cannot dispose the global call frame
            //       unless we are [also] disposing of the interpreter itself.
            //
            if (globalFrame != null)
            {
                globalFrame.Free(global);
                globalFrame = null;
            }
        }
示例#20
0
        ///////////////////////////////////////////////////////////////////////

        public void Free(
            bool global
            )
        {
            //
            // HACK: *SPECIAL CASE* We cannot dispose the global call frame
            //       unless we are [also] disposing of the interpreter itself.
            //
            if (global ||
                !FlagOps.HasFlags(flags, CallFrameFlags.NoFree, true))
            {
                kind        = IdentifierKind.None;
                id          = Guid.Empty;
                name        = null;
                group       = null;
                description = null;
                clientData  = null;
                frameId     = 0;
                frameLevel  = 0;
                flags       = CallFrameFlags.None;

                ///////////////////////////////////////////////////////////////

                if (tags != null)
                {
                    tags.Clear();
                    tags = null;
                }

                ///////////////////////////////////////////////////////////////

                index = 0;
                level = 0;

                ///////////////////////////////////////////////////////////////

                if (arguments != null)
                {
                    //
                    // BUGFIX: We can only mutate argument lists that we own.
                    //
                    if (ownArguments)
                    {
                        arguments.Clear();
                    }

                    arguments = null;
                }

                ///////////////////////////////////////////////////////////////

                ownArguments = false;

                ///////////////////////////////////////////////////////////////

                if (procedureArguments != null)
                {
                    procedureArguments.Clear();
                    procedureArguments = null;
                }

                ///////////////////////////////////////////////////////////////

                if (variables != null)
                {
                    variables.Clear();
                    variables = null;
                }

                ///////////////////////////////////////////////////////////////

                other    = null; /* NOTE: Not owned, do not dispose. */
                previous = null; /* NOTE: Not owned, do not dispose. */
                next     = null; /* NOTE: Not owned, do not dispose. */

                ///////////////////////////////////////////////////////////////

                engineData    = null; /* NOTE: Not owned, do not dispose. */
                auxiliaryData = null; /* NOTE: Not owned, do not dispose. */
                resolveData   = null; /* NOTE: Not owned, do not dispose. */
                extraData     = null; /* NOTE: Not owned, do not dispose. */
            }
        }