summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tkEntry.c38
-rw-r--r--tests/entry.test6
-rw-r--r--tests/spinbox.test6
3 files changed, 44 insertions, 6 deletions
diff --git a/generic/tkEntry.c b/generic/tkEntry.c
index dd753f0..338652b 100644
--- a/generic/tkEntry.c
+++ b/generic/tkEntry.c
@@ -1102,6 +1102,7 @@ ConfigureEntry(
int valuesChanged = 0; /* lint initialization */
double oldFrom = 0.0; /* lint initialization */
double oldTo = 0.0; /* lint initialization */
+ int code;
/*
* Eliminate any existing trace on a variable monitored by the entry.
@@ -1297,9 +1298,6 @@ ConfigureEntry(
/*
* If the entry is tied to the value of a variable, create the variable if
* it doesn't exist, and set the entry's value from the variable's value.
- * No checking of the return value of EntryValueChanged is needed since it
- * can only return TCL_ERROR if there is a trace on the textvariable and
- * since any existing trace on it was eliminated above.
*/
if (entryPtr->textVarName != NULL) {
@@ -1307,6 +1305,17 @@ ConfigureEntry(
value = Tcl_GetVar(interp, entryPtr->textVarName, TCL_GLOBAL_ONLY);
if (value == NULL) {
+
+ /*
+ * Since any trace on the textvariable was eliminated above,
+ * the only possible reason for EntryValueChanged to return
+ * an error is that the textvariable lives in a namespace
+ * that does not (yet) exist. Indeed, namespaces are not
+ * automatically created as needed. Don't trap this error
+ * here, better do it below when attempting to trace the
+ * variable.
+ */
+
EntryValueChanged(entryPtr, NULL);
} else {
EntrySetValue(entryPtr, value);
@@ -1325,7 +1334,13 @@ ConfigureEntry(
*/
Tcl_ListObjIndex(interp, sbPtr->listObj, 0, &objPtr);
- EntryValueChanged(entryPtr, Tcl_GetString(objPtr));
+
+ /*
+ * No check for error return here as well, because any possible
+ * error will be trapped below when attempting tracing.
+ */
+
+ EntryValueChanged(entryPtr, Tcl_GetString(objPtr));
} else if ((sbPtr->valueStr == NULL)
&& !DOUBLES_EQ(sbPtr->fromValue, sbPtr->toValue)
&& (!DOUBLES_EQ(sbPtr->fromValue, oldFrom)
@@ -1350,6 +1365,12 @@ ConfigureEntry(
}
}
sprintf(sbPtr->formatBuf, sbPtr->valueFormat, dvalue);
+
+ /*
+ * No check for error return here as well, because any possible
+ * error will be trapped below when attempting tracing.
+ */
+
EntryValueChanged(entryPtr, sbPtr->formatBuf);
}
}
@@ -1361,10 +1382,13 @@ ConfigureEntry(
if ((entryPtr->textVarName != NULL)
&& !(entryPtr->flags & ENTRY_VAR_TRACED)) {
- Tcl_TraceVar(interp, entryPtr->textVarName,
+ code = Tcl_TraceVar(interp, entryPtr->textVarName,
TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
EntryTextVarProc, (ClientData) entryPtr);
- entryPtr->flags |= ENTRY_VAR_TRACED;
+ if (code != TCL_OK) {
+ return TCL_ERROR;
+ }
+ entryPtr->flags |= ENTRY_VAR_TRACED;
}
EntryWorldChanged((ClientData) entryPtr);
@@ -2267,6 +2291,8 @@ EntryValueChanged(
/*
* An error may have happened when setting the textvariable in case there
* is a trace on that variable and the trace proc triggered an error.
+ * Another possibility is that the textvariable is in a namespace that
+ * does not (yet) exist.
* Signal this error.
*/
diff --git a/tests/entry.test b/tests/entry.test
index da8f280..da3637d 100644
--- a/tests/entry.test
+++ b/tests/entry.test
@@ -1641,6 +1641,12 @@ test entry-23.1 {error in trace proc attached to the textvariable} {
} [list {can't set "myvar": Intentional error here!} \
{can't set "myvar": Intentional error here!}]
+test entry-24.1 {textvariable lives in a non-existing namespace} {
+ destroy .e
+ catch {entry .e -textvariable thisnsdoesntexist::myvar} result1
+ set result1
+} {can't trace "thisnsdoesntexist::myvar": parent namespace doesn't exist}
+
destroy .e
# XXX Still need to write tests for EntryBlinkProc, EntryFocusProc,
diff --git a/tests/spinbox.test b/tests/spinbox.test
index 5fba390..68c6fae 100644
--- a/tests/spinbox.test
+++ b/tests/spinbox.test
@@ -1599,6 +1599,12 @@ test spinbox-24.1 {error in trace proc attached to the textvariable} {
{can't set "myvar": Intentional error here!} \
{can't set "myvar": Intentional error here!}]
+test spinbox-25.1 {textvariable lives in a non-existing namespace} {
+ destroy .s
+ catch {spinbox .s -textvariable thisnsdoesntexist::myvar} result1
+ set result1
+} {can't trace "thisnsdoesntexist::myvar": parent namespace doesn't exist}
+
catch {unset ::e ::vVals}
##