Ejemplo n.º 1
0
        ///////////////////////////////////////////////////////////////////////

        #region Private Methods
        private bool HasFlags(
            ScriptBlockFlags hasFlags, /* in */
            bool all                   /* in */
            )
        {
            return(FlagOps.HasFlags(scriptBlockFlags, hasFlags, all));
        }
Ejemplo n.º 2
0
        ///////////////////////////////////////////////////////////////////////

        internal ArgumentList( /* NOTE: For [apply] and [proc] use only. */
            StringPairList list,
            ArgumentFlags flags
            )
            : this()
        {
            if (list != null)
            {
                int count = list.Count;

                for (int index = 0; index < count; index++)
                {
                    IPair <string> element = list[index];

                    //
                    // HACK: Skip over any null entries, thus ignoring
                    //       them.
                    //
                    if (element == null)
                    {
                        continue;
                    }

                    //
                    // NOTE: Does this argument list accept a variable
                    //       numbers of arguments (COMPAT: Tcl)?  If so,
                    //       add a flag to the final argument to mark it
                    //       as an "argument list".
                    //
                    ArgumentFlags nameFlags = ArgumentFlags.None;

                    if ((index == (count - 1)) && String.Compare(
                            element.X, TclVars.Arguments,
                            StringOps.SystemStringComparisonType) == 0)
                    {
                        nameFlags |= ArgumentFlags.ArgumentList;
                    }

                    ArgumentFlags valueFlags = (element.Y != null) ?
                                               ArgumentFlags.HasDefault : ArgumentFlags.None;

                    Argument argument;

                    if (FlagOps.HasFlags(flags, ArgumentFlags.NameOnly, true))
                    {
                        argument = Argument.InternalCreate(
                            flags | nameFlags | valueFlags, element.X,
                            Argument.NoValue, element.Y);
                    }
                    else
                    {
                        argument = Argument.InternalCreate(
                            flags | nameFlags | valueFlags, Argument.NoName,
                            element.X, element.Y);
                    }

                    this.Add(argument);
                }
            }
        }
Ejemplo n.º 3
0
        ///////////////////////////////////////////////////////////////////////

        public bool HasFlags(
            VariableFlags hasFlags,
            bool all
            )
        {
            return(FlagOps.HasFlags(flags, hasFlags, all));
        }
Ejemplo n.º 4
0
 public bool HasFlags(
     ResultFlags hasFlags,
     bool all
     )
 {
     return(FlagOps.HasFlags(flags, hasFlags, all));
 }
Ejemplo n.º 5
0
        ///////////////////////////////////////////////////////////////////////

        public bool HasFlags(
            OptionFlags flags,
            bool all
            )
        {
            return(FlagOps.HasFlags(this.flags, flags, all));
        }
Ejemplo n.º 6
0
        ///////////////////////////////////////////////////////////////////////

        public ReturnCode ToList(
            AliasFlags hasFlags,
            AliasFlags notHasFlags,
            bool hasAll,
            bool notHasAll,
            string pattern,
            bool noCase,
            ref StringList list,
            ref Result error
            )
        {
            StringList inputList;

            //
            // NOTE: If no flags were supplied, we do not bother filtering on
            //       them.
            //
            if ((hasFlags == AliasFlags.None) &&
                (notHasFlags == AliasFlags.None))
            {
                inputList = new StringList(this.Keys);
            }
            else
            {
                inputList = new StringList();

                foreach (KeyValuePair <string, _Wrappers.Alias> pair in this)
                {
                    IAlias alias = pair.Value as IAlias;

                    if (alias == null)
                    {
                        continue;
                    }

                    if (((hasFlags == AliasFlags.None) ||
                         FlagOps.HasFlags(
                             alias.AliasFlags, hasFlags, hasAll)) &&
                        ((notHasFlags == AliasFlags.None) ||
                         !FlagOps.HasFlags(
                             alias.AliasFlags, notHasFlags, notHasAll)))
                    {
                        inputList.Add(pair.Key);
                    }
                }
            }

            if (list == null)
            {
                list = new StringList();
            }

            return(GenericOps <string> .FilterList(
                       inputList, list, Index.Invalid, Index.Invalid,
                       ToStringFlags.None, pattern, noCase, ref error));
        }
Ejemplo n.º 7
0
        ///////////////////////////////////////////////////////////////////////

        private ArgumentList GetArgumentsForExecute(
            ArgumentList arguments
            )
        {
            SubCommandFlags subCommandFlags = this.Flags;

            if (FlagOps.HasFlags(subCommandFlags,
                                 SubCommandFlags.UseExecuteArguments, true))
            {
                return(arguments);
            }

            return(null);
        }
Ejemplo n.º 8
0
        ///////////////////////////////////////////////////////////////////////

        public string ToString(
            DetailFlags detailFlags
            )
        {
            CheckDisposed();

            if (FlagOps.HasFlags(
                    detailFlags, DetailFlags.ICallFrameNameOnly, true))
            {
                return((name != null) ? name : String.Empty);
            }
            else
            {
                return(ToList(detailFlags).ToString());
            }
        }
Ejemplo n.º 9
0
        ///////////////////////////////////////////////////////////////////////

        internal static bool MaybeDispose(
            IEvent @event /* in */
            )
        {
            if (@event != null)
            {
                EventFlags flags = EntityOps.GetFlagsNoThrow(@event);

                if (FlagOps.HasFlags(
                        flags, EventFlags.FireAndForget, true))
                {
                    return(Dispose(@event));
                }
            }

            return(false);
        }
