internal static ParseResult parseNestedCmd(Interp interp, string inString, int index, int length) { CharPointer script; TclObject obj; // Check for the easy case where the last character in the string is '['. if (index == length) { throw new TclException(interp, "missing close-bracket"); } script = new CharPointer(inString); script._index = index; interp._evalFlags |= Parser.TCL_BRACKET_TERM; Parser.eval2(interp, script._array, script._index, length - index, 0); obj = interp.GetResult(); obj.Preserve(); return(new ParseResult(obj, index + interp._termOffset + 1)); }
/// <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); }
public static int Tcl_EvalObjEx(Interp interp, TclObject tobj, int flags) { try { interp.Eval(tobj, flags); return(0); } catch (TclException e) { if (e.GetCompletionCode() == TCL.CompletionCode.RETURN) { return(TCL_RETURN); } else if (e.GetCompletionCode() == TCL.CompletionCode.BREAK || interp.GetResult().ToString() == "invoked \"break\" outside of a loop") { return(TCL_BREAK); } else { return(TCL_ERROR); } }; }
/// <summary> Compares the order of two items in the array. /// /// </summary> /// <param name="obj1">first item. /// </param> /// <param name="obj2">second item. /// </param> /// <returns> 0 if they are equal, 1 if obj1 > obj2, -1 otherwise. /// /// </returns> /// <exception cref=""> TclException if an error occurs during sorting. /// </exception> private int compare(TclObject obj1, TclObject obj2) { int index; int code = 0; if (sortIndex != -1) { // The "-index" option was specified. Treat each object as a // list, extract the requested element from each list, and // compare the elements, not the lists. The special index "end" // is signaled here with a negative index (other than -1). TclObject obj; if (sortIndex < -1) { index = TclList.getLength(sortInterp, obj1) - 1; } else { index = sortIndex; } obj = TclList.index(sortInterp, obj1, index); if (obj == null) { throw new TclException(sortInterp, "element " + index + " missing from sublist \"" + obj1 + "\""); } obj1 = obj; if (sortIndex < -1) { index = TclList.getLength(sortInterp, obj2) - 1; } else { index = sortIndex; } obj = TclList.index(sortInterp, obj2, index); if (obj == null) { throw new TclException(sortInterp, "element " + index + " missing from sublist \"" + obj2 + "\""); } obj2 = obj; } switch (sortMode) { case ASCII: // ATK C# CompareTo use option // similar to -dictionary but a > A code = System.Globalization.CultureInfo.InvariantCulture.CompareInfo.Compare(obj1.ToString(), obj2.ToString(), System.Globalization.CompareOptions.Ordinal); // code = obj1.ToString().CompareTo(obj2.ToString()); break; case DICTIONARY: code = doDictionary(obj1.ToString(), obj2.ToString()); break; case INTEGER: try { int int1 = TclInteger.Get(sortInterp, obj1); int int2 = TclInteger.Get(sortInterp, obj2); if (int1 > int2) { code = 1; } else if (int2 > int1) { code = -1; } } catch (TclException e1) { sortInterp.AddErrorInfo("\n (converting list element from string to integer)"); throw e1; } break; case REAL: try { double f1 = TclDouble.Get(sortInterp, obj1); double f2 = TclDouble.Get(sortInterp, obj2); if (f1 > f2) { code = 1; } else if (f2 > f1) { code = -1; } } catch (TclException e2) { sortInterp.AddErrorInfo("\n (converting list element from string to real)"); throw e2; } break; case COMMAND: StringBuilder sbuf = new StringBuilder(sortCommand); Util.appendElement(sortInterp, sbuf, obj1.ToString()); Util.appendElement(sortInterp, sbuf, obj2.ToString()); try { sortInterp.Eval(sbuf.ToString(), 0); } catch (TclException e3) { sortInterp.AddErrorInfo("\n (user-defined comparison command)"); throw e3; } try { code = TclInteger.Get(sortInterp, sortInterp.GetResult()); } catch (TclException e) { sortInterp.ResetResult(); TclException e4 = new TclException(sortInterp, "comparison command returned non-numeric result"); throw e4; } break; default: throw new TclRuntimeError("Unknown sortMode " + sortMode); } if (sortIncreasing) { return(code); } else { return(-code); } }
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); } } } }
/// <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); }
public static string Tcl_GetStringResult(Interp interp) { return(interp.GetResult().ToString()); }
public static TclObject Tcl_GetObjResult(Interp interp) { TclObject toReturn = interp.GetResult(); return(toReturn); }