summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhobbs <hobbs>2000-09-06 18:31:36 (GMT)
committerhobbs <hobbs>2000-09-06 18:31:36 (GMT)
commit33815286906fe7cce72acba259c0e810eb4cccb6 (patch)
tree570b5ee446672824397aecae434438db4149bc20
parentf27975a82da0d3457defda9dc6f274fdda29df98 (diff)
downloadtcl-33815286906fe7cce72acba259c0e810eb4cccb6.zip
tcl-33815286906fe7cce72acba259c0e810eb4cccb6.tar.gz
tcl-33815286906fe7cce72acba259c0e810eb4cccb6.tar.bz2
* generic/tclCmdMZ.c (Tcl_StringObjCmd): changed STR_REPEAT to
preallocate the full space of the final string, avoided repeated appends.
-rw-r--r--generic/tclCmdMZ.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c
index 2421158..9fa3166 100644
--- a/generic/tclCmdMZ.c
+++ b/generic/tclCmdMZ.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: tclCmdMZ.c,v 1.28 2000/08/25 02:04:28 ericm Exp $
+ * RCS: @(#) $Id: tclCmdMZ.c,v 1.29 2000/09/06 18:31:36 hobbs Exp $
*/
#include "tclInt.h"
@@ -1826,10 +1826,35 @@ Tcl_StringObjCmd(dummy, interp, objc, objv)
return TCL_ERROR;
}
- string1 = Tcl_GetStringFromObj(objv[2], &length1);
- if (length1 > 0) {
- for (index = 0; index < count; index++) {
- Tcl_AppendToObj(resultPtr, string1, length1);
+ if (count == 1) {
+ Tcl_SetObjResult(interp, objv[2]);
+ } else if (count > 1) {
+ string1 = Tcl_GetStringFromObj(objv[2], &length1);
+ if (length1 > 0) {
+ /*
+ * Only build up a string that has data. Instead of
+ * building it up with repeated appends, we just allocate
+ * the necessary space once and copy the string value in.
+ */
+ length2 = length1 * count;
+ /*
+ * Include space for the NULL
+ */
+ string2 = (char *) ckalloc((size_t) length2+1);
+ for (index = 0; index < count; index++) {
+ memcpy(string2 + (length1 * index), string1,
+ (size_t) length1);
+ }
+ string2[length2] = '\0';
+ /*
+ * We have to directly assign this instead of using
+ * Tcl_SetStringObj (and indirectly TclInitStringRep)
+ * because that makes another copy of the data.
+ */
+ resultPtr = Tcl_NewObj();
+ resultPtr->bytes = string2;
+ resultPtr->length = length2;
+ Tcl_SetObjResult(interp, resultPtr);
}
}
break;