diff options
-rw-r--r-- | generic/tkEntry.c | 38 | ||||
-rw-r--r-- | tests/entry.test | 9 | ||||
-rw-r--r-- | tests/spinbox.test | 9 |
3 files changed, 50 insertions, 6 deletions
diff --git a/generic/tkEntry.c b/generic/tkEntry.c index e1189b6..36798a2 100644 --- a/generic/tkEntry.c +++ b/generic/tkEntry.c @@ -1104,6 +1104,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. @@ -1304,9 +1305,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) { @@ -1314,6 +1312,17 @@ ConfigureEntry( value = Tcl_GetVar2(interp, entryPtr->textVarName, NULL, 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); @@ -1332,7 +1341,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) @@ -1355,6 +1370,12 @@ ConfigureEntry( dvalue = sbPtr->fromValue; } 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); } } @@ -1366,10 +1387,13 @@ ConfigureEntry( if ((entryPtr->textVarName != NULL) && !(entryPtr->flags & ENTRY_VAR_TRACED)) { - Tcl_TraceVar2(interp, entryPtr->textVarName, + code = Tcl_TraceVar2(interp, entryPtr->textVarName, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, EntryTextVarProc, entryPtr); - entryPtr->flags |= ENTRY_VAR_TRACED; + if (code != TCL_OK) { + return TCL_ERROR; + } + entryPtr->flags |= ENTRY_VAR_TRACED; } EntryWorldChanged(entryPtr); @@ -2270,6 +2294,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 4cc9218..9c30b00 100644 --- a/tests/entry.test +++ b/tests/entry.test @@ -3493,6 +3493,15 @@ test entry-23.1 {error in trace proc attached to the textvariable} -setup { } -result [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} -setup { + destroy .e +} -body { + catch {entry .e -textvariable thisnsdoesntexist::myvar} result1 + set result1 +} -cleanup { + destroy .e +} -result {can't trace "thisnsdoesntexist::myvar": parent namespace doesn't exist} + # Gathered comments about lacks # XXX Still need to write tests for EntryBlinkProc, EntryFocusProc, # and EntryTextVarProc. diff --git a/tests/spinbox.test b/tests/spinbox.test index f101640..594cc90 100644 --- a/tests/spinbox.test +++ b/tests/spinbox.test @@ -3808,6 +3808,15 @@ test spinbox-24.1 {error in trace proc attached to the textvariable} -setup { {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} -setup { + destroy .s +} -body { + catch {spinbox .s -textvariable thisnsdoesntexist::myvar} result1 + set result1 +} -cleanup { + destroy .s +} -result {can't trace "thisnsdoesntexist::myvar": parent namespace doesn't exist} + # Collected comments about lacks from the test # XXX Still need to write tests for SpinboxBlinkProc, SpinboxFocusProc, # and SpinboxTextVarProc. |