/// <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); }
/// <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); }
/// <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"); }
/// <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); }
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); }
/// <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; 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); }
public void Dispose(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; }
/// <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"); }
/// <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); }
/// <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 (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 (IOException e) { throw new TclException(interp, "cannot open file: " + argv[1].ToString()); } } else { /* * Pipeline code here... */ } return(TCL.CompletionCode.RETURN); }
/// <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); }
/// <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 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 (IOException e) { throw new TclRuntimeError("ReadCmd.cmdProc() Error: IOException when reading " + chan.ChanName); } return(TCL.CompletionCode.RETURN); }
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(EnclosingInstance.Errors, this); // Restore important state variables to what they were at the time the error occurred. try { EnclosingInstance.Interp.SetVar("errorInfo", null, ErrorInfo, TCL.VarFlag.GLOBAL_ONLY); } // Ignore any TclException's, possibly caused by variable traces on the errorInfo variable. This is compatible with the behavior of the Tcl C API. catch (TclException) { } try { EnclosingInstance.Interp.SetVar("errorCode", null, ErrorCode, TCL.VarFlag.GLOBAL_ONLY); } // Ignore any TclException's, possibly caused by variable traces on the errorCode variable. This is compatible with the behavior of the Tcl C API. catch (TclException) { } // Make sure, that the interpreter will surive the invocation of the bgerror command. EnclosingInstance.Interp.preserve(); try { // Invoke the bgerror command. TclObject[] argv = new TclObject[2]; argv[0] = EnclosingInstance.BgerrorCmdObj; argv[1] = ErrorMsg; Parser.EvalObjv(EnclosingInstance.Interp, argv, 0, TCL.EVAL_GLOBAL); } catch (TclException e) { switch (e.GetCompletionCode()) { case TCL.CompletionCode.ERROR: try { Channel chan = TclIO.GetStdChannel(StdChannel.STDERR); var interp = EnclosingInstance.Interp; if (EnclosingInstance.Interp.GetResult().ToString().Equals("\"bgerror\" is an invalid command name or ambiguous abbreviation")) { chan.Write(interp, ErrorInfo); chan.Write(interp, "\n"); } else { chan.Write(interp, "bgerror failed to handle background error.\n"); chan.Write(interp, " Original error: "); chan.Write(interp, ErrorMsg); chan.Write(interp, "\n"); chan.Write(interp, " Error in bgerror: "); chan.Write(interp, EnclosingInstance.Interp.GetResult()); chan.Write(interp, "\n"); } chan.Flush(EnclosingInstance.Interp); } catch (TclException) { } // Ignore. catch (IOException) { } // Ignore, too. break; case TCL.CompletionCode.BREAK: for (int i = EnclosingInstance.Errors.Count - 1; i >= 0; i--) { BgError bgError = (BgError)EnclosingInstance.Errors[i]; EnclosingInstance.Errors.RemoveAt(i); bgError.Cancel(); bgError.ErrorMsg.Release(); bgError.ErrorMsg = null; bgError.ErrorInfo.Release(); bgError.ErrorInfo = null; bgError.ErrorCode.Release(); bgError.ErrorCode = null; } break; } } EnclosingInstance.Interp.release(); ErrorMsg.Release(); ErrorMsg = null; ErrorInfo.Release(); ErrorInfo = null; ErrorCode.Release(); ErrorCode = null; }
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); }
/// <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); } }
public static void Tcl_UnregisterChannel(Interp interp, Channel chan) { TclIO.unregisterChannel(interp, chan); }