summaryrefslogtreecommitdiffstats
path: root/generic/tclVar.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclVar.c')
-rw-r--r--generic/tclVar.c66
1 files changed, 65 insertions, 1 deletions
diff --git a/generic/tclVar.c b/generic/tclVar.c
index 2dc867d..67a5cab 100644
--- a/generic/tclVar.c
+++ b/generic/tclVar.c
@@ -14,7 +14,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.11 1999/07/22 21:50:54 redman Exp $
+ * RCS: @(#) $Id: tclVar.c,v 1.12 1999/08/10 02:42:14 welch Exp $
*/
#include "tclInt.h"
@@ -4668,3 +4668,67 @@ VarErrMsg(interp, part1, part2, operation, reason)
}
Tcl_AppendResult(interp, "\": ", reason, (char *) NULL);
}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclTraceVarExists --
+ *
+ * This is called from info exists. We need to trigger read
+ * and/or array traces because they may end up creating a
+ * variable that doesn't currently exist.
+ *
+ * Results:
+ * A pointer to the Var structure, or NULL.
+ *
+ * Side effects:
+ * May fill in error messages in the interp.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Var *
+TclVarTraceExists(interp, varName)
+ Tcl_Interp *interp; /* The interpreter */
+ char *varName; /* The variable name */
+{
+ Var *varPtr;
+ Var *arrayPtr;
+ char *msg;
+
+ /*
+ * The choice of "create" flag values is delicate here, and
+ * matches the semantics of GetVar. Things are still not perfect,
+ * however, because if you do "info exists x" you get a varPtr
+ * and therefore trigger traces. However, if you do
+ * "info exists x(i)", then you only get a varPtr if x is already
+ * known to be an array. Otherwise you get NULL, and no trace
+ * is triggered. This matches Tcl 7.6 semantics.
+ */
+
+ varPtr = TclLookupVar(interp, varName, (char *) NULL,
+ 0, "access",
+ /*createPart1*/ 0, /*createPart2*/ 1, &arrayPtr);
+ if (varPtr == NULL) {
+ return NULL;
+ }
+ if ((varPtr != NULL) &&
+ ((varPtr->tracePtr != NULL)
+ || ((arrayPtr != NULL) && (arrayPtr->tracePtr != NULL)))) {
+ msg = CallTraces((Interp *)interp, arrayPtr, varPtr, varName,
+ (char *) NULL, TCL_TRACE_READS);
+ if (msg != NULL) {
+ /*
+ * If the variable doesn't exist anymore and no-one's using
+ * it, then free up the relevant structures and hash table entries.
+ */
+
+ if (TclIsVarUndefined(varPtr)) {
+ CleanupVar(varPtr, arrayPtr);
+ }
+ return NULL;
+ }
+ }
+ return varPtr;
+}