Beispiel #1
0
        ///////////////////////////////////////////////////////////////////////

        #region Private Methods
        private void AddRange(
            IClientData clientData,
            TraceFlags traceFlags,
            IPlugin plugin,
            IEnumerable <TraceCallback> collection
            )
        {
            foreach (TraceCallback item in collection)
            {
                if (item != null)
                {
                    Result error = null;

                    ITrace trace = ScriptOps.NewCoreTrace(
                        item, clientData, traceFlags, plugin, ref error);

                    if (trace != null)
                    {
                        this.Add(trace);
                    }
                    else
                    {
                        DebugOps.Complain(ReturnCode.Error, error);
                    }
                }
            }
        }
Beispiel #2
0
        ///////////////////////////////////////////////////////////////////////

        #region IExecute Members
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            return(ScriptOps.EachLoopCommand(
                       this, true, interpreter, clientData, arguments, ref result));
        }
Beispiel #3
0
        ///////////////////////////////////////////////////////////////////////

        internal StringList GetLocals(
            Interpreter interpreter,
            string pattern
            )
        {
            if (pattern != null)
            {
                pattern = ScriptOps.MakeVariableName(pattern);
            }

            StringList result = new StringList();

            foreach (KeyValuePair <string, IVariable> pair in this)
            {
                IVariable variable = pair.Value;

                if (variable == null)
                {
                    continue;
                }

                if (EntityOps.IsUndefined(variable) ||
                    EntityOps.IsLink(variable))
                {
                    continue;
                }

                ICallFrame frame = CallFrameOps.FollowNext(variable.Frame);

                if (interpreter != null)
                {
                    if (interpreter.IsGlobalCallFrame(frame))
                    {
                        continue;
                    }

                    if (Interpreter.IsNamespaceCallFrame(frame))
                    {
                        continue;
                    }
                }

                string name = variable.Name;

                if ((pattern == null) || StringOps.Match(
                        interpreter, StringOps.DefaultMatchMode,
                        name, pattern, false))
                {
                    result.Add(name);
                }
            }

            return(result);
        }
Beispiel #4
0
        public string SerializeCallStack()
        {
            var sb = new StringBuilder();

            for (var i = 0; i < FrameCount; i++)
            {
                var frame = CallStack[i];
                sb.AppendLine($"  At Op:{ScriptOps.GetName(frame.OriginatingNode.OperationId)} consuming Op:{ScriptOps.GetName(frame.Current.OperationId)} and next of {frame.Next}");
            }

            return(sb.ToString());
        }
Beispiel #5
0
        ///////////////////////////////////////////////////////////////////////

        private string GetOriginName(
            string aliasName
            )
        {
            if (aliasName == null)
            {
                return(null);
            }

            Result result = null;

            if (NamespaceOps.Origin(interpreter, this,
                                    NamespaceOps.MakeAbsoluteName(aliasName),
                                    ref result) == ReturnCode.Ok)
            {
                return(ScriptOps.MakeCommandName(result));
            }

            return(null);
        }
