/// <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 static int FormatNumber(Interp interp, char type, TclObject src, byte[] resultBytes, int cursor) { if (type == 'd') { double dvalue = TclDouble.get(interp, src); System.IO.MemoryStream ms = new System.IO.MemoryStream(resultBytes, cursor, 8); System.IO.BinaryWriter writer = new System.IO.BinaryWriter(ms); writer.Write(dvalue); cursor += 8; writer.Close(); ms.Close(); } else if (type == 'f') { float fvalue = (float)TclDouble.get(interp, src); System.IO.MemoryStream ms = new System.IO.MemoryStream(resultBytes, cursor, 4); System.IO.BinaryWriter writer = new System.IO.BinaryWriter(ms); writer.Write(fvalue); cursor += 4; writer.Close(); ms.Close(); } else { int value = TclInteger.get(interp, src); if (type == 'c') { resultBytes[cursor++] = (byte)value; } else if (type == 's') { resultBytes[cursor++] = (byte)value; resultBytes[cursor++] = (byte)(value >> 8); } else if (type == 'S') { resultBytes[cursor++] = (byte)(value >> 8); resultBytes[cursor++] = (byte)value; } else if (type == 'i') { resultBytes[cursor++] = (byte)value; resultBytes[cursor++] = (byte)(value >> 8); resultBytes[cursor++] = (byte)(value >> 16); resultBytes[cursor++] = (byte)(value >> 24); } else if (type == 'I') { resultBytes[cursor++] = (byte)(value >> 24); resultBytes[cursor++] = (byte)(value >> 16); resultBytes[cursor++] = (byte)(value >> 8); resultBytes[cursor++] = (byte)value; } } return(cursor); }
/* *---------------------------------------------------------------------- * * InfoLevelCmd -- * * Called to implement the "info level" command that returns * information about the call stack. Handles the following syntax: * * info level ?number? * * Results: * Returns if successful, raises TclException otherwise. * * Side effects: * Returns a result in the interpreter's result object. * *---------------------------------------------------------------------- */ private static void InfoLevelCmd(Interp interp, TclObject[] objv) { int level; CallFrame frame; TclObject list; if (objv.Length == 2) { // just "info level" if (interp.varFrame == null) { interp.setResult(0); } else { interp.setResult(interp.varFrame.level); } return; } else if (objv.Length == 3) { level = TclInteger.get(interp, objv[2]); if (level <= 0) { if (interp.varFrame == null) { throw new TclException(interp, "bad level \"" + objv[2].ToString() + "\""); } level += interp.varFrame.level; } for (frame = interp.varFrame; frame != null; frame = frame.callerVar) { if (frame.level == level) { break; } } if ((frame == null) || frame.objv == null) { throw new TclException(interp, "bad level \"" + objv[2].ToString() + "\""); } list = TclList.newInstance(); for (int i = 0; i < frame.objv.Length; i++) { TclList.append(interp, list, TclString.newInstance(frame.objv[i])); } interp.setResult(list); return; } throw new TclNumArgsException(interp, 2, objv, "?number?"); }
public static int Tcl_GetIntFromObj(Interp interp, TclObject to, out int value) { try { value = TclInteger.get(interp, to); return(TCL.TCL_OK); } catch { value = 0; return(TCL.TCL_ERROR); } }
public static bool Tcl_GetInt(Interp interp, TclObject to, out u32 value) { try { value = (u32)TclInteger.get(interp, to); return(false); } catch { value = 0; return(true); } }
/// <summary> This procedure is invoked to process the "incr" Tcl command. /// See the user documentation for details on what it does. /// </summary> /// <exception cref=""> TclException if wrong # of args or increment is not an /// integer. /// </exception> public TCL.CompletionCode cmdProc(Interp interp, TclObject[] objv) { int incrAmount; TclObject newValue; if ((objv.Length != 2) && (objv.Length != 3)) { throw new TclNumArgsException(interp, 1, objv, "varName ?increment?"); } // Calculate the amount to increment by. if (objv.Length == 2) { incrAmount = 1; } else { try { incrAmount = TclInteger.get(interp, objv[2]); } catch (TclException e) { interp.addErrorInfo("\n (reading increment)"); throw; } } // Increment the variable's value. newValue = Var.incrVar(interp, objv[1], null, incrAmount, TCL.VarFlag.LEAVE_ERR_MSG); // FIXME: we need to look at this exception throwing problem again /* * if (newValue == null) { * return TCL_ERROR; * } */ // Set the interpreter's object result to refer to the variable's new // value object. interp.setResult(newValue); return(TCL.CompletionCode.RETURN); }
internal static int getIntForIndex(Interp interp, TclObject tobj, int endValue) { int length, offset; if (tobj.InternalRep is TclInteger) { return(TclInteger.get(interp, tobj)); } string bytes = tobj.ToString(); length = bytes.Length; string intforindex_error = "bad index \"" + bytes + "\": must be integer or end?-integer?" + checkBadOctal(interp, bytes); // FIXME : should we replace this call to regionMatches with a generic strncmp? if (!(String.Compare("end", 0, bytes, 0, (length > 3) ? 3 : length) == 0)) { try { offset = TclInteger.get(null, tobj); } catch (TclException e) { throw new TclException(interp, "bad index \"" + bytes + "\": must be integer or end?-integer?" + checkBadOctal(interp, bytes)); } return(offset); } if (length <= 3) { return(endValue); } else if (bytes[3] == '-') { // This is our limited string expression evaluator offset = Util.getInt(interp, bytes.Substring(3)); return(endValue + offset); } else { throw new TclException(interp, "bad index \"" + bytes + "\": must be integer or end?-integer?" + checkBadOctal(interp, bytes.Substring(3))); } }
/// <summary> See Tcl user documentation for details.</summary> public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv) { int code; if (argv.Length > 2) { throw new TclNumArgsException(interp, 1, argv, "?returnCode?"); } if (argv.Length == 2) { code = TclInteger.get(interp, argv[1]); } else { code = 0; } return(TCL.CompletionCode.EXIT); }
/// <summary> See Tcl user documentation for details.</summary> public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv) { int code; if (argv.Length > 2) { throw new TclNumArgsException(interp, 1, argv, "?returnCode?"); } if (argv.Length == 2) { code = TclInteger.get(interp, argv[1]); } else { code = 0; } System.Environment.Exit(code); return(TCL.CompletionCode.RETURN); }
private static void setDoubleFromAny(Interp interp, TclObject tobj) { InternalRep rep = tobj.InternalRep; if (rep is TclDouble) { /* * Do nothing. */ } else if (rep is TclBoolean) { /* * Short-cut. */ bool b = TclBoolean.get(interp, tobj); if (b) { tobj.InternalRep = new TclDouble(1.0); } else { tobj.InternalRep = new TclDouble(0.0); } } else if (rep is TclInteger) { /* * Short-cut. */ int i = TclInteger.get(interp, tobj); tobj.InternalRep = new TclDouble(i); } else { tobj.InternalRep = new TclDouble(interp, tobj.ToString()); } }
/// <summary> Called to convert the other object's internal rep to boolean. /// /// </summary> /// <param name="interp">current interpreter. /// </param> /// <param name="tobj">the TclObject to convert to use the /// representation provided by this class. /// </param> private static void setBooleanFromAny(Interp interp, TclObject tobj) { InternalRep rep = tobj.InternalRep; if (rep is TclBoolean) { /* * Do nothing. */ } else if (rep is TclInteger) { int i = TclInteger.get(interp, tobj); tobj.InternalRep = new TclBoolean(i != 0); } else { /* * (ToDo) other short-cuts */ tobj.InternalRep = new TclBoolean(interp, tobj.ToString()); } }
/// <summary> See Tcl user documentation for details.</summary> public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv) { if ((argv.Length < 2) || (argv.Length > 3)) { throw new TclNumArgsException(interp, 1, argv, "script ?count?"); } int count; if (argv.Length == 2) { count = 1; } else { count = TclInteger.get(interp, argv[2]); } long startTime = System.DateTime.Now.Ticks; for (int i = 0; i < count; i++) { interp.eval(argv[1], 0); } long endTime = System.DateTime.Now.Ticks; long uSecs = (((endTime - startTime) / 10) / count); if (uSecs == 1) { interp.setResult(TclString.newInstance("1 microsecond per iteration")); } else { interp.setResult(TclString.newInstance(uSecs + " microseconds per iteration")); } return(TCL.CompletionCode.RETURN); }
private const int GENERIC = 4; // Floating or exponential, // depending on exponent. %g /// <summary> This procedure is invoked to process the "format" Tcl command. /// See the user documentation for details on what it does. /// /// The first argument to the cmdProc is the formatString. The cmdProc /// simply copies all the chars into the sbuf until a '%' is found. At /// this point the cmdProc parces the formatString and determines the /// format parameters. The parcing of the formatString can be broken into /// six possible phases: /// /// Phase 0 - Simply Print: If the next char is % /// Phase 1 - XPG3 Position Specifier: If the format [1-n]$ is used /// Phase 2 - A Set of Flags: One or more of the following + - /// [space] 0 # /// Phase 3 - A Minimun Field Width Either [integer] or * /// Phase 4 - A Precision If the format .[integer] or .* /// Phase 5 - A Length Modifier If h is present /// Phase 6 - A Conversion Character If one of the following is used /// d u i o x X c s f E g G /// /// Any phase can skip ahead one or more phases, but are not allowed /// to move back to previous phases. Once the parameters are determined /// the cmdProc calls one of three private methods that returns a fully /// formatted string. This loop occurs for ever '%' in the formatString. /// </summary> public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv) { System.Text.StringBuilder sbuf; // Stores the return value of the parsed // format string StrtoulResult stoul; // A return object to the strtoul call char[] format; // The format argument is converted to a char // array and manipulated as such int phase; // Stores the current phase of the parsing int width; // Minimum field width int precision; // Field precision from field specifier int fmtFlags; // Used to store the format flags ( #,+,etc) int argIndex; // Index of argument to substitute next. int fmtIndex; // Used to locate end of the format fields. int endIndex; // Used to locate end of numerical fields. int intValue; // Generic storage variable long lngValue; // Store the TclInteger.get() result double dblValue; // Store the TclDouble.get() result bool noPercent; // Special case for speed: indicates there's // no field specifier, just a string to copy. bool xpgSet; // Indicates that xpg has been used for the // particular format of the main while loop bool gotXpg; // True means that an XPG3 %n$-style // specifier has been seen. bool gotSequential; // True means that a regular sequential // (non-XPG3) conversion specifier has // been seen. bool useShort; // Value to be printed is short // (half word). bool precisionSet; // Used for f, e, and E conversions bool cont; // Used for phase 3 if (argv.Length < 2) { throw new TclNumArgsException(interp, 1, argv, "formatString ?arg arg ...?"); } argIndex = 2; fmtIndex = 0; gotXpg = gotSequential = false; format = argv[1].ToString().ToCharArray(); sbuf = new System.Text.StringBuilder(); // So, what happens here is to scan the format string one % group // at a time, making many individual appends to the StringBuffer. while (fmtIndex < format.Length) { fmtFlags = phase = width = 0; noPercent = true; xpgSet = precisionSet = useShort = false; precision = -1; // Append all characters to sbuf that are not used for the // format specifier. if (format[fmtIndex] != '%') { int i; for (i = fmtIndex; (i < format.Length); i++) { if (format[i] == '%') { noPercent = false; break; } } sbuf.Append(new string(format, fmtIndex, i - fmtIndex)); fmtIndex = i; if (noPercent) { break; } } // If true, then a % has been indicated but we are at the end // of the format string. Call function to throw exception. if (fmtIndex + 1 >= format.Length) { errorEndMiddle(interp); } // Phase 0: // Check for %%. If true then simply write a single '%' // to the list. checkOverFlow(interp, format, fmtIndex + 1); if (format[fmtIndex + 1] == '%') { sbuf.Append("%"); fmtIndex += 2; // Re-enter the loop continue; } fmtIndex++; checkOverFlow(interp, format, fmtIndex); if (System.Char.IsDigit(format[fmtIndex])) { // Parce the format array looking for the end of // the number. stoul = strtoul(format, fmtIndex); intValue = (int)stoul.value; endIndex = stoul.index; if (format[endIndex] == '$') { if (intValue == 0) { errorBadIndex(interp, true); } // Phase 1: // Check for an XPG3-style %n$ specification. // Note: there must not be a mixture of XPG3 // specs and non-XPG3 specs in the same format string. if (gotSequential) { errorMixedXPG(interp); } gotXpg = true; xpgSet = true; phase = 2; fmtIndex = endIndex + 1; argIndex = intValue + 1; if ((argIndex < 2) || (argIndex >= argv.Length)) { errorBadIndex(interp, gotXpg); } } else { // Phase 3: // Format jumped straight to phase 3; Setting // width field. Again, verify that all format // specifiers are sequential. if (gotXpg) { errorMixedXPG(interp); } gotSequential = true; if (format[fmtIndex] != '0') { fmtIndex = endIndex; width = intValue; phase = 4; } } } else { if (gotXpg) { errorMixedXPG(interp); } gotSequential = true; } // Phase 2: // Setting the Format Flags. At this point the phase value // can be either zero or three. Anything greater is an // incorrect format. if (phase < 3) { checkOverFlow(interp, format, fmtIndex); char ch = format[fmtIndex]; cont = true; while (cont) { switch (ch) { case '-': { fmtFlags |= LEFT_JUSTIFY; break; } case '#': { fmtFlags |= ALT_OUTPUT; break; } case '0': { fmtFlags |= PAD_W_ZERO; break; } case ' ': { fmtFlags |= SPACE_OR_SIGN; break; } case '+': { fmtFlags |= SHOW_SIGN; break; } default: { cont = false; } break; } if (cont) { fmtIndex++; checkOverFlow(interp, format, fmtIndex); ch = format[fmtIndex]; } } phase = 3; } // Phase 3: // Setting width field. Partially redundant code from the // Phase 1 if/else statement, but this is made to run fast. checkOverFlow(interp, format, fmtIndex); if (System.Char.IsDigit(format[fmtIndex])) { stoul = strtoul(format, fmtIndex); width = (int)stoul.value; fmtIndex = stoul.index; } else if (format[fmtIndex] == '*') { if (argv.Length > argIndex) { width = TclInteger.get(interp, argv[argIndex]); if (width < 0) { width = -width; fmtFlags |= LEFT_JUSTIFY; } argIndex++; fmtIndex++; } } // Phase 4: // Setting the precision field. checkOverFlow(interp, format, fmtIndex); if (format[fmtIndex] == '.') { fmtIndex++; checkOverFlow(interp, format, fmtIndex); if (System.Char.IsDigit(format[fmtIndex])) { precisionSet = true; stoul = strtoul(format, fmtIndex); precision = (int)stoul.value; fmtIndex = stoul.index; } else if (format[fmtIndex] == '*') { if (argv.Length > argIndex) { precisionSet = true; precision = TclInteger.get(interp, argv[argIndex]); argIndex++; fmtIndex++; checkOverFlow(interp, format, fmtIndex); } } else { // Format field had a '.' without an integer or '*' // preceeding it (eg %2.d or %2.-5d) errorBadField(interp, format[fmtIndex]); } } // Phase 5: // Setting the length modifier. if (format[fmtIndex] == 'h') { fmtIndex++; checkOverFlow(interp, format, fmtIndex); useShort = true; } else if (format[fmtIndex] == 'l') { fmtIndex++; checkOverFlow(interp, format, fmtIndex); // 'l' is ignored, but should still be processed. } if ((argIndex < 2) || (argIndex >= argv.Length)) { errorBadIndex(interp, gotXpg); } // Phase 6: // Setting conversion field. // At this point, variables are initialized as follows: // // width The specified field width. This is always // non-negative. Zero is the default. // precision The specified precision. The default // is -1. // argIndex The argument index from the argv array // for the appropriate arg. // fmtFlags The format flags are set via bitwise // operations. Below are the bits // and their meanings. // ALT_OUTPUT set if a '#' is present. // SHOW_SIGN set if a '+' is present. // SPACE_OR_SIGN set if a ' ' is present. // LEFT_JUSTIFY set if a '-' is present or if the // field width was negative. // PAD_W_ZERO set if a '0' is present string strValue = ""; char index = format[fmtIndex]; switch (index) { case 'u': case 'd': case 'o': case 'x': case 'X': case 'i': { if (index == 'u') { // Since Java does not provide unsigned ints we need to // make our own. If the value is negative we need to // clear out all of the leading bits from the 33rd bit // and on. The result is a long value equal to that // of an unsigned int. lngValue = (long)TclInteger.get(interp, argv[argIndex]); if (lngValue < 0) { lngValue = (lngValue << 32); lngValue = (SupportClass.URShift(lngValue, 32)); } } else { fmtFlags |= SIGNED_VALUE; lngValue = (long)TclInteger.get(interp, argv[argIndex]); } // If the useShort option has been selected, we need // to clear all but the first 16 bits. if (useShort) { lngValue = (lngValue << 48); lngValue = (lngValue >> 48); } if (index == 'o') { sbuf.Append(cvtLngToStr(lngValue, width, precision, fmtFlags, 8, "01234567".ToCharArray(), "0")); } else if (index == 'x') { sbuf.Append(cvtLngToStr(lngValue, width, precision, fmtFlags, 16, "0123456789abcdef".ToCharArray(), "0x")); } else if (index == 'X') { sbuf.Append(cvtLngToStr(lngValue, width, precision, fmtFlags, 16, "0123456789ABCDEF".ToCharArray(), "0X")); } else { sbuf.Append(cvtLngToStr(lngValue, width, precision, fmtFlags, 10, "0123456789".ToCharArray(), "")); } break; } case 'c': { intValue = 0; char[] arr = new char[] { (char)TclInteger.get(interp, argv[argIndex]) }; strValue = new string(arr); sbuf.Append(cvtStrToStr(strValue, width, precision, fmtFlags)); break; } case 's': { strValue = argv[argIndex].ToString(); sbuf.Append(cvtStrToStr(strValue, width, precision, fmtFlags)); break; } case 'f': { dblValue = TclDouble.get(interp, argv[argIndex]); sbuf.Append(cvtDblToStr(dblValue, width, precision, fmtFlags, 10, "0123456789".ToCharArray(), "", FLOAT)); break; } case 'e': { dblValue = TclDouble.get(interp, argv[argIndex]); sbuf.Append(cvtDblToStr(dblValue, width, precision, fmtFlags, 10, "e".ToCharArray(), "", EXP)); break; } case 'E': { dblValue = TclDouble.get(interp, argv[argIndex]); sbuf.Append(cvtDblToStr(dblValue, width, precision, fmtFlags, 10, "E".ToCharArray(), "", EXP)); break; } case 'g': { dblValue = TclDouble.get(interp, argv[argIndex]); sbuf.Append(cvtDblToStr(dblValue, width, precision, fmtFlags, 10, "e".ToCharArray(), "", GENERIC)); break; } case 'G': { dblValue = TclDouble.get(interp, argv[argIndex]); sbuf.Append(cvtDblToStr(dblValue, width, precision, fmtFlags, 10, "E".ToCharArray(), "", GENERIC)); break; } default: { errorBadField(interp, format[fmtIndex]); } break; } fmtIndex++; argIndex++; } interp.setResult(sbuf.ToString()); return(TCL.CompletionCode.RETURN); }
/* *----------------------------------------------------------------------------- * * cmdProc -- * * This procedure is invoked to process the "lsearch" Tcl command. * See the user documentation for details on what it does. * * Results: * None. * * Side effects: * See the user documentation. * *----------------------------------------------------------------------------- */ public TCL.CompletionCode cmdProc(Interp interp, TclObject[] objv) { int mode = GLOB; int dataType = ASCII; bool isIncreasing = true; TclObject pattern; TclObject list; if (objv.Length < 3) { throw new TclNumArgsException(interp, 1, objv, "?options? list pattern"); } for (int i = 1; i < objv.Length - 2; i++) { switch (TclIndex.get(interp, objv[i], options, "option", 0)) { case LSEARCH_ASCII: dataType = ASCII; break; case LSEARCH_DECREASING: isIncreasing = false; break; case LSEARCH_DICTIONARY: dataType = DICTIONARY; break; case LSEARCH_EXACT: mode = EXACT; break; case LSEARCH_INCREASING: isIncreasing = true; break; case LSEARCH_INTEGER: dataType = INTEGER; break; case LSEARCH_GLOB: mode = GLOB; break; case LSEARCH_REAL: dataType = REAL; break; case LSEARCH_REGEXP: mode = REGEXP; break; case LSEARCH_SORTED: mode = SORTED; break; } } // Make sure the list argument is a list object and get its length and // a pointer to its array of element pointers. TclObject[] listv = TclList.getElements(interp, objv[objv.Length - 2]); TclObject patObj = objv[objv.Length - 1]; string patternBytes = null; int patInt = 0; double patDouble = 0.0; int length = 0; if (mode == EXACT || mode == SORTED) { switch (dataType) { case ASCII: case DICTIONARY: patternBytes = patObj.ToString(); length = patternBytes.Length; break; case INTEGER: patInt = TclInteger.get(interp, patObj); break; case REAL: patDouble = TclDouble.get(interp, patObj); break; } } else { patternBytes = patObj.ToString(); length = patternBytes.Length; } // Set default index value to -1, indicating failure; if we find the // item in the course of our search, index will be set to the correct // value. int index = -1; if (mode == SORTED) { // If the data is sorted, we can do a more intelligent search. int match = 0; int lower = -1; int upper = listv.Length; while (lower + 1 != upper) { int i = (lower + upper) / 2; switch (dataType) { case ASCII: { string bytes = listv[i].ToString(); match = patternBytes.CompareTo(bytes); break; } case DICTIONARY: { string bytes = listv[i].ToString(); match = DictionaryCompare(patternBytes, bytes); break; } case INTEGER: { int objInt = TclInteger.get(interp, listv[i]); if (patInt == objInt) { match = 0; } else if (patInt < objInt) { match = -1; } else { match = 1; } break; } case REAL: { double objDouble = TclDouble.get(interp, listv[i]); if (patDouble == objDouble) { match = 0; } else if (patDouble < objDouble) { match = -1; } else { match = 1; } break; } } if (match == 0) { // Normally, binary search is written to stop when it // finds a match. If there are duplicates of an element in // the list, our first match might not be the first occurance. // Consider: 0 0 0 1 1 1 2 2 2 // To maintain consistancy with standard lsearch semantics, // we must find the leftmost occurance of the pattern in the // list. Thus we don't just stop searching here. This // variation means that a search always makes log n // comparisons (normal binary search might "get lucky" with // an early comparison). index = i; upper = i; } else if (match > 0) { if (isIncreasing) { lower = i; } else { upper = i; } } else { if (isIncreasing) { upper = i; } else { lower = i; } } } } else { for (int i = 0; i < listv.Length; i++) { bool match = false; switch (mode) { case SORTED: case EXACT: { switch (dataType) { case ASCII: { string bytes = listv[i].ToString(); int elemLen = bytes.Length; if (length == elemLen) { match = bytes.Equals(patternBytes); } break; } case DICTIONARY: { string bytes = listv[i].ToString(); match = (DictionaryCompare(bytes, patternBytes) == 0); break; } case INTEGER: { int objInt = TclInteger.get(interp, listv[i]); match = (objInt == patInt); break; } case REAL: { double objDouble = TclDouble.get(interp, listv[i]); match = (objDouble == patDouble); break; } } break; } case GLOB: { match = Util.stringMatch(listv[i].ToString(), patternBytes); break; } case REGEXP: { match = Util.regExpMatch(interp, listv[i].ToString(), patObj); break; } } if (match) { index = i; break; } } } interp.setResult(index); 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 (System.IO.IOException e) { throw new TclException(interp, "cannot open file: " + argv[1].ToString()); } bool generatedAux = tmpBool2; } if (len == 1) { modeFlags = (TclIO.WRONLY | TclIO.CREAT); break; } else if (modeStr[1] == '+') { modeFlags = (TclIO.RDWR | TclIO.CREAT); break; } } goto case 'a'; case 'a': { if (len == 1) { modeFlags = (TclIO.WRONLY | TclIO.APPEND); break; } else if (modeStr[1] == '+') { modeFlags = (TclIO.RDWR | TclIO.CREAT | TclIO.APPEND); break; } } goto default; default: { throw new TclException(interp, "illegal access mode \"" + modeStr + "\""); } } } else { modeFlags = 0; bool gotRorWflag = false; int mlen = TclList.getLength(interp, mode); for (int i = 0; i < mlen; i++) { TclObject marg = TclList.index(interp, mode, i); if (marg.ToString().Equals("RDONLY")) { modeFlags |= TclIO.RDONLY; gotRorWflag = true; } else { if (marg.ToString().Equals("WRONLY")) { modeFlags |= TclIO.WRONLY; gotRorWflag = true; } else { if (marg.ToString().Equals("RDWR")) { modeFlags |= TclIO.RDWR; gotRorWflag = true; } else { if (marg.ToString().Equals("APPEND")) { modeFlags |= TclIO.APPEND; } else { if (marg.ToString().Equals("CREAT")) { modeFlags |= TclIO.CREAT; } else { if (marg.ToString().Equals("EXCL")) { modeFlags |= TclIO.EXCL; } else { if (marg.ToString().Equals("TRUNC")) { modeFlags |= TclIO.TRUNC; } else { throw new TclException(interp, "invalid access mode \"" + marg.ToString() + "\": must be RDONLY, WRONLY, RDWR, APPEND, " + "CREAT EXCL, NOCTTY, NONBLOCK, or TRUNC"); } } } } } } } } if (!gotRorWflag) { throw new TclException(interp, "access mode must include either RDONLY, WRONLY, or RDWR"); } } } if (argv.Length == 4) { prot = TclInteger.get(interp, argv[3]); throw new TclException(interp, "setting permissions not implemented yet"); } if ((argv[1].ToString().Length > 0) && (argv[1].ToString()[0] == '|')) { pipeline = true; throw new TclException(interp, "pipes not implemented yet"); } /* * Open the file or create a process pipeline. */ if (!pipeline) { try { FileChannel file = new FileChannel(); file.open(interp, argv[1].ToString(), modeFlags); TclIO.registerChannel(interp, file); interp.setResult(file.ChanName); } catch (System.IO.IOException e) { throw new TclException(interp, "cannot open file: " + argv[1].ToString()); } } else { /* * Pipeline code here... */ } return(TCL.CompletionCode.RETURN); }
public static bool Tcl_GetIntFromObj(Interp interp, TclObject to, ref int value) { try { value = TclInteger.get(interp, to); return(false); } catch { return(true); } }
public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv) { int i; Notifier notifier = (Notifier)interp.getNotifier(); Object info; if (assocData == null) { /* * Create the "after" information associated for this * interpreter, if it doesn't already exist. */ assocData = (AfterAssocData)interp.getAssocData("tclAfter"); if (assocData == null) { assocData = new AfterAssocData(this); interp.setAssocData("tclAfter", assocData); } } if (argv.Length < 2) { throw new TclNumArgsException(interp, 1, argv, "option ?arg arg ...?"); } /* * First lets see if the command was passed a number as the first argument. */ bool isNumber = false; int ms = 0; if (argv[1].InternalRep is TclInteger) { ms = TclInteger.get(interp, argv[1]); isNumber = true; } else { string s = argv[1].ToString(); if ((s.Length > 0) && (System.Char.IsDigit(s[0]))) { ms = TclInteger.get(interp, argv[1]); isNumber = true; } } if (isNumber) { if (ms < 0) { ms = 0; } if (argv.Length == 2) { /* * Sleep for at least the given milliseconds and return. */ long endTime = System.DateTime.Now.Ticks / 10000 + ms; while (true) { try { System.Threading.Thread.Sleep(ms); return(TCL.CompletionCode.RETURN); } catch (System.Threading.ThreadInterruptedException e) { /* * We got interrupted. Sleep again if we havn't slept * long enough yet. */ long sysTime = System.DateTime.Now.Ticks / 10000; if (sysTime >= endTime) { return(TCL.CompletionCode.RETURN); } ms = (int)(endTime - sysTime); continue; } } } TclObject cmd = getCmdObject(argv); cmd.preserve(); assocData.lastAfterId++; TimerInfo timerInfo = new TimerInfo(this, notifier, ms); timerInfo.interp = interp; timerInfo.command = cmd; timerInfo.id = assocData.lastAfterId; assocData.handlers.Add(timerInfo); interp.setResult("after#" + timerInfo.id); return(TCL.CompletionCode.RETURN); } /* * If it's not a number it must be a subcommand. */ int index; try { index = TclIndex.get(interp, argv[1], validOpts, "option", 0); } catch (TclException e) { throw new TclException(interp, "bad argument \"" + argv[1] + "\": must be cancel, idle, info, or a number"); } switch (index) { case OPT_CANCEL: if (argv.Length < 3) { throw new TclNumArgsException(interp, 2, argv, "id|command"); } TclObject arg = getCmdObject(argv); arg.preserve(); /* * Search the timer/idle handler by id or by command. */ info = null; for (i = 0; i < assocData.handlers.Count; i++) { Object obj = assocData.handlers[i]; if (obj is TimerInfo) { TclObject cmd = ((TimerInfo)obj).command; if ((cmd == arg) || cmd.ToString().Equals(arg.ToString())) { info = obj; break; } } else { TclObject cmd = ((IdleInfo)obj).command; if ((cmd == arg) || cmd.ToString().Equals(arg.ToString())) { info = obj; break; } } } if (info == null) { info = getAfterEvent(arg.ToString()); } arg.release(); /* * Cancel the handler. */ if (info != null) { if (info is TimerInfo) { ((TimerInfo)info).cancel(); ((TimerInfo)info).command.release(); } else { ((IdleInfo)info).cancel(); ((IdleInfo)info).command.release(); } SupportClass.VectorRemoveElement(assocData.handlers, info); } break; case OPT_IDLE: if (argv.Length < 3) { throw new TclNumArgsException(interp, 2, argv, "script script ..."); } TclObject cmd2 = getCmdObject(argv); cmd2.preserve(); assocData.lastAfterId++; IdleInfo idleInfo = new IdleInfo(this, notifier); idleInfo.interp = interp; idleInfo.command = cmd2; idleInfo.id = assocData.lastAfterId; assocData.handlers.Add(idleInfo); interp.setResult("after#" + idleInfo.id); break; case OPT_INFO: if (argv.Length == 2) { /* * No id is given. Return a list of current after id's. */ TclObject list = TclList.newInstance(); for (i = 0; i < assocData.handlers.Count; i++) { int id; Object obj = assocData.handlers[i]; if (obj is TimerInfo) { id = ((TimerInfo)obj).id; } else { id = ((IdleInfo)obj).id; } TclList.append(interp, list, TclString.newInstance("after#" + id)); } interp.resetResult(); interp.setResult(list); return(TCL.CompletionCode.RETURN); } if (argv.Length != 3) { throw new TclNumArgsException(interp, 2, argv, "?id?"); } /* * Return command and type of the given after id. */ info = getAfterEvent(argv[2].ToString()); if (info == null) { throw new TclException(interp, "event \"" + argv[2] + "\" doesn't exist"); } TclObject list2 = TclList.newInstance(); TclList.append(interp, list2, ((info is TimerInfo)?((TimerInfo)info).command:((IdleInfo)info).command)); TclList.append(interp, list2, TclString.newInstance((info is TimerInfo)?"timer":"idle")); interp.resetResult(); interp.setResult(list2); break; } 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); }
/// <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 TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv) { interp.errorCode = null; interp.errorInfo = null; TCL.CompletionCode returnCode; int i; /* * Note: returnCode is the value given by the -code option. Don't * confuse this value with the compCode variable of the * TclException thrown by this method, which is always TCL.CompletionCode.RETURN. */ returnCode = TCL.CompletionCode.OK; for (i = 1; i < argv.Length - 1; i += 2) { if (argv[i].ToString().Equals("-code")) { if (argv[i + 1].ToString().Equals("ok")) { returnCode = TCL.CompletionCode.OK; } else { if (argv[i + 1].ToString().Equals("error")) { returnCode = TCL.CompletionCode.ERROR; } else { if (argv[i + 1].ToString().Equals("return")) { returnCode = TCL.CompletionCode.RETURN; } else { if (argv[i + 1].ToString().Equals("break")) { returnCode = TCL.CompletionCode.BREAK; } else { if (argv[i + 1].ToString().Equals("continue")) { returnCode = TCL.CompletionCode.CONTINUE; } else { try { returnCode = (TCL.CompletionCode)TclInteger.get(interp, argv[i + 1]); } catch (TclException e) { throw new TclException(interp, "bad completion code \"" + argv[i + 1] + "\": must be ok, error, return, break, " + "continue, or an integer"); } } } } } } } else { if (argv[i].ToString().Equals("-errorcode")) { interp.errorCode = argv[i + 1].ToString(); } else { if (argv[i].ToString().Equals("-errorinfo")) { interp.errorInfo = argv[i + 1].ToString(); } else { throw new TclException(interp, "bad option \"" + argv[i] + "\": must be -code, -errorcode, or -errorinfo"); } } } } if (i != argv.Length) { interp.setResult(argv[argv.Length - 1]); } interp.returnCode = returnCode; throw new TclException(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 System.Text.StringBuilder(64)); } if (readAll) { charactersRead = chan.read(interp, result, TclIO.READ_ALL, 0); // If -nonewline was specified, and we have not hit EOF // and the last char is a "\n", then remove it and return. if (noNewline) { string inStr = result.ToString(); if ((charactersRead > 0) && (inStr[charactersRead - 1] == '\n')) { interp.setResult(inStr.Substring(0, ((charactersRead - 1)) - (0))); return(TCL.CompletionCode.RETURN); } } } else { // FIXME: Bug here, the -nonewline flag must be respected // when reading a set number of bytes charactersRead = chan.read(interp, result, TclIO.READ_N_BYTES, toRead); } /* * // FIXME: Port this -nonewline logic from the C code. * if (charactersRead < 0) { * Tcl_ResetResult(interp); * Tcl_AppendResult(interp, "error reading \"", name, "\": ", * Tcl_PosixError(interp), (char *) NULL); * Tcl_DecrRefCount(resultPtr); * return TCL_ERROR; * } * * // If requested, remove the last newline in the channel if at EOF. * * if ((charactersRead > 0) && (newline != 0)) { * char *result; * int length; * * result = Tcl_GetStringFromObj(resultPtr, length); * if (result[length - 1] == '\n') { * Tcl_SetObjLength(resultPtr, length - 1); * } * } * */ interp.setResult(result); } catch (System.IO.IOException e) { throw new TclRuntimeError("ReadCmd.cmdProc() Error: IOException when reading " + chan.ChanName); } return(TCL.CompletionCode.RETURN); }
/// <summary> Compares the order of two items in the array. /// /// </summary> /// <param name="obj1">first item. /// </param> /// <param name="obj2">second item. /// </param> /// <returns> 0 if they are equal, 1 if obj1 > obj2, -1 otherwise. /// /// </returns> /// <exception cref=""> TclException if an error occurs during sorting. /// </exception> private int compare(TclObject obj1, TclObject obj2) { int index; int code = 0; if (sortIndex != -1) { // The "-index" option was specified. Treat each object as a // list, extract the requested element from each list, and // compare the elements, not the lists. The special index "end" // is signaled here with a negative index (other than -1). TclObject obj; if (sortIndex < -1) { index = TclList.getLength(sortInterp, obj1) - 1; } else { index = sortIndex; } obj = TclList.index(sortInterp, obj1, index); if (obj == null) { throw new TclException(sortInterp, "element " + index + " missing from sublist \"" + obj1 + "\""); } obj1 = obj; if (sortIndex < -1) { index = TclList.getLength(sortInterp, obj2) - 1; } else { index = sortIndex; } obj = TclList.index(sortInterp, obj2, index); if (obj == null) { throw new TclException(sortInterp, "element " + index + " missing from sublist \"" + obj2 + "\""); } obj2 = obj; } switch (sortMode) { case ASCII: // ATK C# CompareTo use option // similar to -dictionary but a > A code = System.Globalization.CultureInfo.InvariantCulture.CompareInfo.Compare(obj1.ToString(), obj2.ToString(), System.Globalization.CompareOptions.Ordinal); // code = obj1.ToString().CompareTo(obj2.ToString()); break; case DICTIONARY: code = doDictionary(obj1.ToString(), obj2.ToString()); break; case INTEGER: try { int int1 = TclInteger.get(sortInterp, obj1); int int2 = TclInteger.get(sortInterp, obj2); if (int1 > int2) { code = 1; } else if (int2 > int1) { code = -1; } } catch (TclException e1) { sortInterp.addErrorInfo("\n (converting list element from string to integer)"); throw e1; } break; case REAL: try { double f1 = TclDouble.get(sortInterp, obj1); double f2 = TclDouble.get(sortInterp, obj2); if (f1 > f2) { code = 1; } else if (f2 > f1) { code = -1; } } catch (TclException e2) { sortInterp.addErrorInfo("\n (converting list element from string to real)"); throw e2; } break; case COMMAND: System.Text.StringBuilder sbuf = new System.Text.StringBuilder(sortCommand); Util.appendElement(sortInterp, sbuf, obj1.ToString()); Util.appendElement(sortInterp, sbuf, obj2.ToString()); try { sortInterp.eval(sbuf.ToString(), 0); } catch (TclException e3) { sortInterp.addErrorInfo("\n (user-defined comparison command)"); throw e3; } try { code = TclInteger.get(sortInterp, sortInterp.getResult()); } catch (TclException e) { sortInterp.resetResult(); TclException e4 = new TclException(sortInterp, "comparison command returned non-numeric result"); throw e4; } break; default: throw new TclRuntimeError("Unknown sortMode " + sortMode); } if (sortIncreasing) { return(code); } else { return(-code); } }