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 | 5d7ae02a8ce96d7fbec18af96fbe91a775f126d3 (patch) | |
tree | 906e565ada666e5d5f751bcc47bad7d05a5f9212 | |
parent | c0468b3264ddb516b6086f5f0c57aaee4824f25c (diff) | |
download | tcl-5d7ae02a8ce96d7fbec18af96fbe91a775f126d3.zip tcl-5d7ae02a8ce96d7fbec18af96fbe91a775f126d3.tar.gz tcl-5d7ae02a8ce96d7fbec18af96fbe91a775f126d3.tar.bz2 |
[Bug 0e4d88b650] First draft fix. Re-resolve namespace after cmd deletion.
-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; |