示例#1
0
文件: FlushCmd.cs 项目: ekicyou/pasta
        /// <summary> This procedure is invoked to process the "flush" 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>

        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            Channel chan; /* The channel being operated on this method */

            if (argv.Length != 2)
            {
                throw new TclNumArgsException(interp, 1, argv, "channelId");
            }


            chan = TclIO.getChannel(interp, argv[1].ToString());
            if (chan == null)
            {
                throw new TclException(interp, "can not find channel named \"" + argv[1].ToString() + "\"");
            }

            try
            {
                chan.flush(interp);
            }
            catch (IOException e)
            {
                throw new TclRuntimeError("FlushCmd.cmdProc() Error: IOException when flushing " + chan.ChanName);
            }
            return(TCL.CompletionCode.RETURN);
        }
示例#2
0
        /// <summary> This procedure is invoked to process the "eof" 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>

        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            Channel chan; /* The channel being operated on this method */

            if (argv.Length != 2)
            {
                throw new TclNumArgsException(interp, 1, argv, "channelId");
            }


            chan = TclIO.getChannel(interp, argv[1].ToString());
            if (chan == null)
            {
                throw new TclException(interp, "can not find channel named \"" + argv[1].ToString() + "\"");
            }

            if (chan.eof())
            {
                interp.setResult(TclInteger.newInstance(1));
            }
            else
            {
                interp.setResult(TclInteger.newInstance(0));
            }
            return(TCL.CompletionCode.RETURN);
        }
示例#3
0
文件: SeekCmd.cs 项目: ekicyou/pasta
        /// <summary> This procedure is invoked to process the "seek" Tcl command.
        /// See the user documentation for details on what it does.
        /// </summary>

        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            Channel chan; /* The channel being operated on this method */
            int     mode; /* Stores the search mode, either beg, cur or end
                           * of file.  See the TclIO class for more info */

            if (argv.Length != 3 && argv.Length != 4)
            {
                throw new TclNumArgsException(interp, 1, argv, "channelId offset ?origin?");
            }

            // default is the beginning of the file

            mode = TclIO.SEEK_SET;
            if (argv.Length == 4)
            {
                int index = TclIndex.get(interp, argv[3], validOrigins, "origin", 0);

                switch (index)
                {
                case OPT_START:
                {
                    mode = TclIO.SEEK_SET;
                    break;
                }

                case OPT_CURRENT:
                {
                    mode = TclIO.SEEK_CUR;
                    break;
                }

                case OPT_END:
                {
                    mode = TclIO.SEEK_END;
                    break;
                }
                }
            }


            chan = TclIO.getChannel(interp, argv[1].ToString());
            if (chan == null)
            {
                throw new TclException(interp, "can not find channel named \"" + argv[1].ToString() + "\"");
            }
            long offset = TclInteger.get(interp, argv[2]);

            try
            {
                chan.seek(interp, offset, mode);
            }
            catch (IOException e)
            {
                // FIXME: Need to figure out Tcl specific error conditions.
                // Should we also wrap an IOException in a ReflectException?
                throw new TclRuntimeError("SeekCmd.cmdProc() Error: IOException when seeking " + chan.ChanName + ":" + e.Message);
            }
            return(TCL.CompletionCode.RETURN);
        }
示例#4
0
        /// <summary> This procedure is invoked to process the "tell" 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>

        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            Channel chan;             /* The channel being operated on this method */

            if (argv.Length != 2)
            {
                throw new TclNumArgsException(interp, 1, argv, "channelId");
            }


            chan = TclIO.getChannel(interp, argv[1].ToString());
            if (chan == null)
            {
                throw new TclException(interp, "can not find channel named \"" + argv[1].ToString() + "\"");
            }

            try
            {
                interp.setResult(TclInteger.newInstance((int)chan.tell()));
            }
            catch (System.IO.IOException e)
            {
                throw new TclException(interp, "Error in TellCmd");
            }
            return(TCL.CompletionCode.RETURN);
        }
示例#5
0
        /// <summary> Constructor for making SocketChannel objects from connections
        /// made to a ServerSocket.
        ///
        /// </summary>

        public SocketChannel(Interp interp, System.Net.Sockets.TcpClient s)
        {
            this.mode = TclIO.RDWR;
            this.sock = s;

            ChanName = TclIO.getNextDescriptor(interp, "sock");
        }
示例#6
0
        internal ConsoleThread(Interp i)
        {
            Name   = "ConsoleThread";
            interp = i;
            sbuf   = new System.Text.StringBuilder(100);

            out_Renamed = TclIO.getStdChannel(StdChannel.STDOUT);
            err         = TclIO.getStdChannel(StdChannel.STDERR);
        }
