summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2017-09-02 19:35:22 (GMT)
committerdgp <dgp@users.sourceforge.net>2017-09-02 19:35:22 (GMT)
commit5d7ae02a8ce96d7fbec18af96fbe91a775f126d3 (patch)
tree906e565ada666e5d5f751bcc47bad7d05a5f9212 /generic
parentc0468b3264ddb516b6086f5f0c57aaee4824f25c (diff)
downloadtcl-5d7ae02a8ce96d7fbec18af96fbe91a775f126d3.zip
tcl-5d7ae02a8ce96d7fbec18af96fbe91a775f126d3.tar.gz
tcl-5d7ae02a8ce96d7fbec18af96fbe91a775f126d3.tar.bz2
[Bug 0e4d88b650] First draft fix. Re-resolve namespace after cmd deletion.
Diffstat (limited to 'generic')
-rw-r--r--generic/tclBasic.c28
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;