Ejemplo n.º 10
0
        ///////////////////////////////////////////////////////////////////////

        public bool MaybeAddOrReplace(
            FindFlags flags, /* in */
            string key,      /* in */
            TclBuild value,  /* in */
            ref Result error /* out */
            )
        {
            if (key == null)
            {
                error = String.Format(
                    "can't add Tcl build file {0}: invalid key",
                    FormatOps.TclBuildFileName(value));

                return(false);
            }

            if (FlagOps.HasFlags(flags, FindFlags.TrustedOnly, true) &&
                ((value == null) ||
                 !RuntimeOps.IsFileTrusted(value.FileName, IntPtr.Zero)))
            {
                error = String.Format(
                    "can't add Tcl build file {0}: not trusted",
                    FormatOps.TclBuildFileName(value));

                return(false);
            }

            if (!this.ContainsKey(key))
            {
                this.Add(key, value);
                return(true);
            }

            if (FlagOps.HasFlags(
                    flags, FindFlags.OverwriteBuilds, true))
            {
                this[key] = value;
                return(true);
            }

            error = String.Format(
                "can't add Tcl build file {0}: already present",
                FormatOps.TclBuildFileName(value));

            return(false);
        }
Ejemplo n.º 11
0
        ///////////////////////////////////////////////////////////////////////

        public int GetOptionalCount()
        {
            //
            // NOTE: Return the total number of arguments in the list
            //       that are optional.  In order for an argument to
            //       be considered optional, it must meet the following
            //       criteria:
            //
            //       1. It must have a default value that is not null.
            //
            //       2. No non-optional arguments may occur after it
            //          in the argument list (COMPAT: Tcl).
            //
            int result = 0;

            //
            // NOTE: Grab the count as we need to use it several times in
            //       this method.
            //
            int count = this.Count;

            //
            // NOTE: Count all the arguments starting from the end of the
            //       list going backward that have a default value.
            //
            int index = IsVariadic(false) ? count - 2 : count - 1;

            for (; index >= 0; index--)
            {
                Argument argument = this[index];

                if ((argument != null) && FlagOps.HasFlags(
                        argument.Flags, ArgumentFlags.HasDefault, true))
                {
                    result++;
                }
                else
                {
                    break;
                }
            }

            return(result);
        }
Ejemplo n.º 12
0
        ///////////////////////////////////////////////////////////////////////

        public virtual ReturnCode AddOrUpdateSubCommand(
            string name,
            ISubCommand subCommand,
            IClientData clientData,
            SubCommandFlags flags,
            ref Result error
            )
        {
            if (name == null)
            {
                error = "invalid sub-command name";
                return(ReturnCode.Error);
            }

            EnsembleDictionary subCommands = this.SubCommands;

            if (subCommands == null)
            {
                error = "sub-commands not available";
                return(ReturnCode.Error);
            }

            if ((subCommand == null) &&
                FlagOps.HasFlags(flags, SubCommandFlags.Core, true))
            {
                subCommand = GetCoreSubCommand();
            }

            subCommands[name] = subCommand;

            if (subCommand != null)
            {
                EnsembleDictionary subSubCommands = subCommand.SubCommands;

                if (subSubCommands != null)
                {
                    subSubCommands[name] = subCommand;
                }
            }

            return(ReturnCode.Ok);
        }
Ejemplo n.º 13
0
        ///////////////////////////////////////////////////////////////////////

        public override ReturnCode Initialize(
            Interpreter interpreter,
            IClientData clientData,
            ref Result result
            )
        {
            if (interpreter != null)
            {
                NotifyType notifyTypes = GetTypes(interpreter);

                if (!FlagOps.HasFlags(
                        interpreter.NotifyTypes, notifyTypes, true))
                {
                    //
                    // NOTE: Add the notify types that we need to the
                    //       interpreter.
                    //
                    interpreter.GlobalNotifyTypes |= notifyTypes;
                    savedNotifyTypes = notifyTypes;
                }

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

                NotifyFlags notifyFlags = GetFlags(interpreter);

                if (!FlagOps.HasFlags(
                        interpreter.NotifyFlags, notifyFlags, true))
                {
                    //
                    // NOTE: Add the notify flags that we need to the
                    //       interpreter.
                    //
                    interpreter.GlobalNotifyFlags |= notifyFlags;
                    savedNotifyFlags = notifyFlags;
                }
            }

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

            return(base.Initialize(interpreter, clientData, ref result));
        }
Ejemplo n.º 14
0
        ///////////////////////////////////////////////////////////////////////

        internal ArgumentList(
            IEnumerable <string> collection,
            ArgumentFlags flags
            )
            : this()
        {
            foreach (string item in collection)
            {
                Argument argument;

                if (FlagOps.HasFlags(flags, ArgumentFlags.NameOnly, true))
                {
                    argument = Argument.InternalCreate(flags, item);
                }
                else
                {
                    argument = Argument.InternalCreate(
                        flags, Argument.NoName, item);
                }

                this.Add(argument);
            }
        }
Ejemplo n.º 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 = "wrong # args: should be \"variable ?name value...? name ?value?\"";
                return(ReturnCode.Error);
            }

            ICallFrame localFrame = null;

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

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

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

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

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

            ICallFrame otherFrame = null;

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

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

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

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

                    IVariable otherVariable = null;
                    Result    error         = null;

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

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

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

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

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

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

            result = String.Empty;
            return(ReturnCode.Ok);
        }
