Tcl Source Code

Artifact [f288c6bf12]
Login

Artifact f288c6bf1290e8dcf0ea69f2d39d33591e07ad46:

Attachment "trace.diff" to ticket [1693986fff] added by msofer 2007-04-04 09:13:25.
Index: generic/tclBasic.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclBasic.c,v
retrieving revision 1.241
diff -u -r1.241 tclBasic.c
--- generic/tclBasic.c	3 Apr 2007 01:34:35 -0000	1.241
+++ generic/tclBasic.c	4 Apr 2007 02:09:35 -0000
@@ -3404,10 +3404,9 @@
 				 * the words that make up the command. */
     const char *command,	/* Points to the beginning of the string
 				 * representation of the command; this is used
-				 * for traces. If the string representation of
-				 * the command is unknown, an empty string
-				 * should be supplied. If it is NULL, no
-				 * traces will be called. */
+				 * for traces. NULL causes a string
+				 * representation to be computed from
+				 * objc/objv */
     int length,			/* Number of bytes in command; if -1, all
 				 * characters up to the first null byte are
 				 * used. */
@@ -3563,7 +3562,7 @@
      * Call trace functions if needed.
      */
 
-    if (checkTraces && (command != NULL)) {
+    if (checkTraces) {
 	int cmdEpoch = cmdPtr->cmdEpoch;
 	int newEpoch;
 
@@ -3700,37 +3699,11 @@
 				 * currently supported. */
 {
     Interp *iPtr = (Interp *) interp;
-    Trace *tracePtr;
-    Tcl_DString cmdBuf;
-    const char *cmdString = "";	/* A command string is only necessary for
-				 * command traces or error logs; it will be
-				 * generated to replace this default value if
-				 * necessary. */
-    int cmdLen = 0;		/* A non-zero value indicates that a command
-				 * string was generated. */
-    int code = TCL_OK;
-    int i;
+    int code;
     int allowExceptions = (iPtr->evalFlags & TCL_ALLOW_EXCEPTIONS);
 
-    for (tracePtr = iPtr->tracePtr; tracePtr; tracePtr = tracePtr->nextPtr) {
-	if ((tracePtr->level == 0) || (iPtr->numLevels <= tracePtr->level)) {
-	    /*
-	     * The command may be needed for an execution trace. Generate a
-	     * command string.
-	     */
-
-	    Tcl_DStringInit(&cmdBuf);
-	    for (i = 0; i < objc; i++) {
-		Tcl_DStringAppendElement(&cmdBuf, Tcl_GetString(objv[i]));
-	    }
-	    cmdString = Tcl_DStringValue(&cmdBuf);
-	    cmdLen = Tcl_DStringLength(&cmdBuf);
-	    break;
-	}
-    }
-
     iPtr->numLevels++;
-    code = TclEvalObjvInternal(interp, objc, objv, cmdString, cmdLen, flags);
+    code = TclEvalObjvInternal(interp, objc, objv, NULL, 0, flags);
     iPtr->numLevels--;
 
     /*
@@ -3754,20 +3727,16 @@
 	 * error log: generate it now if it was not done previously.
 	 */
 
-	if (cmdLen == 0) {
-	    Tcl_DStringInit(&cmdBuf);
-	    for (i = 0; i < objc; i++) {
-		Tcl_DStringAppendElement(&cmdBuf, Tcl_GetString(objv[i]));
-	    }
-	    cmdString = Tcl_DStringValue(&cmdBuf);
-	    cmdLen = Tcl_DStringLength(&cmdBuf);
-	}
+	Tcl_Obj *listObjPtr;
+	const char *cmdString;
+	int cmdLen;
+
+	listObjPtr = Tcl_NewListObj(objc, objv);
+	cmdString = Tcl_GetStringFromObj(listObjPtr, &cmdLen);
 	Tcl_LogCommandInfo(interp, cmdString, cmdString, cmdLen);
+	Tcl_DecrRefCount(listObjPtr);;
     }
 
-    if (cmdLen != 0) {
-	Tcl_DStringFree(&cmdBuf);
-    }
     return code;
 }
 
Index: generic/tclTrace.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclTrace.c,v
retrieving revision 1.35
diff -u -r1.35 tclTrace.c
--- generic/tclTrace.c	2 Apr 2007 18:48:04 -0000	1.35
+++ generic/tclTrace.c	4 Apr 2007 02:09:37 -0000
@@ -1412,8 +1412,11 @@
     int traceCode = TCL_OK;
     TraceCommandInfo* tcmdPtr;
     Tcl_InterpState state = NULL;
+    Tcl_Obj *commandPtr = NULL;
+    int nulTerminated = (command &&
+	    ((numChars == -1) || (command[numChars] == '\0')));
 
-    if (command == NULL || cmdPtr->tracePtr == NULL) {
+    if (cmdPtr->tracePtr == NULL) {
 	return traceCode;
     }
 
@@ -1452,6 +1455,25 @@
 		if (state == NULL) {
 		    state = Tcl_SaveInterpState(interp, code);
 		}
+
+		/*
+		 * Insure that we have a nul-terminated 'command' string
+		 */
+
+		if (nulTerminated) {
+		    if (numChars == -1) {
+			numChars = strlen(command);
+		    }
+		} else if (command) {
+		    commandPtr = Tcl_NewStringObj(command, numChars);
+		    command = Tcl_GetString(commandPtr);
+		    nulTerminated = 1;
+		} else {
+		    commandPtr = Tcl_NewListObj(objc, objv);
+		    command = Tcl_GetStringFromObj(commandPtr, &numChars);
+		    nulTerminated = 1;
+		}
+		
 		traceCode = TraceExecutionProc((ClientData)tcmdPtr, interp,
 			curLevel, command, (Tcl_Command)cmdPtr, objc, objv);
 		if ((--tcmdPtr->refCount) <= 0) {
@@ -1467,6 +1489,10 @@
     if (state) {
 	(void) Tcl_RestoreInterpState(interp, state);
     }
+
+    if (commandPtr) {
+	Tcl_DecrRefCount(commandPtr);
+    }
     return(traceCode);
 }
 
@@ -1512,8 +1538,11 @@
     int curLevel;
     int traceCode = TCL_OK;
     Tcl_InterpState state = NULL;
+    Tcl_Obj *commandPtr = NULL;
+    int nulTerminated = (command &&
+	    ((numChars == -1) || (command[numChars] == '\0')));
 
-    if (command == NULL || iPtr->tracePtr == NULL
+    if ((iPtr->tracePtr == NULL)
 	    || (iPtr->flags & INTERP_TRACE_IN_PROGRESS)) {
 	return(traceCode);
     }
@@ -1568,6 +1597,24 @@
 		state = Tcl_SaveInterpState(interp, code);
 	    }
 
+	    /*
+	     * Insure that we have a nul-terminated 'command' string
+	     */
+
+	    if (nulTerminated) {
+		if (numChars == -1) {
+		    numChars = strlen(command);
+		}
+	    } else if (command) {
+		commandPtr = Tcl_NewStringObj(command, numChars);
+		command = Tcl_GetString(commandPtr);
+		nulTerminated = 1;
+	    } else {
+		commandPtr = Tcl_NewListObj(objc, objv);
+		command = Tcl_GetStringFromObj(commandPtr, &numChars);
+		nulTerminated = 1;
+	    }
+	    
 	    if (tracePtr->flags &
 		    (TCL_TRACE_ENTER_EXEC | TCL_TRACE_LEAVE_EXEC)) {
 		/*
@@ -1615,6 +1662,10 @@
 	    Tcl_DiscardInterpState(state);
 	}
     }
+
+    if (commandPtr) {
+	Tcl_DecrRefCount(commandPtr);
+    } 
     return(traceCode);
 }