diff options
author | dgp <dgp@users.sourceforge.net> | 2017-09-02 19:35:22 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2017-09-02 19:35:22 (GMT) |
commit | ce58cdff9f1d04dfc684cd7f68b920ef6f2164eb (patch) | |
tree | 906e565ada666e5d5f751bcc47bad7d05a5f9212 /generic/tclBasic.c | |
parent | d39c33303f33ae3e5b8a27c34661a9b0aed9e2f3 (diff) | |
download | tcl-ce58cdff9f1d04dfc684cd7f68b920ef6f2164eb.zip tcl-ce58cdff9f1d04dfc684cd7f68b920ef6f2164eb.tar.gz tcl-ce58cdff9f1d04dfc684cd7f68b920ef6f2164eb.tar.bz2 |
[Bug 0e4d88b650] First draft fix. Re-resolve namespace after cmd deletion.
Diffstat (limited to 'generic/tclBasic.c')
-rw-r--r-- | generic/tclBasic.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 44cf543..fddce1a 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -2017,7 +2017,7 @@ Tcl_CreateObjCommand( Command *cmdPtr, *refCmdPtr; Tcl_HashEntry *hPtr; const char *tail; - int isNew; + int isNew = 0, deleted = 0; ImportedCmdData *dataPtr; if (iPtr->flags & DELETED) { @@ -2030,6 +2030,14 @@ Tcl_CreateObjCommand( } /* + * If the command name we seek to create already exists, we need to + * delete that first. That can be tricky in the presence of traces. + * Loop until we no longer find an existing command in the way. + */ + + while (1) { + + /* * Determine where the command should reside. If its name contains * namespace qualifiers, we put it in the specified namespace; otherwise, * we always put it in the global namespace. @@ -2047,11 +2055,13 @@ Tcl_CreateObjCommand( } hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew); - TclInvalidateNsPath(nsPtr); - if (!isNew) { - cmdPtr = Tcl_GetHashValue(hPtr); + + if (isNew || deleted) { + break; + } /* Command already exists. */ + cmdPtr = Tcl_GetHashValue(hPtr); /* * [***] This is wrong. See Tcl Bug a16752c252. @@ -2089,8 +2099,8 @@ Tcl_CreateObjCommand( cmdPtr->importRefPtr = NULL; } TclCleanupCommandMacro(cmdPtr); - - hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew); + deleted = 1; + } if (!isNew) { /* * If the deletion callback recreated the command, just throw away @@ -2100,7 +2110,8 @@ Tcl_CreateObjCommand( ckfree(Tcl_GetHashValue(hPtr)); } - } else { + + if (!deleted) { /* * The list of command exported from the namespace might have changed. * However, we do not need to recompute this just yet; next time we @@ -2108,7 +2119,8 @@ Tcl_CreateObjCommand( */ TclInvalidateNsCmdLookup(nsPtr); - } + TclInvalidateNsPath(nsPtr); + } cmdPtr = (Command *) ckalloc(sizeof(Command)); Tcl_SetHashValue(hPtr, cmdPtr); cmdPtr->hPtr = hPtr; |