Ejemplo n.º 16
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);
        }
Ejemplo n.º 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);
        }
Ejemplo n.º 18
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);
        }
Ejemplo n.º 19
0
        ///////////////////////////////////////////////////////////////////////

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

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

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

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

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

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

                    AliasFlags aliasFlags = this.AliasFlags;

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

                    interpreter.PushAutomaticCallFrame(frame);

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

                    bool targetUsable;

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

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

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

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

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

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

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

            return(code);
        }
Ejemplo n.º 20
0
        ///////////////////////////////////////////////////////////////////////

        #region INotify Members
        public override ReturnCode Notify(
            Interpreter interpreter,
            IScriptEventArgs eventArgs,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            //
            // NOTE: If we are disabled -OR- there are no event arguments -OR-
            //       this event does not match the kind we are interested in
            //       then just return "success" now.
            //
            if (disabled || (eventArgs == null) ||
                !FlagOps.HasFlags(
                    eventArgs.NotifyTypes, NotifyType.Engine, false) ||
                !FlagOps.HasFlags(
                    eventArgs.NotifyFlags, NotifyFlags.Executed, false))
            {
                return(ReturnCode.Ok);
            }

            //
            // NOTE: In "direct" mode, skip [almost] all the tracing ceremony
            //       and just call into Trace.WriteLine().  Otherwise, use the
            //       TraceOps class and all its special handling.  Either way,
            //       figure out the String.Format() arguments ahead of time,
            //       based on our current "normalize" and "ellipsis" settings.
            //
            try
            {
                string arg0 = FormatOps.WrapTraceOrNull(
                    normalizeArguments, ellipsisArguments, quoteArguments,
                    displayArguments, eventArgs.Arguments);

                string arg1 = FormatOps.WrapTraceOrNull(
                    normalizeResult, ellipsisResult, quoteResult,
                    displayResult, eventArgs.Result);

                if (direct)
                {
                    //
                    // NOTE: This is just an extremely thin wrapper around
                    //       the Trace.WriteLine method.
                    //
                    DebugOps.TraceWriteLine(String.Format(
                                                directFormat, arg0, arg1), directCategory);
                }
                else
                {
                    //
                    // NOTE: Use the tracing subsystem.
                    //
                    TraceOps.DebugTrace(String.Format(
                                            normalFormat, arg0, arg1), normalCategory,
                                        TracePriority.EngineDebug);
                }

                return(ReturnCode.Ok);
            }
            catch (Exception e)
            {
                TraceOps.DebugTrace(
                    e, typeof(Trace).Name,
                    TracePriority.EngineError);

                result = e;
                return(ReturnCode.Error);
            }
        }
Ejemplo n.º 21
0
        private Version loading; // which version are we actively loading?

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

        public override ReturnCode Load(
            Interpreter interpreter,
            Version version,
            ref Result result
            )
        {
            if (interpreter != null)
            {
                if (version != null)
                {
                    string name = this.Name;
                    VersionStringDictionary ifNeeded = this.IfNeeded;

                    if (ifNeeded != null)
                    {
                        string text;

                        if (ifNeeded.TryGetValue(version, out text))
                        {
                            if (!FlagOps.HasFlags(Flags, PackageFlags.Loading, true))
                            {
                                Flags  |= PackageFlags.Loading;
                                loading = version;

                                try
                                {
                                    return(interpreter.EvaluateGlobalScript(
                                               text, ref result));
                                }
                                catch (Exception e)
                                {
                                    result = String.Format(
                                        "caught exception while evaluating ifneeded script: {0}",
                                        e);
                                }
                                finally
                                {
                                    loading = null;
                                    Flags  &= ~PackageFlags.Loading;
                                }
                            }
                            else
                            {
                                result = String.Format(
                                    "circular package dependency: " +
                                    "attempt to provide \"{0}\" requires \"{1}\"",
                                    FormatOps.PackageName(name, version),
                                    FormatOps.PackageName(name, loading));
                            }
                        }
                        else
                        {
                            result = String.Format(
                                "can't find package \"{0}\"",
                                FormatOps.PackageName(name, version));
                        }
                    }
                    else
                    {
                        result = String.Format(
                            "package \"{0}\" ifneeded scripts not available",
                            name);
                    }
                }
                else
                {
                    result = "invalid package version";
                }
            }
            else
            {
                result = "invalid interpreter";
            }

            return(ReturnCode.Error);
        }
Ejemplo n.º 22
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);
            }
        }
