Example #1
0
        ///////////////////////////////////////////////////////////////////////

        public string ToString(
            string pattern,
            bool noCase,
            bool qualified
            )
        {
            if (qualified)
            {
                StringList list = new StringList();

                foreach (Type type in this)
                {
                    if (type != null)
                    {
                        list.Add(FormatOps.QualifiedName(type));
                    }
                }

                return(GenericOps <string> .ListToString(
                           list, Index.Invalid, Index.Invalid, ToStringFlags.None,
                           Characters.Space.ToString(), pattern, noCase));
            }
            else
            {
                return(GenericOps <Type> .ListToString(
                           this, Index.Invalid, Index.Invalid, ToStringFlags.None,
                           Characters.Space.ToString(), pattern, noCase));
            }
        }
Example #2
0
        ///////////////////////////////////////////////////////////////////////

        #region Public Static Methods
        public static object StaticFireDynamicInvokeCallback(
            object firstArgument,
            object[] args
            )
        {
            ICallback callback;

            lock (syncRoot)
            {
                if ((firstArgument == null) || (callbacks == null) ||
                    !callbacks.TryGetValue(firstArgument, out callback))
                {
                    throw new ScriptException(String.Format(
                        "{0} for object {1} with hash code {2} not found",
                        typeof(ICallback), FormatOps.WrapOrNull(
                        firstArgument), RuntimeHelpers.GetHashCode(
                        firstArgument)));
                }
            }

            //
            // NOTE: The "callback" variable could be null at this point.
            //
            return CommandCallback.StaticFireDynamicInvokeCallback(
                callback, args);
        }
Example #3
0
        ///////////////////////////////////////////////////////////////////////

        public StringPairList ToList()
        {
            StringPairList list = new StringPairList();

            list.Add("findFlags", findFlags.ToString());
            list.Add("loadFlags", loadFlags.ToString());
            list.Add("findData", StringOps.GetStringsFromObject(findData));
            list.Add("fileName", fileName);
            list.Add("priority", priority.ToString());
            list.Add("sequence", sequence.ToString());
            list.Add("operatingSystem", operatingSystemId.ToString());

            list.Add("version", (version != null) ?
                     version.ToString() : null);

            list.Add("patchLevel", (patchLevel != null) ?
                     patchLevel.ToString() : null);

            list.Add("releaseLevel", releaseLevel.ToString());
            list.Add("magic", FormatOps.Hexadecimal(magic, true));
            list.Add("threaded", threaded.ToString());
            list.Add("debug", debug.ToString());
            list.Add("defaultThreaded", DefaultThreaded.ToString());
            list.Add("matchDebug", MatchDebug.ToString());

            return(list);
        }
Example #4
0
        ///////////////////////////////////////////////////////////////////////

        public override string GetString(
            Interpreter interpreter,
            string name,
            CultureInfo cultureInfo,
            ref Result error
            )
        {
            if (!enableGetString)
            {
                return(base.GetString(
                           interpreter, name, cultureInfo, ref error));
            }

            if (name != null)
            {
                return(String.Format(
                           "interpreter: {0}, name: {1}, cultureInfo: {2}",
                           FormatOps.InterpreterNoThrow(interpreter),
                           FormatOps.WrapOrNull(name),
                           FormatOps.WrapOrNull(cultureInfo)));
            }
            else
            {
                error = "invalid string name";
                return(null);
            }
        }
Example #5
0
        ///////////////////////////////////////////////////////////////////////

        #region ToString Methods
        public ReturnCode ToList(
            string pattern,
            bool noCase,
            bool fullName,
            bool qualified,
            ref StringList list,
            ref Result error
            )
        {
            StringList inputList = new StringList();

            foreach (Type type in this)
            {
                if (type != null)
                {
                    inputList.Add(FormatOps.QualifiedAndOrFullName(
                                      type, fullName, qualified, false));
                }
            }

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

            return(GenericOps <string> .FilterList(
                       inputList, list, Index.Invalid, Index.Invalid,
                       ToStringFlags.None, pattern, noCase, ref error));
        }
