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