diff options
Diffstat (limited to 'generic/tclBasic.c')
-rw-r--r-- | generic/tclBasic.c | 55 |
1 files changed, 52 insertions, 3 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 760a92c..3f7c983 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -13,7 +13,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclBasic.c,v 1.262 2007/06/29 03:16:01 das Exp $ + * RCS: @(#) $Id: tclBasic.c,v 1.263 2007/07/24 03:05:53 msofer Exp $ */ #include "tclInt.h" @@ -54,6 +54,8 @@ static char * CallCommandTraces(Interp *iPtr, Command *cmdPtr, static int CheckDoubleResult(Tcl_Interp *interp, double dResult); static void DeleteInterpProc(Tcl_Interp *interp); static void DeleteOpCmdClientData(ClientData clientData); +static Tcl_Obj *GetCommandSource(Interp *iPtr, const char *command, + int numChars, int objc, Tcl_Obj *const objv[]); static void ProcessUnexpectedResult(Tcl_Interp *interp, int returnCode); static int OldMathFuncProc(ClientData clientData, Tcl_Interp *interp, int argc, Tcl_Obj *const *objv); @@ -2863,6 +2865,40 @@ CallCommandTraces( Tcl_Release((ClientData) iPtr); return result; } + +/* + *---------------------------------------------------------------------- + * + * GetCommandSource -- + * + * This function returns a Tcl_Obj with the full source string for the + * command. This insures that traces get a correct nul-terminated command + * string. + * + */ + +static Tcl_Obj * +GetCommandSource( + Interp *iPtr, + const char *command, + int numChars, + int objc, + Tcl_Obj *const objv[]) +{ + Tcl_Obj *commandPtr; + + if (!command) { + commandPtr = Tcl_NewListObj(objc, objv); + } else { + if (command == (char *) -1) { + command = TclGetSrcInfoForCmd(iPtr, &numChars); + } + commandPtr = Tcl_NewStringObj(command, numChars); + } + + return commandPtr; +} + /* *---------------------------------------------------------------------- @@ -3358,7 +3394,9 @@ TclEvalObjvInternal( * representation of the command; this is used * for traces. NULL if the string * representation of the command is unknown is - * to be generated from (objc,objv).*/ + * to be generated from (objc,objv), -1 if it + * is to be generated from bytecode + * source. This is only needed the traces. */ int length, /* Number of bytes in command; if -1, all * characters up to the first null byte are * used. */ @@ -3378,7 +3416,7 @@ TclEvalObjvInternal( int checkTraces = 1, traced; Namespace *savedNsPtr = NULL; Namespace *lookupNsPtr = iPtr->lookupNsPtr; - + Tcl_Obj *commandPtr = NULL; if (TclInterpReady(interp) == TCL_ERROR) { return TCL_ERROR; @@ -3449,6 +3487,14 @@ TclEvalObjvInternal( int newEpoch; /* + * Insure that we have a correct nul-terminated command string for the + * trace code. + */ + + commandPtr = GetCommandSource(iPtr, command, length, objc, objv); + command = Tcl_GetStringFromObj(commandPtr, &length); + + /* * Execute any command or execution traces. Note that we bump up the * command's reference count for the duration of the calling of the * traces so that the structure doesn't go away underneath our feet. @@ -3521,6 +3567,9 @@ TclEvalObjvInternal( if (traceCode != TCL_OK) { code = traceCode; } + if (commandPtr) { + Tcl_DecrRefCount(commandPtr); + } } /* |