Example #6
0
        ///////////////////////////////////////////////////////////////////////

        #region IPackage Members
        public override ReturnCode Select(
            PackagePreference preference,
            ref Version version,
            ref Result error
            )
        {
            if (preference == PackagePreference.Default)
            {
                string name = this.Name;
                VersionStringDictionary ifNeeded = this.IfNeeded;

                if (ifNeeded != null)
                {
                    //
                    // NOTE: *HACK* For now, always select the latest version
                    //       from the list of candidate versions.
                    //
                    Version latest = null;

                    foreach (Version candidate in ifNeeded.Keys)
                    {
                        if (PackageOps.VersionCompare(candidate, latest) > 0)
                        {
                            latest = candidate;
                        }
                    }

                    //
                    // NOTE: Were we able to find the latest (i.e. any)
                    //       version?
                    //
                    if (latest != null)
                    {
                        version = latest;
                        return(ReturnCode.Ok);
                    }
                    else
                    {
                        error = String.Format(
                            "can't find package \"{0}\"",
                            FormatOps.PackageName(name, null));
                    }
                }
                else
                {
                    error = String.Format(
                        "package \"{0}\" ifneeded scripts not available",
                        name);
                }
            }
            else
            {
                error = String.Format(
                    "unsupported package preference \"{0}\"",
                    preference);
            }

            return(ReturnCode.Error);
        }
Example #7
0
        ///////////////////////////////////////////////////////////////////////

        #region IPlugin Members
        public override ReturnCode About(
            Interpreter interpreter,
            ref Result result
            )
        {
            result = FormatOps.PluginAbout(this, false);
            return(ReturnCode.Ok);
        }
Example #8
0
        ///////////////////////////////////////////////////////////////////////

        public virtual string ToString(
            string format,
            int limit,
            bool strict
            )
        {
            return(FormatOps.Ellipsis(
                       String.Format(format, this.X, this.Y), limit, strict));
        }
Example #9
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        #region Public Methods
#if CACHE_STATISTICS
        public bool HaveCacheCounts()
        {
            if (this.Count > 0)
            {
                return(true);
            }

            return(FormatOps.HaveCacheCounts(cacheCounts));
        }
Example #10
0
        ///////////////////////////////////////////////////////////////////////

        private ICommand CreateCommand(
            IClientData clientData
            )
        {
            return(new _Commands.Nop(new CommandData(
                                         FormatOps.PluginCommand(this.Assembly, this.Name,
                                                                 typeof(_Commands.Nop), null), null, null, clientData,
                                         typeof(_Commands.Nop).FullName, CommandFlags.None,
                                         this, 0)));
        }
Example #11
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        public string CacheToString()
        {
            return(StringList.MakeList(
                       "count", this.Count,
#if CACHE_DICTIONARY
                       "maximumCount", this.MaximumCount,
                       "maximumAccessCount", this.MaximumAccessCount,
#endif
                       FormatOps.CacheCounts(cacheCounts)));
        }
        ///////////////////////////////////////////////////////////////////////

        public void AddRange(
            IEnumerable <ExecuteCallback> collection
            )
        {
            foreach (ExecuteCallback item in collection)
            {
                if (item != null)
                {
                    this.Add(FormatOps.DelegateName(item), item);
                }
            }
        }
Example #13
0
        ///////////////////////////////////////////////////////////////////////

        public static StringDictionary FromString(
            string value,
            bool addOnly,
            ref Result error
            )
        {
            StringList list = StringList.FromString(value, ref error);

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

            int count = list.Count;

            if ((count % 2) != 0)
            {
                error = String.Format(
                    "list of name/value pairs must have an even number of " +
                    "elements, has {0}", count);

                return(null);
            }

            StringDictionary dictionary = new StringDictionary();

            for (int index = 0; index < count; index += 2)
            {
                string key = list[index];

                if (key == null)
                {
                    error = String.Format(
                        "key at index {0} cannot be null",
                        index);

                    return(null);
                }

                if (addOnly && dictionary.ContainsKey(key))
                {
                    error = String.Format(
                        "key {0} at index {1} already exists",
                        FormatOps.WrapOrNull(key), index);

                    return(null);
                }

                dictionary[key] = list[index + 1];
            }

            return(dictionary);
        }
