/// <summary> TCL.Tcl_GetIntFromObj -> TclInteger.get /// /// Returns the integer value of the object. /// /// </summary> /// <param name="interp">current interpreter. /// </param> /// <param name="tobj">the object to operate on. /// </param> /// <returns> the integer value of the object. /// </returns> public static int Get(Interp interp, TclObject tobj) { setIntegerFromAny(interp, tobj); TclInteger tint = (TclInteger)tobj.InternalRep; return(tint.value); }
/// <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); }
/// <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> 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 int FormatNumber(Interp interp, char type, TclObject src, byte[] resultBytes, int cursor) { if (type == 'd') { double dvalue = TclDouble.Get(interp, src); MemoryStream ms = new MemoryStream(resultBytes, cursor, 8); BinaryWriter writer = new BinaryWriter(ms); writer.Write(dvalue); cursor += 8; writer.Close(); ms.Close(); } else if (type == 'f') { float fvalue = (float)TclDouble.Get(interp, src); MemoryStream ms = new MemoryStream(resultBytes, cursor, 4); BinaryWriter writer = new 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 void Tcl_SetIntObj(TclObject to, int result ) { while (to.Shared) { to.Release(); } TclInteger.set(to, result); to.Preserve(); }
private static TclObject ScanNumber(byte[] src, int pos, int type) // Format character from "binary scan" { switch (type) { case 'c': { return(TclInteger.NewInstance((sbyte)src[pos])); } case 's': { short value = (short)((src[pos] & 0xff) + ((src[pos + 1] & 0xff) << 8)); return(TclInteger.NewInstance((int)value)); } case 'S': { short value = (short)((src[pos + 1] & 0xff) + ((src[pos] & 0xff) << 8)); return(TclInteger.NewInstance((int)value)); } case 'i': { int value = (src[pos] & 0xff) + ((src[pos + 1] & 0xff) << 8) + ((src[pos + 2] & 0xff) << 16) + ((src[pos + 3] & 0xff) << 24); return(TclInteger.NewInstance(value)); } case 'I': { int value = (src[pos + 3] & 0xff) + ((src[pos + 2] & 0xff) << 8) + ((src[pos + 1] & 0xff) << 16) + ((src[pos] & 0xff) << 24); return(TclInteger.NewInstance(value)); } case 'f': { MemoryStream ms = new MemoryStream(src, pos, 4, false); BinaryReader reader = new BinaryReader(ms); double fvalue = reader.ReadSingle(); reader.Close(); ms.Close(); return(TclDouble.NewInstance(fvalue)); } case 'd': { MemoryStream ms = new MemoryStream(src, pos, 8, false); BinaryReader reader = new BinaryReader(ms); double dvalue = reader.ReadDouble(); reader.Close(); ms.Close(); return(TclDouble.NewInstance(dvalue)); } } return(null); }
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); }
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()); } }
/// <summary> This procedure is invoked to process the "catch" Tcl command. /// See the user documentation for details on what it does. /// /// </summary> /// <param name="interp">the current interpreter. /// </param> /// <param name="argv">command arguments. /// </param> /// <exception cref=""> TclException if wrong number of arguments. /// </exception> public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { if (argv.Length != 2 && argv.Length != 3) { throw new TclNumArgsException(interp, 1, argv, "command ?varName?"); } TclObject result; TCL.CompletionCode code = TCL.CompletionCode.OK; try { interp.Eval(argv[1], 0); } catch (TclException e) { code = e.GetCompletionCode(); } result = interp.GetResult(); if (argv.Length == 3) { try { interp.SetVar(argv[2], result, 0); } catch (TclException e) { throw new TclException(interp, "couldn't save command result in variable"); } } interp.ResetResult(); interp.SetResult(TclInteger.NewInstance((int)code)); return(TCL.CompletionCode.RETURN); }
/// <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) { IInternalRep 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); }
public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { int firstWord; /* Index to the first non-switch arg */ int argLen = argv.Length; /* No of args to copy to argStrs */ int exit; /* denotes exit status of process */ int errorBytes = 0; /* number of bytes of process stderr */ //bool background; /* Indicates a bg process */ //bool keepNewline; /* Retains newline in pipline output */ System.Diagnostics.Process p; /* The exec-ed process */ string argStr; /* Conversion of argv to a string */ StringBuilder sbuf; /* * Check for a leading "-keepnewline" argument. */ for (firstWord = 1; firstWord < argLen; firstWord++) { argStr = argv[firstWord].ToString(); if ((argStr.Length > 0) && (argStr[0] == '-')) { //if (argStr.Equals("-keepnewline")) //{ // keepNewline = true; //} //else if (argStr.Equals("--")) { firstWord++; break; } else { throw new TclException(interp, "bad switch \"" + argStr + "\": must be -keepnewline or --"); } } } if (argLen <= firstWord) { throw new TclNumArgsException(interp, 1, argv, "?switches? arg ?arg ...?"); } /* * See if the command is to be run in background. * Currently this does nothing, it is just for compatibility */ //if (argv[argLen - 1].ToString().Equals("&")) //{ // argLen--; // background = true; //} try { /* * It is necessary to perform system specific * operations before calling exec. For now Solaris * and Windows execs are somewhat supported, in all other cases * we simply call exec and give it our "best shot" */ if (execMethod != null) { p = execReflection(interp, argv, firstWord, argLen); } else if (Util.Unix) { p = execUnix(interp, argv, firstWord, argLen); } else if (Util.Windows) { p = execWin(interp, argv, firstWord, argLen); } else { p = execDefault(interp, argv, firstWord, argLen); } //note to self : buffer reading should be done in //a separate thread and not by calling waitFor() //because a process that is waited for can block //Wait for the process to finish running, try { p.Start(); p.WaitForExit(); exit = p.ExitCode; } catch (Exception e) { throw new TclException(interp, "exception in exec process: " + e.Message); } //Make buffer for the results of the subprocess execution sbuf = new StringBuilder(); //read data on stdout stream into result buffer readStreamIntoBuffer(p.StandardOutput.BaseStream, sbuf); //if there is data on the stderr stream then append //this data onto the result StringBuffer //check for the special case where there is no error //data but the process returns an error result errorBytes = readStreamIntoBuffer(p.StandardError.BaseStream, sbuf); if ((errorBytes == 0) && (exit != 0)) { sbuf.Append("child process exited abnormally"); } //If the last character of the result buffer is a newline, then //remove the newline character (the newline would just confuse //things). Finally, we set pass the result to the interpreter. // Tcl supports lots of child status conditions. // Unfortunately, we can only find the child's // exit status using the Java API if (exit != 0) { TclObject childstatus = TclList.NewInstance(); TclList.Append(interp, childstatus, TclString.NewInstance("CHILDSTATUS")); // We don't know how to find the child's pid TclList.Append(interp, childstatus, TclString.NewInstance("?PID?")); TclList.Append(interp, childstatus, TclInteger.NewInstance(exit)); interp.SetErrorCode(childstatus); } //when the subprocess writes to its stderr stream or returns //a non zero result we generate an error if ((exit != 0) || (errorBytes != 0)) { throw new TclException(interp, sbuf.ToString()); } //otherwise things went well so set the result interp.SetResult(sbuf.ToString()); } catch (IOException e) { //if exec fails we end up catching the exception here throw new TclException(interp, "couldn't execute \"" + argv[firstWord].ToString() + "\": no such file or directory"); } catch (System.Threading.ThreadInterruptedException e) { /* * Do Nothing... */ } return(TCL.CompletionCode.RETURN); }
private static void getAndStoreStatData(Interp interp, string fileName, string varName) { FileInfo fileObj = FileUtil.getNewFileObj(interp, fileName); bool tmpBool; if (File.Exists(fileObj.FullName)) { tmpBool = true; } else { tmpBool = Directory.Exists(fileObj.FullName); } if (!tmpBool) { throw new TclPosixException(interp, TclPosixException.ENOENT, true, "could not read \"" + fileName + "\""); } try { int mtime = getMtime(interp, fileName, fileObj); TclObject mtimeObj = TclInteger.NewInstance(mtime); TclObject atimeObj = TclInteger.NewInstance(mtime); TclObject ctimeObj = TclInteger.NewInstance(mtime); interp.SetVar(varName, "atime", atimeObj, 0); interp.SetVar(varName, "ctime", ctimeObj, 0); interp.SetVar(varName, "mtime", mtimeObj, 0); } catch (System.Security.SecurityException e) { throw new TclException(interp, e.Message); } catch (TclException e) { throw new TclException(interp, "can't set \"" + varName + "(dev)\": variable isn't array"); } try { TclObject sizeObj = TclInteger.NewInstance((int)SupportClass.FileLength(fileObj)); interp.SetVar(varName, "size", sizeObj, 0); } catch (System.Exception e) { // Do nothing. } try { TclObject typeObj = TclString.NewInstance(getType(interp, fileName, fileObj)); interp.SetVar(varName, "type", typeObj, 0); } catch (System.Exception e) { } try { TclObject uidObj = TclBoolean.newInstance(isOwner(interp, fileObj)); interp.SetVar(varName, "uid", uidObj, 0); } catch (TclException e) { // Do nothing. } }
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 && 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 = DateTime.Now.Ticks / 10000 + ms; while (true) { try { Thread.Sleep(ms); return(TCL.CompletionCode.RETURN); } catch (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); }
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 "scan" Tcl command. /// See the user documentation for details on what it does. /// /// Each iteration of the cmdProc compares the scanArr's current index to /// the frmtArr's index. If the chars are equal then the indicies are /// incremented. If a '%' is found in the frmtArr, the formatSpecifier /// is parced from the frmtArr, the corresponding value is extracted from /// the scanArr, and that value is set in the Tcl Interp. /// /// If the chars are not equal, or the conversion fails, the boolean /// scanArrDone is set to true, indicating the scanArr is not to be /// parced and no new values are to be set. However the frmtArr is still /// parced because of the priority of error messages. In the C version /// of Tcl, bad format specifiers throw errors before incorrect argument /// input or other scan errors. Thus we need to parce the entire frmtArr /// to verify correct formating. This is dumb and inefficient but it is /// consistent w/ the current C-version of Tcl. /// </summary> public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { if (argv.Length < 3) { throw new TclNumArgsException(interp, 1, argv, "string format ?varName varName ...?"); } ; StrtoulResult strul; // Return value for parcing the scanArr when // extracting integers/longs StrtodResult strd; ; // Return value for parcing the scanArr when // extracting doubles char[] scanArr; // Array containing parce info char[] frmtArr; // Array containing info on how to // parse the scanArr int scanIndex; // Index into the scan array int frmtIndex; // Index into the frmt array int tempIndex; // Temporary index holder int argIndex; // Index into the current arg int width; // Stores the user specified result width int base_; // Base of the integer being converted int numUnMatched; // Number of fields actually set. int numMatched; // Number of fields actually matched. int negateScan; // Mult by result, set to -1 if true int i; // Generic variable char ch; // Generic variable bool cont; // Used in loops to indicate when to stop bool scanOK; // Set to false if strtoul/strtod fails bool scanArrDone; // Set to false if strtoul/strtod fails bool widthFlag; // True is width is specified bool discardFlag; // If a "%*" is in the formatString dont // write output to arg scanArr = argv[1].ToString().ToCharArray(); frmtArr = argv[2].ToString().ToCharArray(); width = base_ = numMatched = numUnMatched = 0; scanIndex = frmtIndex = 0; scanOK = true; scanArrDone = false; argIndex = 3; // Skip all (if any) of the white space before getting to a char frmtIndex = skipWhiteSpace(frmtArr, frmtIndex); // Search through the frmtArr. If the next char is a '%' parse the // next chars and determine the type (if any) of the format specifier. // If the scanArr has been fully searched, do nothing but incerment // "numUnMatched". The reason to continue the frmtArr search is for // consistency in output. Previously scan format errors were reported // before arg input mismatch, so this maintains the same level of error // checking. while (frmtIndex < frmtArr.Length) { discardFlag = widthFlag = false; negateScan = 1; cont = true; // Parce the format array and read in the correct value from the // scan array. When the correct value is retrieved, set the // variable (from argv) in the interp. if (frmtArr[frmtIndex] == '%') { frmtIndex++; checkOverFlow(interp, frmtArr, frmtIndex); // Two '%'s in a row, do nothing... if (frmtArr[frmtIndex] == '%') { frmtIndex++; scanIndex++; continue; } // Check for a discard field flag if (frmtArr[frmtIndex] == '*') { discardFlag = true; frmtIndex++; checkOverFlow(interp, frmtArr, frmtIndex); } // Check for a width field and accept the 'h', 'l', 'L' // characters, but do nothing with them. // // Note: The order of the width specifier and the other // chars is unordered, so we need to iterate until all // of the specifiers are identified. while (cont) { cont = false; switch (frmtArr[frmtIndex]) { case 'h': case 'l': case 'L': { // Just ignore these values frmtIndex++; cont = true; break; } default: { if (System.Char.IsDigit(frmtArr[frmtIndex])) { strul = Util.Strtoul(new string(frmtArr), frmtIndex, base_); frmtIndex = strul.Index; width = (int)strul.value; widthFlag = true; cont = true; } } break; } checkOverFlow(interp, frmtArr, frmtIndex); } // On all conversion specifiers except 'c', move the // scanIndex to the next non-whitespace. ch = frmtArr[frmtIndex]; if ((ch != 'c') && (ch != '[') && !scanArrDone) { scanIndex = skipWhiteSpace(scanArr, scanIndex); } if (scanIndex >= scanArr.Length) { scanArrDone = true; } if ((scanIndex < scanArr.Length) && (ch != 'c') && (ch != '[')) { // Since strtoul dosent take signed numbers, make the // value positive and store the sign. if (scanArr[scanIndex] == '-') { negateScan = -1; scanIndex++; width--; } else if (scanArr[scanIndex] == '+') { scanIndex++; width--; } // The width+scanIndex might be greater than // the scanArr so we need to re-adjust when this // happens. if (widthFlag && (width + scanIndex > scanArr.Length)) { width = scanArr.Length - scanIndex; } } if (scanIndex >= scanArr.Length) { scanArrDone = true; } // Foreach iteration we want strul and strd to be // null since we error check on this case. strul = null; strd = null; switch (ch) { case 'd': case 'o': case 'x': { if (!scanArrDone) { if (ch == 'd') { base_ = 10; } else if (ch == 'o') { base_ = 8; } else { base_ = 16; } // If the widthFlag is set then convert only // "width" characters to an ascii representation, // else read in until the end of the integer. The // scanIndex is moved to the point where we stop // reading in. if (widthFlag) { strul = Util.Strtoul(new string(scanArr, 0, width + scanIndex), scanIndex, base_); } else { strul = Util.Strtoul(new string(scanArr), scanIndex, base_); } if (strul.errno != 0) { scanOK = false; break; } scanIndex = strul.Index; if (!discardFlag) { i = (int)strul.value * negateScan; if (argIndex == argv.Length) { numMatched--; } else { testAndSetVar(interp, argv, argIndex++, TclInteger.NewInstance(i)); } } } break; } case 'c': { if (widthFlag) { errorCharFieldWidth(interp); } if (!discardFlag && !scanArrDone) { testAndSetVar(interp, argv, argIndex++, TclInteger.NewInstance(scanArr[scanIndex++])); } break; } case 's': { if (!scanArrDone) { // If the widthFlag is set then read only "width" // characters into the string, else read in until // the first whitespace or endArr is found. The // scanIndex is moved to the point where we stop // reading in. tempIndex = scanIndex; if (!widthFlag) { width = scanArr.Length; } for (i = 0; (scanIndex < scanArr.Length) && (i < width); i++) { ch = scanArr[scanIndex]; if ((ch == ' ') || (ch == '\n') || (ch == '\r') || (ch == '\t') || (ch == '\f')) { break; } scanIndex++; } if (!discardFlag) { string str = new string(scanArr, tempIndex, scanIndex - tempIndex); testAndSetVar(interp, argv, argIndex++, TclString.NewInstance(str)); } } break; } case 'e': case 'f': case 'g': { if (!scanArrDone) { // If the wisthFlag is set then read only "width" // characters into the string, else read in until // the first whitespace or endArr is found. The // scanIndex is moved to the point where we stop // reading in. if (widthFlag) { strd = Util.Strtod(new string(scanArr, 0, width + scanIndex), scanIndex); } else { strd = Util.Strtod(new string(scanArr), scanIndex); } if (strd.errno != 0) { scanOK = false; break; } scanIndex = strd.index; if (!discardFlag) { double d = strd.value * negateScan; testAndSetVar(interp, argv, argIndex++, TclDouble.NewInstance(d)); } } break; } case '[': { bool charMatchFound = false; bool charNotMatch = false; char[] tempArr; int startIndex; int endIndex; string unmatched = "unmatched [ in format string"; if ((++frmtIndex) >= frmtArr.Length) { throw new TclException(interp, unmatched); } if (frmtArr[frmtIndex] == '^') { charNotMatch = true; frmtIndex += 2; } else { frmtIndex++; } tempIndex = frmtIndex - 1; if (frmtIndex >= frmtArr.Length) { throw new TclException(interp, unmatched); } // Extract the list of chars for matching. while (frmtArr[frmtIndex] != ']') { if ((++frmtIndex) >= frmtArr.Length) { throw new TclException(interp, unmatched); } } tempArr = new string(frmtArr, tempIndex, frmtIndex - tempIndex).ToCharArray(); startIndex = scanIndex; if (charNotMatch) { // Format specifier contained a '^' so interate // until one of the chars in tempArr is found. while (scanOK && !charMatchFound) { if (scanIndex >= scanArr.Length) { scanOK = false; break; } for (i = 0; i < tempArr.Length; i++) { if (tempArr[i] == scanArr[scanIndex]) { charMatchFound = true; break; } } if (widthFlag && ((scanIndex - startIndex) >= width)) { break; } if (!charMatchFound) { scanIndex++; } } } else { // Iterate until the char in the scanArr is not // in the tempArr. charMatchFound = true; while (scanOK && charMatchFound) { if (scanIndex >= scanArr.Length) { scanOK = false; break; } charMatchFound = false; for (i = 0; i < tempArr.Length; i++) { if (tempArr[i] == scanArr[scanIndex]) { charMatchFound = true; break; } } if (widthFlag && (scanIndex - startIndex) >= width) { break; } if (charMatchFound) { scanIndex++; } } } // Indicates nothing was found. endIndex = scanIndex - startIndex; if (endIndex <= 0) { scanOK = false; break; } if (!discardFlag) { string str = new string(scanArr, startIndex, endIndex); testAndSetVar(interp, argv, argIndex++, TclString.NewInstance(str)); } break; } default: { errorBadField(interp, ch); } break; } // As long as the scan was successful (scanOK), the format // specifier did not contain a '*' (discardFlag), and // we are not at the end of the scanArr (scanArrDone); // increment the num of vars set in the interp. Otherwise // increment the number of valid format specifiers. if (scanOK && !discardFlag && !scanArrDone) { numMatched++; } else if ((scanArrDone || !scanOK) && !discardFlag) { numUnMatched++; } frmtIndex++; } else if (scanIndex < scanArr.Length && scanArr[scanIndex] == frmtArr[frmtIndex]) { // No '%' was found, but the characters matched scanIndex++; frmtIndex++; } else { // No '%' found and the characters int frmtArr & scanArr // did not match. frmtIndex++; } } // The numMatched is the return value: a count of the num of vars set. // While the numUnMatched is the number of formatSpecifiers that // passed the parsing stage, but did not match anything in the scanArr. if ((numMatched + numUnMatched) != (argv.Length - 3)) { errorDiffVars(interp); } interp.SetResult(TclInteger.NewInstance(numMatched)); return(TCL.CompletionCode.RETURN); }
/// <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: StringBuilder sbuf = new 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); } }
public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { bool nocase = false; bool indices = false; try { int i = 1; while (argv[i].ToString().StartsWith("-")) { int index = TclIndex.Get(interp, argv[i], validOpts, "switch", 0); i++; switch (index) { case OPT_INDICES: { indices = true; break; } case OPT_NOCASE: { nocase = true; break; } case OPT_LAST: { goto opts_brk; } } } opts_brk: ; TclObject exp = TclString.NewInstance(argv[i++].ToString().Replace("\\d", "[0-9]")); string inString = argv[i++].ToString(); int matches = argv.Length - i; Regexp r = TclRegexp.compile(interp, exp, nocase); int[] args = new int[matches * 2]; bool matched = r.match(inString, args); if (matched) { for (int match = 0; i < argv.Length; i++) { TclObject obj; int start = args[match++]; int end = args[match++]; if (indices) { if (end >= 0) { end--; } obj = TclList.NewInstance(); TclList.Append(interp, obj, TclInteger.NewInstance(start)); TclList.Append(interp, obj, TclInteger.NewInstance(end)); } else { string range = (start >= 0) ? inString.Substring(start, (end) - (start)) : ""; obj = TclString.NewInstance(range); } try { interp.SetVar(argv[i].ToString(), obj, 0); } catch (TclException e) { throw new TclException(interp, "couldn't set variable \"" + argv[i] + "\""); } } } interp.SetResult(matched); } catch (System.IndexOutOfRangeException e) { throw new TclNumArgsException(interp, 1, argv, "?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?"); } return(TCL.CompletionCode.RETURN); }
/// <summary> This procedure is invoked to process the "read" Tcl command. /// See the user documentation for details on what it does. /// /// </summary> /// <param name="interp">the current interpreter. /// </param> /// <param name="argv">command arguments. /// </param> public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { Channel chan; // The channel being operated on this // method int i = 1; // Index to the next arg in argv int toRead = 0; // Number of bytes or chars to read from channel int charactersRead; // Number of bytes or chars read from channel bool readAll = true; // If true read-all else toRead bool noNewline = false; // If true, strip the newline if there TclObject result; if ((argv.Length != 2) && (argv.Length != 3)) { errorWrongNumArgs(interp, argv[0].ToString()); } if (argv[i].ToString().Equals("-nonewline")) { noNewline = true; i++; } if (i == argv.Length) { errorWrongNumArgs(interp, argv[0].ToString()); } chan = TclIO.getChannel(interp, argv[i].ToString()); if (chan == null) { throw new TclException(interp, "can not find channel named \"" + argv[i].ToString() + "\""); } // Consumed channel name. i++; // Compute how many bytes or chars to read, and see whether the final // noNewline should be dropped. if (i < argv.Length) { string arg = argv[i].ToString(); if (System.Char.IsDigit(arg[0])) { toRead = TclInteger.Get(interp, argv[i]); readAll = false; } else if (arg.Equals("nonewline")) { noNewline = true; } else { throw new TclException(interp, "bad argument \"" + arg + "\": should be \"nonewline\""); } } try { if ((System.Object)chan.Encoding == null) { result = TclByteArray.NewInstance(); } else { result = TclString.NewInstance(new StringBuilder(64)); } if (readAll) { charactersRead = chan.read(interp, result, TclIO.READ_ALL, 0); // If -nonewline was specified, and we have not hit EOF // and the last char is a "\n", then remove it and return. if (noNewline) { string inStr = result.ToString(); if ((charactersRead > 0) && (inStr[charactersRead - 1] == '\n')) { interp.SetResult(inStr.Substring(0, ((charactersRead - 1)) - (0))); return(TCL.CompletionCode.RETURN); } } } else { // FIXME: Bug here, the -nonewline flag must be respected // when reading a set number of bytes charactersRead = chan.read(interp, result, TclIO.READ_N_BYTES, toRead); } /* * // FIXME: Port this -nonewline logic from the C code. * if (charactersRead < 0) { * Tcl_ResetResult(interp); * Tcl_AppendResult(interp, "error reading \"", name, "\": ", * Tcl_PosixError(interp), (char *) NULL); * Tcl_DecrRefCount(resultPtr); * return TCL_ERROR; * } * * // If requested, remove the last newline in the channel if at EOF. * * if ((charactersRead > 0) && (newline != 0)) { * char *result; * int length; * * result = Tcl_GetStringFromObj(resultPtr, length); * if (result[length - 1] == '\n') { * Tcl_SetObjLength(resultPtr, length - 1); * } * } * */ interp.SetResult(result); } catch (IOException e) { throw new TclRuntimeError("ReadCmd.cmdProc() Error: IOException when reading " + chan.ChanName); } return(TCL.CompletionCode.RETURN); }
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) { 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 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); }
public static TclObject Tcl_NewIntObj(int value) { return(TclInteger.NewInstance(value)); }
public TclObject get() { TclObject obj; TclToken token; string typeString; int nextIndex; string cmd; int i; System.Diagnostics.Debug.WriteLine("Entered TclParse.get()"); System.Diagnostics.Debug.WriteLine("numTokens is " + numTokens); obj = TclList.NewInstance(); try { if (commentSize > 0) { TclList.Append(interp, obj, TclString.NewInstance(new string(inString, commentStart, commentSize))); } else { TclList.Append(interp, obj, TclString.NewInstance("-")); } if (commandStart >= (endIndex + 1)) { commandStart = endIndex; } cmd = new string(inString, commandStart, commandSize); TclList.Append(interp, obj, TclString.NewInstance(cmd)); TclList.Append(interp, obj, TclInteger.NewInstance(numWords)); for (i = 0; i < numTokens; i++) { System.Diagnostics.Debug.WriteLine("processing token " + i); token = tokenList[i]; switch (token.type) { case Parser.TCL_TOKEN_WORD: typeString = "word"; break; case Parser.TCL_TOKEN_SIMPLE_WORD: typeString = "simple"; break; case Parser.TCL_TOKEN_EXPAND_WORD: typeString = "expand"; break; case Parser.TCL_TOKEN_TEXT: typeString = "text"; break; case Parser.TCL_TOKEN_BS: typeString = "backslash"; break; case Parser.TCL_TOKEN_COMMAND: typeString = "command"; break; case Parser.TCL_TOKEN_VARIABLE: typeString = "variable"; break; default: typeString = "??"; break; } System.Diagnostics.Debug.WriteLine("typeString is " + typeString); TclList.Append(interp, obj, TclString.NewInstance(typeString)); TclList.Append(interp, obj, TclString.NewInstance(token.TokenString)); TclList.Append(interp, obj, TclInteger.NewInstance(token.numComponents)); } nextIndex = commandStart + commandSize; TclList.Append(interp, obj, TclString.NewInstance(new string(inString, nextIndex, (endIndex - nextIndex)))); } catch (TclException e) { // Do Nothing. } return(obj); }
public static void Tcl_BackgroundError(Interp interp) { interp.SetErrorCode(TclInteger.NewInstance(TCL_ERROR)); interp.AddErrorInfo("Background Error"); }
/* *----------------------------------------------------------------------------- * * 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); }