diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2014-02-08 07:54:21 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2014-02-08 07:54:21 (GMT) |
commit | 2ac3c16d405d20153ce0ad43f308ff05bc372f7a (patch) | |
tree | a2c25a30318c9b3b690cc56b74cd1e45cfb7d794 | |
parent | c688c0e2b32e29091cb41f2ef425fe3cafa39c19 (diff) | |
parent | 5c88f32139644538542058b07833e3731af7be18 (diff) | |
download | tcl-2ac3c16d405d20153ce0ad43f308ff05bc372f7a.zip tcl-2ac3c16d405d20153ce0ad43f308ff05bc372f7a.tar.gz tcl-2ac3c16d405d20153ce0ad43f308ff05bc372f7a.tar.bz2 |
merge trunk
-rw-r--r-- | generic/tcl.h | 2 | ||||
-rw-r--r-- | generic/tclBasic.c | 39 | ||||
-rw-r--r-- | generic/tclInt.h | 1 | ||||
-rw-r--r-- | tests/namespace.test | 9 |
4 files changed, 40 insertions, 11 deletions
diff --git a/generic/tcl.h b/generic/tcl.h index 4bf81cc..b7237bf 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -191,7 +191,7 @@ extern "C" { * MSVCRT. */ -#if (defined(__WIN32__) && (defined(_MSC_VER) || (__BORLANDC__ >= 0x0550) || defined(__LCC__) || defined(__WATCOMC__) || (defined(__GNUC__) && defined(__declspec)))) +#if (defined(__WIN32__) && (defined(_MSC_VER) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0550)) || defined(__LCC__) || defined(__WATCOMC__) || (defined(__GNUC__) && defined(__declspec)))) # define HAVE_DECLSPEC 1 # ifdef STATIC_BUILD # define DLLIMPORT diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 795fe15..361ed49 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -2087,10 +2087,19 @@ Tcl_CreateCommand( */ cmdPtr = Tcl_GetHashValue(hPtr); - oldRefPtr = cmdPtr->importRefPtr; - cmdPtr->importRefPtr = NULL; + cmdPtr->refCount++; + if (cmdPtr->importRefPtr) { + cmdPtr->flags |= CMD_REDEF_IN_PROGRESS; + } Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr); + + if (cmdPtr->flags & CMD_REDEF_IN_PROGRESS) { + oldRefPtr = cmdPtr->importRefPtr; + cmdPtr->importRefPtr = NULL; + } + TclCleanupCommandMacro(cmdPtr); + hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew); if (!isNew) { /* @@ -2274,10 +2283,19 @@ Tcl_CreateObjCommand( * intact. */ - oldRefPtr = cmdPtr->importRefPtr; - cmdPtr->importRefPtr = NULL; + cmdPtr->refCount++; + if (cmdPtr->importRefPtr) { + cmdPtr->flags |= CMD_REDEF_IN_PROGRESS; + } Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr); + + if (cmdPtr->flags & CMD_REDEF_IN_PROGRESS) { + oldRefPtr = cmdPtr->importRefPtr; + cmdPtr->importRefPtr = NULL; + } + TclCleanupCommandMacro(cmdPtr); + hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew); if (!isNew) { /* @@ -3119,12 +3137,13 @@ Tcl_DeleteCommandFromToken( * commands were created that refer back to this command. Delete these * imported commands now. */ - - for (refPtr = cmdPtr->importRefPtr; refPtr != NULL; - refPtr = nextRefPtr) { - nextRefPtr = refPtr->nextPtr; - importCmd = (Tcl_Command) refPtr->importedCmdPtr; - Tcl_DeleteCommandFromToken(interp, importCmd); + if (!(cmdPtr->flags & CMD_REDEF_IN_PROGRESS)) { + for (refPtr = cmdPtr->importRefPtr; refPtr != NULL; + refPtr = nextRefPtr) { + nextRefPtr = refPtr->nextPtr; + importCmd = (Tcl_Command) refPtr->importedCmdPtr; + Tcl_DeleteCommandFromToken(interp, importCmd); + } } /* diff --git a/generic/tclInt.h b/generic/tclInt.h index 7da0b7f..2aa1725 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -1686,6 +1686,7 @@ typedef struct Command { #define CMD_TRACE_ACTIVE 0x2 #define CMD_HAS_EXEC_TRACES 0x4 #define CMD_COMPILES_EXPANDED 0x8 +#define CMD_REDEF_IN_PROGRESS 0x10 /* *---------------------------------------------------------------- diff --git a/tests/namespace.test b/tests/namespace.test index f6688f1..8c4b81c 100644 --- a/tests/namespace.test +++ b/tests/namespace.test @@ -558,6 +558,15 @@ test namespace-13.1 {DeleteImportedCmd, deletes imported cmds} { lappend l [info commands ::test_ns_import::*] } } {::test_ns_import::cmd1 {}} +test namespace-13.2 {DeleteImportedCmd, Bug a4494e28ed} { + # Will panic if still buggy + namespace eval src {namespace export foo; proc foo {} {}} + namespace eval dst {namespace import [namespace parent]::src::foo} + trace add command src::foo delete \ + "[list namespace delete [namespace current]::dst] ;#" + proc src::foo {} {} + namespace delete src +} {} test namespace-14.1 {TclGetNamespaceForQualName, absolute names} { catch {namespace delete {*}[namespace children :: test_ns_*]} |