summaryrefslogtreecommitdiffstats
path: root/generic/tclBasic.c
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)
commitce58cdff9f1d04dfc684cd7f68b920ef6f2164eb (patch)
tree906e565ada666e5d5f751bcc47bad7d05a5f9212 /generic/tclBasic.c
parentd39c33303f33ae3e5b8a27c34661a9b0aed9e2f3 (diff)
downloadtcl-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.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;