示例#7
0
        /// <summary> This procedure is invoked to process the "gets" 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>

        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            bool      writeToVar = false; // If true write to var passes as arg
            string    varName    = "";    // The variable to write value to
            Channel   chan;               // The channel being operated on
            int       lineLen;
            TclObject line;

            if ((argv.Length < 2) || (argv.Length > 3))
            {
                throw new TclNumArgsException(interp, 1, argv, "channelId ?varName?");
            }

            if (argv.Length == 3)
            {
                writeToVar = true;

                varName = argv[2].ToString();
            }


            chan = TclIO.getChannel(interp, argv[1].ToString());
            if (chan == null)
            {
                throw new TclException(interp, "can not find channel named \"" + argv[1].ToString() + "\"");
            }

            try
            {
                line    = TclString.newInstance(new StringBuilder(64));
                lineLen = chan.read(interp, line, TclIO.READ_LINE, 0);
                if (lineLen < 0)
                {
                    // FIXME: Need more specific posix error codes!
                    if (!chan.eof() && !chan.isBlocked(interp))
                    {
                        throw new TclPosixException(interp, TclPosixException.EIO, true, "error reading \"" + argv[1].ToString() + "\"");
                    }
                    lineLen = -1;
                }
                if (writeToVar)
                {
                    interp.setVar(varName, line, 0);
                    interp.setResult(lineLen);
                }
                else
                {
                    interp.setResult(line);
                }
            }
            catch (IOException e)
            {
                throw new TclRuntimeError("GetsCmd.cmdProc() Error: IOException when getting " + chan.ChanName + ": " + e.Message);
            }
            return(TCL.CompletionCode.RETURN);
        }
        /// <summary> Open a file with the read/write permissions determined by modeFlags.
        /// This method must be called before any other methods will function
        /// properly.
        ///
        /// </summary>
        /// <param name="interp">currrent interpreter.
        /// </param>
        /// <param name="fileName">the absolute path or name of file in the current
        /// directory to open
        /// </param>
        /// <param name="modeFlags">modes used to open a file for reading, writing, etc
        /// </param>
        /// <returns> the channelId of the file.
        /// </returns>
        /// <exception cref=""> TclException is thrown when the modeFlags try to open
        /// a file it does not have permission for or if the
        /// file dosent exist and CREAT wasnt specified.
        /// </exception>
        /// <exception cref=""> IOException is thrown when an IO error occurs that was not
        /// correctly tested for.  Most cases should be caught.
        /// </exception>

        internal string open(Interp interp, string fileName, int modeFlags)
        {
            mode = modeFlags;
            System.IO.FileInfo fileObj    = FileUtil.getNewFileObj(interp, fileName);
            FileMode           fileMode   = 0;
            FileAccess         fileAccess = 0;

            if (((modeFlags & TclIO.CREAT) != 0) && ((modeFlags & TclIO.EXCL) != 0))
            {
                fileMode = FileMode.CreateNew;
            }
            else if ((modeFlags & TclIO.CREAT) != 0)
            {
                fileMode = FileMode.Create;
            }
            else
            {
                fileMode = FileMode.Open;
            }
            if ((modeFlags & TclIO.TRUNC) != 0)
            {
                fileMode = fileMode & FileMode.Truncate;
            }
            if ((modeFlags & TclIO.APPEND) != 0)
            {
                fileMode = fileMode & FileMode.Append;
            }

            if ((modeFlags & TclIO.RDWR) != 0)
            {
                fileAccess = FileAccess.ReadWrite;
            }
            else if ((modeFlags & TclIO.RDONLY) != 0)
            {
                fileAccess = FileAccess.Read;
            }
            else if ((modeFlags & TclIO.WRONLY) != 0)
            {
                fileAccess = FileAccess.Write;
            }
            else
            {
                throw new TclRuntimeError("FileChannel.java: invalid mode value");
            }

            file = new FileStream(fileObj.FullName, fileMode, fileAccess, FileShare.ReadWrite);

            string fName = TclIO.getNextDescriptor(interp, "file");

            ChanName = fName;
            //Console.Out.WriteLine("",file.Name);
            return(fName);
        }
示例#9
0
        /// <summary> Constructor - creates a new SocketChannel object with the given
        /// options. Also creates an underlying Socket object, and Input and
        /// Output Streams.
        ///
        /// </summary>

        public SocketChannel(Interp interp, int mode, string localAddr, int localPort, bool async, string address, int port)
        {
            System.Net.IPAddress localAddress = null;
            System.Net.IPAddress addr         = null;

            if (async)
            {
                throw new TclException(interp, "Asynchronous socket connection not " + "currently implemented");
            }

            // Resolve addresses
            if (!localAddr.Equals(""))
            {
                try
                {
                    localAddress = System.Net.Dns.GetHostByName(localAddr).AddressList[0];
                }
                catch (System.Exception e)
                {
                    throw new TclException(interp, "host unknown: " + localAddr);
                }
            }

            try
            {
                addr = System.Net.Dns.GetHostByName(address).AddressList[0];
            }
            catch (System.Exception e)
            {
                throw new TclException(interp, "host unknown: " + address);
            }


            // Set the mode of this socket.
            this.mode = mode;

            // Create the Socket object

//			if ((localAddress != null) && (localPort != 0))
//			{
//
//				sock = new Socket(addr, port, localAddress, localPort);
//			}
//			else
            sock = new System.Net.Sockets.TcpClient(addr.ToString(), port);

            // If we got this far, then the socket has been created.
            // Create the channel name
            ChanName = TclIO.getNextDescriptor(interp, "sock");
        }
        public void  disposeAssocData(Interp interp)
        // Current interpreter.
        {
            // There shouldn't be any commands left.

            if (!(interp.slaveTable.Count == 0))
            {
                System.Console.Error.WriteLine("InterpInfoDeleteProc: still exist commands");
            }
            interp.slaveTable = null;

            // Tell any interps that have aliases to this interp that they should
            // delete those aliases.  If the other interp was already dead, it
            // would have removed the target record already.

            // TODO ATK
            foreach (WrappedCommand slaveCmd in new ArrayList(interp.targetTable.Keys))
            {
                Interp slaveInterp = (Interp)interp.targetTable[slaveCmd];
                slaveInterp.deleteCommandFromToken(slaveCmd);
            }
            interp.targetTable = null;

            if (interp.interpChanTable != null)
            {
                foreach (Channel channel in new ArrayList(interp.interpChanTable.Values))
                {
                    TclIO.unregisterChannel(interp, channel);
                }
            }

            if (interp.slave.interpCmd != null)
            {
                // Tcl_DeleteInterp() was called on this interpreter, rather
                // "interp delete" or the equivalent deletion of the command in the
                // master.  First ensure that the cleanup callback doesn't try to
                // delete the interp again.

                interp.slave.slaveInterp = null;
                interp.slave.masterInterp.deleteCommandFromToken(interp.slave.interpCmd);
            }

            // There shouldn't be any aliases left.

            if (!(interp.aliasTable.Count == 0))
            {
                System.Console.Error.WriteLine("InterpInfoDeleteProc: still exist aliases");
            }
            interp.aliasTable = null;
        }
示例#11
0
        /// <summary> This procedure is invoked to process the "close" 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>

        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            Channel chan; /* The channel being operated on this method */

            if (argv.Length != 2)
            {
                throw new TclNumArgsException(interp, 1, argv, "channelId");
            }


            chan = TclIO.getChannel(interp, argv[1].ToString());
            if (chan == null)
            {
                throw new TclException(interp, "can not find channel named \"" + argv[1].ToString() + "\"");
            }

            TclIO.unregisterChannel(interp, chan);
            return(TCL.CompletionCode.RETURN);
        }
 public static void Tcl_UnregisterChannel(Interp interp, Channel chan)
 {
     TclIO.unregisterChannel(interp, chan);
 }