Ejemplo n.º 23
0
        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        ///   Initialize the plugin and add any contained commands.
        ///
        ///   WARNING: PLEASE DO NOT CHANGE THIS METHOD BECAUSE DERIVED PLUGINS
        ///            DEPEND ON ITS EXACT SEMANTICS.
        /// </summary>
        ///
        /// <param name="interpreter">
        ///   The interpreter context we are executing in.
        /// </param>
        ///
        /// <param name="clientData">
        ///   The extra data supplied when this plugin was initially created,
        ///   if any.
        /// </param>
        ///
        /// <param name="result">
        ///   Upon success, this may contain an informational message.
        ///   Upon failure, this must contain an appropriate error message.
        /// </param>
        ///
        /// <returns>
        ///   ReturnCode.Ok on success, ReturnCode.Error on failure.
        /// </returns>
        public virtual ReturnCode Initialize(
            Interpreter interpreter,
            IClientData clientData,
            ref Result result
            )
        {
            ReturnCode code;

            if (FlagOps.HasFlags(
                    this.Flags, PluginFlags.NoInitialize, true))
            {
                if (!FlagOps.HasFlags(
                        this.Flags, PluginFlags.NoInitializeFlag,
                        true))
                {
                    initialized = true;
                }

                if (!FlagOps.HasFlags(
                        this.Flags, PluginFlags.NoResult, true))
                {
                    result = String.Empty;
                }

                code = ReturnCode.Ok;
            }
            else
            {
                //
                // NOTE: We require a valid interpreter context.
                //
                if (interpreter != null)
                {
                    code = ReturnCode.Ok;

                    if ((code == ReturnCode.Ok) && !FlagOps.HasFlags(
                            this.Flags, PluginFlags.NoCommands, true))
                    {
                        //
                        // NOTE: Call the interpreter helper method that
                        //       takes care of loading all valid commands
                        //       (i.e. classes that implement ICommand,
                        //       directly or indirectly) in this plugin.
                        //
                        code = interpreter.AddCommands(
                            this, clientData, CommandFlags.None,
                            ref result);

                        if (code == ReturnCode.Ok)
                        {
                            code = interpreter.MoveExposedAndHiddenCommands(
                                this.Flags, ref result);
                        }
                    }

                    if ((code == ReturnCode.Ok) && !FlagOps.HasFlags(
                            this.Flags, PluginFlags.NoPolicies, true))
                    {
                        //
                        // NOTE: Call the interpreter helper method that
                        //       takes care of loading all valid policies
                        //       (i.e. methods that are flagged as a "policy"
                        //       and are of the appropriate delegate type(s))
                        //       in this plugin.
                        //
                        code = interpreter.AddPolicies(
                            this, clientData, ref result);
                    }

                    Version version = null;

                    if ((code == ReturnCode.Ok) && !FlagOps.HasFlags(
                            this.Flags, PluginFlags.NoProvide, true))
                    {
                        //
                        // NOTE: Grab the plugin version now, if
                        //       necessary, since we know that we
                        //       need it.
                        //
                        if (version == null)
                        {
                            version = this.Version;
                        }

                        //
                        // NOTE: Formally "provide" (i.e. announce) this
                        //       package to the interpreter so that scripts
                        //       can easily detect it.
                        //
                        code = interpreter.PkgProvide(
                            this.GetType().FullName, version,
                            GetPackageFlags(), ref result);
                    }

                    //
                    // NOTE: If the above steps succeeded, mark the
                    //       plugin as initialized and return an
                    //       appropriate result.
                    //
                    if (code == ReturnCode.Ok)
                    {
                        if (!FlagOps.HasFlags(
                                this.Flags, PluginFlags.NoInitializeFlag,
                                true))
                        {
                            initialized = true;
                        }

                        //
                        // NOTE: Returning the loaded plugin name
                        //       and version is HIGHLY RECOMMENDED
                        //       here.
                        //
                        if (!FlagOps.HasFlags(
                                this.Flags, PluginFlags.NoResult, true))
                        {
                            //
                            // NOTE: Grab the plugin version now, if
                            //       necessary, since we know that
                            //       we need it.
                            //
                            if (version == null)
                            {
                                version = this.Version;
                            }

                            result = StringList.MakeList(
                                this.Name, version);
                        }
                    }
                }
                else
                {
                    result = "invalid interpreter";
                    code   = ReturnCode.Error;
                }
            }

            return(code);
        }
