Attachment "binconcat.patch" to
ticket [1953758fff]
added by
ferrieux
2008-04-29 06:47:35.
--- tcl8.5.1-orig/generic/tclExecute.c Mon Feb 4 20:24:55 2008
+++ tcl8.5.1/generic/tclExecute.c Mon Apr 28 23:28:47 2008
@@ -2020,19 +2020,42 @@
int opnd, length, appendLen = 0;
char *bytes, *p;
Tcl_Obj **currPtr;
+ int onlyb ;
opnd = TclGetUInt1AtPtr(pc+1);
/*
+ * Detect only-bytearray-or-null case
+ */
+ onlyb = 1;
+ for (currPtr=&OBJ_AT_DEPTH(opnd-1); currPtr<=&OBJ_AT_TOS; currPtr++) {
+ if (((*currPtr)->typePtr != &tclByteArrayType)
+ &&((*currPtr)->bytes != tclEmptyStringRep))
+ {onlyb=0;break;}
+ }
+
+ /*
* Compute the length to be appended.
*/
+ if (onlyb)
+ {
+ for (currPtr=&OBJ_AT_DEPTH(opnd-2); currPtr<=&OBJ_AT_TOS; currPtr++) {
+ if ((*currPtr)->bytes == tclEmptyStringRep)
+ continue; /* don't shimmer nulls */
+ Tcl_GetByteArrayFromObj(*currPtr, &length);
+ appendLen += length;
+ }
+ }
+ else
+ {
for (currPtr=&OBJ_AT_DEPTH(opnd-2); currPtr<=&OBJ_AT_TOS; currPtr++) {
bytes = TclGetStringFromObj(*currPtr, &length);
if (bytes != NULL) {
appendLen += length;
}
}
+ }
/*
* If nothing is to be appended, just return the first object by
@@ -2056,6 +2079,8 @@
*/
objResultPtr = OBJ_AT_DEPTH(opnd-1);
+ if (!onlyb)
+ {
bytes = TclGetStringFromObj(objResultPtr, &length);
#if !TCL_COMPILE_DEBUG
if (bytes != tclEmptyStringRep && !Tcl_IsShared(objResultPtr)) {
@@ -2088,6 +2113,37 @@
}
}
*p = '\0';
+
+ } else {
+
+ bytes = Tcl_GetByteArrayFromObj(objResultPtr, &length);
+#if !TCL_COMPILE_DEBUG
+ if (!Tcl_IsShared(objResultPtr)) {
+ bytes = Tcl_SetByteArrayLength(objResultPtr,length+appendLen);
+ p = bytes + length;
+ currPtr = &OBJ_AT_DEPTH(opnd - 2);
+ } else {
+#endif
+ TclNewObj(objResultPtr);
+ bytes = Tcl_SetByteArrayLength(objResultPtr,length+appendLen);
+ p = bytes;
+ currPtr = &OBJ_AT_DEPTH(opnd - 1);
+#if !TCL_COMPILE_DEBUG
+ }
+#endif
+
+ /*
+ * Append the remaining characters.
+ */
+
+ for (; currPtr <= &OBJ_AT_TOS; currPtr++) {
+ if ((*currPtr)->bytes == tclEmptyStringRep)
+ continue; /* don't shimmer nulls */
+ bytes = Tcl_GetByteArrayFromObj(*currPtr, &length);
+ memcpy(p, bytes, (size_t) length);
+ p += length;
+ }
+ }
TRACE_WITH_OBJ(("%u => ", opnd), objResultPtr);
NEXT_INST_V(2, opnd, 1);