示例#13
0
        /// <summary> Prints the given string to a channel. See Tcl user
        /// documentation for details.
        ///
        /// </summary>
        /// <param name="interp">the current interpreter.
        /// </param>
        /// <param name="argv">command arguments.
        /// </param>

        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            Channel chan;        // The channel being operated on this method
            string  channelId;   // String containing the key to chanTable
            string  arg;         // Argv[i] converted to a string
            int     i       = 1; // Index to the next arg in argv
            bool    newline = true;

            // Indicates to print a newline in result


            if ((argv.Length >= 2) && (argv[1].ToString().Equals("-nonewline")))
            {
                newline = false;
                i++;
            }
            if ((i < argv.Length - 3) || (i >= argv.Length))
            {
                throw new TclNumArgsException(interp, 1, argv, "?-nonewline? ?channelId? string");
            }

            // The code below provides backwards compatibility with an old
            // form of the command that is no longer recommended or documented.

            if (i == (argv.Length - 3))
            {
                arg = argv[i + 2].ToString();
                if (!arg.Equals("nonewline"))
                {
                    throw new TclException(interp, "bad argument \"" + arg + "\": should be \"nonewline\"");
                }
                newline = false;
            }

            if (i == (argv.Length - 1))
            {
                channelId = "stdout";
            }
            else
            {
                channelId = argv[i].ToString();
                i++;
            }

            if (i != (argv.Length - 1))
            {
                throw new TclNumArgsException(interp, 1, argv, "?-nonewline? ?channelId? string");
            }

            chan = TclIO.getChannel(interp, channelId);
            if (chan == null)
            {
                throw new TclException(interp, "can not find channel named \"" + channelId + "\"");
            }

            try
            {
                if (newline)
                {
                    chan.write(interp, argv[i]);
                    chan.write(interp, "\n");
                }
                else
                {
                    chan.write(interp, argv[i]);
                }
            }
            catch (IOException e)
            {
                throw new TclRuntimeError("PutsCmd.cmdProc() Error: IOException when putting " + chan.ChanName);
            }
            return(TCL.CompletionCode.RETURN);
        }
        private static void  makeSafe(Interp interp)
        {
            Channel chan;             // Channel to remove from safe interpreter.

            interp.hideUnsafeCommands();

            interp.isSafe = true;

            //  Unsetting variables : (which should not have been set
            //  in the first place, but...)

            // No env array in a safe slave.

            try
            {
                interp.unsetVar("env", TCL.VarFlag.GLOBAL_ONLY);
            }
            catch (TclException e)
            {
            }

            // Remove unsafe parts of tcl_platform

            try
            {
                interp.unsetVar("tcl_platform", "os", TCL.VarFlag.GLOBAL_ONLY);
            }
            catch (TclException e)
            {
            }
            try
            {
                interp.unsetVar("tcl_platform", "osVersion", TCL.VarFlag.GLOBAL_ONLY);
            }
            catch (TclException e)
            {
            }
            try
            {
                interp.unsetVar("tcl_platform", "machine", TCL.VarFlag.GLOBAL_ONLY);
            }
            catch (TclException e)
            {
            }
            try
            {
                interp.unsetVar("tcl_platform", "user", TCL.VarFlag.GLOBAL_ONLY);
            }
            catch (TclException e)
            {
            }

            // Unset path informations variables
            // (the only one remaining is [info nameofexecutable])

            try
            {
                interp.unsetVar("tclDefaultLibrary", TCL.VarFlag.GLOBAL_ONLY);
            }
            catch (TclException e)
            {
            }
            try
            {
                interp.unsetVar("tcl_library", TCL.VarFlag.GLOBAL_ONLY);
            }
            catch (TclException e)
            {
            }
            try
            {
                interp.unsetVar("tcl_pkgPath", TCL.VarFlag.GLOBAL_ONLY);
            }
            catch (TclException e)
            {
            }

            // Remove the standard channels from the interpreter; safe interpreters
            // do not ordinarily have access to stdin, stdout and stderr.
            //
            // NOTE: These channels are not added to the interpreter by the
            // Tcl_CreateInterp call, but may be added later, by another I/O
            // operation. We want to ensure that the interpreter does not have
            // these channels even if it is being made safe after being used for
            // some time..

            chan = TclIO.getStdChannel(StdChannel.STDIN);
            if (chan != null)
            {
                TclIO.unregisterChannel(interp, chan);
            }
            chan = TclIO.getStdChannel(StdChannel.STDOUT);
            if (chan != null)
            {
                TclIO.unregisterChannel(interp, chan);
            }
            chan = TclIO.getStdChannel(StdChannel.STDERR);
            if (chan != null)
            {
                TclIO.unregisterChannel(interp, chan);
            }
        }