Beispiel #6
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 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)
                        {
                            //
                            // NOTE: Programmatically interact with the debugger (breakpoint, watch,
                            //       eval, etc).
                            //
                            switch (subCommand)
                            {
                            case "clear":
                            {
                                if (arguments.Count == 2)
                                {
                                    code = interpreter.ClearCallbackQueue(ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        result = String.Empty;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"callback clear\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "count":
                            {
                                if (arguments.Count == 2)
                                {
                                    int count = 0;

                                    code = interpreter.CountCallbacks(ref count, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        result = count;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"callback count\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "dequeue":
                            {
                                if (arguments.Count >= 2)
                                {
                                    OptionDictionary options = ObjectOps.GetDequeueOptions();

                                    int argumentIndex = Index.Invalid;

                                    if (arguments.Count > 2)
                                    {
                                        code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result);
                                    }
                                    else
                                    {
                                        code = ReturnCode.Ok;
                                    }

                                    if (code == ReturnCode.Ok)
                                    {
                                        if (argumentIndex == Index.Invalid)
                                        {
                                            Type        returnType;
                                            ObjectFlags objectFlags;
                                            string      objectName;
                                            string      interpName;
                                            bool        create;
                                            bool        dispose;
                                            bool        alias;
                                            bool        aliasRaw;
                                            bool        aliasAll;
                                            bool        aliasReference;
                                            bool        toString;

                                            ObjectOps.ProcessFixupReturnValueOptions(
                                                options, null, out returnType, out objectFlags,
                                                out objectName, out interpName, out create,
                                                out dispose, out alias, out aliasRaw, out aliasAll,
                                                out aliasReference, out toString);

                                            //
                                            // NOTE: Which Tcl interpreter do we want a command alias created
                                            //       in, if any?
                                            //
                                            ICallback callback = null;

                                            code = interpreter.DequeueCallback(ref callback, ref result);

                                            if (code == ReturnCode.Ok)
                                            {
                                                ObjectOptionType objectOptionType = ObjectOptionType.Dequeue |
                                                                                    ObjectOps.GetOptionType(aliasRaw, aliasAll);

                                                code = MarshalOps.FixupReturnValue(
                                                    interpreter, interpreter.Binder, interpreter.CultureInfo,
                                                    returnType, objectFlags, ObjectOps.GetInvokeOptions(
                                                        objectOptionType), objectOptionType, objectName, interpName,
                                                    callback, create, dispose, alias, aliasReference, toString,
                                                    ref result);
                                            }
                                        }
                                        else
                                        {
                                            result = "wrong # args: should be \"callback dequeue ?options?\"";
                                            code   = ReturnCode.Error;
                                        }
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"callback dequeue ?options?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "enqueue":
                            {
                                if (arguments.Count >= 3)
                                {
                                    ICallback callback = CommandCallback.Create(
                                        MarshalFlags.Default, CallbackFlags.Default,
                                        ObjectFlags.Callback, ByRefArgumentFlags.None,
                                        interpreter, clientData, null, new StringList(
                                            arguments, 2), ref result);

                                    if (callback != null)
                                    {
                                        code = interpreter.EnqueueCallback(callback, ref result);

                                        if (code == ReturnCode.Ok)
                                        {
                                            result = String.Empty;
                                        }
                                    }
                                    else
                                    {
                                        code = ReturnCode.Error;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"callback enqueue name ?arg ...?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "execute":
                            {
                                if (arguments.Count == 2)
                                {
                                    code = interpreter.ExecuteCallbackQueue(ref result);
                                }
                                else
                                {
                                    result = "wrong # args: should be \"callback execute\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "list":
                            {
                                if ((arguments.Count == 2) || (arguments.Count == 3))
                                {
                                    string pattern = null;

                                    if (arguments.Count == 3)
                                    {
                                        pattern = arguments[2];
                                    }

                                    StringList list = null;

                                    code = interpreter.ListCallbacks(
                                        pattern, false, ref list, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        result = list;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"callback list ?pattern?\"";
                                    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 \"callback option ?arg ...?\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
Beispiel #7
0
        ///////////////////////////////////////////////////////////////////////

        public static ReturnCode HandleBackgroundError(
            Interpreter interpreter,
            ReturnCode code,
            Result result,
            ref bool bgError
            )
        {
            if (interpreter == null)
            {
                ReportBackgroundError(interpreter /* null */, null,
                                      "cannot handle background error, interpreter is " +
                                      "invalid.", "Original error", code, result, 0, null,
                                      ReturnCode.Ok, null, 0);

                return(ReturnCode.Error);
            }

            //
            // BUGFIX: Acquire the interpreter lock here; however, do not use
            //         the public property just in case the interpreter may be
            //         disposed at this point.
            //
            lock (interpreter.InternalSyncRoot) /* TRANSACTIONAL */
            {
                //
                // BUGFIX: Do not try to handle any background errors with a
                //         deleted or disposed interpreter.
                //
                if (Interpreter.IsDeletedOrDisposed(interpreter))
                {
                    ReportBackgroundError(interpreter /* disposed? */, null,
                                          "cannot handle background error, interpreter is " +
                                          "deleted or disposed.", "Original error", code,
                                          result, 0, null, ReturnCode.Ok, null, 0);

                    return(ReturnCode.Error);
                }

                int    errorLine   = Interpreter.GetErrorLine(interpreter);
                string handlerName = interpreter.BackgroundError;

                //
                // NOTE: If there is an invalid background error handler set,
                //       ignore the error.
                //
                if (!String.IsNullOrEmpty(handlerName))
                {
                    //
                    // NOTE: Must hold lock while processing the error.
                    //
                    // TODO: Need to more carefully analyze this lock usage at
                    //       some point.
                    //
                    lock (interpreter.SyncRoot) /* TRANSACTIONAL */
                    {
                        //
                        // NOTE: Should a failure to handle the background
                        //       error simply be ignored?
                        //
                        bool ignoreFailure = ScriptOps.HasFlags(interpreter,
                                                                InterpreterFlags.IgnoreBgErrorFailure, true);

                        //
                        // NOTE: We do not yet know if the background error
                        //       handler can actually be resolved.
                        //
                        bool haveBgError = false;

                        //
                        // NOTE: Construct a new argument list to pass along
                        //       to the actual error handler command, e.g.
                        //       "[list bgerror <message>]".
                        //
                        ArgumentList bgArguments = new ArgumentList(
                            handlerName, result);

                        //
                        // NOTE: Attempt to lookup the background error
                        //       handler via the current command resolvers
                        //       for the interpreter.  If this lookup fails
                        //       the default background error processing
                        //       will be used.
                        //
                        ReturnCode resolveCode;
                        Result     resolveError = null;
                        IExecute   bgExecute    = null;

                        resolveCode = interpreter.GetIExecuteViaResolvers(
                            interpreter.GetResolveEngineFlags(true),
                            handlerName, bgArguments, LookupFlags.Default,
                            ref bgExecute, ref resolveError);

                        if (resolveCode == ReturnCode.Ok)
                        {
                            //
                            // NOTE: We found a background error handler.
                            //
                            haveBgError = true;

                            //
                            // NOTE: Execute the background error handler now
                            //       and save the results.
                            //
                            ReturnCode bgCode;
                            Result     bgResult    = null;
                            int        bgErrorLine = 0;

                            bgCode = ExecuteBackgroundError(
                                interpreter, handlerName, bgExecute, null,
                                bgArguments, ref bgResult, ref bgErrorLine);

                            //
                            // NOTE: Now we handle the return code for the
                            //       background error handler.
                            //
                            if (bgCode == ReturnCode.Break)
                            {
                                //
                                // NOTE: A return code of "Break" indicates
                                //       that we should not call the background
                                //       error handler until the next time
                                //       ProcessEvents is invoked.
                                //
                                bgError = false;
                            }
                            else if (!ignoreFailure && (bgCode != ReturnCode.Ok))
                            {
                                //
                                // NOTE: Any other non-"Ok" return code is an
                                //       error an gets reported to the standard
                                //       error channel of the host, if any.
                                //
                                ReportBackgroundError(interpreter, handlerName,
                                                      "handler {0} failed for background error.",
                                                      "Original error", code, result, errorLine,
                                                      "Handler error", bgCode, bgResult,
                                                      bgErrorLine);
                            }
                        }

                        //
                        // NOTE: If there is no background error handler setup
                        //       just write the errorInfo to the error channel
                        //       (if possible).  If failures should be ignored,
                        //       skip reporting the problem.
                        //
                        if (!ignoreFailure && !haveBgError)
                        {
                            ReportBackgroundError(interpreter, handlerName,
                                                  "handler {0} missing for background error.",
                                                  "Original error", code, result, errorLine,
                                                  "Resolver error", resolveCode, resolveError,
                                                  0);
                        }
                    }
                }

                return(ReturnCode.Ok);
            }
        }
Beispiel #8
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)
                {
                    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 "forget":
                            {
                                if (arguments.Count >= 2)
                                {
                                    code = interpreter.PkgForget(
                                        new StringList(arguments, 2), ref result);
                                }
                                else
                                {
                                    result = "wrong # args: should be \"package forget ?package package ...?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "ifneeded":
                            {
                                if ((arguments.Count == 4) || (arguments.Count == 5))
                                {
                                    Version version = null;

                                    code = Value.GetVersion(
                                        arguments[3], interpreter.CultureInfo,
                                        ref version, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        string text = null;

                                        if (arguments.Count == 5)
                                        {
                                            text = arguments[4];
                                        }

                                        code = interpreter.PkgIfNeeded(
                                            arguments[2], version, text, interpreter.PackageFlags,
                                            ref result);
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"package ifneeded package version ?script?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "indexes":
                            {
                                if ((arguments.Count == 2) || (arguments.Count == 3))
                                {
                                    string pattern = null;

                                    if (arguments.Count == 3)
                                    {
                                        pattern = arguments[2];
                                    }

                                    code = interpreter.PkgIndexes(
                                        pattern, false, ref result);
                                }
                                else
                                {
                                    result = "wrong # args: should be \"package indexes ?pattern?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "info":
                            {
                                if (arguments.Count == 3)
                                {
                                    IPackage package = null;

                                    code = interpreter.GetPackage(
                                        arguments[2], LookupFlags.Default,
                                        ref package, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        bool         scrub = interpreter.IsSafe();
                                        PackageFlags flags = package.Flags;
                                        Guid         id    = AttributeOps.GetObjectId(package);

                                        result = StringList.MakeList(
                                            "kind", package.Kind,
                                            "id", package.Id.Equals(Guid.Empty) ? id : package.Id,
                                            "name", package.Name,
                                            "description", package.Description,
                                            "indexFileName", scrub ? PathOps.ScrubPath(
                                                GlobalState.GetBasePath(), package.IndexFileName) :
                                            package.IndexFileName,
                                            "provideFileName", scrub ? PathOps.ScrubPath(
                                                GlobalState.GetBasePath(), package.ProvideFileName) :
                                            package.ProvideFileName,
                                            "flags", flags,
                                            "loaded", (package.Loaded != null) ? package.Loaded : null,
                                            "ifNeeded", (!scrub && (package.IfNeeded != null)) ?
                                            package.IfNeeded.KeysAndValuesToString(null, false) :
                                            null);
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"package info name\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "loaded":
                            {
                                if ((arguments.Count == 2) || (arguments.Count == 3))
                                {
                                    string pattern = null;

                                    if (arguments.Count == 3)
                                    {
                                        pattern = arguments[2];
                                    }

                                    code = interpreter.PkgLoaded(
                                        pattern, false, false, ref result);
                                }
                                else
                                {
                                    result = "wrong # args: should be \"package loaded ?pattern?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "names":
                            {
                                if ((arguments.Count == 2) || (arguments.Count == 3))
                                {
                                    string pattern = null;

                                    if (arguments.Count == 3)
                                    {
                                        pattern = arguments[2];
                                    }

                                    code = interpreter.PkgNames(
                                        pattern, false, ref result);
                                }
                                else
                                {
                                    result = "wrong # args: should be \"package names ?pattern?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "present":
                            {
                                if (arguments.Count >= 3)
                                {
                                    OptionDictionary options = new OptionDictionary(
                                        new IOption[] {
                                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-exact", null),
                                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null)
                                        });

                                    int argumentIndex = Index.Invalid;

                                    code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, false, ref argumentIndex, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        if ((argumentIndex != Index.Invalid) &&
                                            ((argumentIndex + 2) >= arguments.Count))
                                        {
                                            bool exact = false;

                                            if (options.IsPresent("-exact"))
                                            {
                                                exact = true;
                                            }

                                            Version version = null;

                                            if ((argumentIndex + 1) < arguments.Count)
                                            {
                                                code = Value.GetVersion(
                                                    arguments[argumentIndex + 1], interpreter.CultureInfo,
                                                    ref version, ref result);
                                            }

                                            if (code == ReturnCode.Ok)
                                            {
                                                code = interpreter.PresentPackage(
                                                    arguments[argumentIndex], version, exact, ref result);
                                            }
                                        }
                                        else
                                        {
                                            if ((argumentIndex != Index.Invalid) &&
                                                Option.LooksLikeOption(arguments[argumentIndex]))
                                            {
                                                result = OptionDictionary.BadOption(options, arguments[argumentIndex]);
                                            }
                                            else
                                            {
                                                result = "wrong # args: should be \"package present ?-exact? package ?version?\"";
                                            }

                                            code = ReturnCode.Error;
                                        }
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"package present ?-exact? package ?version?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "provide":
                            {
                                if ((arguments.Count == 3) || (arguments.Count == 4))
                                {
                                    PackageFlags flags = interpreter.PackageFlags;

                                    if (!FlagOps.HasFlags(flags, PackageFlags.NoProvide, true))
                                    {
                                        Version version = null;

                                        if (arguments.Count == 4)
                                        {
                                            code = Value.GetVersion(arguments[3], interpreter.CultureInfo, ref version, ref result);
                                        }

                                        if (code == ReturnCode.Ok)
                                        {
                                            code = interpreter.PkgProvide(arguments[2], version, flags, ref result);
                                        }
                                    }
                                    else
                                    {
                                        //
                                        // HACK: Do nothing, provide no package, and return nothing.
                                        //
                                        result = String.Empty;
                                        code   = ReturnCode.Ok;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"package provide package ?version?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "relativefilename":
                            {
                                if ((arguments.Count == 3) || (arguments.Count == 4))
                                {
                                    PathComparisonType pathComparisonType = PathComparisonType.Default;

                                    if (arguments.Count == 4)
                                    {
                                        object enumValue = EnumOps.TryParseFlagsEnum(
                                            interpreter, typeof(PathComparisonType),
                                            pathComparisonType.ToString(), arguments[3],
                                            interpreter.CultureInfo, true, true, true,
                                            ref result);

                                        if (enumValue is EventFlags)
                                        {
                                            pathComparisonType = (PathComparisonType)enumValue;
                                        }
                                        else
                                        {
                                            code = ReturnCode.Error;
                                        }
                                    }

                                    if (code == ReturnCode.Ok)
                                    {
                                        string fileName = null;

                                        code = PackageOps.GetRelativeFileName(
                                            interpreter, arguments[2], pathComparisonType,
                                            ref fileName, ref result);

                                        if (code == ReturnCode.Ok)
                                        {
                                            result = fileName;
                                        }
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"package relativefilename fileName ?type?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "require":
                            {
                                if (arguments.Count >= 3)
                                {
                                    OptionDictionary options = new OptionDictionary(
                                        new IOption[] {
                                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-exact", null),
                                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null)
                                        });

                                    int argumentIndex = Index.Invalid;

                                    code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, false, ref argumentIndex, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        if ((argumentIndex != Index.Invalid) && ((argumentIndex + 2) >= arguments.Count))
                                        {
                                            bool exact = false;

                                            if (options.IsPresent("-exact"))
                                            {
                                                exact = true;
                                            }

                                            Version version = null;

                                            if ((argumentIndex + 1) < arguments.Count)
                                            {
                                                code = Value.GetVersion(
                                                    arguments[argumentIndex + 1], interpreter.CultureInfo,
                                                    ref version, ref result);
                                            }

                                            if (code == ReturnCode.Ok)
                                            {
                                                code = interpreter.RequirePackage(
                                                    arguments[argumentIndex], version, exact, ref result);
                                            }

                                            //
                                            // NOTE: This is a new feature.  If the initial attempt to
                                            //       require a package fails, call the package fallback
                                            //       delegate for the interpreter and then try requiring
                                            //       the package again.
                                            //
                                            if ((code != ReturnCode.Ok) && !ScriptOps.HasFlags(
                                                    interpreter, InterpreterFlags.NoPackageFallback, true))
                                            {
                                                PackageCallback packageFallback = interpreter.PackageFallback;

                                                if (packageFallback != null)
                                                {
                                                    code = packageFallback(
                                                        interpreter, arguments[argumentIndex], version, null,
                                                        interpreter.PackageFlags, exact, ref result);

                                                    if (code == ReturnCode.Ok)
                                                    {
                                                        code = interpreter.RequirePackage(
                                                            arguments[argumentIndex], version, exact, ref result);
                                                    }
                                                }
                                            }

                                            //
                                            // BUGFIX: This is really a new feature.  In the event of a failure
                                            //         here, we now fallback to the "unknown package handler",
                                            //         just like Tcl does.
                                            //
                                            if ((code != ReturnCode.Ok) && !ScriptOps.HasFlags(
                                                    interpreter, InterpreterFlags.NoPackageUnknown, true))
                                            {
                                                string text = interpreter.PackageUnknown + Characters.Space +
                                                              Parser.Quote(arguments[argumentIndex]);

                                                if (version != null)
                                                {
                                                    text += Characters.Space + Parser.Quote(version.ToString());
                                                }

                                                code = interpreter.EvaluateScript(text, ref result);         /* EXEMPT */

                                                if (code == ReturnCode.Ok)
                                                {
                                                    code = interpreter.RequirePackage(
                                                        arguments[argumentIndex], version, exact, ref result);
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if ((argumentIndex != Index.Invalid) &&
                                                Option.LooksLikeOption(arguments[argumentIndex]))
                                            {
                                                result = OptionDictionary.BadOption(options, arguments[argumentIndex]);
                                            }
                                            else
                                            {
                                                result = "wrong # args: should be \"package require ?-exact? package ?version?\"";
                                            }

                                            code = ReturnCode.Error;
                                        }
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"package require ?-exact? package ?version?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "reset":
                            {
                                if (arguments.Count == 2)
                                {
                                    code = interpreter.ResetPkgIndexes(ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        result = String.Empty;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"package reset\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "scan":
                            {
                                if (arguments.Count >= 2)
                                {
                                    OptionDictionary options = new OptionDictionary(
                                        new IOption[] {
                                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-interpreter", null),
                                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-preferfilesystem", null),
                                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-preferhost", null),
                                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-host", null),
                                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-normal", null),
                                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-nonormal", null),
                                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-recursive", null),
                                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-resolve", null),
                                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-refresh", null),
                                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-autopath", 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, true, ref argumentIndex, ref result);
                                    }
                                    else
                                    {
                                        code = ReturnCode.Ok;
                                    }

                                    if (code == ReturnCode.Ok)
                                    {
                                        lock (interpreter.SyncRoot)         /* TRANSACTIONAL */
                                        {
                                            PackageIndexFlags flags;

                                            if (options.IsPresent("-interpreter"))
                                            {
                                                flags = interpreter.PackageIndexFlags;
                                            }
                                            else
                                            {
                                                flags = PackageIndexFlags.Default;
                                            }

                                            if (options.IsPresent("-preferfilesystem"))
                                            {
                                                flags |= PackageIndexFlags.PreferFileSystem;
                                            }

                                            if (options.IsPresent("-preferhost"))
                                            {
                                                flags |= PackageIndexFlags.PreferHost;
                                            }

                                            if (options.IsPresent("-host"))
                                            {
                                                flags |= PackageIndexFlags.Host;
                                            }

                                            if (options.IsPresent("-normal"))
                                            {
                                                flags |= PackageIndexFlags.Normal;
                                            }

                                            if (options.IsPresent("-nonormal"))
                                            {
                                                flags |= PackageIndexFlags.NoNormal;
                                            }

                                            if (options.IsPresent("-recursive"))
                                            {
                                                flags |= PackageIndexFlags.Recursive;
                                            }

                                            if (options.IsPresent("-refresh"))
                                            {
                                                flags |= PackageIndexFlags.Refresh;
                                            }

                                            if (options.IsPresent("-resolve"))
                                            {
                                                flags |= PackageIndexFlags.Resolve;
                                            }

                                            bool autoPath = false;

                                            if (options.IsPresent("-autopath"))
                                            {
                                                autoPath = true;
                                            }

                                            StringList paths;

                                            if (argumentIndex != Index.Invalid)
                                            {
                                                //
                                                // NOTE: Refresh the specified path list.
                                                //
                                                paths = new StringList(arguments, argumentIndex);
                                            }
                                            else
                                            {
                                                //
                                                // NOTE: Refresh the default path list.
                                                //
                                                paths = GlobalState.GetAutoPathList(interpreter, autoPath);

                                                //
                                                // NOTE: Did they request the auto-path be rebuilt?
                                                //
                                                if (autoPath)
                                                {
                                                    //
                                                    // NOTE: Since the actual auto-path may have changed,
                                                    //       update the variable now.  We disable traces
                                                    //       here because we manually rescan, if necessary,
                                                    //       below.
                                                    //
                                                    code = interpreter.SetLibraryVariableValue(
                                                        VariableFlags.SkipTrace, TclVars.AutoPath,
                                                        (paths != null) ? paths.ToString() : null,
                                                        ref result);
                                                }
                                            }

                                            if (code == ReturnCode.Ok)
                                            {
                                                PackageIndexDictionary packageIndexes = interpreter.CopyPackageIndexes();

                                                if (code == ReturnCode.Ok)
                                                {
                                                    code = PackageOps.FindAll(
                                                        interpreter, paths, flags, ref packageIndexes,
                                                        ref result);
                                                }

                                                if (code == ReturnCode.Ok)
                                                {
                                                    interpreter.PackageIndexes = packageIndexes;
                                                    result = String.Empty;
                                                }
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"package scan ?options? ?dir dir ...?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "unknown":
                            {
                                if ((arguments.Count == 2) || (arguments.Count == 3))
                                {
                                    if (arguments.Count == 3)
                                    {
                                        interpreter.PackageUnknown = arguments[2];
                                        result = String.Empty;
                                    }
                                    else
                                    {
                                        result = interpreter.PackageUnknown;
                                    }

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

                            case "vcompare":
                            {
                                if (arguments.Count == 4)
                                {
                                    Version version1 = null;

                                    code = Value.GetVersion(
                                        arguments[2], interpreter.CultureInfo,
                                        ref version1, ref result);

                                    Version version2 = null;

                                    if (code == ReturnCode.Ok)
                                    {
                                        code = Value.GetVersion(
                                            arguments[3], interpreter.CultureInfo,
                                            ref version2, ref result);
                                    }

                                    if (code == ReturnCode.Ok)
                                    {
                                        result = PackageOps.VersionCompare(version1, version2);
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"package vcompare version1 version2\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "versions":
                            {
                                if (arguments.Count == 3)
                                {
                                    code = interpreter.PkgVersions(
                                        arguments[2], ref result);
                                }
                                else
                                {
                                    result = "wrong # args: should be \"package versions package\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "vloaded":
                            {
                                if ((arguments.Count == 2) || (arguments.Count == 3))
                                {
                                    string pattern = null;

                                    if (arguments.Count == 3)
                                    {
                                        pattern = arguments[2];
                                    }

                                    code = interpreter.PkgLoaded(
                                        pattern, false, true, ref result);
                                }
                                else
                                {
                                    result = "wrong # args: should be \"package vloaded ?pattern?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "vsatisfies":
                            {
                                if (arguments.Count == 4)
                                {
                                    PackageFlags flags = interpreter.PackageFlags;

                                    if (!FlagOps.HasFlags(flags, PackageFlags.AlwaysSatisfy, true))
                                    {
                                        Version version1 = null;

                                        code = Value.GetVersion(arguments[2], interpreter.CultureInfo, ref version1, ref result);

                                        Version version2 = null;

                                        if (code == ReturnCode.Ok)
                                        {
                                            code = Value.GetVersion(
                                                arguments[3], interpreter.CultureInfo,
                                                ref version2, ref result);
                                        }

                                        if (code == ReturnCode.Ok)
                                        {
                                            result = PackageOps.VersionSatisfies(
                                                version1, version2, false);
                                        }
                                    }
                                    else
                                    {
                                        //
                                        // HACK: Always fake that this was a satisfied package request.
                                        //
                                        result = true;
                                        code   = ReturnCode.Ok;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"package vsatisfies version1 version2\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "withdraw":
                            {
                                if ((arguments.Count == 3) || (arguments.Count == 4))
                                {
                                    Version version = null;

                                    if (arguments.Count == 4)
                                    {
                                        code = Value.GetVersion(
                                            arguments[3], interpreter.CultureInfo,
                                            ref version, ref result);
                                    }

                                    if (code == ReturnCode.Ok)
                                    {
                                        code = interpreter.WithdrawPackage(
                                            arguments[2], version, ref result);
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"package withdraw package ?version?\"";
                                    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 \"package arg ?arg ...?\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
Beispiel #9
0
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            ReturnCode code = ReturnCode.Ok;

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    if (arguments.Count >= 2)
                    {
                        string subCommand = arguments[1];
                        bool   tried      = false;

                        code = ScriptOps.TryExecuteSubCommandFromEnsemble(
                            interpreter, this, clientData, arguments, true,
                            false, ref subCommand, ref tried, ref result);

                        if ((code == ReturnCode.Ok) && !tried)
                        {
                            switch (subCommand)
                            {
                            case "compare":
                            {
                                if (arguments.Count == 4)
                                {
                                    Guid guid1 = Guid.Empty;

                                    code = Value.GetGuid(arguments[2], interpreter.CultureInfo, ref guid1, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        Guid guid2 = Guid.Empty;

                                        code = Value.GetGuid(arguments[3], interpreter.CultureInfo, ref guid2, ref result);

                                        if (code == ReturnCode.Ok)
                                        {
                                            result = guid1.CompareTo(guid2);
                                        }
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"guid compare guid1 guid2\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "isnull":
                            {
                                if (arguments.Count == 3)
                                {
                                    Guid guid = Guid.Empty;

                                    code = Value.GetGuid(arguments[2], interpreter.CultureInfo, ref guid, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        result = ConversionOps.ToInt(guid.CompareTo(Guid.Empty) == 0);
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"guid isnull guid\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "isvalid":
                            {
                                if (arguments.Count == 3)
                                {
                                    Guid   guid        = Guid.Empty;
                                    Result localResult = null;

                                    result = ConversionOps.ToInt(Value.GetGuid(arguments[2], interpreter.CultureInfo, ref guid, ref localResult) == ReturnCode.Ok);
                                }
                                else
                                {
                                    result = "wrong # args: should be \"guid isvalid guid\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "new":
                            {
                                if (arguments.Count == 2)
                                {
                                    result = Guid.NewGuid();
                                }
                                else
                                {
                                    result = "wrong # args: should be \"guid new\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "null":
                            {
                                if (arguments.Count == 2)
                                {
                                    result = Guid.Empty;
                                }
                                else
                                {
                                    result = "wrong # args: should be \"guid null\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            default:
                            {
                                result = ScriptOps.BadSubCommand(
                                    interpreter, null, null, subCommand, this, null, null);

                                code = ReturnCode.Error;
                                break;
                            }
                            }
                        }
                    }
                    else
                    {
                        result = "wrong # args: should be \"guid option ?arg ...?\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
Beispiel #10
0
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            ReturnCode code = ReturnCode.Ok;

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    if (arguments.Count >= 2)
                    {
                        string subCommand = arguments[1];
                        bool   tried      = false;

                        code = ScriptOps.TryExecuteSubCommandFromEnsemble(
                            interpreter, this, clientData, arguments, true,
                            false, ref subCommand, ref tried, ref result);

                        if ((code == ReturnCode.Ok) && !tried)
                        {
                            switch (subCommand)
                            {
                            case "deserialize":
                            {
                                if (arguments.Count >= 4)
                                {
#if SERIALIZATION
                                    OptionDictionary options = ObjectOps.GetDeserializeOptions();

                                    int argumentIndex = Index.Invalid;

                                    code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        if ((argumentIndex != Index.Invalid) && ((argumentIndex + 2) == arguments.Count))
                                        {
                                            bool verbose;
                                            bool strictType;
                                            bool noCase;

                                            ObjectOps.ProcessGetTypeOptions(
                                                options, out verbose, out strictType, out noCase);

                                            Type        returnType;
                                            ObjectFlags objectFlags;
                                            string      objectName;
                                            string      interpName;
                                            bool        create;
                                            bool        dispose;
                                            bool        alias;
                                            bool        aliasRaw;
                                            bool        aliasAll;
                                            bool        aliasReference;
                                            bool        toString;

                                            ObjectOps.ProcessFixupReturnValueOptions(
                                                options, null, out returnType, out objectFlags,
                                                out objectName, out interpName, out create,
                                                out dispose, out alias, out aliasRaw, out aliasAll,
                                                out aliasReference, out toString);

                                            if (noCase)
                                            {
                                                objectFlags |= ObjectFlags.NoCase;
                                            }

                                            Variant  value    = null;
                                            Encoding encoding = null;

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

                                            if (code == ReturnCode.Ok)
                                            {
                                                Type       objectType = null;
                                                ResultList errors     = null;

                                                code = Value.GetType(interpreter,
                                                                     arguments[argumentIndex], null, interpreter.GetAppDomain(),
                                                                     Value.GetTypeValueFlags(strictType, verbose, noCase),
                                                                     interpreter.CultureInfo, ref objectType, ref errors);

                                                if (code == ReturnCode.Ok)
                                                {
                                                    byte[] bytes = null;

                                                    code = StringOps.GetBytes(
                                                        encoding, arguments[argumentIndex + 1],
                                                        EncodingType.Default, ref bytes, ref result);

                                                    if (code == ReturnCode.Ok)
                                                    {
                                                        object @object = null;

                                                        code = XmlOps.Deserialize(
                                                            objectType, bytes, ref @object, ref result);

                                                        if (code == ReturnCode.Ok)
                                                        {
                                                            ObjectOptionType objectOptionType =
                                                                ObjectOptionType.Deserialize |
                                                                ObjectOps.GetOptionType(aliasRaw, aliasAll);

                                                            code = MarshalOps.FixupReturnValue(
                                                                interpreter, interpreter.Binder, interpreter.CultureInfo,
                                                                returnType, objectFlags, ObjectOps.GetInvokeOptions(
                                                                    objectOptionType), objectOptionType, objectName, interpName,
                                                                @object, create, dispose, alias, aliasReference, toString,
                                                                ref result);
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    errors.Insert(0, String.Format(
                                                                      "type \"{0}\" not found",
                                                                      arguments[argumentIndex]));

                                                    result = errors;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if ((argumentIndex != Index.Invalid) &&
                                                Option.LooksLikeOption(arguments[argumentIndex]))
                                            {
                                                result = OptionDictionary.BadOption(options, arguments[argumentIndex]);
                                            }
                                            else
                                            {
                                                result = "wrong # args: should be \"xml deserialize ?options? type xml\"";
                                            }

                                            code = ReturnCode.Error;
                                        }
                                    }
#else
                                    result = "not implemented";
                                    code   = ReturnCode.Error;
#endif
                                }
                                else
                                {
                                    result = "wrong # args: should be \"xml deserialize ?options? type xml\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "serialize":
                            {
                                if (arguments.Count >= 4)
                                {
#if SERIALIZATION
                                    OptionDictionary options = ObjectOps.GetSerializeOptions();

                                    int argumentIndex = Index.Invalid;

                                    code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        if ((argumentIndex != Index.Invalid) && ((argumentIndex + 2) == arguments.Count))
                                        {
                                            bool noCase = false;

                                            if (options.IsPresent("-nocase"))
                                            {
                                                noCase = true;
                                            }

                                            bool strictType = false;

                                            if (options.IsPresent("-stricttype"))
                                            {
                                                strictType = true;
                                            }

                                            bool verbose = false;

                                            if (options.IsPresent("-verbose"))
                                            {
                                                verbose = true;
                                            }

                                            Variant  value    = null;
                                            Encoding encoding = null;

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

                                            if (code == ReturnCode.Ok)
                                            {
                                                Type       objectType = null;
                                                ResultList errors     = null;

                                                code = Value.GetType(interpreter,
                                                                     arguments[argumentIndex], null, interpreter.GetAppDomain(),
                                                                     Value.GetTypeValueFlags(strictType, verbose, noCase),
                                                                     interpreter.CultureInfo, ref objectType, ref errors);

                                                if (code == ReturnCode.Ok)
                                                {
                                                    IObject @object = null;

                                                    code = interpreter.GetObject(
                                                        arguments[argumentIndex + 1], LookupFlags.Default,
                                                        ref @object, ref result);

                                                    if (code == ReturnCode.Ok)
                                                    {
                                                        byte[] bytes = null;

                                                        code = XmlOps.Serialize(
                                                            (@object != null) ? @object.Value : null,
                                                            objectType, null, ref bytes, ref result);

                                                        if (code == ReturnCode.Ok)
                                                        {
                                                            string stringValue = null;

                                                            code = StringOps.GetString(
                                                                encoding, bytes, EncodingType.Default,
                                                                ref stringValue, ref result);

                                                            if (code == ReturnCode.Ok)
                                                            {
                                                                result = stringValue;
                                                            }
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    errors.Insert(0, String.Format(
                                                                      "type \"{0}\" not found",
                                                                      arguments[argumentIndex]));

                                                    result = errors;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if ((argumentIndex != Index.Invalid) &&
                                                Option.LooksLikeOption(arguments[argumentIndex]))
                                            {
                                                result = OptionDictionary.BadOption(options, arguments[argumentIndex]);
                                            }
                                            else
                                            {
                                                result = "wrong # args: should be \"xml serialize ?options? type object\"";
                                            }

                                            code = ReturnCode.Error;
                                        }
                                    }
#else
                                    result = "not implemented";
                                    code   = ReturnCode.Error;
#endif
                                }
                                else
                                {
                                    result = "wrong # args: should be \"xml serialize ?options? type object\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "validate":
                            {
                                if (arguments.Count == 4)
                                {
                                    XmlDocument document = null;

                                    code = XmlOps.LoadString(
                                        arguments[3], ref document, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        code = XmlOps.Validate(
                                            arguments[2], document, ref result);

                                        if (code == ReturnCode.Ok)
                                        {
                                            result = String.Empty;
                                        }
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"xml validate schemaXml documentXml\"";
                                    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 \"xml option ?arg ...?\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
Beispiel #11
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 \"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);
            }
        }
Beispiel #12
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);
        }
Beispiel #13
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 \"hash option ?arg ...?\"";
                return(ReturnCode.Error);
            }

            ReturnCode code;
            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)
            {
                return(code);
            }

            //
            // NOTE: These algorithms are known to be supported by the
            //       framework.
            //
            //       Normal: MD5, RIPEMD160, SHA, SHA1, SHA256, SHA384, SHA512
            //
            //        Keyed: MACTripleDES
            //
            //         HMAC: HMACMD5, HMACRIPEMD160, HMACSHA1, HMACSHA256,
            //               HMACSHA384, HMACSHA512
            //
            switch (subCommand)
            {
            case "keyed":
            {
                if (arguments.Count >= 4)
                {
                    OptionDictionary options = new OptionDictionary(
                        new IOption[] {
                            new Option(null, OptionFlags.None,
                                       Index.Invalid, Index.Invalid, "-raw",
                                       null),
                            new Option(null, OptionFlags.None,
                                       Index.Invalid, Index.Invalid, "-filename",
                                       null), /* COMPAT: Tcllib. */
                            new Option(null, OptionFlags.MustHaveEncodingValue,
                                       Index.Invalid, Index.Invalid, "-encoding",
                                       null),
                            new Option(null, OptionFlags.None,
                                       Index.Invalid, Index.Invalid,
                                       Option.EndOfOptions, null)
                        });

                    int argumentIndex = Index.Invalid;

                    code = interpreter.GetOptions(
                        options, arguments, 0, 2, Index.Invalid, false,
                        ref argumentIndex, ref result);

                    if (code == ReturnCode.Ok)
                    {
                        if ((argumentIndex != Index.Invalid) &&
                            ((argumentIndex + 2) <= arguments.Count) &&
                            ((argumentIndex + 3) >= arguments.Count))
                        {
                            Variant value = null;
                            bool    raw   = false;

                            if (options.IsPresent("-raw"))
                            {
                                raw = true;
                            }

                            bool isFileName = false;

                            if (options.IsPresent("-filename", ref value))
                            {
                                isFileName = true;
                            }

                            Encoding encoding = null;

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

                            if (code == ReturnCode.Ok)
                            {
                                try
                                {
                                    using (KeyedHashAlgorithm algorithm =
                                               KeyedHashAlgorithm.Create(
                                                   arguments[argumentIndex]))
                                    {
                                        if (algorithm != null)
                                        {
                                            algorithm.Initialize();

                                            if ((argumentIndex + 3) == arguments.Count)
                                            {
                                                byte[] bytes = null;

                                                code = StringOps.GetBytes(
                                                    encoding, arguments[argumentIndex + 2],
                                                    EncodingType.Binary, ref bytes, ref result);

                                                if (code == ReturnCode.Ok)
                                                {
                                                    algorithm.Key = bytes;
                                                }
                                            }

                                            if (code == ReturnCode.Ok)
                                            {
                                                if (isFileName)
                                                {
                                                    Stream stream = null;

                                                    try
                                                    {
                                                        code = RuntimeOps.NewStream(
                                                            interpreter,
                                                            arguments[argumentIndex + 1],
                                                            FileMode.Open, FileAccess.Read,
                                                            ref stream, ref result);

                                                        if (code == ReturnCode.Ok)
                                                        {
                                                            if (raw)
                                                            {
                                                                result = new ByteList(
                                                                    algorithm.ComputeHash(stream));
                                                            }
                                                            else
                                                            {
                                                                result = FormatOps.Hash(
                                                                    algorithm.ComputeHash(stream));
                                                            }
                                                        }
                                                    }
                                                    finally
                                                    {
                                                        if (stream != null)
                                                        {
                                                            stream.Close();
                                                            stream = null;
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    byte[] bytes = null;

                                                    code = StringOps.GetBytes(
                                                        encoding, arguments[argumentIndex + 1],
                                                        EncodingType.Binary, ref bytes, ref result);

                                                    if (raw)
                                                    {
                                                        result = new ByteList(
                                                            algorithm.ComputeHash(bytes));
                                                    }
                                                    else
                                                    {
                                                        result = FormatOps.Hash(
                                                            algorithm.ComputeHash(bytes));
                                                    }
                                                }
                                            }
                                        }
                                        else
                                        {
                                            result = String.Format(
                                                "unsupported keyed hash algorithm \"{0}\"",
                                                arguments[argumentIndex]);

                                            code = ReturnCode.Error;
                                        }
                                    }
                                }
                                catch (Exception e)
                                {
                                    Engine.SetExceptionErrorCode(interpreter, e);

                                    result = e;
                                    code   = ReturnCode.Error;
                                }
                            }
                        }
                        else
                        {
                            if ((argumentIndex != Index.Invalid) &&
                                Option.LooksLikeOption(arguments[argumentIndex]))
                            {
                                result = OptionDictionary.BadOption(
                                    options, arguments[argumentIndex]);
                            }
                            else
                            {
                                result = String.Format(
                                    "wrong # args: should be \"{0} {1} ?options? algorithm string ?key?\"",
                                    this.Name, subCommand);
                            }

                            code = ReturnCode.Error;
                        }
                    }
                }
                else
                {
                    result = String.Format(
                        "wrong # args: should be \"{0} {1} ?options? algorithm string ?key?\"",
                        this.Name, subCommand);

                    code = ReturnCode.Error;
                }
                break;
            }

            case "list":
            {
                if ((arguments.Count == 2) || (arguments.Count == 3))
                {
                    string type = null;

                    if (arguments.Count == 3)
                    {
                        type = arguments[2];
                    }

                    switch (type)
                    {
                    case null:
                    case "all":
                    {
                        StringList list = new StringList();

                        lock (syncRoot)
                        {
                            if (defaultAlgorithms != null)
                            {
                                list.AddRange(defaultAlgorithms);
                            }
                        }

                        if (keyedHashAlgorithmNames != null)
                        {
                            foreach (string hashAlgorithmName in keyedHashAlgorithmNames)
                            {
                                list.Add(StringList.MakeList("keyed", hashAlgorithmName));
                            }
                        }

                        if (macHashAlgorithmNames != null)
                        {
                            foreach (string hashAlgorithmName in macHashAlgorithmNames)
                            {
                                list.Add(StringList.MakeList("mac", hashAlgorithmName));
                            }
                        }

                        if (normalHashAlgorithmNames != null)
                        {
                            foreach (string hashAlgorithmName in normalHashAlgorithmNames)
                            {
                                list.Add(StringList.MakeList("normal", hashAlgorithmName));
                            }
                        }

                        result = list;
                        break;
                    }

                    case "default":
                    {
                        lock (syncRoot)
                        {
                            result = (defaultAlgorithms != null) ?
                                     new StringList(defaultAlgorithms) : null;
                        }
                        break;
                    }

                    case "keyed":
                    {
                        result = (keyedHashAlgorithmNames != null) ?
                                 new StringList(keyedHashAlgorithmNames) : null;

                        break;
                    }

                    case "mac":
                    {
                        result = (macHashAlgorithmNames != null) ?
                                 new StringList(macHashAlgorithmNames) : null;

                        break;
                    }

                    case "normal":
                    {
                        result = (normalHashAlgorithmNames != null) ?
                                 new StringList(normalHashAlgorithmNames) : null;

                        break;
                    }

                    default:
                    {
                        result = "unknown algorithm list, must be: all, default, keyed, mac, or normal";
                        code   = ReturnCode.Error;
                        break;
                    }
                    }
                }
                else
                {
                    result = String.Format(
                        "wrong # args: should be \"{0} {1} ?type?\"",
                        this.Name, subCommand);

                    code = ReturnCode.Error;
                }
                break;
            }

            case "mac":
            {
                if (arguments.Count >= 4)
                {
                    OptionDictionary options = new OptionDictionary(
                        new IOption[] {
                            new Option(null, OptionFlags.None,
                                       Index.Invalid, Index.Invalid, "-raw",
                                       null),
                            new Option(null, OptionFlags.None,
                                       Index.Invalid, Index.Invalid, "-filename",
                                       null), /* COMPAT: Tcllib. */
                            new Option(null, OptionFlags.MustHaveEncodingValue,
                                       Index.Invalid, Index.Invalid, "-encoding",
                                       null),
                            new Option(null, OptionFlags.None,
                                       Index.Invalid, Index.Invalid,
                                       Option.EndOfOptions, null)
                        });

                    int argumentIndex = Index.Invalid;

                    code = interpreter.GetOptions(
                        options, arguments, 0, 2, Index.Invalid, false,
                        ref argumentIndex, ref result);

                    if (code == ReturnCode.Ok)
                    {
                        if ((argumentIndex != Index.Invalid) &&
                            ((argumentIndex + 2) <= arguments.Count) &&
                            ((argumentIndex + 3) >= arguments.Count))
                        {
                            Variant value = null;
                            bool    raw   = false;

                            if (options.IsPresent("-raw"))
                            {
                                raw = true;
                            }

                            bool isFileName = false;

                            if (options.IsPresent("-filename", ref value))
                            {
                                isFileName = true;
                            }

                            Encoding encoding = null;

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

                            if (code == ReturnCode.Ok)
                            {
                                try
                                {
                                    using (HMAC algorithm = HMAC.Create(
                                               arguments[argumentIndex]))
                                    {
                                        if (algorithm != null)
                                        {
                                            algorithm.Initialize();

                                            if ((argumentIndex + 3) == arguments.Count)
                                            {
                                                byte[] bytes = null;

                                                code = StringOps.GetBytes(
                                                    encoding, arguments[argumentIndex + 2],
                                                    EncodingType.Binary, ref bytes, ref result);

                                                if (code == ReturnCode.Ok)
                                                {
                                                    algorithm.Key = bytes;
                                                }
                                            }

                                            if (code == ReturnCode.Ok)
                                            {
                                                if (isFileName)
                                                {
                                                    Stream stream = null;

                                                    try
                                                    {
                                                        code = RuntimeOps.NewStream(
                                                            interpreter,
                                                            arguments[argumentIndex + 1],
                                                            FileMode.Open, FileAccess.Read,
                                                            ref stream, ref result);

                                                        if (code == ReturnCode.Ok)
                                                        {
                                                            if (raw)
                                                            {
                                                                result = new ByteList(
                                                                    algorithm.ComputeHash(stream));
                                                            }
                                                            else
                                                            {
                                                                result = FormatOps.Hash(
                                                                    algorithm.ComputeHash(stream));
                                                            }
                                                        }
                                                    }
                                                    finally
                                                    {
                                                        if (stream != null)
                                                        {
                                                            stream.Close();
                                                            stream = null;
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    byte[] bytes = null;

                                                    code = StringOps.GetBytes(
                                                        encoding, arguments[argumentIndex + 1],
                                                        EncodingType.Binary, ref bytes, ref result);

                                                    if (raw)
                                                    {
                                                        result = new ByteList(
                                                            algorithm.ComputeHash(bytes));
                                                    }
                                                    else
                                                    {
                                                        result = FormatOps.Hash(
                                                            algorithm.ComputeHash(bytes));
                                                    }
                                                }
                                            }
                                        }
                                        else
                                        {
                                            result = String.Format(
                                                "unsupported hmac algorithm \"{0}\"",
                                                arguments[argumentIndex]);

                                            code = ReturnCode.Error;
                                        }
                                    }
                                }
                                catch (Exception e)
                                {
                                    Engine.SetExceptionErrorCode(interpreter, e);

                                    result = e;
                                    code   = ReturnCode.Error;
                                }
                            }
                        }
                        else
                        {
                            if ((argumentIndex != Index.Invalid) &&
                                Option.LooksLikeOption(arguments[argumentIndex]))
                            {
                                result = OptionDictionary.BadOption(
                                    options, arguments[argumentIndex]);
                            }
                            else
                            {
                                result = String.Format(
                                    "wrong # args: should be \"{0} {1} ?options? algorithm string ?key?\"",
                                    this.Name, subCommand);
                            }

                            code = ReturnCode.Error;
                        }
                    }
                }
                else
                {
                    result = String.Format(
                        "wrong # args: should be \"{0} {1} ?options? algorithm string ?key?\"",
                        this.Name, subCommand);

                    code = ReturnCode.Error;
                }
                break;
            }

            case "normal":
            {
                if (arguments.Count >= 4)
                {
                    OptionDictionary options = new OptionDictionary(
                        new IOption[] {
                            new Option(null, OptionFlags.None,
                                       Index.Invalid, Index.Invalid, "-raw",
                                       null),
                            new Option(null, OptionFlags.None,
                                       Index.Invalid, Index.Invalid, "-filename",
                                       null), /* COMPAT: Tcllib. */
                            new Option(null, OptionFlags.MustHaveEncodingValue,
                                       Index.Invalid, Index.Invalid, "-encoding",
                                       null),
                            new Option(null, OptionFlags.None,
                                       Index.Invalid, Index.Invalid,
                                       Option.EndOfOptions, null)
                        });

                    int argumentIndex = Index.Invalid;

                    code = interpreter.GetOptions(
                        options, arguments, 0, 2, Index.Invalid, false,
                        ref argumentIndex, ref result);

                    if (code == ReturnCode.Ok)
                    {
                        if ((argumentIndex != Index.Invalid) &&
                            ((argumentIndex + 2) == arguments.Count))
                        {
                            Variant value = null;
                            bool    raw   = false;

                            if (options.IsPresent("-raw"))
                            {
                                raw = true;
                            }

                            bool isFileName = false;

                            if (options.IsPresent("-filename", ref value))
                            {
                                isFileName = true;
                            }

                            Encoding encoding = null;

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

                            if (code == ReturnCode.Ok)
                            {
                                try
                                {
                                    using (HashAlgorithm algorithm =
                                               HashAlgorithm.Create(
                                                   arguments[argumentIndex]))
                                    {
                                        if (algorithm != null)
                                        {
                                            algorithm.Initialize();

                                            if (isFileName)
                                            {
                                                Stream stream = null;

                                                try
                                                {
                                                    code = RuntimeOps.NewStream(
                                                        interpreter,
                                                        arguments[argumentIndex + 1],
                                                        FileMode.Open, FileAccess.Read,
                                                        ref stream, ref result);

                                                    if (code == ReturnCode.Ok)
                                                    {
                                                        if (raw)
                                                        {
                                                            result = new ByteList(
                                                                algorithm.ComputeHash(stream));
                                                        }
                                                        else
                                                        {
                                                            result = FormatOps.Hash(
                                                                algorithm.ComputeHash(stream));
                                                        }
                                                    }
                                                }
                                                finally
                                                {
                                                    if (stream != null)
                                                    {
                                                        stream.Close();
                                                        stream = null;
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                byte[] bytes = null;

                                                code = StringOps.GetBytes(
                                                    encoding, arguments[argumentIndex + 1],
                                                    EncodingType.Binary, ref bytes, ref result);

                                                if (code == ReturnCode.Ok)
                                                {
                                                    if (raw)
                                                    {
                                                        result = new ByteList(
                                                            algorithm.ComputeHash(bytes));
                                                    }
                                                    else
                                                    {
                                                        result = FormatOps.Hash(
                                                            algorithm.ComputeHash(bytes));
                                                    }
                                                }
                                            }
                                        }
                                        else
                                        {
                                            result = String.Format(
                                                "unsupported hash algorithm \"{0}\"",
                                                arguments[argumentIndex]);

                                            code = ReturnCode.Error;
                                        }
                                    }
                                }
                                catch (Exception e)
                                {
                                    Engine.SetExceptionErrorCode(interpreter, e);

                                    result = e;
                                    code   = ReturnCode.Error;
                                }
                            }
                        }
                        else
                        {
                            if ((argumentIndex != Index.Invalid) &&
                                Option.LooksLikeOption(arguments[argumentIndex]))
                            {
                                result = OptionDictionary.BadOption(
                                    options, arguments[argumentIndex]);
                            }
                            else
                            {
                                result = String.Format(
                                    "wrong # args: should be \"{0} {1} ?options? algorithm string\"",
                                    this.Name, subCommand);
                            }

                            code = ReturnCode.Error;
                        }
                    }
                }
                else
                {
                    result = String.Format(
                        "wrong # args: should be \"{0} {1} ?options? algorithm string\"",
                        this.Name, subCommand);

                    code = ReturnCode.Error;
                }
                break;
            }

            default:
            {
                result = ScriptOps.BadSubCommand(
                    interpreter, null, null, subCommand, this, null, null);

                code = ReturnCode.Error;
                break;
            }
            }

            return(code);
        }
Beispiel #14
0
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            ReturnCode code = ReturnCode.Ok;

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    if (arguments.Count >= 4)
                    {
                        StringList list = null;

                        //
                        // WARNING: Cannot cache list representation here, the list
                        //          is modified below.
                        //
                        code = Parser.SplitList(
                            interpreter, arguments[1], 0,
                            Length.Invalid, false, ref list,
                            ref result);

                        if (code == ReturnCode.Ok)
                        {
                            int firstIndex = Index.Invalid;

                            code = Value.GetIndex(
                                arguments[2], list.Count, ValueFlags.AnyIndex,
                                interpreter.CultureInfo, ref firstIndex,
                                ref result);

                            if (code == ReturnCode.Ok)
                            {
                                int lastIndex = Index.Invalid;

                                code = Value.GetIndex(
                                    arguments[3], list.Count, ValueFlags.AnyIndex,
                                    interpreter.CultureInfo, ref lastIndex,
                                    ref result);

                                if (code == ReturnCode.Ok)
                                {
                                    if (firstIndex < 0)
                                    {
                                        firstIndex = 0;
                                    }

                                    if ((firstIndex < list.Count) || (list.Count == 0))
                                    {
                                        if (list.Count > 0)
                                        {
                                            if (lastIndex >= list.Count)
                                            {
                                                lastIndex = list.Count - 1;
                                            }

                                            int numToDelete;

                                            if (firstIndex <= lastIndex)
                                            {
                                                numToDelete = (lastIndex - firstIndex + 1);
                                            }
                                            else
                                            {
                                                numToDelete = 0;
                                            }

                                            list.RemoveRange(firstIndex, numToDelete);

                                            if (arguments.Count >= 5)
                                            {
                                                list.InsertRange(firstIndex, arguments, 4);
                                            }

                                            result = list;
                                        }
                                        else if (ScriptOps.HasFlags(interpreter,
                                                                    InterpreterFlags.ReplaceEmptyListOk, true))
                                        {
                                            result = list;
                                        }
                                        else
                                        {
                                            result = String.Format(
                                                "list doesn't contain element {0}", arguments[2]);

                                            code = ReturnCode.Error;
                                        }
                                    }
                                    else
                                    {
                                        result = String.Format(
                                            "list doesn't contain element {0}", arguments[2]);

                                        code = ReturnCode.Error;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        result = "wrong # args: should be \"lreplace list first last ?value ...?\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
Beispiel #15
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);
        }
Beispiel #16
0
        ///////////////////////////////////////////////////////////////////////

        #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);
        }
Beispiel #17
0
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            ReturnCode code = ReturnCode.Ok;

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    if (arguments.Count >= 2)
                    {
                        string fileName = arguments[1];

                        if (interpreter.HasChannels(ref result))
                        {
                            MapOpenAccess access      = MapOpenAccess.Default;
                            int           permissions = 0; // NOTE: This is ONLY parsed, NOT used for opening the file.
                            string        type        = null;

                            if (arguments.Count >= 3)
                            {
                                Result enumString = arguments[2];

                                if (!String.IsNullOrEmpty(enumString))
                                {
                                    //
                                    // HACK: Translate illegal mode char "+" to what our Enum uses.
                                    //       This strategy will backfire later if we ever decide to
                                    //       allow parsing of the access mode as "flags" (via GetOptions).
                                    //
                                    enumString = enumString.Replace(Characters.PlusSign.ToString(), "Plus");
                                }

                                code = StringOps.StringToEnumList(interpreter, enumString, ref enumString);

                                if (code == ReturnCode.Ok)
                                {
                                    object enumValue = EnumOps.TryParseEnum(
                                        typeof(MapOpenAccess), enumString,
                                        true, true);

                                    if (enumValue is MapOpenAccess)
                                    {
                                        access = (MapOpenAccess)enumValue;
                                    }
                                    else
                                    {
                                        enumString = ScriptOps.BadValue(
                                            "invalid", "access mode", arguments[2],
                                            Enum.GetNames(typeof(MapOpenAccess)), null, null);

                                        code = ReturnCode.Error;
                                    }
                                }

                                if (code != ReturnCode.Ok)
                                {
                                    //
                                    // NOTE: Transfer local result from above and add to the error info.
                                    //
                                    result = enumString;

                                    Engine.AddErrorInformation(interpreter, result,
                                                               String.Format("{0}    while processing open access modes \"{1}\"",
                                                                             Environment.NewLine, FormatOps.Ellipsis(arguments[2])));
                                }
                            }

                            if ((code == ReturnCode.Ok) && (arguments.Count >= 4))
                            {
                                code = Value.GetInteger2(
                                    (IGetValue)arguments[3], ValueFlags.AnyInteger,
                                    interpreter.CultureInfo, ref permissions, ref result);
                            }

                            if (code == ReturnCode.Ok)
                            {
                                if (arguments.Count >= 5)
                                {
                                    type = arguments[4];
                                }

                                OptionDictionary options = new OptionDictionary(
                                    new IOption[] {
#if CONSOLE
                                    new Option(null, OptionFlags.None, 1, Index.Invalid, "-stdin", null),
                                    new Option(null, OptionFlags.None, 1, Index.Invalid, "-stdout", null),
                                    new Option(null, OptionFlags.None, 1, Index.Invalid, "-stderr", null),
#else
                                    new Option(null, OptionFlags.Unsupported, 1, Index.Invalid, "-stdin", null),
                                    new Option(null, OptionFlags.Unsupported, 1, Index.Invalid, "-stdout", null),
                                    new Option(null, OptionFlags.Unsupported, 1, Index.Invalid, "-stderr", null),
#endif
                                    new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-channelid", null),
                                    new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-buffersize", null),
                                    new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-autoflush", null),
                                    new Option(typeof(HostStreamFlags), OptionFlags.MustHaveEnumValue, Index.Invalid, Index.Invalid, "-streamflags",
                                               new Variant(HostStreamFlags.Default)),
                                    new Option(typeof(FileOptions), OptionFlags.MustHaveEnumValue, Index.Invalid, Index.Invalid, "-options",
                                               new Variant(FileOptions.None)),
                                    new Option(typeof(FileShare), OptionFlags.MustHaveEnumValue, Index.Invalid, Index.Invalid, "-share",
                                               new Variant(FileShare.Read))
                                });

                                int argumentIndex = Index.Invalid;

                                if (arguments.Count > 5)
                                {
                                    code = interpreter.GetOptions(options, arguments, 0, 5, Index.Invalid, true, ref argumentIndex, ref result);
                                }
                                else
                                {
                                    code = ReturnCode.Ok;
                                }

                                if (code == ReturnCode.Ok)
                                {
                                    if (argumentIndex == Index.Invalid)
                                    {
                                        Variant value     = null;
                                        string  channelId = null;

                                        if (options.IsPresent("-channelid", ref value))
                                        {
                                            channelId = value.ToString();
                                        }

                                        if ((channelId == null) ||
                                            (interpreter.DoesChannelExist(channelId) != ReturnCode.Ok))
                                        {
#if CONSOLE
                                            if (options.IsPresent("-stdin"))
                                            {
                                                //
                                                // NOTE: Enforce the proper access for the standard input
                                                //       channel.
                                                //
                                                if (access == MapOpenAccess.RdOnly)
                                                {
                                                    try
                                                    {
                                                        IStreamHost streamHost = interpreter.Host;

                                                        //
                                                        // NOTE: *WARNING* This option causes the "fileName",
                                                        //       "access", "permissions", and "type" arguments
                                                        //       to be ignored.
                                                        //
                                                        lock (interpreter.SyncRoot) /* TRANSACTIONAL */
                                                        {
                                                            if (streamHost.In == null)
                                                            {
                                                                int?bufferSize = null;

                                                                if (options.IsPresent("-buffersize", ref value))
                                                                {
                                                                    bufferSize = (int)value.Value;
                                                                }

                                                                streamHost.In = (bufferSize != null) ?
                                                                                Console.OpenStandardInput((int)bufferSize) :
                                                                                Console.OpenStandardInput();
                                                            }
                                                        }

                                                        code = interpreter.ModifyStandardChannels(
                                                            streamHost, channelId, ChannelType.Input |
                                                            ChannelType.ErrorOnExist, ref result);

                                                        if (code == ReturnCode.Ok)
                                                        {
                                                            result = (channelId != null) ? channelId : StandardChannel.Input;
                                                        }
                                                    }
                                                    catch (Exception e)
                                                    {
                                                        Engine.SetExceptionErrorCode(interpreter, e);

                                                        result = e;
                                                        code   = ReturnCode.Error;
                                                    }
                                                }
                                                else
                                                {
                                                    result = String.Format(
                                                        "illegal access mode \"{0}\", standard input " +
                                                        "can only be opened using access mode \"{1}\"",
                                                        access, MapOpenAccess.RdOnly);

                                                    code = ReturnCode.Error;
                                                }
                                            }
                                            else if (options.IsPresent("-stdout"))
                                            {
                                                //
                                                // NOTE: Enforce the proper access for the standard output
                                                //       channel.
                                                //
                                                if (access == MapOpenAccess.WrOnly)
                                                {
                                                    try
                                                    {
                                                        IStreamHost streamHost = interpreter.Host;

                                                        //
                                                        // NOTE: *WARNING* This option causes the "fileName",
                                                        //       "access", "permissions", and "type" arguments
                                                        //       to be ignored.
                                                        //
                                                        lock (interpreter.SyncRoot) /* TRANSACTIONAL */
                                                        {
                                                            if (streamHost.Out == null)
                                                            {
                                                                int?bufferSize = null;

                                                                if (options.IsPresent("-buffersize", ref value))
                                                                {
                                                                    bufferSize = (int)value.Value;
                                                                }

                                                                streamHost.Out = (bufferSize != null) ?
                                                                                 Console.OpenStandardOutput((int)bufferSize) :
                                                                                 Console.OpenStandardOutput();
                                                            }
                                                        }

                                                        code = interpreter.ModifyStandardChannels(
                                                            streamHost, channelId, ChannelType.Output |
                                                            ChannelType.ErrorOnExist, ref result);

                                                        if (code == ReturnCode.Ok)
                                                        {
                                                            result = (channelId != null) ? channelId : StandardChannel.Output;
                                                        }
                                                    }
                                                    catch (Exception e)
                                                    {
                                                        Engine.SetExceptionErrorCode(interpreter, e);

                                                        result = e;
                                                        code   = ReturnCode.Error;
                                                    }
                                                }
                                                else
                                                {
                                                    result = String.Format(
                                                        "illegal access mode \"{0}\", standard output " +
                                                        "can only be opened using access mode \"{1}\"",
                                                        access, MapOpenAccess.WrOnly);

                                                    code = ReturnCode.Error;
                                                }
                                            }
                                            else if (options.IsPresent("-stderr"))
                                            {
                                                //
                                                // NOTE: Enforce the proper access for the standard error
                                                //       channel.
                                                //
                                                if (access == MapOpenAccess.WrOnly)
                                                {
                                                    try
                                                    {
                                                        IStreamHost streamHost = interpreter.Host;

                                                        //
                                                        // NOTE: *WARNING* This option causes the "fileName",
                                                        //       "access", "permissions", and "type" arguments
                                                        //       to be ignored.
                                                        //
                                                        lock (interpreter.SyncRoot) /* TRANSACTIONAL */
                                                        {
                                                            if (streamHost.Error == null)
                                                            {
                                                                int?bufferSize = null;

                                                                if (options.IsPresent("-buffersize", ref value))
                                                                {
                                                                    bufferSize = (int)value.Value;
                                                                }

                                                                streamHost.Error = (bufferSize != null) ?
                                                                                   Console.OpenStandardError((int)bufferSize) :
                                                                                   Console.OpenStandardError();
                                                            }
                                                        }

                                                        code = interpreter.ModifyStandardChannels(
                                                            streamHost, channelId, ChannelType.Error |
                                                            ChannelType.ErrorOnExist, ref result);

                                                        if (code == ReturnCode.Ok)
                                                        {
                                                            result = (channelId != null) ? channelId : StandardChannel.Error;
                                                        }
                                                    }
                                                    catch (Exception e)
                                                    {
                                                        Engine.SetExceptionErrorCode(interpreter, e);

                                                        result = e;
                                                        code   = ReturnCode.Error;
                                                    }
                                                }
                                                else
                                                {
                                                    result = String.Format(
                                                        "illegal access mode \"{0}\", standard error " +
                                                        "can only be opened using access mode \"{1}\"",
                                                        access, MapOpenAccess.WrOnly);

                                                    code = ReturnCode.Error;
                                                }
                                            }
                                            else
#endif
                                            {
                                                Stream stream    = null;
                                                bool   autoFlush = false;

                                                switch (type)
                                                {
                                                case null:                      /* FALL-THROUGH */
                                                case /* String.Empty */ "":     /* FALL-THROUGH */
                                                case "file":
                                                {
                                                    try
                                                    {
                                                        HostStreamFlags hostStreamFlags = HostStreamFlags.OpenCommand;
                                                        FileAccess      fileAccess      = FileOps.FileAccessFromAccess(access);
                                                        FileMode        fileMode        = FileOps.FileModeFromAccess(access);
                                                        FileShare       fileShare       = FileShare.Read;

                                                        if (options.IsPresent("-streamflags", ref value))
                                                        {
                                                            hostStreamFlags = (HostStreamFlags)value.Value;
                                                        }

                                                        if (options.IsPresent("-share", ref value))
                                                        {
                                                            fileShare = (FileShare)value.Value;
                                                        }

                                                        int bufferSize = Channel.DefaultBufferSize;

                                                        if (options.IsPresent("-buffersize", ref value))
                                                        {
                                                            bufferSize = (int)value.Value;
                                                        }

                                                        FileOptions fileOptions = FileOptions.None;

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

                                                        if (options.IsPresent("-autoflush"))
                                                        {
                                                            autoFlush = true;
                                                        }

                                                        bool seekToEof = false;

                                                        //
                                                        // HACK: Check for special case where they want to Append
                                                        //       and Read/ReadWrite.
                                                        //
                                                        if (((fileAccess == FileAccess.Read) ||
                                                             (fileAccess == FileAccess.ReadWrite)) &&
                                                            (FlagOps.HasFlags(access, MapOpenAccess.SeekToEof, true) ||
                                                             FlagOps.HasFlags(access, MapOpenAccess.Append, true)))
                                                        {
                                                            seekToEof = true;
                                                        }

                                                        code = interpreter.GetStream(
                                                            fileName, fileMode, fileAccess, fileShare, bufferSize,
                                                            fileOptions, Channel.StrictGetStream, ref hostStreamFlags,
                                                            ref stream, ref result);

                                                        if (code == ReturnCode.Ok)
                                                        {
                                                            if ((stream != null) && seekToEof)
                                                            {
                                                                stream.Seek(0, SeekOrigin.End);
                                                            }
                                                        }
                                                    }
                                                    catch (Exception e)
                                                    {
                                                        Engine.SetExceptionErrorCode(interpreter, e);

                                                        result = e;
                                                        code   = ReturnCode.Error;
                                                    }
                                                    break;
                                                }

                                                default:
                                                {
                                                    result = String.Format(
                                                        "unsupported channel type \"{0}\"",
                                                        type);

                                                    code = ReturnCode.Error;
                                                    break;
                                                }
                                                }

                                                //
                                                // NOTE: Did we manage to open the file successfully?
                                                //
                                                if (code == ReturnCode.Ok)
                                                {
                                                    StreamFlags flags = StreamFlags.PreventClose;

                                                    if (channelId == null)
                                                    {
                                                        channelId = FormatOps.Id("file", null, interpreter.NextId());
                                                    }

                                                    code = interpreter.AddFileOrSocketChannel(
                                                        channelId, stream, options, flags,
                                                        FlagOps.HasFlags(access, MapOpenAccess.Append, true),
                                                        autoFlush, null, ref result);

                                                    if (code == ReturnCode.Ok)
                                                    {
                                                        result = channelId;
                                                    }
                                                }
                                            }
                                        }
                                        else
                                        {
                                            result = String.Format(
                                                "can't add \"{0}\": channel already exists",
                                                channelId);

                                            code = ReturnCode.Error;
                                        }
                                    }
                                    else
                                    {
                                        result = "wrong # args: should be \"open fileName ?access? ?permissions? ?type? ?options?\"";
                                        code   = ReturnCode.Error;
                                    }
                                }
                            }
                        }
                        else
                        {
                            code = ReturnCode.Error;
                        }
                    }
                    else
                    {
                        result = "wrong # args: should be \"open fileName ?access? ?permissions? ?type? ?options?\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
Beispiel #18
0
        ///////////////////////////////////////////////////////////////////////

        public ReturnCode RenameImport(
            string oldQualifiedName,
            string newQualifiedName,
            bool strict,
            ref Result error
            )
        {
            CheckDisposed();

            if (imports == null)
            {
                error = String.Format(
                    "imports not available in namespace \"{0}\"",
                    GetDisplayName());

                return(ReturnCode.Error);
            }

            INamespace oldNamespace = NamespaceOps.LookupParent(
                interpreter, oldQualifiedName, false, true, false, ref error);

            if (oldNamespace == null)
            {
                return(ReturnCode.Error);
            }

            INamespace newNamespace = NamespaceOps.LookupParent(
                interpreter, newQualifiedName, false, true, false, ref error);

            if (newNamespace == null)
            {
                return(ReturnCode.Error);
            }

            int count = 0;

            ObjectDictionary localImports = new ObjectDictionary(
                (IDictionary <string, object>)imports);

            foreach (KeyValuePair <string, object> pair in localImports)
            {
                IAlias alias = pair.Value as IAlias;

                if (alias == null)
                {
                    continue;
                }

                string aliasName = NamespaceOps.GetAliasName(alias);

                if (NamespaceOps.IsSame(
                        alias.TargetNamespace, oldNamespace) &&
                    StringOps.Match(interpreter, MatchMode.Glob, aliasName,
                                    ScriptOps.MakeCommandName(oldQualifiedName), false))
                {
                    alias.TargetNamespace = newNamespace;
                    NamespaceOps.SetAliasName(alias, newQualifiedName);

                    return(ReturnCode.Ok);
                }
                else if (strict)
                {
                    error = String.Format(
                        "import \"{0}\" is not an alias in namespace \"{1}\"",
                        oldQualifiedName, GetDisplayName());

                    return(ReturnCode.Error);
                }
            }

            if (strict && (count == 0))
            {
                error = String.Format(
                    "no imports matched name \"{0}\" in namespace \"{1}\"",
                    oldQualifiedName, GetDisplayName());

                return(ReturnCode.Error);
            }

            return(ReturnCode.Ok);
        }
Beispiel #19
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)
                {
                    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)
                        {
                            if (code == ReturnCode.Ok)
                            {
                                switch (subCommand)
                                {
                                case "command":
                                {
                                    if (arguments.Count >= 3)
                                    {
                                        OptionDictionary options = new OptionDictionary(
                                            new IOption[] {
                                                new Option(typeof(EngineFlags), OptionFlags.MustHaveEnumValue | OptionFlags.Unsafe,
                                                           Index.Invalid, Index.Invalid, "-engineflags", new Variant(interpreter.EngineFlags)),
                                                new Option(typeof(SubstitutionFlags), OptionFlags.MustHaveEnumValue, Index.Invalid, Index.Invalid, "-substitutionflags",
                                                           new Variant(interpreter.SubstitutionFlags)),
                                                new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-startindex", null),
                                                new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-characters", null),
                                                new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-nested", null),
                                                new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-noready", null),
                                                new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null)
                                            });

                                        int argumentIndex = Index.Invalid;

                                        code = interpreter.GetOptions(
                                            options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex,
                                            ref result);

                                        if (code == ReturnCode.Ok)
                                        {
                                            if ((argumentIndex != Index.Invalid) &&
                                                ((argumentIndex + 1) == arguments.Count))
                                            {
                                                Variant     value       = null;
                                                EngineFlags engineFlags = interpreter.EngineFlags;

                                                if (options.IsPresent("-engineflags", ref value))
                                                {
                                                    engineFlags = (EngineFlags)value.Value;
                                                }

                                                SubstitutionFlags substitutionFlags = interpreter.SubstitutionFlags;

                                                if (options.IsPresent("-substitutionflags", ref value))
                                                {
                                                    substitutionFlags = (SubstitutionFlags)value.Value;
                                                }

                                                int startIndex = 0;

                                                if (options.IsPresent("-startindex", ref value))
                                                {
                                                    startIndex = (int)value.Value;
                                                }

                                                int characters = arguments[argumentIndex].Length;

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

                                                bool nested = false;

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

                                                bool noReady = false;

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

                                                IParseState state = new ParseState(
                                                    engineFlags, substitutionFlags);

                                                code = Parser.ParseCommand(
                                                    interpreter, arguments[argumentIndex],
                                                    startIndex, characters, nested, state,
                                                    noReady, ref result);

                                                if (code == ReturnCode.Ok)
                                                {
                                                    //
                                                    // NOTE: Success, return the entire
                                                    //       state as a string.
                                                    //
                                                    result = state.ToString();
                                                }
                                            }
                                            else
                                            {
                                                if ((argumentIndex != Index.Invalid) &&
                                                    Option.LooksLikeOption(arguments[argumentIndex]))
                                                {
                                                    result = OptionDictionary.BadOption(options, arguments[argumentIndex]);
                                                }
                                                else
                                                {
                                                    result = "wrong # args: should be \"parse command ?options? text\"";
                                                }

                                                code = ReturnCode.Error;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        result = "wrong # args: should be \"parse command ?options? text\"";
                                        code   = ReturnCode.Error;
                                    }
                                    break;
                                }

                                case "expression":
                                {
                                    if (arguments.Count >= 3)
                                    {
                                        OptionDictionary options = new OptionDictionary(
                                            new IOption[] {
                                                new Option(typeof(EngineFlags), OptionFlags.MustHaveEnumValue | OptionFlags.Unsafe,
                                                           Index.Invalid, Index.Invalid, "-engineflags", new Variant(interpreter.EngineFlags)),
                                                new Option(typeof(SubstitutionFlags), OptionFlags.MustHaveEnumValue, Index.Invalid, Index.Invalid, "-substitutionflags",
                                                           new Variant(interpreter.SubstitutionFlags)),
                                                new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-startindex", null),
                                                new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-characters", null),
                                                new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-noready", null),
                                                new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null)
                                            });

                                        int argumentIndex = Index.Invalid;

                                        code = interpreter.GetOptions(
                                            options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex,
                                            ref result);

                                        if (code == ReturnCode.Ok)
                                        {
                                            if ((argumentIndex != Index.Invalid) &&
                                                ((argumentIndex + 1) == arguments.Count))
                                            {
                                                Variant     value       = null;
                                                EngineFlags engineFlags = interpreter.EngineFlags;

                                                if (options.IsPresent("-engineflags", ref value))
                                                {
                                                    engineFlags = (EngineFlags)value.Value;
                                                }

                                                SubstitutionFlags substitutionFlags = interpreter.SubstitutionFlags;

                                                if (options.IsPresent("-substitutionflags", ref value))
                                                {
                                                    substitutionFlags = (SubstitutionFlags)value.Value;
                                                }

                                                int startIndex = 0;

                                                if (options.IsPresent("-startindex", ref value))
                                                {
                                                    startIndex = (int)value.Value;
                                                }

                                                int characters = arguments[argumentIndex].Length;

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

                                                bool noReady = false;

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

                                                IParseState state = new ParseState(
                                                    engineFlags, substitutionFlags);

                                                code = ExpressionParser.ParseExpression(
                                                    interpreter, arguments[argumentIndex],
                                                    startIndex, characters, state, noReady,
                                                    ref result);

                                                if (code == ReturnCode.Ok)
                                                {
                                                    //
                                                    // NOTE: Success, return the entire
                                                    //       state as a string.
                                                    //
                                                    result = state.ToString();
                                                }
                                            }
                                            else
                                            {
                                                if ((argumentIndex != Index.Invalid) &&
                                                    Option.LooksLikeOption(arguments[argumentIndex]))
                                                {
                                                    result = OptionDictionary.BadOption(options, arguments[argumentIndex]);
                                                }
                                                else
                                                {
                                                    result = "wrong # args: should be \"parse expression ?options? text\"";
                                                }

                                                code = ReturnCode.Error;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        result = "wrong # args: should be \"parse expression ?options? text\"";
                                        code   = ReturnCode.Error;
                                    }
                                    break;
                                }

                                case "options":
                                {
                                    if (arguments.Count >= 4)
                                    {
                                        OptionDictionary options = new OptionDictionary(
                                            new IOption[] {
                                                new Option(typeof(OptionBehaviorFlags), OptionFlags.MustHaveEnumValue, Index.Invalid, Index.Invalid, "-flags",
                                                           new Variant(OptionBehaviorFlags.Default)),
                                                new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-optionsvar", null),
                                                new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-indexes", null),
                                                new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-allowinteger", null),
                                                new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-strict", null),
                                                new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-verbose", null),
                                                new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-nocase", null),
                                                new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-novalue", null),
                                                new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-noset", null),
                                                new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-noready", null),
                                                new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-simple", null),
                                                new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null)
                                            });

                                        int argumentIndex = Index.Invalid;

                                        code = interpreter.GetOptions(
                                            options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex,
                                            ref result);

                                        if (code == ReturnCode.Ok)
                                        {
                                            if ((argumentIndex != Index.Invalid) &&
                                                ((argumentIndex + 2) == arguments.Count))
                                            {
                                                Variant value          = null;
                                                string  optionsVarName = Vars.OptionSet.Options;

                                                if (options.IsPresent("-optionsvar", ref value))
                                                {
                                                    optionsVarName = value.ToString();
                                                }

                                                OptionBehaviorFlags flags = OptionBehaviorFlags.Default;

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

                                                bool indexes = false;

                                                if (options.IsPresent("-indexes"))
                                                {
                                                    indexes = true;
                                                }

                                                bool allowInteger = false;

                                                if (options.IsPresent("-allowinteger"))
                                                {
                                                    allowInteger = true;
                                                }

                                                bool strict = false;

                                                if (options.IsPresent("-strict"))
                                                {
                                                    strict = true;
                                                }

                                                bool verbose = false;

                                                if (options.IsPresent("-verbose"))
                                                {
                                                    verbose = true;
                                                }

                                                bool noCase = false;

                                                if (options.IsPresent("-nocase"))
                                                {
                                                    noCase = true;
                                                }

                                                bool noValue = false;

                                                if (options.IsPresent("-novalue"))
                                                {
                                                    noValue = true;
                                                }

                                                bool noSet = false;

                                                if (options.IsPresent("-noset"))
                                                {
                                                    noSet = true;
                                                }

                                                bool noReady = false;

                                                if (options.IsPresent("-noready"))
                                                {
                                                    noReady = true;
                                                }

                                                bool simple = false;

                                                if (options.IsPresent("-simple"))
                                                {
                                                    simple = true;
                                                }

                                                OptionDictionary newOptions  = null;
                                                AppDomain        appDomain   = interpreter.GetAppDomain();
                                                CultureInfo      cultureInfo = interpreter.CultureInfo;

                                                if (simple)
                                                {
                                                    newOptions = OptionDictionary.FromString(
                                                        interpreter, arguments[argumentIndex],
                                                        appDomain, Value.GetTypeValueFlags(
                                                            allowInteger, strict, verbose, noCase),
                                                        cultureInfo, ref result);
                                                }
                                                else
                                                {
                                                    newOptions = OptionDictionary.FromString(
                                                        interpreter, arguments[argumentIndex],
                                                        appDomain, allowInteger, strict, verbose,
                                                        noCase, cultureInfo, ref result);
                                                }

                                                if (newOptions != null)
                                                {
                                                    StringList list = StringList.FromString(
                                                        arguments[argumentIndex + 1], ref result);

                                                    if (list != null)
                                                    {
                                                        ArgumentList newArguments = new ArgumentList(list);

                                                        int nextIndex = Index.Invalid;
                                                        int endIndex  = Index.Invalid;

                                                        code = interpreter.GetOptions(
                                                            newOptions, newArguments, 0, 0, Index.Invalid, flags,
                                                            noCase, noValue, noSet, ref nextIndex, ref endIndex,
                                                            ref result);

                                                        if (code == ReturnCode.Ok)
                                                        {
                                                            VariableFlags variableFlags = VariableFlags.None;

                                                            if (noReady)
                                                            {
                                                                variableFlags |= VariableFlags.NoReady;
                                                            }

                                                            if (indexes)
                                                            {
                                                                code = interpreter.SetVariableValue2(
                                                                    variableFlags, optionsVarName,
                                                                    Vars.OptionSet.NextIndex, nextIndex.ToString(),
                                                                    null, ref result);

                                                                if (code == ReturnCode.Ok)
                                                                {
                                                                    code = interpreter.SetVariableValue2(
                                                                        variableFlags, optionsVarName,
                                                                        Vars.OptionSet.EndIndex, endIndex.ToString(),
                                                                        null, ref result);
                                                                }
                                                            }

                                                            if (code == ReturnCode.Ok)
                                                            {
                                                                foreach (KeyValuePair <string, IOption> pair in newOptions)
                                                                {
                                                                    IOption option = pair.Value;

                                                                    if (option == null)
                                                                    {
                                                                        continue;
                                                                    }

                                                                    if (option.IsIgnored(newOptions))
                                                                    {
                                                                        continue;
                                                                    }

                                                                    /* REUSED */
                                                                    value = null;

                                                                    bool present = option.IsPresent(newOptions, ref value);

                                                                    if (present &&
                                                                        !option.CanBePresent(newOptions, ref result))
                                                                    {
                                                                        code = ReturnCode.Error;
                                                                        break;
                                                                    }

                                                                    code = interpreter.SetVariableValue2(
                                                                        variableFlags, optionsVarName, pair.Key,
                                                                        present.ToString(), null, ref result);

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

                                                                    if (option.MustHaveValue(newOptions))
                                                                    {
                                                                        //
                                                                        // NOTE: If the option was not actually present,
                                                                        //       grab and use the default value instead.
                                                                        //
                                                                        if (!present)
                                                                        {
                                                                            value = option.Value;
                                                                        }

                                                                        //
                                                                        // NOTE: Only set the value if the option was
                                                                        //       actually present OR there is a bonafide
                                                                        //       default value.
                                                                        //
                                                                        if (present || (value != null))
                                                                        {
                                                                            string index = pair.Key +
                                                                                           Characters.Comma + Vars.OptionSet.Value;

                                                                            code = interpreter.SetVariableValue2(
                                                                                variableFlags, optionsVarName, index,
                                                                                (value != null) ? value.ToString() : null,
                                                                                null, ref result);

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

                                                                if (code == ReturnCode.Ok)
                                                                {
                                                                    result = String.Empty;
                                                                }
                                                            }
                                                        }
                                                    }
                                                    else
                                                    {
                                                        code = ReturnCode.Error;
                                                    }
                                                }
                                                else
                                                {
                                                    code = ReturnCode.Error;
                                                }
                                            }
                                            else
                                            {
                                                if ((argumentIndex != Index.Invalid) &&
                                                    Option.LooksLikeOption(arguments[argumentIndex]))
                                                {
                                                    result = OptionDictionary.BadOption(options, arguments[argumentIndex]);
                                                }
                                                else
                                                {
                                                    result = "wrong # args: should be \"parse options ?options? optionList argumentList\"";
                                                }

                                                code = ReturnCode.Error;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        result = "wrong # args: should be \"parse options ?options? options optionList argumentList\"";
                                        code   = ReturnCode.Error;
                                    }
                                    break;
                                }

                                case "script":
                                {
                                    if (arguments.Count >= 3)
                                    {
                                        OptionDictionary options = new OptionDictionary(
                                            new IOption[] {
                                                new Option(typeof(EngineFlags), OptionFlags.MustHaveEnumValue | OptionFlags.Unsafe,
                                                           Index.Invalid, Index.Invalid, "-engineflags", new Variant(interpreter.EngineFlags)),
                                                new Option(typeof(SubstitutionFlags), OptionFlags.MustHaveEnumValue, Index.Invalid, Index.Invalid, "-substitutionflags",
                                                           new Variant(interpreter.SubstitutionFlags)),
                                                new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-filename", null),
                                                new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-currentline", null),
                                                new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-startindex", null),
                                                new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-characters", null),
                                                new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-nested", null),
                                                new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-syntax", null),
                                                new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-strict", null),
                                                new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-roundtrip", null),
                                                new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-noready", null),
                                                new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null)
                                            });

                                        int argumentIndex = Index.Invalid;

                                        code = interpreter.GetOptions(
                                            options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex,
                                            ref result);

                                        if (code == ReturnCode.Ok)
                                        {
                                            if ((argumentIndex != Index.Invalid) &&
                                                ((argumentIndex + 1) == arguments.Count))
                                            {
                                                Variant     value       = null;
                                                EngineFlags engineFlags = interpreter.EngineFlags;

                                                if (options.IsPresent("-engineflags", ref value))
                                                {
                                                    engineFlags = (EngineFlags)value.Value;
                                                }

                                                SubstitutionFlags substitutionFlags = interpreter.SubstitutionFlags;

                                                if (options.IsPresent("-substitutionflags", ref value))
                                                {
                                                    substitutionFlags = (SubstitutionFlags)value.Value;
                                                }

                                                string fileName = null;

                                                if (options.IsPresent("-filename", ref value))
                                                {
                                                    fileName = value.ToString();
                                                }

                                                int currentLine = Parser.StartLine;

                                                if (options.IsPresent("-currentline", ref value))
                                                {
                                                    currentLine = (int)value.Value;
                                                }

                                                int startIndex = 0;

                                                if (options.IsPresent("-startindex", ref value))
                                                {
                                                    startIndex = (int)value.Value;
                                                }

                                                int characters = arguments[argumentIndex].Length;

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

                                                bool nested = false;

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

                                                bool syntax = false;

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

                                                bool strict = false;

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

                                                bool roundTrip = false;

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

                                                bool noReady = false;

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

                                                IParseState state = new ParseState(
                                                    engineFlags, substitutionFlags);

                                                TokenList tokens = null;

                                                code = Parser.ParseScript(
                                                    interpreter, fileName, currentLine,
                                                    arguments[argumentIndex], startIndex,
                                                    characters, engineFlags, substitutionFlags,
                                                    nested, noReady, syntax, strict, ref state,
                                                    ref tokens, ref result);

                                                if (code == ReturnCode.Ok)
                                                {
                                                    if (roundTrip)
                                                    {
                                                        //
                                                        // NOTE: Return only the tokens that
                                                        //       are absolutely necessary to
                                                        //       rebuild the script text.
                                                        //
                                                        TokenList newTokens = new TokenList();

                                                        for (int index = 0; index < tokens.Count; index++)
                                                        {
                                                            IToken token = tokens[index];

                                                            if (token.Type == TokenType.Variable)
                                                            {
                                                                index += token.Components;
                                                            }
                                                            else if ((token.Type != TokenType.Separator) &&
                                                                     (token.Components != 0))
                                                            {
                                                                continue;
                                                            }

                                                            newTokens.Add(token);
                                                        }

                                                        result = newTokens.ToString();
                                                    }
                                                    else
                                                    {
                                                        //
                                                        // NOTE: Replace final token list
                                                        //       with the one we have been
                                                        //       building.
                                                        //
                                                        state.Tokens = tokens;

                                                        //
                                                        // NOTE: Success, return the entire
                                                        //       state as a string.
                                                        //
                                                        result = state.ToString();
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                if ((argumentIndex != Index.Invalid) &&
                                                    Option.LooksLikeOption(arguments[argumentIndex]))
                                                {
                                                    result = OptionDictionary.BadOption(options, arguments[argumentIndex]);
                                                }
                                                else
                                                {
                                                    result = "wrong # args: should be \"parse script ?options? text\"";
                                                }

                                                code = ReturnCode.Error;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        result = "wrong # args: should be \"parse script ?options? text\"";
                                        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 \"parse type ?arg ...?\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
Beispiel #20
0
        ///////////////////////////////////////////////////////////////////////

        public ReturnCode RemoveImports(
            string qualifiedPattern,
            bool strict,
            ref Result error
            )
        {
            CheckDisposed();

            if (imports == null)
            {
                error = String.Format(
                    "imports not available in namespace \"{0}\"",
                    GetDisplayName());

                return(ReturnCode.Error);
            }

            INamespace patternNamespace = null;

            if ((qualifiedPattern != null) && (interpreter != null))
            {
                patternNamespace = NamespaceOps.LookupParent(
                    interpreter, qualifiedPattern, false, true, false,
                    ref error);

                if (patternNamespace == null)
                {
                    return(ReturnCode.Error);
                }
            }

            int count = 0;

            ObjectDictionary localImports = new ObjectDictionary(
                (IDictionary <string, object>)imports);

            foreach (KeyValuePair <string, object> pair in localImports)
            {
                IAlias alias      = pair.Value as IAlias;
                string aliasName  = NamespaceOps.GetAliasName(alias);
                string originName = GetOriginName(aliasName);

                if ((qualifiedPattern == null) ||
                    StringOps.Match(interpreter, MatchMode.Glob, aliasName,
                                    ScriptOps.MakeCommandName(qualifiedPattern), false) ||
                    ((originName != null) &&
                     StringOps.Match(interpreter, MatchMode.Glob, originName,
                                     ScriptOps.MakeCommandName(qualifiedPattern), false)))
                {
                    INamespace originNamespace = null;

                    if (originName != null)
                    {
                        originNamespace = NamespaceOps.LookupParent(
                            interpreter, originName, false, true, false,
                            ref error);

                        if (originNamespace == null)
                        {
                            return(ReturnCode.Error);
                        }
                    }

                    if ((patternNamespace == null) || ((alias != null) &&
                                                       (NamespaceOps.IsSame(
                                                            alias.TargetNamespace, patternNamespace) ||
                                                        NamespaceOps.IsSame(
                                                            originNamespace, patternNamespace))))
                    {
                        if ((alias != null) && (interpreter != null))
                        {
                            string nameToken = alias.NameToken;

                            if ((nameToken != null) &&
                                interpreter.RemoveAliasAndCommand(
                                    alias.NameToken, null, false,
                                    ref error) != ReturnCode.Ok)
                            {
                                return(ReturnCode.Error);
                            }
                        }

                        count += imports.Remove(pair.Key) ? 1 : 0;
                    }
                }
            }

            if (strict && (count == 0))
            {
                error = String.Format(
                    "no imports matched pattern \"{0}\" in namespace \"{1}\"",
                    qualifiedPattern, GetDisplayName());

                return(ReturnCode.Error);
            }

            return(ReturnCode.Ok);
        }
Beispiel #21
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);
        }
Beispiel #22
0
        ///////////////////////////////////////////////////////////////////////

        public StringList GetImportNames(
            string pattern,
            bool keys,
            bool tailOnly
            )
        {
            CheckDisposed();

            StringList list = new StringList();

            if (imports == null)
            {
                return(list);
            }

            if (pattern != null)
            {
                pattern = ScriptOps.MakeCommandName(pattern);
            }

            foreach (KeyValuePair <string, object> pair in imports)
            {
                IAlias alias = pair.Value as IAlias;

                if (alias == null)
                {
                    continue;
                }

                if (keys)
                {
                    string importName = pair.Key;

                    string importNameTailOnly = NamespaceOps.TailOnly(
                        importName);

                    if ((pattern == null) || StringOps.Match(
                            interpreter, MatchMode.Glob, importNameTailOnly,
                            pattern, false))
                    {
                        list.Add(tailOnly ? importNameTailOnly : importName);
                    }
                }
                else
                {
                    string aliasName = NamespaceOps.GetAliasName(alias);

                    string aliasNameTailOnly = NamespaceOps.TailOnly(
                        aliasName);

                    if ((pattern == null) || StringOps.Match(
                            interpreter, MatchMode.Glob, aliasNameTailOnly,
                            pattern, false))
                    {
                        list.Add(tailOnly ? aliasNameTailOnly : aliasName);
                    }
                }
            }

            return(list);
        }
Beispiel #23
0
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            ReturnCode code = ReturnCode.Ok;

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    if (arguments.Count >= 3)
                    {
                        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);
        }
Beispiel #24
0
        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);
        }
Beispiel #25
0
        ///////////////////////////////////////////////////////////////////////

        #region Background Error Executor
        private static ReturnCode ExecuteBackgroundError(
            Interpreter interpreter,
            string handlerName,
            IExecute execute,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result,
            ref int errorLine
            )
        {
            if (interpreter == null)
            {
                result = "invalid interpreter";
                return(ReturnCode.Error);
            }

            //
            // NOTE: Create a new call frame for the background error handler
            //       and push it.
            //
            ICallFrame frame = interpreter.NewTrackingCallFrame(
                StringList.MakeList("bgerror", handlerName),
                CallFrameFlags.BackgroundError);

            interpreter.PushAutomaticCallFrame(frame);

            try
            {
                //
                // NOTE: Save current engine flags and then enable external
                //       execution.
                //
                EngineFlags savedEngineFlags =
                    interpreter.BeginExternalExecution();

                try
                {
                    //
                    // NOTE: If the interpreter is configured to reset the
                    //       script cancellation flags prior to executing
                    //       the background error handler, do that now.
                    //
                    if (ScriptOps.HasFlags(
                            interpreter, InterpreterFlags.BgErrorResetCancel,
                            true))
                    {
                        /* IGNORED */
                        Engine.ResetCancel(interpreter, CancelFlags.BgError);
                    }

                    //
                    // NOTE: Evaluate the script and then check the result to
                    //       see if the background error handler failed or
                    //       canceled further background error handling for
                    //       this invocation of ProcessEvents.
                    //
                    ReturnCode code;

                    code = interpreter.Execute(
                        handlerName, execute, clientData, arguments,
                        ref result);

                    //
                    // NOTE: Maybe grab the new error line number, if any.
                    //
                    if (code != ReturnCode.Ok)
                    {
                        errorLine = Interpreter.GetErrorLine(interpreter);
                    }

                    //
                    // NOTE: We are done now, return.
                    //
                    return(code);
                }
                finally
                {
                    //
                    // NOTE: Restore saved engine flags, disabling external
                    //       execution as necessary.
                    //
                    /* IGNORED */
                    interpreter.EndAndCleanupExternalExecution(
                        savedEngineFlags);
                }
            }
            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();
            }
        }
Beispiel #26
0
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            ReturnCode code = ReturnCode.Ok;

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    if (arguments.Count >= 2)
                    {
                        string subCommand = arguments[1];
                        bool   tried      = false;

                        code = ScriptOps.TryExecuteSubCommandFromEnsemble(
                            interpreter, this, clientData, arguments, false,
                            false, ref subCommand, ref tried, ref result);

                        if ((code == ReturnCode.Ok) && !tried)
                        {
                            switch (subCommand)
                            {
                            case "active":
                            {
                                if (arguments.Count == 2)
                                {
                                    IEventManager eventManager = interpreter.EventManager;

                                    if (EventOps.ManagerIsOk(eventManager))
                                    {
                                        result = eventManager.Active;
                                        code   = ReturnCode.Ok;
                                    }
                                    else
                                    {
                                        result = "event manager not available";
                                        code   = ReturnCode.Error;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"after active\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "cancel":
                            {
                                if (arguments.Count >= 3)
                                {
                                    string text;

                                    if (arguments.Count == 3)
                                    {
                                        text = arguments[2];
                                    }
                                    else
                                    {
                                        text = ListOps.Concat(arguments, 2);
                                    }

                                    IEventManager eventManager = interpreter.EventManager;

                                    if (EventOps.ManagerIsOk(eventManager))
                                    {
                                        code = eventManager.CancelEvents(
                                            text, false, false, ref result);
                                    }
                                    else
                                    {
                                        result = "event manager not available";
                                        code   = ReturnCode.Error;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"after cancel arg ?arg ...?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "clear":
                            {
                                if (arguments.Count == 2)
                                {
                                    IEventManager eventManager = interpreter.EventManager;

                                    if (EventOps.ManagerIsOk(eventManager))
                                    {
                                        code = eventManager.ClearEvents(ref result);

                                        if (code == ReturnCode.Ok)
                                        {
                                            result = String.Empty;
                                        }
                                    }
                                    else
                                    {
                                        result = "event manager not available";
                                        code   = ReturnCode.Error;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"after clear\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "counts":
                            {
                                if (arguments.Count == 2)
                                {
                                    IEventManager eventManager = interpreter.EventManager;

                                    if (EventOps.ManagerIsOk(eventManager))
                                    {
                                        result = StringList.MakeList(
                                            "enabled", eventManager.Enabled,
                                            "active", eventManager.Active,
                                            "createEventCount", Event.CreateCount,
                                            "disposeEventCount", Event.DisposeCount,
                                            "queueEventCount", eventManager.QueueEventCount,
                                            "queueIdleEventCount", eventManager.QueueIdleEventCount,
                                            "eventCount", eventManager.EventCount,
                                            "idleEventCount", eventManager.IdleEventCount,
                                            "totalEventCount", eventManager.TotalEventCount,
                                            "maximumEventCount", eventManager.MaximumEventCount,
                                            "maximumIdleEventCount", eventManager.MaximumIdleEventCount,
                                            "maybeDisposeEventCount", eventManager.MaybeDisposeEventCount,
                                            "reallyDisposeEventCount", eventManager.ReallyDisposeEventCount,
                                            "interpreterEventCount", interpreter.EventCount,
#if NATIVE && TCL
                                            "interpreterTclEventCount", interpreter.TclEventCount,
#endif
                                            "interpreterWaitCount", interpreter.WaitCount,
                                            "interpreterWaitSpinCount", interpreter.WaitSpinCount);

                                        code = ReturnCode.Ok;
                                    }
                                    else
                                    {
                                        result = "event manager not available";
                                        code   = ReturnCode.Error;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"after counts\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "dump":
                            {
                                if (arguments.Count == 2)
                                {
                                    IEventManager eventManager = interpreter.EventManager;

                                    if (EventOps.ManagerIsOk(eventManager))
                                    {
                                        code = eventManager.Dump(ref result);
                                    }
                                    else
                                    {
                                        result = "event manager not available";
                                        code   = ReturnCode.Error;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"after dump\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "enable":
                            {
                                if ((arguments.Count == 2) || (arguments.Count == 3))
                                {
                                    IEventManager eventManager = interpreter.EventManager;

                                    if (EventOps.ManagerIsOk(eventManager))
                                    {
                                        if (arguments.Count == 3)
                                        {
                                            bool enabled = false;

                                            code = Value.GetBoolean2(
                                                arguments[2], ValueFlags.AnyBoolean,
                                                interpreter.CultureInfo, ref enabled, ref result);

                                            if (code == ReturnCode.Ok)
                                            {
                                                eventManager.Enabled = enabled;
                                            }
                                        }

                                        if (code == ReturnCode.Ok)
                                        {
                                            result = eventManager.Enabled;
                                        }
                                    }
                                    else
                                    {
                                        result = "event manager not available";
                                        code   = ReturnCode.Error;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"after enable ?enabled?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "flags":
                            {
                                if ((arguments.Count == 2) || (arguments.Count == 3))
                                {
                                    lock (interpreter.SyncRoot)         /* TRANSACTIONAL */
                                    {
                                        if (arguments.Count == 3)
                                        {
                                            object enumValue = EnumOps.TryParseFlagsEnum(
                                                interpreter, typeof(EventFlags),
                                                interpreter.AfterEventFlags.ToString(),
                                                arguments[2], interpreter.CultureInfo,
                                                true, true, true, ref result);

                                            if (enumValue is EventFlags)
                                            {
                                                interpreter.AfterEventFlags = (EventFlags)enumValue;
                                            }
                                            else
                                            {
                                                code = ReturnCode.Error;
                                            }
                                        }

                                        if (code == ReturnCode.Ok)
                                        {
                                            result = interpreter.AfterEventFlags;
                                        }
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"after flags ?flags?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "idle":
                            {
                                if (arguments.Count >= 3)
                                {
                                    IEventManager eventManager = interpreter.EventManager;

                                    if (EventOps.ManagerIsOk(eventManager))
                                    {
                                        //
                                        // FIXME: PRI 5: Somewhat arbitrary, we cannot be "idle" with no
                                        //        windows message loop.
                                        //
                                        string   name     = FormatOps.Id(this.Name, null, interpreter.NextId());
                                        DateTime now      = TimeOps.GetUtcNow();
                                        DateTime dateTime = now.AddMilliseconds(EventManager.MinimumIdleWaitTime);
                                        string   text;

                                        if (arguments.Count == 3)
                                        {
                                            text = arguments[2];
                                        }
                                        else
                                        {
                                            text = ListOps.Concat(arguments, 2);
                                        }

                                        IScript script = interpreter.CreateAfterScript(
                                            name, null, null, ScriptTypes.Idle, text,
                                            now, EngineMode.EvaluateScript, ScriptFlags.None,
                                            clientData, true);

                                        code = eventManager.QueueScript(
                                            name, dateTime, script, script.EventFlags,
                                            EventPriority.Idle, ref result);

                                        if (code == ReturnCode.Ok)
                                        {
                                            result = name;
                                        }
                                    }
                                    else
                                    {
                                        result = "event manager not available";
                                        code   = ReturnCode.Error;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"after idle arg ?arg ...?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "info":
                            {
                                if ((arguments.Count == 2) || (arguments.Count == 3))
                                {
                                    IEventManager eventManager = interpreter.EventManager;

                                    if (EventOps.ManagerIsOk(eventManager))
                                    {
                                        if (arguments.Count == 3)
                                        {
                                            IEvent @event = null;

                                            code = eventManager.GetEvent(
                                                arguments[2], ref @event, ref result);

                                            if (code == ReturnCode.Ok)
                                            {
                                                if (EventManager.IsScriptEvent(@event))
                                                {
                                                    if (@event.ClientData != null)
                                                    {
                                                        IScript script = @event.ClientData.Data as IScript;

                                                        if (script != null)
                                                        {
                                                            result = script.ToString();
                                                        }
                                                        else
                                                        {
                                                            result = String.Format(
                                                                "event \"{0}\" clientData is not a script",
                                                                arguments[2]);

                                                            code = ReturnCode.Error;
                                                        }
                                                    }
                                                    else
                                                    {
                                                        result = String.Format(
                                                            "event \"{0}\" has invalid clientData",
                                                            arguments[2]);

                                                        code = ReturnCode.Error;
                                                    }
                                                }
                                                else
                                                {
                                                    result = String.Format(
                                                        "event \"{0}\" is not an after event",
                                                        arguments[2]);

                                                    code = ReturnCode.Error;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            StringList list = null;

                                            code = eventManager.ListEvents(null, false, ref list, ref result);

                                            if (code == ReturnCode.Ok)
                                            {
                                                result = list;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        result = "event manager not available";
                                        code   = ReturnCode.Error;
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"after info ?id?\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            default:
                            {
                                long milliseconds = 0;         // for idle, execute the script right now.

                                code = Value.GetWideInteger2(
                                    subCommand, ValueFlags.AnyWideInteger,
                                    interpreter.CultureInfo, ref milliseconds, ref result);

                                if (code == ReturnCode.Ok)
                                {
                                    if (arguments.Count == 2)
                                    {
                                        //
                                        // BUGBUG: This call will never timeout if we cannot obtain
                                        //         the interpreter lock.
                                        //
                                        code = EventOps.Wait(
                                            interpreter, PerformanceOps.GetMicroseconds(milliseconds),
                                            false, false, ref result);

                                        if (code == ReturnCode.Ok)
                                        {
                                            result = String.Empty;
                                        }
                                    }
                                    else if (arguments.Count >= 3)
                                    {
                                        IEventManager eventManager = interpreter.EventManager;

                                        if (EventOps.ManagerIsOk(eventManager))
                                        {
                                            string   name     = FormatOps.Id(this.Name, null, interpreter.NextId());
                                            DateTime now      = TimeOps.GetUtcNow();
                                            DateTime dateTime = now.AddMilliseconds(milliseconds);
                                            string   text;

                                            if (arguments.Count == 3)
                                            {
                                                text = arguments[2];
                                            }
                                            else
                                            {
                                                text = ListOps.Concat(arguments, 2);
                                            }

                                            IScript script = interpreter.CreateAfterScript(
                                                name, null, null, ScriptTypes.Timer, text,
                                                now, EngineMode.EvaluateScript, ScriptFlags.None,
                                                clientData, false);

                                            code = eventManager.QueueScript(
                                                name, dateTime, script, script.EventFlags,
                                                EventPriority.After, ref result);

                                            if (code == ReturnCode.Ok)
                                            {
                                                result = name;
                                            }
                                        }
                                        else
                                        {
                                            result = "event manager not available";
                                            code   = ReturnCode.Error;
                                        }
                                    }
                                    else
                                    {
                                        result = "wrong # args: should be \"after milliseconds arg ?arg ...?\"";
                                        code   = ReturnCode.Error;
                                    }
                                }
                                else
                                {
                                    result = ScriptOps.BadSubCommand(
                                        interpreter, null, "argument", subCommand, this, null, ", or a number");
                                }
                                break;
                            }
                            }
                        }
                    }
                    else
                    {
                        result = "wrong # args: should be \"after option ?arg ...?\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
Beispiel #27
0
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            ReturnCode code = ReturnCode.Ok;

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    if (arguments.Count >= 2)
                    {
                        string subCommand = arguments[1];
                        bool   tried      = false;

                        code = ScriptOps.TryExecuteSubCommandFromEnsemble(
                            interpreter, this, clientData, arguments, true,
                            false, ref subCommand, ref tried, ref result);

                        if ((code == ReturnCode.Ok) && !tried)
                        {
                            switch (subCommand)
                            {
                            case "decode":
                            {
                                if (arguments.Count >= 3)
                                {
                                    OptionDictionary options = new OptionDictionary(
                                        new IOption[] {
                                            new Option(null, OptionFlags.MustHaveEncodingValue, Index.Invalid, Index.Invalid, "-encoding", null),
                                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null)
                                        });

                                    int argumentIndex = Index.Invalid;

                                    code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        if ((argumentIndex != Index.Invalid) &&
                                            ((argumentIndex + 1) == arguments.Count))
                                        {
                                            Variant  value    = null;
                                            Encoding encoding = null;

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

                                            if (code == ReturnCode.Ok)
                                            {
                                                try
                                                {
                                                    string stringValue = null;

                                                    code = StringOps.GetString(encoding,
                                                                               Convert.FromBase64String(arguments[argumentIndex]),
                                                                               EncodingType.Binary, ref stringValue, ref result);

                                                    if (code == ReturnCode.Ok)
                                                    {
                                                        result = stringValue;
                                                    }
                                                }
                                                catch (Exception e)
                                                {
                                                    Engine.SetExceptionErrorCode(interpreter, e);

                                                    result = e;
                                                    code   = ReturnCode.Error;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if ((argumentIndex != Index.Invalid) &&
                                                Option.LooksLikeOption(arguments[argumentIndex]))
                                            {
                                                result = OptionDictionary.BadOption(options, arguments[argumentIndex]);
                                            }
                                            else
                                            {
                                                result = "wrong # args: should be \"base64 decode ?options? string\"";
                                            }

                                            code = ReturnCode.Error;
                                        }
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"base64 decode ?options? string\"";
                                    code   = ReturnCode.Error;
                                }
                                break;
                            }

                            case "encode":
                            {
                                if (arguments.Count >= 3)
                                {
                                    OptionDictionary options = new OptionDictionary(
                                        new IOption[] {
                                            new Option(null, OptionFlags.MustHaveEncodingValue, Index.Invalid, Index.Invalid, "-encoding", null),
                                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null)
                                        });

                                    int argumentIndex = Index.Invalid;

                                    code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        if ((argumentIndex != Index.Invalid) && ((argumentIndex + 1) == arguments.Count))
                                        {
                                            Variant  value    = null;
                                            Encoding encoding = null;

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

                                            if (code == ReturnCode.Ok)
                                            {
                                                try
                                                {
                                                    byte[] bytes = null;

                                                    code = StringOps.GetBytes(
                                                        encoding, arguments[argumentIndex],
                                                        EncodingType.Binary, ref bytes, ref result);

                                                    if (code == ReturnCode.Ok)
                                                    {
                                                        result = Convert.ToBase64String(bytes,
                                                                                        Base64FormattingOptions.InsertLineBreaks);
                                                    }
                                                }
                                                catch (Exception e)
                                                {
                                                    Engine.SetExceptionErrorCode(interpreter, e);

                                                    result = e;
                                                    code   = ReturnCode.Error;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if ((argumentIndex != Index.Invalid) &&
                                                Option.LooksLikeOption(arguments[argumentIndex]))
                                            {
                                                result = OptionDictionary.BadOption(options, arguments[argumentIndex]);
                                            }
                                            else
                                            {
                                                result = "wrong # args: should be \"base64 encode ?options? string\"";
                                            }

                                            code = ReturnCode.Error;
                                        }
                                    }
                                }
                                else
                                {
                                    result = "wrong # args: should be \"base64 encode ?options? string\"";
                                    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 \"base64 option ?arg ...?\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
Beispiel #28
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 >= 1)
                    {
                        OptionDictionary options = new OptionDictionary(
                            new IOption[] {
                            new Option(null, OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-force", null),
                            new Option(null, OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-fail", null),
                            new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-message", null),
                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-current", null),
                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null)
                        });

                        int argumentIndex = Index.Invalid;

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

                        if (code == ReturnCode.Ok)
                        {
                            if ((argumentIndex == Index.Invalid) ||
                                ((argumentIndex + 1) == arguments.Count))
                            {
                                bool force = false;

                                if (options.IsPresent("-force"))
                                {
                                    force = true;
                                }

                                bool fail = false;

                                if (options.IsPresent("-fail"))
                                {
                                    fail = true;
                                }

                                Variant value   = null;
                                string  message = null;

                                if (options.IsPresent("-message", ref value))
                                {
                                    message = value.ToString();
                                }

                                //
                                // NOTE: The default exit code is "success" (i.e. zero).
                                //
                                ExitCode exitCode = ResultOps.SuccessExitCode();

                                if (options.IsPresent("-current"))
                                {
                                    exitCode = interpreter.ExitCode;
                                }

                                //
                                // NOTE: Was an exit code specified in the command?
                                //
                                if (argumentIndex != Index.Invalid)
                                {
                                    object enumValue = EnumOps.TryParseEnum(
                                        typeof(ExitCode), arguments[argumentIndex],
                                        true, true, ref result);

                                    if (enumValue is ExitCode)
                                    {
                                        exitCode = (ExitCode)enumValue;
                                    }
                                    else
                                    {
                                        result = ScriptOps.BadValue(
                                            null, "exit code", arguments[argumentIndex],
                                            Enum.GetNames(typeof(ExitCode)), null, ", or an integer");

                                        code = ReturnCode.Error;
                                    }
                                }

                                //
                                // NOTE: Make sure we succeeded at coverting the exit code to an integer.
                                //
                                if (code == ReturnCode.Ok)
                                {
                                    //
                                    // NOTE: Make sure the interpreter host, if any, agrees to exit (i.e. it may deny the
                                    //       request if the application is doing something that should not be interrupted).
                                    //
                                    code = interpreter.CanExit(exitCode, force, fail, message, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        //
                                        // NOTE: Exit the application (either by marking the current interpreter as "exited"
                                        //       or physically exiting the containing process).
                                        //
                                        TraceOps.DebugTrace(String.Format(
                                                                "Execute: {0}, interpreter = {1}, message = {2}",
                                                                force && fail ?
                                                                "forcibly failing" : force ? "forcibly exiting" : "exiting",
                                                                FormatOps.InterpreterNoThrow(interpreter), FormatOps.WrapOrNull(message)),
                                                            typeof(Exit).Name, TracePriority.Command);

                                        if (force)
                                        {
#if !MONO
                                            if (fail && !CommonOps.Runtime.IsMono())
                                            {
                                                try
                                                {
                                                    //
                                                    // NOTE: Using this method to exit a script is NOT recommended unless
                                                    //       you are trying to prevent damaging another part of the system.
                                                    //
                                                    // MONO: This method is not supported by the Mono runtime.
                                                    //
                                                    Environment.FailFast(message);

                                                    /* NOT REACHED */
                                                    result = "failed to exit process";
                                                    code   = ReturnCode.Error;
                                                }
                                                catch (Exception e)
                                                {
                                                    result = e;
                                                    code   = ReturnCode.Error;
                                                }
                                            }
                                            else
#endif
                                            {
                                                //
                                                // BUGFIX: Try to dispose our containing interpreter now.  We must do
                                                //         this to prevent it from being disposed on a random GC thread.
                                                //
                                                try
                                                {
                                                    interpreter.Dispose();
                                                    interpreter = null;
                                                }
                                                catch (Exception e)
                                                {
                                                    result = e;
                                                    code   = ReturnCode.Error;
                                                }

                                                //
                                                // NOTE: If we could not dispose the interpreter properly, complain;
                                                //       however, keep exiting anyway.
                                                //
                                                if (code != ReturnCode.Ok)
                                                {
                                                    DebugOps.Complain(interpreter, code, result);
                                                }

                                                try
                                                {
                                                    //
                                                    // NOTE: Using this method to exit a script is NOT recommended unless
                                                    //       you are running a standalone script in the Eagle Shell (i.e.
                                                    //       you are not hosted within another application).
                                                    //
                                                    Environment.Exit((int)exitCode);

                                                    /* NOT REACHED */
                                                    result = "failed to exit process";
                                                    code   = ReturnCode.Error;
                                                }
                                                catch (Exception e)
                                                {
                                                    result = e;
                                                    code   = ReturnCode.Error;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            interpreter.ExitCode = exitCode;
                                            interpreter.Exit     = true;

                                            result = String.Empty;
                                            code   = ReturnCode.Ok;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                if ((argumentIndex != Index.Invalid) &&
                                    Option.LooksLikeOption(arguments[argumentIndex]))
                                {
                                    result = OptionDictionary.BadOption(options, arguments[argumentIndex]);
                                }
                                else
                                {
                                    result = "wrong # args: should be \"exit ?options? ?returnCode?\"";
                                }

                                code = ReturnCode.Error;
                            }
                        }
                    }
                    else
                    {
                        result = "wrong # args: should be \"exit ?options? ?returnCode?\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
Beispiel #29
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)
                {
                    if (arguments.Count == 4)
                    {
                        string     name = arguments[1];
                        StringList list = null;

                        code = Parser.SplitList(
                            interpreter, arguments[2], 0,
                            Length.Invalid, true, ref list,
                            ref result);

                        if (code == ReturnCode.Ok)
                        {
                            StringPairList list2 = new StringPairList();

                            for (int argumentIndex = 0; argumentIndex < list.Count; argumentIndex++)
                            {
                                StringList list3 = null;

                                code = Parser.SplitList(
                                    interpreter, list[argumentIndex], 0,
                                    Length.Invalid, true, ref list3,
                                    ref result);

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

                                if (list3.Count > 2)
                                {
                                    result = String.Format(
                                        "too many fields in argument specifier \"{0}\"",
                                        list[argumentIndex]);

                                    code = ReturnCode.Error;
                                    break;
                                }
                                else if ((list3.Count == 0) || String.IsNullOrEmpty(list3[0]))
                                {
                                    result = "argument with no name";
                                    code   = ReturnCode.Error;
                                    break;
                                }
                                else if (!Parser.IsSimpleScalarVariableName(list3[0],
                                                                            String.Format(Interpreter.ArgumentNotSimpleError, list3[0]),
                                                                            String.Format(Interpreter.ArgumentNotScalarError, list3[0]), ref result))
                                {
                                    code = ReturnCode.Error;
                                    break;
                                }

                                string argName    = list3[0];
                                string argDefault = (list3.Count >= 2) ? list3[1] : null;

                                list2.Add(new StringPair(argName, argDefault));
                            }

                            if (code == ReturnCode.Ok)
                            {
                                lock (interpreter.SyncRoot) /* TRANSACTIONAL */
                                {
                                    ProcedureFlags procedureFlags = interpreter.ProcedureFlags;

                                    IProcedure procedure = RuntimeOps.NewCoreProcedure(
                                        interpreter, interpreter.AreNamespacesEnabled() ?
                                        NamespaceOps.MakeQualifiedName(interpreter, name) :
                                        ScriptOps.MakeCommandName(name), null, null,
                                        procedureFlags, new ArgumentList(list2,
                                                                         ArgumentFlags.NameOnly), arguments[3],
                                        ScriptLocation.Create(arguments[3]), clientData);

                                    code = interpreter.AddOrUpdateProcedureWithReplace(
                                        procedure, clientData, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        result = String.Empty;
                                    }
                                }
                            }
                        }

                        if (code == ReturnCode.Error)
                        {
                            Engine.AddErrorInformation(interpreter, result,
                                                       String.Format("{0}    (creating proc \"{1}\")",
                                                                     Environment.NewLine, name));
                        }
                    }
                    else
                    {
                        result = "wrong # args: should be \"proc name args body\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
Beispiel #30
0
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            ReturnCode code = ReturnCode.Ok;

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    OptionDictionary options = new OptionDictionary(
                        new IOption[] {
                        new Option(null, OptionFlags.None, 1, Index.Invalid, "-exact", null),
                        new Option(null, OptionFlags.None, 3, Index.Invalid, "-integer", null),
                        new Option(null, OptionFlags.None, 3, Index.Invalid, "-substring", null),
                        new Option(null, OptionFlags.None, 1, Index.Invalid, "-glob", null),
                        new Option(null, OptionFlags.None, 1, Index.Invalid, "-regexp", null),
                        new Option(null, OptionFlags.None, 2, Index.Invalid, "-subst", null),
                        new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-nocase", null),
                        new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null)
                    });

                    int argumentIndex = Index.Invalid;

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

                    if (code == ReturnCode.Ok)
                    {
                        if ((argumentIndex != Index.Invalid) && ((argumentIndex + 1) < arguments.Count))
                        {
                            MatchMode mode = StringOps.DefaultSwitchMatchMode;

                            if (options.IsPresent("-integer"))
                            {
                                mode = MatchMode.Integer;
                            }
                            else if (options.IsPresent("-regexp"))
                            {
                                mode = MatchMode.RegExp;
                            }
                            else if (options.IsPresent("-glob"))
                            {
                                mode = MatchMode.Glob;
                            }
                            else if (options.IsPresent("-substring"))
                            {
                                mode = MatchMode.SubString;
                            }
                            else if (options.IsPresent("-exact"))
                            {
                                mode = MatchMode.Exact;
                            }

                            if (options.IsPresent("-subst"))
                            {
                                mode |= MatchMode.Substitute;
                            }

                            bool noCase = false;

                            if (options.IsPresent("-nocase"))
                            {
                                noCase = true;
                            }

                            bool            splitList = false;
                            StringList      list      = null;
                            IScriptLocation location  = null;

                            //
                            // NOTE: Is there only one argument following the string to match?
                            //
                            if ((argumentIndex + 2) == arguments.Count)
                            {
                                code = Parser.SplitList(
                                    interpreter, arguments[argumentIndex + 1], 0,
                                    Length.Invalid, true, ref list);

                                if (code == ReturnCode.Ok)
                                {
                                    if (list.Count > 0)
                                    {
                                        location  = arguments[argumentIndex + 1];
                                        splitList = true;
                                    }
                                    else
                                    {
                                        result = "wrong # args: should be \"switch ?switches? string {pattern body ... ?default body?}\"";
                                        code   = ReturnCode.Error;
                                    }
                                }
                            }
                            else
                            {
                                //
                                // TODO: Make sure this is always accurate.
                                //
                                code = ScriptOps.GetLocation(
                                    interpreter, arguments, argumentIndex + 1, ref location,
                                    ref result);

                                if (code == ReturnCode.Ok)
                                {
                                    list = ArgumentList.GetRangeAsStringList(arguments, argumentIndex + 1);
                                }
                            }

                            //
                            // NOTE: Ok, now we should have a list of patterns and bodies
                            //       if everything went Ok above.
                            //
                            if (code == ReturnCode.Ok)
                            {
                                //
                                // NOTE: Complain if there is an odd number of words in the
                                //       list of patterns and bodies.
                                //
                                if ((list.Count % 2) == 0)
                                {
                                    //
                                    // NOTE: Complain if the last body is a continuation.
                                    //
                                    if (String.Compare(list[list.Count - 1], Characters.MinusSign.ToString(),
                                                       StringOps.SystemStringComparisonType) != 0)
                                    {
                                        //
                                        // NOTE: Get the text to match against.
                                        //
                                        string input = arguments[argumentIndex];

                                        //
                                        // NOTE: We need to return an empty string if we do not
                                        //       match anything.
                                        //
                                        result = String.Empty;

                                        //
                                        // NOTE: Search the patterns for a match.
                                        //
                                        for (int index = 0; index < list.Count; index += 2)
                                        {
                                            Result pattern = list[index];

                                            bool match = false;

                                            if ((index == (list.Count - 2)) &&
                                                (String.Compare(pattern, Switch.Default, StringOps.SystemStringComparisonType) == 0))
                                            {
                                                //
                                                // NOTE: Default pattern at end always matches.
                                                //
                                                match = true;
                                            }
                                            else
                                            {
                                                if ((mode & MatchMode.Substitute) == MatchMode.Substitute)
                                                {
                                                    code = interpreter.SubstituteString(pattern, ref pattern);
                                                }

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

                                                code = StringOps.Match(
                                                    interpreter, mode, input, pattern, noCase, ref match,
                                                    ref result);

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

                                            if (!match)
                                            {
                                                continue;
                                            }

                                            //
                                            // NOTE: We've got a match. Find a body to execute, skipping
                                            //       bodies that are "-".
                                            //
                                            for (int index2 = index + 1; ; index2 += 2)
                                            {
                                                if (index2 >= list.Count)
                                                {
                                                    result = "fall-out when searching for body to match pattern";
                                                    code   = ReturnCode.Error;

                                                    goto switch_done;
                                                }

                                                if (String.Compare(list[index2], Characters.MinusSign.ToString(),
                                                                   StringOps.SystemStringComparisonType) != 0)
                                                {
                                                    code = interpreter.EvaluateScript(list[index2], location, ref result);

                                                    if (code == ReturnCode.Error)
                                                    {
                                                        Engine.AddErrorInformation(interpreter, result,
                                                                                   String.Format("{0}    (\"{1}\" arm line {2})",
                                                                                                 Environment.NewLine, FormatOps.Ellipsis(pattern),
                                                                                                 Interpreter.GetErrorLine(interpreter)));
                                                    }

                                                    goto switch_done;
                                                }
                                            }
                                        }

switch_done:
                                        ;
                                    }
                                    else
                                    {
                                        result = String.Format(
                                            "no body specified for pattern \"{0}\"",
                                            list[list.Count - 2]);

                                        code = ReturnCode.Error;
                                    }
                                }
                                else
                                {
                                    result = "extra switch pattern with no body";
                                    code   = ReturnCode.Error;

                                    if (splitList)
                                    {
                                        /*
                                         * Check if this can be due to a badly placed comment
                                         * in the switch block.
                                         *
                                         * The following is an heuristic to detect the infamous
                                         * "comment in switch" error: just check if a pattern
                                         * begins with '#'.
                                         */

                                        for (int index = 0; index < list.Count; index++)
                                        {
                                            if (!String.IsNullOrEmpty(list[index]) &&
                                                (list[index][0] == Characters.NumberSign))
                                            {
                                                result += ", this may be due to a comment incorrectly placed " +
                                                          "outside of a switch body - see the \"switch\" documentation";

                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            if ((argumentIndex != Index.Invalid) &&
                                Option.LooksLikeOption(arguments[argumentIndex]))
                            {
                                result = OptionDictionary.BadOption(options, arguments[argumentIndex]);
                            }
                            else
                            {
                                result = "wrong # args: should be \"switch ?switches? string pattern body ... ?default body?\"";
                            }

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

            return(code);
        }