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
}
/*