Example #14
0
        ///////////////////////////////////////////////////////////////////////

        public static OptionDictionary FromString(
            Interpreter interpreter,
            string text,
            AppDomain appDomain,
            bool allowInteger,
            bool strict,
            bool verbose,
            bool noCase,
            CultureInfo cultureInfo,
            ref Result error
            )
        {
            StringList list = null;

            if (Parser.SplitList(
                    interpreter, text, 0, Length.Invalid, true,
                    ref list, ref error) == ReturnCode.Ok)
            {
                OptionDictionary options = new OptionDictionary();

                foreach (string element in list)
                {
                    IOption option = Option.FromString(
                        interpreter, element, appDomain,
                        allowInteger, strict, verbose,
                        noCase, cultureInfo, ref error);

                    if (option == null)
                    {
                        return(null);
                    }

                    if (options.Has(option))
                    {
                        error = String.Format(
                            "duplicate option name {0}",
                            FormatOps.WrapOrNull(option.Name));

                        return(null);
                    }

                    options.Add(option);
                }

                return(options);
            }

            return(null);
        }
Example #15
0
        ///////////////////////////////////////////////////////////////////////

        public static StringList GetRangeAsStringList(
            IList list,
            int firstIndex,
            int lastIndex,
            bool dequote
            )
        {
            StringList range = null;

            if (list != null)
            {
                range = new StringList();

                if (firstIndex == Index.Invalid)
                {
                    firstIndex = 0;
                }

                if (lastIndex == Index.Invalid)
                {
                    lastIndex = list.Count - 1;
                }

                for (int index = firstIndex; index <= lastIndex; index++)
                {
                    object item = list[index];

                    if (item == null)
                    {
                        range.Add((string)null);
                        continue;
                    }

                    string @string = item.ToString();

                    if (dequote)
                    {
                        @string = FormatOps.StripOuter(
                            @string, Characters.QuotationMark);
                    }

                    range.Add(@string);
                }
            }

            return(range);
        }
Example #16
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);
        }
Example #17
0
        ///////////////////////////////////////////////////////////////////////

        #region Private Constructors
        private Event(
            object syncRoot,         /* in: OPTIONAL */
            Delegate @delegate,      /* in: OPTIONAL */
            EventType type,          /* in */
            EventFlags flags,        /* in */
            EventPriority priority,  /* in */
            Interpreter interpreter, /* in: OPTIONAL */
            string name,             /* in: OPTIONAL */
            DateTime dateTime,       /* in */
            EventCallback callback,  /* in: OPTIONAL */
            IClientData clientData   /* in: OPTIONAL */
            )
        {
            this.syncRoot    = syncRoot;
            this.@delegate   = @delegate;
            this.type        = type;
            this.flags       = flags;
            this.priority    = priority;
            this.interpreter = interpreter;
            this.name        = name;
            this.dateTime    = dateTime;
            this.callback    = callback;
            this.clientData  = clientData;

            //
            // NOTE: Setup inter-thread communication event.
            //
            doneEventName = FormatOps.EventName(interpreter,
                                                typeof(Event).Name, name, GlobalState.NextEventId(
                                                    interpreter));

            doneEvent = ThreadOps.CreateEvent(doneEventName);

            //
            // NOTE: Setup the initial result state.
            //
            ResetResultData();

            //
            // NOTE: Keep track of how many event objects are created
            //       within this AppDomain.
            //
            Interlocked.Increment(ref createCount);
        }
Example #18
0
        ///////////////////////////////////////////////////////////////////////

        private bool WaitOnEventHandle(
            int milliseconds,
            ref Result error
            )
        {
            EventWaitHandle doneEvent = null;

            try
            {
                doneEvent = ThreadOps.OpenEvent(doneEventName);

                if (doneEvent != null)
                {
                    if (ThreadOps.WaitEvent(
                            doneEvent, milliseconds))
                    {
                        return(true);
                    }
                    else
                    {
                        error = String.Format(
                            "timed wait of {0} milliseconds for event {1} failed",
                            milliseconds, FormatOps.WrapOrNull(doneEventName));
                    }
                }
                else
                {
                    error = String.Format(
                        "cannot open event {0} in order to wait",
                        FormatOps.WrapOrNull(doneEventName));
                }
            }
            finally
            {
                /* NO RESULT */
                ThreadOps.CloseEvent(ref doneEvent);
            }

            return(false);
        }
