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 "open" 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) { bool pipeline = false; /* True if opening pipeline chan */ int prot = 438; /* Final rdwr permissions of file */ int modeFlags = TclIO.RDONLY; /* Rdwr mode for the file. See the * TclIO class for more info on the * valid modes */ if ((argv.Length < 2) || (argv.Length > 4)) { throw new TclNumArgsException(interp, 1, argv, "fileName ?access? ?permissions?"); } if (argv.Length > 2) { TclObject mode = argv[2]; string modeStr = mode.ToString(); int len = modeStr.Length; // This "r+1" hack is just to get a test case to pass if ((len == 0) || (modeStr.StartsWith("r+") && len >= 3)) { throw new TclException(interp, "illegal access mode \"" + modeStr + "\""); } if (len < 3) { switch (modeStr[0]) { case 'r': { if (len == 1) { modeFlags = TclIO.RDONLY; break; } else if (modeStr[1] == '+') { modeFlags = TclIO.RDWR; break; } } goto case 'w'; case 'w': { FileInfo f = FileUtil.getNewFileObj(interp, argv[1].ToString()); bool tmpBool; if (File.Exists(f.FullName)) { tmpBool = true; } else { tmpBool = Directory.Exists(f.FullName); } if (tmpBool) { bool tmpBool2; try { if (File.Exists(f.FullName)) { File.SetAttributes(f.FullName, FileAttributes.Normal); File.Delete(f.FullName); tmpBool2 = true; } else if (Directory.Exists(f.FullName)) { Directory.Delete(f.FullName); tmpBool2 = true; } else { tmpBool2 = false; } } // ATK added because .NET do not allow often to delete // files used by another process catch (IOException e) { throw new TclException(interp, "cannot open file: " + argv[1].ToString()); } bool generatedAux = tmpBool2; } if (len == 1) { modeFlags = (TclIO.WRONLY | TclIO.CREAT); break; } else if (modeStr[1] == '+') { modeFlags = (TclIO.RDWR | TclIO.CREAT); break; } } goto case 'a'; case 'a': { if (len == 1) { modeFlags = (TclIO.WRONLY | TclIO.APPEND); break; } else if (modeStr[1] == '+') { modeFlags = (TclIO.RDWR | TclIO.CREAT | TclIO.APPEND); break; } } goto default; default: { throw new TclException(interp, "illegal access mode \"" + modeStr + "\""); } } } else { modeFlags = 0; bool gotRorWflag = false; int mlen = TclList.getLength(interp, mode); for (int i = 0; i < mlen; i++) { TclObject marg = TclList.index(interp, mode, i); if (marg.ToString().Equals("RDONLY")) { modeFlags |= TclIO.RDONLY; gotRorWflag = true; } else { if (marg.ToString().Equals("WRONLY")) { modeFlags |= TclIO.WRONLY; gotRorWflag = true; } else { if (marg.ToString().Equals("RDWR")) { modeFlags |= TclIO.RDWR; gotRorWflag = true; } else { if (marg.ToString().Equals("APPEND")) { modeFlags |= TclIO.APPEND; } else { if (marg.ToString().Equals("CREAT")) { modeFlags |= TclIO.CREAT; } else { if (marg.ToString().Equals("EXCL")) { modeFlags |= TclIO.EXCL; } else { if (marg.ToString().Equals("TRUNC")) { modeFlags |= TclIO.TRUNC; } else { throw new TclException(interp, "invalid access mode \"" + marg.ToString() + "\": must be RDONLY, WRONLY, RDWR, APPEND, " + "CREAT EXCL, NOCTTY, NONBLOCK, or TRUNC"); } } } } } } } } if (!gotRorWflag) { throw new TclException(interp, "access mode must include either RDONLY, WRONLY, or RDWR"); } } } if (argv.Length == 4) { prot = TclInteger.Get(interp, argv[3]); throw new TclException(interp, "setting permissions not implemented yet"); } if ((argv[1].ToString().Length > 0) && (argv[1].ToString()[0] == '|')) { pipeline = true; throw new TclException(interp, "pipes not implemented yet"); } /* * Open the file or create a process pipeline. */ if (!pipeline) { try { FileChannel file = new FileChannel(); file.open(interp, argv[1].ToString(), modeFlags); TclIO.registerChannel(interp, file); interp.SetResult(file.ChanName); } catch (IOException e) { throw new TclException(interp, "cannot open file: " + argv[1].ToString()); } } else { /* * Pipeline code here... */ } return(TCL.CompletionCode.RETURN); }