summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2008-05-21 13:26:14 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2008-05-21 13:26:14 (GMT)
commit422670d42865358d830bc1a65fc7aa48904a2d71 (patch)
tree4fd121267a29b8a26506b15326ed9b38bb167344 /generic
parente47e090ebc6534d30664a39311da929831681b02 (diff)
downloadtcl-422670d42865358d830bc1a65fc7aa48904a2d71.zip
tcl-422670d42865358d830bc1a65fc7aa48904a2d71.tar.gz
tcl-422670d42865358d830bc1a65fc7aa48904a2d71.tar.bz2
Backport of fixes to Tcl_SetNamespaceUnknownHandler
Diffstat (limited to 'generic')
-rw-r--r--generic/tclNamesp.c61
1 files changed, 37 insertions, 24 deletions
diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c
index f7fa9c1..c51ea08 100644
--- a/generic/tclNamesp.c
+++ b/generic/tclNamesp.c
@@ -23,7 +23,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.162 2008/03/02 18:46:39 msofer Exp $
+ * RCS: @(#) $Id: tclNamesp.c,v 1.162.2.1 2008/05/21 13:26:16 dkf Exp $
*/
#include "tclInt.h"
@@ -4296,45 +4296,58 @@ Tcl_SetNamespaceUnknownHandler(
Tcl_Namespace *nsPtr, /* Namespace which is being updated. */
Tcl_Obj *handlerPtr) /* The new handler, or NULL to reset. */
{
- int lstlen;
+ int lstlen = 0;
Namespace *currNsPtr = (Namespace *)nsPtr;
- if (currNsPtr->unknownHandlerPtr != NULL) {
- /*
- * Remove old handler first.
- */
+ /*
+ * Ensure that we check for errors *first* before we change anything.
+ */
- Tcl_DecrRefCount(currNsPtr->unknownHandlerPtr);
- currNsPtr->unknownHandlerPtr = NULL;
+ if (handlerPtr != NULL) {
+ if (TclListObjLength(interp, handlerPtr, &lstlen) != TCL_OK) {
+ /*
+ * Not a list.
+ */
+
+ return TCL_ERROR;
+ }
+ if (lstlen > 0) {
+ /*
+ * We are going to be saving this handler. Increment the reference
+ * count before decrementing the refcount on the previous handler,
+ * so that nothing strange can happen if we are told to set the
+ * handler to the previous value.
+ */
+
+ Tcl_IncrRefCount(handlerPtr);
+ }
}
/*
- * If NULL or an empty list is passed, then reset to the default
- * handler.
+ * Remove old handler next.
*/
- if (handlerPtr == NULL) {
- currNsPtr->unknownHandlerPtr = NULL;
- } else if (TclListObjLength(interp, handlerPtr, &lstlen) != TCL_OK) {
- /*
- * Not a list.
- */
+ if (currNsPtr->unknownHandlerPtr != NULL) {
+ Tcl_DecrRefCount(currNsPtr->unknownHandlerPtr);
+ }
- return TCL_ERROR;
- } else if (lstlen == 0) {
+ /*
+ * Install the new handler.
+ */
+
+ if (lstlen > 0) {
/*
- * Empty list - reset to default.
+ * Just store the handler. It already has the correct reference count.
*/
- currNsPtr->unknownHandlerPtr = NULL;
+ currNsPtr->unknownHandlerPtr = handlerPtr;
} else {
/*
- * Increment ref count and store. The reference count is decremented
- * either in the code above, or when the namespace is deleted.
+ * If NULL or an empty list is passed, this resets to the default
+ * handler.
*/
- Tcl_IncrRefCount(handlerPtr);
- currNsPtr->unknownHandlerPtr = handlerPtr;
+ currNsPtr->unknownHandlerPtr = NULL;
}
return TCL_OK;
}