Tcl Source Code

Artifact [cd1fafea91]
Login

Artifact cd1fafea91e87a7bf5b59801e16f95a023fbeb23:

Attachment "undo.patch" to ticket [1041072fff] added by dgp 2004-11-18 06:08:00.
Index: generic/tclResult.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclResult.c,v
retrieving revision 1.22
diff -u -r1.22 tclResult.c
--- generic/tclResult.c	13 Nov 2004 00:19:10 -0000	1.22
+++ generic/tclResult.c	17 Nov 2004 22:38:58 -0000
@@ -617,23 +617,92 @@
  */
 
 void
-Tcl_AppendResultVA(interp, argList)
+Tcl_AppendResultVA (interp, argList)
     Tcl_Interp *interp;		/* Interpreter with which to associate the
 				 * return value. */
     va_list argList;		/* Variable argument list. */
 {
-    Tcl_Obj *objPtr = Tcl_GetObjResult(interp);
+#define STATIC_LIST_SIZE 16
+    Interp *iPtr = (Interp *) interp;
+    char *string, *static_list[STATIC_LIST_SIZE];
+    char **args = static_list;
+    int nargs_space = STATIC_LIST_SIZE;
+    int nargs, newSpace, i;
 
-    if (Tcl_IsShared(objPtr)) {
-	objPtr = Tcl_DuplicateObj(objPtr);
+    /*
+     * If the string result is empty, move the object result to the
+     * string result, then reset the object result.
+     */
+
+    if (*(iPtr->result) == 0) {
+	Tcl_SetResult((Tcl_Interp *) iPtr,
+	        TclGetString(Tcl_GetObjResult((Tcl_Interp *) iPtr)),
+	        TCL_VOLATILE);
     }
-    Tcl_AppendStringsToObjVA(objPtr, argList);
-    Tcl_SetObjResult(interp, objPtr);
+    
     /*
-     * Ensure that the interp->result is legal so old Tcl 7.* code
-     * still works. There's still embarrasingly much of it about...
+     * Scan through all the arguments to see how much space is needed
+     * and save pointers to the arguments in the args array,
+     * reallocating as necessary.
      */
-    (void) Tcl_GetStringResult(interp);
+
+    nargs = 0;
+    newSpace = 0;
+    while (1) {
+ 	string = va_arg(argList, char *);
+	if (string == NULL) {
+	    break;
+	}
+ 	if (nargs >= nargs_space) {
+ 	    /* 
+ 	     * Expand the args buffer
+ 	     */
+ 	    nargs_space += STATIC_LIST_SIZE;
+ 	    if (args == static_list) {
+ 	    	args = (void *)ckalloc(nargs_space * sizeof(char *));
+ 		for (i = 0; i < nargs; ++i) {
+ 		    args[i] = static_list[i];
+ 		}
+ 	    } else {
+ 		args = (void *)ckrealloc((void *)args,
+			nargs_space * sizeof(char *));
+ 	    }
+ 	}
+  	newSpace += strlen(string);
+	args[nargs++] = string;
+    }
+
+    /*
+     * If the append buffer isn't already setup and large enough to hold
+     * the new data, set it up.
+     */
+
+    if ((iPtr->result != iPtr->appendResult)
+	    || (iPtr->appendResult[iPtr->appendUsed] != 0)
+	    || ((newSpace + iPtr->appendUsed) >= iPtr->appendAvl)) {
+       SetupAppendBuffer(iPtr, newSpace);
+    }
+
+    /*
+     * Now go through all the argument strings again, copying them into the
+     * buffer.
+     */
+
+    for (i = 0; i < nargs; ++i) {
+ 	string = args[i];
+  	strcpy(iPtr->appendResult + iPtr->appendUsed, string);
+  	iPtr->appendUsed += strlen(string);
+    }
+ 
+    /*
+     * If we had to allocate a buffer from the heap, 
+     * free it now.
+     */
+ 
+    if (args != static_list) {
+     	ckfree((void *)args);
+    }
+#undef STATIC_LIST_SIZE
 }
 
 /*