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); }
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); }