/// <summary> This procedure is invoked to process the "eval" Tcl command. /// See the user documentation for details on what it does. /// /// </summary> /// <param name="interp">the current interpreter. /// </param> /// <param name="argv">command arguments. /// </param> /// <exception cref=""> TclException if script causes error. /// </exception> public TCL.CompletionCode cmdProc( Interp interp, TclObject[] argv ) { if ( argv.Length < 2 ) { throw new TclNumArgsException( interp, 1, argv, "arg ?arg ...?" ); } try { if ( argv.Length == 2 ) { interp.eval( argv[1], 0 ); } else { string s = Util.concat( 1, argv.Length - 1, argv ); interp.eval( s, 0 ); } } catch ( TclException e ) { if ( e.getCompletionCode() == TCL.CompletionCode.ERROR ) { interp.addErrorInfo( "\n (\"eval\" body line " + interp.errorLine + ")" ); } throw; } return TCL.CompletionCode.RETURN; }
/// <summary> See Tcl user documentation for details.</summary> public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv) { if ((argv.Length < 2) || (argv.Length > 3)) { throw new TclNumArgsException(interp, 1, argv, "script ?count?"); } int count; if (argv.Length == 2) { count = 1; } else { count = TclInteger.get(interp, argv[2]); } long startTime = System.DateTime.Now.Ticks; for (int i = 0; i < count; i++) { interp.eval(argv[1], 0); } long endTime = System.DateTime.Now.Ticks; long uSecs = (((endTime - startTime) / 10) / count); if (uSecs == 1) { interp.setResult(TclString.newInstance("1 microsecond per iteration")); } else { interp.setResult(TclString.newInstance(uSecs + " microseconds per iteration")); } return TCL.CompletionCode.RETURN; }
/// <summary> This procedure is invoked to process the "while" Tcl command. /// See the user documentation for details on what it does. /// /// </summary> /// <param name="interp">the current interpreter. /// </param> /// <param name="argv">command arguments. /// </param> /// <exception cref=""> TclException if script causes error. /// </exception> public TCL.CompletionCode cmdProc( Interp interp, TclObject[] argv ) { if ( argv.Length != 3 ) { throw new TclNumArgsException( interp, 1, argv, "test command" ); } string test = argv[1].ToString(); TclObject command = argv[2]; { while ( interp.expr.evalBoolean( interp, test ) ) { try { interp.eval( command, 0 ); } catch ( TclException e ) { switch ( e.getCompletionCode() ) { case TCL.CompletionCode.BREAK: goto loop_brk; case TCL.CompletionCode.CONTINUE: continue; case TCL.CompletionCode.ERROR: interp.addErrorInfo( "\n (\"while\" body line " + interp.errorLine + ")" ); throw; default: throw; } } } } loop_brk: ; interp.resetResult(); return TCL.CompletionCode.RETURN; }
/// <summary> This procedure is invoked to process the "catch" Tcl command. /// See the user documentation for details on what it does. /// /// </summary> /// <param name="interp">the current interpreter. /// </param> /// <param name="argv">command arguments. /// </param> /// <exception cref=""> TclException if wrong number of arguments. /// </exception> public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv) { if (argv.Length != 2 && argv.Length != 3) { throw new TclNumArgsException(interp, 1, argv, "command ?varName?"); } TclObject result; TCL.CompletionCode code = TCL.CompletionCode.OK; try { interp.eval(argv[1], 0); } catch (TclException e) { code = e.getCompletionCode(); } result = interp.getResult(); if ( argv.Length == 3 ) { try { interp.setVar(argv[2], result, 0); } catch (TclException e) { throw new TclException(interp, "couldn't save command result in variable"); } } interp.resetResult(); interp.setResult(TclInteger.newInstance((int)code)); return TCL.CompletionCode.RETURN; }
/// <summary> This procedure is invoked to process the "subst" Tcl command. /// See the user documentation for details on what it does. /// /// </summary> /// <param name="interp">the current interpreter. /// </param> /// <param name="argv">command arguments. /// </param> /// <exception cref=""> TclException if wrong # of args or invalid argument(s). /// </exception> public TCL.CompletionCode cmdProc( Interp interp, TclObject[] argv ) { int currentObjIndex, len, i; int objc = argv.Length - 1; bool doBackslashes = true; bool doCmds = true; bool doVars = true; StringBuilder result = new StringBuilder(); string s; char c; for ( currentObjIndex = 1; currentObjIndex < objc; currentObjIndex++ ) { if ( !argv[currentObjIndex].ToString().StartsWith( "-" ) ) { break; } int opt = TclIndex.get( interp, argv[currentObjIndex], validCmds, "switch", 0 ); switch ( opt ) { case OPT_NOBACKSLASHES: doBackslashes = false; break; case OPT_NOCOMMANDS: doCmds = false; break; case OPT_NOVARS: doVars = false; break; default: throw new TclException( interp, "SubstCmd.cmdProc: bad option " + opt + " index to cmds" ); } } if ( currentObjIndex != objc ) { throw new TclNumArgsException( interp, currentObjIndex, argv, "?-nobackslashes? ?-nocommands? ?-novariables? string" ); } /* * Scan through the string one character at a time, performing * command, variable, and backslash substitutions. */ s = argv[currentObjIndex].ToString(); len = s.Length; i = 0; while ( i < len ) { c = s[i]; if ( ( c == '[' ) && doCmds ) { ParseResult res; try { interp.evalFlags = Parser.TCL_BRACKET_TERM; interp.eval( s.Substring( i + 1, ( len ) - ( i + 1 ) ) ); TclObject interp_result = interp.getResult(); interp_result.preserve(); res = new ParseResult( interp_result, i + interp.termOffset ); } catch ( TclException e ) { i = e.errIndex + 1; throw; } i = res.nextIndex + 2; result.Append( res.value.ToString() ); res.release(); } else if ( c == '\r' ) { /* * (ToDo) may not be portable on Mac */ i++; } else if ( ( c == '$' ) && doVars ) { ParseResult vres = Parser.parseVar( interp, s.Substring( i, ( len ) - ( i ) ) ); i += vres.nextIndex; result.Append( vres.value.ToString() ); vres.release(); } else if ( ( c == '\\' ) && doBackslashes ) { BackSlashResult bs = tcl.lang.Interp.backslash( s, i, len ); i = bs.nextIndex; if ( bs.isWordSep ) { break; } else { result.Append( bs.c ); } } else { result.Append( c ); i++; } } interp.setResult( result.ToString() ); return TCL.CompletionCode.RETURN; }
/* * This procedure is invoked to process the "for" Tcl command. * See the user documentation for details on what it does. * * @param interp the current interpreter. * @param argv command arguments. * @exception TclException if script causes error. */ public TCL.CompletionCode cmdProc( Interp interp, TclObject[] argv ) { if ( argv.Length != 5 ) { throw new TclNumArgsException( interp, 1, argv, "start test next command" ); } TclObject start = argv[1]; string test = argv[2].ToString(); TclObject next = argv[3]; TclObject command = argv[4]; bool done = false; try { interp.eval( start, 0 ); } catch ( TclException e ) { interp.addErrorInfo( "\n (\"for\" initial command)" ); throw; } while ( !done ) { if ( !interp.expr.evalBoolean( interp, test ) ) { break; } try { interp.eval( command, 0 ); } catch ( TclException e ) { switch ( e.getCompletionCode() ) { case TCL.CompletionCode.BREAK: done = true; break; case TCL.CompletionCode.CONTINUE: break; case TCL.CompletionCode.ERROR: interp.addErrorInfo( "\n (\"for\" body line " + interp.errorLine + ")" ); throw; default: throw; } } if ( !done ) { try { interp.eval( next, 0 ); } catch ( TclException e ) { switch ( e.getCompletionCode() ) { case TCL.CompletionCode.BREAK: done = true; break; case TCL.CompletionCode.CONTINUE: break; default: interp.addErrorInfo( "\n (\"for\" loop-end command)" ); throw; } } } } interp.resetResult(); return TCL.CompletionCode.RETURN; }
public TCL.CompletionCode cmdProc( Interp interp, TclObject[] objv ) { string optLevel; int result; CallFrame savedVarFrame, frame; int objc = objv.Length; int objv_index; TclObject cmd; if ( objv.Length < 2 ) { throw new TclNumArgsException( interp, 1, objv, "?level? command ?arg ...?" ); } // Find the level to use for executing the command. optLevel = objv[1].ToString(); // Java does not support passing a reference by refernece so use an array CallFrame[] frameArr = new CallFrame[1]; result = CallFrame.getFrame( interp, optLevel, frameArr ); frame = frameArr[0]; objc -= ( result + 1 ); if ( objc == 0 ) { throw new TclNumArgsException( interp, 1, objv, "?level? command ?arg ...?" ); } objv_index = ( result + 1 ); // Modify the interpreter state to execute in the given frame. savedVarFrame = interp.varFrame; interp.varFrame = frame; // Execute the residual arguments as a command. if ( objc == 1 ) { cmd = objv[objv_index]; } else { cmd = TclString.newInstance( Util.concat( objv_index, objv.Length - 1, objv ) ); } cmd.preserve(); try { interp.eval( cmd, 0 ); } catch ( TclException e ) { if ( e.getCompletionCode() == TCL.CompletionCode.ERROR ) { interp.addErrorInfo( "\n (\"uplevel\" body line " + interp.errorLine + ")" ); } throw; } finally { interp.varFrame = savedVarFrame; cmd.release(); } return TCL.CompletionCode.RETURN; }
internal static string pkgRequire( Interp interp, string pkgName, string version, bool exact ) { VersionSatisfiesResult vsres; Package pkg; PkgAvail avail, best; string script; StringBuilder sbuf; int pass, result; // Do extra check to make sure that version is not // null when the exact flag is set to true. if ( (System.Object)version == null && exact ) { throw new TclException( interp, "conflicting arguments : version == null and exact == true" ); } // Before we can compare versions the version string // must be verified but if it is null we are just looking // for the latest version so skip the check in this case. if ( (System.Object)version != null ) { checkVersion( interp, version ); } // It can take up to three passes to find the package: one pass to // run the "package unknown" script, one to run the "package ifneeded" // script for a specific version, and a final pass to lookup the // package loaded by the "package ifneeded" script. vsres = new VersionSatisfiesResult(); for ( pass = 1; ; pass++ ) { pkg = findPackage( interp, pkgName ); if ( (System.Object)pkg.version != null ) { break; } // The package isn't yet present. Search the list of available // versions and invoke the script for the best available version. best = null; for ( avail = pkg.avail; avail != null; avail = avail.next ) { if ( ( best != null ) && ( compareVersions( avail.version, best.version, null ) <= 0 ) ) { continue; } if ( (System.Object)version != null ) { result = compareVersions( avail.version, version, vsres ); if ( ( result != 0 ) && exact ) { continue; } if ( !vsres.satisfies ) { continue; } } best = avail; } if ( best != null ) { // We found an ifneeded script for the package. Be careful while // executing it: this could cause reentrancy, so (a) protect the // script itself from deletion and (b) don't assume that best // will still exist when the script completes. script = best.script; try { interp.eval( script, TCL.EVAL_GLOBAL ); } catch ( TclException e ) { interp.addErrorInfo( "\n (\"package ifneeded\" script)" ); // Throw the error with new info added to errorInfo. throw; } interp.resetResult(); pkg = findPackage( interp, pkgName ); break; } // Package not in the database. If there is a "package unknown" // command, invoke it (but only on the first pass; after that, // we should not get here in the first place). if ( pass > 1 ) { break; } script = interp.packageUnknown; if ( (System.Object)script != null ) { sbuf = new StringBuilder(); try { Util.appendElement( interp, sbuf, script ); Util.appendElement( interp, sbuf, pkgName ); if ( (System.Object)version == null ) { Util.appendElement( interp, sbuf, "" ); } else { Util.appendElement( interp, sbuf, version ); } if ( exact ) { Util.appendElement( interp, sbuf, "-exact" ); } } catch ( TclException e ) { throw new TclRuntimeError( "unexpected TclException: " + e.Message ); } try { interp.eval( sbuf.ToString(), TCL.EVAL_GLOBAL ); } catch ( TclException e ) { interp.addErrorInfo( "\n (\"package unknown\" script)" ); // Throw the first exception. throw; } interp.resetResult(); } } if ( (System.Object)pkg.version == null ) { sbuf = new StringBuilder(); sbuf.Append( "can't find package " + pkgName ); if ( (System.Object)version != null ) { sbuf.Append( " " + version ); } throw new TclException( interp, sbuf.ToString() ); } // At this point we know that the package is present. Make sure that the // provided version meets the current requirement. if ( (System.Object)version == null ) { return pkg.version; } result = compareVersions( pkg.version, version, vsres ); if ( ( vsres.satisfies && !exact ) || ( result == 0 ) ) { return pkg.version; } // If we have a version conflict we throw a TclException. throw new TclException( interp, "version conflict for package \"" + pkgName + "\": have " + pkg.version + ", need " + version ); }
internal static void eval( Interp interp, Interp slaveInterp, int objIx, TclObject[] objv ) { TCL.CompletionCode result; slaveInterp.preserve(); slaveInterp.allowExceptions(); try { if ( objIx + 1 == objv.Length ) { slaveInterp.eval( objv[objIx], 0 ); } else { TclObject obj = TclList.newInstance(); for ( int ix = objIx; ix < objv.Length; ix++ ) { TclList.append( interp, obj, objv[ix] ); } obj.preserve(); slaveInterp.eval( obj, 0 ); obj.release(); } result = slaveInterp.returnCode; } catch ( TclException e ) { result = e.getCompletionCode(); } slaveInterp.release(); interp.transferResult( slaveInterp, result ); }
/// <summary> See Tcl user documentation for details.</summary> /// <exception cref=""> TclException If incorrect number of arguments. /// </exception> public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv) { int i; bool value; i = 1; while (true) { /* * At this point in the loop, argv and argc refer to an * expression to test, either for the main expression or * an expression following an "elseif". The arguments * after the expression must be "then" (optional) and a * script to execute if the expression is true. */ if (i >= argv.Length) { throw new TclException(interp, "wrong # args: no expression after \"" + argv[i - 1] + "\" argument"); } try { value = interp.expr.evalBoolean(interp, argv[i].ToString()); } catch (TclException e) { switch (e.getCompletionCode()) { case TCL.CompletionCode.ERROR: interp.addErrorInfo("\n (\"if\" test expression)"); break; } throw ; } i++; if ((i < argv.Length) && (argv[i].ToString().Equals("then"))) { i++; } if (i >= argv.Length) { throw new TclException(interp, "wrong # args: no script following \"" + argv[i - 1] + "\" argument"); } if (value) { try { interp.eval(argv[i], 0); } catch (TclException e) { switch (e.getCompletionCode()) { case TCL.CompletionCode.ERROR: interp.addErrorInfo("\n (\"if\" then script line " + interp.errorLine + ")"); break; } throw ; } return TCL.CompletionCode.RETURN; } /* * The expression evaluated to false. Skip the command, then * see if there is an "else" or "elseif" clause. */ i++; if (i >= argv.Length) { interp.resetResult(); return TCL.CompletionCode.RETURN; } if (argv[i].ToString().Equals("elseif")) { i++; continue; } break; } /* * Couldn't find a "then" or "elseif" clause to execute. * Check now for an "else" clause. We know that there's at * least one more argument when we get here. */ if (argv[i].ToString().Equals("else")) { i++; if (i >= argv.Length) { throw new TclException(interp, "wrong # args: no script following \"else\" argument"); } else if (i != (argv.Length - 1)) { throw new TclException(interp, "wrong # args: extra words after \"else\" clause in " + "\"if\" command"); } } try { interp.eval(argv[i], 0); } catch (TclException e) { switch (e.getCompletionCode()) { case TCL.CompletionCode.ERROR: interp.addErrorInfo("\n (\"if\" else script line " + interp.errorLine + ")"); break; } throw ; } return TCL.CompletionCode.RETURN; }
public void traceProc(Interp interp, string part1, string part2, TCL.VarFlag flags) { if (((this.flags & flags) != 0) && ((flags & TCL.VarFlag.INTERP_DESTROYED) == 0)) { System.Text.StringBuilder sbuf = new System.Text.StringBuilder(command); try { Util.appendElement(interp, sbuf, part1); if ((System.Object) part2 != null) { Util.appendElement(interp, sbuf, part2); } else { Util.appendElement(interp, sbuf, ""); } if ((flags & TCL.VarFlag.TRACE_READS) != 0) { Util.appendElement(interp, sbuf, "r"); } else if ((flags & TCL.VarFlag.TRACE_WRITES) != 0) { Util.appendElement(interp, sbuf, "w"); } else if ((flags & TCL.VarFlag.TRACE_UNSETS) != 0) { Util.appendElement(interp, sbuf, "u"); } } catch (TclException e) { throw new TclRuntimeError("unexpected TclException: " + e.Message,e); } // Execute the command. interp.eval(sbuf.ToString(), 0); } }
/// <summary> Executes a "case" statement. See Tcl user /// documentation for details. /// /// </summary> /// <param name="interp">the current interpreter. /// </param> /// <param name="argv">command arguments. /// </param> /// <exception cref=""> TclException If incorrect number of arguments. /// </exception> public TCL.CompletionCode cmdProc( Interp interp, TclObject[] argv ) { if ( argv.Length < 3 ) { throw new TclNumArgsException( interp, 1, argv, "string ?in? patList body ... ?default body?" ); } int i; int body; TclObject[] caseArgv; string inString; inString = argv[1].ToString(); caseArgv = argv; body = -1; if ( argv[2].ToString().Equals( "in" ) ) { i = 3; } else { i = 2; } /* * If all of the pattern/command pairs are lumped into a single * argument, split them out again. */ if ( argv.Length - i == 1 ) { caseArgv = TclList.getElements( interp, argv[i] ); i = 0; } { for ( ; i < caseArgv.Length; i += 2 ) { int j; if ( i == ( caseArgv.Length - 1 ) ) { throw new TclException( interp, "extra case pattern with no body" ); } /* * Check for special case of single pattern (no list) with * no backslash sequences. */ string caseString = caseArgv[i].ToString(); int len = caseString.Length; for ( j = 0; j < len; j++ ) { char c = caseString[j]; if ( System.Char.IsWhiteSpace( c ) || ( c == '\\' ) ) { break; } } if ( j == len ) { if ( caseString.Equals( "default" ) ) { body = i + 1; } if ( Util.stringMatch( inString, caseString ) ) { body = i + 1; goto match_loop_brk; } continue; } /* * Break up pattern lists, then check each of the patterns * in the list. */ int numPats = TclList.getLength( interp, caseArgv[i] ); for ( j = 0; j < numPats; j++ ) { if ( Util.stringMatch( inString, TclList.index( interp, caseArgv[i], j ).ToString() ) ) { body = i + 1; goto match_loop_brk; } } } } match_loop_brk: ; if ( body != -1 ) { try { interp.eval( caseArgv[body], 0 ); } catch ( TclException e ) { if ( e.getCompletionCode() == TCL.CompletionCode.ERROR ) { interp.addErrorInfo( "\n (\"" + caseArgv[body - 1] + "\" arm line " + interp.errorLine + ")" ); } throw; } } return TCL.CompletionCode.RETURN; }
public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv) { int i, mode, body; bool matched; string inString; TclObject[] switchArgv = null; mode = EXACT; for (i = 1; i < argv.Length; i++) { if (!argv[i].ToString().StartsWith("-")) { break; } int opt = TclIndex.get(interp, argv[i], validCmds, "option", 1); if (opt == LAST) { i++; break; } else if (opt > LAST) { throw new TclException(interp, "SwitchCmd.cmdProc: bad option " + opt + " index to validCmds"); } else { mode = opt; } } if (argv.Length - i < 2) { throw new TclNumArgsException(interp, 1, argv, "?switches? string pattern body ... ?default body?"); } inString = argv[i].ToString(); i++; // If all of the pattern/command pairs are lumped into a single // argument, split them out again. if (argv.Length - i == 1) { switchArgv = TclList.getElements(interp, argv[i]); i = 0; } else { switchArgv = argv; } for (; i < switchArgv.Length; i += 2) { if (i == (switchArgv.Length - 1)) { throw new TclException(interp, "extra switch pattern with no body"); } // See if the pattern matches the string. matched = false; string pattern = switchArgv[i].ToString(); if ((i == switchArgv.Length - 2) && pattern.Equals("default")) { matched = true; } else { switch (mode) { case EXACT: matched = inString.Equals(pattern); break; case GLOB: matched = Util.stringMatch(inString, pattern); break; case REGEXP: matched = Util.regExpMatch(interp, inString, switchArgv[i]); break; } } if (!matched) { continue; } // We've got a match. Find a body to execute, skipping bodies // that are "-". for (body = i + 1; ; body += 2) { if (body >= switchArgv.Length) { throw new TclException(interp, "no body specified for pattern \"" + switchArgv[i] + "\""); } if (!switchArgv[body].ToString().Equals("-")) { break; } } try { interp.eval(switchArgv[body], 0); return TCL.CompletionCode.RETURN; } catch (TclException e) { if (e.getCompletionCode() == TCL.CompletionCode.ERROR) { interp.addErrorInfo("\n (\"" + switchArgv[i] + "\" arm line " + interp.errorLine + ")"); } throw ; } } // Nothing matched: return nothing. return TCL.CompletionCode.RETURN; }
/// <summary> Tcl_ForeachObjCmd -> ForeachCmd.cmdProc /// /// This procedure is invoked to process the "foreach" Tcl command. /// See the user documentation for details on what it does. /// /// </summary> /// <param name="interp">the current interpreter. /// </param> /// <param name="objv">command arguments. /// </param> /// <exception cref=""> TclException if script causes error. /// </exception> public TCL.CompletionCode cmdProc(Interp interp, TclObject[] objv) { if (objv.Length < 4 || (objv.Length % 2) != 0) { throw new TclNumArgsException(interp, 1, objv, "varList list ?varList list ...? command"); } // foreach {n1 n2} {1 2 3 4} {n3} {1 2} {puts $n1-$n2-$n3} // name[0] = {n1 n2} value[0] = {1 2 3 4} // name[1] = {n3} value[0] = {1 2} TclObject[] name = new TclObject[(objv.Length - 2) / 2]; TclObject[] value = new TclObject[(objv.Length - 2) / 2]; int c, i, j, base_; int maxIter = 0; TclObject command = objv[objv.Length - 1]; bool done = false; for (i = 0; i < objv.Length - 2; i += 2) { int x = i / 2; name[x] = objv[i + 1]; value[x] = objv[i + 2]; int nSize = TclList.getLength(interp, name[x]); int vSize = TclList.getLength(interp, value[x]); if (nSize == 0) { throw new TclException(interp, "foreach varlist is empty"); } int iter = (vSize + nSize - 1) / nSize; if (maxIter < iter) { maxIter = iter; } } for (c = 0; !done && c < maxIter; c++) { // Set up the variables for (i = 0; i < objv.Length - 2; i += 2) { int x = i / 2; int nSize = TclList.getLength(interp, name[x]); base_ = nSize * c; for (j = 0; j < nSize; j++) { // Test and see if the name variable is an array. Var[] result = Var.lookupVar(interp, name[x].ToString(), null, 0, null, false, false); Var var = null; if (result != null) { if (result[1] != null) { var = result[1]; } else { var = result[0]; } } try { if (base_ + j >= TclList.getLength(interp, value[x])) { interp.setVar(TclList.index(interp, name[x], j), TclString.newInstance(""), 0); } else { interp.setVar(TclList.index(interp, name[x], j), TclList.index(interp, value[x], base_ + j), 0); } } catch (TclException e) { throw new TclException(interp, "couldn't set loop variable: \"" + TclList.index(interp, name[x], j) + "\""); } } } // Execute the script try { interp.eval(command, 0); } catch (TclException e) { switch (e.getCompletionCode()) { case TCL.CompletionCode.BREAK: done = true; break; case TCL.CompletionCode.CONTINUE: continue; case TCL.CompletionCode.ERROR: interp.addErrorInfo("\n (\"foreach\" body line " + interp.errorLine + ")"); throw ; default: throw ; } } } interp.resetResult(); return TCL.CompletionCode.RETURN; }
/* *---------------------------------------------------------------------- * * NamespaceInscopeCmd -> inscopeCmd * * Invoked to implement the "namespace inscope" command that executes a * script in the context of a particular namespace. This command is not * expected to be used directly by programmers; calls to it are * generated implicitly when programs use "namespace code" commands * to register callback scripts. Handles the following syntax: * * namespace inscope name arg ?arg...? * * The "namespace inscope" command is much like the "namespace eval" * command except that it has lappend semantics and the namespace must * already exist. It treats the first argument as a list, and appends * any arguments after the first onto the end as proper list elements. * For example, * * namespace inscope ::foo a b c d * * is equivalent to * * namespace eval ::foo [concat a [list b c d]] * * This lappend semantics is important because many callback scripts * are actually prefixes. * * Results: * Returns if successful, raises TclException if something goes wrong. * * Side effects: * Returns a result in the Tcl interpreter's result object. * *---------------------------------------------------------------------- */ private static void inscopeCmd(Interp interp, TclObject[] objv) { Namespace namespace_Renamed; CallFrame frame; int i, result; if (objv.Length < 4) { throw new TclNumArgsException(interp, 2, objv, "name arg ?arg...?"); } // Resolve the namespace reference. namespace_Renamed = getNamespaceFromObj(interp, objv[2]); if (namespace_Renamed == null) { throw new TclException(interp, "unknown namespace \"" + objv[2].ToString() + "\" in inscope namespace command"); } // Make the specified namespace the current namespace. frame = interp.newCallFrame(); pushCallFrame(interp, frame, namespace_Renamed, false); // Execute the command. If there is just one argument, just treat it as // a script and evaluate it. Otherwise, create a list from the arguments // after the first one, then concatenate the first argument and the list // of extra arguments to form the command to evaluate. try { if (objv.Length == 4) { interp.eval(objv[3], 0); } else { TclObject[] concatObjv = new TclObject[2]; TclObject list; string cmd; list = TclList.newInstance(); for (i = 4; i < objv.Length; i++) { try { TclList.append(interp, list, objv[i]); } catch (TclException ex) { list.release(); // free unneeded obj throw ex; } } concatObjv[0] = objv[3]; concatObjv[1] = list; cmd = Util.concat(0, 1, concatObjv); interp.eval(cmd); // do not pass TCL_EVAL_DIRECT, for compiler only list.release(); // we're done with the list object } } catch (TclException ex) { if (ex.getCompletionCode() == TCL.CompletionCode.ERROR) { interp.addErrorInfo("\n (in namespace inscope \"" + namespace_Renamed.fullName + "\" script line " + interp.errorLine + ")"); } throw ex; } finally { popCallFrame(interp); } return ; }
/* *---------------------------------------------------------------------- * * NamespaceEvalCmd -> evalCmd * * Invoked to implement the "namespace eval" command. Executes * commands in a namespace. If the namespace does not already exist, * it is created. Handles the following syntax: * * namespace eval name arg ?arg...? * * If more than one arg argument is specified, the command that is * executed is the result of concatenating the arguments together with * a space between each argument. * * Results: * Returns if successful, raises TclException if something goes wrong. * * Side effects: * Returns the result of the command in the interpreter's result * object. If anything goes wrong, this procedure returns an error * message as the result. * *---------------------------------------------------------------------- */ private static void evalCmd(Interp interp, TclObject[] objv) { Namespace namespace_Renamed; CallFrame frame; string cmd; string name; int length; if (objv.Length < 4) { throw new TclNumArgsException(interp, 2, objv, "name arg ?arg...?"); } // Try to resolve the namespace reference, caching the result in the // namespace object along the way. namespace_Renamed = getNamespaceFromObj(interp, objv[2]); // If the namespace wasn't found, try to create it. if (namespace_Renamed == null) { name = objv[2].ToString(); namespace_Renamed = createNamespace(interp, name, null); if (namespace_Renamed == null) { // FIXME : result hack, we get the interp result and throw it! throw new TclException(interp, interp.getResult().ToString()); } } // Make the specified namespace the current namespace and evaluate // the command(s). frame = interp.newCallFrame(); pushCallFrame(interp, frame, namespace_Renamed, false); try { if (objv.Length == 4) { interp.eval(objv[3], 0); } else { cmd = Util.concat(3, objv.Length, objv); // eval() will delete the object when it decrements its // refcount after eval'ing it. interp.eval(cmd); // do not pass TCL_EVAL_DIRECT, for compiler only } } catch (TclException ex) { if (ex.getCompletionCode() == TCL.CompletionCode.ERROR) { interp.addErrorInfo("\n (in namespace eval \"" + namespace_Renamed.fullName + "\" script line " + interp.errorLine + ")"); } throw ex; } finally { popCallFrame(interp); } return ; }