From 0c315e1f78e0a6ea716ec52e58542a2eb6472a8e Mon Sep 17 00:00:00 2001 From: avl Date: Wed, 7 Jun 2017 09:24:40 +0000 Subject: bug-716b427f76 branch continued. --- generic/tclStringObj.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index aae52ba..d85bd30 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -2884,6 +2884,9 @@ TclStringCatObjv( /* Prevent shimmer of non-string types. */ allowUniChar = 0; } + } else { + /* if so-far-first is empty string, then skip it */ + if (first+oc == objc) { first++; } } } else { /* assert (objPtr->typePtr != NULL) -- stork! */ @@ -2902,9 +2905,30 @@ TclStringCatObjv( } } while (--oc && (binary || allowUniChar)); - if (binary) { + /* + * Trim easily recognizable empty strings from end. + * Note: oc might already be 0 before the loop. + */ + ov = objv + objc; oc = objc - first; + while (oc) { + objPtr = *(--ov); --oc; + if (objPtr->bytes && objPtr->length==0) { + objc--; + } + } + + /* Don't update objv, yet: we may still need it */ + ov = objv + first; oc = objc - first; + + if (oc <= 1) { + if (oc == 0) { + /* all operands were empty strings; use first one */ + first = 0; /* last = 0, anyway */ + } else { + last = first; + } + } else if (binary) { /* Result will be pure byte array. Pre-size it */ - ov = objv; oc = objc; do { objPtr = *ov++; @@ -2925,7 +2949,6 @@ TclStringCatObjv( } while (--oc); } else if (allowUniChar && requestUniChar) { /* Result will be pure Tcl_UniChar array. Pre-size it. */ - ov = objv; oc = objc; do { objPtr = *ov++; @@ -2946,7 +2969,6 @@ TclStringCatObjv( } while (--oc); } else { /* Result will be concat of string reps. Pre-size it. */ - ov = objv; oc = objc; do { int numBytes; -- cgit v0.12