示例#15
0
        /// <summary> This procedure is invoked to process the "fconfigure" 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>

        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            Channel chan; // The channel being operated on this method

            if ((argv.Length < 2) || (((argv.Length % 2) == 1) && (argv.Length != 3)))
            {
                throw new TclNumArgsException(interp, 1, argv, "channelId ?optionName? ?value? ?optionName value?...");
            }


            chan = TclIO.getChannel(interp, argv[1].ToString());
            if (chan == null)
            {
                throw new TclException(interp, "can not find channel named \"" + argv[1].ToString() + "\"");
            }

            if (argv.Length == 2)
            {
                // return list of all name/value pairs for this channelId
                TclObject list = TclList.newInstance();

                TclList.append(interp, list, TclString.newInstance("-blocking"));
                TclList.append(interp, list, TclBoolean.newInstance(chan.Blocking));

                TclList.append(interp, list, TclString.newInstance("-buffering"));
                TclList.append(interp, list, TclString.newInstance(TclIO.getBufferingString(chan.Buffering)));

                TclList.append(interp, list, TclString.newInstance("-buffersize"));
                TclList.append(interp, list, TclInteger.newInstance(chan.BufferSize));

                // -encoding

                TclList.append(interp, list, TclString.newInstance("-encoding"));

                System.Text.Encoding javaEncoding = chan.Encoding;
                string tclEncoding;
                if ((System.Object)javaEncoding == null)
                {
                    tclEncoding = "binary";
                }
                else
                {
                    tclEncoding = EncodingCmd.getTclName(javaEncoding);
                }
                TclList.append(interp, list, TclString.newInstance(tclEncoding));

                // -eofchar

                TclList.append(interp, list, TclString.newInstance("-eofchar"));
                if (chan.ReadOnly)
                {
                    char eofChar = chan.InputEofChar;
                    TclList.append(interp, list, (eofChar == 0) ? TclString.newInstance("") : TclString.newInstance(eofChar));
                }
                else if (chan.WriteOnly)
                {
                    char eofChar = chan.OutputEofChar;
                    TclList.append(interp, list, (eofChar == 0) ? TclString.newInstance("") : TclString.newInstance(eofChar));
                }
                else if (chan.ReadWrite)
                {
                    char inEofChar  = chan.InputEofChar;
                    char outEofChar = chan.OutputEofChar;

                    TclObject eofchar_pair = TclList.newInstance();

                    TclList.append(interp, eofchar_pair, (inEofChar == 0) ? TclString.newInstance("") : TclString.newInstance(inEofChar));

                    TclList.append(interp, eofchar_pair, (outEofChar == 0) ? TclString.newInstance("") : TclString.newInstance(outEofChar));

                    TclList.append(interp, list, eofchar_pair);
                }
                else
                {
                    // Not readable or writeable, do nothing
                }

                // -translation

                TclList.append(interp, list, TclString.newInstance("-translation"));

                if (chan.ReadOnly)
                {
                    TclList.append(interp, list, TclString.newInstance(TclIO.getTranslationString(chan.InputTranslation)));
                }
                else if (chan.WriteOnly)
                {
                    TclList.append(interp, list, TclString.newInstance(TclIO.getTranslationString(chan.OutputTranslation)));
                }
                else if (chan.ReadWrite)
                {
                    TclObject translation_pair = TclList.newInstance();

                    TclList.append(interp, translation_pair, TclString.newInstance(TclIO.getTranslationString(chan.InputTranslation)));
                    TclList.append(interp, translation_pair, TclString.newInstance(TclIO.getTranslationString(chan.OutputTranslation)));

                    TclList.append(interp, list, translation_pair);
                }
                else
                {
                    // Not readable or writeable, do nothing
                }

                interp.setResult(list);
            }

            if (argv.Length == 3)
            {
                // return value for supplied name

                int index = TclIndex.get(interp, argv[2], validCmds, "option", 0);

                switch (index)
                {
                case OPT_BLOCKING:
                {
                    // -blocking
                    interp.setResult(chan.Blocking);
                    break;
                }

                case OPT_BUFFERING:
                {
                    // -buffering
                    interp.setResult(TclIO.getBufferingString(chan.Buffering));
                    break;
                }

                case OPT_BUFFERSIZE:
                {
                    // -buffersize
                    interp.setResult(chan.BufferSize);
                    break;
                }

                case OPT_ENCODING:
                {
                    // -encoding
                    System.Text.Encoding javaEncoding = chan.Encoding;
                    if ((System.Object)javaEncoding == null)
                    {
                        interp.setResult("binary");
                    }
                    else
                    {
                        interp.setResult(EncodingCmd.getTclName(javaEncoding));
                    }
                    break;
                }

                case OPT_EOFCHAR:
                {
                    // -eofchar
                    if (chan.ReadOnly)
                    {
                        char eofChar = chan.InputEofChar;
                        interp.setResult((eofChar == 0) ? TclString.newInstance("") : TclString.newInstance(eofChar));
                    }
                    else if (chan.WriteOnly)
                    {
                        char eofChar = chan.OutputEofChar;
                        interp.setResult((eofChar == 0) ? TclString.newInstance("") : TclString.newInstance(eofChar));
                    }
                    else if (chan.ReadWrite)
                    {
                        char inEofChar  = chan.InputEofChar;
                        char outEofChar = chan.OutputEofChar;

                        TclObject eofchar_pair = TclList.newInstance();

                        TclList.append(interp, eofchar_pair, (inEofChar == 0) ? TclString.newInstance("") : TclString.newInstance(inEofChar));

                        TclList.append(interp, eofchar_pair, (outEofChar == 0) ? TclString.newInstance("") : TclString.newInstance(outEofChar));

                        interp.setResult(eofchar_pair);
                    }
                    else
                    {
                        // Not readable or writeable, do nothing
                    }

                    break;
                }

                case OPT_TRANSLATION:
                {
                    // -translation
                    if (chan.ReadOnly)
                    {
                        interp.setResult(TclIO.getTranslationString(chan.InputTranslation));
                    }
                    else if (chan.WriteOnly)
                    {
                        interp.setResult(TclIO.getTranslationString(chan.OutputTranslation));
                    }
                    else if (chan.ReadWrite)
                    {
                        TclObject translation_pair = TclList.newInstance();

                        TclList.append(interp, translation_pair, TclString.newInstance(TclIO.getTranslationString(chan.InputTranslation)));
                        TclList.append(interp, translation_pair, TclString.newInstance(TclIO.getTranslationString(chan.OutputTranslation)));

                        interp.setResult(translation_pair);
                    }
                    else
                    {
                        // Not readable or writeable, do nothing
                    }

                    break;
                }

                default:
                {
                    throw new TclRuntimeError("Fconfigure.cmdProc() error: " + "incorrect index returned from TclIndex.get()");
                }
                }
            }
            for (int i = 3; i < argv.Length; i += 2)
            {
                // Iterate through the list setting the name with the
                // corresponding value.

                int index = TclIndex.get(interp, argv[i - 1], validCmds, "option", 0);

                switch (index)
                {
                case OPT_BLOCKING:
                {
                    // -blocking
                    chan.Blocking = TclBoolean.get(interp, argv[i]);
                    break;
                }

                case OPT_BUFFERING:
                {
                    // -buffering

                    int id = TclIO.getBufferingID(argv[i].ToString());

                    if (id == -1)
                    {
                        throw new TclException(interp, "bad value for -buffering: must be " + "one of full, line, or none");
                    }

                    chan.Buffering = id;
                    break;
                }

                case OPT_BUFFERSIZE:
                {
                    // -buffersize
                    chan.BufferSize = TclInteger.get(interp, argv[i]);
                    break;
                }

                case OPT_ENCODING:
                {
                    // -encoding

                    string tclEncoding = argv[i].ToString();

                    if (tclEncoding.Equals("") || tclEncoding.Equals("binary"))
                    {
                        chan.Encoding = null;
                    }
                    else
                    {
                        System.Text.Encoding javaEncoding = EncodingCmd.getJavaName(tclEncoding);
                        if ((System.Object)javaEncoding == null)
                        {
                            throw new TclException(interp, "unknown encoding \"" + tclEncoding + "\"");
                        }
                        chan.Encoding = javaEncoding;
                    }

                    break;
                }

                case OPT_EOFCHAR:
                {
                    // -eofchar
                    TclList.setListFromAny(interp, argv[i]);
                    int length = TclList.getLength(interp, argv[i]);

                    if (length > 2)
                    {
                        throw new TclException(interp, "bad value for -eofchar: " + "should be a list of zero, one, or two elements");
                    }

                    char   inputEofChar, outputEofChar;
                    string s;

                    if (length == 0)
                    {
                        inputEofChar = outputEofChar = (char)(0);
                    }
                    else if (length == 1)
                    {
                        s            = TclList.index(interp, argv[i], 0).ToString();
                        inputEofChar = outputEofChar = s[0];
                    }
                    else
                    {
                        s            = TclList.index(interp, argv[i], 0).ToString();
                        inputEofChar = s[0];


                        s             = TclList.index(interp, argv[i], 1).ToString();
                        outputEofChar = s[0];
                    }

                    chan.InputEofChar  = inputEofChar;
                    chan.OutputEofChar = outputEofChar;

                    break;
                }

                case OPT_TRANSLATION:
                {
                    // -translation
                    TclList.setListFromAny(interp, argv[i]);
                    int length = TclList.getLength(interp, argv[i]);

                    if (length < 1 || length > 2)
                    {
                        throw new TclException(interp, "bad value for -translation: " + "must be a one or two element list");
                    }

                    string inputTranslationArg, outputTranslationArg;
                    int    inputTranslation, outputTranslation;

                    if (length == 2)
                    {
                        inputTranslationArg = TclList.index(interp, argv[i], 0).ToString();
                        inputTranslation    = TclIO.getTranslationID(inputTranslationArg);

                        outputTranslationArg = TclList.index(interp, argv[i], 1).ToString();
                        outputTranslation    = TclIO.getTranslationID(outputTranslationArg);
                    }
                    else
                    {
                        outputTranslationArg = inputTranslationArg = argv[i].ToString();
                        outputTranslation    = inputTranslation = TclIO.getTranslationID(outputTranslationArg);
                    }

                    if ((inputTranslation == -1) || (outputTranslation == -1))
                    {
                        throw new TclException(interp, "bad value for -translation: " + "must be one of auto, binary, cr, lf, " + "crlf, or platform");
                    }

                    if (outputTranslation == TclIO.TRANS_AUTO)
                    {
                        outputTranslation = TclIO.TRANS_PLATFORM;
                    }

                    if (chan.ReadOnly)
                    {
                        chan.InputTranslation = inputTranslation;
                        if (inputTranslationArg.Equals("binary"))
                        {
                            chan.Encoding = null;
                        }
                    }
                    else if (chan.WriteOnly)
                    {
                        chan.OutputTranslation = outputTranslation;
                        if (outputTranslationArg.Equals("binary"))
                        {
                            chan.Encoding = null;
                        }
                    }
                    else if (chan.ReadWrite)
                    {
                        chan.InputTranslation  = inputTranslation;
                        chan.OutputTranslation = outputTranslation;
                        if (inputTranslationArg.Equals("binary") || outputTranslationArg.Equals("binary"))
                        {
                            chan.Encoding = null;
                        }
                    }
                    else
                    {
                        // Not readable or writeable, do nothing
                    }

                    break;
                }

                default:
                {
                    throw new TclRuntimeError("Fconfigure.cmdProc() error: " + "incorrect index returned from TclIndex.get()");
                }
                }
            }
            return(TCL.CompletionCode.RETURN);
        }
