/// <summary>---------------------------------------------------------------------- /// /// disposeCmd -- /// /// Invoked when an object command for a slave interpreter is deleted; /// cleans up all state associated with the slave interpreter and destroys /// the slave interpreter. /// /// Results: /// None. /// /// Side effects: /// Cleans up all state associated with the slave interpreter and /// destroys the slave interpreter. /// /// ---------------------------------------------------------------------- /// </summary> public void Dispose() { // Unlink the slave from its master interpreter. SupportClass.HashtableRemove(masterInterp._slaveTable, path); // Set to null so that when the InterpInfo is cleaned up in the slave // it does not try to delete the command causing all sorts of grief. // See SlaveRecordDeleteProc(). interpCmd = null; if (slaveInterp != null) { slaveInterp.Dispose(); } }
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); } } } }