/// <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 "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); }
/// <summary> See Tcl user documentation for details.</summary> /// <exception cref=""> TclException If incorrect number of arguments. /// </exception> public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv) { if (argv.Length != 2) { throw new TclNumArgsException(interp, 1, argv, "list"); } interp.setResult(TclInteger.newInstance(TclList.getLength(interp, argv[1]))); return(TCL.CompletionCode.RETURN); }
private static TclObject ScanNumber(byte[] src, int pos, int type) // Format character from "binary scan" { switch (type) { case 'c': { return(TclInteger.newInstance((sbyte)src[pos])); } case 's': { short value = (short)((src[pos] & 0xff) + ((src[pos + 1] & 0xff) << 8)); return(TclInteger.newInstance((int)value)); } case 'S': { short value = (short)((src[pos + 1] & 0xff) + ((src[pos] & 0xff) << 8)); return(TclInteger.newInstance((int)value)); } case 'i': { int value = (src[pos] & 0xff) + ((src[pos + 1] & 0xff) << 8) + ((src[pos + 2] & 0xff) << 16) + ((src[pos + 3] & 0xff) << 24); return(TclInteger.newInstance(value)); } case 'I': { int value = (src[pos + 3] & 0xff) + ((src[pos + 2] & 0xff) << 8) + ((src[pos + 1] & 0xff) << 16) + ((src[pos] & 0xff) << 24); return(TclInteger.newInstance(value)); } case 'f': { System.IO.MemoryStream ms = new System.IO.MemoryStream(src, pos, 4, false); System.IO.BinaryReader reader = new System.IO.BinaryReader(ms); double fvalue = reader.ReadSingle(); reader.Close(); ms.Close(); return(TclDouble.newInstance(fvalue)); } case 'd': { System.IO.MemoryStream ms = new System.IO.MemoryStream(src, pos, 8, false); System.IO.BinaryReader reader = new System.IO.BinaryReader(ms); double dvalue = reader.ReadDouble(); reader.Close(); ms.Close(); return(TclDouble.newInstance(dvalue)); } } return(null); }
/// <summary> This procedure is invoked to process the "catch" Tcl command. /// See the user documentation for details on what it does. /// /// </summary> /// <param name="interp">the current interpreter. /// </param> /// <param name="argv">command arguments. /// </param> /// <exception cref=""> TclException if wrong number of arguments. /// </exception> public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv) { if (argv.Length != 2 && argv.Length != 3) { throw new TclNumArgsException(interp, 1, argv, "command ?varName?"); } TclObject result; TCL.CompletionCode code = TCL.CompletionCode.OK; try { interp.eval(argv[1], 0); } catch (TclException e) { code = e.getCompletionCode(); } result = interp.getResult(); if (argv.Length == 3) { try { interp.setVar(argv[2], result, 0); } catch (TclException e) { throw new TclException(interp, "couldn't save command result in variable"); } } interp.resetResult(); interp.setResult(TclInteger.newInstance((int)code)); return(TCL.CompletionCode.RETURN); }
private static void getAndStoreStatData(Interp interp, string fileName, string varName) { System.IO.FileInfo fileObj = FileUtil.getNewFileObj(interp, fileName); bool tmpBool; if (System.IO.File.Exists(fileObj.FullName)) { tmpBool = true; } else { tmpBool = System.IO.Directory.Exists(fileObj.FullName); } if (!tmpBool) { throw new TclPosixException(interp, TclPosixException.ENOENT, true, "could not read \"" + fileName + "\""); } try { int mtime = getMtime(interp, fileName, fileObj); TclObject mtimeObj = TclInteger.newInstance(mtime); TclObject atimeObj = TclInteger.newInstance(mtime); TclObject ctimeObj = TclInteger.newInstance(mtime); interp.setVar(varName, "atime", atimeObj, 0); interp.setVar(varName, "ctime", ctimeObj, 0); interp.setVar(varName, "mtime", mtimeObj, 0); } catch (System.Security.SecurityException e) { throw new TclException(interp, e.Message); } catch (TclException e) { throw new TclException(interp, "can't set \"" + varName + "(dev)\": variable isn't array"); } try { TclObject sizeObj = TclInteger.newInstance((int)SupportClass.FileLength(fileObj)); interp.setVar(varName, "size", sizeObj, 0); } catch (System.Exception e) { // Do nothing. } try { TclObject typeObj = TclString.newInstance(getType(interp, fileName, fileObj)); interp.setVar(varName, "type", typeObj, 0); } catch (System.Exception e) { } try { TclObject uidObj = TclBoolean.newInstance(isOwner(interp, fileObj)); interp.setVar(varName, "uid", uidObj, 0); } catch (TclException e) { // Do nothing. } }
/// <summary> This procedure is invoked to process the "scan" Tcl command. /// See the user documentation for details on what it does. /// /// Each iteration of the cmdProc compares the scanArr's current index to /// the frmtArr's index. If the chars are equal then the indicies are /// incremented. If a '%' is found in the frmtArr, the formatSpecifier /// is parced from the frmtArr, the corresponding value is extracted from /// the scanArr, and that value is set in the Tcl Interp. /// /// If the chars are not equal, or the conversion fails, the boolean /// scanArrDone is set to true, indicating the scanArr is not to be /// parced and no new values are to be set. However the frmtArr is still /// parced because of the priority of error messages. In the C version /// of Tcl, bad format specifiers throw errors before incorrect argument /// input or other scan errors. Thus we need to parce the entire frmtArr /// to verify correct formating. This is dumb and inefficient but it is /// consistent w/ the current C-version of Tcl. /// </summary> public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv) { if (argv.Length < 3) { throw new TclNumArgsException(interp, 1, argv, "string format ?varName varName ...?"); } ; StrtoulResult strul; // Return value for parcing the scanArr when // extracting integers/longs StrtodResult strd;; // Return value for parcing the scanArr when // extracting doubles char[] scanArr; // Array containing parce info char[] frmtArr; // Array containing info on how to // parse the scanArr int scanIndex; // Index into the scan array int frmtIndex; // Index into the frmt array int tempIndex; // Temporary index holder int argIndex; // Index into the current arg int width; // Stores the user specified result width int base_; // Base of the integer being converted int numUnMatched; // Number of fields actually set. int numMatched; // Number of fields actually matched. int negateScan; // Mult by result, set to -1 if true int i; // Generic variable char ch; // Generic variable bool cont; // Used in loops to indicate when to stop bool scanOK; // Set to false if strtoul/strtod fails bool scanArrDone; // Set to false if strtoul/strtod fails bool widthFlag; // True is width is specified bool discardFlag; // If a "%*" is in the formatString dont // write output to arg scanArr = argv[1].ToString().ToCharArray(); frmtArr = argv[2].ToString().ToCharArray(); width = base_ = numMatched = numUnMatched = 0; scanIndex = frmtIndex = 0; scanOK = true; scanArrDone = false; argIndex = 3; // Skip all (if any) of the white space before getting to a char frmtIndex = skipWhiteSpace(frmtArr, frmtIndex); // Search through the frmtArr. If the next char is a '%' parse the // next chars and determine the type (if any) of the format specifier. // If the scanArr has been fully searched, do nothing but incerment // "numUnMatched". The reason to continue the frmtArr search is for // consistency in output. Previously scan format errors were reported // before arg input mismatch, so this maintains the same level of error // checking. while (frmtIndex < frmtArr.Length) { discardFlag = widthFlag = false; negateScan = 1; cont = true; // Parce the format array and read in the correct value from the // scan array. When the correct value is retrieved, set the // variable (from argv) in the interp. if (frmtArr[frmtIndex] == '%') { frmtIndex++; checkOverFlow(interp, frmtArr, frmtIndex); // Two '%'s in a row, do nothing... if (frmtArr[frmtIndex] == '%') { frmtIndex++; scanIndex++; continue; } // Check for a discard field flag if (frmtArr[frmtIndex] == '*') { discardFlag = true; frmtIndex++; checkOverFlow(interp, frmtArr, frmtIndex); } // Check for a width field and accept the 'h', 'l', 'L' // characters, but do nothing with them. // // Note: The order of the width specifier and the other // chars is unordered, so we need to iterate until all // of the specifiers are identified. while (cont) { cont = false; switch (frmtArr[frmtIndex]) { case 'h': case 'l': case 'L': { // Just ignore these values frmtIndex++; cont = true; break; } default: { if (System.Char.IsDigit(frmtArr[frmtIndex])) { strul = Util.strtoul(new string(frmtArr), frmtIndex, base_); frmtIndex = strul.index; width = (int)strul.value; widthFlag = true; cont = true; } } break; } checkOverFlow(interp, frmtArr, frmtIndex); } // On all conversion specifiers except 'c', move the // scanIndex to the next non-whitespace. ch = frmtArr[frmtIndex]; if ((ch != 'c') && (ch != '[') && !scanArrDone) { scanIndex = skipWhiteSpace(scanArr, scanIndex); } if (scanIndex >= scanArr.Length) { scanArrDone = true; } if ((scanIndex < scanArr.Length) && (ch != 'c') && (ch != '[')) { // Since strtoul dosent take signed numbers, make the // value positive and store the sign. if (scanArr[scanIndex] == '-') { negateScan = -1; scanIndex++; width--; } else if (scanArr[scanIndex] == '+') { scanIndex++; width--; } // The width+scanIndex might be greater than // the scanArr so we need to re-adjust when this // happens. if (widthFlag && (width + scanIndex > scanArr.Length)) { width = scanArr.Length - scanIndex; } } if (scanIndex >= scanArr.Length) { scanArrDone = true; } // Foreach iteration we want strul and strd to be // null since we error check on this case. strul = null; strd = null; switch (ch) { case 'd': case 'o': case 'x': { if (!scanArrDone) { if (ch == 'd') { base_ = 10; } else if (ch == 'o') { base_ = 8; } else { base_ = 16; } // If the widthFlag is set then convert only // "width" characters to an ascii representation, // else read in until the end of the integer. The // scanIndex is moved to the point where we stop // reading in. if (widthFlag) { strul = Util.strtoul(new string(scanArr, 0, width + scanIndex), scanIndex, base_); } else { strul = Util.strtoul(new string(scanArr), scanIndex, base_); } if (strul.errno != 0) { scanOK = false; break; } scanIndex = strul.index; if (!discardFlag) { i = (int)strul.value * negateScan; if (argIndex == argv.Length) { numMatched--; } else { testAndSetVar(interp, argv, argIndex++, TclInteger.newInstance(i)); } } } break; } case 'c': { if (widthFlag) { errorCharFieldWidth(interp); } if (!discardFlag && !scanArrDone) { testAndSetVar(interp, argv, argIndex++, TclInteger.newInstance(scanArr[scanIndex++])); } break; } case 's': { if (!scanArrDone) { // If the widthFlag is set then read only "width" // characters into the string, else read in until // the first whitespace or endArr is found. The // scanIndex is moved to the point where we stop // reading in. tempIndex = scanIndex; if (!widthFlag) { width = scanArr.Length; } for (i = 0; (scanIndex < scanArr.Length) && (i < width); i++) { ch = scanArr[scanIndex]; if ((ch == ' ') || (ch == '\n') || (ch == '\r') || (ch == '\t') || (ch == '\f')) { break; } scanIndex++; } if (!discardFlag) { string str = new string(scanArr, tempIndex, scanIndex - tempIndex); testAndSetVar(interp, argv, argIndex++, TclString.newInstance(str)); } } break; } case 'e': case 'f': case 'g': { if (!scanArrDone) { // If the wisthFlag is set then read only "width" // characters into the string, else read in until // the first whitespace or endArr is found. The // scanIndex is moved to the point where we stop // reading in. if (widthFlag) { strd = Util.strtod(new string(scanArr, 0, width + scanIndex), scanIndex); } else { strd = Util.strtod(new string(scanArr), scanIndex); } if (strd.errno != 0) { scanOK = false; break; } scanIndex = strd.index; if (!discardFlag) { double d = strd.value * negateScan; testAndSetVar(interp, argv, argIndex++, TclDouble.newInstance(d)); } } break; } case '[': { bool charMatchFound = false; bool charNotMatch = false; char[] tempArr; int startIndex; int endIndex; string unmatched = "unmatched [ in format string"; if ((++frmtIndex) >= frmtArr.Length) { throw new TclException(interp, unmatched); } if (frmtArr[frmtIndex] == '^') { charNotMatch = true; frmtIndex += 2; } else { frmtIndex++; } tempIndex = frmtIndex - 1; if (frmtIndex >= frmtArr.Length) { throw new TclException(interp, unmatched); } // Extract the list of chars for matching. while (frmtArr[frmtIndex] != ']') { if ((++frmtIndex) >= frmtArr.Length) { throw new TclException(interp, unmatched); } } tempArr = new string(frmtArr, tempIndex, frmtIndex - tempIndex).ToCharArray(); startIndex = scanIndex; if (charNotMatch) { // Format specifier contained a '^' so interate // until one of the chars in tempArr is found. while (scanOK && !charMatchFound) { if (scanIndex >= scanArr.Length) { scanOK = false; break; } for (i = 0; i < tempArr.Length; i++) { if (tempArr[i] == scanArr[scanIndex]) { charMatchFound = true; break; } } if (widthFlag && ((scanIndex - startIndex) >= width)) { break; } if (!charMatchFound) { scanIndex++; } } } else { // Iterate until the char in the scanArr is not // in the tempArr. charMatchFound = true; while (scanOK && charMatchFound) { if (scanIndex >= scanArr.Length) { scanOK = false; break; } charMatchFound = false; for (i = 0; i < tempArr.Length; i++) { if (tempArr[i] == scanArr[scanIndex]) { charMatchFound = true; break; } } if (widthFlag && (scanIndex - startIndex) >= width) { break; } if (charMatchFound) { scanIndex++; } } } // Indicates nothing was found. endIndex = scanIndex - startIndex; if (endIndex <= 0) { scanOK = false; break; } if (!discardFlag) { string str = new string(scanArr, startIndex, endIndex); testAndSetVar(interp, argv, argIndex++, TclString.newInstance(str)); } break; } default: { errorBadField(interp, ch); } break; } // As long as the scan was successful (scanOK), the format // specifier did not contain a '*' (discardFlag), and // we are not at the end of the scanArr (scanArrDone); // increment the num of vars set in the interp. Otherwise // increment the number of valid format specifiers. if (scanOK && !discardFlag && !scanArrDone) { numMatched++; } else if ((scanArrDone || !scanOK) && !discardFlag) { numUnMatched++; } frmtIndex++; } else if (scanIndex < scanArr.Length && scanArr[scanIndex] == frmtArr[frmtIndex]) { // No '%' was found, but the characters matched scanIndex++; frmtIndex++; } else { // No '%' found and the characters int frmtArr & scanArr // did not match. frmtIndex++; } } // The numMatched is the return value: a count of the num of vars set. // While the numUnMatched is the number of formatSpecifiers that // passed the parsing stage, but did not match anything in the scanArr. if ((numMatched + numUnMatched) != (argv.Length - 3)) { errorDiffVars(interp); } interp.setResult(TclInteger.newInstance(numMatched)); return(TCL.CompletionCode.RETURN); }
public static void Tcl_BackgroundError(Interp interp) { interp.setErrorCode(TclInteger.newInstance(TCL_ERROR)); interp.addErrorInfo("Background Error"); }
public static TclObject Tcl_NewIntObj(int value) { return(TclInteger.newInstance(value)); }
public TclObject get() { TclObject obj; TclToken token; string typeString; int nextIndex; string cmd; int i; System.Diagnostics.Debug.WriteLine("Entered TclParse.get()"); System.Diagnostics.Debug.WriteLine("numTokens is " + numTokens); obj = TclList.newInstance(); try { if (commentSize > 0) { TclList.append(interp, obj, TclString.newInstance(new string( inString, commentStart, commentSize ))); } else { TclList.append(interp, obj, TclString.newInstance("-")); } if (commandStart >= (endIndex + 1)) { commandStart = endIndex; } cmd = new string( inString, commandStart, commandSize ); TclList.append(interp, obj, TclString.newInstance(cmd)); TclList.append(interp, obj, TclInteger.newInstance(numWords)); for (i = 0; i < numTokens; i++) { System.Diagnostics.Debug.WriteLine("processing token " + i); token = tokenList[i]; switch (token.type) { case Parser.TCL_TOKEN_WORD: typeString = "word"; break; case Parser.TCL_TOKEN_SIMPLE_WORD: typeString = "simple"; break; case Parser.TCL_TOKEN_EXPAND_WORD: typeString = "expand"; break; case Parser.TCL_TOKEN_TEXT: typeString = "text"; break; case Parser.TCL_TOKEN_BS: typeString = "backslash"; break; case Parser.TCL_TOKEN_COMMAND: typeString = "command"; break; case Parser.TCL_TOKEN_VARIABLE: typeString = "variable"; break; default: typeString = "??"; break; } System.Diagnostics.Debug.WriteLine("typeString is " + typeString); TclList.append(interp, obj, TclString.newInstance(typeString)); TclList.append(interp, obj, TclString.newInstance(token.TokenString)); TclList.append(interp, obj, TclInteger.newInstance(token.numComponents)); } nextIndex = commandStart + commandSize; TclList.append(interp, obj, TclString.newInstance(new string( inString, nextIndex, (endIndex - nextIndex)))); } catch (TclException e) { // Do Nothing. } return(obj); }
/// <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); }
public void traceProc(Interp interp, string name1, string name2, TCL.VarFlag flags) { // If the variable is unset, then recreate the trace and restore // the default value of the format string. if ((flags & TCL.VarFlag.TRACE_UNSETS) != 0) { if (((flags & TCL.VarFlag.TRACE_DESTROYED) != 0) && ((flags & TCL.VarFlag.INTERP_DESTROYED) == 0)) { interp.traceVar(name1, name2, new PrecTraceProc(), TCL.VarFlag.GLOBAL_ONLY | TCL.VarFlag.TRACE_WRITES | TCL.VarFlag.TRACE_READS | TCL.VarFlag.TRACE_UNSETS); Util.precision = Util.DEFAULT_PRECISION; } return; } // When the variable is read, reset its value from our shared // value. This is needed in case the variable was modified in // some other interpreter so that this interpreter's value is // out of date. if ((flags & TCL.VarFlag.TRACE_READS) != 0) { interp.setVar(name1, name2, TclInteger.newInstance(Util.precision), flags & TCL.VarFlag.GLOBAL_ONLY); return; } // The variable is being written. Check the new value and disallow // it if it isn't reasonable. // // (ToDo) Disallow it if this is a safe interpreter (we don't want // safe interpreters messing up the precision of other // interpreters). TclObject tobj = null; try { tobj = interp.getVar(name1, name2, (flags & TCL.VarFlag.GLOBAL_ONLY)); } catch (TclException e) { // Do nothing when var does not exist. } string value; if (tobj != null) { value = tobj.ToString(); } else { value = ""; } StrtoulResult r = Util.strtoul(value, 0, 10); if ((r == null) || (r.value <= 0) || (r.value > TCL_MAX_PREC) || (r.value > 100) || (r.index == 0) || (r.index != value.Length)) { interp.setVar(name1, name2, TclInteger.newInstance(Util.precision), TCL.VarFlag.GLOBAL_ONLY); throw new TclException(interp, "improper value for precision"); } Util.precision = (int)r.value; }
public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv) { bool nocase = false; bool indices = false; try { int i = 1; while (argv[i].ToString().StartsWith("-")) { int index = TclIndex.get(interp, argv[i], validOpts, "switch", 0); i++; switch (index) { case OPT_INDICES: { indices = true; break; } case OPT_NOCASE: { nocase = true; break; } case OPT_LAST: { goto opts_brk; } } } opts_brk :; TclObject exp = TclString.newInstance(argv[i++].ToString().Replace("\\d", "[0-9]")); string inString = argv[i++].ToString(); int matches = argv.Length - i; Regexp r = TclRegexp.compile(interp, exp, nocase); int[] args = new int[matches * 2]; bool matched = r.match(inString, args); if (matched) { for (int match = 0; i < argv.Length; i++) { TclObject obj; int start = args[match++]; int end = args[match++]; if (indices) { if (end >= 0) { end--; } obj = TclList.newInstance(); TclList.append(interp, obj, TclInteger.newInstance(start)); TclList.append(interp, obj, TclInteger.newInstance(end)); } else { string range = (start >= 0)?inString.Substring(start, (end) - (start)):""; obj = TclString.newInstance(range); } try { interp.setVar(argv[i].ToString(), obj, 0); } catch (TclException e) { throw new TclException(interp, "couldn't set variable \"" + argv[i] + "\""); } } } interp.setResult(matched); } catch (System.IndexOutOfRangeException e) { throw new TclNumArgsException(interp, 1, argv, "?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?"); } return(TCL.CompletionCode.RETURN); }
/// <summary>---------------------------------------------------------------------- /// /// Tcl_StringObjCmd -> StringCmd.cmdProc /// /// This procedure is invoked to process the "string" Tcl command. /// See the user documentation for details on what it does. /// /// Results: /// None. /// /// Side effects: /// See the user documentation. /// /// ---------------------------------------------------------------------- /// </summary> public TCL.CompletionCode cmdProc(Interp interp, TclObject[] objv) { if (objv.Length < 2) { throw new TclNumArgsException(interp, 1, objv, "option arg ?arg ...?"); } int index = TclIndex.get(interp, objv[1], options, "option", 0); switch (index) { case STR_EQUAL: case STR_COMPARE: { if (objv.Length < 4 || objv.Length > 7) { throw new TclNumArgsException(interp, 2, objv, "?-nocase? ?-length int? string1 string2"); } bool nocase = false; int reqlength = -1; for (int i = 2; i < objv.Length - 2; i++) { string string2 = objv[i].ToString(); int length2 = string2.Length; if ((length2 > 1) && "-nocase".StartsWith(string2)) { nocase = true; } else if ((length2 > 1) && "-length".StartsWith(string2)) { if (i + 1 >= objv.Length - 2) { throw new TclNumArgsException(interp, 2, objv, "?-nocase? ?-length int? string1 string2"); } reqlength = TclInteger.get(interp, objv[++i]); } else { throw new TclException(interp, "bad option \"" + string2 + "\": must be -nocase or -length"); } } string string1 = objv[objv.Length - 2].ToString(); string string3 = objv[objv.Length - 1].ToString(); int length1 = string1.Length; int length3 = string3.Length; // This is the min length IN BYTES of the two strings int length = (length1 < length3)?length1:length3; int match; if (reqlength == 0) { // Anything matches at 0 chars, right? match = 0; } else if (nocase || ((reqlength > 0) && (reqlength <= length))) { // In Java, strings are always encoded in unicode, so we do // not need to worry about individual char lengths // Do the reqlength check again, against 0 as well for // the benfit of nocase if ((reqlength > 0) && (reqlength < length)) { length = reqlength; } else if (reqlength < 0) { // The requested length is negative, so we ignore it by // setting it to the longer of the two lengths. reqlength = (length1 > length3)?length1:length3; } if (nocase) { string1 = string1.ToLower(); string3 = string3.ToLower(); } match = System.Globalization.CultureInfo.InvariantCulture.CompareInfo.Compare(string1, 0, length, string3, 0, length, System.Globalization.CompareOptions.Ordinal); // match = string1.Substring(0, (length) - (0)).CompareTo(string3.Substring(0, (length) - (0))); if ((match == 0) && (reqlength > length)) { match = length1 - length3; } } else { match = System.Globalization.CultureInfo.InvariantCulture.CompareInfo.Compare(string1, 0, length, string3, 0, length, System.Globalization.CompareOptions.Ordinal); // ATK match = string1.Substring(0, (length) - (0)).CompareTo(string3.Substring(0, (length) - (0))); if (match == 0) { match = length1 - length3; } } if (index == STR_EQUAL) { interp.setResult((match != 0)?false:true); } else { interp.setResult(((match > 0)?1:(match < 0)?-1:0)); } break; } case STR_FIRST: { if (objv.Length < 4 || objv.Length > 5) { throw new TclNumArgsException(interp, 2, objv, "subString string ?startIndex?"); } string string1 = objv[2].ToString(); string string2 = objv[3].ToString(); int length2 = string2.Length; int start = 0; if (objv.Length == 5) { // If a startIndex is specified, we will need to fast // forward to that point in the string before we think // about a match. start = Util.getIntForIndex(interp, objv[4], length2 - 1); if (start >= length2) { interp.setResult(-1); return(TCL.CompletionCode.RETURN); } } if (string1.Length == 0) { interp.setResult(-1); } else { interp.setResult(string2.IndexOf(string1, start)); } break; } case STR_INDEX: { if (objv.Length != 4) { throw new TclNumArgsException(interp, 2, objv, "string charIndex"); } string string1 = objv[2].ToString(); int length1 = string1.Length; int i = Util.getIntForIndex(interp, objv[3], length1 - 1); if ((i >= 0) && (i < length1)) { interp.setResult(string1.Substring(i, (i + 1) - (i))); } break; } case STR_IS: { if (objv.Length < 4 || objv.Length > 7) { throw new TclNumArgsException(interp, 2, objv, "class ?-strict? ?-failindex var? str"); } index = TclIndex.get(interp, objv[2], isOptions, "class", 0); bool strict = false; TclObject failVarObj = null; if (objv.Length != 4) { for (int i = 3; i < objv.Length - 1; i++) { string string2 = objv[i].ToString(); int length2 = string2.Length; if ((length2 > 1) && "-strict".StartsWith(string2)) { strict = true; } else if ((length2 > 1) && "-failindex".StartsWith(string2)) { if (i + 1 >= objv.Length - 1) { throw new TclNumArgsException(interp, 3, objv, "?-strict? ?-failindex var? str"); } failVarObj = objv[++i]; } else { throw new TclException(interp, "bad option \"" + string2 + "\": must be -strict or -failindex"); } } } bool result = true; int failat = 0; // We get the objPtr so that we can short-cut for some classes // by checking the object type (int and double), but we need // the string otherwise, because we don't want any conversion // of type occuring (as, for example, Tcl_Get*FromObj would do TclObject obj = objv[objv.Length - 1]; string string1 = obj.ToString(); int length1 = string1.Length; if (length1 == 0) { if (strict) { result = false; } } switch (index) { case STR_IS_BOOL: case STR_IS_TRUE: case STR_IS_FALSE: { if (obj.InternalRep is TclBoolean) { if (((index == STR_IS_TRUE) && !TclBoolean.get(interp, obj)) || ((index == STR_IS_FALSE) && TclBoolean.get(interp, obj))) { result = false; } } else { try { bool i = TclBoolean.get(null, obj); if (((index == STR_IS_TRUE) && !i) || ((index == STR_IS_FALSE) && i)) { result = false; } } catch (TclException e) { result = false; } } break; } case STR_IS_DOUBLE: { if ((obj.InternalRep is TclDouble) || (obj.InternalRep is TclInteger)) { break; } // This is adapted from Tcl_GetDouble // // The danger in this function is that // "12345678901234567890" is an acceptable 'double', // but will later be interp'd as an int by something // like [expr]. Therefore, we check to see if it looks // like an int, and if so we do a range check on it. // If strtoul gets to the end, we know we either // received an acceptable int, or over/underflow if (Expression.looksLikeInt(string1, length1, 0)) { char c = string1[0]; int signIx = (c == '-' || c == '+')?1:0; StrtoulResult res = Util.strtoul(string1, signIx, 0); if (res.index == length1) { if (res.errno == TCL.INTEGER_RANGE) { result = false; failat = -1; } break; } } char c2 = string1[0]; int signIx2 = (c2 == '-' || c2 == '+')?1:0; StrtodResult res2 = Util.strtod(string1, signIx2); if (res2.errno == TCL.DOUBLE_RANGE) { // if (errno == ERANGE), then it was an over/underflow // problem, but in this method, we only want to know // yes or no, so bad flow returns 0 (false) and sets // the failVarObj to the string length. result = false; failat = -1; } else if (res2.index == 0) { // In this case, nothing like a number was found result = false; failat = 0; } else { // Go onto SPACE, since we are // allowed trailing whitespace failat = res2.index; for (int i = res2.index; i < length1; i++) { if (!System.Char.IsWhiteSpace(string1[i])) { result = false; break; } } } break; } case STR_IS_INT: { if (obj.InternalRep is TclInteger) { break; } bool isInteger = true; try { TclInteger.get(null, obj); } catch (TclException e) { isInteger = false; } if (isInteger) { break; } char c = string1[0]; int signIx = (c == '-' || c == '+')?1:0; StrtoulResult res = Util.strtoul(string1, signIx, 0); if (res.errno == TCL.INTEGER_RANGE) { // if (errno == ERANGE), then it was an over/underflow // problem, but in this method, we only want to know // yes or no, so bad flow returns false and sets // the failVarObj to the string length. result = false; failat = -1; } else if (res.index == 0) { // In this case, nothing like a number was found result = false; failat = 0; } else { // Go onto SPACE, since we are // allowed trailing whitespace failat = res.index; for (int i = res.index; i < length1; i++) { if (!System.Char.IsWhiteSpace(string1[i])) { result = false; break; } } } break; } default: { for (failat = 0; failat < length1; failat++) { char c = string1[failat]; switch (index) { case STR_IS_ASCII: result = c < 0x80; break; case STR_IS_ALNUM: result = System.Char.IsLetterOrDigit(c); break; case STR_IS_ALPHA: result = System.Char.IsLetter(c); break; case STR_IS_DIGIT: result = System.Char.IsDigit(c); break; case STR_IS_GRAPH: result = ((1 << (int)System.Char.GetUnicodeCategory(c)) & PRINT_BITS) != 0 && c != ' '; break; case STR_IS_PRINT: result = ((1 << (int)System.Char.GetUnicodeCategory(c)) & PRINT_BITS) != 0; break; case STR_IS_PUNCT: result = ((1 << (int)System.Char.GetUnicodeCategory(c)) & PUNCT_BITS) != 0; break; case STR_IS_UPPER: result = System.Char.IsUpper(c); break; case STR_IS_SPACE: result = System.Char.IsWhiteSpace(c); break; case STR_IS_CONTROL: result = (System.Char.GetUnicodeCategory(c) == System.Globalization.UnicodeCategory.Control); break; case STR_IS_LOWER: result = System.Char.IsLower(c); break; case STR_IS_WORD: result = ((1 << (int)System.Char.GetUnicodeCategory(c)) & WORD_BITS) != 0; break; case STR_IS_XDIGIT: result = "0123456789ABCDEFabcdef".IndexOf(c) >= 0; break; default: throw new TclRuntimeError("unimplemented"); } if (!result) { break; } } } break; } // Only set the failVarObj when we will return 0 // and we have indicated a valid fail index (>= 0) if ((!result) && (failVarObj != null)) { interp.setVar(failVarObj, TclInteger.newInstance(failat), 0); } interp.setResult(result); break; } case STR_LAST: { if (objv.Length < 4 || objv.Length > 5) { throw new TclNumArgsException(interp, 2, objv, "subString string ?startIndex?"); } string string1 = objv[2].ToString(); string string2 = objv[3].ToString(); int length2 = string2.Length; int start = 0; if (objv.Length == 5) { // If a startIndex is specified, we will need to fast // forward to that point in the string before we think // about a match. start = Util.getIntForIndex(interp, objv[4], length2 - 1); if (start < 0) { interp.setResult(-1); break; } else if (start < length2) { string2 = string2.Substring(0, (start + 1) - (0)); } } if (string1.Length == 0) { interp.setResult(-1); } else { interp.setResult(string2.LastIndexOf(string1)); } break; } case STR_BYTELENGTH: if (objv.Length != 3) { throw new TclNumArgsException(interp, 2, objv, "string"); } interp.setResult(Utf8Count(objv[2].ToString())); break; case STR_LENGTH: { if (objv.Length != 3) { throw new TclNumArgsException(interp, 2, objv, "string"); } interp.setResult(objv[2].ToString().Length); break; } case STR_MAP: { if (objv.Length < 4 || objv.Length > 5) { throw new TclNumArgsException(interp, 2, objv, "?-nocase? charMap string"); } bool nocase = false; if (objv.Length == 5) { string string2 = objv[2].ToString(); int length2 = string2.Length; if ((length2 > 1) && "-nocase".StartsWith(string2)) { nocase = true; } else { throw new TclException(interp, "bad option \"" + string2 + "\": must be -nocase"); } } TclObject[] mapElemv = TclList.getElements(interp, objv[objv.Length - 2]); if (mapElemv.Length == 0) { // empty charMap, just return whatever string was given interp.setResult(objv[objv.Length - 1]); } else if ((mapElemv.Length % 2) != 0) { // The charMap must be an even number of key/value items throw new TclException(interp, "char map list unbalanced"); } string string1 = objv[objv.Length - 1].ToString(); string cmpString1; if (nocase) { cmpString1 = string1.ToLower(); } else { cmpString1 = string1; } int length1 = string1.Length; if (length1 == 0) { // Empty input string, just stop now break; } // Precompute pointers to the unicode string and length. // This saves us repeated function calls later, // significantly speeding up the algorithm. string[] mapStrings = new string[mapElemv.Length]; int[] mapLens = new int[mapElemv.Length]; for (int ix = 0; ix < mapElemv.Length; ix++) { mapStrings[ix] = mapElemv[ix].ToString(); mapLens[ix] = mapStrings[ix].Length; } string[] cmpStrings; if (nocase) { cmpStrings = new string[mapStrings.Length]; for (int ix = 0; ix < mapStrings.Length; ix++) { cmpStrings[ix] = mapStrings[ix].ToLower(); } } else { cmpStrings = mapStrings; } TclObject result = TclString.newInstance(""); int p, str1; for (p = 0, str1 = 0; str1 < length1; str1++) { for (index = 0; index < mapStrings.Length; index += 2) { // Get the key string to match on string string2 = mapStrings[index]; int length2 = mapLens[index]; if ((length2 > 0) && (cmpString1.Substring(str1).StartsWith(cmpStrings[index]))) { if (p != str1) { // Put the skipped chars onto the result first TclString.append(result, string1.Substring(p, (str1) - (p))); p = str1 + length2; } else { p += length2; } // Adjust len to be full length of matched string str1 = p - 1; // Append the map value to the unicode string TclString.append(result, mapStrings[index + 1]); break; } } } if (p != str1) { // Put the rest of the unmapped chars onto result TclString.append(result, string1.Substring(p, (str1) - (p))); } interp.setResult(result); break; } case STR_MATCH: { if (objv.Length < 4 || objv.Length > 5) { throw new TclNumArgsException(interp, 2, objv, "?-nocase? pattern string"); } string string1, string2; if (objv.Length == 5) { string inString = objv[2].ToString(); if (!((inString.Length > 1) && "-nocase".StartsWith(inString))) { throw new TclException(interp, "bad option \"" + inString + "\": must be -nocase"); } string1 = objv[4].ToString().ToLower(); string2 = objv[3].ToString().ToLower(); } else { string1 = objv[3].ToString(); string2 = objv[2].ToString(); } interp.setResult(Util.stringMatch(string1, string2)); break; } case STR_RANGE: { if (objv.Length != 5) { throw new TclNumArgsException(interp, 2, objv, "string first last"); } string string1 = objv[2].ToString(); int length1 = string1.Length; int first = Util.getIntForIndex(interp, objv[3], length1 - 1); if (first < 0) { first = 0; } int last = Util.getIntForIndex(interp, objv[4], length1 - 1); if (last >= length1) { last = length1 - 1; } if (first > last) { interp.resetResult(); } else { interp.setResult(string1.Substring(first, (last + 1) - (first))); } break; } case STR_REPEAT: { if (objv.Length != 4) { throw new TclNumArgsException(interp, 2, objv, "string count"); } int count = TclInteger.get(interp, objv[3]); string string1 = objv[2].ToString(); if (string1.Length > 0) { TclObject tstr = TclString.newInstance(""); for (index = 0; index < count; index++) { TclString.append(tstr, string1); } interp.setResult(tstr); } break; } case STR_REPLACE: { if (objv.Length < 5 || objv.Length > 6) { throw new TclNumArgsException(interp, 2, objv, "string first last ?string?"); } string string1 = objv[2].ToString(); int length1 = string1.Length - 1; int first = Util.getIntForIndex(interp, objv[3], length1); int last = Util.getIntForIndex(interp, objv[4], length1); if ((last < first) || (first > length1) || (last < 0)) { interp.setResult(objv[2]); } else { if (first < 0) { first = 0; } string start = string1.Substring(first); int ind = ((last > length1)?length1:last) - first + 1; string end; if (ind <= 0) { end = start; } else if (ind >= start.Length) { end = ""; } else { end = start.Substring(ind); } TclObject tstr = TclString.newInstance(string1.Substring(0, (first) - (0))); if (objv.Length == 6) { TclString.append(tstr, objv[5]); } if (last < length1) { TclString.append(tstr, end); } interp.setResult(tstr); } break; } case STR_TOLOWER: case STR_TOUPPER: case STR_TOTITLE: { if (objv.Length < 3 || objv.Length > 5) { throw new TclNumArgsException(interp, 2, objv, "string ?first? ?last?"); } string string1 = objv[2].ToString(); if (objv.Length == 3) { if (index == STR_TOLOWER) { interp.setResult(string1.ToLower()); } else if (index == STR_TOUPPER) { interp.setResult(string1.ToUpper()); } else { interp.setResult(Util.toTitle(string1)); } } else { int length1 = string1.Length - 1; int first = Util.getIntForIndex(interp, objv[3], length1); if (first < 0) { first = 0; } int last = first; if (objv.Length == 5) { last = Util.getIntForIndex(interp, objv[4], length1); } if (last >= length1) { last = length1; } if (last < first) { interp.setResult(objv[2]); break; } string string2; System.Text.StringBuilder buf = new System.Text.StringBuilder(); buf.Append(string1.Substring(0, (first) - (0))); if (last + 1 > length1) { string2 = string1.Substring(first); } else { string2 = string1.Substring(first, (last + 1) - (first)); } if (index == STR_TOLOWER) { buf.Append(string2.ToLower()); } else if (index == STR_TOUPPER) { buf.Append(string2.ToUpper()); } else { buf.Append(Util.toTitle(string2)); } if (last + 1 <= length1) { buf.Append(string1.Substring(last + 1)); } interp.setResult(buf.ToString()); } break; } case STR_TRIM: { if (objv.Length == 3) { // Case 1: "string trim str" -- // Remove leading and trailing white space interp.setResult(objv[2].ToString().Trim()); } else if (objv.Length == 4) { // Case 2: "string trim str chars" -- // Remove leading and trailing chars in the chars set string tmp = Util.TrimLeft(objv[2].ToString(), objv[3].ToString()); interp.setResult(Util.TrimRight(tmp, objv[3].ToString())); } else { // Case 3: Wrong # of args throw new TclNumArgsException(interp, 2, objv, "string ?chars?"); } break; } case STR_TRIMLEFT: { if (objv.Length == 3) { // Case 1: "string trimleft str" -- // Remove leading and trailing white space interp.setResult(Util.TrimLeft(objv[2].ToString())); } else if (objv.Length == 4) { // Case 2: "string trimleft str chars" -- // Remove leading and trailing chars in the chars set interp.setResult(Util.TrimLeft(objv[2].ToString(), objv[3].ToString())); } else { // Case 3: Wrong # of args throw new TclNumArgsException(interp, 2, objv, "string ?chars?"); } break; } case STR_TRIMRIGHT: { if (objv.Length == 3) { // Case 1: "string trimright str" -- // Remove leading and trailing white space interp.setResult(Util.TrimRight(objv[2].ToString())); } else if (objv.Length == 4) { // Case 2: "string trimright str chars" -- // Remove leading and trailing chars in the chars set interp.setResult(Util.TrimRight(objv[2].ToString(), objv[3].ToString())); } else { // Case 3: Wrong # of args throw new TclNumArgsException(interp, 2, objv, "string ?chars?"); } break; } case STR_WORDEND: { if (objv.Length != 4) { throw new TclNumArgsException(interp, 2, objv, "string index"); } string string1 = objv[2].ToString(); char[] strArray = string1.ToCharArray(); int cur; int length1 = string1.Length; index = Util.getIntForIndex(interp, objv[3], length1 - 1); if (index < 0) { index = 0; } if (index >= length1) { interp.setResult(length1); return(TCL.CompletionCode.RETURN); } for (cur = index; cur < length1; cur++) { char c = strArray[cur]; if (((1 << (int)System.Char.GetUnicodeCategory(c)) & WORD_BITS) == 0) { break; } } if (cur == index) { cur = index + 1; } interp.setResult(cur); break; } case STR_WORDSTART: { if (objv.Length != 4) { throw new TclNumArgsException(interp, 2, objv, "string index"); } string string1 = objv[2].ToString(); char[] strArray = string1.ToCharArray(); int cur; int length1 = string1.Length; index = Util.getIntForIndex(interp, objv[3], length1 - 1); if (index > length1) { index = length1 - 1; } if (index < 0) { interp.setResult(0); return(TCL.CompletionCode.RETURN); } for (cur = index; cur >= 0; cur--) { char c = strArray[cur]; if (((1 << (int)System.Char.GetUnicodeCategory(c)) & WORD_BITS) == 0) { break; } } if (cur != index) { cur += 1; } interp.setResult(cur); break; } } return(TCL.CompletionCode.RETURN); }
public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv) { int firstWord; /* Index to the first non-switch arg */ int argLen = argv.Length; /* No of args to copy to argStrs */ int exit; /* denotes exit status of process */ int errorBytes = 0; /* number of bytes of process stderr */ //bool background; /* Indicates a bg process */ //bool keepNewline; /* Retains newline in pipline output */ System.Diagnostics.Process p; /* The exec-ed process */ string argStr; /* Conversion of argv to a string */ StringBuilder sbuf; /* * Check for a leading "-keepnewline" argument. */ for (firstWord = 1; firstWord < argLen; firstWord++) { argStr = argv[firstWord].ToString(); if ((argStr.Length > 0) && (argStr[0] == '-')) { //if (argStr.Equals("-keepnewline")) //{ // keepNewline = true; //} //else if (argStr.Equals("--")) { firstWord++; break; } else { throw new TclException(interp, "bad switch \"" + argStr + "\": must be -keepnewline or --"); } } } if (argLen <= firstWord) { throw new TclNumArgsException(interp, 1, argv, "?switches? arg ?arg ...?"); } /* * See if the command is to be run in background. * Currently this does nothing, it is just for compatibility */ //if (argv[argLen - 1].ToString().Equals("&")) //{ // argLen--; // background = true; //} try { /* * It is necessary to perform system specific * operations before calling exec. For now Solaris * and Windows execs are somewhat supported, in all other cases * we simply call exec and give it our "best shot" */ if (execMethod != null) { p = execReflection(interp, argv, firstWord, argLen); } else if (Util.Unix) { p = execUnix(interp, argv, firstWord, argLen); } else if (Util.Windows) { p = execWin(interp, argv, firstWord, argLen); } else { p = execDefault(interp, argv, firstWord, argLen); } //note to self : buffer reading should be done in //a separate thread and not by calling waitFor() //because a process that is waited for can block //Wait for the process to finish running, try { p.Start(); p.WaitForExit(); exit = p.ExitCode; } catch (Exception e) { throw new TclException(interp, "exception in exec process: " + e.Message); } //Make buffer for the results of the subprocess execution sbuf = new StringBuilder(); //read data on stdout stream into result buffer readStreamIntoBuffer(p.StandardOutput.BaseStream, sbuf); //if there is data on the stderr stream then append //this data onto the result StringBuffer //check for the special case where there is no error //data but the process returns an error result errorBytes = readStreamIntoBuffer(p.StandardError.BaseStream, sbuf); if ((errorBytes == 0) && (exit != 0)) { sbuf.Append("child process exited abnormally"); } //If the last character of the result buffer is a newline, then //remove the newline character (the newline would just confuse //things). Finally, we set pass the result to the interpreter. // Tcl supports lots of child status conditions. // Unfortunately, we can only find the child's // exit status using the Java API if (exit != 0) { TclObject childstatus = TclList.newInstance(); TclList.append(interp, childstatus, TclString.newInstance("CHILDSTATUS")); // We don't know how to find the child's pid TclList.append(interp, childstatus, TclString.newInstance("?PID?")); TclList.append(interp, childstatus, TclInteger.newInstance(exit)); interp.setErrorCode(childstatus); } //when the subprocess writes to its stderr stream or returns //a non zero result we generate an error if ((exit != 0) || (errorBytes != 0)) { throw new TclException(interp, sbuf.ToString()); } //otherwise things went well so set the result interp.setResult(sbuf.ToString()); } catch (IOException e) { //if exec fails we end up catching the exception here throw new TclException(interp, "couldn't execute \"" + argv[firstWord].ToString() + "\": no such file or directory"); } catch (System.Threading.ThreadInterruptedException e) { /* * Do Nothing... */ } return(TCL.CompletionCode.RETURN); }