示例#16
0
        /// <summary> This procedure is invoked to process the "open" 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>

        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            bool pipeline  = false;        /* True if opening pipeline chan */
            int  prot      = 438;          /* Final rdwr permissions of file */
            int  modeFlags = TclIO.RDONLY; /* Rdwr mode for the file.  See the
                                            * TclIO class for more info on the
                                            * valid modes */

            if ((argv.Length < 2) || (argv.Length > 4))
            {
                throw new TclNumArgsException(interp, 1, argv, "fileName ?access? ?permissions?");
            }

            if (argv.Length > 2)
            {
                TclObject mode = argv[2];

                string modeStr = mode.ToString();
                int    len     = modeStr.Length;

                // This "r+1" hack is just to get a test case to pass
                if ((len == 0) || (modeStr.StartsWith("r+") && len >= 3))
                {
                    throw new TclException(interp, "illegal access mode \"" + modeStr + "\"");
                }

                if (len < 3)
                {
                    switch (modeStr[0])
                    {
                    case 'r':  {
                        if (len == 1)
                        {
                            modeFlags = TclIO.RDONLY;
                            break;
                        }
                        else if (modeStr[1] == '+')
                        {
                            modeFlags = TclIO.RDWR;
                            break;
                        }
                    }
                        goto case 'w';

                    case 'w':  {
                        FileInfo f = FileUtil.getNewFileObj(interp, argv[1].ToString());
                        bool     tmpBool;
                        if (File.Exists(f.FullName))
                        {
                            tmpBool = true;
                        }
                        else
                        {
                            tmpBool = Directory.Exists(f.FullName);
                        }
                        if (tmpBool)
                        {
                            bool tmpBool2;
                            try {
                                if (File.Exists(f.FullName))
                                {
                                    File.SetAttributes(f.FullName, FileAttributes.Normal);
                                    File.Delete(f.FullName);
                                    tmpBool2 = true;
                                }
                                else if (Directory.Exists(f.FullName))
                                {
                                    Directory.Delete(f.FullName);
                                    tmpBool2 = true;
                                }
                                else
                                {
                                    tmpBool2 = false;
                                }
                            }
                            // ATK added because .NET do not allow often to delete
                            // files used by another process
                            catch (System.IO.IOException e)
                            {
                                throw new TclException(interp, "cannot open file: " + argv[1].ToString());
                            }
                            bool generatedAux = tmpBool2;
                        }
                        if (len == 1)
                        {
                            modeFlags = (TclIO.WRONLY | TclIO.CREAT);
                            break;
                        }
                        else if (modeStr[1] == '+')
                        {
                            modeFlags = (TclIO.RDWR | TclIO.CREAT);
                            break;
                        }
                    }
                        goto case 'a';

                    case 'a':  {
                        if (len == 1)
                        {
                            modeFlags = (TclIO.WRONLY | TclIO.APPEND);
                            break;
                        }
                        else if (modeStr[1] == '+')
                        {
                            modeFlags = (TclIO.RDWR | TclIO.CREAT | TclIO.APPEND);
                            break;
                        }
                    }
                        goto default;

                    default:  {
                        throw new TclException(interp, "illegal access mode \"" + modeStr + "\"");
                    }
                    }
                }
                else
                {
                    modeFlags = 0;
                    bool gotRorWflag = false;
                    int  mlen        = TclList.getLength(interp, mode);
                    for (int i = 0; i < mlen; i++)
                    {
                        TclObject marg = TclList.index(interp, mode, i);

                        if (marg.ToString().Equals("RDONLY"))
                        {
                            modeFlags  |= TclIO.RDONLY;
                            gotRorWflag = true;
                        }
                        else
                        {
                            if (marg.ToString().Equals("WRONLY"))
                            {
                                modeFlags  |= TclIO.WRONLY;
                                gotRorWflag = true;
                            }
                            else
                            {
                                if (marg.ToString().Equals("RDWR"))
                                {
                                    modeFlags  |= TclIO.RDWR;
                                    gotRorWflag = true;
                                }
                                else
                                {
                                    if (marg.ToString().Equals("APPEND"))
                                    {
                                        modeFlags |= TclIO.APPEND;
                                    }
                                    else
                                    {
                                        if (marg.ToString().Equals("CREAT"))
                                        {
                                            modeFlags |= TclIO.CREAT;
                                        }
                                        else
                                        {
                                            if (marg.ToString().Equals("EXCL"))
                                            {
                                                modeFlags |= TclIO.EXCL;
                                            }
                                            else
                                            {
                                                if (marg.ToString().Equals("TRUNC"))
                                                {
                                                    modeFlags |= TclIO.TRUNC;
                                                }
                                                else
                                                {
                                                    throw new TclException(interp, "invalid access mode \"" + marg.ToString() + "\": must be RDONLY, WRONLY, RDWR, APPEND, " + "CREAT EXCL, NOCTTY, NONBLOCK, or TRUNC");
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (!gotRorWflag)
                    {
                        throw new TclException(interp, "access mode must include either RDONLY, WRONLY, or RDWR");
                    }
                }
            }

            if (argv.Length == 4)
            {
                prot = TclInteger.get(interp, argv[3]);
                throw new TclException(interp, "setting permissions not implemented yet");
            }

            if ((argv[1].ToString().Length > 0) && (argv[1].ToString()[0] == '|'))
            {
                pipeline = true;
                throw new TclException(interp, "pipes not implemented yet");
            }

            /*
             * Open the file or create a process pipeline.
             */

            if (!pipeline)
            {
                try
                {
                    FileChannel file = new FileChannel();

                    file.open(interp, argv[1].ToString(), modeFlags);
                    TclIO.registerChannel(interp, file);
                    interp.setResult(file.ChanName);
                }
                catch (System.IO.IOException e)
                {
                    throw new TclException(interp, "cannot open file: " + argv[1].ToString());
                }
            }
            else
            {
                /*
                 * Pipeline code here...
                 */
            }
            return(TCL.CompletionCode.RETURN);
        }
示例#17
0
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] objv)
        {
            if (objv.Length < 2)
            {
                throw new TclNumArgsException(interp, 1, objv, "cmd ?arg ...?");
            }
            int cmd = TclIndex.get(interp, objv[1], options, "option", 0);

            switch (cmd)
            {
            case OPT_ALIAS:
            {
                if (objv.Length >= 4)
                {
                    Interp slaveInterp = getInterp(interp, objv[2]);

                    if (objv.Length == 4)
                    {
                        InterpAliasCmd.describe(interp, slaveInterp, objv[3]);
                        return(TCL.CompletionCode.RETURN);
                    }

                    if ((objv.Length == 5) && ("".Equals(objv[4].ToString())))
                    {
                        InterpAliasCmd.delete(interp, slaveInterp, objv[3]);
                        return(TCL.CompletionCode.RETURN);
                    }
                    if (objv.Length > 5)
                    {
                        Interp masterInterp = getInterp(interp, objv[4]);

                        if ("".Equals(objv[5].ToString()))
                        {
                            if (objv.Length == 6)
                            {
                                InterpAliasCmd.delete(interp, slaveInterp, objv[3]);
                                return(TCL.CompletionCode.RETURN);
                            }
                        }
                        else
                        {
                            InterpAliasCmd.create(interp, slaveInterp, masterInterp, objv[3], objv[5], 6, objv);
                            return(TCL.CompletionCode.RETURN);
                        }
                    }
                }
                throw new TclNumArgsException(interp, 2, objv, "slavePath slaveCmd ?masterPath masterCmd? ?args ..?");
            }

            case OPT_ALIASES:
            {
                Interp slaveInterp = getInterp(interp, objv);
                InterpAliasCmd.list(interp, slaveInterp);
                break;
            }

            case OPT_CREATE:
            {
                // Weird historical rules: "-safe" is accepted at the end, too.

                bool safe = interp.isSafe;

                TclObject slaveNameObj = null;
                bool      last         = false;
                for (int i = 2; i < objv.Length; i++)
                {
                    if ((!last) && (objv[i].ToString()[0] == '-'))
                    {
                        int index = TclIndex.get(interp, objv[i], createOptions, "option", 0);
                        if (index == OPT_CREATE_SAFE)
                        {
                            safe = true;
                            continue;
                        }
                        i++;
                        last = true;
                    }
                    if (slaveNameObj != null)
                    {
                        throw new TclNumArgsException(interp, 2, objv, "?-safe? ?--? ?path?");
                    }
                    slaveNameObj = objv[i];
                }
                if (slaveNameObj == null)
                {
                    // Create an anonymous interpreter -- we choose its name and
                    // the name of the command. We check that the command name
                    // that we use for the interpreter does not collide with an
                    // existing command in the master interpreter.

                    int i = 0;
                    while (interp.getCommand("interp" + i) != null)
                    {
                        i++;
                    }
                    slaveNameObj = TclString.newInstance("interp" + i);
                }
                InterpSlaveCmd.create(interp, slaveNameObj, safe);
                interp.setResult(slaveNameObj);
                break;
            }

            case OPT_DELETE:
            {
                for (int i = 2; i < objv.Length; i++)
                {
                    Interp slaveInterp = getInterp(interp, objv[i]);

                    if (slaveInterp == interp)
                    {
                        throw new TclException(interp, "cannot delete the current interpreter");
                    }
                    InterpSlaveCmd slave = slaveInterp.slave;
                    slave.masterInterp.deleteCommandFromToken(slave.interpCmd);
                }
                break;
            }

            case OPT_EVAL:
            {
                if (objv.Length < 4)
                {
                    throw new TclNumArgsException(interp, 2, objv, "path arg ?arg ...?");
                }
                Interp slaveInterp = getInterp(interp, objv[2]);
                InterpSlaveCmd.eval(interp, slaveInterp, 3, objv);
                break;
            }

            case OPT_EXISTS:
            {
                bool exists = true;

                try
                {
                    getInterp(interp, objv);
                }
                catch (TclException e)
                {
                    if (objv.Length > 3)
                    {
                        throw;
                    }
                    exists = false;
                }
                interp.setResult(exists);
                break;
            }

            case OPT_EXPOSE:
            {
                if (objv.Length < 4 || objv.Length > 5)
                {
                    throw new TclNumArgsException(interp, 2, objv, "path hiddenCmdName ?cmdName?");
                }
                Interp slaveInterp = getInterp(interp, objv[2]);
                InterpSlaveCmd.expose(interp, slaveInterp, 3, objv);
                break;
            }

            case OPT_HIDE:
            {
                if (objv.Length < 4 || objv.Length > 5)
                {
                    throw new TclNumArgsException(interp, 2, objv, "path cmdName ?hiddenCmdName?");
                }
                Interp slaveInterp = getInterp(interp, objv[2]);
                InterpSlaveCmd.hide(interp, slaveInterp, 3, objv);
                break;
            }

            case OPT_HIDDEN:
            {
                Interp slaveInterp = getInterp(interp, objv);
                InterpSlaveCmd.hidden(interp, slaveInterp);
                break;
            }

            case OPT_ISSAFE:
            {
                Interp slaveInterp = getInterp(interp, objv);
                interp.setResult(slaveInterp.isSafe);
                break;
            }

            case OPT_INVOKEHIDDEN:
            {
                bool global = false;
                int  i;
                for (i = 3; i < objv.Length; i++)
                {
                    if (objv[i].ToString()[0] != '-')
                    {
                        break;
                    }
                    int index = TclIndex.get(interp, objv[i], hiddenOptions, "option", 0);
                    if (index == OPT_HIDDEN_GLOBAL)
                    {
                        global = true;
                    }
                    else
                    {
                        i++;
                        break;
                    }
                }
                if (objv.Length - i < 1)
                {
                    throw new TclNumArgsException(interp, 2, objv, "path ?-global? ?--? cmd ?arg ..?");
                }
                Interp slaveInterp = getInterp(interp, objv[2]);
                InterpSlaveCmd.invokeHidden(interp, slaveInterp, global, i, objv);
                break;
            }

            case OPT_MARKTRUSTED:
            {
                if (objv.Length != 3)
                {
                    throw new TclNumArgsException(interp, 2, objv, "path");
                }
                Interp slaveInterp = getInterp(interp, objv[2]);
                InterpSlaveCmd.markTrusted(interp, slaveInterp);
                break;
            }

            case OPT_SLAVES:
            {
                Interp slaveInterp = getInterp(interp, objv);

                TclObject result = TclList.newInstance();
                interp.setResult(result);

                IEnumerator keys = slaveInterp.slaveTable.Keys.GetEnumerator();
                while (keys.MoveNext())
                {
                    string inString = (string)keys.Current;
                    TclList.append(interp, result, TclString.newInstance(inString));
                }

                break;
            }

            case OPT_SHARE:
            {
                if (objv.Length != 5)
                {
                    throw new TclNumArgsException(interp, 2, objv, "srcPath channelId destPath");
                }
                Interp masterInterp = getInterp(interp, objv[2]);


                Channel chan = TclIO.getChannel(masterInterp, objv[3].ToString());
                if (chan == null)
                {
                    throw new TclException(interp, "can not find channel named \"" + objv[3].ToString() + "\"");
                }

                Interp slaveInterp = getInterp(interp, objv[4]);
                TclIO.registerChannel(slaveInterp, chan);
                break;
            }

            case OPT_TARGET:
            {
                if (objv.Length != 4)
                {
                    throw new TclNumArgsException(interp, 2, objv, "path alias");
                }

                Interp slaveInterp = getInterp(interp, objv[2]);

                string aliasName    = objv[3].ToString();
                Interp targetInterp = InterpAliasCmd.getTargetInterp(slaveInterp, aliasName);
                if (targetInterp == null)
                {
                    throw new TclException(interp, "alias \"" + aliasName + "\" in path \"" + objv[2].ToString() + "\" not found");
                }
                if (!getInterpPath(interp, targetInterp))
                {
                    throw new TclException(interp, "target interpreter for alias \"" + aliasName + "\" in path \"" + objv[2].ToString() + "\" is not my descendant");
                }
                break;
            }

            case OPT_TRANSFER:
            {
                if (objv.Length != 5)
                {
                    throw new TclNumArgsException(interp, 2, objv, "srcPath channelId destPath");
                }
                Interp masterInterp = getInterp(interp, objv[2]);


                Channel chan = TclIO.getChannel(masterInterp, objv[3].ToString());
                if (chan == null)
                {
                    throw new TclException(interp, "can not find channel named \"" + objv[3].ToString() + "\"");
                }

                Interp slaveInterp = getInterp(interp, objv[4]);
                TclIO.registerChannel(slaveInterp, chan);
                TclIO.unregisterChannel(masterInterp, chan);
                break;
            }
            }
            return(TCL.CompletionCode.RETURN);
        }
示例#18
0
        /// <summary> This procedure is invoked to process the "read" 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>

        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            Channel chan;                // The channel being operated on this
            // method
            int       i      = 1;        // Index to the next arg in argv
            int       toRead = 0;        // Number of bytes or chars to read from channel
            int       charactersRead;    // Number of bytes or chars read from channel
            bool      readAll   = true;  // If true read-all else toRead
            bool      noNewline = false; // If true, strip the newline if there
            TclObject result;


            if ((argv.Length != 2) && (argv.Length != 3))
            {
                errorWrongNumArgs(interp, argv[0].ToString());
            }


            if (argv[i].ToString().Equals("-nonewline"))
            {
                noNewline = true;
                i++;
            }

            if (i == argv.Length)
            {
                errorWrongNumArgs(interp, argv[0].ToString());
            }


            chan = TclIO.getChannel(interp, argv[i].ToString());
            if (chan == null)
            {
                throw new TclException(interp, "can not find channel named \"" + argv[i].ToString() + "\"");
            }

            // Consumed channel name.

            i++;

            // Compute how many bytes or chars to read, and see whether the final
            // noNewline should be dropped.

            if (i < argv.Length)
            {
                string arg = argv[i].ToString();

                if (System.Char.IsDigit(arg[0]))
                {
                    toRead  = TclInteger.get(interp, argv[i]);
                    readAll = false;
                }
                else if (arg.Equals("nonewline"))
                {
                    noNewline = true;
                }
                else
                {
                    throw new TclException(interp, "bad argument \"" + arg + "\": should be \"nonewline\"");
                }
            }

            try
            {
                if ((System.Object)chan.Encoding == null)
                {
                    result = TclByteArray.newInstance();
                }
                else
                {
                    result = TclString.newInstance(new System.Text.StringBuilder(64));
                }
                if (readAll)
                {
                    charactersRead = chan.read(interp, result, TclIO.READ_ALL, 0);

                    // If -nonewline was specified, and we have not hit EOF
                    // and the last char is a "\n", then remove it and return.

                    if (noNewline)
                    {
                        string inStr = result.ToString();
                        if ((charactersRead > 0) && (inStr[charactersRead - 1] == '\n'))
                        {
                            interp.setResult(inStr.Substring(0, ((charactersRead - 1)) - (0)));
                            return(TCL.CompletionCode.RETURN);
                        }
                    }
                }
                else
                {
                    // FIXME: Bug here, the -nonewline flag must be respected
                    // when reading a set number of bytes
                    charactersRead = chan.read(interp, result, TclIO.READ_N_BYTES, toRead);
                }

                /*
                 * // FIXME: Port this -nonewline logic from the C code.
                 * if (charactersRead < 0) {
                 * Tcl_ResetResult(interp);
                 * Tcl_AppendResult(interp, "error reading \"", name, "\": ",
                 * Tcl_PosixError(interp), (char *) NULL);
                 * Tcl_DecrRefCount(resultPtr);
                 * return TCL_ERROR;
                 * }
                 *
                 * // If requested, remove the last newline in the channel if at EOF.
                 *
                 * if ((charactersRead > 0) && (newline != 0)) {
                 * char *result;
                 * int length;
                 *
                 * result = Tcl_GetStringFromObj(resultPtr, length);
                 * if (result[length - 1] == '\n') {
                 * Tcl_SetObjLength(resultPtr, length - 1);
                 * }
                 * }
                 *
                 */

                interp.setResult(result);
            }
            catch (System.IO.IOException e)
            {
                throw new TclRuntimeError("ReadCmd.cmdProc() Error: IOException when reading " + chan.ChanName);
            }
            return(TCL.CompletionCode.RETURN);
        }
示例#19
0
            public override void  processIdleEvent()
            {
                // During the execution of this method, elements may be removed from
                // the errors list (because a TCL.CompletionCode.BREAK was returned by the bgerror
                // command, or because the interp was deleted). We remove this
                // BgError instance from the list first so that this instance won't
                // be deleted twice.

                SupportClass.VectorRemoveElement(Enclosing_Instance.errors, this);

                // Restore important state variables to what they were at
                // the time the error occurred.

                try
                {
                    Enclosing_Instance.interp.setVar("errorInfo", null, errorInfo, TCL.VarFlag.GLOBAL_ONLY);
                }
                catch (TclException e)
                {
                    // Ignore any TclException's, possibly caused by variable traces on
                    // the errorInfo variable. This is compatible with the behavior of
                    // the Tcl C API.
                }

                try
                {
                    Enclosing_Instance.interp.setVar("errorCode", null, errorCode, TCL.VarFlag.GLOBAL_ONLY);
                }
                catch (TclException e)
                {
                    // Ignore any TclException's, possibly caused by variable traces on
                    // the errorCode variable. This is compatible with the behavior of
                    // the Tcl C API.
                }

                // Make sure, that the interpreter will surive the invocation
                // of the bgerror command.

                Enclosing_Instance.interp.preserve();

                try
                {
                    // Invoke the bgerror command.

                    TclObject[] argv = new TclObject[2];
                    argv[0] = Enclosing_Instance.bgerrorCmdObj;
                    argv[1] = errorMsg;

                    Parser.evalObjv(Enclosing_Instance.interp, argv, 0, TCL.EVAL_GLOBAL);
                }
                catch (TclException e)
                {
                    switch (e.getCompletionCode())
                    {
                    case TCL.CompletionCode.ERROR:
                        try
                        {
                            Channel chan = TclIO.getStdChannel(StdChannel.STDERR);

                            if (Enclosing_Instance.interp.getResult().ToString().Equals("\"bgerror\" is an invalid command name or ambiguous abbreviation"))
                            {
                                chan.write(Enclosing_Instance.interp, errorInfo);
                                chan.write(Enclosing_Instance.interp, "\n");
                            }
                            else
                            {
                                chan.write(Enclosing_Instance.interp, "bgerror failed to handle background error.\n");
                                chan.write(Enclosing_Instance.interp, "    Original error: ");
                                chan.write(Enclosing_Instance.interp, errorMsg);
                                chan.write(Enclosing_Instance.interp, "\n");
                                chan.write(Enclosing_Instance.interp, "    Error in bgerror: ");
                                chan.write(Enclosing_Instance.interp, Enclosing_Instance.interp.getResult());
                                chan.write(Enclosing_Instance.interp, "\n");
                            }
                            chan.flush(Enclosing_Instance.interp);
                        }
                        catch (TclException e1)
                        {
                            // Ignore.
                        }
                        catch (System.IO.IOException e2)
                        {
                            // Ignore, too.
                        }
                        break;


                    case TCL.CompletionCode.BREAK:

                        for (int i = Enclosing_Instance.errors.Count - 1; i >= 0; i--)
                        {
                            BgError bgErr = (BgError)Enclosing_Instance.errors[i];
                            Enclosing_Instance.errors.RemoveAt(i);
                            bgErr.cancel();

                            bgErr.errorMsg.release();
                            bgErr.errorMsg = null;
                            bgErr.errorInfo.release();
                            bgErr.errorInfo = null;
                            bgErr.errorCode.release();
                            bgErr.errorCode = null;
                        }
                        break;
                    }
                }

                Enclosing_Instance.interp.release();

                errorMsg.release();
                errorMsg = null;
                errorInfo.release();
                errorInfo = null;
                errorCode.release();
                errorCode = null;
            }