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

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

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

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

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

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

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

                                    IEventManager eventManager = interpreter.EventManager;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            return(code);
        }