/* *---------------------------------------------------------------------- * * InfoLocalsCmd -- * * Called to implement the "info locals" command to return a list of * local variables that match an optional pattern. Handles the * following syntax: * * info locals ?pattern? * * Results: * Returns if successful, raises TclException otherwise. * * Side effects: * Returns a result in the interpreter's result object. * *---------------------------------------------------------------------- */ private static void InfoLocalsCmd(Interp interp, TclObject[] objv) { string pattern; TclObject list; if (objv.Length == 2) { pattern = null; } else if (objv.Length == 3) { pattern = objv[2].ToString(); } else { throw new TclNumArgsException(interp, 2, objv, "?pattern?"); } if (interp.VarFrame == null || !interp.VarFrame.IsProcCallFrame) { return; } // Return a list containing names of first the compiled locals (i.e. the // ones stored in the call frame), then the variables in the local hash // table (if one exists). list = TclList.NewInstance(); AppendLocals(interp, list, pattern, false); interp.SetResult(list); return; }
/* *---------------------------------------------------------------------- * * InfoArgsCmd -- * * Called to implement the "info args" command that returns the * argument list for a procedure. Handles the following syntax: * * info args procName * * Results: * Returns if successful, raises TclException otherwise. * * Side effects: * Returns a result in the interpreter's result object. * *---------------------------------------------------------------------- */ private static void InfoArgsCmd(Interp interp, TclObject[] objv) { string name; Procedure proc; TclObject listObj; if (objv.Length != 3) { throw new TclNumArgsException(interp, 2, objv, "procname"); } name = objv[2].ToString(); proc = Procedure.findProc(interp, name); if (proc == null) { throw new TclException(interp, "\"" + name + "\" isn't a procedure"); } // Build a return list containing the arguments. listObj = TclList.NewInstance(); for (int i = 0; i < proc.ArgList.Length; i++) { TclObject s = TclString.NewInstance(proc.ArgList[i][0]); TclList.Append(interp, listObj, s); } interp.SetResult(listObj); return; }
internal static void eval(Interp interp, Interp slaveInterp, int objIx, TclObject[] objv) { TCL.CompletionCode result; slaveInterp.preserve(); slaveInterp.allowExceptions(); try { if (objIx + 1 == objv.Length) { slaveInterp.Eval(objv[objIx], 0); } else { TclObject obj = TclList.NewInstance(); for (int ix = objIx; ix < objv.Length; ix++) { TclList.Append(interp, obj, objv[ix]); } obj.Preserve(); slaveInterp.Eval(obj, 0); obj.Release(); } result = slaveInterp._returnCode; } catch (TclException e) { result = e.GetCompletionCode(); } slaveInterp.release(); interp.transferResult(slaveInterp, result); }
public TclPosixException(Interp interp, int errno, bool appendPosixMsg, string errorMsg) : base(TCL.CompletionCode.ERROR) { string msg = getPosixMsg(errno); TclObject threeEltListObj = TclList.NewInstance(); TclList.Append(interp, threeEltListObj, TclString.NewInstance("POSIX")); TclList.Append(interp, threeEltListObj, TclString.NewInstance(getPosixId(errno))); TclList.Append(interp, threeEltListObj, TclString.NewInstance(msg)); interp.SetErrorCode(threeEltListObj); if (interp != null) { if (appendPosixMsg) { interp.SetResult(errorMsg + ": " + msg); } else { interp.SetResult(errorMsg); } } }
internal static void create(Interp interp, Interp slaveInterp, Interp masterInterp, TclObject name, TclObject targetName, int objIx, TclObject[] objv) { string inString = name.ToString(); InterpAliasCmd alias = new InterpAliasCmd(); alias.name = name; name.Preserve(); alias.slaveInterp = slaveInterp; alias.targetInterp = masterInterp; alias.prefix = TclList.NewInstance(); alias.prefix.Preserve(); TclList.Append(interp, alias.prefix, targetName); TclList.insert(interp, alias.prefix, 1, objv, objIx, objv.Length - 1); slaveInterp.CreateCommand(inString, alias); alias.slaveCmd = NamespaceCmd.findCommand(slaveInterp, inString, null, 0); try { interp.preventAliasLoop(slaveInterp, alias.slaveCmd); } catch (TclException e) { // Found an alias loop! The last call to Tcl_CreateObjCommand made // the alias point to itself. Delete the command and its alias // record. Be careful to wipe out its client data first, so the // command doesn't try to delete itself. slaveInterp.DeleteCommandFromToken(alias.slaveCmd); throw; } // Make an entry in the alias table. If it already exists delete // the alias command. Then retry. if (slaveInterp._aliasTable.ContainsKey(inString)) { InterpAliasCmd oldAlias = (InterpAliasCmd)slaveInterp._aliasTable[inString]; slaveInterp.DeleteCommandFromToken(oldAlias.slaveCmd); } alias.aliasEntry = inString; SupportClass.PutElement(slaveInterp._aliasTable, inString, alias); // Create the new command. We must do it after deleting any old command, // because the alias may be pointing at a renamed alias, as in: // // interp alias {} foo {} bar # Create an alias "foo" // rename foo zop # Now rename the alias // interp alias {} foo {} zop # Now recreate "foo"... SupportClass.PutElement(masterInterp._targetTable, alias.slaveCmd, slaveInterp); interp.SetResult(name); }
public static TclObject Tcl_GetVar2Ex(Interp interp, string part1, string part2, VarFlag flags) { try { Var[] result = Var.LookupVar(interp, part1, part2, flags, "read", false, true); if (result == null) { // lookupVar() returns null only if VarFlag.LEAVE_ERR_MSG is // not part of the flags argument, return null in this case. return(null); } Var var = result[0]; Var array = result[1]; TclObject to = null; if (var.IsVarScalar() && !var.IsVarUndefined()) { to = (TclObject)var._value; //if ( to.typePtr != "String" ) //{ // double D = 0; // if ( !Double.TryParse( to.ToString(), out D ) ) { if ( String.IsNullOrEmpty( to.typePtr ) ) to.typePtr = "string"; } // else if ( to.typePtr == "ByteArray" ) // to.typePtr = "bytearray"; // else if ( to.ToString().Contains( "." ) ) // to.typePtr = "double"; // else // to.typePtr = "int"; //} return(to); } else if (var.isSQLITE3_Link()) { to = (TclObject)var.Ext_Get(); } else { to = TclList.NewInstance(); foreach (string key in ((Hashtable)array._value).Keys) { Var s = (Var)((Hashtable)array._value)[key]; if (s._value != null) { TclList.Append(null, to, TclString.NewInstance(s._value.ToString())); } } } return(to); } catch (Exception e) { return(null); }; }
/* *---------------------------------------------------------------------- * * 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 TclObject Tcl_NewListObj(int nArg, TclObject[] aArg) { TclObject to = TclList.NewInstance(); for (int i = 0; i < nArg; i++) { TclList.Append(null, to, aArg[i]); } return(to); }
/// <summary> /// Chain this frame into the call frame stack and binds the parameters values to the formal parameters of the procedure. /// </summary> /// <param name="proc"> /// the procedure. /// </param> /// <param name="proc"> /// argv the parameter values. /// </param> /// <exception cref=""> /// TclException if wrong number of arguments. /// </exception> internal void Chain(Procedure proc, TclObject[] objv) { // FIXME: double check this ns thing in case where proc is renamed to different ns. NS = proc.NS; Objv = objv; // FIXME : quick level hack : fix later Level = (Interp.VarFrame == null ? 1 : Interp.VarFrame.Level + 1); Caller = Interp.Frame; CallerVar = Interp.VarFrame; Interp.Frame = this; Interp.VarFrame = this; // parameter bindings int numArgs = proc.ArgList.Length; if (!proc.isVarArgs && objv.Length - 1 > numArgs) { WrongNumProcArgs(objv[0], proc); } for (int i = 0, j = 1; i < numArgs; i++, j++) { // Handle the special case of the last formal being "args". When it occurs, assign it a list consisting of // all the remaining actual arguments. TclObject varName = proc.ArgList[i][0]; TclObject value = null; if (i == (numArgs - 1) && proc.isVarArgs) { value = TclList.NewInstance(); value.Preserve(); for (int k = j; k < objv.Length; k++) { TclList.Append(Interp, value, objv[k]); } Interp.SetVar(varName, value, 0); value.Release(); } else { if (j < objv.Length) { value = objv[j]; } else if (proc.ArgList[i][1] != null) { value = proc.ArgList[i][1]; } else { WrongNumProcArgs(objv[0], proc); } Interp.SetVar(varName, value, 0); } } }
internal static void list(Interp interp, Interp slaveInterp) { TclObject result = TclList.NewInstance(); interp.SetResult(result); IEnumerator aliases = slaveInterp._aliasTable.Values.GetEnumerator(); while (aliases.MoveNext()) { InterpAliasCmd alias = (InterpAliasCmd)aliases.Current; TclList.Append(interp, result, alias.name); } }
public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { targetInterp.preserve(); targetInterp._nestLevel++; targetInterp.ResetResult(); targetInterp.allowExceptions(); // Append the arguments to the command prefix and invoke the command // in the target interp's global namespace. TclObject[] prefv = TclList.getElements(interp, prefix); TclObject cmd = TclList.NewInstance(); cmd.Preserve(); TclList.replace(interp, cmd, 0, 0, prefv, 0, prefv.Length - 1); TclList.replace(interp, cmd, prefv.Length, 0, argv, 1, argv.Length - 1); TclObject[] cmdv = TclList.getElements(interp, cmd); TCL.CompletionCode result = targetInterp.invoke(cmdv, Interp.INVOKE_NO_TRACEBACK); cmd.Release(); targetInterp._nestLevel--; // Check if we are at the bottom of the stack for the target interpreter. // If so, check for special return codes. if (targetInterp._nestLevel == 0) { if (result == TCL.CompletionCode.RETURN) { result = targetInterp.updateReturnInfo(); } if (result != TCL.CompletionCode.OK && result != TCL.CompletionCode.ERROR) { try { targetInterp.processUnexpectedResult(result); } catch (TclException e) { result = e.GetCompletionCode(); } } } targetInterp.release(); interp.transferResult(targetInterp, result); return(TCL.CompletionCode.RETURN); }
/* *---------------------------------------------------------------------- * * InfoProcsCmd -- * * Called to implement the "info procs" command that returns the * procedures in the current namespace that match an optional pattern. * Handles the following syntax: * * info procs ?pattern? * * Results: * Returns if successful, raises TclException otherwise. * * Side effects: * Returns a result in the interpreter's result object. * *---------------------------------------------------------------------- */ private static void InfoProcsCmd(Interp interp, TclObject[] objv) { string cmdName, pattern; NamespaceCmd.Namespace currNs = NamespaceCmd.getCurrentNamespace(interp); IDictionaryEnumerator search; WrappedCommand cmd, realCmd; TclObject list; if (objv.Length == 2) { pattern = null; } else if (objv.Length == 3) { pattern = objv[2].ToString(); } else { throw new TclNumArgsException(interp, 2, objv, "?pattern?"); } // Scan through the current namespace's command table and return a list // of all procs that match the pattern. list = TclList.NewInstance(); for (search = currNs.cmdTable.GetEnumerator(); search.MoveNext();) { cmdName = ((string)search.Key); cmd = (WrappedCommand)search.Value; // If the command isn't itself a proc, it still might be an // imported command that points to a "real" proc in a different // namespace. realCmd = NamespaceCmd.getOriginalCommand(cmd); if (Procedure.isProc(cmd) || ((realCmd != null) && Procedure.isProc(realCmd))) { if (((System.Object)pattern == null) || Util.StringMatch(cmdName, pattern)) { TclList.Append(interp, list, TclString.NewInstance(cmdName)); } } } interp.SetResult(list); return; }
/* *---------------------------------------------------------------------- * * InfoGlobalsCmd -- * * Called to implement the "info globals" command that returns the list * of global variables matching an optional pattern. Handles the * following syntax: * * info globals ?pattern?* * * Results: * Returns if successful, raises TclException otherwise. * * Side effects: * Returns a result in the interpreter's result object. * *---------------------------------------------------------------------- */ private static void InfoGlobalsCmd(Interp interp, TclObject[] objv) { string varName, pattern; NamespaceCmd.Namespace globalNs = NamespaceCmd.getGlobalNamespace(interp); IDictionaryEnumerator search; Var var; TclObject list; if (objv.Length == 2) { pattern = null; } else if (objv.Length == 3) { pattern = objv[2].ToString(); } else { throw new TclNumArgsException(interp, 2, objv, "?pattern?"); } // Scan through the global :: namespace's variable table and create a // list of all global variables that match the pattern. list = TclList.NewInstance(); for (search = globalNs.varTable.GetEnumerator(); search.MoveNext();) { varName = ((string)search.Key); var = (Var)search.Value; if (var.IsVarUndefined()) { continue; } if (((System.Object)pattern == null) || Util.StringMatch(varName, pattern)) { TclList.Append(interp, list, TclString.NewInstance(varName)); } } interp.SetResult(list); return; }
/// <summary> See Tcl user documentation for details.</summary> public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { TclObject list = TclList.NewInstance(); list.Preserve(); try { for (int i = 1; i < argv.Length; i++) { TclList.Append(interp, list, argv[i]); } interp.SetResult(list); } finally { list.Release(); } return(TCL.CompletionCode.RETURN); }
internal static void hidden(Interp interp, Interp slaveInterp) { if (slaveInterp._hiddenCmdTable == null) { return; } TclObject result = TclList.NewInstance(); interp.SetResult(result); IEnumerator hiddenCmds = slaveInterp._hiddenCmdTable.Keys.GetEnumerator(); while (hiddenCmds.MoveNext()) { string cmdName = (string)hiddenCmds.Current; TclList.Append(interp, result, TclString.NewInstance(cmdName)); } }
/* *---------------------------------------------------------------------- * * InfoNameOfExecutableCmd -- * * Called to implement the "info nameofexecutable" command that returns * the name of the binary file running this application. Handles the * following syntax: * * info nameofexecutable * * Results: * Returns if successful, raises TclException otherwise. * * Side effects: * Returns a result in the interpreter's result object. * *---------------------------------------------------------------------- */ private static void InfoNameOfExecutableCmd(Interp interp, TclObject[] objv) { if (objv.Length != 2) { throw new TclNumArgsException(interp, 2, objv, null); } // We depend on a user defined property named "JAVA" since // the JDK provides no means to learn the name of the executable // that launched the application. string nameOfExecutable = "nacl"; if ((System.Object)nameOfExecutable != null) { TclObject result = TclList.NewInstance(); TclList.Append(interp, result, TclString.NewInstance(nameOfExecutable)); TclList.Append(interp, result, TclString.NewInstance("tcl.lang.Shell")); interp.SetResult(result); } return; }
/// <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); }
/// <summary> This procedure is invoked to process the "split" Tcl /// command. See Tcl user documentation for details. /// /// </summary> /// <param name="interp">the current interpreter. /// </param> /// <param name="argv">command arguments. /// </param> /// <exception cref=""> TclException If incorrect number of arguments. /// </exception> public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { char[] splitChars = null; string inString; if (argv.Length == 2) { splitChars = defSplitChars; } else if (argv.Length == 3) { splitChars = argv[2].ToString().ToCharArray(); } else { throw new TclNumArgsException(interp, 1, argv, "string ?splitChars?"); } inString = argv[1].ToString(); int len = inString.Length; int num = splitChars.Length; /* * Handle the special case of splitting on every character. */ if (num == 0) { TclObject list = TclList.NewInstance(); list.Preserve(); try { for (int i = 0; i < len; i++) { TclList.Append(interp, list, TclString.NewInstance(inString[i])); } interp.SetResult(list); } finally { list.Release(); } return(TCL.CompletionCode.RETURN); } /* * Normal case: split on any of a given set of characters. * Discard instances of the split characters. */ TclObject list2 = TclList.NewInstance(); int elemStart = 0; list2.Preserve(); try { int i, j; for (i = 0; i < len; i++) { char c = inString[i]; for (j = 0; j < num; j++) { if (c == splitChars[j]) { TclList.Append(interp, list2, TclString.NewInstance(inString.Substring(elemStart, (i) - (elemStart)))); elemStart = i + 1; break; } } } if (i != 0) { TclList.Append(interp, list2, TclString.NewInstance(inString.Substring(elemStart))); } interp.SetResult(list2); } finally { list2.Release(); } 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 != 4) { throw new TclNumArgsException(interp, 1, argv, "list first last"); } int size = TclList.getLength(interp, argv[1]); int first; int last; first = Util.getIntForIndex(interp, argv[2], size - 1); last = Util.getIntForIndex(interp, argv[3], size - 1); if (last < 0) { interp.ResetResult(); return(TCL.CompletionCode.RETURN); } if (first >= size) { interp.ResetResult(); return(TCL.CompletionCode.RETURN); } if (first <= 0 && last >= size) { interp.SetResult(argv[1]); return(TCL.CompletionCode.RETURN); } if (first < 0) { first = 0; } if (first >= size) { first = size - 1; } if (last < 0) { last = 0; } if (last >= size) { last = size - 1; } if (first > last) { interp.ResetResult(); return(TCL.CompletionCode.RETURN); } TclObject list = TclList.NewInstance(); list.Preserve(); try { for (int i = first; i <= last; i++) { TclList.Append(interp, list, TclList.index(interp, argv[1], i)); } interp.SetResult(list); } finally { list.Release(); } 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> /// Tcl_LappendObjCmd -> LappendCmd.cmdProc /// /// This procedure is invoked to process the "lappend" Tcl command. /// See the user documentation for details on what it does. /// </summary> public TCL.CompletionCode CmdProc(Interp interp, TclObject[] objv) { TclObject varValue, newValue = null; int i;//int numElems, i, j; bool createdNewObj, createVar; if (objv.Length < 2) { throw new TclNumArgsException(interp, 1, objv, "varName ?value value ...?"); } if (objv.Length == 2) { try { newValue = interp.GetVar(objv[1], 0); } catch (TclException e) { // The variable doesn't exist yet. Just create it with an empty // initial value. varValue = TclList.NewInstance(); try { newValue = interp.SetVar(objv[1], varValue, 0); } finally { if (newValue == null) { varValue.Release(); // free unneeded object } } interp.ResetResult(); return(TCL.CompletionCode.RETURN); } } else { // We have arguments to append. We used to call Tcl_SetVar2 to // append each argument one at a time to ensure that traces were run // for each append step. We now append the arguments all at once // because it's faster. Note that a read trace and a write trace for // the variable will now each only be called once. Also, if the // variable's old value is unshared we modify it directly, otherwise // we create a new copy to modify: this is "copy on write". createdNewObj = false; createVar = true; try { varValue = interp.GetVar(objv[1], 0); } catch (TclException e) { // We couldn't read the old value: either the var doesn't yet // exist or it's an array element. If it's new, we will try to // create it with Tcl_ObjSetVar2 below. // FIXME : not sure we even need this parse for anything! // If we do not need to parse could we at least speed it up a bit string varName; int nameBytes; varName = objv[1].ToString(); nameBytes = varName.Length; // Number of Unicode chars in string for (i = 0; i < nameBytes; i++) { if (varName[i] == '(') { i = nameBytes - 1; if (varName[i] == ')') { // last char is ')' => array ref createVar = false; } break; } } varValue = TclList.NewInstance(); createdNewObj = true; } // We only take this branch when the catch branch was not run if (createdNewObj == false && varValue.Shared) { varValue = varValue.duplicate(); createdNewObj = true; } // Insert the new elements at the end of the list. for (i = 2; i < objv.Length; i++) { TclList.Append(interp, varValue, objv[i]); } // No need to call varValue.invalidateStringRep() since it // is called during the TclList.append operation. // Now store the list object back into the variable. If there is an // error setting the new value, decrement its ref count if it // was new and we didn't create the variable. try { newValue = interp.SetVar(objv[1].ToString(), varValue, 0); } catch (TclException e) { if (createdNewObj && !createVar) { varValue.Release(); // free unneeded obj } throw; } } // Set the interpreter's object result to refer to the variable's value // object. interp.SetResult(newValue); return(TCL.CompletionCode.RETURN); }
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 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); }
internal static TclObject splitPath(Interp interp, string path) { TclObject resultListObj = TclList.NewInstance(); TclObject componentObj; string component = ""; string tmpPath; bool foundComponent = false; bool convertDotToColon = false; bool isColonSeparator = false; bool appendColon = false; bool prependColon = false; string thisDir = "./"; // If the path is the empty string, returnan empty result list. if (path.Length == 0) { return(resultListObj); } // Handling the 1st component is file system dependent. switch (JACL.PLATFORM) { case JACL.PLATFORM_WINDOWS: tmpPath = path.Replace('\\', '/'); StringBuilder absBuf = new StringBuilder(0); int absIndex = getWinAbsPath(tmpPath, absBuf); if (absIndex > 0) { componentObj = TclString.NewInstance(absBuf.ToString()); TclList.Append(interp, resultListObj, componentObj); tmpPath = tmpPath.Substring(absIndex); foundComponent = true; } break; case JACL.PLATFORM_MAC: tmpPath = ""; thisDir = ":"; switch (path.IndexOf((System.Char) ':')) { case -1: if (path[0] != '/') { tmpPath = path; convertDotToColon = true; if (path[0] == '~') { // If '~' is the first char, then append a colon to end // of the 1st component. appendColon = true; } break; } int degenIndex = getDegenerateUnixPath(path); if (degenIndex < path.Length) { // First component of absolute unix path is followed by a ':', // instead of being preceded by a degenerate unix-style // pattern. tmpPath = path.Substring(degenIndex); convertDotToColon = true; appendColon = true; break; } // Degenerate unix path can't be split. Return a list with one // element: ":" prepended to "path". componentObj = TclString.NewInstance(":" + path); TclList.Append(interp, resultListObj, componentObj); return(resultListObj); case 0: if (path.Length == 1) { // If path == ":", then return a list with ":" as its only // element. componentObj = TclString.NewInstance(":"); TclList.Append(interp, resultListObj, componentObj); return(resultListObj); } // For each component, if slashes exist in the remaining filename, // prepend a colon to the component. Since this path is relative, // pretend that we have already processed 1 components so a // tilde-prefixed 1st component will have ":" prepended to it. tmpPath = path.Substring(1); foundComponent = true; prependColon = true; isColonSeparator = true; break; default: tmpPath = path; appendColon = true; prependColon = true; isColonSeparator = true; break; } break; default: if (path[0] == '/') { componentObj = TclString.NewInstance("/"); TclList.Append(interp, resultListObj, componentObj); tmpPath = path.Substring(1); foundComponent = true; } else { tmpPath = path; } break; } // Iterate over all of the components of the path. int sIndex = 0; while (sIndex != -1) { if (isColonSeparator) { sIndex = tmpPath.IndexOf(":"); // process adjacent ':' if (sIndex == 0) { componentObj = TclString.NewInstance("::"); TclList.Append(interp, resultListObj, componentObj); foundComponent = true; tmpPath = tmpPath.Substring(sIndex + 1); continue; } } else { sIndex = tmpPath.IndexOf("/"); // Ignore a redundant '/' if (sIndex == 0) { tmpPath = tmpPath.Substring(sIndex + 1); continue; } } if (sIndex == -1) { // Processing the last component. If it is empty, exit loop. if (tmpPath.Length == 0) { break; } component = tmpPath; } else { component = tmpPath.Substring(0, (sIndex) - (0)); } if (convertDotToColon && (component.Equals(".") || component.Equals(".."))) { // If platform = MAC, convert .. to :: or . to : component = component.Replace('.', ':'); } if (foundComponent) { if (component[0] == '~') { // If a '~' preceeds a component (other than the 1st one), then // prepend "./" or ":" to the component. component = thisDir + component; } else if (prependColon) { // If the prependColon flag is set, either unset it or prepend // ":" to the component, depending on whether any '/'s remain // in tmpPath. if (tmpPath.IndexOf((System.Char) '/') == -1) { prependColon = false; } else { component = ":" + component; } } } else if (appendColon) { //If platform = MAC, append a ':' to the first component. component = component + ":"; } componentObj = TclString.NewInstance(component); TclList.Append(interp, resultListObj, componentObj); foundComponent = true; tmpPath = tmpPath.Substring(sIndex + 1); } return(resultListObj); }
/* *---------------------------------------------------------------------- * * InfoVarsCmd -- * * Called to implement the "info vars" command that returns the * list of variables in the interpreter that match an optional pattern. * The pattern, if any, consists of an optional sequence of namespace * names separated by "::" qualifiers, which is followed by a * glob-style pattern that restricts which variables are returned. * Handles the following syntax: * * info vars ?pattern? * * Results: * Returns if successful, raises TclException otherwise. * * Side effects: * Returns a result in the interpreter's result object. * *---------------------------------------------------------------------- */ private static void InfoVarsCmd(Interp interp, TclObject[] objv) { string varName, pattern, simplePattern; IDictionaryEnumerator search; Var var; NamespaceCmd.Namespace ns; NamespaceCmd.Namespace globalNs = NamespaceCmd.getGlobalNamespace(interp); NamespaceCmd.Namespace currNs = NamespaceCmd.getCurrentNamespace(interp); TclObject list, elemObj; bool specificNsInPattern = false; // Init. to avoid compiler warning. // Get the pattern and find the "effective namespace" in which to // list variables. We only use this effective namespace if there's // no active Tcl procedure frame. if (objv.Length == 2) { simplePattern = null; ns = currNs; specificNsInPattern = false; } else if (objv.Length == 3) { // From the pattern, get the effective namespace and the simple // pattern (no namespace qualifiers or ::'s) at the end. If an // error was found while parsing the pattern, return it. Otherwise, // if the namespace wasn't found, just leave ns = null: we will // return an empty list since no variables there can be found. pattern = objv[2].ToString(); // Java does not support passing an address so we pass // an array of size 1 and then assign arr[0] to the value NamespaceCmd.Namespace[] nsArr = new NamespaceCmd.Namespace[1]; NamespaceCmd.Namespace[] dummy1Arr = new NamespaceCmd.Namespace[1]; NamespaceCmd.Namespace[] dummy2Arr = new NamespaceCmd.Namespace[1]; string[] simplePatternArr = new string[1]; NamespaceCmd.getNamespaceForQualName(interp, pattern, null, 0, nsArr, dummy1Arr, dummy2Arr, simplePatternArr); // Get the values out of the arrays! ns = nsArr[0]; simplePattern = simplePatternArr[0]; if (ns != null) { // we successfully found the pattern's ns specificNsInPattern = (simplePattern.CompareTo(pattern) != 0); } } else { throw new TclNumArgsException(interp, 2, objv, "?pattern?"); } // If the namespace specified in the pattern wasn't found, just return. if (ns == null) { return; } list = TclList.NewInstance(); if ((interp.VarFrame == null) || !interp.VarFrame.IsProcCallFrame || specificNsInPattern) { // There is no frame pointer, the frame pointer was pushed only // to activate a namespace, or we are in a procedure call frame // but a specific namespace was specified. Create a list containing // only the variables in the effective namespace's variable table. search = ns.varTable.GetEnumerator(); while (search.MoveNext()) { varName = ((string)search.Key); var = (Var)search.Value; if (!var.IsVarUndefined() || ((var.Flags & VarFlags.NAMESPACE_VAR) != 0)) { if (((System.Object)simplePattern == null) || Util.StringMatch(varName, simplePattern)) { if (specificNsInPattern) { elemObj = TclString.NewInstance(Var.getVariableFullName(interp, var)); } else { elemObj = TclString.NewInstance(varName); } TclList.Append(interp, list, elemObj); } } } // If the effective namespace isn't the global :: namespace, and a // specific namespace wasn't requested in the pattern (i.e., the // pattern only specifies variable names), then add in all global :: // variables that match the simple pattern. Of course, add in only // those variables that aren't hidden by a variable in the effective // namespace. if ((ns != globalNs) && !specificNsInPattern) { search = globalNs.varTable.GetEnumerator(); while (search.MoveNext()) { varName = ((string)search.Key); var = (Var)search.Value; if (!var.IsVarUndefined() || ((var.Flags & VarFlags.NAMESPACE_VAR) != 0)) { if (((System.Object)simplePattern == null) || Util.StringMatch(varName, simplePattern)) { // Skip vars defined in current namespace if (ns.varTable[varName] == null) { TclList.Append(interp, list, TclString.NewInstance(varName)); } } } } } } else { AppendLocals(interp, list, simplePattern, true); } interp.SetResult(list); return; }
/* *---------------------------------------------------------------------- * * InfoCommandsCmd -- * * Called to implement the "info commands" command that returns the * list of commands in the interpreter that match an optional pattern. * The pattern, if any, consists of an optional sequence of namespace * names separated by "::" qualifiers, which is followed by a * glob-style pattern that restricts which commands are returned. * Handles the following syntax: * * info commands ?pattern? * * Results: * Returns if successful, raises TclException otherwise. * * Side effects: * Returns a result in the interpreter's result object. * *---------------------------------------------------------------------- */ private static void InfoCommandsCmd(Interp interp, TclObject[] objv) { string cmdName, pattern, simplePattern; IDictionaryEnumerator search; NamespaceCmd.Namespace ns; NamespaceCmd.Namespace globalNs = NamespaceCmd.getGlobalNamespace(interp); NamespaceCmd.Namespace currNs = NamespaceCmd.getCurrentNamespace(interp); TclObject list, elemObj; bool specificNsInPattern = false; // Init. to avoid compiler warning. WrappedCommand cmd; // Get the pattern and find the "effective namespace" in which to // list commands. if (objv.Length == 2) { simplePattern = null; ns = currNs; specificNsInPattern = false; } else if (objv.Length == 3) { // From the pattern, get the effective namespace and the simple // pattern (no namespace qualifiers or ::'s) at the end. If an // error was found while parsing the pattern, return it. Otherwise, // if the namespace wasn't found, just leave ns NULL: we will // return an empty list since no commands there can be found. pattern = objv[2].ToString(); // Java does not support passing an address so we pass // an array of size 1 and then assign arr[0] to the value NamespaceCmd.Namespace[] nsArr = new NamespaceCmd.Namespace[1]; NamespaceCmd.Namespace[] dummy1Arr = new NamespaceCmd.Namespace[1]; NamespaceCmd.Namespace[] dummy2Arr = new NamespaceCmd.Namespace[1]; string[] simplePatternArr = new string[1]; NamespaceCmd.getNamespaceForQualName(interp, pattern, null, 0, nsArr, dummy1Arr, dummy2Arr, simplePatternArr); // Get the values out of the arrays! ns = nsArr[0]; simplePattern = simplePatternArr[0]; if (ns != null) { // we successfully found the pattern's ns specificNsInPattern = (simplePattern.CompareTo(pattern) != 0); } } else { throw new TclNumArgsException(interp, 2, objv, "?pattern?"); } // Scan through the effective namespace's command table and create a // list with all commands that match the pattern. If a specific // namespace was requested in the pattern, qualify the command names // with the namespace name. list = TclList.NewInstance(); if (ns != null) { search = ns.cmdTable.GetEnumerator(); while (search.MoveNext()) { cmdName = ((string)search.Key); if (((System.Object)simplePattern == null) || Util.StringMatch(cmdName, simplePattern)) { if (specificNsInPattern) { cmd = (WrappedCommand)search.Value; elemObj = TclString.NewInstance(interp.getCommandFullName(cmd)); } else { elemObj = TclString.NewInstance(cmdName); } TclList.Append(interp, list, elemObj); } } // If the effective namespace isn't the global :: namespace, and a // specific namespace wasn't requested in the pattern, then add in // all global :: commands that match the simple pattern. Of course, // we add in only those commands that aren't hidden by a command in // the effective namespace. if ((ns != globalNs) && !specificNsInPattern) { search = globalNs.cmdTable.GetEnumerator(); while (search.MoveNext()) { cmdName = ((string)search.Key); if (((System.Object)simplePattern == null) || Util.StringMatch(cmdName, simplePattern)) { if (ns.cmdTable[cmdName] == null) { TclList.Append(interp, list, TclString.NewInstance(cmdName)); } } } } } interp.SetResult(list); 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); }
internal static Interp create(Interp interp, TclObject path, bool safe) { Interp masterInterp; string pathString; TclObject[] objv = TclList.getElements(interp, path); if (objv.Length < 2) { masterInterp = interp; pathString = path.ToString(); } else { TclObject obj = TclList.NewInstance(); TclList.insert(interp, obj, 0, objv, 0, objv.Length - 2); masterInterp = InterpCmd.getInterp(interp, obj); pathString = objv[objv.Length - 1].ToString(); } if (!safe) { safe = masterInterp._isSafe; } if (masterInterp._slaveTable.ContainsKey(pathString)) { throw new TclException(interp, "interpreter named \"" + pathString + "\" already exists, cannot create"); } Interp slaveInterp = new Interp(); InterpSlaveCmd slave = new InterpSlaveCmd(); slaveInterp._slave = slave; slaveInterp.SetAssocData("InterpSlaveCmd", slave); slave.masterInterp = masterInterp; slave.path = pathString; slave.slaveInterp = slaveInterp; masterInterp.CreateCommand(pathString, slaveInterp._slave); slaveInterp._slave.interpCmd = NamespaceCmd.findCommand(masterInterp, pathString, null, 0); SupportClass.PutElement(masterInterp._slaveTable, pathString, slaveInterp._slave); slaveInterp.SetVar("tcl_interactive", "0", TCL.VarFlag.GLOBAL_ONLY); // Inherit the recursion limit. slaveInterp._maxNestingDepth = masterInterp._maxNestingDepth; if (safe) { try { makeSafe(slaveInterp); } catch (TclException e) { SupportClass.WriteStackTrace(e, Console.Error); } } else { //Tcl_Init(slaveInterp); } return(slaveInterp); }
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 "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); }