public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { bool debug; if (argv.Length == 2) { System.Diagnostics.Debug.WriteLine("getting value of \"" + argv[1].ToString() + "\""); interp.SetResult(interp.GetVar(argv[1], 0)); } else if (argv.Length == 3) { System.Diagnostics.Debug.WriteLine("setting value of \"" + argv[1].ToString() + "\" to \"" + argv[2].ToString() + "\""); interp.SetResult(interp.SetVar(argv[1], argv[2], 0)); } else { throw new TclNumArgsException(interp, 1, argv, "varName ?newValue?"); } return TCL.CompletionCode.RETURN; }
/// <summary> Called whenever the cmdProc wants to set an interp value. /// This method <ol> /// <li> verifies that there exisits a varName from the argv array, /// <li> that the variable either dosent exisit or is of type scalar /// <li> set the variable in interp if (1) and (2) are OK /// </ol> /// /// </summary> /// <param name="interp"> - the Tcl interpreter /// </param> /// <param name="argv"> - the argument array /// </param> /// <param name="argIndex">- the current index into the argv array /// </param> /// <param name="tobj"> - the TclObject that the varName equals /// /// </param> private static void testAndSetVar(Interp interp, TclObject[] argv, int argIndex, TclObject tobj) { if (argIndex < argv.Length) { try { interp.SetVar(argv[argIndex].ToString(), tobj, 0); } catch (TclException e) { throw new TclException(interp, "couldn't set variable \"" + argv[argIndex].ToString() + "\""); } } else { errorDiffVars(interp); } }
/// <summary> /// Tcl_LappendObjCmd -> LappendCmd.cmdProc /// /// This procedure is invoked to process the "lappend" Tcl command. /// See the user documentation for details on what it does. /// </summary> public TCL.CompletionCode CmdProc(Interp interp, TclObject[] objv) { TclObject varValue, newValue = null; int i;//int numElems, i, j; bool createdNewObj, createVar; if (objv.Length < 2) { throw new TclNumArgsException(interp, 1, objv, "varName ?value value ...?"); } if (objv.Length == 2) { try { newValue = interp.GetVar(objv[1], 0); } catch (TclException e) { // The variable doesn't exist yet. Just create it with an empty // initial value. varValue = TclList.NewInstance(); try { newValue = interp.SetVar(objv[1], varValue, 0); } finally { if (newValue == null) varValue.Release(); // free unneeded object } interp.ResetResult(); return TCL.CompletionCode.RETURN; } } else { // We have arguments to append. We used to call Tcl_SetVar2 to // append each argument one at a time to ensure that traces were run // for each append step. We now append the arguments all at once // because it's faster. Note that a read trace and a write trace for // the variable will now each only be called once. Also, if the // variable's old value is unshared we modify it directly, otherwise // we create a new copy to modify: this is "copy on write". createdNewObj = false; createVar = true; try { varValue = interp.GetVar(objv[1], 0); } catch (TclException e) { // We couldn't read the old value: either the var doesn't yet // exist or it's an array element. If it's new, we will try to // create it with Tcl_ObjSetVar2 below. // FIXME : not sure we even need this parse for anything! // If we do not need to parse could we at least speed it up a bit string varName; int nameBytes; varName = objv[1].ToString(); nameBytes = varName.Length; // Number of Unicode chars in string for (i = 0; i < nameBytes; i++) { if (varName[i] == '(') { i = nameBytes - 1; if (varName[i] == ')') { // last char is ')' => array ref createVar = false; } break; } } varValue = TclList.NewInstance(); createdNewObj = true; } // We only take this branch when the catch branch was not run if (createdNewObj == false && varValue.Shared) { varValue = varValue.duplicate(); createdNewObj = true; } // Insert the new elements at the end of the list. for (i = 2; i < objv.Length; i++) TclList.Append(interp, varValue, objv[i]); // No need to call varValue.invalidateStringRep() since it // is called during the TclList.append operation. // Now store the list object back into the variable. If there is an // error setting the new value, decrement its ref count if it // was new and we didn't create the variable. try { newValue = interp.SetVar(objv[1].ToString(), varValue, 0); } catch (TclException e) { if (createdNewObj && !createVar) { varValue.Release(); // free unneeded obj } throw; } } // Set the interpreter's object result to refer to the variable's value // object. interp.SetResult(newValue); return TCL.CompletionCode.RETURN; }
private static void getAndStoreStatData(Interp interp, string fileName, string varName) { FileInfo fileObj = FileUtil.getNewFileObj(interp, fileName); bool tmpBool; if (File.Exists(fileObj.FullName)) tmpBool = true; else tmpBool = Directory.Exists(fileObj.FullName); if (!tmpBool) { throw new TclPosixException(interp, TclPosixException.ENOENT, true, "could not read \"" + fileName + "\""); } try { int mtime = getMtime(interp, fileName, fileObj); TclObject mtimeObj = TclInteger.NewInstance(mtime); TclObject atimeObj = TclInteger.NewInstance(mtime); TclObject ctimeObj = TclInteger.NewInstance(mtime); interp.SetVar(varName, "atime", atimeObj, 0); interp.SetVar(varName, "ctime", ctimeObj, 0); interp.SetVar(varName, "mtime", mtimeObj, 0); } catch (System.Security.SecurityException e) { throw new TclException(interp, e.Message); } catch (TclException e) { throw new TclException(interp, "can't set \"" + varName + "(dev)\": variable isn't array"); } try { TclObject sizeObj = TclInteger.NewInstance((int)SupportClass.FileLength(fileObj)); interp.SetVar(varName, "size", sizeObj, 0); } catch (System.Exception e) { // Do nothing. } try { TclObject typeObj = TclString.NewInstance(getType(interp, fileName, fileObj)); interp.SetVar(varName, "type", typeObj, 0); } catch (System.Exception e) { } try { TclObject uidObj = TclBoolean.newInstance(isOwner(interp, fileObj)); interp.SetVar(varName, "uid", uidObj, 0); } catch (TclException e) { // Do nothing. } }
internal static Interp create( Interp interp, TclObject path, bool safe ) { Interp masterInterp; string pathString; TclObject[] objv = TclList.getElements( interp, path ); if ( objv.Length < 2 ) { masterInterp = interp; pathString = path.ToString(); } else { TclObject obj = TclList.NewInstance(); TclList.insert( interp, obj, 0, objv, 0, objv.Length - 2 ); masterInterp = InterpCmd.getInterp( interp, obj ); pathString = objv[objv.Length - 1].ToString(); } if ( !safe ) { safe = masterInterp._isSafe; } if ( masterInterp._slaveTable.ContainsKey( pathString ) ) { throw new TclException( interp, "interpreter named \"" + pathString + "\" already exists, cannot create" ); } Interp slaveInterp = new Interp(); InterpSlaveCmd slave = new InterpSlaveCmd(); slaveInterp._slave = slave; slaveInterp.SetAssocData( "InterpSlaveCmd", slave ); slave.masterInterp = masterInterp; slave.path = pathString; slave.slaveInterp = slaveInterp; masterInterp.CreateCommand( pathString, slaveInterp._slave ); slaveInterp._slave.interpCmd = NamespaceCmd.findCommand( masterInterp, pathString, null, 0 ); SupportClass.PutElement( masterInterp._slaveTable, pathString, slaveInterp._slave ); slaveInterp.SetVar( "tcl_interactive", "0", TCL.VarFlag.GLOBAL_ONLY ); // Inherit the recursion limit. slaveInterp._maxNestingDepth = masterInterp._maxNestingDepth; if ( safe ) { try { makeSafe( slaveInterp ); } catch ( TclException e ) { SupportClass.WriteStackTrace( e, Console.Error ); } } else { //Tcl_Init(slaveInterp); } return slaveInterp; }
public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { bool nocase = false; bool indices = false; try { int i = 1; while (argv[i].ToString().StartsWith("-")) { int index = TclIndex.Get(interp, argv[i], validOpts, "switch", 0); i++; switch (index) { case OPT_INDICES: { indices = true; break; } case OPT_NOCASE: { nocase = true; break; } case OPT_LAST: { goto opts_brk; } } } opts_brk: ; TclObject exp = TclString.NewInstance(argv[i++].ToString().Replace("\\d", "[0-9]")); string inString = argv[i++].ToString(); int matches = argv.Length - i; Regexp r = TclRegexp.compile(interp, exp, nocase); int[] args = new int[matches * 2]; bool matched = r.match(inString, args); if (matched) { for (int match = 0; i < argv.Length; i++) { TclObject obj; int start = args[match++]; int end = args[match++]; if (indices) { if (end >= 0) { end--; } obj = TclList.NewInstance(); TclList.Append(interp, obj, TclInteger.NewInstance(start)); TclList.Append(interp, obj, TclInteger.NewInstance(end)); } else { string range = (start >= 0) ? inString.Substring(start, (end) - (start)) : ""; obj = TclString.NewInstance(range); } try { interp.SetVar(argv[i].ToString(), obj, 0); } catch (TclException e) { throw new TclException(interp, "couldn't set variable \"" + argv[i] + "\""); } } } interp.SetResult(matched); } catch (System.IndexOutOfRangeException e) { throw new TclNumArgsException(interp, 1, argv, "?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?"); } return TCL.CompletionCode.RETURN; }
public static void Main(string[] args) { // Array of command-line argument strings. { string fileName = null; // Create the interpreter. This will also create the built-in // Tcl commands. Interp interp = new Interp(); // Make command-line arguments available in the Tcl variables "argc" // and "argv". If the first argument doesn't start with a "-" then // strip it off and use it as the name of a script file to process. // We also set the argv0 and TCL.Tcl_interactive vars here. if ((args.Length > 0) && !(args[0].StartsWith("-"))) { fileName = args[0]; } TclObject argv = TclList.NewInstance(); argv.Preserve(); try { int i = 0; int argc = args.Length; if ((System.Object)fileName == null) { interp.SetVar("argv0", "tcl.lang.Shell", TCL.VarFlag.GLOBAL_ONLY); interp.SetVar("tcl_interactive", "1", TCL.VarFlag.GLOBAL_ONLY); } else { interp.SetVar("argv0", fileName, TCL.VarFlag.GLOBAL_ONLY); interp.SetVar("tcl_interactive", "0", TCL.VarFlag.GLOBAL_ONLY); i++; argc--; } for (; i < args.Length; i++) { TclList.Append(interp, argv, TclString.NewInstance(args[i])); } interp.SetVar("argv", argv, TCL.VarFlag.GLOBAL_ONLY); interp.SetVar("argc", System.Convert.ToString(argc), TCL.VarFlag.GLOBAL_ONLY); } catch (TclException e) { throw new TclRuntimeError("unexpected TclException: " + e.Message); } finally { argv.Release(); } // Normally we would do application specific initialization here. // However, that feature is not currently supported. // If a script file was specified then just source that file // and quit. Console.WriteLine("C#-TCL version " + Assembly.GetExecutingAssembly().GetName().Version.ToString()); Console.WriteLine("=============================================================="); Console.WriteLine(""); if ((System.Object)fileName != null) { try { interp.evalFile(fileName); } catch (TclException e) { TCL.CompletionCode code = e.GetCompletionCode(); if (code == TCL.CompletionCode.RETURN) { code = interp.updateReturnInfo(); if (code != TCL.CompletionCode.OK) { System.Console.Error.WriteLine("command returned bad code: " + code); if (Tcl.Lang.ConsoleThread.debug) System.Diagnostics.Debug.WriteLine("command returned bad code: " + code); } } else if (code == TCL.CompletionCode.ERROR) { System.Console.Error.WriteLine(interp.GetResult().ToString()); if (Tcl.Lang.ConsoleThread.debug) System.Diagnostics.Debug.WriteLine(interp.GetResult().ToString()); System.Diagnostics.Debug.Assert(false, interp.GetResult().ToString()); } else { System.Console.Error.WriteLine("command returned bad code: " + code); if (Tcl.Lang.ConsoleThread.debug) System.Diagnostics.Debug.WriteLine("command returned bad code: " + code); } } // Note that if the above interp.evalFile() returns the main // thread will exit. This may bring down the VM and stop // the execution of Tcl. // // If the script needs to handle events, it must call // vwait or do something similar. // // Note that the script can create AWT widgets. This will // start an AWT event handling thread and keep the VM up. However, // the interpreter thread (the same as the main thread) would // have exited and no Tcl scripts can be executed. interp.Dispose(); System.Environment.Exit(0); } if ((System.Object)fileName == null) { // We are running in interactive mode. Start the ConsoleThread // that loops, grabbing stdin and passing it to the interp. ConsoleThread consoleThread = new ConsoleThread(interp); consoleThread.IsBackground = true; consoleThread.Start(); // Loop forever to handle user input events in the command line. Notifier notifier = interp.GetNotifier(); while (true) { // process events until "exit" is called. notifier.doOneEvent(TCL.ALL_EVENTS); } } } }