Beispiel #1
0
        internal void transferResult(Interp sourceInterp, TCL.CompletionCode result)
        {
            if (sourceInterp == this)
            {
                return;
            }

            if (result == TCL.CompletionCode.ERROR)
            {
                TclObject obj;

                // An error occurred, so transfer error information from the source
                // interpreter to the target interpreter.  Setting the flags tells
                // the target interp that it has inherited a partial traceback
                // chain, not just a simple error message.

                if (!sourceInterp._errAlreadyLogged)
                {
                    sourceInterp.AddErrorInfo("");
                }
                sourceInterp._errAlreadyLogged = true;

                ResetResult();

                obj = sourceInterp.GetVar("errorInfo", TCL.VarFlag.GLOBAL_ONLY);
                SetVar("errorInfo", obj, TCL.VarFlag.GLOBAL_ONLY);

                obj = sourceInterp.GetVar("errorCode", TCL.VarFlag.GLOBAL_ONLY);
                SetVar("errorCode", obj, TCL.VarFlag.GLOBAL_ONLY);

                _errInProgress = true;
                _errCodeSet = true;
            }

            _returnCode = result;
            SetResult(sourceInterp.GetResult());
            sourceInterp.ResetResult();

            if (result != TCL.CompletionCode.OK)
            {

                throw new TclException(this, GetResult().ToString(), result);
            }
        }
Beispiel #2
0
        /// <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;
        }
Beispiel #3
0
  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);
        }
      }
    }
  }