private ArrayList Errors = new ArrayList(10); // A list of the pending background error handlers. internal BgErrorMgr(Interp i) { Interp = i; BgerrorCmdObj = TclString.NewInstance("bgerror"); BgerrorCmdObj.Preserve(); Errors = new ArrayList(10); }
/// <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; }
/// <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 "break" Tcl command. /// See the user documentation for details on what it does. /// </summary> /// <exception cref=""> TclException is always thrown. /// </exception> public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { if (argv.Length != 1) { throw new TclNumArgsException(interp, 1, argv, null); } throw new TclException(interp, null, TCL.CompletionCode.BREAK); }
/// <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; }
internal static void registerChannel(Interp interp, Channel chan) { if (interp != null) { Hashtable chanTable = getInterpChanTable(interp); SupportClass.PutElement(chanTable, chan.ChanName, chan); chan.refCount++; } }
protected internal Hashtable VarTable; // Stores the variables of this CallFrame. /// <summary> /// Creates a CallFrame for the global variables.</summary> /// <param name="interp"> /// current interpreter. /// </param> internal CallFrame(Interp i) { Interp = i; NS = i.GlobalNS; VarTable = new Hashtable(); Caller = null; CallerVar = null; Objv = null; Level = 0; IsProcCallFrame = true; }
/// <summary> Open a file with the read/write permissions determined by modeFlags. /// This method must be called before any other methods will function /// properly. /// /// </summary> /// <param name="interp">currrent interpreter. /// </param> /// <param name="fileName">the absolute path or name of file in the current /// directory to open /// </param> /// <param name="modeFlags">modes used to open a file for reading, writing, etc /// </param> /// <returns> the channelId of the file. /// </returns> /// <exception cref=""> TclException is thrown when the modeFlags try to open /// a file it does not have permission for or if the /// file dosent exist and CREAT wasnt specified. /// </exception> /// <exception cref=""> IOException is thrown when an IO error occurs that was not /// correctly tested for. Most cases should be caught. /// </exception> internal string open(Interp interp, string fileName, int modeFlags) { mode = modeFlags; FileInfo fileObj = FileUtil.getNewFileObj(interp, fileName); FileMode fileMode = 0; FileAccess fileAccess = 0; if (((modeFlags & TclIO.CREAT) != 0) && ((modeFlags & TclIO.EXCL) != 0)) { fileMode = FileMode.CreateNew; } else if ((modeFlags & TclIO.CREAT) != 0) { fileMode = FileMode.Create; } else { fileMode = FileMode.Open; } if ((modeFlags & TclIO.TRUNC) != 0) { fileMode = fileMode & FileMode.Truncate; } if ((modeFlags & TclIO.APPEND) != 0) { fileMode = fileMode & FileMode.Append; } if ((modeFlags & TclIO.RDWR) != 0) { fileAccess = FileAccess.ReadWrite; } else if ((modeFlags & TclIO.RDONLY) != 0) { fileAccess = FileAccess.Read; } else if ((modeFlags & TclIO.WRONLY) != 0) { fileAccess = FileAccess.Write; } else { throw new TclRuntimeError("FileChannel.java: invalid mode value"); } file = new FileStream(fileObj.FullName, fileMode, fileAccess, FileShare.ReadWrite); string fName = TclIO.getNextDescriptor(interp, "file"); ChanName = fName; //Console.Out.WriteLine("",file.Name); return fName; }
// The interpreter in which this AssocData instance is registered in. public void Dispose(Interp interp) { for (int i = Errors.Count - 1; i >= 0; i--) { BgError bgError = (BgError)Errors[i]; Errors.RemoveAt(i); bgError.Cancel(); bgError.ErrorMsg.Release(); bgError.ErrorMsg = null; bgError.ErrorInfo.Release(); bgError.ErrorInfo = null; bgError.ErrorCode.Release(); bgError.ErrorCode = null; } BgerrorCmdObj.Release(); BgerrorCmdObj = null; }
/// <summary> Creates an exception with the appropiate Tcl error message to /// indicate an error with variable access. /// /// </summary> /// <param name="interp">currrent interpreter. /// </param> /// <param name="name1">first part of a variable name. /// </param> /// <param name="name2">second part of a variable name. May be null. /// </param> /// <param name="operation">either "read" or "set". /// </param> /// <param name="reason">a string message to explain why the operation fails.. /// </param> internal TclVarException(Interp interp, string name1, string name2, string operation, string reason) : base(TCL.CompletionCode.ERROR) { if (interp != null) { interp.ResetResult(); if ((System.Object)name2 == null) { interp.SetResult("can't " + operation + " \"" + name1 + "\": " + reason); } else { interp.SetResult("can't " + operation + " \"" + name1 + "(" + name2 + ")\": " + reason); } } }
/// <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; }
/// <summary> See Tcl user documentation for details.</summary> public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { TclObject list = TclList.NewInstance(); list.Preserve(); try { for (int i = 1; i < argv.Length; i++) TclList.Append(interp, list, argv[i]); interp.SetResult(list); } finally { list.Release(); } return TCL.CompletionCode.RETURN; }
/// <summary> See Tcl user documentation for details.</summary> public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { string sep = null; if (argv.Length == 2) { sep = null; } else if (argv.Length == 3) { sep = argv[2].ToString(); } else { throw new TclNumArgsException(interp, 1, argv, "list ?joinString?"); } TclObject list = argv[1]; int size = TclList.getLength(interp, list); if (size == 0) { interp.ResetResult(); return TCL.CompletionCode.RETURN; } StringBuilder sbuf = new StringBuilder(TclList.index(interp, list, 0).ToString()); for (int i = 1; i < size; i++) { if ((System.Object)sep == null) { sbuf.Append(' '); } else { sbuf.Append(sep); } sbuf.Append(TclList.index(interp, list, i).ToString()); } interp.SetResult(sbuf.ToString()); return TCL.CompletionCode.RETURN; }
/// <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; }
internal static void unregisterChannel(Interp interp, Channel chan) { Hashtable chanTable = getInterpChanTable(interp); SupportClass.HashtableRemove(chanTable, chan.ChanName); if (--chan.refCount <= 0) { try { chan.Close(); } catch (IOException e) { throw new TclRuntimeError("TclIO.unregisterChannel() Error: IOException when closing " + chan.ChanName + ": " + e.Message, e); } } }
public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { bool debug; if (argv.Length == 2) { System.Diagnostics.Debug.WriteLine("getting value of \"" + argv[1].ToString() + "\""); interp.SetResult(interp.GetVar(argv[1], 0)); } else if (argv.Length == 3) { System.Diagnostics.Debug.WriteLine("setting value of \"" + argv[1].ToString() + "\" to \"" + argv[2].ToString() + "\""); interp.SetResult(interp.SetVar(argv[1], argv[2], 0)); } else { throw new TclNumArgsException(interp, 1, argv, "varName ?newValue?"); } return TCL.CompletionCode.RETURN; }
private static void setDoubleFromAny(Interp interp, TclObject tobj) { IInternalRep 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()); } }
public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { if (argv.Length != 1) { throw new TclNumArgsException(interp, 1, argv, null); } // Get the name of the working dir. string dirName = interp.getWorkingDir().ToString(); // Java File Object methods use backslashes on Windows. // Convert them to forward slashes before returning the dirName to Tcl. if (JACL.PLATFORM == JACL.PLATFORM_WINDOWS) { dirName = dirName.Replace('\\', '/'); } interp.SetResult(dirName); return TCL.CompletionCode.RETURN; }
/// <summary> Tcl_UnsetObjCmd -> UnsetCmd.cmdProc /// /// Unsets Tcl variable (s). See Tcl user documentation * for /// details. /// </summary> /// <exception cref=""> TclException If tries to unset a variable that does /// not exist. /// </exception> public TCL.CompletionCode CmdProc(Interp interp, TclObject[] objv) { switch (objv.Length) { case 2: interp.UnsetVar(objv[1], 0); break; case 3: for (int i = (objv[1].ToString() != "-nocomplain") ? 1 : 2; i < objv.Length; i++) { Var.UnsetVar(interp, objv[i].ToString(), 0); } break; default: if (objv.Length < 2) { throw new TclNumArgsException(interp, 1, objv, "varName ?varName ...?"); } break; } return TCL.CompletionCode.RETURN; }
public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { int flags; if (argv.Length == 1) { flags = TCL.ALL_EVENTS | TCL.DONT_WAIT; } else if (argv.Length == 2) { TclIndex.Get(interp, argv[1], validOpts, "option", 0); /* * Since we just have one valid option, if the above call returns * without an exception, we've got "idletasks" (or abreviations). */ flags = TCL.IDLE_EVENTS | TCL.DONT_WAIT; } else { throw new TclNumArgsException(interp, 1, argv, "?idletasks?"); } while (interp.GetNotifier().doOneEvent(flags) != 0) { /* Empty loop body */ } /* * Must clear the interpreter's result because event handlers could * have executed commands. */ interp.ResetResult(); return TCL.CompletionCode.RETURN; }
public TCL.CompletionCode CmdProc(Interp interp, TclObject[] objv) { int clockVal; // Time value as seconds of epoch. string dateString; // Time value as string. int argIx; // Counter over arguments. string format = null; // User specified format string. bool useGmt = false; // User specified flag to use gmt. TclObject baseObj = null; // User specified raw value of baseClock. System.DateTime baseClock; // User specified time value. System.DateTime date; // Parsed date value. if (objv.Length < 2) { throw new TclNumArgsException(interp, 1, objv, "option ?arg ...?"); } int cmd = TclIndex.Get(interp, objv[1], validCmds, "option", 0); switch (cmd) { case CMD_CLICKS: { if (objv.Length > 3) { throw new TclNumArgsException(interp, 2, objv, "?-milliseconds?"); } if (objv.Length == 3) { // We can safely ignore the -milliseconds options, since // we measure the clicks in milliseconds anyway... int clicksOpt = TclIndex.Get(interp, objv[2], clicksOpts, "switch", 0); } long millis = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; int clicks = (int)(millis % System.Int32.MaxValue); interp.SetResult(clicks); break; } case CMD_FORMAT: { if ((objv.Length < 3) || (objv.Length > 7)) { throw new TclNumArgsException(interp, 2, objv, "clockval ?-format string? ?-gmt boolean?"); } clockVal = TclInteger.Get(interp, objv[2]); for (argIx = 3; argIx + 1 < objv.Length; argIx += 2) { int formatOpt = TclIndex.Get(interp, objv[argIx], formatOpts, "switch", 0); switch (formatOpt) { case OPT_FORMAT_FORMAT: { format = objv[argIx + 1].ToString(); break; } case OPT_FORMAT_GMT: { useGmt = TclBoolean.get(interp, objv[argIx + 1]); break; } } } if (argIx < objv.Length) { throw new TclNumArgsException(interp, 2, objv, "clockval ?-format string? ?-gmt boolean?"); } FormatClock(interp, clockVal, useGmt, format); break; } case CMD_SCAN: { if ((objv.Length < 3) || (objv.Length > 7)) { throw new TclNumArgsException(interp, 2, objv, "dateString ?-base clockValue? ?-gmt boolean?"); } dateString = objv[2].ToString(); for (argIx = 3; argIx + 1 < objv.Length; argIx += 2) { int scanOpt = TclIndex.Get(interp, objv[argIx], scanOpts, "switch", 0); switch (scanOpt) { case OPT_SCAN_BASE: { baseObj = objv[argIx + 1]; break; } case OPT_SCAN_GMT: { useGmt = TclBoolean.get(interp, objv[argIx + 1]); break; } } } if (argIx < objv.Length) { throw new TclNumArgsException(interp, 2, objv, "clockval ?-format string? ?-gmt boolean?"); } if (baseObj != null) { long seconds = TclInteger.Get(interp, baseObj); baseClock = new System.DateTime((long)seconds * 10000 * 1000 + 621355968000000000); } else { baseClock = System.DateTime.Now; } try { date = GetDate(dateString, baseClock, useGmt); } catch (FormatException) { throw new TclException(interp, "unable to convert date-time string \"" + dateString + "\""); } long millis = (date.Ticks - 621355968000000000) / 10000; int seconds2 = (int)(millis / 1000); interp.SetResult(seconds2); break; } case CMD_SECONDS: { if (objv.Length != 2) { throw new TclNumArgsException(interp, 2, objv, null); } long millis = (System.DateTime.Now.Ticks - 621355968000000000) / 10000; int seconds = (int)(millis / 1000); interp.SetResult(seconds); break; } } return TCL.CompletionCode.RETURN; }
public static double Get(Interp interp, TclObject tobj) { IInternalRep rep = tobj.InternalRep; TclDouble tdouble; if (!(rep is TclDouble)) { setDoubleFromAny(interp, tobj); tdouble = (TclDouble)(tobj.InternalRep); } else { tdouble = (TclDouble)rep; } return tdouble.value; }
private void FormatClock(Interp interp, int clockVal, bool useGMT, string format) { DateTime date = new DateTime((long)clockVal * 10000 * 1000 + 621355968000000000); DateTimeFormatInfo formatInfo = new DateTimeFormatInfo(); string fmt, locFmt; GregorianCalendar calendar = new GregorianCalendar(); System.Int32[] temp_int_array; temp_int_array = new System.Int32[3]; temp_int_array[0] = 0; temp_int_array[1] = 0; temp_int_array[2] = 0; System.Int32[] fp = temp_int_array; StringBuilder result = new StringBuilder(); if ((System.Object)format == null) { format = new StringBuilder("%a %b %d %H:%M:%S %Z %Y").ToString(); } if (useGMT) { date = date.ToUniversalTime(); } if (format.Equals("%Q")) { // Enterprise Stardate. (seems to be Star Track fan coding) // ATK not tested int trekYear = date.Year + 377 - 2323; int trekDay = (date.DayOfYear * 1000) / (calendar.IsLeapYear(date.Year) ? 366 : 365); int trekHour = (24 * 60 + date.Minute) / 144; interp.SetResult("Stardate " + (trekYear < 10 ? "0" : "") + (trekYear * 1000 + trekDay) + '.' + trekHour); return; } for (int ix = 0; ix < format.Length; ix++) { if (format[ix] == '%' && ix + 1 < format.Length) { switch (format[++ix]) { case '%': result.Append('%'); break; case 'a': result.Append(date.ToString("ddd", formatInfo)); break; case 'A': result.Append(date.ToString("dddd", formatInfo)); break; case 'b': case 'h': result.Append(date.ToString("MMM", formatInfo)); break; case 'B': result.Append(date.ToString("MMMM", formatInfo)); break; case 'c': result.Append(date.ToString()); break; case 'C': int century = date.Year / 100; result.Append((century < 10 ? "0" : "") + century); break; case 'd': result.Append(date.ToString("dd", formatInfo)); break; case 'D': result.Append(date.ToString("MM/dd/yy", formatInfo)); break; case 'e': result.Append(date.ToString("%d", formatInfo)); break; case 'H': result.Append(date.ToString("HH", formatInfo)); break; case 'I': result.Append(date.ToString("hh", formatInfo)); break; case 'j': result.Append(date.Year.ToString("0###")); break; case 'k': result.Append(date.ToString("H", formatInfo)); break; case 'l': result.Append(date.ToString("%h", formatInfo)); break; case 'm': // Month number (01 - 12). result.Append(date.ToString("MM", formatInfo)); break; case 'M': // Minute (00 - 59). result.Append(date.ToString("mm", formatInfo)); break; case 'n': // Insert a newline. result.Append('\n'); break; case 'p': // AM/PM indicator. result.Append(date.ToString("tt", formatInfo)); break; case 'r': // %r //Time in a locale-specific "meridian" format. The "meridian" format in the default "C" locale is "%I:%M:%S %p". result.Append(date.ToString("hh:mm:ss tt", formatInfo)); break; case 'R': //%R //Time as %H:%M. result.Append(date.ToString("HH:MM", formatInfo)); break; case 's': //%s //Count of seconds since the epoch, expressed as a decimal integer. result.Append((date.Ticks / 1000).ToString()); break; case 'S': //%S //Seconds (00 - 59). result.Append(date.ToString("ss", formatInfo)); break; case 't': //%t //Insert a tab. result.Append('\t'); break; case 'T': //%T //Time as %H:%M:%S. result.Append(date.ToString("HH:mm:ss", formatInfo)); break; case 'u': //%u //Weekday number (Monday = 1, Sunday = 7). if (date.DayOfWeek == DayOfWeek.Sunday) { result.Append("7"); } else { result.Append(((int)date.DayOfWeek).ToString()); } break; case 'U': //%U //Week of year (00 - 52), Sunday is the first day of the week. int weekS = GetWeek(date, System.DayOfWeek.Sunday, false); result.Append((weekS < 10 ? "0" : "") + weekS); break; case 'V': //%V //Week of year according to ISO-8601 rules. Week 1 of a given year is the week containing 4 January. int isoWeek = GetWeek(date, System.DayOfWeek.Monday, true); result.Append((isoWeek < 10 ? "0" : "") + isoWeek); break; case 'w': //%w //Weekday number (Sunday = 0, Saturday = 6). result.Append(((int)date.DayOfWeek).ToString()); break; case 'W': //%W //Week of year (00 - 52), Monday is the first day of the week. int weekM = GetWeek(date, System.DayOfWeek.Monday, false); result.Append((weekM < 10 ? "0" : "") + weekM); break; case 'x': //%x //Locale specific date format. The format for a date in the default "C" locale for Unix/Mac is "%m/%d/%y". On Windows, this value is the locale specific short date format, as specified in the Regional Options control panel settings. result.Append(date.ToShortDateString()); break; case 'X': //%X //Locale specific 24-hour time format. The format for a 24-hour time in the default "C" locale for Unix/Mac is "%H:%M:%S". On Windows, this value is the locale specific time format, as specified in the Regional Options control panel settings. result.Append(date.ToShortTimeString()); break; case 'y': //%y //Year without century (00 - 99). result.Append(date.ToString("yy", formatInfo)); break; case 'Y': //%Y //Year with century (e.g. 1990) result.Append(date.ToString("yyyy", formatInfo)); break; case 'Z': //%Z //Time zone name. result.Append(date.ToString("zzz", formatInfo)); break; default: result.Append(format[ix]); break; } } else { result.Append(format[ix]); } } interp.SetResult(result.ToString()); }
private TclDouble(Interp interp, string str) { value = Util.getDouble(interp, str); }
/// <summary> Called whenever the current char in the frmtArr is erroneous /// /// </summary> /// <param name="interp"> - The TclInterp which called the cmdProc method . /// </param> /// <param name="fieldSpecifier"> - The erroneous character /// </param> private static void errorBadField(Interp interp, char fieldSpecifier) { throw new TclException(interp, "bad scan conversion character \"" + fieldSpecifier + "\""); }
/// <summary> Called whenever the a width field is used in a char ('c') format /// specifier /// /// </summary> /// <param name="interp"> - The TclInterp which called the cmdProc method . /// </param> private static void errorCharFieldWidth(Interp interp) { throw new TclException(interp, "field width may not be specified in %c conversion"); }
/// <summary> Checks the read/write permissions on the File object. If inmode is less /// than 0 it checks for read permissions, if mode greater than 0 it checks /// for write permissions, and if it equals 0 then it checks both. /// /// </summary> /// <param name="interp">currrent interpreter. /// </param> /// <param name="fileObj">a java.io.File object of the file for this channel. /// </param> /// <param name="inmode">what permissions to check for. /// </param> private void checkReadWritePerm(Interp interp, FileInfo fileObj, int inmode) { bool error = false; if (inmode <= 0) { // HACK // if (!fileObj.canRead()) // { // error = true; // } } if (inmode >= 0) { if (!SupportClass.FileCanWrite(fileObj)) { error = true; } } if (error) { throw new TclPosixException(interp, TclPosixException.EACCES, true, "couldn't open \"" + fileObj.Name + "\""); } }
/// <summary> If the file dosent exist then a TclExcpetion is thrown. /// /// </summary> /// <param name="interp">currrent interpreter. /// </param> /// <param name="fileObj">a java.io.File object of the file for this channel. /// </param> private void checkFileExists(Interp interp, FileInfo fileObj) { bool tmpBool; if (File.Exists(fileObj.FullName)) tmpBool = true; else tmpBool = Directory.Exists(fileObj.FullName); if (!tmpBool) { throw new TclPosixException(interp, TclPosixException.ENOENT, true, "couldn't open \"" + fileObj.Name + "\""); } }
/// <summary> Move the file pointer internal to the RandomAccessFile object. /// The file MUST be open or a TclRuntimeError is thrown. /// /// </summary> /// <param name="offset">The number of bytes to move the file pointer. /// </param> /// <param name="inmode">to begin incrementing the file pointer; beginning, /// current, or end of the file. /// </param> public override void seek(Interp interp, long offset, int inmode) { if (file == null) { throw new TclRuntimeError("FileChannel.seek(): null file object"); } //FIXME: Disallow seek on dead channels (raise TclPosixException ??) //if (CheckForDeadChannel(NULL, statePtr)) { // return Tcl_LongAsWide(-1); //} // Compute how much input and output is buffered. If both input and // output is buffered, cannot compute the current position. int inputBuffered = NumBufferedInputBytes; int outputBuffered = NumBufferedOutputBytes; if ((inputBuffered != 0) && (outputBuffered != 0)) { throw new TclPosixException(interp, TclPosixException.EFAULT, true, "error during seek on \"" + ChanName + "\""); } // If we are seeking relative to the current position, compute the // corrected offset taking into account the amount of unread input. if (inmode == TclIO.SEEK_CUR) { offset -= inputBuffered; } // The seekReset method will discard queued input and // reset flags like EOF and BLOCKED. if (input != null) { input.seekReset(); } // FIXME: Next block is disabled since non-blocking is not implemented. // If the channel is in asynchronous output mode, switch it back // to synchronous mode and cancel any async flush that may be // scheduled. After the flush, the channel will be put back into // asynchronous output mode. bool wasAsync = false; //if (false && !Blocking) //{ // wasAsync = true; // Blocking = true; // if (BgFlushScheduled) // { // //scheduleBgFlush(); // } //} // If there is data buffered in curOut then mark the // channel as ready to flush before invoking flushChannel. if (output != null) { output.seekCheckBuferReady(); } // If the flush fails we cannot recover the original position. In // that case the seek is not attempted because we do not know where // the access position is - instead we return the error. FlushChannel // has already called Tcl_SetErrno() to report the error upwards. // If the flush succeeds we do the seek also. if (output != null && output.flushChannel(null, false) != 0) { // FIXME: IS this the proper action to take on error? throw new IOException("flush error while seeking"); } else { // Now seek to the new position in the channel as requested by the // caller. long actual_offset; switch (inmode) { case TclIO.SEEK_SET: { actual_offset = offset; break; } case TclIO.SEEK_CUR: { actual_offset = file.Position + offset; break; } case TclIO.SEEK_END: { actual_offset = file.Length + offset; break; } default: { throw new TclRuntimeError("invalid seek mode"); } } // A negative offset to seek() would raise an IOException, but // we want to raise an invalid argument error instead if (actual_offset < 0) { throw new TclPosixException(interp, TclPosixException.EINVAL, true, "error during seek on \"" + ChanName + "\""); } file.Seek(actual_offset, SeekOrigin.Begin); } // Restore to nonblocking mode if that was the previous behavior. // // NOTE: Even if there was an async flush active we do not restore // it now because we already flushed all the queued output, above. if (wasAsync) { Blocking = false; } }
public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { int i, mode, body; bool matched; string inString; TclObject[] switchArgv = null; mode = EXACT; for (i = 1; i < argv.Length; i++) { if (!argv[i].ToString().StartsWith("-")) { break; } int opt = TclIndex.Get(interp, argv[i], validCmds, "option", 1); if (opt == LAST) { i++; break; } else if (opt > LAST) { throw new TclException(interp, "SwitchCmd.cmdProc: bad option " + opt + " index to validCmds"); } else { mode = opt; } } if (argv.Length - i < 2) { throw new TclNumArgsException(interp, 1, argv, "?switches? string pattern body ... ?default body?"); } inString = argv[i].ToString(); i++; // If all of the pattern/command pairs are lumped into a single // argument, split them out again. if (argv.Length - i == 1) { switchArgv = TclList.getElements(interp, argv[i]); i = 0; } else { switchArgv = argv; } for (; i < switchArgv.Length; i += 2) { if (i == (switchArgv.Length - 1)) { throw new TclException(interp, "extra switch pattern with no body"); } // See if the pattern matches the string. matched = false; string pattern = switchArgv[i].ToString(); if ((i == switchArgv.Length - 2) && pattern.Equals("default")) { matched = true; } else { switch (mode) { case EXACT: matched = inString.Equals(pattern); break; case GLOB: matched = Util.StringMatch(inString, pattern); break; case REGEXP: matched = Util.regExpMatch(interp, inString, switchArgv[i]); break; } } if (!matched) { continue; } // We've got a match. Find a body to execute, skipping bodies // that are "-". for (body = i + 1; ; body += 2) { if (body >= switchArgv.Length) { throw new TclException(interp, "no body specified for pattern \"" + switchArgv[i] + "\""); } if (!switchArgv[body].ToString().Equals("-")) { break; } } try { interp.Eval(switchArgv[body], 0); return TCL.CompletionCode.RETURN; } catch (TclException e) { if (e.GetCompletionCode() == TCL.CompletionCode.ERROR) { interp.AddErrorInfo("\n (\"" + switchArgv[i] + "\" arm line " + interp._errorLine + ")"); } throw; } } // Nothing matched: return nothing. return TCL.CompletionCode.RETURN; }