Example #19
0
        ///////////////////////////////////////////////////////////////////////

        #region Internal Methods
        internal string ToTraceString()
        {
            IStringList list = new StringPairList();

            list.Add("debug", debug.ToString());
            list.Add("args", FormatOps.WrapArgumentsOrNull(true, true, args));
            list.Add("code", code.ToString());
            list.Add("breakpointType", breakpointType.ToString());
            list.Add("breakpointName", FormatOps.WrapOrNull(breakpointName));
            list.Add("token", (token != null).ToString());
            list.Add("traceInfo", (traceInfo != null).ToString());
            list.Add("engineFlags", FormatOps.WrapOrNull(engineFlags));
            list.Add("substitutionFlags", FormatOps.WrapOrNull(substitutionFlags));
            list.Add("eventFlags", FormatOps.WrapOrNull(eventFlags));
            list.Add("expressionFlags", FormatOps.WrapOrNull(expressionFlags));
            list.Add("headerFlags", FormatOps.WrapOrNull(headerFlags));
            list.Add("clientData", FormatOps.WrapOrNull(clientData));
            list.Add("arguments", FormatOps.WrapOrNull(true, true, arguments));
            list.Add("exit", exit.ToString());

            return(list.ToString());
        }
Example #20
0
        ///////////////////////////////////////////////////////////////////////

        private bool SetEventHandle(
            ref Result error
            )
        {
            EventWaitHandle doneEvent = null;

            try
            {
                doneEvent = ThreadOps.OpenEvent(doneEventName);

                if (doneEvent != null)
                {
                    if (ThreadOps.SetEvent(doneEvent))
                    {
                        return(true);
                    }
                    else
                    {
                        error = String.Format(
                            "set for event {0} failed",
                            FormatOps.WrapOrNull(doneEventName));
                    }
                }
                else
                {
                    error = String.Format(
                        "cannot open event {0} in order to set",
                        FormatOps.WrapOrNull(doneEventName));
                }
            }
            finally
            {
                /* NO RESULT */
                ThreadOps.CloseEvent(ref doneEvent);
            }

            return(false);
        }
Example #21
0
        ///////////////////////////////////////////////////////////////////////

        internal string ToTraceString()
        {
            IStringList list = new StringPairList();

            list.Add("ArgumentCallback", FormatOps.WrapOrNull(
                         FormatOps.DelegateName(argumentCallback)));

            list.Add("EvaluateScriptCallback", FormatOps.WrapOrNull(
                         FormatOps.DelegateName(evaluateScriptCallback)));

            list.Add("EvaluateFileCallback", FormatOps.WrapOrNull(
                         FormatOps.DelegateName(evaluateFileCallback)));

            list.Add("EvaluateEncodedFileCallback", FormatOps.WrapOrNull(
                         FormatOps.DelegateName(evaluateEncodedFileCallback)));

            list.Add("InteractiveLoopCallback", FormatOps.WrapOrNull(
                         FormatOps.DelegateName(interactiveLoopCallback)));

            list.Add("Initialized", initialized.ToString());
            list.Add("HadArgumentCallback", hadArgumentCallback.ToString());

            list.Add("HadEvaluateScriptCallback",
                     hadEvaluateScriptCallback.ToString());

            list.Add("HadEvaluateFileCallback",
                     hadEvaluateFileCallback.ToString());

            list.Add("HadEvaluateEncodedFileCallback",
                     hadEvaluateEncodedFileCallback.ToString());

            list.Add("HadInteractiveLoopCallback",
                     hadInteractiveLoopCallback.ToString());

            return(list.ToString());
        }
