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 void Dispose(Interp interp) // Current interpreter. { // There shouldn't be any commands left. if (!(interp._slaveTable.Count == 0)) { System.Console.Error.WriteLine("InterpInfoDeleteProc: still exist commands"); } interp._slaveTable = null; // Tell any interps that have aliases to this interp that they should // delete those aliases. If the other interp was already dead, it // would have removed the target record already. // TODO ATK foreach (WrappedCommand slaveCmd in new ArrayList(interp._targetTable.Keys)) { Interp slaveInterp = (Interp)interp._targetTable[slaveCmd]; slaveInterp.DeleteCommandFromToken(slaveCmd); } interp._targetTable = null; if (interp._interpChanTable != null) { foreach (Channel channel in new ArrayList(interp._interpChanTable.Values)) { TclIO.unregisterChannel(interp, channel); } } if (interp._slave.interpCmd != null) { // Tcl_DeleteInterp() was called on this interpreter, rather // "interp delete" or the equivalent deletion of the command in the // master. First ensure that the cleanup callback doesn't try to // delete the interp again. interp._slave.slaveInterp = null; interp._slave.masterInterp.DeleteCommandFromToken(interp._slave.interpCmd); } // There shouldn't be any aliases left. if (!(interp._aliasTable.Count == 0)) { System.Console.Error.WriteLine("InterpInfoDeleteProc: still exist aliases"); } interp._aliasTable = null; }
internal static void delete(Interp interp, Interp slaveInterp, TclObject name) { // If the alias has been renamed in the slave, the master can still use // the original name (with which it was created) to find the alias to // delete it. string inString = name.ToString(); if (!slaveInterp._aliasTable.ContainsKey(inString)) { throw new TclException(interp, "alias \"" + inString + "\" not found"); } InterpAliasCmd alias = (InterpAliasCmd)slaveInterp._aliasTable[inString]; slaveInterp.DeleteCommandFromToken(alias.slaveCmd); }