/////////////////////////////////////////////////////////////////////// #region Private Methods private void AddRange( IClientData clientData, TraceFlags traceFlags, IPlugin plugin, IEnumerable <TraceCallback> collection ) { foreach (TraceCallback item in collection) { if (item != null) { Result error = null; ITrace trace = ScriptOps.NewCoreTrace( item, clientData, traceFlags, plugin, ref error); if (trace != null) { this.Add(trace); } else { DebugOps.Complain(ReturnCode.Error, error); } } } }
/////////////////////////////////////////////////////////////////////// #region IExecute Members public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { return(ScriptOps.EachLoopCommand( this, true, interpreter, clientData, arguments, ref result)); }
/////////////////////////////////////////////////////////////////////// internal StringList GetLocals( Interpreter interpreter, string pattern ) { if (pattern != null) { pattern = ScriptOps.MakeVariableName(pattern); } StringList result = new StringList(); foreach (KeyValuePair <string, IVariable> pair in this) { IVariable variable = pair.Value; if (variable == null) { continue; } if (EntityOps.IsUndefined(variable) || EntityOps.IsLink(variable)) { continue; } ICallFrame frame = CallFrameOps.FollowNext(variable.Frame); if (interpreter != null) { if (interpreter.IsGlobalCallFrame(frame)) { continue; } if (Interpreter.IsNamespaceCallFrame(frame)) { continue; } } string name = variable.Name; if ((pattern == null) || StringOps.Match( interpreter, StringOps.DefaultMatchMode, name, pattern, false)) { result.Add(name); } } return(result); }
public string SerializeCallStack() { var sb = new StringBuilder(); for (var i = 0; i < FrameCount; i++) { var frame = CallStack[i]; sb.AppendLine($" At Op:{ScriptOps.GetName(frame.OriginatingNode.OperationId)} consuming Op:{ScriptOps.GetName(frame.Current.OperationId)} and next of {frame.Next}"); } return(sb.ToString()); }
/////////////////////////////////////////////////////////////////////// private string GetOriginName( string aliasName ) { if (aliasName == null) { return(null); } Result result = null; if (NamespaceOps.Origin(interpreter, this, NamespaceOps.MakeAbsoluteName(aliasName), ref result) == ReturnCode.Ok) { return(ScriptOps.MakeCommandName(result)); } return(null); }
public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code; if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 2) { string subCommand = arguments[1]; bool tried = false; code = ScriptOps.TryExecuteSubCommandFromEnsemble( interpreter, this, clientData, arguments, true, false, ref subCommand, ref tried, ref result); if ((code == ReturnCode.Ok) && !tried) { // // NOTE: Programmatically interact with the debugger (breakpoint, watch, // eval, etc). // switch (subCommand) { case "clear": { if (arguments.Count == 2) { code = interpreter.ClearCallbackQueue(ref result); if (code == ReturnCode.Ok) { result = String.Empty; } } else { result = "wrong # args: should be \"callback clear\""; code = ReturnCode.Error; } break; } case "count": { if (arguments.Count == 2) { int count = 0; code = interpreter.CountCallbacks(ref count, ref result); if (code == ReturnCode.Ok) { result = count; } } else { result = "wrong # args: should be \"callback count\""; code = ReturnCode.Error; } break; } case "dequeue": { if (arguments.Count >= 2) { OptionDictionary options = ObjectOps.GetDequeueOptions(); int argumentIndex = Index.Invalid; if (arguments.Count > 2) { code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result); } else { code = ReturnCode.Ok; } if (code == ReturnCode.Ok) { if (argumentIndex == Index.Invalid) { Type returnType; ObjectFlags objectFlags; string objectName; string interpName; bool create; bool dispose; bool alias; bool aliasRaw; bool aliasAll; bool aliasReference; bool toString; ObjectOps.ProcessFixupReturnValueOptions( options, null, out returnType, out objectFlags, out objectName, out interpName, out create, out dispose, out alias, out aliasRaw, out aliasAll, out aliasReference, out toString); // // NOTE: Which Tcl interpreter do we want a command alias created // in, if any? // ICallback callback = null; code = interpreter.DequeueCallback(ref callback, ref result); if (code == ReturnCode.Ok) { ObjectOptionType objectOptionType = ObjectOptionType.Dequeue | ObjectOps.GetOptionType(aliasRaw, aliasAll); code = MarshalOps.FixupReturnValue( interpreter, interpreter.Binder, interpreter.CultureInfo, returnType, objectFlags, ObjectOps.GetInvokeOptions( objectOptionType), objectOptionType, objectName, interpName, callback, create, dispose, alias, aliasReference, toString, ref result); } } else { result = "wrong # args: should be \"callback dequeue ?options?\""; code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"callback dequeue ?options?\""; code = ReturnCode.Error; } break; } case "enqueue": { if (arguments.Count >= 3) { ICallback callback = CommandCallback.Create( MarshalFlags.Default, CallbackFlags.Default, ObjectFlags.Callback, ByRefArgumentFlags.None, interpreter, clientData, null, new StringList( arguments, 2), ref result); if (callback != null) { code = interpreter.EnqueueCallback(callback, ref result); if (code == ReturnCode.Ok) { result = String.Empty; } } else { code = ReturnCode.Error; } } else { result = "wrong # args: should be \"callback enqueue name ?arg ...?\""; code = ReturnCode.Error; } break; } case "execute": { if (arguments.Count == 2) { code = interpreter.ExecuteCallbackQueue(ref result); } else { result = "wrong # args: should be \"callback execute\""; code = ReturnCode.Error; } break; } case "list": { if ((arguments.Count == 2) || (arguments.Count == 3)) { string pattern = null; if (arguments.Count == 3) { pattern = arguments[2]; } StringList list = null; code = interpreter.ListCallbacks( pattern, false, ref list, ref result); if (code == ReturnCode.Ok) { result = list; } } else { result = "wrong # args: should be \"callback list ?pattern?\""; code = ReturnCode.Error; } break; } default: { result = ScriptOps.BadSubCommand( interpreter, null, null, subCommand, this, null, null); code = ReturnCode.Error; break; } } } } else { result = "wrong # args: should be \"callback option ?arg ...?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
/////////////////////////////////////////////////////////////////////// public static ReturnCode HandleBackgroundError( Interpreter interpreter, ReturnCode code, Result result, ref bool bgError ) { if (interpreter == null) { ReportBackgroundError(interpreter /* null */, null, "cannot handle background error, interpreter is " + "invalid.", "Original error", code, result, 0, null, ReturnCode.Ok, null, 0); return(ReturnCode.Error); } // // BUGFIX: Acquire the interpreter lock here; however, do not use // the public property just in case the interpreter may be // disposed at this point. // lock (interpreter.InternalSyncRoot) /* TRANSACTIONAL */ { // // BUGFIX: Do not try to handle any background errors with a // deleted or disposed interpreter. // if (Interpreter.IsDeletedOrDisposed(interpreter)) { ReportBackgroundError(interpreter /* disposed? */, null, "cannot handle background error, interpreter is " + "deleted or disposed.", "Original error", code, result, 0, null, ReturnCode.Ok, null, 0); return(ReturnCode.Error); } int errorLine = Interpreter.GetErrorLine(interpreter); string handlerName = interpreter.BackgroundError; // // NOTE: If there is an invalid background error handler set, // ignore the error. // if (!String.IsNullOrEmpty(handlerName)) { // // NOTE: Must hold lock while processing the error. // // TODO: Need to more carefully analyze this lock usage at // some point. // lock (interpreter.SyncRoot) /* TRANSACTIONAL */ { // // NOTE: Should a failure to handle the background // error simply be ignored? // bool ignoreFailure = ScriptOps.HasFlags(interpreter, InterpreterFlags.IgnoreBgErrorFailure, true); // // NOTE: We do not yet know if the background error // handler can actually be resolved. // bool haveBgError = false; // // NOTE: Construct a new argument list to pass along // to the actual error handler command, e.g. // "[list bgerror <message>]". // ArgumentList bgArguments = new ArgumentList( handlerName, result); // // NOTE: Attempt to lookup the background error // handler via the current command resolvers // for the interpreter. If this lookup fails // the default background error processing // will be used. // ReturnCode resolveCode; Result resolveError = null; IExecute bgExecute = null; resolveCode = interpreter.GetIExecuteViaResolvers( interpreter.GetResolveEngineFlags(true), handlerName, bgArguments, LookupFlags.Default, ref bgExecute, ref resolveError); if (resolveCode == ReturnCode.Ok) { // // NOTE: We found a background error handler. // haveBgError = true; // // NOTE: Execute the background error handler now // and save the results. // ReturnCode bgCode; Result bgResult = null; int bgErrorLine = 0; bgCode = ExecuteBackgroundError( interpreter, handlerName, bgExecute, null, bgArguments, ref bgResult, ref bgErrorLine); // // NOTE: Now we handle the return code for the // background error handler. // if (bgCode == ReturnCode.Break) { // // NOTE: A return code of "Break" indicates // that we should not call the background // error handler until the next time // ProcessEvents is invoked. // bgError = false; } else if (!ignoreFailure && (bgCode != ReturnCode.Ok)) { // // NOTE: Any other non-"Ok" return code is an // error an gets reported to the standard // error channel of the host, if any. // ReportBackgroundError(interpreter, handlerName, "handler {0} failed for background error.", "Original error", code, result, errorLine, "Handler error", bgCode, bgResult, bgErrorLine); } } // // NOTE: If there is no background error handler setup // just write the errorInfo to the error channel // (if possible). If failures should be ignored, // skip reporting the problem. // if (!ignoreFailure && !haveBgError) { ReportBackgroundError(interpreter, handlerName, "handler {0} missing for background error.", "Original error", code, result, errorLine, "Resolver error", resolveCode, resolveError, 0); } } } return(ReturnCode.Ok); } }
/////////////////////////////////////////////////////////////////////////////////////////////// #region IExecute Members public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 2) { string subCommand = arguments[1]; bool tried = false; code = ScriptOps.TryExecuteSubCommandFromEnsemble( interpreter, this, clientData, arguments, true, false, ref subCommand, ref tried, ref result); if ((code == ReturnCode.Ok) && !tried) { switch (subCommand) { case "forget": { if (arguments.Count >= 2) { code = interpreter.PkgForget( new StringList(arguments, 2), ref result); } else { result = "wrong # args: should be \"package forget ?package package ...?\""; code = ReturnCode.Error; } break; } case "ifneeded": { if ((arguments.Count == 4) || (arguments.Count == 5)) { Version version = null; code = Value.GetVersion( arguments[3], interpreter.CultureInfo, ref version, ref result); if (code == ReturnCode.Ok) { string text = null; if (arguments.Count == 5) { text = arguments[4]; } code = interpreter.PkgIfNeeded( arguments[2], version, text, interpreter.PackageFlags, ref result); } } else { result = "wrong # args: should be \"package ifneeded package version ?script?\""; code = ReturnCode.Error; } break; } case "indexes": { if ((arguments.Count == 2) || (arguments.Count == 3)) { string pattern = null; if (arguments.Count == 3) { pattern = arguments[2]; } code = interpreter.PkgIndexes( pattern, false, ref result); } else { result = "wrong # args: should be \"package indexes ?pattern?\""; code = ReturnCode.Error; } break; } case "info": { if (arguments.Count == 3) { IPackage package = null; code = interpreter.GetPackage( arguments[2], LookupFlags.Default, ref package, ref result); if (code == ReturnCode.Ok) { bool scrub = interpreter.IsSafe(); PackageFlags flags = package.Flags; Guid id = AttributeOps.GetObjectId(package); result = StringList.MakeList( "kind", package.Kind, "id", package.Id.Equals(Guid.Empty) ? id : package.Id, "name", package.Name, "description", package.Description, "indexFileName", scrub ? PathOps.ScrubPath( GlobalState.GetBasePath(), package.IndexFileName) : package.IndexFileName, "provideFileName", scrub ? PathOps.ScrubPath( GlobalState.GetBasePath(), package.ProvideFileName) : package.ProvideFileName, "flags", flags, "loaded", (package.Loaded != null) ? package.Loaded : null, "ifNeeded", (!scrub && (package.IfNeeded != null)) ? package.IfNeeded.KeysAndValuesToString(null, false) : null); } } else { result = "wrong # args: should be \"package info name\""; code = ReturnCode.Error; } break; } case "loaded": { if ((arguments.Count == 2) || (arguments.Count == 3)) { string pattern = null; if (arguments.Count == 3) { pattern = arguments[2]; } code = interpreter.PkgLoaded( pattern, false, false, ref result); } else { result = "wrong # args: should be \"package loaded ?pattern?\""; code = ReturnCode.Error; } break; } case "names": { if ((arguments.Count == 2) || (arguments.Count == 3)) { string pattern = null; if (arguments.Count == 3) { pattern = arguments[2]; } code = interpreter.PkgNames( pattern, false, ref result); } else { result = "wrong # args: should be \"package names ?pattern?\""; code = ReturnCode.Error; } break; } case "present": { if (arguments.Count >= 3) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-exact", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, false, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 2) >= arguments.Count)) { bool exact = false; if (options.IsPresent("-exact")) { exact = true; } Version version = null; if ((argumentIndex + 1) < arguments.Count) { code = Value.GetVersion( arguments[argumentIndex + 1], interpreter.CultureInfo, ref version, ref result); } if (code == ReturnCode.Ok) { code = interpreter.PresentPackage( arguments[argumentIndex], version, exact, ref result); } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"package present ?-exact? package ?version?\""; } code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"package present ?-exact? package ?version?\""; code = ReturnCode.Error; } break; } case "provide": { if ((arguments.Count == 3) || (arguments.Count == 4)) { PackageFlags flags = interpreter.PackageFlags; if (!FlagOps.HasFlags(flags, PackageFlags.NoProvide, true)) { Version version = null; if (arguments.Count == 4) { code = Value.GetVersion(arguments[3], interpreter.CultureInfo, ref version, ref result); } if (code == ReturnCode.Ok) { code = interpreter.PkgProvide(arguments[2], version, flags, ref result); } } else { // // HACK: Do nothing, provide no package, and return nothing. // result = String.Empty; code = ReturnCode.Ok; } } else { result = "wrong # args: should be \"package provide package ?version?\""; code = ReturnCode.Error; } break; } case "relativefilename": { if ((arguments.Count == 3) || (arguments.Count == 4)) { PathComparisonType pathComparisonType = PathComparisonType.Default; if (arguments.Count == 4) { object enumValue = EnumOps.TryParseFlagsEnum( interpreter, typeof(PathComparisonType), pathComparisonType.ToString(), arguments[3], interpreter.CultureInfo, true, true, true, ref result); if (enumValue is EventFlags) { pathComparisonType = (PathComparisonType)enumValue; } else { code = ReturnCode.Error; } } if (code == ReturnCode.Ok) { string fileName = null; code = PackageOps.GetRelativeFileName( interpreter, arguments[2], pathComparisonType, ref fileName, ref result); if (code == ReturnCode.Ok) { result = fileName; } } } else { result = "wrong # args: should be \"package relativefilename fileName ?type?\""; code = ReturnCode.Error; } break; } case "require": { if (arguments.Count >= 3) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-exact", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, false, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 2) >= arguments.Count)) { bool exact = false; if (options.IsPresent("-exact")) { exact = true; } Version version = null; if ((argumentIndex + 1) < arguments.Count) { code = Value.GetVersion( arguments[argumentIndex + 1], interpreter.CultureInfo, ref version, ref result); } if (code == ReturnCode.Ok) { code = interpreter.RequirePackage( arguments[argumentIndex], version, exact, ref result); } // // NOTE: This is a new feature. If the initial attempt to // require a package fails, call the package fallback // delegate for the interpreter and then try requiring // the package again. // if ((code != ReturnCode.Ok) && !ScriptOps.HasFlags( interpreter, InterpreterFlags.NoPackageFallback, true)) { PackageCallback packageFallback = interpreter.PackageFallback; if (packageFallback != null) { code = packageFallback( interpreter, arguments[argumentIndex], version, null, interpreter.PackageFlags, exact, ref result); if (code == ReturnCode.Ok) { code = interpreter.RequirePackage( arguments[argumentIndex], version, exact, ref result); } } } // // BUGFIX: This is really a new feature. In the event of a failure // here, we now fallback to the "unknown package handler", // just like Tcl does. // if ((code != ReturnCode.Ok) && !ScriptOps.HasFlags( interpreter, InterpreterFlags.NoPackageUnknown, true)) { string text = interpreter.PackageUnknown + Characters.Space + Parser.Quote(arguments[argumentIndex]); if (version != null) { text += Characters.Space + Parser.Quote(version.ToString()); } code = interpreter.EvaluateScript(text, ref result); /* EXEMPT */ if (code == ReturnCode.Ok) { code = interpreter.RequirePackage( arguments[argumentIndex], version, exact, ref result); } } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"package require ?-exact? package ?version?\""; } code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"package require ?-exact? package ?version?\""; code = ReturnCode.Error; } break; } case "reset": { if (arguments.Count == 2) { code = interpreter.ResetPkgIndexes(ref result); if (code == ReturnCode.Ok) { result = String.Empty; } } else { result = "wrong # args: should be \"package reset\""; code = ReturnCode.Error; } break; } case "scan": { if (arguments.Count >= 2) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-interpreter", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-preferfilesystem", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-preferhost", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-host", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-normal", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-nonormal", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-recursive", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-resolve", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-refresh", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-autopath", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; if (arguments.Count > 2) { code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result); } else { code = ReturnCode.Ok; } if (code == ReturnCode.Ok) { lock (interpreter.SyncRoot) /* TRANSACTIONAL */ { PackageIndexFlags flags; if (options.IsPresent("-interpreter")) { flags = interpreter.PackageIndexFlags; } else { flags = PackageIndexFlags.Default; } if (options.IsPresent("-preferfilesystem")) { flags |= PackageIndexFlags.PreferFileSystem; } if (options.IsPresent("-preferhost")) { flags |= PackageIndexFlags.PreferHost; } if (options.IsPresent("-host")) { flags |= PackageIndexFlags.Host; } if (options.IsPresent("-normal")) { flags |= PackageIndexFlags.Normal; } if (options.IsPresent("-nonormal")) { flags |= PackageIndexFlags.NoNormal; } if (options.IsPresent("-recursive")) { flags |= PackageIndexFlags.Recursive; } if (options.IsPresent("-refresh")) { flags |= PackageIndexFlags.Refresh; } if (options.IsPresent("-resolve")) { flags |= PackageIndexFlags.Resolve; } bool autoPath = false; if (options.IsPresent("-autopath")) { autoPath = true; } StringList paths; if (argumentIndex != Index.Invalid) { // // NOTE: Refresh the specified path list. // paths = new StringList(arguments, argumentIndex); } else { // // NOTE: Refresh the default path list. // paths = GlobalState.GetAutoPathList(interpreter, autoPath); // // NOTE: Did they request the auto-path be rebuilt? // if (autoPath) { // // NOTE: Since the actual auto-path may have changed, // update the variable now. We disable traces // here because we manually rescan, if necessary, // below. // code = interpreter.SetLibraryVariableValue( VariableFlags.SkipTrace, TclVars.AutoPath, (paths != null) ? paths.ToString() : null, ref result); } } if (code == ReturnCode.Ok) { PackageIndexDictionary packageIndexes = interpreter.CopyPackageIndexes(); if (code == ReturnCode.Ok) { code = PackageOps.FindAll( interpreter, paths, flags, ref packageIndexes, ref result); } if (code == ReturnCode.Ok) { interpreter.PackageIndexes = packageIndexes; result = String.Empty; } } } } } else { result = "wrong # args: should be \"package scan ?options? ?dir dir ...?\""; code = ReturnCode.Error; } break; } case "unknown": { if ((arguments.Count == 2) || (arguments.Count == 3)) { if (arguments.Count == 3) { interpreter.PackageUnknown = arguments[2]; result = String.Empty; } else { result = interpreter.PackageUnknown; } code = ReturnCode.Ok; } else { result = "wrong # args: should be \"package unknown ?command?\""; code = ReturnCode.Error; } break; } case "vcompare": { if (arguments.Count == 4) { Version version1 = null; code = Value.GetVersion( arguments[2], interpreter.CultureInfo, ref version1, ref result); Version version2 = null; if (code == ReturnCode.Ok) { code = Value.GetVersion( arguments[3], interpreter.CultureInfo, ref version2, ref result); } if (code == ReturnCode.Ok) { result = PackageOps.VersionCompare(version1, version2); } } else { result = "wrong # args: should be \"package vcompare version1 version2\""; code = ReturnCode.Error; } break; } case "versions": { if (arguments.Count == 3) { code = interpreter.PkgVersions( arguments[2], ref result); } else { result = "wrong # args: should be \"package versions package\""; code = ReturnCode.Error; } break; } case "vloaded": { if ((arguments.Count == 2) || (arguments.Count == 3)) { string pattern = null; if (arguments.Count == 3) { pattern = arguments[2]; } code = interpreter.PkgLoaded( pattern, false, true, ref result); } else { result = "wrong # args: should be \"package vloaded ?pattern?\""; code = ReturnCode.Error; } break; } case "vsatisfies": { if (arguments.Count == 4) { PackageFlags flags = interpreter.PackageFlags; if (!FlagOps.HasFlags(flags, PackageFlags.AlwaysSatisfy, true)) { Version version1 = null; code = Value.GetVersion(arguments[2], interpreter.CultureInfo, ref version1, ref result); Version version2 = null; if (code == ReturnCode.Ok) { code = Value.GetVersion( arguments[3], interpreter.CultureInfo, ref version2, ref result); } if (code == ReturnCode.Ok) { result = PackageOps.VersionSatisfies( version1, version2, false); } } else { // // HACK: Always fake that this was a satisfied package request. // result = true; code = ReturnCode.Ok; } } else { result = "wrong # args: should be \"package vsatisfies version1 version2\""; code = ReturnCode.Error; } break; } case "withdraw": { if ((arguments.Count == 3) || (arguments.Count == 4)) { Version version = null; if (arguments.Count == 4) { code = Value.GetVersion( arguments[3], interpreter.CultureInfo, ref version, ref result); } if (code == ReturnCode.Ok) { code = interpreter.WithdrawPackage( arguments[2], version, ref result); } } else { result = "wrong # args: should be \"package withdraw package ?version?\""; code = ReturnCode.Error; } break; } default: { result = ScriptOps.BadSubCommand( interpreter, null, null, subCommand, this, null, null); code = ReturnCode.Error; break; } } } } else { result = "wrong # args: should be \"package arg ?arg ...?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 2) { string subCommand = arguments[1]; bool tried = false; code = ScriptOps.TryExecuteSubCommandFromEnsemble( interpreter, this, clientData, arguments, true, false, ref subCommand, ref tried, ref result); if ((code == ReturnCode.Ok) && !tried) { switch (subCommand) { case "compare": { if (arguments.Count == 4) { Guid guid1 = Guid.Empty; code = Value.GetGuid(arguments[2], interpreter.CultureInfo, ref guid1, ref result); if (code == ReturnCode.Ok) { Guid guid2 = Guid.Empty; code = Value.GetGuid(arguments[3], interpreter.CultureInfo, ref guid2, ref result); if (code == ReturnCode.Ok) { result = guid1.CompareTo(guid2); } } } else { result = "wrong # args: should be \"guid compare guid1 guid2\""; code = ReturnCode.Error; } break; } case "isnull": { if (arguments.Count == 3) { Guid guid = Guid.Empty; code = Value.GetGuid(arguments[2], interpreter.CultureInfo, ref guid, ref result); if (code == ReturnCode.Ok) { result = ConversionOps.ToInt(guid.CompareTo(Guid.Empty) == 0); } } else { result = "wrong # args: should be \"guid isnull guid\""; code = ReturnCode.Error; } break; } case "isvalid": { if (arguments.Count == 3) { Guid guid = Guid.Empty; Result localResult = null; result = ConversionOps.ToInt(Value.GetGuid(arguments[2], interpreter.CultureInfo, ref guid, ref localResult) == ReturnCode.Ok); } else { result = "wrong # args: should be \"guid isvalid guid\""; code = ReturnCode.Error; } break; } case "new": { if (arguments.Count == 2) { result = Guid.NewGuid(); } else { result = "wrong # args: should be \"guid new\""; code = ReturnCode.Error; } break; } case "null": { if (arguments.Count == 2) { result = Guid.Empty; } else { result = "wrong # args: should be \"guid null\""; code = ReturnCode.Error; } break; } default: { result = ScriptOps.BadSubCommand( interpreter, null, null, subCommand, this, null, null); code = ReturnCode.Error; break; } } } } else { result = "wrong # args: should be \"guid option ?arg ...?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 2) { string subCommand = arguments[1]; bool tried = false; code = ScriptOps.TryExecuteSubCommandFromEnsemble( interpreter, this, clientData, arguments, true, false, ref subCommand, ref tried, ref result); if ((code == ReturnCode.Ok) && !tried) { switch (subCommand) { case "deserialize": { if (arguments.Count >= 4) { #if SERIALIZATION OptionDictionary options = ObjectOps.GetDeserializeOptions(); int argumentIndex = Index.Invalid; code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 2) == arguments.Count)) { bool verbose; bool strictType; bool noCase; ObjectOps.ProcessGetTypeOptions( options, out verbose, out strictType, out noCase); Type returnType; ObjectFlags objectFlags; string objectName; string interpName; bool create; bool dispose; bool alias; bool aliasRaw; bool aliasAll; bool aliasReference; bool toString; ObjectOps.ProcessFixupReturnValueOptions( options, null, out returnType, out objectFlags, out objectName, out interpName, out create, out dispose, out alias, out aliasRaw, out aliasAll, out aliasReference, out toString); if (noCase) { objectFlags |= ObjectFlags.NoCase; } Variant value = null; Encoding encoding = null; if (options.IsPresent("-encoding", ref value)) { encoding = (Encoding)value.Value; } if (code == ReturnCode.Ok) { Type objectType = null; ResultList errors = null; code = Value.GetType(interpreter, arguments[argumentIndex], null, interpreter.GetAppDomain(), Value.GetTypeValueFlags(strictType, verbose, noCase), interpreter.CultureInfo, ref objectType, ref errors); if (code == ReturnCode.Ok) { byte[] bytes = null; code = StringOps.GetBytes( encoding, arguments[argumentIndex + 1], EncodingType.Default, ref bytes, ref result); if (code == ReturnCode.Ok) { object @object = null; code = XmlOps.Deserialize( objectType, bytes, ref @object, ref result); if (code == ReturnCode.Ok) { ObjectOptionType objectOptionType = ObjectOptionType.Deserialize | ObjectOps.GetOptionType(aliasRaw, aliasAll); code = MarshalOps.FixupReturnValue( interpreter, interpreter.Binder, interpreter.CultureInfo, returnType, objectFlags, ObjectOps.GetInvokeOptions( objectOptionType), objectOptionType, objectName, interpName, @object, create, dispose, alias, aliasReference, toString, ref result); } } } else { errors.Insert(0, String.Format( "type \"{0}\" not found", arguments[argumentIndex])); result = errors; } } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"xml deserialize ?options? type xml\""; } code = ReturnCode.Error; } } #else result = "not implemented"; code = ReturnCode.Error; #endif } else { result = "wrong # args: should be \"xml deserialize ?options? type xml\""; code = ReturnCode.Error; } break; } case "serialize": { if (arguments.Count >= 4) { #if SERIALIZATION OptionDictionary options = ObjectOps.GetSerializeOptions(); int argumentIndex = Index.Invalid; code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 2) == arguments.Count)) { bool noCase = false; if (options.IsPresent("-nocase")) { noCase = true; } bool strictType = false; if (options.IsPresent("-stricttype")) { strictType = true; } bool verbose = false; if (options.IsPresent("-verbose")) { verbose = true; } Variant value = null; Encoding encoding = null; if (options.IsPresent("-encoding", ref value)) { encoding = (Encoding)value.Value; } if (code == ReturnCode.Ok) { Type objectType = null; ResultList errors = null; code = Value.GetType(interpreter, arguments[argumentIndex], null, interpreter.GetAppDomain(), Value.GetTypeValueFlags(strictType, verbose, noCase), interpreter.CultureInfo, ref objectType, ref errors); if (code == ReturnCode.Ok) { IObject @object = null; code = interpreter.GetObject( arguments[argumentIndex + 1], LookupFlags.Default, ref @object, ref result); if (code == ReturnCode.Ok) { byte[] bytes = null; code = XmlOps.Serialize( (@object != null) ? @object.Value : null, objectType, null, ref bytes, ref result); if (code == ReturnCode.Ok) { string stringValue = null; code = StringOps.GetString( encoding, bytes, EncodingType.Default, ref stringValue, ref result); if (code == ReturnCode.Ok) { result = stringValue; } } } } else { errors.Insert(0, String.Format( "type \"{0}\" not found", arguments[argumentIndex])); result = errors; } } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"xml serialize ?options? type object\""; } code = ReturnCode.Error; } } #else result = "not implemented"; code = ReturnCode.Error; #endif } else { result = "wrong # args: should be \"xml serialize ?options? type object\""; code = ReturnCode.Error; } break; } case "validate": { if (arguments.Count == 4) { XmlDocument document = null; code = XmlOps.LoadString( arguments[3], ref document, ref result); if (code == ReturnCode.Ok) { code = XmlOps.Validate( arguments[2], document, ref result); if (code == ReturnCode.Ok) { result = String.Empty; } } } else { result = "wrong # args: should be \"xml validate schemaXml documentXml\""; code = ReturnCode.Error; } break; } default: { result = ScriptOps.BadSubCommand( interpreter, null, null, subCommand, this, null, null); code = ReturnCode.Error; break; } } } } else { result = "wrong # args: should be \"xml option ?arg ...?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
/////////////////////////////////////////////////////////////////////// #region IExecute Members public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { if (interpreter == null) { result = "invalid interpreter"; return(ReturnCode.Error); } if (arguments == null) { result = "invalid argument list"; return(ReturnCode.Error); } if (arguments.Count < 2) { result = "wrong # args: should be \"global varName ?varName ...?\""; return(ReturnCode.Error); } ICallFrame localFrame = null; if (interpreter.GetVariableFrameViaResolvers( LookupFlags.Default, ref localFrame, ref result) == ReturnCode.Ok) { if ((localFrame != null) && !interpreter.IsGlobalCallFrame(localFrame)) { bool useNamespaces = interpreter.AreNamespacesEnabled(); for (int argumentIndex = 1; argumentIndex < arguments.Count; argumentIndex++) { string varName = arguments[argumentIndex]; ICallFrame otherFrame = interpreter.CurrentGlobalFrame; if (useNamespaces) { string qualifiers = null; string tail = null; NamespaceFlags namespaceFlags = NamespaceFlags.None; if (NamespaceOps.SplitName( varName, ref qualifiers, ref tail, ref namespaceFlags, ref result) == ReturnCode.Ok) { // // NOTE: For linking between call frames, use // the simple variable name only. // varName = tail; } else { return(ReturnCode.Error); } if (FlagOps.HasFlags(namespaceFlags, NamespaceFlags.Qualified, true)) { INamespace @namespace = NamespaceOps.Lookup( interpreter, qualifiers, false, false, ref result); if (@namespace != null) { otherFrame = @namespace.VariableFrame; } else { return(ReturnCode.Error); } } } if (ScriptOps.LinkVariable( interpreter, localFrame, varName, otherFrame, varName, ref result) != ReturnCode.Ok) { return(ReturnCode.Error); } } result = String.Empty; } else { // already in global scope... this is a NOP. result = String.Empty; } return(ReturnCode.Ok); } else { return(ReturnCode.Error); } }
/////////////////////////////////////////////////////////////////////// #region IExecute Members public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code; // // NOTE: *WARNING* We do NOT actually support namespaces. This // command exists for the sole purpose of improving source // code compatibility with simple stand alone scripts that // may simply wrap themselves in a "namespace eval" block, // etc. Any other (more involved) use may not work at all // or may cause undesired and/or unpredictable results. // if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 2) { string subCommand = arguments[1]; bool tried = false; code = ScriptOps.TryExecuteSubCommandFromEnsemble( interpreter, this, clientData, arguments, true, false, ref subCommand, ref tried, ref result); if ((code == ReturnCode.Ok) && !tried) { switch (subCommand) { case "children": { if ((arguments.Count >= 2) && (arguments.Count <= 4)) { string name = null; if (arguments.Count >= 3) { name = arguments[2]; } if ((arguments.Count < 3) || NamespaceOps.IsGlobalName(name)) { result = String.Empty; code = ReturnCode.Ok; } else { if (NamespaceOps.IsAbsoluteName(name)) { result = String.Format("namespace \"{0}\" not found", name); } else { result = String.Format("namespace \"{0}\" not found in \"{1}\"", name, TclVars.GlobalNamespace); } code = ReturnCode.Error; } } else { result = "wrong # args: should be \"namespace children ?name? ?pattern?\""; code = ReturnCode.Error; } break; } case "code": { if (arguments.Count == 3) { // // NOTE: We are always in the global namespace, fake it. // result = new StringList( TclVars.GlobalNamespace + this.Name, "inscope", TclVars.GlobalNamespace, arguments[2]); code = ReturnCode.Ok; } else { result = "wrong # args: should be \"namespace code script\""; code = ReturnCode.Error; } break; } case "current": { if (arguments.Count == 2) { result = TclVars.GlobalNamespace; code = ReturnCode.Ok; } else { result = "wrong # args: should be \"namespace current\""; code = ReturnCode.Error; } break; } case "delete": { if (arguments.Count >= 2) { code = ReturnCode.Ok; for (int index = 2; index < arguments.Count; index++) { if (!NamespaceOps.IsGlobalName(arguments[index])) { // // NOTE: We only know about the global namespace; an attempt // to delete any other namespace is an error. // result = String.Format( "unknown namespace \"{0}\" in namespace delete command", arguments[index]); code = ReturnCode.Error; break; } } if (code == ReturnCode.Ok) { for (int index = 2; index < arguments.Count; /* index++ */) { // // NOTE: Delete the one-and-only namespace (global) now (actually, // as soon as the evaluation stack unwinds). // code = interpreter.DeleteNamespace( VariableFlags.None, arguments[index], false, ref result); // // NOTE: Since we only know about the global namespace there // is no point in attempting to delete it multiple times. // break; } } if (code == ReturnCode.Ok) { result = String.Empty; } } else { result = "wrong # args: should be \"namespace delete ?name name ...?\""; code = ReturnCode.Error; } break; } case "enable": { if ((arguments.Count >= 2) && (arguments.Count <= 4)) { if (arguments.Count >= 3) { bool enabled = false; code = Value.GetBoolean2( arguments[2], ValueFlags.AnyBoolean, interpreter.CultureInfo, ref enabled, ref result); bool force = false; if ((code == ReturnCode.Ok) && (arguments.Count >= 4)) { code = Value.GetBoolean2( arguments[3], ValueFlags.AnyBoolean, interpreter.CultureInfo, ref force, ref result); } if (code == ReturnCode.Ok) { code = NamespaceOps.Enable( interpreter, enabled, force, ref result); } } if (code == ReturnCode.Ok) { result = interpreter.AreNamespacesEnabled(); } } else { result = "wrong # args: should be \"namespace enable ?enabled? ?force?\""; code = ReturnCode.Error; } break; } case "eval": { if (arguments.Count >= 4) { string name = StringList.MakeList("namespace eval", arguments[2]); ICallFrame frame = interpreter.NewTrackingCallFrame(name, CallFrameFlags.Namespace | CallFrameFlags.Evaluate); interpreter.PushAutomaticCallFrame(frame); if (arguments.Count == 4) { code = interpreter.EvaluateScript(arguments[3], ref result); } else { code = interpreter.EvaluateScript(arguments, 3, ref result); } if (code == ReturnCode.Error) { Engine.AddErrorInformation(interpreter, result, String.Format("{0} (in namespace eval \"{1}\" script line {2})", Environment.NewLine, arguments[2], Interpreter.GetErrorLine(interpreter))); } // // NOTE: Pop the original call frame that we pushed above and // any intervening scope call frames that may be leftover // (i.e. they were not explicitly closed). // /* IGNORED */ interpreter.PopScopeCallFramesAndOneMore(); } else { result = "wrong # args: should be \"namespace eval name arg ?arg ...?\""; code = ReturnCode.Error; } break; } case "exists": { if (arguments.Count == 3) { if (NamespaceOps.IsGlobalName(arguments[2])) { result = true; } else { result = false; } code = ReturnCode.Ok; } else { result = "wrong # args: should be \"namespace exists name\""; code = ReturnCode.Error; } break; } case "export": { if (arguments.Count >= 2) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-clear", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; if (arguments.Count > 2) { code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, false, ref argumentIndex, ref result); } else { code = ReturnCode.Ok; } // // NOTE: We do not support importing or exporting of namespace commands // because we do not really support namespaces; therefore, we do // nothing. // if (code == ReturnCode.Ok) { result = String.Empty; } } else { result = "wrong # args: should be \"namespace export ?-clear? ?pattern pattern ...?\""; code = ReturnCode.Error; } break; } case "forget": { if (arguments.Count >= 2) { // // NOTE: We do not support importing or exporting of namespace commands // because we do not really support namespaces; therefore, we do // nothing. // result = String.Empty; code = ReturnCode.Ok; } else { result = "wrong # args: should be \"namespace forget ?pattern pattern ...?\""; code = ReturnCode.Error; } break; } case "import": { if (arguments.Count >= 2) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-force", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; if (arguments.Count > 2) { code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, false, ref argumentIndex, ref result); } else { code = ReturnCode.Ok; } // // NOTE: We do not support importing or exporting of namespace commands // because we do not really support namespaces; therefore, we do // nothing. // if (code == ReturnCode.Ok) { result = String.Empty; } } else { result = "wrong # args: should be \"namespace import ?-force? ?pattern pattern ...?\""; code = ReturnCode.Error; } break; } case "info": { if (arguments.Count == 3) { code = NamespaceOps.InfoSubCommand( interpreter, arguments[2], ref result); } else { result = "wrong # args: should be \"namespace info name\""; code = ReturnCode.Error; } break; } case "inscope": { if (arguments.Count >= 4) { if (NamespaceOps.IsGlobalName(arguments[2])) { if (arguments.Count > 4) { IScriptLocation location = null; #if DEBUGGER && BREAKPOINTS code = ScriptOps.GetLocation( interpreter, arguments, 3, ref location, ref result); if (code == ReturnCode.Ok) #endif { string name = StringList.MakeList("namespace inscope", arguments[2]); ICallFrame frame = interpreter.NewTrackingCallFrame(name, CallFrameFlags.Namespace | CallFrameFlags.InScope); interpreter.PushAutomaticCallFrame(frame); StringList list = new StringList(arguments, 4); code = interpreter.EvaluateScript( ListOps.Concat(arguments[3], list.ToString()), location, ref result); if (code == ReturnCode.Error) { Engine.AddErrorInformation(interpreter, result, String.Format("{0} (in namespace inscope \"{1}\" script line {2})", Environment.NewLine, arguments[2], Interpreter.GetErrorLine(interpreter))); } // // NOTE: Pop the original call frame that we pushed above and // any intervening scope call frames that may be leftover // (i.e. they were not explicitly closed). // /* IGNORED */ interpreter.PopScopeCallFramesAndOneMore(); } } else { string name = StringList.MakeList("namespace inscope", arguments[2]); ICallFrame frame = interpreter.NewTrackingCallFrame(name, CallFrameFlags.Namespace | CallFrameFlags.InScope); interpreter.PushAutomaticCallFrame(frame); code = interpreter.EvaluateScript(arguments[3], ref result); if (code == ReturnCode.Error) { Engine.AddErrorInformation(interpreter, result, String.Format("{0} (in namespace inscope \"{1}\" script line {2})", Environment.NewLine, arguments[2], Interpreter.GetErrorLine(interpreter))); } // // NOTE: Pop the original call frame that we pushed above and // any intervening scope call frames that may be leftover // (i.e. they were not explicitly closed). // /* IGNORED */ interpreter.PopScopeCallFramesAndOneMore(); } } else { result = String.Format( "unknown namespace \"{0}\" in inscope namespace command", arguments[2]); code = ReturnCode.Error; } } else { result = "wrong # args: should be \"namespace inscope name arg ?arg...?\""; code = ReturnCode.Error; } break; } case "mappings": { if (arguments.Count == 2) { lock (interpreter.SyncRoot) /* TRANSACTIONAL */ { StringDictionary namespaceMappings = interpreter.NamespaceMappings; if (namespaceMappings != null) { result = namespaceMappings.KeysAndValuesToString(null, false); code = ReturnCode.Ok; } else { result = "namespace mappings not available"; code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"namespace mappings\""; code = ReturnCode.Error; } break; } case "name": { if (arguments.Count == 3) { // // NOTE: We are always in the global namespace, fake it. // string name = arguments[2]; if (!NamespaceOps.IsQualifiedName(name)) { result = NamespaceOps.MakeAbsoluteName(name); code = ReturnCode.Ok; } else { result = "only non-qualified names are allowed"; code = ReturnCode.Error; } } else { result = "wrong # args: should be \"namespace name name\""; code = ReturnCode.Error; } break; } case "origin": { if (arguments.Count == 3) { string executeName = arguments[2]; IExecute execute = null; code = interpreter.GetIExecuteViaResolvers( interpreter.GetResolveEngineFlags(true), executeName, null, LookupFlags.Default, ref execute, ref result); if (code == ReturnCode.Ok) { result = TclVars.GlobalNamespace + executeName; } } else { result = "wrong # args: should be \"namespace origin name\""; code = ReturnCode.Error; } break; } case "parent": { if ((arguments.Count == 2) || (arguments.Count == 3)) { // // NOTE: Either they did not specify a namespace argument (use current // namespace, which is always global and always exists) or they // specified a namespace which should be the global one; otherwise, // an error is reported because we do not really support namespaces. // if ((arguments.Count == 2) || NamespaceOps.IsGlobalName(arguments[2])) { result = String.Empty; code = ReturnCode.Ok; } else { // // NOTE: See if they prefixed the argument with "::" to figure out // the appropriate error message (Tcl emulation). // if (NamespaceOps.IsAbsoluteName(arguments[2])) { result = String.Format("namespace \"{0}\" not found", arguments[2]); } else { result = String.Format("namespace \"{0}\" not found in \"{1}\"", arguments[2], TclVars.GlobalNamespace); } code = ReturnCode.Error; } } else { result = "wrong # args: should be \"namespace parent ?name?\""; code = ReturnCode.Error; } break; } case "qualifiers": { if (arguments.Count == 3) { string qualifiers = null; string tail = null; code = NamespaceOps.SplitName( arguments[2], ref qualifiers, ref tail, ref result); if (code == ReturnCode.Ok) { result = qualifiers; } } else { result = "wrong # args: should be \"namespace qualifiers string\""; code = ReturnCode.Error; } break; } case "rename": { if (arguments.Count == 4) { result = "not implemented"; code = ReturnCode.Error; } else { result = "wrong # args: should be \"namespace rename oldName newName\""; code = ReturnCode.Error; } break; } case "tail": { if (arguments.Count == 3) { string qualifiers = null; string tail = null; code = NamespaceOps.SplitName( arguments[2], ref qualifiers, ref tail, ref result); if (code == ReturnCode.Ok) { result = tail; } } else { result = "wrong # args: should be \"namespace tail string\""; code = ReturnCode.Error; } break; } case "unknown": { // // NOTE: The string is currently used as the name of the command // or procedure to execute when an unknown command is // encountered by the engine. // if ((arguments.Count == 2) || (arguments.Count == 3)) { if (arguments.Count == 3) { string unknown = StringOps.NullIfEmpty(arguments[2]); if (String.IsNullOrEmpty(unknown)) { interpreter.NamespaceUnknown = interpreter.GlobalUnknown; } else { interpreter.NamespaceUnknown = unknown; } result = unknown; } else { result = interpreter.NamespaceUnknown; } code = ReturnCode.Ok; } else { result = "wrong # args: should be \"namespace unknown ?script?\""; code = ReturnCode.Error; } break; } case "which": { // // TODO: *FIXME* Only the global namespace is supported here. // if (arguments.Count >= 2) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-command", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-variable", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; if (arguments.Count > 2) { code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, OptionBehaviorFlags.LastIsNonOption, false, ref argumentIndex, ref result); } else { code = ReturnCode.Ok; } if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 1) == arguments.Count)) { string name = arguments[argumentIndex]; bool isCommand = false; if (options.IsPresent("-command")) { isCommand = true; } bool isVariable = false; if (options.IsPresent("-variable")) { isVariable = true; } if (!isCommand || !isVariable) { if (!isCommand && !isVariable) { isCommand = true; } if (isCommand) { IExecute execute = null; code = interpreter.GetIExecuteViaResolvers( interpreter.GetResolveEngineFlags(true), name, null, LookupFlags.Default, ref execute, ref result); if (code == ReturnCode.Ok) { result = TclVars.GlobalNamespace + ScriptOps.MakeCommandName(name); } else { result = String.Empty; code = ReturnCode.Ok; } } else { VariableFlags flags = VariableFlags.NamespaceWhichMask; IVariable variable = null; code = interpreter.GetVariableViaResolversWithSplit( name, ref flags, ref variable, ref result); if (code == ReturnCode.Ok) { result = TclVars.GlobalNamespace + ScriptOps.MakeVariableName(name); } else { result = String.Empty; code = ReturnCode.Ok; } } } else { result = "wrong # args: should be \"namespace which ?-command? ?-variable? name\""; /* COMPAT: Tcl */ code = ReturnCode.Error; } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"namespace which ?-command? ?-variable? name\""; } code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"namespace which ?-command? ?-variable? name\""; code = ReturnCode.Error; } break; } default: { result = ScriptOps.BadSubCommand( interpreter, null, null, subCommand, this, null, null); code = ReturnCode.Error; break; } } } } else { result = "wrong # args: should be \"namespace subcommand ?arg ...?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
/////////////////////////////////////////////////////////////////////// #region IExecute Members public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { if (interpreter == null) { result = "invalid interpreter"; return(ReturnCode.Error); } if (arguments == null) { result = "invalid argument list"; return(ReturnCode.Error); } if (arguments.Count < 2) { result = "wrong # args: should be \"hash option ?arg ...?\""; return(ReturnCode.Error); } ReturnCode code; string subCommand = arguments[1]; bool tried = false; code = ScriptOps.TryExecuteSubCommandFromEnsemble( interpreter, this, clientData, arguments, true, false, ref subCommand, ref tried, ref result); if ((code != ReturnCode.Ok) || tried) { return(code); } // // NOTE: These algorithms are known to be supported by the // framework. // // Normal: MD5, RIPEMD160, SHA, SHA1, SHA256, SHA384, SHA512 // // Keyed: MACTripleDES // // HMAC: HMACMD5, HMACRIPEMD160, HMACSHA1, HMACSHA256, // HMACSHA384, HMACSHA512 // switch (subCommand) { case "keyed": { if (arguments.Count >= 4) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-raw", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-filename", null), /* COMPAT: Tcllib. */ new Option(null, OptionFlags.MustHaveEncodingValue, Index.Invalid, Index.Invalid, "-encoding", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; code = interpreter.GetOptions( options, arguments, 0, 2, Index.Invalid, false, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 2) <= arguments.Count) && ((argumentIndex + 3) >= arguments.Count)) { Variant value = null; bool raw = false; if (options.IsPresent("-raw")) { raw = true; } bool isFileName = false; if (options.IsPresent("-filename", ref value)) { isFileName = true; } Encoding encoding = null; if (options.IsPresent("-encoding", ref value)) { encoding = (Encoding)value.Value; } if (code == ReturnCode.Ok) { try { using (KeyedHashAlgorithm algorithm = KeyedHashAlgorithm.Create( arguments[argumentIndex])) { if (algorithm != null) { algorithm.Initialize(); if ((argumentIndex + 3) == arguments.Count) { byte[] bytes = null; code = StringOps.GetBytes( encoding, arguments[argumentIndex + 2], EncodingType.Binary, ref bytes, ref result); if (code == ReturnCode.Ok) { algorithm.Key = bytes; } } if (code == ReturnCode.Ok) { if (isFileName) { Stream stream = null; try { code = RuntimeOps.NewStream( interpreter, arguments[argumentIndex + 1], FileMode.Open, FileAccess.Read, ref stream, ref result); if (code == ReturnCode.Ok) { if (raw) { result = new ByteList( algorithm.ComputeHash(stream)); } else { result = FormatOps.Hash( algorithm.ComputeHash(stream)); } } } finally { if (stream != null) { stream.Close(); stream = null; } } } else { byte[] bytes = null; code = StringOps.GetBytes( encoding, arguments[argumentIndex + 1], EncodingType.Binary, ref bytes, ref result); if (raw) { result = new ByteList( algorithm.ComputeHash(bytes)); } else { result = FormatOps.Hash( algorithm.ComputeHash(bytes)); } } } } else { result = String.Format( "unsupported keyed hash algorithm \"{0}\"", arguments[argumentIndex]); code = ReturnCode.Error; } } } catch (Exception e) { Engine.SetExceptionErrorCode(interpreter, e); result = e; code = ReturnCode.Error; } } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption( options, arguments[argumentIndex]); } else { result = String.Format( "wrong # args: should be \"{0} {1} ?options? algorithm string ?key?\"", this.Name, subCommand); } code = ReturnCode.Error; } } } else { result = String.Format( "wrong # args: should be \"{0} {1} ?options? algorithm string ?key?\"", this.Name, subCommand); code = ReturnCode.Error; } break; } case "list": { if ((arguments.Count == 2) || (arguments.Count == 3)) { string type = null; if (arguments.Count == 3) { type = arguments[2]; } switch (type) { case null: case "all": { StringList list = new StringList(); lock (syncRoot) { if (defaultAlgorithms != null) { list.AddRange(defaultAlgorithms); } } if (keyedHashAlgorithmNames != null) { foreach (string hashAlgorithmName in keyedHashAlgorithmNames) { list.Add(StringList.MakeList("keyed", hashAlgorithmName)); } } if (macHashAlgorithmNames != null) { foreach (string hashAlgorithmName in macHashAlgorithmNames) { list.Add(StringList.MakeList("mac", hashAlgorithmName)); } } if (normalHashAlgorithmNames != null) { foreach (string hashAlgorithmName in normalHashAlgorithmNames) { list.Add(StringList.MakeList("normal", hashAlgorithmName)); } } result = list; break; } case "default": { lock (syncRoot) { result = (defaultAlgorithms != null) ? new StringList(defaultAlgorithms) : null; } break; } case "keyed": { result = (keyedHashAlgorithmNames != null) ? new StringList(keyedHashAlgorithmNames) : null; break; } case "mac": { result = (macHashAlgorithmNames != null) ? new StringList(macHashAlgorithmNames) : null; break; } case "normal": { result = (normalHashAlgorithmNames != null) ? new StringList(normalHashAlgorithmNames) : null; break; } default: { result = "unknown algorithm list, must be: all, default, keyed, mac, or normal"; code = ReturnCode.Error; break; } } } else { result = String.Format( "wrong # args: should be \"{0} {1} ?type?\"", this.Name, subCommand); code = ReturnCode.Error; } break; } case "mac": { if (arguments.Count >= 4) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-raw", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-filename", null), /* COMPAT: Tcllib. */ new Option(null, OptionFlags.MustHaveEncodingValue, Index.Invalid, Index.Invalid, "-encoding", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; code = interpreter.GetOptions( options, arguments, 0, 2, Index.Invalid, false, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 2) <= arguments.Count) && ((argumentIndex + 3) >= arguments.Count)) { Variant value = null; bool raw = false; if (options.IsPresent("-raw")) { raw = true; } bool isFileName = false; if (options.IsPresent("-filename", ref value)) { isFileName = true; } Encoding encoding = null; if (options.IsPresent("-encoding", ref value)) { encoding = (Encoding)value.Value; } if (code == ReturnCode.Ok) { try { using (HMAC algorithm = HMAC.Create( arguments[argumentIndex])) { if (algorithm != null) { algorithm.Initialize(); if ((argumentIndex + 3) == arguments.Count) { byte[] bytes = null; code = StringOps.GetBytes( encoding, arguments[argumentIndex + 2], EncodingType.Binary, ref bytes, ref result); if (code == ReturnCode.Ok) { algorithm.Key = bytes; } } if (code == ReturnCode.Ok) { if (isFileName) { Stream stream = null; try { code = RuntimeOps.NewStream( interpreter, arguments[argumentIndex + 1], FileMode.Open, FileAccess.Read, ref stream, ref result); if (code == ReturnCode.Ok) { if (raw) { result = new ByteList( algorithm.ComputeHash(stream)); } else { result = FormatOps.Hash( algorithm.ComputeHash(stream)); } } } finally { if (stream != null) { stream.Close(); stream = null; } } } else { byte[] bytes = null; code = StringOps.GetBytes( encoding, arguments[argumentIndex + 1], EncodingType.Binary, ref bytes, ref result); if (raw) { result = new ByteList( algorithm.ComputeHash(bytes)); } else { result = FormatOps.Hash( algorithm.ComputeHash(bytes)); } } } } else { result = String.Format( "unsupported hmac algorithm \"{0}\"", arguments[argumentIndex]); code = ReturnCode.Error; } } } catch (Exception e) { Engine.SetExceptionErrorCode(interpreter, e); result = e; code = ReturnCode.Error; } } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption( options, arguments[argumentIndex]); } else { result = String.Format( "wrong # args: should be \"{0} {1} ?options? algorithm string ?key?\"", this.Name, subCommand); } code = ReturnCode.Error; } } } else { result = String.Format( "wrong # args: should be \"{0} {1} ?options? algorithm string ?key?\"", this.Name, subCommand); code = ReturnCode.Error; } break; } case "normal": { if (arguments.Count >= 4) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-raw", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-filename", null), /* COMPAT: Tcllib. */ new Option(null, OptionFlags.MustHaveEncodingValue, Index.Invalid, Index.Invalid, "-encoding", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; code = interpreter.GetOptions( options, arguments, 0, 2, Index.Invalid, false, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 2) == arguments.Count)) { Variant value = null; bool raw = false; if (options.IsPresent("-raw")) { raw = true; } bool isFileName = false; if (options.IsPresent("-filename", ref value)) { isFileName = true; } Encoding encoding = null; if (options.IsPresent("-encoding", ref value)) { encoding = (Encoding)value.Value; } if (code == ReturnCode.Ok) { try { using (HashAlgorithm algorithm = HashAlgorithm.Create( arguments[argumentIndex])) { if (algorithm != null) { algorithm.Initialize(); if (isFileName) { Stream stream = null; try { code = RuntimeOps.NewStream( interpreter, arguments[argumentIndex + 1], FileMode.Open, FileAccess.Read, ref stream, ref result); if (code == ReturnCode.Ok) { if (raw) { result = new ByteList( algorithm.ComputeHash(stream)); } else { result = FormatOps.Hash( algorithm.ComputeHash(stream)); } } } finally { if (stream != null) { stream.Close(); stream = null; } } } else { byte[] bytes = null; code = StringOps.GetBytes( encoding, arguments[argumentIndex + 1], EncodingType.Binary, ref bytes, ref result); if (code == ReturnCode.Ok) { if (raw) { result = new ByteList( algorithm.ComputeHash(bytes)); } else { result = FormatOps.Hash( algorithm.ComputeHash(bytes)); } } } } else { result = String.Format( "unsupported hash algorithm \"{0}\"", arguments[argumentIndex]); code = ReturnCode.Error; } } } catch (Exception e) { Engine.SetExceptionErrorCode(interpreter, e); result = e; code = ReturnCode.Error; } } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption( options, arguments[argumentIndex]); } else { result = String.Format( "wrong # args: should be \"{0} {1} ?options? algorithm string\"", this.Name, subCommand); } code = ReturnCode.Error; } } } else { result = String.Format( "wrong # args: should be \"{0} {1} ?options? algorithm string\"", this.Name, subCommand); code = ReturnCode.Error; } break; } default: { result = ScriptOps.BadSubCommand( interpreter, null, null, subCommand, this, null, null); code = ReturnCode.Error; break; } } return(code); }
public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 4) { StringList list = null; // // WARNING: Cannot cache list representation here, the list // is modified below. // code = Parser.SplitList( interpreter, arguments[1], 0, Length.Invalid, false, ref list, ref result); if (code == ReturnCode.Ok) { int firstIndex = Index.Invalid; code = Value.GetIndex( arguments[2], list.Count, ValueFlags.AnyIndex, interpreter.CultureInfo, ref firstIndex, ref result); if (code == ReturnCode.Ok) { int lastIndex = Index.Invalid; code = Value.GetIndex( arguments[3], list.Count, ValueFlags.AnyIndex, interpreter.CultureInfo, ref lastIndex, ref result); if (code == ReturnCode.Ok) { if (firstIndex < 0) { firstIndex = 0; } if ((firstIndex < list.Count) || (list.Count == 0)) { if (list.Count > 0) { if (lastIndex >= list.Count) { lastIndex = list.Count - 1; } int numToDelete; if (firstIndex <= lastIndex) { numToDelete = (lastIndex - firstIndex + 1); } else { numToDelete = 0; } list.RemoveRange(firstIndex, numToDelete); if (arguments.Count >= 5) { list.InsertRange(firstIndex, arguments, 4); } result = list; } else if (ScriptOps.HasFlags(interpreter, InterpreterFlags.ReplaceEmptyListOk, true)) { result = list; } else { result = String.Format( "list doesn't contain element {0}", arguments[2]); code = ReturnCode.Error; } } else { result = String.Format( "list doesn't contain element {0}", arguments[2]); code = ReturnCode.Error; } } } } } else { result = "wrong # args: should be \"lreplace list first last ?value ...?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
/////////////////////////////////////////////////////////////////////// #region IExecute Members public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { if (interpreter == null) { result = "invalid interpreter"; return(ReturnCode.Error); } if (arguments == null) { result = "invalid argument list"; return(ReturnCode.Error); } if (arguments.Count < 2) { result = String.Format( "wrong # args: should be \"{0} option ?arg ...?\"", this.Name); return(ReturnCode.Error); } string subCommand = arguments[1]; if (!String.Equals( subCommand, this.Name, StringOps.SystemStringComparisonType)) { result = ScriptOps.BadSubCommand( interpreter, null, null, subCommand, this, null, null); return(ReturnCode.Error); } // // NOTE: Evaluate the configured script command, maybe // adding all the local arguments, and return the // results verbatim. // string name = StringList.MakeList(this.Name); ICallFrame frame = interpreter.NewTrackingCallFrame(name, CallFrameFlags.Evaluate | CallFrameFlags.SubCommand); interpreter.PushAutomaticCallFrame(frame); ReturnCode code = interpreter.EvaluateScript( ScriptOps.GetArgumentsForExecute(this, scriptCommand, GetArgumentsForExecute(arguments), 0), 0, ref result); if (code == ReturnCode.Error) { Engine.AddErrorInformation(interpreter, result, String.Format("{0} (\"{1}\" body line {2})", Environment.NewLine, ScriptOps.GetNameForExecute( arguments[0], this), Interpreter.GetErrorLine( interpreter))); } // // NOTE: Pop the original call frame that we pushed above and // any intervening scope call frames that may be leftover // (i.e. they were not explicitly closed). // /* IGNORED */ interpreter.PopScopeCallFramesAndOneMore(); return(code); }
/////////////////////////////////////////////////////////////////////// #region INotify Members public override ReturnCode Notify( Interpreter interpreter, IScriptEventArgs eventArgs, IClientData clientData, ArgumentList arguments, ref Result result ) { if (eventArgs == null) { return(ReturnCode.Ok); } if (!FlagOps.HasFlags( eventArgs.NotifyTypes, NotifyType.CallFrame, false)) { return(ReturnCode.Ok); } NotifyFlags notifyFlags = eventArgs.NotifyFlags; if (!FlagOps.HasFlags(notifyFlags, NotifyFlags.Popped | NotifyFlags.Deleted, false)) { return(ReturnCode.Ok); } IClientData eventClientData = eventArgs.ClientData; if (eventClientData == null) { return(ReturnCode.Ok); } ICallFrame newFrame = eventClientData.Data as ICallFrame; if (newFrame == null) { return(ReturnCode.Ok); } // // NOTE: Make sure the variables in this frame actually BELONG // to this frame. Also, we do not handle the global call // frame. // if (!FlagOps.HasFlags(notifyFlags, NotifyFlags.Force, true) && !CallFrameOps.IsNonGlobalVariable(newFrame)) { return(ReturnCode.Ok); } // // NOTE: If this is a [scope] created call frame, we do NOT want // to change any reference counts unless the call frame is // being deleted, not simply popped. // if (!FlagOps.HasFlags(notifyFlags, NotifyFlags.Deleted, true) && CallFrameOps.IsScope(newFrame)) { return(ReturnCode.Ok); } // // NOTE: Grab the variables for this call frame. If there are // none, we are done. // VariableDictionary variables = newFrame.Variables; if (variables == null) { return(ReturnCode.Ok); } // // NOTE: Process each variable in the call frame to adjust all // all the reference counts. After this point, we need // the interpreter context for the event. // Interpreter eventInterpreter = eventArgs.Interpreter; if (eventInterpreter == null) { return(ReturnCode.Ok); } foreach (KeyValuePair <string, IVariable> pair in variables) { // // NOTE: Grab the variable and make sure the variable it is // valid. // IVariable variable = pair.Value; if (variable == null) { continue; } // // NOTE: For unset operations, ObjectTraceCallback uses only // the "traceInfo.Variable" and "traceInfo.oldValue" // members of the ITraceInfo object instance. If the // number of trace and/or watch levels exceeds one, // force creation of a new TraceInfo object here; // otherwise, we may interfere with the setting of an // unrelated variable value. // ITraceInfo traceInfo = ScriptOps.NewTraceInfo( interpreter, null, BreakpointType.BeforeVariableUnset, newFrame, variable, pair.Key, null, VariableFlags.None, variable.Value, null, null, null, null, interpreter.NeedNewTraceInfo(VariableFlags.None), false, !EntityOps.IsNoPostProcess(variable), ReturnCode.Ok); // // HACK: Manually invoke the Interpreter.ObjectTraceCallback // static (trace callback) method, in order to handle // contained object reference(s), if any. After this // method returns, the entire call frame will be going // away, along with any object references contained // within it. // ReturnCode code = Interpreter.ObjectTraceCallback( traceInfo.BreakpointType, eventInterpreter, traceInfo, ref result); if (code != ReturnCode.Ok) { return(code); } } return(ReturnCode.Ok); }
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); }
/////////////////////////////////////////////////////////////////////// public ReturnCode RenameImport( string oldQualifiedName, string newQualifiedName, bool strict, ref Result error ) { CheckDisposed(); if (imports == null) { error = String.Format( "imports not available in namespace \"{0}\"", GetDisplayName()); return(ReturnCode.Error); } INamespace oldNamespace = NamespaceOps.LookupParent( interpreter, oldQualifiedName, false, true, false, ref error); if (oldNamespace == null) { return(ReturnCode.Error); } INamespace newNamespace = NamespaceOps.LookupParent( interpreter, newQualifiedName, false, true, false, ref error); if (newNamespace == null) { return(ReturnCode.Error); } int count = 0; ObjectDictionary localImports = new ObjectDictionary( (IDictionary <string, object>)imports); foreach (KeyValuePair <string, object> pair in localImports) { IAlias alias = pair.Value as IAlias; if (alias == null) { continue; } string aliasName = NamespaceOps.GetAliasName(alias); if (NamespaceOps.IsSame( alias.TargetNamespace, oldNamespace) && StringOps.Match(interpreter, MatchMode.Glob, aliasName, ScriptOps.MakeCommandName(oldQualifiedName), false)) { alias.TargetNamespace = newNamespace; NamespaceOps.SetAliasName(alias, newQualifiedName); return(ReturnCode.Ok); } else if (strict) { error = String.Format( "import \"{0}\" is not an alias in namespace \"{1}\"", oldQualifiedName, GetDisplayName()); return(ReturnCode.Error); } } if (strict && (count == 0)) { error = String.Format( "no imports matched name \"{0}\" in namespace \"{1}\"", oldQualifiedName, GetDisplayName()); return(ReturnCode.Error); } return(ReturnCode.Ok); }
/////////////////////////////////////////////////////////////////////// #region IExecute Members public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 2) { string subCommand = arguments[1]; bool tried = false; code = ScriptOps.TryExecuteSubCommandFromEnsemble( interpreter, this, clientData, arguments, true, false, ref subCommand, ref tried, ref result); if ((code == ReturnCode.Ok) && !tried) { if (code == ReturnCode.Ok) { switch (subCommand) { case "command": { if (arguments.Count >= 3) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(typeof(EngineFlags), OptionFlags.MustHaveEnumValue | OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-engineflags", new Variant(interpreter.EngineFlags)), new Option(typeof(SubstitutionFlags), OptionFlags.MustHaveEnumValue, Index.Invalid, Index.Invalid, "-substitutionflags", new Variant(interpreter.SubstitutionFlags)), new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-startindex", null), new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-characters", null), new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-nested", null), new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-noready", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; code = interpreter.GetOptions( options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 1) == arguments.Count)) { Variant value = null; EngineFlags engineFlags = interpreter.EngineFlags; if (options.IsPresent("-engineflags", ref value)) { engineFlags = (EngineFlags)value.Value; } SubstitutionFlags substitutionFlags = interpreter.SubstitutionFlags; if (options.IsPresent("-substitutionflags", ref value)) { substitutionFlags = (SubstitutionFlags)value.Value; } int startIndex = 0; if (options.IsPresent("-startindex", ref value)) { startIndex = (int)value.Value; } int characters = arguments[argumentIndex].Length; if (options.IsPresent("-characters", ref value)) { characters = (int)value.Value; } bool nested = false; if (options.IsPresent("-nested", ref value)) { nested = (bool)value.Value; } bool noReady = false; if (options.IsPresent("-noready", ref value)) { noReady = (bool)value.Value; } IParseState state = new ParseState( engineFlags, substitutionFlags); code = Parser.ParseCommand( interpreter, arguments[argumentIndex], startIndex, characters, nested, state, noReady, ref result); if (code == ReturnCode.Ok) { // // NOTE: Success, return the entire // state as a string. // result = state.ToString(); } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"parse command ?options? text\""; } code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"parse command ?options? text\""; code = ReturnCode.Error; } break; } case "expression": { if (arguments.Count >= 3) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(typeof(EngineFlags), OptionFlags.MustHaveEnumValue | OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-engineflags", new Variant(interpreter.EngineFlags)), new Option(typeof(SubstitutionFlags), OptionFlags.MustHaveEnumValue, Index.Invalid, Index.Invalid, "-substitutionflags", new Variant(interpreter.SubstitutionFlags)), new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-startindex", null), new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-characters", null), new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-noready", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; code = interpreter.GetOptions( options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 1) == arguments.Count)) { Variant value = null; EngineFlags engineFlags = interpreter.EngineFlags; if (options.IsPresent("-engineflags", ref value)) { engineFlags = (EngineFlags)value.Value; } SubstitutionFlags substitutionFlags = interpreter.SubstitutionFlags; if (options.IsPresent("-substitutionflags", ref value)) { substitutionFlags = (SubstitutionFlags)value.Value; } int startIndex = 0; if (options.IsPresent("-startindex", ref value)) { startIndex = (int)value.Value; } int characters = arguments[argumentIndex].Length; if (options.IsPresent("-characters", ref value)) { characters = (int)value.Value; } bool noReady = false; if (options.IsPresent("-noready", ref value)) { noReady = (bool)value.Value; } IParseState state = new ParseState( engineFlags, substitutionFlags); code = ExpressionParser.ParseExpression( interpreter, arguments[argumentIndex], startIndex, characters, state, noReady, ref result); if (code == ReturnCode.Ok) { // // NOTE: Success, return the entire // state as a string. // result = state.ToString(); } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"parse expression ?options? text\""; } code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"parse expression ?options? text\""; code = ReturnCode.Error; } break; } case "options": { if (arguments.Count >= 4) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(typeof(OptionBehaviorFlags), OptionFlags.MustHaveEnumValue, Index.Invalid, Index.Invalid, "-flags", new Variant(OptionBehaviorFlags.Default)), new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-optionsvar", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-indexes", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-allowinteger", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-strict", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-verbose", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-nocase", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-novalue", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-noset", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-noready", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-simple", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; code = interpreter.GetOptions( options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 2) == arguments.Count)) { Variant value = null; string optionsVarName = Vars.OptionSet.Options; if (options.IsPresent("-optionsvar", ref value)) { optionsVarName = value.ToString(); } OptionBehaviorFlags flags = OptionBehaviorFlags.Default; if (options.IsPresent("-flags", ref value)) { flags = (OptionBehaviorFlags)value.Value; } bool indexes = false; if (options.IsPresent("-indexes")) { indexes = true; } bool allowInteger = false; if (options.IsPresent("-allowinteger")) { allowInteger = true; } bool strict = false; if (options.IsPresent("-strict")) { strict = true; } bool verbose = false; if (options.IsPresent("-verbose")) { verbose = true; } bool noCase = false; if (options.IsPresent("-nocase")) { noCase = true; } bool noValue = false; if (options.IsPresent("-novalue")) { noValue = true; } bool noSet = false; if (options.IsPresent("-noset")) { noSet = true; } bool noReady = false; if (options.IsPresent("-noready")) { noReady = true; } bool simple = false; if (options.IsPresent("-simple")) { simple = true; } OptionDictionary newOptions = null; AppDomain appDomain = interpreter.GetAppDomain(); CultureInfo cultureInfo = interpreter.CultureInfo; if (simple) { newOptions = OptionDictionary.FromString( interpreter, arguments[argumentIndex], appDomain, Value.GetTypeValueFlags( allowInteger, strict, verbose, noCase), cultureInfo, ref result); } else { newOptions = OptionDictionary.FromString( interpreter, arguments[argumentIndex], appDomain, allowInteger, strict, verbose, noCase, cultureInfo, ref result); } if (newOptions != null) { StringList list = StringList.FromString( arguments[argumentIndex + 1], ref result); if (list != null) { ArgumentList newArguments = new ArgumentList(list); int nextIndex = Index.Invalid; int endIndex = Index.Invalid; code = interpreter.GetOptions( newOptions, newArguments, 0, 0, Index.Invalid, flags, noCase, noValue, noSet, ref nextIndex, ref endIndex, ref result); if (code == ReturnCode.Ok) { VariableFlags variableFlags = VariableFlags.None; if (noReady) { variableFlags |= VariableFlags.NoReady; } if (indexes) { code = interpreter.SetVariableValue2( variableFlags, optionsVarName, Vars.OptionSet.NextIndex, nextIndex.ToString(), null, ref result); if (code == ReturnCode.Ok) { code = interpreter.SetVariableValue2( variableFlags, optionsVarName, Vars.OptionSet.EndIndex, endIndex.ToString(), null, ref result); } } if (code == ReturnCode.Ok) { foreach (KeyValuePair <string, IOption> pair in newOptions) { IOption option = pair.Value; if (option == null) { continue; } if (option.IsIgnored(newOptions)) { continue; } /* REUSED */ value = null; bool present = option.IsPresent(newOptions, ref value); if (present && !option.CanBePresent(newOptions, ref result)) { code = ReturnCode.Error; break; } code = interpreter.SetVariableValue2( variableFlags, optionsVarName, pair.Key, present.ToString(), null, ref result); if (code != ReturnCode.Ok) { break; } if (option.MustHaveValue(newOptions)) { // // NOTE: If the option was not actually present, // grab and use the default value instead. // if (!present) { value = option.Value; } // // NOTE: Only set the value if the option was // actually present OR there is a bonafide // default value. // if (present || (value != null)) { string index = pair.Key + Characters.Comma + Vars.OptionSet.Value; code = interpreter.SetVariableValue2( variableFlags, optionsVarName, index, (value != null) ? value.ToString() : null, null, ref result); if (code != ReturnCode.Ok) { break; } } } } if (code == ReturnCode.Ok) { result = String.Empty; } } } } else { code = ReturnCode.Error; } } else { code = ReturnCode.Error; } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"parse options ?options? optionList argumentList\""; } code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"parse options ?options? options optionList argumentList\""; code = ReturnCode.Error; } break; } case "script": { if (arguments.Count >= 3) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(typeof(EngineFlags), OptionFlags.MustHaveEnumValue | OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-engineflags", new Variant(interpreter.EngineFlags)), new Option(typeof(SubstitutionFlags), OptionFlags.MustHaveEnumValue, Index.Invalid, Index.Invalid, "-substitutionflags", new Variant(interpreter.SubstitutionFlags)), new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-filename", null), new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-currentline", null), new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-startindex", null), new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-characters", null), new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-nested", null), new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-syntax", null), new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-strict", null), new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-roundtrip", null), new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-noready", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; code = interpreter.GetOptions( options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 1) == arguments.Count)) { Variant value = null; EngineFlags engineFlags = interpreter.EngineFlags; if (options.IsPresent("-engineflags", ref value)) { engineFlags = (EngineFlags)value.Value; } SubstitutionFlags substitutionFlags = interpreter.SubstitutionFlags; if (options.IsPresent("-substitutionflags", ref value)) { substitutionFlags = (SubstitutionFlags)value.Value; } string fileName = null; if (options.IsPresent("-filename", ref value)) { fileName = value.ToString(); } int currentLine = Parser.StartLine; if (options.IsPresent("-currentline", ref value)) { currentLine = (int)value.Value; } int startIndex = 0; if (options.IsPresent("-startindex", ref value)) { startIndex = (int)value.Value; } int characters = arguments[argumentIndex].Length; if (options.IsPresent("-characters", ref value)) { characters = (int)value.Value; } bool nested = false; if (options.IsPresent("-nested", ref value)) { nested = (bool)value.Value; } bool syntax = false; if (options.IsPresent("-syntax", ref value)) { syntax = (bool)value.Value; } bool strict = false; if (options.IsPresent("-strict", ref value)) { strict = (bool)value.Value; } bool roundTrip = false; if (options.IsPresent("-roundtrip", ref value)) { roundTrip = (bool)value.Value; } bool noReady = false; if (options.IsPresent("-noready", ref value)) { noReady = (bool)value.Value; } IParseState state = new ParseState( engineFlags, substitutionFlags); TokenList tokens = null; code = Parser.ParseScript( interpreter, fileName, currentLine, arguments[argumentIndex], startIndex, characters, engineFlags, substitutionFlags, nested, noReady, syntax, strict, ref state, ref tokens, ref result); if (code == ReturnCode.Ok) { if (roundTrip) { // // NOTE: Return only the tokens that // are absolutely necessary to // rebuild the script text. // TokenList newTokens = new TokenList(); for (int index = 0; index < tokens.Count; index++) { IToken token = tokens[index]; if (token.Type == TokenType.Variable) { index += token.Components; } else if ((token.Type != TokenType.Separator) && (token.Components != 0)) { continue; } newTokens.Add(token); } result = newTokens.ToString(); } else { // // NOTE: Replace final token list // with the one we have been // building. // state.Tokens = tokens; // // NOTE: Success, return the entire // state as a string. // result = state.ToString(); } } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"parse script ?options? text\""; } code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"parse script ?options? text\""; code = ReturnCode.Error; } break; } default: { result = ScriptOps.BadSubCommand( interpreter, null, null, subCommand, this, null, null); code = ReturnCode.Error; break; } } } } } else { result = "wrong # args: should be \"parse type ?arg ...?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
/////////////////////////////////////////////////////////////////////// public ReturnCode RemoveImports( string qualifiedPattern, bool strict, ref Result error ) { CheckDisposed(); if (imports == null) { error = String.Format( "imports not available in namespace \"{0}\"", GetDisplayName()); return(ReturnCode.Error); } INamespace patternNamespace = null; if ((qualifiedPattern != null) && (interpreter != null)) { patternNamespace = NamespaceOps.LookupParent( interpreter, qualifiedPattern, false, true, false, ref error); if (patternNamespace == null) { return(ReturnCode.Error); } } int count = 0; ObjectDictionary localImports = new ObjectDictionary( (IDictionary <string, object>)imports); foreach (KeyValuePair <string, object> pair in localImports) { IAlias alias = pair.Value as IAlias; string aliasName = NamespaceOps.GetAliasName(alias); string originName = GetOriginName(aliasName); if ((qualifiedPattern == null) || StringOps.Match(interpreter, MatchMode.Glob, aliasName, ScriptOps.MakeCommandName(qualifiedPattern), false) || ((originName != null) && StringOps.Match(interpreter, MatchMode.Glob, originName, ScriptOps.MakeCommandName(qualifiedPattern), false))) { INamespace originNamespace = null; if (originName != null) { originNamespace = NamespaceOps.LookupParent( interpreter, originName, false, true, false, ref error); if (originNamespace == null) { return(ReturnCode.Error); } } if ((patternNamespace == null) || ((alias != null) && (NamespaceOps.IsSame( alias.TargetNamespace, patternNamespace) || NamespaceOps.IsSame( originNamespace, patternNamespace)))) { if ((alias != null) && (interpreter != null)) { string nameToken = alias.NameToken; if ((nameToken != null) && interpreter.RemoveAliasAndCommand( alias.NameToken, null, false, ref error) != ReturnCode.Ok) { return(ReturnCode.Error); } } count += imports.Remove(pair.Key) ? 1 : 0; } } } if (strict && (count == 0)) { error = String.Format( "no imports matched pattern \"{0}\" in namespace \"{1}\"", qualifiedPattern, GetDisplayName()); return(ReturnCode.Error); } return(ReturnCode.Ok); }
/////////////////////////////////////////////////////////////////////// #region IExecute Members public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code; // // NOTE: *WARNING* We do NOT actually support namespaces. This // command exists for the sole purpose of improving source // code compatibility with simple stand alone scripts that // may simply wrap themselves in a "namespace eval" block, // etc. Any other (more involved) use may not work at all // or may cause undesired and/or unpredictable results. // if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 2) { string subCommand = arguments[1]; bool tried = false; code = ScriptOps.TryExecuteSubCommandFromEnsemble( interpreter, this, clientData, arguments, true, false, ref subCommand, ref tried, ref result); if ((code == ReturnCode.Ok) && !tried) { switch (subCommand) { case "children": { if ((arguments.Count >= 2) && (arguments.Count <= 4)) { string name = null; if (arguments.Count >= 3) { name = arguments[2]; } string pattern = null; if (arguments.Count >= 4) { pattern = arguments[3]; } IEnumerable <INamespace> children = NamespaceOps.Children( interpreter, name, pattern, false, ref result); if (children != null) { StringList list = new StringList(); foreach (INamespace child in children) { list.Add(child.QualifiedName); } result = list; } else { code = ReturnCode.Error; } } else { result = "wrong # args: should be \"namespace children ?name? ?pattern?\""; code = ReturnCode.Error; } break; } case "code": { if (arguments.Count == 3) { string text = arguments[2]; if (!NamespaceOps.IsSubCommand(interpreter, text, "inscope")) { INamespace currentNamespace = null; code = interpreter.GetCurrentNamespaceViaResolvers( null, LookupFlags.Default, ref currentNamespace, ref result); if (code == ReturnCode.Ok) { StringList list = new StringList(); list.Add(NamespaceOps.MakeAbsoluteName( this.Name)); list.Add("inscope"); list.Add(NamespaceOps.MakeAbsoluteName( currentNamespace.QualifiedName)); list.Add(text); result = list; } } else { result = text; /* COMPAT: Tcl. */ } } else { result = "wrong # args: should be \"namespace code script\""; code = ReturnCode.Error; } break; } case "current": { if (arguments.Count == 2) { INamespace currentNamespace = null; code = interpreter.GetCurrentNamespaceViaResolvers( null, LookupFlags.Default, ref currentNamespace, ref result); if (code == ReturnCode.Ok) { if (currentNamespace != null) { result = currentNamespace.QualifiedName; } else { result = "current namespace is invalid"; code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"namespace current\""; code = ReturnCode.Error; } break; } case "delete": { if (arguments.Count >= 2) { for (int index = 2; index < arguments.Count; index++) { code = interpreter.DeleteNamespace( VariableFlags.None, arguments[index], false, ref result); if (code != ReturnCode.Ok) { break; } } if (code == ReturnCode.Ok) { result = String.Empty; } } else { result = "wrong # args: should be \"namespace delete ?name name ...?\""; code = ReturnCode.Error; } break; } case "enable": { if ((arguments.Count >= 2) && (arguments.Count <= 4)) { if (arguments.Count >= 3) { bool enabled = false; code = Value.GetBoolean2( arguments[2], ValueFlags.AnyBoolean, interpreter.CultureInfo, ref enabled, ref result); bool force = false; if ((code == ReturnCode.Ok) && (arguments.Count >= 4)) { code = Value.GetBoolean2( arguments[3], ValueFlags.AnyBoolean, interpreter.CultureInfo, ref force, ref result); } if (code == ReturnCode.Ok) { code = NamespaceOps.Enable( interpreter, enabled, force, ref result); } } if (code == ReturnCode.Ok) { result = interpreter.AreNamespacesEnabled(); } } else { result = "wrong # args: should be \"namespace enable ?enabled? ?force?\""; code = ReturnCode.Error; } break; } case "eval": { if (arguments.Count >= 4) { string namespaceName = NamespaceOps.MapName( interpreter, arguments[2]); INamespace @namespace = NamespaceOps.Lookup( interpreter, namespaceName, false, true, ref result); if (@namespace != null) { string name = StringList.MakeList("namespace eval", @namespace.QualifiedName); ICallFrame frame = interpreter.NewNamespaceCallFrame( name, CallFrameFlags.Evaluate | CallFrameFlags.UseNamespace, arguments, @namespace, false); interpreter.PushNamespaceCallFrame(frame); if (arguments.Count == 4) { code = interpreter.EvaluateScript(arguments[3], ref result); } else { code = interpreter.EvaluateScript(arguments, 3, ref result); } if (code == ReturnCode.Error) { Engine.AddErrorInformation(interpreter, result, String.Format("{0} (in namespace eval \"{1}\" script line {2})", Environment.NewLine, NamespaceOps.MaybeQualifiedName(@namespace, true), Interpreter.GetErrorLine(interpreter))); } /* IGNORED */ interpreter.PopNamespaceCallFrame(frame); /* NO RESULT */ Engine.CleanupNamespacesOrComplain(interpreter); } else { code = ReturnCode.Error; } } else { result = "wrong # args: should be \"namespace eval name arg ?arg ...?\""; code = ReturnCode.Error; } break; } case "exists": { if (arguments.Count == 3) { result = ConversionOps.ToInt(NamespaceOps.Lookup( interpreter, arguments[2], false, false) != null); } else { result = "wrong # args: should be \"namespace exists name\""; code = ReturnCode.Error; } break; } case "export": { if (arguments.Count >= 2) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-clear", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; if (arguments.Count > 2) { code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, false, ref argumentIndex, ref result); } else { code = ReturnCode.Ok; } if (code == ReturnCode.Ok) { bool clear = false; if (options.IsPresent("-clear")) { clear = true; } StringList patterns = new StringList(); if (argumentIndex != Index.Invalid) { patterns.AddObjects(ArgumentList.GetRange(arguments, argumentIndex)); } code = NamespaceOps.Export(interpreter, null, patterns, clear, ref result); } } else { result = "wrong # args: should be \"namespace export ?-clear? ?pattern pattern ...?\""; code = ReturnCode.Error; } break; } case "forget": { if (arguments.Count >= 2) { if (arguments.Count >= 3) { code = NamespaceOps.Forget(interpreter, new StringList(ArgumentList.GetRange(arguments, 2)), ref result); if (code == ReturnCode.Ok) { result = String.Empty; } } else { result = String.Empty; code = ReturnCode.Ok; } } else { result = "wrong # args: should be \"namespace forget ?pattern pattern ...?\""; code = ReturnCode.Error; } break; } case "import": { if (arguments.Count >= 2) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-force", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; if (arguments.Count > 2) { code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, false, ref argumentIndex, ref result); } else { code = ReturnCode.Ok; } if (code == ReturnCode.Ok) { bool force = false; if (options.IsPresent("-force")) { force = true; } StringList patterns = new StringList(); if (argumentIndex != Index.Invalid) { patterns.AddObjects(ArgumentList.GetRange(arguments, argumentIndex)); } code = NamespaceOps.Import(interpreter, patterns, force, ref result); } } else { result = "wrong # args: should be \"namespace import ?-force? ?pattern pattern ...?\""; code = ReturnCode.Error; } break; } case "info": { if (arguments.Count == 3) { code = NamespaceOps.InfoSubCommand( interpreter, arguments[2], ref result); } else { result = "wrong # args: should be \"namespace info name\""; code = ReturnCode.Error; } break; } case "inscope": { if (arguments.Count >= 4) { string namespaceName = NamespaceOps.MapName( interpreter, arguments[2]); INamespace @namespace = NamespaceOps.Lookup( interpreter, namespaceName, false, false, ref result); if (@namespace != null) { if (arguments.Count > 4) { IScriptLocation location = null; #if DEBUGGER && BREAKPOINTS code = ScriptOps.GetLocation( interpreter, arguments, 3, ref location, ref result); if (code == ReturnCode.Ok) #endif { string name = StringList.MakeList("namespace inscope", @namespace.QualifiedName); ICallFrame frame = interpreter.NewNamespaceCallFrame( name, CallFrameFlags.InScope | CallFrameFlags.UseNamespace, arguments, @namespace, false); interpreter.PushNamespaceCallFrame(frame); StringList list = new StringList(arguments, 4); code = interpreter.EvaluateScript( ListOps.Concat(arguments[3], list.ToString()), location, ref result); if (code == ReturnCode.Error) { Engine.AddErrorInformation(interpreter, result, String.Format("{0} (in namespace inscope \"{1}\" script line {2})", Environment.NewLine, NamespaceOps.MaybeQualifiedName(@namespace, true), Interpreter.GetErrorLine(interpreter))); } /* IGNORED */ interpreter.PopNamespaceCallFrame(frame); /* NO RESULT */ Engine.CleanupNamespacesOrComplain(interpreter); } } else { string name = StringList.MakeList("namespace inscope", @namespace.QualifiedName); ICallFrame frame = interpreter.NewNamespaceCallFrame( name, CallFrameFlags.InScope | CallFrameFlags.UseNamespace, arguments, @namespace, false); interpreter.PushNamespaceCallFrame(frame); code = interpreter.EvaluateScript(arguments[3], ref result); if (code == ReturnCode.Error) { Engine.AddErrorInformation(interpreter, result, String.Format("{0} (in namespace inscope \"{1}\" script line {2})", Environment.NewLine, NamespaceOps.MaybeQualifiedName(@namespace, true), Interpreter.GetErrorLine(interpreter))); } /* IGNORED */ interpreter.PopNamespaceCallFrame(frame); /* NO RESULT */ Engine.CleanupNamespacesOrComplain(interpreter); } } else { code = ReturnCode.Error; } } else { result = "wrong # args: should be \"namespace inscope name arg ?arg...?\""; code = ReturnCode.Error; } break; } case "mappings": { if (arguments.Count == 2) { lock (interpreter.SyncRoot) /* TRANSACTIONAL */ { StringDictionary namespaceMappings = interpreter.NamespaceMappings; if (namespaceMappings != null) { result = namespaceMappings.KeysAndValuesToString(null, false); code = ReturnCode.Ok; } else { result = "namespace mappings not available"; code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"namespace mappings\""; code = ReturnCode.Error; } break; } case "name": { if (arguments.Count == 3) { string name = arguments[2]; if (!NamespaceOps.IsQualifiedName(name)) { result = NamespaceOps.MakeQualifiedName(interpreter, name, true); code = ReturnCode.Ok; } else { result = "only non-qualified names are allowed"; code = ReturnCode.Error; } } else { result = "wrong # args: should be \"namespace name name\""; code = ReturnCode.Error; } break; } case "origin": { if (arguments.Count == 3) { code = NamespaceOps.Origin(interpreter, null, arguments[2], ref result); } else { result = "wrong # args: should be \"namespace origin name\""; code = ReturnCode.Error; } break; } case "parent": { if ((arguments.Count == 2) || (arguments.Count == 3)) { code = NamespaceOps.Parent( interpreter, (arguments.Count == 3) ? arguments[2] : null, ref result); } else { result = "wrong # args: should be \"namespace parent ?name?\""; code = ReturnCode.Error; } break; } case "qualifiers": { if (arguments.Count == 3) { string qualifiers = null; string tail = null; code = NamespaceOps.SplitName( arguments[2], ref qualifiers, ref tail, ref result); if (code == ReturnCode.Ok) { result = qualifiers; } } else { result = "wrong # args: should be \"namespace qualifiers string\""; code = ReturnCode.Error; } break; } case "rename": { if (arguments.Count == 4) { code = interpreter.RenameNamespace( arguments[2], arguments[3], RenameGlobalOk, RenameInUseOk, ref result); } else { result = "wrong # args: should be \"namespace rename oldName newName\""; code = ReturnCode.Error; } break; } case "tail": { if (arguments.Count == 3) { string qualifiers = null; string tail = null; code = NamespaceOps.SplitName( arguments[2], ref qualifiers, ref tail, ref result); if (code == ReturnCode.Ok) { result = tail; } } else { result = "wrong # args: should be \"namespace tail string\""; code = ReturnCode.Error; } break; } case "unknown": { if ((arguments.Count == 2) || (arguments.Count == 3)) { INamespace currentNamespace = null; code = interpreter.GetCurrentNamespaceViaResolvers( null, LookupFlags.Default, ref currentNamespace, ref result); if (code == ReturnCode.Ok) { if (currentNamespace != null) { if (arguments.Count == 3) { string unknown = StringOps.NullIfEmpty(arguments[2]); if (String.IsNullOrEmpty(unknown) && NamespaceOps.IsGlobal(interpreter, currentNamespace)) { currentNamespace.Unknown = interpreter.GlobalUnknown; } else { currentNamespace.Unknown = unknown; } result = unknown; } else { result = currentNamespace.Unknown; } } else { if (arguments.Count == 3) { string unknown = StringOps.NullIfEmpty(arguments[2]); if (String.IsNullOrEmpty(unknown)) { interpreter.GlobalUnknown = TclVars.Unknown; } else { interpreter.GlobalUnknown = unknown; } result = unknown; } else { result = interpreter.GlobalUnknown; } } } } else { result = "wrong # args: should be \"namespace unknown ?script?\""; code = ReturnCode.Error; } break; } case "which": { if (arguments.Count >= 2) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-command", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-variable", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; if (arguments.Count > 2) { code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, OptionBehaviorFlags.LastIsNonOption, false, ref argumentIndex, ref result); } else { code = ReturnCode.Ok; } if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 1) == arguments.Count)) { string name = arguments[argumentIndex]; bool isCommand = false; if (options.IsPresent("-command")) { isCommand = true; } bool isVariable = false; if (options.IsPresent("-variable")) { isVariable = true; } if (!isCommand || !isVariable) { NamespaceFlags flags = NamespaceFlags.None; if (isCommand) { flags |= NamespaceFlags.Command; } else if (isVariable) { flags |= NamespaceFlags.Variable; } else { flags |= NamespaceFlags.Command; } code = NamespaceOps.Which(interpreter, null, name, flags, ref result); } else { result = "wrong # args: should be \"namespace which ?-command? ?-variable? name\""; code = ReturnCode.Error; } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"namespace which ?-command? ?-variable? name\""; } code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"namespace which ?-command? ?-variable? name\""; code = ReturnCode.Error; } break; } default: { result = ScriptOps.BadSubCommand( interpreter, null, null, subCommand, this, null, null); code = ReturnCode.Error; break; } } } } else { result = "wrong # args: should be \"namespace subcommand ?arg ...?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
/////////////////////////////////////////////////////////////////////// public StringList GetImportNames( string pattern, bool keys, bool tailOnly ) { CheckDisposed(); StringList list = new StringList(); if (imports == null) { return(list); } if (pattern != null) { pattern = ScriptOps.MakeCommandName(pattern); } foreach (KeyValuePair <string, object> pair in imports) { IAlias alias = pair.Value as IAlias; if (alias == null) { continue; } if (keys) { string importName = pair.Key; string importNameTailOnly = NamespaceOps.TailOnly( importName); if ((pattern == null) || StringOps.Match( interpreter, MatchMode.Glob, importNameTailOnly, pattern, false)) { list.Add(tailOnly ? importNameTailOnly : importName); } } else { string aliasName = NamespaceOps.GetAliasName(alias); string aliasNameTailOnly = NamespaceOps.TailOnly( aliasName); if ((pattern == null) || StringOps.Match( interpreter, MatchMode.Glob, aliasNameTailOnly, pattern, false)) { list.Add(tailOnly ? aliasNameTailOnly : aliasName); } } } return(list); }
public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 3) { ICallFrame otherFrame = null; FrameResult frameResult = interpreter.GetCallFrame( arguments[1], ref otherFrame, ref result); if (frameResult != FrameResult.Invalid) { int count = arguments.Count - ((int)frameResult + 1); if ((count & 1) == 0) { lock (interpreter.SyncRoot) /* TRANSACTIONAL */ { ICallFrame localFrame = null; code = interpreter.GetVariableFrameViaResolvers( LookupFlags.Default, ref localFrame, ref result); if (code == ReturnCode.Ok) { int argumentIndex = ((int)frameResult + 1); // skip "upvar ?level?" for (; count > 0; count -= 2, argumentIndex += 2) { string otherName = arguments[argumentIndex]; string localName = arguments[argumentIndex + 1]; code = ScriptOps.LinkVariable( interpreter, localFrame, localName, otherFrame, otherName, ref result); if (code != ReturnCode.Ok) { break; } } } } } else { result = "wrong # args: should be \"upvar ?level? otherVar localVar ?otherVar localVar ...?\""; code = ReturnCode.Error; } } else { code = ReturnCode.Error; } } else { result = "wrong # args: should be \"upvar ?level? otherVar localVar ?otherVar localVar ...?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code; if (interpreter != null) { if (arguments != null) { // // try {<tryBody>} // [finally {<finallyBody>}] // if ((arguments.Count == 2) || (arguments.Count == 4)) { if ((arguments.Count < 3) || (String.Compare(arguments[2], Try.Finally, StringOps.SystemStringComparisonType) == 0)) { string name = StringList.MakeList("try"); ICallFrame frame = interpreter.NewTrackingCallFrame(name, CallFrameFlags.Try); interpreter.PushAutomaticCallFrame(frame); ReturnCode tryCode; Result tryResult = null; tryCode = interpreter.EvaluateScript(arguments[1], ref tryResult); if (tryCode == ReturnCode.Error) { Engine.AddErrorInformation(interpreter, tryResult, String.Format("{0} (\"try\" body line {1})", Environment.NewLine, Interpreter.GetErrorLine(interpreter))); } // // NOTE: Pop the original call frame that we pushed above and // any intervening scope call frames that may be leftover // (i.e. they were not explicitly closed). // /* IGNORED */ interpreter.PopScopeCallFramesAndOneMore(); Result finallyResult = null; ReturnCode finallyCode = ReturnCode.Ok; if (arguments.Count == 4) { name = StringList.MakeList("finally"); frame = interpreter.NewTrackingCallFrame(name, CallFrameFlags.Finally); interpreter.PushAutomaticCallFrame(frame); // // BUGFIX: Preserve any and all existing error related // information during evaluation of the finally // block. // Engine.SetNoResetError(interpreter, true); // // NOTE: If there was an error during the try block as well, // keep them somewhat organized in the final error // information. // if (tryCode == ReturnCode.Error) { Engine.AddErrorInformation(interpreter, null, String.Format("{0} ... continued ...", Environment.NewLine)); } // // NOTE: If the appropriate flag is set, call into the // Engine.ResetCancel method (with "force" enabled) // prior to evaluating the finally block script. // It should be noted here that even though the // return code of this call is checked by the code, // it basically cannot fail at this point. // Result canceledResult = null; bool canceled = false; bool unwound = false; bool resetCancel = false; // // NOTE: If the appropriate flag is set, reset the Exit // property prior to evaluating the finally block // script. // bool exit = false; bool resetExit = false; try { if (ScriptOps.HasFlags(interpreter, InterpreterFlags.FinallyResetCancel, true)) { ReturnCode resetCode; Result resetError = null; resetCode = Engine.ResetCancel( interpreter, CancelFlags.TryBlock, ref canceledResult, ref canceled, ref unwound, ref resetCancel, ref resetError); if (resetCode != ReturnCode.Ok) { DebugOps.Complain(interpreter, resetCode, resetError); } } if (ScriptOps.HasFlags(interpreter, InterpreterFlags.FinallyResetExit, true)) { exit = interpreter.Exit; if (exit) { interpreter.Exit = false; resetExit = true; } } ReturnCode timeoutCode; Result timeoutResult = null; timeoutCode = Interpreter.StartFinallyTimeoutThread( interpreter, false, true, ref timeoutResult); if (timeoutCode != ReturnCode.Ok) { DebugOps.Complain(interpreter, timeoutCode, timeoutResult); } try { // // NOTE: Evaluate the finally block. // finallyCode = interpreter.EvaluateScript( arguments[3], ref finallyResult); } finally { timeoutCode = Interpreter.InterruptFinallyTimeoutThread( interpreter, false, ref timeoutResult); if (timeoutCode != ReturnCode.Ok) { DebugOps.Complain(interpreter, timeoutCode, timeoutResult); } } } finally { if (exit && resetExit) { if (ScriptOps.HasFlags(interpreter, InterpreterFlags.FinallyRestoreExit, true)) { interpreter.Exit = true; } } if ((canceled || unwound) && resetCancel) { if (ScriptOps.HasFlags(interpreter, InterpreterFlags.FinallyRestoreCancel, true)) { CancelFlags cancelFlags = CancelFlags.FinallyBlock; if (unwound) { cancelFlags |= CancelFlags.Unwind; } ReturnCode cancelCode; Result cancelError = null; cancelCode = Engine.CancelEvaluate( interpreter, canceledResult, cancelFlags, ref cancelError); if (cancelCode != ReturnCode.Ok) { DebugOps.Complain(interpreter, cancelCode, cancelError); } } } } if (finallyCode == ReturnCode.Error) { Engine.AddErrorInformation(interpreter, finallyResult, String.Format("{0} (\"finally\" body line {1})", Environment.NewLine, Interpreter.GetErrorLine(interpreter))); } // // NOTE: Restore normal result reset semantics. // Engine.SetNoResetError(interpreter, false); // // NOTE: Pop the original call frame that we pushed above and // any intervening scope call frames that may be leftover // (i.e. they were not explicitly closed). // /* IGNORED */ interpreter.PopScopeCallFramesAndOneMore(); } // // NOTE: Initially, the overall command return code and result // is that of the try block; however, if the finally block // fails, that will be the return code and result. // if (finallyCode == ReturnCode.Ok) { result = tryResult; code = tryCode; } else { result = finallyResult; code = finallyCode; } } else { result = String.Format( "expected \"finally\" but got \"{0}\"", arguments[2]); code = ReturnCode.Error; } } else { result = "wrong # args: should be \"try script ?finally script?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; return(ReturnCode.Error); } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
/////////////////////////////////////////////////////////////////////// #region Background Error Executor private static ReturnCode ExecuteBackgroundError( Interpreter interpreter, string handlerName, IExecute execute, IClientData clientData, ArgumentList arguments, ref Result result, ref int errorLine ) { if (interpreter == null) { result = "invalid interpreter"; return(ReturnCode.Error); } // // NOTE: Create a new call frame for the background error handler // and push it. // ICallFrame frame = interpreter.NewTrackingCallFrame( StringList.MakeList("bgerror", handlerName), CallFrameFlags.BackgroundError); interpreter.PushAutomaticCallFrame(frame); try { // // NOTE: Save current engine flags and then enable external // execution. // EngineFlags savedEngineFlags = interpreter.BeginExternalExecution(); try { // // NOTE: If the interpreter is configured to reset the // script cancellation flags prior to executing // the background error handler, do that now. // if (ScriptOps.HasFlags( interpreter, InterpreterFlags.BgErrorResetCancel, true)) { /* IGNORED */ Engine.ResetCancel(interpreter, CancelFlags.BgError); } // // NOTE: Evaluate the script and then check the result to // see if the background error handler failed or // canceled further background error handling for // this invocation of ProcessEvents. // ReturnCode code; code = interpreter.Execute( handlerName, execute, clientData, arguments, ref result); // // NOTE: Maybe grab the new error line number, if any. // if (code != ReturnCode.Ok) { errorLine = Interpreter.GetErrorLine(interpreter); } // // NOTE: We are done now, return. // return(code); } finally { // // NOTE: Restore saved engine flags, disabling external // execution as necessary. // /* IGNORED */ interpreter.EndAndCleanupExternalExecution( savedEngineFlags); } } finally { // // NOTE: Pop the original call frame that we pushed above // and any intervening scope call frames that may be // leftover (i.e. they were not explicitly closed). // /* IGNORED */ interpreter.PopScopeCallFramesAndOneMore(); } }
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); }
public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 2) { string subCommand = arguments[1]; bool tried = false; code = ScriptOps.TryExecuteSubCommandFromEnsemble( interpreter, this, clientData, arguments, true, false, ref subCommand, ref tried, ref result); if ((code == ReturnCode.Ok) && !tried) { switch (subCommand) { case "decode": { if (arguments.Count >= 3) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.MustHaveEncodingValue, Index.Invalid, Index.Invalid, "-encoding", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 1) == arguments.Count)) { Variant value = null; Encoding encoding = null; if (options.IsPresent("-encoding", ref value)) { encoding = (Encoding)value.Value; } if (code == ReturnCode.Ok) { try { string stringValue = null; code = StringOps.GetString(encoding, Convert.FromBase64String(arguments[argumentIndex]), EncodingType.Binary, ref stringValue, ref result); if (code == ReturnCode.Ok) { result = stringValue; } } catch (Exception e) { Engine.SetExceptionErrorCode(interpreter, e); result = e; code = ReturnCode.Error; } } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"base64 decode ?options? string\""; } code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"base64 decode ?options? string\""; code = ReturnCode.Error; } break; } case "encode": { if (arguments.Count >= 3) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.MustHaveEncodingValue, Index.Invalid, Index.Invalid, "-encoding", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 1) == arguments.Count)) { Variant value = null; Encoding encoding = null; if (options.IsPresent("-encoding", ref value)) { encoding = (Encoding)value.Value; } if (code == ReturnCode.Ok) { try { byte[] bytes = null; code = StringOps.GetBytes( encoding, arguments[argumentIndex], EncodingType.Binary, ref bytes, ref result); if (code == ReturnCode.Ok) { result = Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks); } } catch (Exception e) { Engine.SetExceptionErrorCode(interpreter, e); result = e; code = ReturnCode.Error; } } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"base64 encode ?options? string\""; } code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"base64 encode ?options? string\""; code = ReturnCode.Error; } break; } default: { result = ScriptOps.BadSubCommand( interpreter, null, null, subCommand, this, null, null); code = ReturnCode.Error; break; } } } } else { result = "wrong # args: should be \"base64 option ?arg ...?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code; if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 1) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-force", null), new Option(null, OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-fail", null), new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-message", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-current", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null) }); int argumentIndex = Index.Invalid; if (arguments.Count > 1) { code = interpreter.GetOptions(options, arguments, 0, 1, Index.Invalid, false, ref argumentIndex, ref result); } else { code = ReturnCode.Ok; } if (code == ReturnCode.Ok) { if ((argumentIndex == Index.Invalid) || ((argumentIndex + 1) == arguments.Count)) { bool force = false; if (options.IsPresent("-force")) { force = true; } bool fail = false; if (options.IsPresent("-fail")) { fail = true; } Variant value = null; string message = null; if (options.IsPresent("-message", ref value)) { message = value.ToString(); } // // NOTE: The default exit code is "success" (i.e. zero). // ExitCode exitCode = ResultOps.SuccessExitCode(); if (options.IsPresent("-current")) { exitCode = interpreter.ExitCode; } // // NOTE: Was an exit code specified in the command? // if (argumentIndex != Index.Invalid) { object enumValue = EnumOps.TryParseEnum( typeof(ExitCode), arguments[argumentIndex], true, true, ref result); if (enumValue is ExitCode) { exitCode = (ExitCode)enumValue; } else { result = ScriptOps.BadValue( null, "exit code", arguments[argumentIndex], Enum.GetNames(typeof(ExitCode)), null, ", or an integer"); code = ReturnCode.Error; } } // // NOTE: Make sure we succeeded at coverting the exit code to an integer. // if (code == ReturnCode.Ok) { // // NOTE: Make sure the interpreter host, if any, agrees to exit (i.e. it may deny the // request if the application is doing something that should not be interrupted). // code = interpreter.CanExit(exitCode, force, fail, message, ref result); if (code == ReturnCode.Ok) { // // NOTE: Exit the application (either by marking the current interpreter as "exited" // or physically exiting the containing process). // TraceOps.DebugTrace(String.Format( "Execute: {0}, interpreter = {1}, message = {2}", force && fail ? "forcibly failing" : force ? "forcibly exiting" : "exiting", FormatOps.InterpreterNoThrow(interpreter), FormatOps.WrapOrNull(message)), typeof(Exit).Name, TracePriority.Command); if (force) { #if !MONO if (fail && !CommonOps.Runtime.IsMono()) { try { // // NOTE: Using this method to exit a script is NOT recommended unless // you are trying to prevent damaging another part of the system. // // MONO: This method is not supported by the Mono runtime. // Environment.FailFast(message); /* NOT REACHED */ result = "failed to exit process"; code = ReturnCode.Error; } catch (Exception e) { result = e; code = ReturnCode.Error; } } else #endif { // // BUGFIX: Try to dispose our containing interpreter now. We must do // this to prevent it from being disposed on a random GC thread. // try { interpreter.Dispose(); interpreter = null; } catch (Exception e) { result = e; code = ReturnCode.Error; } // // NOTE: If we could not dispose the interpreter properly, complain; // however, keep exiting anyway. // if (code != ReturnCode.Ok) { DebugOps.Complain(interpreter, code, result); } try { // // NOTE: Using this method to exit a script is NOT recommended unless // you are running a standalone script in the Eagle Shell (i.e. // you are not hosted within another application). // Environment.Exit((int)exitCode); /* NOT REACHED */ result = "failed to exit process"; code = ReturnCode.Error; } catch (Exception e) { result = e; code = ReturnCode.Error; } } } else { interpreter.ExitCode = exitCode; interpreter.Exit = true; result = String.Empty; code = ReturnCode.Ok; } } } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"exit ?options? ?returnCode?\""; } code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"exit ?options? ?returnCode?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
/////////////////////////////////////////////////////////////////////////////////////////////// #region IExecute Members public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { if (arguments != null) { if (arguments.Count == 4) { string name = arguments[1]; StringList list = null; code = Parser.SplitList( interpreter, arguments[2], 0, Length.Invalid, true, ref list, ref result); if (code == ReturnCode.Ok) { StringPairList list2 = new StringPairList(); for (int argumentIndex = 0; argumentIndex < list.Count; argumentIndex++) { StringList list3 = null; code = Parser.SplitList( interpreter, list[argumentIndex], 0, Length.Invalid, true, ref list3, ref result); if (code != ReturnCode.Ok) { break; } if (list3.Count > 2) { result = String.Format( "too many fields in argument specifier \"{0}\"", list[argumentIndex]); code = ReturnCode.Error; break; } else if ((list3.Count == 0) || String.IsNullOrEmpty(list3[0])) { result = "argument with no name"; code = ReturnCode.Error; break; } else if (!Parser.IsSimpleScalarVariableName(list3[0], String.Format(Interpreter.ArgumentNotSimpleError, list3[0]), String.Format(Interpreter.ArgumentNotScalarError, list3[0]), ref result)) { code = ReturnCode.Error; break; } string argName = list3[0]; string argDefault = (list3.Count >= 2) ? list3[1] : null; list2.Add(new StringPair(argName, argDefault)); } if (code == ReturnCode.Ok) { lock (interpreter.SyncRoot) /* TRANSACTIONAL */ { ProcedureFlags procedureFlags = interpreter.ProcedureFlags; IProcedure procedure = RuntimeOps.NewCoreProcedure( interpreter, interpreter.AreNamespacesEnabled() ? NamespaceOps.MakeQualifiedName(interpreter, name) : ScriptOps.MakeCommandName(name), null, null, procedureFlags, new ArgumentList(list2, ArgumentFlags.NameOnly), arguments[3], ScriptLocation.Create(arguments[3]), clientData); code = interpreter.AddOrUpdateProcedureWithReplace( procedure, clientData, ref result); if (code == ReturnCode.Ok) { result = String.Empty; } } } } if (code == ReturnCode.Error) { Engine.AddErrorInformation(interpreter, result, String.Format("{0} (creating proc \"{1}\")", Environment.NewLine, name)); } } else { result = "wrong # args: should be \"proc name args body\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
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); }