summaryrefslogtreecommitdiffstats
path: root/generic/tclNamesp.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2004-09-09 17:09:33 (GMT)
committerdgp <dgp@users.sourceforge.net>2004-09-09 17:09:33 (GMT)
commit7387119ded3440e51b1dfe897052611bd8a7eb53 (patch)
tree5f2596dc36b2a3bc9bef50e9dee8518b4c5a1889 /generic/tclNamesp.c
parentd78ee8b94bc6fcdd3bbd3b5d1c9cb5107a360e20 (diff)
downloadtcl-7387119ded3440e51b1dfe897052611bd8a7eb53.zip
tcl-7387119ded3440e51b1dfe897052611bd8a7eb53.tar.gz
tcl-7387119ded3440e51b1dfe897052611bd8a7eb53.tar.bz2
Also corrected faulty prevention of [namespace import] cycles.
[Bug 1017299]
Diffstat (limited to 'generic/tclNamesp.c')
-rw-r--r--generic/tclNamesp.c47
1 files changed, 27 insertions, 20 deletions
diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c
index cd4b8f2..9a60232 100644
--- a/generic/tclNamesp.c
+++ b/generic/tclNamesp.c
@@ -21,7 +21,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclNamesp.c,v 1.49 2004/09/09 15:44:23 dgp Exp $
+ * RCS: @(#) $Id: tclNamesp.c,v 1.50 2004/09/09 17:09:34 dgp Exp $
*/
#include "tclInt.h"
@@ -1273,7 +1273,7 @@ Tcl_Import(interp, namespacePtr, pattern, allowOverwrite)
char *cmdName;
register Tcl_HashEntry *hPtr;
Tcl_HashSearch search;
- Command *cmdPtr, *realCmdPtr;
+ Command *cmdPtr;
ImportRef *refPtr;
Tcl_Command autoCmd, importedCmd;
ImportedCmdData *dataPtr;
@@ -1373,6 +1373,7 @@ Tcl_Import(interp, namespacePtr, pattern, allowOverwrite)
* pattern. Check whether it was exported. If it wasn't,
* we ignore it.
*/
+ Tcl_HashEntry *found;
wasExported = 0;
for (i = 0; i < importNsPtr->numExportPatterns; i++) {
@@ -1390,8 +1391,9 @@ Tcl_Import(interp, namespacePtr, pattern, allowOverwrite)
* in the current namespace that refers to cmdPtr.
*/
- if ((Tcl_FindHashEntry(&nsPtr->cmdTable, cmdName) == NULL)
- || allowOverwrite) {
+
+ found = Tcl_FindHashEntry(&nsPtr->cmdTable, cmdName);
+ if ((found == NULL) || allowOverwrite) {
/*
* Create the imported command and its client data.
* To create the new command in the current namespace,
@@ -1409,25 +1411,30 @@ Tcl_Import(interp, namespacePtr, pattern, allowOverwrite)
/*
* Check whether creating the new imported command in the
- * current namespace would create a cycle of imported->real
- * command references that also would destroy an existing
- * "real" command already in the current namespace.
+ * current namespace would create a cycle of imported
+ * command references.
*/
cmdPtr = (Command *) Tcl_GetHashValue(hPtr);
- if (cmdPtr->deleteProc == DeleteImportedCmd) {
- realCmdPtr = (Command *) TclGetOriginalCommand(
- (Tcl_Command) cmdPtr);
- if ((realCmdPtr != NULL)
- && (realCmdPtr->nsPtr == currNsPtr)
- && (Tcl_FindHashEntry(&currNsPtr->cmdTable,
- cmdName) != NULL)) {
- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
- "import pattern \"", pattern,
- "\" would create a loop containing command \"",
- Tcl_DStringValue(&ds), "\"", (char *) NULL);
- Tcl_DStringFree(&ds);
- return TCL_ERROR;
+ if ((found != NULL)
+ && cmdPtr->deleteProc == DeleteImportedCmd) {
+
+ Command *overwrite = (Command *) Tcl_GetHashValue(found);
+ Command *link = cmdPtr;
+ while (link->deleteProc == DeleteImportedCmd) {
+ ImportedCmdData *dataPtr;
+
+ dataPtr = (ImportedCmdData *) link->objClientData;
+ link = dataPtr->realCmdPtr;
+ if (overwrite == link) {
+ Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
+ "import pattern \"", pattern,
+ "\" would create a loop containing ",
+ "command \"", Tcl_DStringValue(&ds),
+ "\"", (char *) NULL);
+ Tcl_DStringFree(&ds);
+ return TCL_ERROR;
+ }
}
}