Ejemplo n.º 24
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        #region IExecute Members
        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)
                    {
                        //
                        // NOTE: Grab the variable and event wait flags from the
                        //       interpreter and use them as the defaults for the
                        //       associated options.
                        //
                        EventWaitFlags eventWaitFlags = interpreter.EventWaitFlags;
                        VariableFlags  variableFlags  = interpreter.EventVariableFlags;

                        OptionDictionary options = new OptionDictionary(
                            new IOption[] {
                            new Option(null,
                                       OptionFlags.MustHaveObjectValue | OptionFlags.Unsafe,
                                       Index.Invalid, Index.Invalid, "-handle", null),
                            new Option(typeof(EventWaitFlags),
                                       OptionFlags.MustHaveEnumValue | OptionFlags.Unsafe,
                                       Index.Invalid, Index.Invalid, "-eventwaitflags",
                                       new Variant(eventWaitFlags)),
                            new Option(typeof(VariableFlags),
                                       OptionFlags.MustHaveEnumValue | OptionFlags.Unsafe,
                                       Index.Invalid, Index.Invalid, "-variableflags",
                                       new Variant(variableFlags)),
                            new Option(null,
                                       OptionFlags.MustHaveIntegerValue | OptionFlags.Unsafe,
                                       Index.Invalid, Index.Invalid, "-limit", null),
                            new Option(null, OptionFlags.Unsafe, Index.Invalid,
                                       Index.Invalid, "-force", null),
                            new Option(null, OptionFlags.Unsafe, Index.Invalid,
                                       Index.Invalid, "-nocomplain", null),
                            new Option(null, OptionFlags.Unsafe, Index.Invalid,
                                       Index.Invalid, "-leaveresult", null),
                            new Option(null, OptionFlags.None, Index.Invalid,
                                       Index.Invalid, Option.EndOfOptions, null)
                        });

                        int argumentIndex = Index.Invalid;

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

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

                                if (options.IsPresent("-handle", ref value))
                                {
                                    IObject @object = (IObject)value.Value;

                                    if ((@object.Value == null) ||
                                        (@object.Value is EventWaitHandle))
                                    {
                                        @event = (EventWaitHandle)@object.Value;
                                    }
                                    else
                                    {
                                        result = "option value has invalid EventWaitHandle";
                                        code   = ReturnCode.Error;
                                    }
                                }

                                if (code == ReturnCode.Ok)
                                {
                                    int limit = 0;

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

                                    if (options.IsPresent("-eventwaitflags", ref value))
                                    {
                                        eventWaitFlags = (EventWaitFlags)value.Value;
                                    }

                                    if (options.IsPresent("-variableflags", ref value))
                                    {
                                        variableFlags = (VariableFlags)value.Value;
                                    }

                                    bool force = false;

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

                                    bool noComplain = false;

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

                                    bool leaveResult = false;

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

                                    //
                                    // NOTE: Typically, we do not want to enter a wait state if
                                    //       there are no events queued because there would be
                                    //       no possible way to ever (gracefully) exit the wait;
                                    //       however, there are exceptions to this.
                                    //
                                    if (force || interpreter.ShouldWaitVariable())
                                    {
                                        //
                                        // HACK: The call to ThreadOps.IsStaThread here is made
                                        //       under the assumption that no user-interface
                                        //       thread can exist without also being an STA
                                        //       thread.  This may eventually prove to be false;
                                        //       however, currently WinForms, WPF, et al require
                                        //       this (i.e. an STA thread).
                                        //
                                        if (!FlagOps.HasFlags(
                                                eventWaitFlags, EventWaitFlags.UserInterface,
                                                true) && ThreadOps.IsStaThread())
                                        {
                                            eventWaitFlags |= EventWaitFlags.UserInterface;
                                        }

                                        code = interpreter.WaitVariable(eventWaitFlags,
                                                                        variableFlags, arguments[argumentIndex], limit,
                                                                        @event, ref result);

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

                                        if ((code == ReturnCode.Ok) && !leaveResult)
                                        {
                                            Engine.ResetResult(interpreter, ref result);
                                        }
                                    }
                                    else
                                    {
                                        result = String.Format(
                                            "can't wait for variable \"{0}\": would wait forever",
                                            arguments[1]);

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

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

            return(code);
        }
Ejemplo n.º 25
0
        ///////////////////////////////////////////////////////////////////////

        public static IOption FromString(
            Interpreter interpreter,
            string text,
            AppDomain appDomain,
            ValueFlags valueFlags,
            CultureInfo cultureInfo,
            ref Result error
            )
        {
            StringList list = null;

            if (Parser.SplitList(
                    interpreter, text, 0, Length.Invalid, true,
                    ref list, ref error) != ReturnCode.Ok)
            {
                return(null);
            }

            if (list.Count < MinimumElementCount)
            {
                error = String.Format(
                    "cannot create option, only {0} of {1} " +
                    "required elements were specified", list.Count,
                    MinimumElementCount);

                return(null);
            }

            bool allowInteger;
            bool strict;
            bool verbose;
            bool noCase;

            _Public.Value.ExtractTypeValueFlags(
                valueFlags, out allowInteger, out strict,
                out verbose, out noCase);

            object enumValue = EnumOps.TryParseFlagsEnum(
                interpreter, typeof(OptionFlags), null,
                list[0], cultureInfo, allowInteger, strict,
                noCase, ref error);

            if (!(enumValue is OptionFlags))
            {
                return(null);
            }

            OptionFlags optionFlags = (OptionFlags)enumValue;
            string      name        = list[1];

            if (name == null)
            {
                error = "invalid option name";
                return(null);
            }

            int  nextIndex = MinimumElementCount;
            Type type      = null;

            if (FlagOps.HasFlags(
                    optionFlags, OptionFlags.MustBeEnumMask, false))
            {
                if (nextIndex >= list.Count)
                {
                    error = String.Format(
                        "option with {0} or {1} flags must have type name",
                        FormatOps.WrapOrNull(OptionFlags.MustBeEnum),
                        FormatOps.WrapOrNull(OptionFlags.MustBeEnumList));

                    return(null);
                }

                ResultList errors = null;

                if (_Public.Value.GetType(
                        interpreter, list[nextIndex], null, appDomain,
                        _Public.Value.GetTypeValueFlags(optionFlags),
                        cultureInfo, ref type, ref errors) != ReturnCode.Ok)
                {
                    error = errors;
                    return(null);
                }

                nextIndex++;
            }

            Variant value = null;

            if (ScriptOps.GetOptionValue(
                    interpreter, list, type, optionFlags, false, allowInteger,
                    strict, noCase, cultureInfo, ref value, ref nextIndex,
                    ref error) != ReturnCode.Ok)
            {
                return(null);
            }

            int groupIndex = _Constants.Index.Invalid;

            if (nextIndex < list.Count)
            {
                if (_Public.Value.GetInteger2(
                        list[nextIndex], ValueFlags.AnyInteger, cultureInfo,
                        ref groupIndex, ref error) != ReturnCode.Ok)
                {
                    return(null);
                }

                nextIndex++;
            }

            return(new Option(
                       type, optionFlags, groupIndex, _Constants.Index.Invalid,
                       name, value));
        }
Ejemplo n.º 26
0
        /// <summary>
        ///   This is the constructor used by the core library to create an
        ///   instance of the plugin, passing the necessary data to be used
        ///   for initializing the plugin.
        /// </summary>
        ///
        /// <param name="pluginData">
        ///   An instance of the plugin data component used to hold the data
        ///   necessary to fully initialize the plugin instance.  This
        ///   parameter may be null.  Derived plugins are free to override
        ///   this constructor; however, they are very strongly encouraged to
        ///   call this constructor (i.e. the base class constructor) in that
        ///   case.
        /// </param>
        public Default(
            IPluginData pluginData
            )
        {
            kind = IdentifierKind.Plugin;

            //
            // VIRTUAL: Id of the deepest derived class.
            //
            id = AttributeOps.GetObjectId(this);

            //
            // VIRTUAL: Group of the deepest derived class.
            //
            group = AttributeOps.GetObjectGroup(this);

            //
            // NOTE: Is the supplied plugin data valid?
            //
            if (pluginData != null)
            {
                EntityOps.MaybeSetGroup(
                    this, pluginData.Group);

                name         = pluginData.Name;
                description  = pluginData.Description;
                flags        = pluginData.Flags;
                clientData   = pluginData.ClientData;
                version      = pluginData.Version;
                uri          = pluginData.Uri;
                appDomain    = pluginData.AppDomain;
                assembly     = pluginData.Assembly;
                assemblyName = pluginData.AssemblyName;
                fileName     = pluginData.FileName;
                typeName     = pluginData.TypeName;
            }

            //
            // NOTE: Are we going to use their command list or create an
            //       entirely new list?
            //
            if ((pluginData != null) && (pluginData.Commands != null))
            {
                commands = pluginData.Commands;
            }
            else
            {
                commands = new CommandDataList();
            }

            //
            // NOTE: Are we going to use their policy list or create an
            //       entirely new list?
            //
            if ((pluginData != null) && (pluginData.Policies != null))
            {
                policies = pluginData.Policies;
            }
            else
            {
                policies = new PolicyDataList();
            }

            //
            // NOTE: Are we going to use their command tokens or create an
            //       entirely new list?
            //
            if ((pluginData != null) && (pluginData.CommandTokens != null))
            {
                commandTokens = pluginData.CommandTokens;
            }
            else
            {
                commandTokens = new LongList();
            }

            //
            // NOTE: Are we going to use their command tokens or create an
            //       entirely new list?
            //
            if ((pluginData != null) && (pluginData.FunctionTokens != null))
            {
                functionTokens = pluginData.FunctionTokens;
            }
            else
            {
                functionTokens = new LongList();
            }

            //
            // NOTE: Are we going to use their policy tokens or create an
            //       entirely new list?
            //
            if ((pluginData != null) && (pluginData.PolicyTokens != null))
            {
                policyTokens = pluginData.PolicyTokens;
            }
            else
            {
                policyTokens = new LongList();
            }

            //
            // NOTE: Are we going to use their trace tokens or create an
            //       entirely new list?
            //
            if ((pluginData != null) && (pluginData.TraceTokens != null))
            {
                traceTokens = pluginData.TraceTokens;
            }
            else
            {
                traceTokens = new LongList();
            }

            //
            // NOTE: Are we going to use the resource manager they specified or
            //       create a new one based on the plugin name and assembly?
            //
            if ((pluginData != null) && (pluginData.ResourceManager != null))
            {
                resourceManager = pluginData.ResourceManager;
            }
            else
            {
                //
                // NOTE: If the assembly is null we are probably loaded into an
                //       isolated application domain.  Therefore, in that case,
                //       and only in that case, since we are executing in the
                //       target application domain, load the assembly based on
                //       the assembly name and then use that to create the
                //       resource manager.  However, do not simply set the
                //       assembly field of this plugin to any non-null value
                //       because we do not want to cause issues with the
                //       interpreter plugin manager later.  Also, skip attempts
                //       to create a resource manager if the NoResources flag
                //       has been set on the plugin.
                //
                if (!FlagOps.HasFlags(flags, PluginFlags.NoResources, true))
                {
                    if (assembly != null)
                    {
                        resourceManager = RuntimeOps.NewResourceManager(
                            assembly);
                    }
                    else if (assemblyName != null)
                    {
                        resourceManager = RuntimeOps.NewResourceManager(
                            assemblyName);
                    }
                }
            }

            //
            // NOTE: Are we going to use the auxiliary data they specified or
            //       create a new one?
            //
            if ((pluginData != null) && (pluginData.AuxiliaryData != null))
            {
                auxiliaryData = pluginData.AuxiliaryData;
            }
            else
            {
                if (!FlagOps.HasFlags(
                        flags, PluginFlags.NoAuxiliaryData, true))
                {
                    auxiliaryData = new ObjectDictionary();
                }
            }

            //
            // NOTE: Also store the plugin token (which may be zero at this
            //       point).
            //
            if (pluginData != null)
            {
                token = pluginData.Token;
            }
        }
Ejemplo n.º 27
0
        ///////////////////////////////////////////////////////////////////////

        public ReturnCode ToList(
            OperatorFlags hasFlags,
            OperatorFlags notHasFlags,
            bool hasAll,
            bool notHasAll,
            string pattern,
            bool noCase,
            ref StringList list,
            ref Result error
            )
        {
            StringList inputList;

            //
            // NOTE: If no flags were supplied, we do not bother filtering on
            //       them.
            //
            if ((hasFlags == OperatorFlags.None) &&
                (notHasFlags == OperatorFlags.None))
            {
                inputList = new StringList();

                foreach (KeyValuePair <string, _Wrappers.Operator> pair in this)
                {
                    _Wrappers.Operator @operator = pair.Value;

                    if (@operator != null)
                    {
                        inputList.Add(StringList.MakeList(
                                          @operator.Lexeme.ToString(),
                                          @operator.Operands.ToString(),
                                          @operator.Flags.ToString(),
                                          pair.Key));
                    }
                }
            }
            else
            {
                inputList = new StringList();

                foreach (KeyValuePair <string, _Wrappers.Operator> pair in this)
                {
                    _Wrappers.Operator @operator = pair.Value;

                    if (@operator != null)
                    {
                        if (((hasFlags == OperatorFlags.None) ||
                             FlagOps.HasFlags(@operator.Flags,
                                              hasFlags, hasAll)) &&
                            ((notHasFlags == OperatorFlags.None) ||
                             !FlagOps.HasFlags(@operator.Flags,
                                               notHasFlags, notHasAll)))
                        {
                            inputList.Add(StringList.MakeList(
                                              @operator.Lexeme.ToString(),
                                              @operator.Operands.ToString(),
                                              @operator.Flags.ToString(),
                                              pair.Key));
                        }
                    }
                }
            }

            if (list == null)
            {
                list = new StringList();
            }

            return(GenericOps <string> .FilterList(
                       inputList, list, Index.Invalid, Index.Invalid,
                       ToStringFlags.None, pattern, noCase, ref error));
        }
Ejemplo n.º 28
0
        ///////////////////////////////////////////////////////////////////////

        /// <summary>
        ///   Terminate the plugin and remove any contained commands.
        ///
        ///   WARNING: PLEASE DO NOT CHANGE THIS METHOD BECAUSE DERIVED PLUGINS
        ///            DEPEND ON ITS EXACT SEMANTICS.
        /// </summary>
        ///
        /// <param name="interpreter">
        ///   The interpreter context we are executing in.
        /// </param>
        ///
        /// <param name="clientData">
        ///   The extra data supplied when this plugin was initially created,
        ///   if any.
        /// </param>
        ///
        /// <param name="result">
        ///   Upon success, this may contain an informational message.
        ///   Upon failure, this must contain an appropriate error message.
        /// </param>
        ///
        /// <returns>
        ///   ReturnCode.Ok on success, ReturnCode.Error on failure.
        /// </returns>
        public virtual ReturnCode Terminate(
            Interpreter interpreter,
            IClientData clientData,
            ref Result result
            )
        {
            ReturnCode code;

            if (FlagOps.HasFlags(
                    this.Flags, PluginFlags.NoTerminate, true))
            {
                if (!FlagOps.HasFlags(
                        this.Flags, PluginFlags.NoInitializeFlag,
                        true))
                {
                    initialized = false;
                }

                if (!FlagOps.HasFlags(
                        this.Flags, PluginFlags.NoResult, true))
                {
                    result = null;
                }

                code = ReturnCode.Ok;
            }
            else
            {
                //
                // NOTE: We require a valid interpreter context.
                //
                if (interpreter != null)
                {
                    code = ReturnCode.Ok;

                    if ((code == ReturnCode.Ok) && !FlagOps.HasFlags(
                            this.Flags, PluginFlags.NoTraces, true))
                    {
                        //
                        // NOTE: Call the interpreter helper method that
                        //       takes care of unloading all previously
                        //       loaded traces (i.e. methods that are
                        //       flagged as a "trace" and are of the
                        //       appropriate delegate type(s)) from this
                        //       plugin.
                        //
                        code = interpreter.RemoveTraces(
                            this, clientData, ref result);
                    }

                    if ((code == ReturnCode.Ok) && !FlagOps.HasFlags(
                            this.Flags, PluginFlags.NoPolicies, true))
                    {
                        //
                        // NOTE: Call the interpreter helper method that
                        //       takes care of unloading all previously
                        //       loaded policies (i.e. methods that are
                        //       flagged as a "policy" and are of the
                        //       appropriate delegate type(s)) from this
                        //       plugin.
                        //
                        code = interpreter.RemovePolicies(
                            this, clientData, ref result);
                    }

                    if ((code == ReturnCode.Ok) && !FlagOps.HasFlags(
                            this.Flags, PluginFlags.NoFunctions, true))
                    {
                        //
                        // NOTE: Call the interpreter helper method that
                        //       takes care of unloading all previously
                        //       loaded functions (i.e. classes that
                        //       implement IFunction, directly or
                        //       indirectly) from this plugin.
                        //
                        code = interpreter.RemoveFunctions(
                            this, clientData, FunctionFlags.None,
                            ref result);
                    }

                    if ((code == ReturnCode.Ok) && !FlagOps.HasFlags(
                            this.Flags, PluginFlags.NoCommands, true))
                    {
                        //
                        // NOTE: Call the interpreter helper method that
                        //       takes care of unloading all previously
                        //       loaded commands (i.e. classes that
                        //       implement ICommand, directly or
                        //       indirectly) from this plugin.
                        //
                        code = interpreter.RemoveCommands(
                            this, clientData, CommandFlags.None,
                            ref result);
                    }

                    Version version = null;

                    if ((code == ReturnCode.Ok) && !FlagOps.HasFlags(
                            this.Flags, PluginFlags.NoProvide, true))
                    {
                        //
                        // NOTE: Grab the plugin version now, if
                        //       necessary, since we know that we
                        //       need it.
                        //
                        if (version == null)
                        {
                            version = this.Version;
                        }

                        //
                        // NOTE: Formally "withdraw" (i.e. unannounce)
                        //       this package from the interpreter so
                        //       that scripts can no longer detect it.
                        //
                        code = interpreter.WithdrawPackage(
                            this.GetType().FullName, version,
                            ref result);
                    }

                    //
                    // NOTE: If the above steps succeeded, mark the
                    //       plugin as not initialized and return an
                    //       appropriate result.
                    //
                    if (code == ReturnCode.Ok)
                    {
                        if (!FlagOps.HasFlags(
                                this.Flags, PluginFlags.NoInitializeFlag,
                                true))
                        {
                            initialized = false;
                        }

                        //
                        // NOTE: Returning the unloaded plugin name
                        //       and version is HIGHLY RECOMMENDED
                        //       here.
                        //
                        if (!FlagOps.HasFlags(
                                this.Flags, PluginFlags.NoResult, true))
                        {
                            //
                            // NOTE: Grab the plugin version now, if
                            //       necessary, since we know that
                            //       we need it.
                            //
                            if (version == null)
                            {
                                version = this.Version;
                            }

                            result = StringList.MakeList(
                                this.Name, version);
                        }
                    }
                }
                else
                {
                    result = "invalid interpreter";
                    code   = ReturnCode.Error;
                }
            }

            return(code);
        }
Ejemplo n.º 29
0
        ///////////////////////////////////////////////////////////////////////

        #region Private Methods
        private void Initialize()
        {
            noHandle = FlagOps.HasFlags(
                marshalFlags, MarshalFlags.NoHandle, true);
        }
Ejemplo n.º 30
0
        ///////////////////////////////////////////////////////////////////////

        public string ToString(
            OptionFlags flags
            )
        {
            string result;

            if (FlagOps.HasFlags(flags, OptionFlags.MustHaveValue, true))
            {
                if (FlagOps.HasFlags(
                        flags, OptionFlags.MustBeExecute, true))
                {
                    result = "execute";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBePlugin, true))
                {
                    result = "plugin";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeEncoding, true))
                {
                    result = "encoding";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeSecureString, true))
                {
                    result = "secure string";
                }
#if NATIVE && TCL
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeTclInterpreter, true))
                {
                    result = "tcl interpreter";
                }
