summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog21
-rw-r--r--generic/tclNamesp.c16
-rw-r--r--generic/tclVar.c23
-rw-r--r--tests/namespace.test38
4 files changed, 55 insertions, 43 deletions
diff --git a/ChangeLog b/ChangeLog
index 2d83a91..63f91d1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2004-05-25 Miguel Sofer <msofer@users.sf.net>
+
+ * generic/tclNamesp.c (Tcl_FindNamespaceVar):
+ * tests/namespace.test (namespace-17.10-12): reverted commit of
+ 2004-05-23 and removed the tests, as it interferes with the
+ varname resolver and there are apps that break (AlphaTk). A fix
+ will have to wait for Tcl9.
+
+ * generic/tclVar.c: Caching of namespace variables disabled: no
+ simple way was found to avoid interfering with the resolver's idea
+ of variable existence. A cached varName may keep a variable's name
+ in the namespace's hash table, which is the resolver's criterion
+ for existence.
+
+ * tests/namespace.c (namespace-17.10): testing for interference
+ between varname caching and name resolver.
+
2004-05-25 Kevin Kenny <kennykb@acm.org>
* tests/winFCmd.test: Correct test for the presence of a CD-ROM so
@@ -61,8 +78,7 @@
* generic/tclVar.c (TclLookupSimpleVar): comments re [Bug 736729]
(predecessor of [Bug 959052]) removed.
* tests/namespace.test: added tests 17.10-12
-
- ***POTENTIAL INCOMPATIBILITY***
+
The patch modifies non-documented behaviour, and passes every test
in the testsuite. However, scripts relying on the old behaviour
may break.
@@ -73,6 +89,7 @@
the namespace resolution process deems a variable to exist exactly
when [info vars] finds it - ie, either it has value, or else it
was "fixed" by a call to [variable].
+ Note: this patch was removed on 2002-05-25.
2004-05-22 Miguel Sofer <msofer@users.sf.net>
diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c
index 89dfbab..88ad3bb 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.39 2004/05/23 22:58:23 msofer Exp $
+ * RCS: @(#) $Id: tclNamesp.c,v 1.40 2004/05/25 19:45:14 msofer Exp $
*/
#include "tclInt.h"
@@ -2324,20 +2324,6 @@ Tcl_FindNamespaceVar(interp, name, contextNsPtr, flags)
simpleName);
if (entryPtr != NULL) {
varPtr = (Var *) Tcl_GetHashValue(entryPtr);
-
- /* Fix for [Bug 959052].
- * We might have found a "zombie" variable: it is in the hash
- * table, but the variable is unset and it was not fixed with
- * a call to [variable]. In particular, zombies created by
- * [trace], [upvar], [global] or a reference in a
- * tclNsVarNameType obj should never be found.
- */
-
- if (TclIsVarUndefined(varPtr)
- && !(varPtr->flags & VAR_NAMESPACE_VAR)
- && !(flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY))) {
- varPtr = NULL;
- }
}
}
}
diff --git a/generic/tclVar.c b/generic/tclVar.c
index e84ce8f..667c206 100644
--- a/generic/tclVar.c
+++ b/generic/tclVar.c
@@ -15,7 +15,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclVar.c,v 1.82 2004/05/23 22:53:20 msofer Exp $
+ * RCS: @(#) $Id: tclVar.c,v 1.83 2004/05/25 19:45:16 msofer Exp $
*/
#include "tclInt.h"
@@ -101,10 +101,21 @@ Tcl_ObjType tclLocalVarNameType = {
FreeLocalVarName, DupLocalVarName, UpdateLocalVarName, NULL
};
+/*
+ * Caching of namespace variables disabled: no simple way was found to
+ * avoid interfering with the resolver's idea of variable existence.
+ * A cached varName may keep a variable's name in the namespace's hash
+ * table, which is the resolver's criterion for existence (see test
+ * namespace-17.10).
+ */
+#define ENABLE_NS_VARNAME_CACHING 0
+
+#if ENABLE_NS_VARNAME_CACHING
Tcl_ObjType tclNsVarNameType = {
"namespaceVarName",
FreeNsVarName, DupNsVarName, NULL, NULL
};
+#endif
Tcl_ObjType tclParsedVarNameType = {
"parsedVarName",
@@ -409,6 +420,7 @@ TclObjLookupVar(interp, part1Ptr, part2, flags, msg, createPart1, createPart2,
}
}
goto doneParsing;
+#if ENABLE_NS_VARNAME_CACHING
} else if (typePtr == &tclNsVarNameType) {
Namespace *cachedNsPtr;
int useGlobal, useReference;
@@ -444,6 +456,7 @@ TclObjLookupVar(interp, part1Ptr, part2, flags, msg, createPart1, createPart2,
goto donePart1;
}
goto doneParsing;
+#endif
}
doParse:
@@ -542,6 +555,7 @@ TclObjLookupVar(interp, part1Ptr, part2, flags, msg, createPart1, createPart2,
procPtr->refCount++;
part1Ptr->internalRep.twoPtrValue.ptr1 = (VOID *) procPtr;
part1Ptr->internalRep.twoPtrValue.ptr2 = (VOID *) index;
+#if ENABLE_NS_VARNAME_CACHING
} else if (index > -3) {
/*
* A cacheable namespace or global variable.
@@ -553,6 +567,7 @@ TclObjLookupVar(interp, part1Ptr, part2, flags, msg, createPart1, createPart2,
part1Ptr->typePtr = &tclNsVarNameType;
part1Ptr->internalRep.twoPtrValue.ptr1 = (VOID *) nsPtr;
part1Ptr->internalRep.twoPtrValue.ptr2 = (VOID *) varPtr;
+#endif
} else {
/*
* At least mark part1Ptr as already parsed.
@@ -2271,6 +2286,7 @@ TclObjUnsetVar2(interp, part1Ptr, part2, flags)
}
}
+#if ENABLE_NS_VARNAME_CACHING
/*
* Try to avoid keeping the Var struct allocated due to a tclNsVarNameType
* keeping a reference. This removes some additional exteriorisations of
@@ -2281,7 +2297,8 @@ TclObjUnsetVar2(interp, part1Ptr, part2, flags)
part1Ptr->typePtr->freeIntRepProc(part1Ptr);
part1Ptr->typePtr = NULL;
}
-
+#endif
+
/*
* Finally, if the variable is truly not in use then free up its Var
* structure and remove it from its hash table, if any. The ref count of
@@ -4619,6 +4636,7 @@ UpdateLocalVarName(objPtr)
objPtr->length = 0;
}
+#if ENABLE_NS_VARNAME_CACHING
/*
* nsVarName -
*
@@ -4653,6 +4671,7 @@ DupNsVarName(srcPtr, dupPtr)
varPtr->refCount++;
dupPtr->typePtr = &tclNsVarNameType;
}
+#endif
/*
* parsedVarName -
diff --git a/tests/namespace.test b/tests/namespace.test
index 3193761..e22eb13 100644
--- a/tests/namespace.test
+++ b/tests/namespace.test
@@ -11,7 +11,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: namespace.test,v 1.27 2004/05/25 18:58:04 dgp Exp $
+# RCS: @(#) $Id: namespace.test,v 1.28 2004/05/25 19:45:17 msofer Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest 2
@@ -560,30 +560,20 @@ test namespace-17.9 {Tcl_FindNamespaceVar, relative name and TCL_GLOBAL_ONLY} {
}
set test_ns_1::a
} {hello}
-test namespace-17.10 {Tcl_FindNamespaceVar, do not find zombies (Bug 959052)} {
- catch {unset x}
- catch {namespace delete test_ns_1 }
- catch {namespace delete test_ns_2}
- namespace eval test_ns_1 upvar x q
- namespace eval test_ns_2 set x 1
- catch {set ::x}
-} 1
-test namespace-17.11 {Tcl_FindNamespaceVar, do not find zombies (Bug 959052)} {
- catch {unset x}
- catch {namespace delete test_ns_1}
- trace add variable x write {;#}
- namespace eval test_ns_1 set x 1
- catch {set ::x}
-} 1
-test namespace-17.12 {Tcl_FindNamespaceVar, do not find zombies (Bug 959052)} {
- catch {unset x}
- catch {namespace delete test_ns_1}
- namespace eval test_ns_1 {trace add variable x write {;#}}
- set ::x 0
- namespace eval test_ns_1 set x 1
- set ::x
+test namespace-17.10 {Tcl_FindNamespaceVar, interference with cached varNames} {
+ namespace eval test_ns_1 {}
+ proc test_ns {} {
+ set ::test_ns_1::a 0
+ }
+ test_ns
+ rename test_ns {}
+ namespace eval test_ns_1 unset a
+ set a 0
+ namespace eval test_ns_1 set a 1
+ namespace delete test_ns_1
+ set a
} 1
-
+catch {unset a}
catch {unset x}
catch {unset l}