Example #22
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

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

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    try
                    {
                        string  name     = null;
                        Variant operand1 = null;
                        Variant operand2 = null;

                        code = Value.GetOperandsFromArguments(interpreter,
                                                              this, arguments, ValueFlags.AnyVariant,
                                                              interpreter.CultureInfo, ref name,
                                                              ref operand1, ref operand2, ref error);

                        if (code == ReturnCode.Ok)
                        {
                            code = Value.FixupVariants(
                                this, operand1, operand2, null, null, false, false,
                                ref error);

                            if (code == ReturnCode.Ok)
                            {
                                if (operand1.IsDouble())
                                {
                                    value = ((double)operand1.Value >= (double)operand2.Value);
                                }
                                else if (operand1.IsDecimal())
                                {
                                    value = ((decimal)operand1.Value >= (decimal)operand2.Value);
                                }
                                else if (operand1.IsWideInteger())
                                {
                                    value = ((long)operand1.Value >= (long)operand2.Value);
                                }
                                else if (operand1.IsInteger())
                                {
                                    value = ((int)operand1.Value >= (int)operand2.Value);
                                }
                                else if (operand1.IsBoolean())
                                {
                                    value = (ConversionOps.ToInt((bool)operand1.Value) >=
                                             ConversionOps.ToInt((bool)operand2.Value));
                                }
                                else
                                {
                                    error = String.Format(
                                        "unsupported operand type for operator {0}",
                                        FormatOps.OperatorName(name, this.Lexeme));

                                    code = ReturnCode.Error;
                                }
                            }
                            else
                            {
                                //
                                // NOTE: Fine, try to treat the operands as strings.
                                //
                                code = Value.FixupStringVariants(
                                    this, operand1, operand2, ref error);

                                if (code == ReturnCode.Ok)
                                {
                                    if (operand1.IsString())
                                    {
                                        value = (String.Compare(
                                                     (string)operand1.Value, (string)operand2.Value,
                                                     StringOps.UserStringComparisonType) >= 0);
                                    }
                                    else
                                    {
                                        error = String.Format(
                                            "unsupported operand type for operator {0}",
                                            FormatOps.OperatorName(name, this.Lexeme));

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

                        error = String.Format(
                            "caught math exception: {0}",
                            e);

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

            return(code);
        }
Example #23
0
        ///////////////////////////////////////////////////////////////////////

        public ReturnCode VerifyModule(
            ref Result error
            )
        {
            if (String.IsNullOrEmpty(fileName))
            {
                error = "invalid Tcl native module file name";
                return(ReturnCode.Error);
            }

            if (!NativeOps.IsValidHandle(module))
            {
                error = "invalid Tcl native module handle";
                return(ReturnCode.Error);
            }

            //
            // HACK: We cannot actually verify the native module handle on any
            //       non-Windows operating system.
            //
            if (!PlatformOps.IsWindowsOperatingSystem())
            {
                return(ReturnCode.Ok);
            }

            try
            {
                IntPtr newModule = NativeOps.GetModuleHandle(fileName);

                if (newModule == IntPtr.Zero)
                {
                    error = String.Format(
                        "bad Tcl native module handle {0}, file name {1} is " +
                        "no longer loaded", module, FormatOps.WrapOrNull(
                            fileName));

                    TraceOps.DebugTrace(String.Format(
                                            "VerifyModule: {0}", FormatOps.WrapOrNull(error)),
                                        typeof(TclModule).Name, TracePriority.NativeError);

                    return(ReturnCode.Error);
                }

                if (newModule != module)
                {
                    //
                    // NOTE: This situation should really never happen.  If it
                    //       does, that indicates that the native Tcl module
                    //       was unloaded and then reloaded out from under the
                    //       native Tcl integration subsystem.
                    //
                    error = String.Format(
                        "bad Tcl native module handle {0}, got {1} for file " +
                        "name {2}", module, newModule, FormatOps.WrapOrNull(
                            fileName));

                    TraceOps.DebugTrace(String.Format(
                                            "VerifyModule: {0}",
                                            FormatOps.WrapOrNull(error)),
                                        typeof(TclModule).Name, TracePriority.NativeError);

                    return(ReturnCode.Error);
                }

                return(ReturnCode.Ok);
            }
            catch (Exception e)
            {
                error = e;
            }

            return(ReturnCode.Error);
        }
Example #24
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)
                    {
                        OptionDictionary options = new OptionDictionary(
                            new IOption[] {
                            new Option(null, OptionFlags.NoCase | OptionFlags.MustHaveBooleanValue,
                                       Index.Invalid, Index.Invalid, "-statistics", null),
                            new Option(null, OptionFlags.NoCase | OptionFlags.MustHaveBooleanValue,
                                       Index.Invalid, Index.Invalid, "-breakOk", null),
                            new Option(null, OptionFlags.NoCase | OptionFlags.MustHaveBooleanValue,
                                       Index.Invalid, Index.Invalid, "-errorOk", null),
                            new Option(null, OptionFlags.NoCase | OptionFlags.MustHaveBooleanValue,
                                       Index.Invalid, Index.Invalid, "-noCancel", null),
                            new Option(null, OptionFlags.NoCase | OptionFlags.MustHaveBooleanValue,
                                       Index.Invalid, Index.Invalid, "-noHalt", null),
                            new Option(null, OptionFlags.NoCase | OptionFlags.MustHaveBooleanValue,
                                       Index.Invalid, Index.Invalid, "-noEvent", null),
                            new Option(null, OptionFlags.NoCase | OptionFlags.MustHaveBooleanValue,
                                       Index.Invalid, Index.Invalid, "-noExit", null),
                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid,
                                       Option.EndOfOptions, null)
                        });

                        int argumentIndex = Index.Invalid;

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

                        if (code == ReturnCode.Ok)
                        {
                            if (argumentIndex == Index.Invalid)
                            {
                                long requestedIterations = 1; /* DEFAULT: One iteration. */

                                if (arguments.Count >= 3)
                                {
                                    if (Value.GetWideInteger2(
                                            (IGetValue)arguments[2], ValueFlags.AnyWideInteger,
                                            interpreter.CultureInfo, ref requestedIterations,
                                            ref result) != ReturnCode.Ok)
                                    {
                                        return(ReturnCode.Error);
                                    }
                                }

                                Variant value      = null;
                                bool    statistics = false;

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

                                bool breakOk = false;

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

                                bool errorOk = false;

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

                                bool noCancel = false;

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

                                bool noHalt = false;

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

                                bool noExit = false;

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

                                bool noEvent = false;

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

                                //
                                // NOTE: These variables are used to keep track of
                                //       the minimum and maximum performance counts
                                //       for a given iteration (i.e. only when the
                                //       statistics option is enabled).
                                //
                                long?minimumIterationCount = null;
                                long?maximumIterationCount = null;

                                //
                                // NOTE: Always start with the number of iterations
                                //       requested by the caller.  Also, record the
                                //       overall starting performance count now.
                                //
                                long actualIterations    = 0;
                                long remainingIterations = requestedIterations;
                                long startCount          = PerformanceOps.GetCount();

                                //
                                // NOTE: If the requested number of iterations is
                                //       exactly negative one, we will keep going
                                //       forever (i.e. until canceled).
                                //
                                try
                                {
                                    while (true)
                                    {
                                        if (remainingIterations == 0)
                                        {
                                            break;
                                        }

                                        long iterationStartCount = statistics ?
                                                                   PerformanceOps.GetCount() : 0;

                                        code = interpreter.EvaluateScript(arguments[1],
                                                                          ref result);

                                        if (statistics)
                                        {
                                            long iterationStopCount =
                                                PerformanceOps.GetCount();

                                            long iterationCount =
                                                iterationStopCount - iterationStartCount;

                                            if ((minimumIterationCount == null) ||
                                                (iterationCount < minimumIterationCount))
                                            {
                                                minimumIterationCount = iterationCount;
                                            }

                                            if ((maximumIterationCount == null) ||
                                                (iterationCount > maximumIterationCount))
                                            {
                                                maximumIterationCount = iterationCount;
                                            }
                                        }

                                        actualIterations++;

                                        if (code == ReturnCode.Continue)
                                        {
                                            continue;
                                        }

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

                                        if (remainingIterations == Count.Invalid)
                                        {
                                            continue;
                                        }

                                        if (--remainingIterations <= 0)
                                        {
                                            break;
                                        }
                                    }
                                }
                                finally
                                {
                                    if (noCancel)
                                    {
                                        /* IGNORED */
                                        Engine.ResetCancel(interpreter,
                                                           CancelFlags.Time);
                                    }

                                    if (noHalt)
                                    {
                                        /* IGNORED */
                                        Engine.ResetHalt(interpreter,
                                                         CancelFlags.Time);
                                    }

                                    if (noEvent)
                                    {
                                        /* IGNORED */
                                        interpreter.ClearEvents();
                                    }

                                    //
                                    // NOTE: If requested, prevent the interactive loop from
                                    //       actually exiting and reset the exit code to be
                                    //       "success".
                                    //
                                    if (noExit && interpreter.Exit)
                                    {
                                        interpreter.ExitCode = ResultOps.SuccessExitCode();
                                        interpreter.Exit     = false;
                                    }
                                }

                                //
                                // NOTE: Make sure the return code indicates "success".
                                //
                                if ((code == ReturnCode.Ok) || (code == ReturnCode.Break) ||
                                    (errorOk && (code == ReturnCode.Error)))
                                {
                                    //
                                    // NOTE: Record the overall ending performance count
                                    //       now.
                                    //
                                    long stopCount = PerformanceOps.GetCount();

                                    //
                                    // NOTE: Calculate the average number of microseconds
                                    //       per iteration based on the starting and ending
                                    //       performance counts and the effective number of
                                    //       iterations.
                                    //
                                    long resultIterations = PerformanceOps.GetIterations(
                                        requestedIterations, actualIterations, code, breakOk);

                                    double averageMicroseconds = (resultIterations != 0) ?
                                                                 PerformanceOps.GetMicroseconds(startCount, stopCount,
                                                                                                resultIterations) : 0;

                                    if (statistics)
                                    {
                                        result = FormatOps.PerformanceWithStatistics(
                                            requestedIterations, actualIterations,
                                            resultIterations, code,
                                            (code == ReturnCode.Error) ? result : null,
                                            startCount, stopCount, averageMicroseconds,
                                            PerformanceOps.GetMicroseconds(
                                                (minimumIterationCount != null) ?
                                                (long)minimumIterationCount : 0, 1),
                                            PerformanceOps.GetMicroseconds(
                                                (maximumIterationCount != null) ?
                                                (long)maximumIterationCount : 0, 1));
                                    }
                                    else
                                    {
                                        result = FormatOps.Performance(averageMicroseconds);
                                    }

                                    //
                                    // NOTE: If the "errorOk" option was used, make sure an
                                    //       "Error" return code gets translated to "Ok".
                                    //
                                    if (errorOk && (code == ReturnCode.Error))
                                    {
                                        Engine.ResetCancel(interpreter,
                                                           CancelFlags.Time);

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

            return(code);
        }
Example #25
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);
        }
Example #26
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

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

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    try
                    {
                        string  name     = null;
                        Variant operand1 = null;
                        Variant operand2 = null;

                        code = Value.GetOperandsFromArguments(interpreter,
                                                              this, arguments, ValueFlags.AnyVariant,
                                                              interpreter.CultureInfo, ref name,
                                                              ref operand1, ref operand2, ref error);

                        if (code == ReturnCode.Ok)
                        {
                            code = Value.FixupVariants(
                                this, operand1, operand2, null, null, false, false,
                                ref error);

                            if (code == ReturnCode.Ok)
                            {
                                if (operand1.IsWideInteger())
                                {
                                    value = ((long)operand1.Value ^ (long)operand2.Value);
                                }
                                else if (operand1.IsInteger())
                                {
                                    value = ((int)operand1.Value ^ (int)operand2.Value);
                                }
                                else if (operand1.IsBoolean())
                                {
                                    value = ((bool)operand1.Value ^ (bool)operand2.Value);
                                }
                                else
                                {
                                    error = String.Format(
                                        "unsupported operand type for operator {0}",
                                        FormatOps.OperatorName(name, this.Lexeme));

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

                        error = String.Format(
                            "caught math exception: {0}",
                            e);

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

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

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    try
                    {
                        string  name     = null;
                        Variant operand1 = null;
                        Variant operand2 = null;

                        code = Value.GetOperandsFromArguments(interpreter,
                                                              this, arguments, ValueFlags.AnyVariant,
                                                              interpreter.CultureInfo, ref name,
                                                              ref operand1, ref operand2, ref error);

                        if (code == ReturnCode.Ok)
                        {
                            //
                            // NOTE: Fine, try to treat the operands as strings.
                            //
                            code = Value.FixupStringVariants(
                                this, operand1, operand2, ref error);

                            if (code == ReturnCode.Ok)
                            {
                                if (operand1.IsString())
                                {
                                    string str1 = (string)operand1.Value;
                                    string str2 = (string)operand2.Value;
                                    value = (str1.StartsWith(str2));
                                }
                                else
                                {
                                    error = String.Format(
                                        "unsupported operand type for operator {0}",
                                        FormatOps.OperatorName(name, this.Lexeme));

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

                        error = String.Format(
                            "caught math exception: {0}",
                            e);

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

            return(code);
        }
Example #28
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

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

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    try
                    {
                        string  name     = null;
                        Variant operand1 = null;
                        Variant operand2 = null;

                        code = Value.GetOperandsFromArguments(interpreter,
                                                              this, arguments, ValueFlags.AnyVariant,
                                                              interpreter.CultureInfo, ref name,
                                                              ref operand1, ref operand2, ref error);

                        if (code == ReturnCode.Ok)
                        {
                            if (operand1 != null)
                            {
                                if (operand1.ConvertTo(typeof(bool)))
                                {
                                    if (operand1.IsBoolean())
                                    {
                                        value = LogicOps.Not((bool)operand1.Value);
                                    }
                                    else
                                    {
                                        error = String.Format(
                                            "unsupported operand type for operator {0}",
                                            FormatOps.OperatorName(name, this.Lexeme));

                                        code = ReturnCode.Error;
                                    }
                                }
                                else
                                {
                                    error = String.Format(
                                        "failed to convert operand to type \"{0}\"",
                                        typeof(bool));

                                    code = ReturnCode.Error;
                                }
                            }
                            else
                            {
                                error = String.Format(
                                    "operand for operator {0} is invalid",
                                    FormatOps.OperatorName(name, this.Lexeme));

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

                        error = String.Format(
                            "caught math exception: {0}",
                            e);

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

            return(code);
        }
Example #29
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

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

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    if (arguments.Count >= 2)
                    {
                        //
                        // NOTE: lambdaExpr must be a two element list {args body} or a three element
                        //       list {args body namespace}.
                        //
                        StringList lambdaExpr = null;

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

                        if (code == ReturnCode.Ok)
                        {
                            if ((lambdaExpr.Count == 2) || (lambdaExpr.Count == 3))
                            {
                                byte[] hashValue = arguments[1].GetHashValue(ref result);

                                if (hashValue != null)
                                {
                                    INamespace @namespace = null;

                                    if (lambdaExpr.Count == 3)
                                    {
                                        @namespace = NamespaceOps.Lookup(
                                            interpreter, lambdaExpr[2], true, false,
                                            ref result);

                                        if (@namespace == null)
                                        {
                                            code = ReturnCode.Error;
                                        }
                                    }

                                    if (code == ReturnCode.Ok)
                                    {
                                        //
                                        // NOTE: Parse the arguments into a list and make sure there are enough
                                        //       supplied to satisfy the request.
                                        //
                                        StringList list = null;

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

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

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

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

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

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

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

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

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

                                            if (code == ReturnCode.Ok)
                                            {
                                                //
                                                // NOTE: We *MUST* have the formal arguments in an actual ArgumentList
                                                //       container now.  The variadic and optional argument semantics
                                                //       depend on it.
                                                //
                                                ArgumentList formalArguments = new ArgumentList(
                                                    list2, ArgumentFlags.NameOnly);

                                                //
                                                // NOTE: Compare lambda argument count with the total outer argument
                                                //       count minus the "apply" and "lambdaExpr" arguments.
                                                //
                                                bool hasArgs      = formalArguments.IsVariadic(true);
                                                int  totalArgs    = hasArgs ? formalArguments.Count - 1 : formalArguments.Count;
                                                int  optionalArgs = formalArguments.GetOptionalCount();

                                                if ((((arguments.Count - 2) >= (totalArgs - optionalArgs)) &&
                                                     ((arguments.Count - 2) <= totalArgs)) ||
                                                    (hasArgs && ((arguments.Count - 2) >= (totalArgs - optionalArgs))))
                                                {
                                                    string     name  = NextName(interpreter, @namespace);
                                                    ICallFrame frame = null;

                                                    try
                                                    {
                                                        frame = interpreter.NewProcedureCallFrame(
                                                            name, CallFrameFlags.Procedure | CallFrameFlags.Lambda,
                                                            new ClientData(hashValue), this, arguments);

                                                        VariableDictionary variables = frame.Variables;

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

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

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

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

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

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

                                                                        argsArguments.Add(argsArgument);
                                                                    }

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

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

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

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

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

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

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

                                                                    code = interpreter.EvaluateScript(lambdaExpr[1], arguments[1], ref result);

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

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

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

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

                                                            frame = null;
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    result = String.Format(
                                                        "wrong # args: should be \"apply lambdaExpr {0}\"",
                                                        formalArguments.ToRawString(ToStringFlags.Decorated,
                                                                                    Characters.Space.ToString()));

                                                    code = ReturnCode.Error;
                                                }
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    code = ReturnCode.Error;
                                }
                            }
                            else
                            {
                                result = String.Format(
                                    "can't interpret \"{0}\" as a lambda expression",
                                    arguments[1]);

                                code = ReturnCode.Error;
                            }
                        }
                    }
                    else
                    {
                        result = "wrong # args: should be \"apply lambdaExpr ?arg1 arg2 ...?\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

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

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

                    int argumentIndex = Index.Invalid;

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

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

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

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

                            bool noCase = false;

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

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

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

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

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

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

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

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

                                            bool match = false;

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

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

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

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

                                            if (!match)
                                            {
                                                continue;
                                            }

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

                                                    goto switch_done;
                                                }

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

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

                                                    goto switch_done;
                                                }
                                            }
                                        }

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

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

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

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

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

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

            return(code);
        }