/// <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); }
public static bool Tcl_GetIndexFromObj(Interp interp, TclObject to, string[] table, string msg, int flags, out int index) { try { index = TclIndex.Get(interp, to, table, msg, flags); return(false); } catch { index = 0; return(true); } }
private static void fileDelete(Interp interp, TclObject[] argv) { bool force = false; int firstSource = 2; for (bool last = false; (firstSource < argv.Length) && (!last); firstSource++) { if (!argv[firstSource].ToString().StartsWith("-")) { break; } int opt = TclIndex.Get(interp, argv[firstSource], validOptions, "option", 1); switch (opt) { case OPT_FORCE: force = true; break; case OPT_LAST: last = true; break; default: throw new TclRuntimeError("FileCmd.cmdProc: bad option " + opt + " index to validOptions"); } } if (firstSource >= argv.Length) { throw new TclNumArgsException(interp, 2, argv, "?options? file ?file ...?"); } for (int i = firstSource; i < argv.Length; i++) { deleteOneFile(interp, argv[i].ToString(), force); } }
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); }
/// <summary> Tcl_InfoObjCmd -> InfoCmd.cmdProc /// /// This procedure is invoked to process the "info" 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 # of args or invalid argument(s). /// </exception> public TCL.CompletionCode CmdProc(Interp interp, TclObject[] objv) { int index; if (objv.Length < 2) { throw new TclNumArgsException(interp, 1, objv, "option ?arg arg ...?"); } index = TclIndex.Get(interp, objv[1], validCmds, "option", 0); switch (index) { case OPT_ARGS: InfoArgsCmd(interp, objv); break; case OPT_BODY: InfoBodyCmd(interp, objv); break; case OPT_CMDCOUNT: InfoCmdCountCmd(interp, objv); break; case OPT_COMMANDS: InfoCommandsCmd(interp, objv); break; case OPT_COMPLETE: InfoCompleteCmd(interp, objv); break; case OPT_DEFAULT: InfoDefaultCmd(interp, objv); break; case OPT_EXISTS: InfoExistsCmd(interp, objv); break; case OPT_GLOBALS: InfoGlobalsCmd(interp, objv); break; case OPT_HOSTNAME: InfoHostnameCmd(interp, objv); break; case OPT_LEVEL: InfoLevelCmd(interp, objv); break; case OPT_LIBRARY: InfoLibraryCmd(interp, objv); break; case OPT_LOADED: InfoLoadedCmd(interp, objv); break; case OPT_LOCALS: InfoLocalsCmd(interp, objv); break; case OPT_NAMEOFEXECUTABLE: InfoNameOfExecutableCmd(interp, objv); break; case OPT_PATCHLEVEL: InfoPatchLevelCmd(interp, objv); break; case OPT_PROCS: InfoProcsCmd(interp, objv); break; case OPT_SCRIPT: InfoScriptCmd(interp, objv); break; case OPT_SHAREDLIBEXTENSION: InfoSharedlibCmd(interp, objv); break; case OPT_TCLVERSION: InfoTclVersionCmd(interp, objv); break; case OPT_VARS: InfoVarsCmd(interp, objv); break; } 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); }
/* *---------------------------------------------------------------------- * * cmdProc -- * * This procedure is invoked as part of the Command interface to * process the "lsort" Tcl command. See the user documentation for * details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { if (argv.Length < 2) { throw new TclNumArgsException(interp, 1, argv, "?options? list"); } string command = null; int sortMode = QSort.ASCII; int sortIndex = -1; bool sortIncreasing = true; bool unique = false; for (int i = 1; i < argv.Length - 1; i++) { int index = TclIndex.Get(interp, argv[i], validOpts, "option", 0); switch (index) { case 0: sortMode = QSort.ASCII; break; case 1: if (i == argv.Length - 2) { throw new TclException(interp, "\"-command\" option must be" + " followed by comparison command"); } sortMode = QSort.COMMAND; command = argv[i + 1].ToString(); i++; break; case 2: sortIncreasing = false; break; case 3: sortMode = QSort.DICTIONARY; break; case 4: sortIncreasing = true; break; case 5: if (i == argv.Length - 2) { throw new TclException(interp, "\"-index\" option must be followed by list index"); } sortIndex = Util.getIntForIndex(interp, argv[i + 1], -2); command = argv[i + 1].ToString(); i++; break; case 6: sortMode = QSort.INTEGER; break; case 7: sortMode = QSort.REAL; break; case 8: /* -unique */ unique = true; break; } } TclObject list = argv[argv.Length - 1]; bool isDuplicate = false; // If the list object is unshared we can modify it directly. Otherwise // we create a copy to modify: this is "copy on write". if (list.Shared) { list = list.duplicate(); isDuplicate = true; } try { TclList.sort(interp, list, sortMode, sortIndex, sortIncreasing, command, unique); interp.SetResult(list); } catch (TclException e) { if (isDuplicate) { list.Release(); } throw; } return(TCL.CompletionCode.RETURN); }
public TCL.CompletionCode CmdProc(Interp interp, TclObject[] objv) { int len; if (objv.Length < 2) { throw new TclNumArgsException(interp, 1, objv, "option [arg arg ...]"); } int opt = TclIndex.Get(interp, objv[1], validCmds, "option", 0); switch (opt) { case OPT_VARIABLE: case OPT_VDELETE: if (objv.Length != 5) { if (opt == OPT_VARIABLE) { throw new TclNumArgsException(interp, 1, objv, "variable name ops command"); } else { throw new TclNumArgsException(interp, 1, objv, "vdelete name ops command"); } } TCL.VarFlag flags = 0; string ops = objv[3].ToString(); len = ops.Length; { for (int i = 0; i < len; i++) { switch (ops[i]) { case 'r': flags |= TCL.VarFlag.TRACE_READS; break; case 'w': flags |= TCL.VarFlag.TRACE_WRITES; break; case 'u': flags |= TCL.VarFlag.TRACE_UNSETS; break; default: flags = 0; goto check_ops_brk; } } } check_ops_brk: ; if (flags == 0) { throw new TclException(interp, "bad operations \"" + objv[3] + "\": should be one or more of rwu"); } if (opt == OPT_VARIABLE) { CmdTraceProc trace = new CmdTraceProc(objv[4].ToString(), flags); Var.TraceVar(interp, objv[2], flags, trace); } else { // Search through all of our traces on this variable to // see if there's one with the given command. If so, then // delete the first one that matches. ArrayList traces = Var.getTraces(interp, objv[2].ToString(), 0); if (traces != null) { len = traces.Count; for (int i = 0; i < len; i++) { TraceRecord rec = (TraceRecord)traces[i]; if (rec.trace is CmdTraceProc) { CmdTraceProc proc = (CmdTraceProc)rec.trace; if (proc.flags == flags && proc.command.ToString().Equals(objv[4].ToString())) { Var.UntraceVar(interp, objv[2], flags, proc); break; } } } } } break; case OPT_VINFO: if (objv.Length != 3) { throw new TclNumArgsException(interp, 2, objv, "name"); } ArrayList traces2 = Var.getTraces(interp, objv[2].ToString(), 0); if (traces2 != null) { len = traces2.Count; TclObject list = TclList.NewInstance(); TclObject cmd = null; list.Preserve(); try { for (int i = 0; i < len; i++) { TraceRecord rec = (TraceRecord)traces2[i]; if (rec.trace is CmdTraceProc) { CmdTraceProc proc = (CmdTraceProc)rec.trace; TCL.VarFlag mode = proc.flags; mode &= (TCL.VarFlag.TRACE_READS | TCL.VarFlag.TRACE_WRITES | TCL.VarFlag.TRACE_UNSETS); int modeInt = (int)mode; modeInt /= ((int)TCL.VarFlag.TRACE_READS); cmd = TclList.NewInstance(); TclList.Append(interp, cmd, opStr[modeInt]); TclList.Append(interp, cmd, TclString.NewInstance(proc.command)); TclList.Append(interp, list, cmd); } } interp.SetResult(list); } finally { list.Release(); } } break; } return(TCL.CompletionCode.RETURN); }
/// <summary> This procedure is invoked to process the "subst" 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 # of args or invalid argument(s). /// </exception> public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { int currentObjIndex, len, i; int objc = argv.Length - 1; bool doBackslashes = true; bool doCmds = true; bool doVars = true; StringBuilder result = new StringBuilder(); string s; char c; for (currentObjIndex = 1; currentObjIndex < objc; currentObjIndex++) { if (!argv[currentObjIndex].ToString().StartsWith("-")) { break; } int opt = TclIndex.Get(interp, argv[currentObjIndex], validCmds, "switch", 0); switch (opt) { case OPT_NOBACKSLASHES: doBackslashes = false; break; case OPT_NOCOMMANDS: doCmds = false; break; case OPT_NOVARS: doVars = false; break; default: throw new TclException(interp, "SubstCmd.cmdProc: bad option " + opt + " index to cmds"); } } if (currentObjIndex != objc) { throw new TclNumArgsException(interp, currentObjIndex, argv, "?-nobackslashes? ?-nocommands? ?-novariables? string"); } /* * Scan through the string one character at a time, performing * command, variable, and backslash substitutions. */ s = argv[currentObjIndex].ToString(); len = s.Length; i = 0; while (i < len) { c = s[i]; if ((c == '[') && doCmds) { ParseResult res; try { interp._evalFlags = Parser.TCL_BRACKET_TERM; interp.Eval(s.Substring(i + 1, (len) - (i + 1))); TclObject interp_result = interp.GetResult(); interp_result.Preserve(); res = new ParseResult(interp_result, i + interp._termOffset); } catch (TclException e) { i = e.errIndex + 1; throw; } i = res.nextIndex + 2; result.Append(res.Value.ToString()); res.Release(); } else if (c == '\r') { /* * (ToDo) may not be portable on Mac */ i++; } else if ((c == '$') && doVars) { ParseResult vres = Parser.parseVar(interp, s.Substring(i, (len) - (i))); i += vres.nextIndex; result.Append(vres.Value.ToString()); vres.Release(); } else if ((c == '\\') && doBackslashes) { BackSlashResult bs = Tcl.Lang.Interp.backslash(s, i, len); i = bs.NextIndex; if (bs.IsWordSep) { break; } else { result.Append(bs.C); } } else { result.Append(c); i++; } } interp.SetResult(result.ToString()); return(TCL.CompletionCode.RETURN); }
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); }
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[] objv) { if (objv.Length < 2) { throw new TclNumArgsException(interp, 1, objv, "cmd ?arg ...?"); } int cmd = TclIndex.Get(interp, objv[1], options, "option", 0); switch (cmd) { case OPT_ALIAS: { if (objv.Length >= 4) { Interp slaveInterp = getInterp(interp, objv[2]); if (objv.Length == 4) { InterpAliasCmd.describe(interp, slaveInterp, objv[3]); return(TCL.CompletionCode.RETURN); } if ((objv.Length == 5) && ("".Equals(objv[4].ToString()))) { InterpAliasCmd.delete(interp, slaveInterp, objv[3]); return(TCL.CompletionCode.RETURN); } if (objv.Length > 5) { Interp masterInterp = getInterp(interp, objv[4]); if ("".Equals(objv[5].ToString())) { if (objv.Length == 6) { InterpAliasCmd.delete(interp, slaveInterp, objv[3]); return(TCL.CompletionCode.RETURN); } } else { InterpAliasCmd.create(interp, slaveInterp, masterInterp, objv[3], objv[5], 6, objv); return(TCL.CompletionCode.RETURN); } } } throw new TclNumArgsException(interp, 2, objv, "slavePath slaveCmd ?masterPath masterCmd? ?args ..?"); } case OPT_ALIASES: { Interp slaveInterp = getInterp(interp, objv); InterpAliasCmd.list(interp, slaveInterp); break; } case OPT_CREATE: { // Weird historical rules: "-safe" is accepted at the end, too. bool safe = interp._isSafe; TclObject slaveNameObj = null; bool last = false; for (int i = 2; i < objv.Length; i++) { if ((!last) && (objv[i].ToString()[0] == '-')) { int index = TclIndex.Get(interp, objv[i], createOptions, "option", 0); if (index == OPT_CREATE_SAFE) { safe = true; continue; } i++; last = true; } if (slaveNameObj != null) { throw new TclNumArgsException(interp, 2, objv, "?-safe? ?--? ?path?"); } slaveNameObj = objv[i]; } if (slaveNameObj == null) { // Create an anonymous interpreter -- we choose its name and // the name of the command. We check that the command name // that we use for the interpreter does not collide with an // existing command in the master interpreter. int i = 0; while (interp.getCommand("interp" + i) != null) { i++; } slaveNameObj = TclString.NewInstance("interp" + i); } InterpSlaveCmd.create(interp, slaveNameObj, safe); interp.SetResult(slaveNameObj); break; } case OPT_DELETE: { for (int i = 2; i < objv.Length; i++) { Interp slaveInterp = getInterp(interp, objv[i]); if (slaveInterp == interp) { throw new TclException(interp, "cannot delete the current interpreter"); } InterpSlaveCmd slave = slaveInterp._slave; slave.masterInterp.DeleteCommandFromToken(slave.interpCmd); } break; } case OPT_EVAL: { if (objv.Length < 4) { throw new TclNumArgsException(interp, 2, objv, "path arg ?arg ...?"); } Interp slaveInterp = getInterp(interp, objv[2]); InterpSlaveCmd.eval(interp, slaveInterp, 3, objv); break; } case OPT_EXISTS: { bool exists = true; try { getInterp(interp, objv); } catch (TclException e) { if (objv.Length > 3) { throw; } exists = false; } interp.SetResult(exists); break; } case OPT_EXPOSE: { if (objv.Length < 4 || objv.Length > 5) { throw new TclNumArgsException(interp, 2, objv, "path hiddenCmdName ?cmdName?"); } Interp slaveInterp = getInterp(interp, objv[2]); InterpSlaveCmd.expose(interp, slaveInterp, 3, objv); break; } case OPT_HIDE: { if (objv.Length < 4 || objv.Length > 5) { throw new TclNumArgsException(interp, 2, objv, "path cmdName ?hiddenCmdName?"); } Interp slaveInterp = getInterp(interp, objv[2]); InterpSlaveCmd.hide(interp, slaveInterp, 3, objv); break; } case OPT_HIDDEN: { Interp slaveInterp = getInterp(interp, objv); InterpSlaveCmd.hidden(interp, slaveInterp); break; } case OPT_ISSAFE: { Interp slaveInterp = getInterp(interp, objv); interp.SetResult(slaveInterp._isSafe); break; } case OPT_INVOKEHIDDEN: { bool global = false; int i; for (i = 3; i < objv.Length; i++) { if (objv[i].ToString()[0] != '-') { break; } int index = TclIndex.Get(interp, objv[i], hiddenOptions, "option", 0); if (index == OPT_HIDDEN_GLOBAL) { global = true; } else { i++; break; } } if (objv.Length - i < 1) { throw new TclNumArgsException(interp, 2, objv, "path ?-global? ?--? cmd ?arg ..?"); } Interp slaveInterp = getInterp(interp, objv[2]); InterpSlaveCmd.invokeHidden(interp, slaveInterp, global, i, objv); break; } case OPT_MARKTRUSTED: { if (objv.Length != 3) { throw new TclNumArgsException(interp, 2, objv, "path"); } Interp slaveInterp = getInterp(interp, objv[2]); InterpSlaveCmd.markTrusted(interp, slaveInterp); break; } case OPT_SLAVES: { Interp slaveInterp = getInterp(interp, objv); TclObject result = TclList.NewInstance(); interp.SetResult(result); IEnumerator keys = slaveInterp._slaveTable.Keys.GetEnumerator(); while (keys.MoveNext()) { string inString = (string)keys.Current; TclList.Append(interp, result, TclString.NewInstance(inString)); } break; } case OPT_SHARE: { if (objv.Length != 5) { throw new TclNumArgsException(interp, 2, objv, "srcPath channelId destPath"); } Interp masterInterp = getInterp(interp, objv[2]); Channel chan = TclIO.getChannel(masterInterp, objv[3].ToString()); if (chan == null) { throw new TclException(interp, "can not find channel named \"" + objv[3].ToString() + "\""); } Interp slaveInterp = getInterp(interp, objv[4]); TclIO.registerChannel(slaveInterp, chan); break; } case OPT_TARGET: { if (objv.Length != 4) { throw new TclNumArgsException(interp, 2, objv, "path alias"); } Interp slaveInterp = getInterp(interp, objv[2]); string aliasName = objv[3].ToString(); Interp targetInterp = InterpAliasCmd.getTargetInterp(slaveInterp, aliasName); if (targetInterp == null) { throw new TclException(interp, "alias \"" + aliasName + "\" in path \"" + objv[2].ToString() + "\" not found"); } if (!getInterpPath(interp, targetInterp)) { throw new TclException(interp, "target interpreter for alias \"" + aliasName + "\" in path \"" + objv[2].ToString() + "\" is not my descendant"); } break; } case OPT_TRANSFER: { if (objv.Length != 5) { throw new TclNumArgsException(interp, 2, objv, "srcPath channelId destPath"); } Interp masterInterp = getInterp(interp, objv[2]); Channel chan = TclIO.getChannel(masterInterp, objv[3].ToString()); if (chan == null) { throw new TclException(interp, "can not find channel named \"" + objv[3].ToString() + "\""); } Interp slaveInterp = getInterp(interp, objv[4]); TclIO.registerChannel(slaveInterp, chan); TclIO.unregisterChannel(masterInterp, chan); break; } } return(TCL.CompletionCode.RETURN); }
/// <summary> 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); }
private const char FORMAT_END = ' '; // End of format was found. public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { int arg; // Index of next argument to consume. char[] format = null; // User specified format string. char cmd; // Current format character. int cursor; // Current position within result buffer. int maxPos; // Greatest position within result buffer that cursor has visited. int value = 0; // Current integer value to be packed. int offset, size = 0, length; // Initialized to avoid compiler warning. if (argv.Length < 2) { throw new TclNumArgsException(interp, 1, argv, "option ?arg arg ...?"); } int cmdIndex = TclIndex.Get(interp, argv[1], _validCmds, "option", 0); switch (cmdIndex) { case CMD_FORMAT: { if (argv.Length < 3) { throw new TclNumArgsException(interp, 2, argv, "formatString ?arg arg ...?"); } // To avoid copying the data, we format the string in two passes. The first pass computes the size of the output buffer. The // second pass places the formatted data into the buffer. format = argv[2].ToString().ToCharArray(); arg = 3; length = 0; offset = 0; int parsePos = 0; while ((cmd = GetFormatSpec(format, ref parsePos)) != FORMAT_END) { int count = GetFormatCount(format, ref parsePos); switch (cmd) { case 'a': case 'A': case 'b': case 'B': case 'h': case 'H': { // For string-type specifiers, the count corresponds to the number of bytes in a single argument. if (arg >= argv.Length) { MissingArg(interp); } if (count == BINARY_ALL) { count = TclByteArray.getLength(interp, argv[arg]); } else if (count == BINARY_NOCOUNT) { count = 1; } arg++; switch (cmd) { case 'a': case 'A': offset += count; break; case 'b': case 'B': offset += (count + 7) / 8; break; case 'h': case 'H': offset += (count + 1) / 2; break; } break; } case 'c': case 's': case 'S': case 'i': case 'I': case 'f': case 'd': { if (arg >= argv.Length) { MissingArg(interp); } switch (cmd) { case 'c': size = 1; break; case 's': case 'S': size = 2; break; case 'i': case 'I': size = 4; break; case 'f': size = 4; break; case 'd': size = 8; break; } // For number-type specifiers, the count corresponds to the number of elements in the list stored in // a single argument. If no count is specified, then the argument is taken as a single non-list value. if (count == BINARY_NOCOUNT) { arg++; count = 1; } else { int listc = TclList.getLength(interp, argv[arg++]); if (count == BINARY_ALL) { count = listc; } else if (count > listc) { throw new TclException(interp, "number of elements in list" + " does not match count"); } } offset += count * size; break; } case 'x': { if (count == BINARY_ALL) { throw new TclException(interp, "cannot use \"*\"" + " in format string with \"x\""); } if (count == BINARY_NOCOUNT) { count = 1; } offset += count; break; } case 'X': { if (count == BINARY_NOCOUNT) { count = 1; } if (count > offset || count == BINARY_ALL) { count = offset; } if (offset > length) { length = offset; } offset -= count; break; } case '@': { if (offset > length) { length = offset; } if (count == BINARY_ALL) { offset = length; } else if (count == BINARY_NOCOUNT) { AlephWithoutCount(interp); } else { offset = count; } break; } default: { BadField(interp, cmd); } break; } } if (offset > length) { length = offset; } if (length == 0) { return(TCL.CompletionCode.RETURN); } // Prepare the result object by preallocating the calculated number of bytes and filling with nulls. TclObject resultObj = TclByteArray.NewInstance(); byte[] resultBytes = TclByteArray.SetLength(interp, resultObj, length); interp.SetResult(resultObj); // Pack the data into the result object. Note that we can skip the error checking during this pass, since we have already parsed the string once. arg = 3; cursor = 0; maxPos = cursor; parsePos = 0; while ((cmd = GetFormatSpec(format, ref parsePos)) != FORMAT_END) { int count = GetFormatCount(format, ref parsePos); if (count == 0 && cmd != '@') { arg++; continue; } switch (cmd) { case 'a': case 'A': { byte pad = (cmd == 'a' ? (byte)0 : (byte)SupportClass.Identity(' ')); byte[] bytes = TclByteArray.getBytes(interp, argv[arg++]); length = bytes.Length; if (count == BINARY_ALL) { count = length; } else if (count == BINARY_NOCOUNT) { count = 1; } if (length >= count) { Array.Copy(bytes, 0, resultBytes, cursor, count); } else { Array.Copy(bytes, 0, resultBytes, cursor, length); for (int ix = 0; ix < count - length; ix++) { resultBytes[cursor + length + ix] = pad; } } cursor += count; break; } case 'b': case 'B': { char[] str = argv[arg++].ToString().ToCharArray(); if (count == BINARY_ALL) { count = str.Length; } else if (count == BINARY_NOCOUNT) { count = 1; } int last = cursor + ((count + 7) / 8); if (count > str.Length) { count = str.Length; } if (cmd == 'B') { for (offset = 0; offset < count; offset++) { value <<= 1; if (str[offset] == '1') { value |= 1; } else if (str[offset] != '0') { ExpectedButGot(interp, "binary", new string(str)); } if (((offset + 1) % 8) == 0) { resultBytes[cursor++] = (byte)value; value = 0; } } } else { for (offset = 0; offset < count; offset++) { value >>= 1; if (str[offset] == '1') { value |= 128; } else if (str[offset] != '0') { ExpectedButGot(interp, "binary", new string(str)); } if (((offset + 1) % 8) == 0) { resultBytes[cursor++] = (byte)value; value = 0; } } } if ((offset % 8) != 0) { if (cmd == 'B') { value <<= 8 - (offset % 8); } else { value >>= 8 - (offset % 8); } resultBytes[cursor++] = (byte)value; } while (cursor < last) { resultBytes[cursor++] = 0; } break; } case 'h': case 'H': { char[] str = argv[arg++].ToString().ToCharArray(); if (count == BINARY_ALL) { count = str.Length; } else if (count == BINARY_NOCOUNT) { count = 1; } int last = cursor + ((count + 1) / 2); if (count > str.Length) { count = str.Length; } if (cmd == 'H') { for (offset = 0; offset < count; offset++) { value <<= 4; int c = HEXDIGITS.IndexOf(Char.ToLower(str[offset])); if (c < 0) { ExpectedButGot(interp, "hexadecimal", new string(str)); } value |= (c & 0xf); if ((offset % 2) != 0) { resultBytes[cursor++] = (byte)value; value = 0; } } } else { for (offset = 0; offset < count; offset++) { value >>= 4; int c = HEXDIGITS.IndexOf(Char.ToLower(str[offset])); if (c < 0) { ExpectedButGot(interp, "hexadecimal", new string(str)); } value |= ((c << 4) & 0xf0); if ((offset % 2) != 0) { resultBytes[cursor++] = (byte)value; value = 0; } } } if ((offset % 2) != 0) { if (cmd == 'H') { value <<= 4; } else { value >>= 4; } resultBytes[cursor++] = (byte)value; } while (cursor < last) { resultBytes[cursor++] = 0; } break; } case 'c': case 's': case 'S': case 'i': case 'I': case 'f': case 'd': { TclObject[] listv; if (count == BINARY_NOCOUNT) { listv = new TclObject[1]; listv[0] = argv[arg++]; count = 1; } else { listv = TclList.getElements(interp, argv[arg++]); if (count == BINARY_ALL) { count = listv.Length; } } for (int ix = 0; ix < count; ix++) { cursor = FormatNumber(interp, cmd, listv[ix], resultBytes, cursor); } break; } case 'x': { if (count == BINARY_NOCOUNT) { count = 1; } for (int ix = 0; ix < count; ix++) { resultBytes[cursor++] = 0; } break; } case 'X': { if (cursor > maxPos) { maxPos = cursor; } if (count == BINARY_NOCOUNT) { count = 1; } if (count == BINARY_ALL || count > cursor) { cursor = 0; } else { cursor -= count; } break; } case '@': { if (cursor > maxPos) { maxPos = cursor; } if (count == BINARY_ALL) { cursor = maxPos; } else { cursor = count; } break; } } } break; } case CMD_SCAN: { if (argv.Length < 4) { throw new TclNumArgsException(interp, 2, argv, "value formatString ?varName varName ...?"); } byte[] src = TclByteArray.getBytes(interp, argv[2]); length = src.Length; format = argv[3].ToString().ToCharArray(); arg = 4; cursor = 0; offset = 0; int parsePos = 0; while ((cmd = GetFormatSpec(format, ref parsePos)) != FORMAT_END) { int count = GetFormatCount(format, ref parsePos); switch (cmd) { case 'a': case 'A': { if (arg >= argv.Length) { MissingArg(interp); } if (count == BINARY_ALL) { count = length - offset; } else { if (count == BINARY_NOCOUNT) { count = 1; } if (count > length - offset) { break; } } size = count; // Trim trailing nulls and spaces, if necessary. if (cmd == 'A') { while (size > 0) { if (src[offset + size - 1] != '\x0000' && src[offset + size - 1] != ' ') { break; } size--; } } interp.SetVar(argv[arg++], TclByteArray.NewInstance(src, offset, size), 0); offset += count; break; } case 'b': case 'B': { if (arg >= argv.Length) { MissingArg(interp); } if (count == BINARY_ALL) { count = (length - offset) * 8; } else { if (count == BINARY_NOCOUNT) { count = 1; } if (count > (length - offset) * 8) { break; } } StringBuilder s = new StringBuilder(count); int thisOffset = offset; if (cmd == 'b') { for (int ix = 0; ix < count; ix++) { if ((ix % 8) != 0) { value >>= 1; } else { value = src[thisOffset++]; } s.Append((value & 1) != 0 ? '1' : '0'); } } else { for (int ix = 0; ix < count; ix++) { if ((ix % 8) != 0) { value <<= 1; } else { value = src[thisOffset++]; } s.Append((value & 0x80) != 0 ? '1' : '0'); } } interp.SetVar(argv[arg++], TclString.NewInstance(s.ToString()), 0); offset += (count + 7) / 8; break; } case 'h': case 'H': { if (arg >= argv.Length) { MissingArg(interp); } if (count == BINARY_ALL) { count = (length - offset) * 2; } else { if (count == BINARY_NOCOUNT) { count = 1; } if (count > (length - offset) * 2) { break; } } StringBuilder s = new StringBuilder(count); int thisOffset = offset; if (cmd == 'h') { for (int ix = 0; ix < count; ix++) { if ((ix % 2) != 0) { value >>= 4; } else { value = src[thisOffset++]; } s.Append(HEXDIGITS[value & 0xf]); } } else { for (int ix = 0; ix < count; ix++) { if ((ix % 2) != 0) { value <<= 4; } else { value = src[thisOffset++]; } s.Append(HEXDIGITS[value >> 4 & 0xf]); } } interp.SetVar(argv[arg++], TclString.NewInstance(s.ToString()), 0); offset += (count + 1) / 2; break; } case 'c': case 's': case 'S': case 'i': case 'I': case 'f': case 'd': { if (arg >= argv.Length) { MissingArg(interp); } switch (cmd) { case 'c': size = 1; break; case 's': case 'S': size = 2; break; case 'i': case 'I': size = 4; break; case 'f': size = 4; break; case 'd': size = 8; break; } TclObject valueObj; if (count == BINARY_NOCOUNT) { if (length - offset < size) { break; } valueObj = ScanNumber(src, offset, cmd); offset += size; } else { if (count == BINARY_ALL) { count = (length - offset) / size; } if (length - offset < count * size) { break; } valueObj = TclList.NewInstance(); int thisOffset = offset; for (int ix = 0; ix < count; ix++) { TclList.Append(null, valueObj, ScanNumber(src, thisOffset, cmd)); thisOffset += size; } offset += count * size; } interp.SetVar(argv[arg++], valueObj, 0); break; } case 'x': { if (count == BINARY_NOCOUNT) { count = 1; } if (count == BINARY_ALL || count > length - offset) { offset = length; } else { offset += count; } break; } case 'X': { if (count == BINARY_NOCOUNT) { count = 1; } if (count == BINARY_ALL || count > offset) { offset = 0; } else { offset -= count; } break; } case '@': { if (count == BINARY_NOCOUNT) { AlephWithoutCount(interp); } if (count == BINARY_ALL || count > length) { offset = length; } else { offset = count; } break; } default: { BadField(interp, cmd); } break; } } // Set the result to the last position of the cursor. interp.SetResult(arg - 4); } break; } return(TCL.CompletionCode.RETURN); }
public TCL.CompletionCode CmdProc(Interp interp, TclObject[] objv) { if (objv.Length < 2) { throw new TclNumArgsException(interp, 1, objv, "cmd ?arg ...?"); } int cmd = TclIndex.Get(interp, objv[1], options, "option", 0); switch (cmd) { case OPT_ALIAS: if (objv.Length == 3) { InterpAliasCmd.describe(interp, slaveInterp, objv[2]); return(TCL.CompletionCode.RETURN); } if ("".Equals(objv[3].ToString())) { if (objv.Length == 4) { InterpAliasCmd.delete(interp, slaveInterp, objv[2]); return(TCL.CompletionCode.RETURN); } } else { InterpAliasCmd.create(interp, slaveInterp, interp, objv[2], objv[3], 4, objv); return(TCL.CompletionCode.RETURN); } throw new TclNumArgsException(interp, 2, objv, "aliasName ?targetName? ?args..?"); case OPT_ALIASES: InterpAliasCmd.list(interp, slaveInterp); break; case OPT_EVAL: if (objv.Length < 3) { throw new TclNumArgsException(interp, 2, objv, "arg ?arg ...?"); } eval(interp, slaveInterp, 2, objv); break; case OPT_EXPOSE: if (objv.Length < 3 || objv.Length > 4) { throw new TclNumArgsException(interp, 2, objv, "hiddenCmdName ?cmdName?"); } expose(interp, slaveInterp, 2, objv); break; case OPT_HIDE: if (objv.Length < 3 || objv.Length > 4) { throw new TclNumArgsException(interp, 2, objv, "cmdName ?hiddenCmdName?"); } hide(interp, slaveInterp, 2, objv); break; case OPT_HIDDEN: if (objv.Length != 2) { throw new TclNumArgsException(interp, 2, objv, null); } InterpSlaveCmd.hidden(interp, slaveInterp); break; case OPT_ISSAFE: interp.SetResult(slaveInterp._isSafe); break; case OPT_INVOKEHIDDEN: bool global = false; int i; for (i = 2; i < objv.Length; i++) { if (objv[i].ToString()[0] != '-') { break; } int index = TclIndex.Get(interp, objv[i], hiddenOptions, "option", 0); if (index == OPT_HIDDEN_GLOBAL) { global = true; } else { i++; break; } } if (objv.Length - i < 1) { throw new TclNumArgsException(interp, 2, objv, "?-global? ?--? cmd ?arg ..?"); } InterpSlaveCmd.invokeHidden(interp, slaveInterp, global, i, objv); break; case OPT_MARKTRUSTED: if (objv.Length != 2) { throw new TclNumArgsException(interp, 2, objv, null); } markTrusted(interp, slaveInterp); break; } return(TCL.CompletionCode.RETURN); }
public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { bool noComplain = false; // If false, error msg will be returned int index; // index of the char just after the end // of the user name int firstArg = 1; // index of the first non-switch arg int i; // generic index string arg; // generic arg string string head = ""; // abs path of user name if provided string tail = ""; // the remaining file path and pattern TclObject resultList; // list of files that match the pattern for (bool last = false; (firstArg < argv.Length) && (!last); firstArg++) { if (!argv[firstArg].ToString().StartsWith("-")) { break; } int opt = TclIndex.Get(interp, argv[firstArg], validOptions, "switch", 1); switch (opt) { case OPT_NOCOMPLAIN: noComplain = true; break; case OPT_LAST: last = true; break; default: throw new TclException(interp, "GlobCmd.cmdProc: bad option " + opt + " index to validOptions"); } } if (firstArg >= argv.Length) { throw new TclNumArgsException(interp, 1, argv, "?switches? name ?name ...?"); } resultList = TclList.NewInstance(); resultList.Preserve(); for (i = firstArg; i < argv.Length; i++) { arg = argv[i].ToString(); string separators; // The system-specific file separators switch (JACL.PLATFORM) { case JACL.PLATFORM_WINDOWS: separators = "/\\:"; break; case JACL.PLATFORM_MAC: if (arg.IndexOf((System.Char) ':') == -1) { separators = "/"; } else { separators = ":"; } break; default: separators = "/"; break; } // Perform tilde substitution, if needed. index = 0; if (arg.StartsWith("~")) { // Find the first path separator after the tilde. for (; index < arg.Length; index++) { char c = arg[index]; if (c == '\\') { if (separators.IndexOf((System.Char)arg[index + 1]) != -1) { break; } } else if (separators.IndexOf((System.Char)c) != -1) { break; } } // Determine the home directory for the specified user. Note // that we don't allow special characters in the user name. if (strpbrk(arg.Substring(1, (index) - (1)).ToCharArray(), specCharArr) < 0) { try { head = FileUtil.doTildeSubst(interp, arg.Substring(1, (index) - (1))); } catch (TclException e) { if (noComplain) { head = null; } else { throw new TclException(interp, e.Message); } } } else { if (!noComplain) { throw new TclException(interp, "globbing characters not supported in user names"); } head = null; } if ((System.Object)head == null) { if (noComplain) { interp.SetResult(""); return(TCL.CompletionCode.RETURN); } else { return(TCL.CompletionCode.RETURN); } } if (index != arg.Length) { index++; } } tail = arg.Substring(index); try { doGlob(interp, separators, new StringBuilder(head), tail, resultList); } catch (TclException e) { if (noComplain) { continue; } else { throw new TclException(interp, e.Message); } } } // If the list is empty and the nocomplain switch was not set then // generate and throw an exception. Always release the TclList upon // completion. try { if ((TclList.getLength(interp, resultList) == 0) && !noComplain) { string sep = ""; StringBuilder ret = new StringBuilder(); ret.Append("no files matched glob pattern"); ret.Append((argv.Length == 2) ? " \"" : "s \""); for (i = firstArg; i < argv.Length; i++) { ret.Append(sep + argv[i].ToString()); if (i == firstArg) { sep = " "; } } ret.Append("\""); throw new TclException(interp, ret.ToString()); } else if (TclList.getLength(interp, resultList) > 0) { interp.SetResult(resultList); } } finally { resultList.Release(); } return(TCL.CompletionCode.RETURN); }
public TCL.CompletionCode CmdProc(Interp interp, TclObject[] objv) { VersionSatisfiesResult vsres; Package pkg; PkgAvail avail; PkgAvail prev; string version; string pkgName; string key; string cmd; string ver1, ver2; StringBuilder sbuf; IDictionaryEnumerator enum_Renamed; int i, opt, exact; bool once; if (objv.Length < 2) { throw new TclNumArgsException(interp, 1, objv, "option ?arg arg ...?"); } opt = TclIndex.Get(interp, objv[1], validCmds, "option", 0); switch (opt) { case OPT_FORGET: { // Forget takes 0 or more arguments. for (i = 2; i < objv.Length; i++) { // We do not need to check to make sure // package name is "" because it would not // be in the hash table so name will be ignored. pkgName = objv[i].ToString(); pkg = (Package)interp._packageTable[pkgName]; // If this package does not exist, go to next one. if (pkg == null) { continue; } SupportClass.HashtableRemove(interp._packageTable, pkgName); while (pkg.avail != null) { avail = pkg.avail; pkg.avail = avail.next; avail = null; } pkg = null; } return(TCL.CompletionCode.RETURN); } case OPT_IFNEEDED: { if ((objv.Length < 4) || (objv.Length > 5)) { throw new TclNumArgsException(interp, 1, objv, "ifneeded package version ?script?"); } pkgName = objv[2].ToString(); version = objv[3].ToString(); // Verify that this version string is valid. checkVersion(interp, version); if (objv.Length == 4) { pkg = (Package)interp._packageTable[pkgName]; if (pkg == null) { return(TCL.CompletionCode.RETURN); } } else { pkg = findPackage(interp, pkgName); } for (avail = pkg.avail, prev = null; avail != null; prev = avail, avail = avail.next) { if (compareVersions(avail.version, version, null) == 0) { if (objv.Length == 4) { // If doing a query return current script. interp.SetResult(avail.script); return(TCL.CompletionCode.RETURN); } // We matched so we must be setting the script. break; } } // When we do not match on a query return nothing. if (objv.Length == 4) { return(TCL.CompletionCode.RETURN); } if (avail == null) { avail = new PkgAvail(); avail.version = version; if (prev == null) { avail.next = pkg.avail; pkg.avail = avail; } else { avail.next = prev.next; prev.next = avail; } } avail.script = objv[4].ToString(); return(TCL.CompletionCode.RETURN); } case OPT_NAMES: { if (objv.Length != 2) { throw new TclNumArgsException(interp, 1, objv, "names"); } try { sbuf = new StringBuilder(); enum_Renamed = interp._packageTable.GetEnumerator(); once = false; while (enum_Renamed.MoveNext()) { once = true; key = ((string)enum_Renamed.Current); pkg = (Package)enum_Renamed.Value; if (((System.Object)pkg.version != null) || (pkg.avail != null)) { Util.appendElement(interp, sbuf, key); } } if (once) { interp.SetResult(sbuf.ToString()); } } catch (TclException e) { throw new TclRuntimeError("unexpected TclException: " + e); } return(TCL.CompletionCode.RETURN); } case OPT_PRESENT: { if (objv.Length < 3) { throw new TclNumArgsException(interp, 2, objv, "?-exact? package ?version?"); } if (objv[2].ToString().Equals("-exact")) { exact = 1; } else { exact = 0; } version = null; if (objv.Length == (4 + exact)) { version = objv[3 + exact].ToString(); checkVersion(interp, version); } else if ((objv.Length != 3) || (exact == 1)) { throw new TclNumArgsException(interp, 2, objv, "?-exact? package ?version?"); } if (exact == 1) { version = pkgPresent(interp, objv[3].ToString(), version, true); } else { version = pkgPresent(interp, objv[2].ToString(), version, false); } interp.SetResult(version); break; } case OPT_PROVIDE: { if ((objv.Length < 3) || (objv.Length > 4)) { throw new TclNumArgsException(interp, 1, objv, "provide package ?version?"); } if (objv.Length == 3) { pkg = (Package)interp._packageTable[objv[2].ToString()]; if (pkg != null) { if ((System.Object)pkg.version != null) { interp.SetResult(pkg.version); } } return(TCL.CompletionCode.RETURN); } pkgProvide(interp, objv[2].ToString(), objv[3].ToString()); return(TCL.CompletionCode.RETURN); } case OPT_REQUIRE: { if ((objv.Length < 3) || (objv.Length > 5)) { throw new TclNumArgsException(interp, 1, objv, "require ?-exact? package ?version?"); } if (objv[2].ToString().Equals("-exact")) { exact = 1; } else { exact = 0; } version = null; if (objv.Length == (4 + exact)) { version = objv[3 + exact].ToString(); checkVersion(interp, version); } else if ((objv.Length != 3) || (exact == 1)) { throw new TclNumArgsException(interp, 1, objv, "require ?-exact? package ?version?"); } if (exact == 1) { version = pkgRequire(interp, objv[3].ToString(), version, true); } else { version = pkgRequire(interp, objv[2].ToString(), version, false); } interp.SetResult(version); return(TCL.CompletionCode.RETURN); } case OPT_UNKNOWN: { if (objv.Length > 3) { throw new TclNumArgsException(interp, 1, objv, "unknown ?command?"); } if (objv.Length == 2) { if ((System.Object)interp._packageUnknown != null) { interp.SetResult(interp._packageUnknown); } } else if (objv.Length == 3) { interp._packageUnknown = null; cmd = objv[2].ToString(); if (cmd.Length > 0) { interp._packageUnknown = cmd; } } return(TCL.CompletionCode.RETURN); } case OPT_VCOMPARE: { if (objv.Length != 4) { throw new TclNumArgsException(interp, 1, objv, "vcompare version1 version2"); } ver1 = objv[2].ToString(); ver2 = objv[3].ToString(); checkVersion(interp, ver1); checkVersion(interp, ver2); interp.SetResult(compareVersions(ver1, ver2, null)); return(TCL.CompletionCode.RETURN); } case OPT_VERSIONS: { if (objv.Length != 3) { throw new TclNumArgsException(interp, 1, objv, "versions package"); } pkg = (Package)interp._packageTable[objv[2].ToString()]; if (pkg != null) { try { sbuf = new StringBuilder(); once = false; for (avail = pkg.avail; avail != null; avail = avail.next) { once = true; Util.appendElement(interp, sbuf, avail.version); } if (once) { interp.SetResult(sbuf.ToString()); } } catch (TclException e) { throw new TclRuntimeError("unexpected TclException: " + e.Message, e); } } return(TCL.CompletionCode.RETURN); } case OPT_VSATISFIES: { if (objv.Length != 4) { throw new TclNumArgsException(interp, 1, objv, "vsatisfies version1 version2"); } ver1 = objv[2].ToString(); ver2 = objv[3].ToString(); checkVersion(interp, ver1); checkVersion(interp, ver2); vsres = new VersionSatisfiesResult(); compareVersions(ver1, ver2, vsres); interp.SetResult(vsres.satisfies); return(TCL.CompletionCode.RETURN); } default: { throw new TclRuntimeError("TclIndex.get() error"); } } // end switch(opt) return(TCL.CompletionCode.RETURN); }
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 "encoding" 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) { if (argv.Length < 2) { throw new TclNumArgsException(interp, 1, argv, "option ?arg ...?"); } int index = TclIndex.Get(interp, argv[1], validCmds, "option", 0); switch (index) { case OPT_CONVERTTO: case OPT_CONVERTFROM: { string tclEncoding; Encoding javaEncoding; TclObject data; if (argv.Length == 3) { tclEncoding = systemTclEncoding; data = argv[2]; } else if (argv.Length == 4) { tclEncoding = argv[2].ToString(); data = argv[3]; } else { throw new TclNumArgsException(interp, 2, argv, "?encoding? data"); } javaEncoding = getJavaName(tclEncoding); if ((System.Object)javaEncoding == null) { throw new TclException(interp, "unknown encoding \"" + tclEncoding + "\""); } try { if (index == OPT_CONVERTFROM) { // Treat the string as binary data byte[] bytes = TclByteArray.getBytes(interp, data); // ATK interp.SetResult(System.Text.Encoding.UTF8.GetString(bytes, 0, bytes.Length)); } else { // Store the result as binary data // ATK byte[] bytes = data.ToString().getBytes(javaEncoding); byte[] bytes = System.Text.Encoding.UTF8.GetBytes(data.ToString()); interp.SetResult(TclByteArray.NewInstance(bytes)); } } catch (IOException ex) { throw new TclRuntimeError("Encoding.cmdProc() error: " + "unsupported java encoding \"" + javaEncoding + "\""); } break; } case OPT_NAMES: { if (argv.Length > 2) { throw new TclNumArgsException(interp, 2, argv, null); } TclObject list = TclList.NewInstance(); for (int i = 0; i < tclNames.Length; i++) { TclList.Append(interp, list, TclString.NewInstance(tclNames[i])); } interp.SetResult(list); break; } case OPT_SYSTEM: { if (argv.Length > 3) { throw new TclNumArgsException(interp, 2, argv, "?encoding?"); } if (argv.Length == 2) { interp.SetResult(systemTclEncoding); } else { string tclEncoding = argv[2].ToString(); Encoding javaEncoding = getJavaName(tclEncoding); if (javaEncoding == null) { throw new TclException(interp, "unknown encoding \"" + tclEncoding + "\""); } systemTclEncoding = tclEncoding; systemJavaEncoding = javaEncoding; } break; } default: { throw new TclRuntimeError("Encoding.cmdProc() error: " + "incorrect index returned from TclIndex.get()"); } } return(TCL.CompletionCode.RETURN); }
public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { if (argv.Length < 2) { throw new TclNumArgsException(interp, 1, argv, "option ?arg ...?"); } int opt = TclIndex.Get(interp, argv[1], validCmds, "option", 0); string path; FileInfo fileObj = null; switch (opt) { case OPT_ATIME: if (argv.Length != 3) { throw new TclNumArgsException(interp, 2, argv, "name"); } // FIXME: Currently returns the same thing as MTIME. // Java does not support retrieval of access time. fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString()); interp.SetResult(getMtime(interp, argv[2].ToString(), fileObj)); return(TCL.CompletionCode.RETURN); case OPT_ATTRIBUTES: if (argv[3].ToString() == "-readonly") { fileSetReadOnly(interp, argv); } else { throw new TclException(interp, "sorry, \"file attributes\" is not implemented yet"); } return(TCL.CompletionCode.RETURN); case OPT_CHANNELS: throw new TclException(interp, "sorry, \"file channels\" is not implemented yet"); case OPT_COPY: fileCopyRename(interp, argv, true); return(TCL.CompletionCode.RETURN); case OPT_DELETE: fileDelete(interp, argv); return(TCL.CompletionCode.RETURN); case OPT_DIRNAME: if (argv.Length != 3) { throw new TclNumArgsException(interp, 2, argv, "name"); } path = argv[2].ToString(); // Return all but the last component. If there is only one // component, return it if the path was non-relative, otherwise // return the current directory. TclObject[] splitArrayObj = TclList.getElements(interp, FileUtil.splitAndTranslate(interp, path)); if (splitArrayObj.Length > 1) { interp.SetResult(FileUtil.joinPath(interp, splitArrayObj, 0, splitArrayObj.Length - 1)); } else if ((splitArrayObj.Length == 0) || (FileUtil.getPathType(path) == FileUtil.PATH_RELATIVE)) { if (JACL.PLATFORM == JACL.PLATFORM_MAC) { interp.SetResult(":"); } else { interp.SetResult("."); } } else { interp.SetResult(splitArrayObj[0].ToString()); } return(TCL.CompletionCode.RETURN); case OPT_EXECUTABLE: if (argv.Length != 3) { throw new TclNumArgsException(interp, 2, argv, "name"); } bool isExe = false; fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString()); // A file must exist to be executable. Directories are always // executable. bool tmpBool; if (File.Exists(fileObj.FullName)) { tmpBool = true; } else { tmpBool = Directory.Exists(fileObj.FullName); } if (tmpBool) { isExe = Directory.Exists(fileObj.FullName); if (isExe) { interp.SetResult(isExe); return(TCL.CompletionCode.RETURN); } if (Util.Windows) { // File that ends with .exe, .com, or .bat is executable. string fileName = argv[2].ToString(); isExe = (fileName.EndsWith(".exe") || fileName.EndsWith(".com") || fileName.EndsWith(".bat")); } else if (Util.Mac) { // FIXME: Not yet implemented on Mac. For now, return true. // Java does not support executability checking. isExe = true; } else { // FIXME: Not yet implemented on Unix. For now, return true. // Java does not support executability checking. isExe = true; } } interp.SetResult(isExe); return(TCL.CompletionCode.RETURN); case OPT_EXISTS: if (argv.Length != 3) { throw new TclNumArgsException(interp, 2, argv, "name"); } fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString()); bool tmpBool2; if (File.Exists(fileObj.FullName)) { tmpBool2 = true; } else { tmpBool2 = Directory.Exists(fileObj.FullName); } interp.SetResult(tmpBool2); return(TCL.CompletionCode.RETURN); case OPT_EXTENSION: if (argv.Length != 3) { throw new TclNumArgsException(interp, 2, argv, "name"); } interp.SetResult(getExtension(argv[2].ToString())); return(TCL.CompletionCode.RETURN); case OPT_ISDIRECTORY: if (argv.Length != 3) { throw new TclNumArgsException(interp, 2, argv, "name"); } fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString()); interp.SetResult(Directory.Exists(fileObj.FullName)); return(TCL.CompletionCode.RETURN); case OPT_ISFILE: if (argv.Length != 3) { throw new TclNumArgsException(interp, 2, argv, "name"); } fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString()); interp.SetResult(File.Exists(fileObj.FullName)); return(TCL.CompletionCode.RETURN); case OPT_JOIN: if (argv.Length < 3) { throw new TclNumArgsException(interp, 2, argv, "name ?name ...?"); } interp.SetResult(FileUtil.joinPath(interp, argv, 2, argv.Length)); return(TCL.CompletionCode.RETURN); case OPT_LINK: throw new TclException(interp, "sorry, \"file link\" is not implemented yet"); case OPT_LSTAT: if (argv.Length != 4) { throw new TclNumArgsException(interp, 2, argv, "name varName"); } // FIXME: Not yet implemented. // Java does not support link access. throw new TclException(interp, "file command with opt " + argv[1].ToString() + " is not yet implemented"); case OPT_MTIME: if (argv.Length != 3) { throw new TclNumArgsException(interp, 2, argv, "name"); } fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString()); interp.SetResult(getMtime(interp, argv[2].ToString(), fileObj)); return(TCL.CompletionCode.RETURN); case OPT_MKDIR: fileMakeDirs(interp, argv); return(TCL.CompletionCode.RETURN); case OPT_NATIVENAME: if (argv.Length != 3) { throw new TclNumArgsException(interp, 2, argv, "name"); } interp.SetResult(FileUtil.translateFileName(interp, argv[2].ToString())); return(TCL.CompletionCode.RETURN); case OPT_NORMALIZE: throw new TclException(interp, "sorry, \"file normalize\" is not implemented yet"); case OPT_OWNED: if (argv.Length != 3) { throw new TclNumArgsException(interp, 2, argv, "name"); } fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString()); interp.SetResult(isOwner(interp, fileObj)); return(TCL.CompletionCode.RETURN); case OPT_PATHTYPE: if (argv.Length != 3) { throw new TclNumArgsException(interp, 2, argv, "name"); } switch (FileUtil.getPathType(argv[2].ToString())) { case FileUtil.PATH_RELATIVE: interp.SetResult("relative"); return(TCL.CompletionCode.RETURN); case FileUtil.PATH_VOLUME_RELATIVE: interp.SetResult("volumerelative"); return(TCL.CompletionCode.RETURN); case FileUtil.PATH_ABSOLUTE: interp.SetResult("absolute"); break; } return(TCL.CompletionCode.RETURN); case OPT_READABLE: if (argv.Length != 3) { throw new TclNumArgsException(interp, 2, argv, "name"); } fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString()); // interp.setResult(fileObj.canRead()); // HACK interp.SetResult(true); return(TCL.CompletionCode.RETURN); case OPT_READLINK: if (argv.Length != 3) { throw new TclNumArgsException(interp, 2, argv, "name"); } // FIXME: Not yet implemented. // Java does not support link access. throw new TclException(interp, "file command with opt " + argv[1].ToString() + " is not yet implemented"); case OPT_RENAME: fileCopyRename(interp, argv, false); return(TCL.CompletionCode.RETURN); case OPT_ROOTNAME: if (argv.Length != 3) { throw new TclNumArgsException(interp, 2, argv, "name"); } string fileName2 = argv[2].ToString(); string extension = getExtension(fileName2); int diffLength = fileName2.Length - extension.Length; interp.SetResult(fileName2.Substring(0, (diffLength) - (0))); return(TCL.CompletionCode.RETURN); case OPT_SEPARATOR: throw new TclException(interp, "sorry, \"file separator\" is not implemented yet"); case OPT_SIZE: if (argv.Length != 3) { throw new TclNumArgsException(interp, 2, argv, "name"); } fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString()); bool tmpBool3; if (File.Exists(fileObj.FullName)) { tmpBool3 = true; } else { tmpBool3 = Directory.Exists(fileObj.FullName); } if (!tmpBool3) { throw new TclPosixException(interp, TclPosixException.ENOENT, true, "could not read \"" + argv[2].ToString() + "\""); } interp.SetResult((int)SupportClass.FileLength(fileObj)); return(TCL.CompletionCode.RETURN); case OPT_SPLIT: if (argv.Length != 3) { throw new TclNumArgsException(interp, 2, argv, "name"); } interp.SetResult(FileUtil.splitPath(interp, argv[2].ToString())); return(TCL.CompletionCode.RETURN); case OPT_STAT: if (argv.Length != 4) { throw new TclNumArgsException(interp, 2, argv, "name varName"); } getAndStoreStatData(interp, argv[2].ToString(), argv[3].ToString()); return(TCL.CompletionCode.RETURN); case OPT_SYSTEM: throw new TclException(interp, "sorry, \"file system\" is not implemented yet"); case OPT_TAIL: if (argv.Length != 3) { throw new TclNumArgsException(interp, 2, argv, "name"); } interp.SetResult(getTail(interp, argv[2].ToString())); return(TCL.CompletionCode.RETURN); case OPT_TYPE: if (argv.Length != 3) { throw new TclNumArgsException(interp, 2, argv, "name"); } fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString()); interp.SetResult(getType(interp, argv[2].ToString(), fileObj)); return(TCL.CompletionCode.RETURN); case OPT_VOLUMES: if (argv.Length != 2) { throw new TclNumArgsException(interp, 2, argv, null); } // use Java 1.2's File.listRoots() method if available if (listRootsMethod == null) { throw new TclException(interp, "\"file volumes\" is not supported"); } try { FileInfo[] roots = (FileInfo[])listRootsMethod.Invoke(null, (System.Object[]) new System.Object[0]); if (roots != null) { TclObject list = TclList.NewInstance(); for (int i = 0; i < roots.Length; i++) { string root = roots[i].FullName; TclList.Append(interp, list, TclString.NewInstance(root)); } interp.SetResult(list); } } catch (System.UnauthorizedAccessException ex) { throw new TclRuntimeError("IllegalAccessException in volumes cmd"); } catch (System.ArgumentException ex) { throw new TclRuntimeError("IllegalArgumentException in volumes cmd"); } catch (System.Reflection.TargetInvocationException ex) { System.Exception t = ex.GetBaseException(); if (t is System.ApplicationException) { throw (System.ApplicationException)t; } else { throw new TclRuntimeError("unexected exception in volumes cmd"); } } return(TCL.CompletionCode.RETURN); case OPT_WRITABLE: if (argv.Length != 3) { throw new TclNumArgsException(interp, 2, argv, "name"); } fileObj = FileUtil.getNewFileObj(interp, argv[2].ToString()); interp.SetResult(SupportClass.FileCanWrite(fileObj)); return(TCL.CompletionCode.RETURN); default: throw new TclRuntimeError("file command with opt " + argv[1].ToString() + " is not implemented"); } }
/// <summary> /// This procedure is invoked to process the "array" Tcl command. See the user documentation for details on what it does. /// </summary> public TCL.CompletionCode CmdProc(Interp interp, TclObject[] objv) { Var var = null, array = null; bool notArray = false; string varName, msg; int index; if (objv.Length < 3) { throw new TclNumArgsException(interp, 1, objv, "option arrayName ?arg ...?"); } index = TclIndex.Get(interp, objv[1], _validCmds, "option", 0); // Locate the array variable (and it better be an array). varName = objv[2].ToString(); Var[] retArray = Var.LookupVar(interp, varName, null, 0, null, false, false); // Assign the values returned in the array if (retArray != null) { var = retArray[0]; array = retArray[1]; } if (var == null || !var.IsVarArray() || var.IsVarUndefined()) { notArray = true; } // Special array trace used to keep the env array in sync for array names, array get, etc. if (var != null && var.Traces != null) { msg = Var.CallTraces(interp, array, var, varName, null, (TCL.VarFlag.LEAVE_ERR_MSG | TCL.VarFlag.NAMESPACE_ONLY | TCL.VarFlag.GLOBAL_ONLY | TCL.VarFlag.TRACE_ARRAY)); if ((object)msg != null) { throw new TclVarException(interp, varName, null, "trace array", msg); } } switch (index) { case OPT_ANYMORE: { if (objv.Length != 4) { throw new TclNumArgsException(interp, 2, objv, "arrayName searchId"); } if (notArray) { ErrorNotArray(interp, objv[2].ToString()); } if (var.SidVec == null) { ErrorIllegalSearchId(interp, objv[2].ToString(), objv[3].ToString()); } SearchId e = var.getSearch(objv[3].ToString()); if (e == null) { ErrorIllegalSearchId(interp, objv[2].ToString(), objv[3].ToString()); } if (e.HasMore) { interp.SetResult("1"); } else { interp.SetResult("0"); } break; } case OPT_DONESEARCH: { if (objv.Length != 4) { throw new TclNumArgsException(interp, 2, objv, "arrayName searchId"); } if (notArray) { ErrorNotArray(interp, objv[2].ToString()); } bool rmOK = true; if (var.SidVec != null) { rmOK = var.RemoveSearch(objv[3].ToString()); } if (var.SidVec == null || !rmOK) { ErrorIllegalSearchId(interp, objv[2].ToString(), objv[3].ToString()); } break; } case OPT_EXISTS: { if (objv.Length != 3) { throw new TclNumArgsException(interp, 2, objv, "arrayName"); } interp.SetResult(!notArray); break; } case OPT_GET: { // Due to the differences in the hashtable implementation from the Tcl core and Java, the output will be rearranged. // This is not a negative side effect, however, test results will differ. if (objv.Length != 3 && objv.Length != 4) { throw new TclNumArgsException(interp, 2, objv, "arrayName ?pattern?"); } if (notArray) { return(TCL.CompletionCode.RETURN); } string pattern = null; if (objv.Length == 4) { pattern = objv[3].ToString(); } Hashtable table = (Hashtable)var._value; TclObject tobj = TclList.NewInstance(); string arrayName = objv[2].ToString(); string key, strValue; Var var2; // Go through each key in the hash table. If there is a pattern, test for a match. Each valid key and its value // is written into sbuf, which is returned. // FIXME : do we need to port over the 8.1 code for this loop? for (IDictionaryEnumerator e = table.GetEnumerator(); e.MoveNext();) { key = ((string)e.Key); var2 = (Var)e.Value; if (var2.IsVarUndefined()) { continue; } if ((object)pattern != null && !Util.StringMatch(key, pattern)) { continue; } strValue = interp.GetVar(arrayName, key, 0).ToString(); TclList.Append(interp, tobj, TclString.NewInstance(key)); TclList.Append(interp, tobj, TclString.NewInstance(strValue)); } interp.SetResult(tobj); break; } case OPT_NAMES: { if ((objv.Length != 3) && (objv.Length != 4)) { throw new TclNumArgsException(interp, 2, objv, "arrayName ?pattern?"); } if (notArray) { return(TCL.CompletionCode.RETURN); } string pattern = null; if (objv.Length == 4) { pattern = objv[3].ToString(); } Hashtable table = (Hashtable)var._value; TclObject tobj = TclList.NewInstance(); string key; // Go through each key in the hash table. If there is a pattern, test for a match. Each valid key and its value // is written into sbuf, which is returned. for (IDictionaryEnumerator e = table.GetEnumerator(); e.MoveNext();) { key = (string)e.Key; Var elem = (Var)e.Value; if (!elem.IsVarUndefined()) { if ((System.Object)pattern != null) { if (!Util.StringMatch(key, pattern)) { continue; } } TclList.Append(interp, tobj, TclString.NewInstance(key)); } } interp.SetResult(tobj); break; } case OPT_NEXTELEMENT: { if (objv.Length != 4) { throw new TclNumArgsException(interp, 2, objv, "arrayName searchId"); } if (notArray) { ErrorNotArray(interp, objv[2].ToString()); } if (var.SidVec == null) { ErrorIllegalSearchId(interp, objv[2].ToString(), objv[3].ToString()); } SearchId e = var.getSearch(objv[3].ToString()); if (e == null) { ErrorIllegalSearchId(interp, objv[2].ToString(), objv[3].ToString()); } if (e.HasMore) { Hashtable table = (Hashtable)var._value; DictionaryEntry entry = e.nextEntry(); string key = (string)entry.Key; Var elem = (Var)entry.Value; if ((elem.Flags & VarFlags.UNDEFINED) == 0) { interp.SetResult(key); } else { interp.SetResult(string.Empty); } } break; } case OPT_SET: { if (objv.Length != 4) { throw new TclNumArgsException(interp, 2, objv, "arrayName list"); } int size = TclList.getLength(interp, objv[3]); if (size % 2 != 0) { throw new TclException(interp, "list must have an even number of elements"); } string name1 = objv[2].ToString(); string name2, strValue; // Set each of the array variable names in the interp for (int i = 0; i < size; i++) { name2 = TclList.index(interp, objv[3], i++).ToString(); strValue = TclList.index(interp, objv[3], i).ToString(); interp.SetVar(name1, name2, TclString.NewInstance(strValue), 0); } break; } case OPT_SIZE: { if (objv.Length != 3) { throw new TclNumArgsException(interp, 2, objv, "arrayName"); } if (notArray) { interp.SetResult(0); } else { Hashtable table = (Hashtable)var._value; int size = 0; for (IDictionaryEnumerator e = table.GetEnumerator(); e.MoveNext();) { Var elem = (Var)e.Value; if ((elem.Flags & VarFlags.UNDEFINED) == 0) { size++; } } interp.SetResult(size); } break; } case OPT_STARTSEARCH: { if (objv.Length != 3) { throw new TclNumArgsException(interp, 2, objv, "arrayName"); } if (notArray) { ErrorNotArray(interp, objv[2].ToString()); } if (var.SidVec == null) { var.SidVec = new ArrayList(10); } // Create a SearchId Object: // To create a new SearchId object, a unique string identifier needs to be composed and we need to // create an Enumeration of the array keys. The unique string identifier is created from three strings: // "s-" is the default prefix // "i" is a unique number that is 1+ the greatest SearchId index currently on the ArrayVar. // "name" is the name of the array // Once the SearchId string is created we construct a new SearchId object using the string and the // Enumeration. From now on the string is used to uniquely identify the SearchId object. int i = var.NextIndex; string s = "s-" + i + "-" + objv[2].ToString(); IDictionaryEnumerator e = ((Hashtable)var._value).GetEnumerator(); var.SidVec.Add(new SearchId(e, s, i)); interp.SetResult(s); break; } case OPT_UNSET: { string pattern; string name; if (objv.Length != 3 && objv.Length != 4) { throw new TclNumArgsException(interp, 2, objv, "arrayName ?pattern?"); } if (notArray) //Ignot this error -- errorNotArray(interp, objv[2].ToString()); { break; } if (objv.Length == 3) // When no pattern is given, just unset the whole array { interp.UnsetVar(objv[2], 0); } else { pattern = objv[3].ToString(); Hashtable table = (Hashtable)(((Hashtable)var._value).Clone()); for (IDictionaryEnumerator e = table.GetEnumerator(); e.MoveNext();) { name = (string)e.Key; Var elem = (Var)e.Value; if (var.IsVarUndefined()) { continue; } if (Util.StringMatch(name, pattern)) { interp.UnsetVar(varName, name, 0); } } } break; } } return(TCL.CompletionCode.RETURN); }
private static void fileCopyRename(Interp interp, TclObject[] argv, bool copyFlag) { int firstSource = 2; bool force = false; for (bool last = false; (firstSource < argv.Length) && (!last); firstSource++) { if (!argv[firstSource].ToString().StartsWith("-")) { break; } int opt = TclIndex.Get(interp, argv[firstSource], validOptions, "option", 1); switch (opt) { case OPT_FORCE: force = true; break; case OPT_LAST: last = true; break; default: throw new TclRuntimeError("FileCmd.cmdProc: bad option " + opt + " index to validOptions"); } } if (firstSource >= (argv.Length - 1)) { throw new TclNumArgsException(interp, firstSource, argv, "?options? source ?source ...? target"); } // WARNING: ignoring links because Java does not support them. int target = argv.Length - 1; string targetName = argv[target].ToString(); FileInfo targetObj = FileUtil.getNewFileObj(interp, targetName); if (Directory.Exists(targetObj.FullName)) { // If the target is a directory, move each source file into target // directory. Extract the tailname from each source, and append it to // the end of the target path. for (int source = firstSource; source < target; source++) { string sourceName = argv[source].ToString(); if (targetName.Length == 0) { copyRenameOneFile(interp, sourceName, targetName, copyFlag, force); } else { string tailName = getTail(interp, sourceName); TclObject[] joinArrayObj = new TclObject[2]; joinArrayObj[0] = TclString.NewInstance(targetName); joinArrayObj[1] = TclString.NewInstance(tailName); string fullTargetName = FileUtil.joinPath(interp, joinArrayObj, 0, 2); copyRenameOneFile(interp, sourceName, fullTargetName, copyFlag, force); } } } else { // If there is more than 1 source file and the target is not a // directory, then throw an exception. if (firstSource + 1 != target) { string action; if (copyFlag) { action = "copying"; } else { action = "renaming"; } throw new TclPosixException(interp, TclPosixException.ENOTDIR, "error " + action + ": target \"" + argv[target].ToString() + "\" is not a directory"); } string sourceName = argv[firstSource].ToString(); copyRenameOneFile(interp, sourceName, targetName, copyFlag, force); } }
public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { bool all = false; bool nocase = 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_ALL: { all = true; break; } case OPT_NOCASE: { nocase = true; break; } case OPT_LAST: { goto opts_brk; } } } opts_brk: ; TclObject exp = argv[i++]; string inString = argv[i++].ToString(); string subSpec = argv[i++].ToString(); string varName = null; if (i != argv.Length) { varName = argv[i++].ToString(); } if (i != argv.Length) { throw new System.IndexOutOfRangeException(); } Regexp r = TclRegexp.compile(interp, exp, nocase); int count = 0; string result; if (all == false) { result = r.sub(inString, subSpec); if ((System.Object)result == null) { result = inString; } else { count++; } } else { StringBuilder sb = new StringBuilder(); Regsub s = new Regsub(r, inString); while (s.nextMatch()) { count++; sb.Append(s.skipped()); Regexp.applySubspec(s, subSpec, sb); } sb.Append(s.rest()); result = sb.ToString(); } TclObject obj = TclString.NewInstance(result); if (varName == null) { interp.SetResult(result); } else { try { interp.SetVar(varName, obj, 0); } catch (TclException e) { throw new TclException(interp, "couldn't set variable \"" + varName + "\""); } interp.SetResult(count); } } catch (System.IndexOutOfRangeException e) { throw new TclNumArgsException(interp, 1, argv, "?switches? exp string subSpec ?varName?"); } return(TCL.CompletionCode.RETURN); }