/* *---------------------------------------------------------------------- * * 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; }
/* *---------------------------------------------------------------------- * * AppendLocals -- * * Append the local variables for the current frame to the * specified list object. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ private static void AppendLocals(Interp interp, TclObject list, string pattern, bool includeLinks) { Var var; string varName; Hashtable localVarTable; IDictionaryEnumerator search; localVarTable = interp.VarFrame.VarTable; // Compiled locals do not exist in Jacl if (localVarTable != null) { for (search = localVarTable.GetEnumerator(); search.MoveNext();) { var = (Var)search.Value; varName = (string)search.Key; if (!var.IsVarUndefined() && (includeLinks || !var.IsVarLink())) { if (((System.Object)pattern == null) || Util.StringMatch(varName, pattern)) { TclList.Append(interp, list, TclString.NewInstance(varName)); } } } } }
/* *---------------------------------------------------------------------- * * 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; }
/// <summary> Sorts the list according to the sort mode and (optional) sort command. /// The resulting list will contain no duplicates, if argument unique is /// specifed as true. /// If tobj is not a list object, an attempt will be made to /// convert it to a list. /// /// </summary> /// <param name="interp">the current interpreter. /// </param> /// <param name="tobj">the list to sort. /// </param> /// <param name="sortMode">the sorting mode. /// </param> /// <param name="sortIncreasing">true if to sort the elements in increasing order. /// </param> /// <param name="command">the command to compute the order of two elements. /// </param> /// <param name="unique">true if the result should contain no duplicates. /// </param> /// <exception cref=""> TclException if tobj is not a valid list. /// </exception> internal static void sort(Interp interp, TclObject tobj, int sortMode, int sortIndex, bool sortIncreasing, string command, bool unique) { setListFromAny(interp, tobj); tobj.invalidateStringRep(); TclList tlist = (TclList)tobj.InternalRep; int size = tlist.vector.Count; if (size <= 1) { return; } TclObject[] objArray = new TclObject[size]; for (int i = 0; i < size; i++) { objArray[i] = (TclObject)tlist.vector[i]; } QSort s = new QSort(); int newsize = s.sort(interp, objArray, sortMode, sortIndex, sortIncreasing, command, unique); for (int i = 0; i < size; i++) { if (i < newsize) { tlist.vector[i] = objArray[i]; objArray[i] = null; } else { tlist.vector.RemoveAt(newsize); } } }
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); }
internal Procedure(Interp interp, NamespaceCmd.Namespace ns, string name, TclObject args, TclObject b, string sFileName, int sLineNumber) { this.NS = ns; srcFileName = sFileName; srcLineNumber = sLineNumber; // Break up the argument list into argument specifiers, then process // each argument specifier. int numArgs = TclList.getLength(interp, args); ArgList = new TclObject[numArgs][]; for (int i = 0; i < numArgs; i++) { ArgList[i] = new TclObject[2]; } for (int i = 0; i < numArgs; i++) { // Now divide the specifier up into name and default. TclObject argSpec = TclList.index(interp, args, i); int specLen = TclList.getLength(interp, argSpec); if (specLen == 0) { throw new TclException(interp, "procedure \"" + name + "\" has argument with no name"); } if (specLen > 2) { throw new TclException(interp, "too many fields in argument " + "specifier \"" + argSpec + "\""); } ArgList[i][0] = TclList.index(interp, argSpec, 0); ArgList[i][0].Preserve(); if (specLen == 2) { ArgList[i][1] = TclList.index(interp, argSpec, 1); ArgList[i][1].Preserve(); } else { ArgList[i][1] = null; } } if (numArgs > 0 && (ArgList[numArgs - 1][0].ToString().Equals("args"))) { isVarArgs = true; } else { isVarArgs = false; } body = new CharPointer(b.ToString()); body_length = body.Length(); }
private static void addFileToResult(Interp interp, string fileName, string separators, TclObject resultList) { string prettyFileName = fileName; int prettyLen = fileName.Length; // Java IO reuqires Windows volumes [A-Za-z]: to be followed by '\\'. if ((JACL.PLATFORM == JACL.PLATFORM_WINDOWS) && (prettyLen >= 2) && (fileName[1] == ':')) { if (prettyLen == 2) { fileName = fileName + '\\'; } else if (fileName[2] != '\\') { fileName = fileName.Substring(0, (2) - (0)) + '\\' + fileName.Substring(2); } } TclObject[] arrayObj = TclList.getElements(interp, FileUtil.splitAndTranslate(interp, fileName)); fileName = FileUtil.joinPath(interp, arrayObj, 0, arrayObj.Length); FileInfo f; if (FileUtil.getPathType(fileName) == FileUtil.PATH_ABSOLUTE) { f = FileUtil.getNewFileObj(interp, fileName); } else { f = new FileInfo(interp.getWorkingDir().FullName + "\\" + fileName); } // If the last character is a spearator, make sure the file is an // existing directory, otherwise check that the file exists. if ((prettyLen > 0) && (separators.IndexOf((System.Char)prettyFileName[prettyLen - 1]) != -1)) { if (Directory.Exists(f.FullName)) { TclList.Append(interp, resultList, TclString.NewInstance(prettyFileName)); } } else { bool tmpBool; if (File.Exists(f.FullName)) { tmpBool = true; } else { tmpBool = Directory.Exists(f.FullName); } if (tmpBool) { TclList.Append(interp, resultList, TclString.NewInstance(prettyFileName)); } } }
internal static Interp getInterp(Interp interp, TclObject path) { TclObject[] objv = TclList.getElements(interp, path); Interp searchInterp = interp; //Interim storage for interp. to find. for (int i = 0; i < objv.Length; i++) { string name = objv[i].ToString(); if (!searchInterp._slaveTable.ContainsKey(name)) { searchInterp = null; break; } InterpSlaveCmd slave = (InterpSlaveCmd)searchInterp._slaveTable[name]; searchInterp = slave.slaveInterp; if (searchInterp == null) { break; } } if (searchInterp == null) { throw new TclException(interp, "could not find interpreter \"" + path.ToString() + "\""); } return(searchInterp); }
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); } } }
/// <summary> Queries the length of the list. If tobj is not a list object, /// an attempt will be made to convert it to a list. /// /// </summary> /// <param name="interp">current interpreter. /// </param> /// <param name="tobj">the TclObject to use as a list. /// </param> /// <returns> the length of the list. /// </returns> /// <exception cref=""> TclException if tobj is not a valid list. /// </exception> public static int getLength(Interp interp, TclObject tobj) { setListFromAny(interp, tobj); TclList tlist = (TclList)tobj.InternalRep; return(tlist.vector.Count); }
internal WrappedCommand getTargetCmd(Interp interp) { TclObject[] objv = TclList.getElements(interp, prefix); string targetName = objv[0].ToString(); return(NamespaceCmd.findCommand(targetInterp, targetName, null, 0)); }
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); }
/// <summary> See Tcl user documentation for details.</summary> /// <exception cref=""> TclException If incorrect number of arguments. /// </exception> public TCL.CompletionCode CmdProc(Interp interp, TclObject[] argv) { if (argv.Length != 2) { throw new TclNumArgsException(interp, 1, argv, "list"); } interp.SetResult(TclInteger.NewInstance(TclList.getLength(interp, argv[1]))); return(TCL.CompletionCode.RETURN); }
/* *---------------------------------------------------------------------- * * 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_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); }; }
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); }
public static void Tcl_ListObjIndex(Interp interp, TclObject to, int nItem, out TclObject elmObj) { try { elmObj = TclList.index(interp, to, nItem); } catch { elmObj = null; } }
public static void Tcl_ListObjLength(Interp interp, TclObject to, out int nArg) { try { nArg = TclList.getLength(interp, to); } catch { nArg = 0; } }
/// <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); } } }
public static bool Tcl_ListObjAppendElement(Interp interp, TclObject to, TclObject elemObj) { try { TclList.Append(interp, to, elemObj); return(false); } catch { return(true); } }
/// <summary> Called to convert the other object's internal rep to list. /// /// </summary> /// <param name="interp">current interpreter. /// </param> /// <param name="tobj">the TclObject to convert to use the List internal rep. /// </param> /// <exception cref=""> TclException if the object doesn't contain a valid list. /// </exception> internal static void setListFromAny(Interp interp, TclObject tobj) { IInternalRep rep = tobj.InternalRep; if (!(rep is TclList)) { TclList tlist = new TclList(); splitList(interp, tlist.vector, tobj.ToString()); tobj.InternalRep = tlist; } }
/// <summary> DupListInternalRep -> duplicate /// /// Returns a dupilcate of the current object. /// /// </summary> /// <param name="obj">the TclObject that contains this internalRep. /// </param> public IInternalRep Duplicate() { int size = vector.Count; TclList newList = new TclList(size); for (int i = 0; i < size; i++) { TclObject tobj = (TclObject)vector[i]; tobj.Preserve(); newList.vector.Add(tobj); } return(newList); }
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); }
/// <summary> Tcl_ListObjAppendElement -> TclList.append() /// /// Appends a TclObject element to a list object. /// /// </summary> /// <param name="interp">current interpreter. /// </param> /// <param name="tobj">the TclObject to append an element to. /// </param> /// <param name="elemObj">the element to append to the object. /// </param> /// <exception cref=""> TclException if tobj cannot be converted into a list. /// </exception> public static void Append(Interp interp, TclObject tobj, TclObject elemObj) { if (tobj.Shared) { throw new TclRuntimeError("TclList.append() called with shared object"); } setListFromAny(interp, tobj); tobj.invalidateStringRep(); TclList tlist = (TclList)tobj.InternalRep; elemObj.Preserve(); tlist.vector.Add(elemObj); }
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); } }
/// <summary> Returns a TclObject array of the elements in a list object. If /// tobj is not a list object, an attempt will be made to convert /// it to a list. <p> /// /// The objects referenced by the returned array should be treated /// as readonly and their ref counts are _not_ incremented; the /// caller must do that if it holds on to a reference. /// /// </summary> /// <param name="interp">the current interpreter. /// </param> /// <param name="tobj">the list to sort. /// </param> /// <returns> a TclObject array of the elements in a list object. /// </returns> /// <exception cref=""> TclException if tobj is not a valid list. /// </exception> public static TclObject[] getElements(Interp interp, TclObject tobj) { setListFromAny(interp, tobj); TclList tlist = (TclList)tobj.InternalRep; int size = tlist.vector.Count; TclObject[] objArray = new TclObject[size]; for (int i = 0; i < size; i++) { objArray[i] = (TclObject)tlist.vector[i]; } return(objArray); }
/* *---------------------------------------------------------------------- * * 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; }
public static bool Tcl_ListObjGetElements(Interp interp, TclObject to, out int nItem, out TclObject[] elmObj) { try { elmObj = TclList.getElements(interp, to); nItem = elmObj.Length; return(false); } catch { elmObj = null; nItem = 0; return(true); } }
/// <summary> This procedure returns a pointer to the index'th object from /// the list referenced by tobj. The first element has index /// 0. If index is negative or greater than or equal to the number /// of elements in the list, a null is returned. If tobj is not a /// list object, an attempt will be made to convert it to a list. /// /// </summary> /// <param name="interp">current interpreter. /// </param> /// <param name="tobj">the TclObject to use as a list. /// </param> /// <param name="index">the index of the requested element. /// </param> /// <returns> the the requested element. /// </returns> /// <exception cref=""> TclException if tobj is not a valid list. /// </exception> public static TclObject index(Interp interp, TclObject tobj, int index) { setListFromAny(interp, tobj); TclList tlist = (TclList)tobj.InternalRep; if (index < 0 || index >= tlist.vector.Count) { return(null); } else { return((TclObject)tlist.vector[index]); } }
public static string translateFileName(Interp interp, string path) { string fileName = ""; if ((path.Length == 0) || (path[0] != '~')) { // fileName = path; TclObject[] joinArrayObj = new TclObject[1]; joinArrayObj[0] = TclString.NewInstance(path); fileName = joinPath(interp, joinArrayObj, 0, 1); } else { TclObject[] splitArrayObj = TclList.getElements(interp, splitPath(interp, path)); string user = splitArrayObj[0].ToString().Substring(1); // Strip the trailing ':' off of a Mac path // before passing the user name to DoTildeSubst. if ((JACL.PLATFORM == JACL.PLATFORM_MAC) && (user.EndsWith(":"))) { user = user.Substring(0, (user.Length - 1) - (0)); } user = doTildeSubst(interp, user); // if (splitArrayObj.length < 2) { // fileName = user; // } else { splitArrayObj[0] = TclString.NewInstance(user); fileName = joinPath(interp, splitArrayObj, 0, splitArrayObj.Length); // } } // Convert forward slashes to backslashes in Windows paths because // some system interfaces don't accept forward slashes. if (JACL.PLATFORM == JACL.PLATFORM_WINDOWS) { fileName = fileName.Replace('/', '\\'); } return(fileName); }