/////////////////////////////////////////////////////////////////////// public override ReturnCode GetCurrentNamespace( ICallFrame frame, ref INamespace @namespace, ref Result error ) { INamespace localNamespace = NamespaceOps.GetCurrent( base.Interpreter, frame); if (localNamespace != null) { IResolve resolve = localNamespace.Resolve; if (resolve != null) { return(resolve.GetCurrentNamespace( frame, ref @namespace, ref error)); } else { @namespace = localNamespace; return(ReturnCode.Ok); } } error = "no current namespace for call frame"; return(ReturnCode.Error); }
/////////////////////////////////////////////////////////////////////// #region IResolve Members public override ReturnCode GetVariableFrame( ref ICallFrame frame, ref string varName, ref VariableFlags flags, ref Result error ) { INamespace @namespace = NamespaceOps.GetCurrent( base.Interpreter, frame); if (@namespace != null) { IResolve resolve = @namespace.Resolve; if (resolve != null) { return(resolve.GetVariableFrame( ref frame, ref varName, ref flags, ref error)); } } return(NamespaceOps.GetVariableFrame( base.Interpreter, ref frame, ref varName, ref flags, ref error)); }
public Namespace( IResolveData resolveData, ICallFrame frame, INamespace @namespace ) : base(resolveData) { NamespaceOps.SetCurrent(base.Interpreter, frame, @namespace); }
/////////////////////////////////////////////////////////////////////// private string GetQualifiedName() { if (qualifiedName == null) { qualifiedName = NamespaceOps.GetQualifiedName(this, null); } return(qualifiedName); }
/////////////////////////////////////////////////////////////////////// public override ReturnCode GetIExecute( ICallFrame frame, EngineFlags engineFlags, string name, ArgumentList arguments, LookupFlags lookupFlags, ref bool ambiguous, ref long token, ref IExecute execute, ref Result error ) { if (!Engine.HasGlobalOnly(engineFlags)) { IResolve resolve = null; string tail = null; INamespace @namespace = GetNamespaceForIExecute( frame, name, ref resolve, ref tail, ref error); if (@namespace != null) { if (resolve != null) { return(resolve.GetIExecute( frame, engineFlags, tail, arguments, lookupFlags, ref ambiguous, ref token, ref execute, ref error)); } else { Interpreter interpreter = base.Interpreter; if (!NamespaceOps.IsGlobal(interpreter, @namespace)) { string qualifiedName = NamespaceOps.MakeQualifiedName( interpreter, @namespace, name); if (base.GetIExecute(frame, engineFlags | EngineFlags.ExactMatch, qualifiedName, arguments, lookupFlags, ref ambiguous, ref token, ref execute, ref error) == ReturnCode.Ok) { return(ReturnCode.Ok); } } } } } return(base.GetIExecute( frame, engineFlags, name, arguments, lookupFlags, ref ambiguous, ref token, ref execute, ref error)); }
/////////////////////////////////////////////////////////////////////// protected virtual INamespace GetNamespaceForVariable( ICallFrame frame, /* in */ string varName, /* in */ ref IResolve resolve, /* out */ ref string tail, /* out */ ref Result error /* out */ ) { return(NamespaceOps.GetForVariable( base.Interpreter, frame, varName, ref resolve, ref tail, ref error)); }
private string NextName( Interpreter interpreter, INamespace @namespace ) { // // NOTE: Create and return a per-interpreter unique name in // the specified namespace (which may be global). // return(NamespaceOps.MakeAbsoluteName( NamespaceOps.MakeQualifiedName(interpreter, @namespace, StringList.MakeList(this.Name, GlobalState.NextId( interpreter))))); }
/////////////////////////////////////////////////////////////////////// private void AfterNameChange( string oldName, bool global ) { // // HACK: The qualified name of the global namespace cannot be // changed; however, we let the local name be changed. // if (!global) { ResetQualifiedName(); // // NOTE: For the rest of the steps in here, we want to make // sure that the name is actually different now. // if (!NamespaceOps.IsSame(oldName, name)) { // // HACK: Next, force all child namespaces to recompute // their qualified names as well. // ResetChildNames(null, true); // // HACK: Finally, "notify" the parent namespace that our // name has been changed (i.e. so it can update its // list of children). // if (parent != null) { ReturnCode renameCode; Result renameError = null; renameCode = parent.RenameChild( oldName, name, ref renameError); if (renameCode != ReturnCode.Ok) { DebugOps.Complain( interpreter, renameCode, renameError); } } } } }
/////////////////////////////////////////////////////////////////////// public override ReturnCode GetVariable( ICallFrame frame, string varName, string varIndex, ref VariableFlags flags, ref IVariable variable, ref Result error ) { IResolve resolve = null; string tail = null; INamespace @namespace = GetNamespaceForVariable( frame, varName, ref resolve, ref tail, ref error); if (@namespace != null) { if (resolve != null) { return(resolve.GetVariable( frame, tail, varIndex, ref flags, ref variable, ref error)); } else { Interpreter interpreter = base.Interpreter; if (!NamespaceOps.IsGlobal(interpreter, @namespace)) { frame = @namespace.VariableFrame; return(base.GetVariable( frame, tail, varIndex, ref flags, ref variable, ref error)); } } } return(base.GetVariable( frame, varName, varIndex, ref flags, ref variable, ref error)); }
public NamespaceData( string name, IClientData clientData, Interpreter interpreter, INamespace parent, IResolve resolve, ICallFrame variableFrame, string unknown ) { this.kind = IdentifierKind.NamespaceData; this.id = AttributeOps.GetObjectId(this); this.name = NamespaceOps.TrimAll(name); this.clientData = clientData; this.interpreter = interpreter; this.parent = parent; this.resolve = resolve; this.variableFrame = variableFrame; this.unknown = unknown; }
/////////////////////////////////////////////////////////////////////// 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); }
/////////////////////////////////////////////////////////////////////////////////////////////// #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); }
/////////////////////////////////////////////////////////////////////////////////////////////// #region IExecute Members public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code = ReturnCode.Ok; if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 2) { // // NOTE: lambdaExpr must be a two element list {args body} or a three element // list {args body namespace}. // StringList lambdaExpr = null; code = Parser.SplitList( interpreter, arguments[1], 0, Length.Invalid, true, ref lambdaExpr, ref result); if (code == ReturnCode.Ok) { if ((lambdaExpr.Count == 2) || (lambdaExpr.Count == 3)) { byte[] hashValue = arguments[1].GetHashValue(ref result); if (hashValue != null) { INamespace @namespace = null; if (lambdaExpr.Count == 3) { @namespace = NamespaceOps.Lookup( interpreter, lambdaExpr[2], true, false, ref result); if (@namespace == null) { code = ReturnCode.Error; } } if (code == ReturnCode.Ok) { // // NOTE: Parse the arguments into a list and make sure there are enough // supplied to satisfy the request. // StringList list = null; code = Parser.SplitList( interpreter, lambdaExpr[0], 0, Length.Invalid, true, ref list, ref result); if (code == ReturnCode.Ok) { StringPairList list2 = new StringPairList(); for (int argumentIndex = 0; argumentIndex < list.Count; argumentIndex++) { StringList list3 = null; code = Parser.SplitList( interpreter, list[argumentIndex], 0, Length.Invalid, true, ref list3, ref result); if (code != ReturnCode.Ok) { break; } if (list3.Count > 2) { result = String.Format( "too many fields in argument specifier \"{0}\"", list[argumentIndex]); code = ReturnCode.Error; break; } else if ((list3.Count == 0) || String.IsNullOrEmpty(list3[0])) { result = "argument with no name"; code = ReturnCode.Error; break; } else if (!Parser.IsSimpleScalarVariableName(list3[0], String.Format(Interpreter.ArgumentNotSimpleError, list3[0]), String.Format(Interpreter.ArgumentNotScalarError, list3[0]), ref result)) { code = ReturnCode.Error; break; } string argName = list3[0]; string argDefault = (list3.Count >= 2) ? list3[1] : null; list2.Add(new StringPair(argName, argDefault)); } if (code == ReturnCode.Ok) { // // NOTE: We *MUST* have the formal arguments in an actual ArgumentList // container now. The variadic and optional argument semantics // depend on it. // ArgumentList formalArguments = new ArgumentList( list2, ArgumentFlags.NameOnly); // // NOTE: Compare lambda argument count with the total outer argument // count minus the "apply" and "lambdaExpr" arguments. // bool hasArgs = formalArguments.IsVariadic(true); int totalArgs = hasArgs ? formalArguments.Count - 1 : formalArguments.Count; int optionalArgs = formalArguments.GetOptionalCount(); if ((((arguments.Count - 2) >= (totalArgs - optionalArgs)) && ((arguments.Count - 2) <= totalArgs)) || (hasArgs && ((arguments.Count - 2) >= (totalArgs - optionalArgs)))) { string name = NextName(interpreter, @namespace); ICallFrame frame = null; try { frame = interpreter.NewProcedureCallFrame( name, CallFrameFlags.Procedure | CallFrameFlags.Lambda, new ClientData(hashValue), this, arguments); VariableDictionary variables = frame.Variables; frame.ProcedureArguments = new ArgumentList(arguments[0]); for (int argumentIndex = 0; argumentIndex < formalArguments.Count; argumentIndex++) { string varName = formalArguments[argumentIndex].Name; if (!variables.ContainsKey(varName)) { ArgumentFlags flags = ArgumentFlags.None; object varValue; if (hasArgs && (argumentIndex == (formalArguments.Count - 1))) { // // NOTE: This argument is part of an argument list. // flags |= ArgumentFlags.ArgumentList; // // NOTE: Build the list for the final formal argument value, // which consists of all the remaining argument values. // ArgumentList argsArguments = new ArgumentList(); for (int argsArgumentIndex = argumentIndex + 2; argsArgumentIndex < arguments.Count; argsArgumentIndex++) { // // NOTE: Sync up the argument name and flags for use when // debugging (below). // Argument argsArgument = Argument.GetOrCreate( interpreter, arguments[argsArgumentIndex].Flags | flags, String.Format("{0}{1}{2}", varName, Characters.Space, argsArguments.Count), arguments[argsArgumentIndex], interpreter.HasNoCacheArgument()); argsArguments.Add(argsArgument); } varValue = argsArguments; } else { if ((argumentIndex + 2) < arguments.Count) { // // NOTE: Sync up the argument name for use when // debugging (below) and use the value // supplied by the caller. // varValue = Argument.GetOrCreate(interpreter, arguments[argumentIndex + 2].Flags | flags, varName, arguments[argumentIndex + 2], interpreter.HasNoCacheArgument()); } else { // // NOTE: We cannot sync up the argument name here // because we are out-of-bounds on that list // and it cannot be extended (i.e. it would // break [info level]); therefore, we punt // on that for now. Use the default value // for this argument, if any; otherwise, use // an empty string. // object @default = formalArguments[argumentIndex].Default; varValue = (@default != null) ? @default : Argument.NoValue; } } code = interpreter.SetVariableValue2(VariableFlags.Argument, frame, varName, varValue, ref result); if (code != ReturnCode.Ok) { break; } // // BUGFIX: Now, also keep track of this argument in the procedure // arguments list. Primarily because we do not want to // have to redo this logic later (i.e. for [scope]). // frame.ProcedureArguments.Add(Argument.GetOrCreate( interpreter, flags, varName, varValue, interpreter.HasNoCacheArgument())); } } // // NOTE: Make sure we succeeded in creating the call frame. // if (code == ReturnCode.Ok) { ICallFrame savedFrame = null; interpreter.PushProcedureCallFrame(frame, true, ref savedFrame); try { #if DEBUGGER && DEBUGGER_EXECUTE if (DebuggerOps.CanHitBreakpoints(interpreter, EngineFlags.None, BreakpointType.BeforeLambdaBody)) { code = interpreter.CheckBreakpoints( code, BreakpointType.BeforeLambdaBody, this.Name, null, null, this, null, clientData, arguments, ref result); } #endif if (code == ReturnCode.Ok) { interpreter.ReturnCode = ReturnCode.Ok; code = interpreter.EvaluateScript(lambdaExpr[1], arguments[1], ref result); #if DEBUGGER && DEBUGGER_EXECUTE if (DebuggerOps.CanHitBreakpoints(interpreter, EngineFlags.None, BreakpointType.AfterLambdaBody)) { code = interpreter.CheckBreakpoints( code, BreakpointType.AfterLambdaBody, this.Name, null, null, this, null, clientData, arguments, ref result); } #endif // // BUGFIX: If an opaque object handle is being returned, add // a reference to it now. // if ((code == ReturnCode.Ok) || (code == ReturnCode.Return)) { code = interpreter.AddObjectReference( code, result, ObjectReferenceType.Return, ref result); } if (code == ReturnCode.Return) { code = Engine.UpdateReturnInformation(interpreter); } else if (code == ReturnCode.Error) { Engine.AddErrorInformation(interpreter, result, String.Format("{0} (lambda term \"{1}\" line {2})", Environment.NewLine, FormatOps.Ellipsis(arguments[1]), Interpreter.GetErrorLine(interpreter))); } } } finally { /* IGNORED */ interpreter.PopProcedureCallFrame(frame, ref savedFrame); } } } finally { if (frame != null) { IDisposable disposable = frame as IDisposable; if (disposable != null) { disposable.Dispose(); disposable = null; } frame = null; } } } else { result = String.Format( "wrong # args: should be \"apply lambdaExpr {0}\"", formalArguments.ToRawString(ToStringFlags.Decorated, Characters.Space.ToString())); code = ReturnCode.Error; } } } } } else { code = ReturnCode.Error; } } else { result = String.Format( "can't interpret \"{0}\" as a lambda expression", arguments[1]); code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"apply lambdaExpr ?arg1 arg2 ...?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
/////////////////////////////////////////////////////////////////////// #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 ) { 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 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); }
/////////////////////////////////////////////////////////////////////// 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); }
/////////////////////////////////////////////////////////////////////// public ReturnCode GetImport( string qualifiedImportName, ref string qualifiedExportName, ref Result error ) { CheckDisposed(); if (qualifiedImportName == null) { error = "invalid import name"; return(ReturnCode.Error); } if (!NamespaceOps.IsQualifiedName(qualifiedImportName)) { error = "import name must be qualified"; return(ReturnCode.Error); } if (interpreter == null) { error = "invalid interpreter"; return(ReturnCode.Error); } if (imports == null) { error = String.Format( "imports not available in namespace \"{0}\"", GetDisplayName()); return(ReturnCode.Error); } object @object; if (imports.TryGetValue(qualifiedImportName, out @object)) { IAlias alias = @object as IAlias; if (alias != null) { qualifiedExportName = NamespaceOps.GetAliasName(alias); return(ReturnCode.Ok); } else { error = String.Format( "import name \"{0}\" is not an alias", qualifiedImportName); } } else { error = String.Format( "import name \"{0}\" not found", qualifiedImportName); } return(ReturnCode.Error); }
/////////////////////////////////////////////////////////////////////// private IDictionary <string, INamespace> PrivateGetChildren( string pattern, bool deleted ) /* CANNOT RETURN NULL */ { IDictionary <string, INamespace> dictionary = new Dictionary <string, INamespace>(); if (children != null) { if (pattern != null) { bool qualified = NamespaceOps.IsQualifiedName(pattern); foreach (KeyValuePair <string, INamespace> pair in children) { INamespace child = pair.Value; if (child == null) { continue; } if (!deleted && child.Deleted) { continue; } if (qualified) { if (!StringOps.Match( interpreter, MatchMode.Glob, child.QualifiedName, pattern, false)) { continue; } } else { if (!StringOps.Match( interpreter, MatchMode.Glob, pair.Key, pattern, false)) { continue; } } dictionary.Add(pair.Key, child); } } else { foreach (KeyValuePair <string, INamespace> pair in children) { INamespace child = pair.Value; if (child == null) { continue; } if (!deleted && child.Deleted) { continue; } dictionary.Add(pair.Key, child); } } } return(dictionary); }
/////////////////////////////////////////////////////////////////////// #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); } }