#endif
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeRelativeNamespace, true))
                {
                    result = "relative namespace";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeAbsoluteNamespace, true))
                {
                    result = "absolute namespace";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeOption, true))
                {
                    result = "option";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeAlias, true))
                {
                    result = "alias";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeReturnCodeList, true))
                {
                    result = "return code list";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeAbsoluteUri, true))
                {
                    result = "absolute uri";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeVersion, true))
                {
                    result = "version";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeTypeList, true))
                {
                    result = "type list";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeType, true))
                {
                    result = "type";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeInterpreter, true))
                {
                    result = "interpreter";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeObject, true))
                {
                    result = "object";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeValue, true))
                {
                    result = "numeric";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeMatchMode, true))
                {
                    result = "match mode";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeDictionary, true))
                {
                    result = "dictionary";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeList, true))
                {
                    result = "list";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeTimeSpan, true))
                {
                    result = "time-span";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeDateTime, true))
                {
                    result = "date-time";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeGuid, true))
                {
                    result = "guid";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeEnum, true))
                {
                    result = (type != null) ?
                             String.Format("{0} enumeration",
                                           FormatOps.TypeNameOrFullName(type)) :
                             "enumeration";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeEnumList, true))
                {
                    result = (type != null) ?
                             String.Format("{0} enumeration list",
                                           FormatOps.TypeNameOrFullName(type)) :
                             "enumeration list";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeReturnCode, true))
                {
                    result = "return code";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeLevel, true))
                {
                    result = "level";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeIndex, true))
                {
                    result = "index";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeUnsignedWideInteger, true))
                {
                    result = "unsigned wide integer";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeWideInteger, true))
                {
                    result = "wide integer";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeUnsignedInteger, true))
                {
                    result = "unsigned integer";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeInteger, true))
                {
                    result = "integer";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeUnsignedNarrowInteger, true))
                {
                    result = "unsigned narrow integer";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeNarrowInteger, true))
                {
                    result = "narrow integer";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeByte, true))
                {
                    result = "byte";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeSignedByte, true))
                {
                    result = "signed byte";
                }
                else if (FlagOps.HasFlags(
                             flags, OptionFlags.MustBeBoolean, true))
                {
                    result = "boolean";
                }
                else
                {
                    result = "string";
                }
            }
            else if (FlagOps.HasFlags(flags, OptionFlags.EndOfOptions, true))
            {
                result = "end of options";
            }
            else if (FlagOps.HasFlags(flags, OptionFlags.ListOfOptions, true))
            {
                result = "list of options";
            }
            else
            {
                result = "nothing";
            }

            return(result);
        }