diff options
| author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2017-11-13 11:47:41 (GMT) |
|---|---|---|
| committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2017-11-13 11:47:41 (GMT) |
| commit | 7cfe36d9aeab32aedade8e127e6d93da817e9707 (patch) | |
| tree | e463a477ff360e0a112a9452647e9d4403b8a434 /generic/tclStringObj.c | |
| parent | 1152be81e65a9a99a71c5e386ee59aee7d0c670c (diff) | |
| parent | 1ce0780915bbebd576e579a400b6b4f37a924529 (diff) | |
| download | tcl-7cfe36d9aeab32aedade8e127e6d93da817e9707.zip tcl-7cfe36d9aeab32aedade8e127e6d93da817e9707.tar.gz tcl-7cfe36d9aeab32aedade8e127e6d93da817e9707.tar.bz2 | |
merge novem
Diffstat (limited to 'generic/tclStringObj.c')
| -rw-r--r-- | generic/tclStringObj.c | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index d607c1d..336b2be 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -3079,6 +3079,7 @@ TclStringCatObjv( /* Ugly interface! No scheme to init array size. */ objResultPtr = Tcl_NewUnicodeObj(&ch, 0); /* PANIC? */ if (0 == Tcl_AttemptSetObjLength(objResultPtr, length)) { + Tcl_DecrRefCount(objResultPtr); if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "concatenation failed: unable to alloc %" @@ -3126,6 +3127,7 @@ TclStringCatObjv( } else { objResultPtr = Tcl_NewObj(); /* PANIC? */ if (0 == Tcl_AttemptSetObjLength(objResultPtr, length)) { + Tcl_DecrRefCount(objResultPtr); if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "concatenation failed: unable to alloc %u bytes", @@ -3217,40 +3219,44 @@ TclStringFind( return -1; } + /* + * Check if we have two strings of single-byte characters. If we have, we + * can use strstr() to do the search. Note that we can sometimes have + * multibyte characters when the string could be minimally represented + * using single byte characters; we can't assume that a mismatch here + * means no match. + */ + lh = Tcl_GetCharLength(haystack); - if (haystack->bytes && ((size_t)lh == haystack->length)) { - /* haystack is all single-byte chars */ + if (haystack->bytes && ((size_t)lh == haystack->length) && needle->bytes + && ((size_t)ln == needle->length)) { + /* + * Both haystack and needle are all single-byte chars. + */ - if (needle->bytes && ((size_t)ln == needle->length)) { - /* needle is also all single-byte chars */ - char *found = strstr(haystack->bytes + start, needle->bytes); + char *found = strstr(haystack->bytes + start, needle->bytes); - if (found) { - return (found - haystack->bytes); - } else { - return -1; - } + if (found) { + return (found - haystack->bytes); } else { - /* - * Cannot find substring with a multi-byte char inside - * a string with no multi-byte chars. - */ return -1; } } else { + /* + * Do the search on the unicode representation for simplicity. + */ + Tcl_UniChar *try, *end, *uh; Tcl_UniChar *un = Tcl_GetUnicodeFromObj(needle, &ln); uh = Tcl_GetUnicodeFromObj(haystack, &lh); end = uh + lh; - try = uh + start; - while (try + ln <= end) { - if ((*try == *un) - && (0 == memcmp(try+1, un+1, (ln-1)*sizeof(Tcl_UniChar)))) { + for (try = uh + start; try + ln <= end; try++) { + if ((*try == *un) && (0 == + memcmp(try + 1, un + 1, (ln-1) * sizeof(Tcl_UniChar)))) { return (try - uh); } - try++; } return -1; } @@ -3433,7 +3439,6 @@ TclStringObjReverse( * Tcl_SetObjLength into growing the unicode rep buffer. */ - ch = 0; objPtr = Tcl_NewUnicodeObj(&ch, 1); Tcl_SetObjLength(objPtr, stringPtr->numChars); to = Tcl_GetUnicode(objPtr); @@ -3536,7 +3541,7 @@ ExtendUnicodeRepWithString( { String *stringPtr = GET_STRING(objPtr); size_t needed, numOrigChars = 0; - Tcl_UniChar *dst; + Tcl_UniChar *dst, unichar = 0; if (stringPtr->hasUnicode) { numOrigChars = stringPtr->numChars; @@ -3559,7 +3564,8 @@ ExtendUnicodeRepWithString( numAppendChars = 0; } for (dst=stringPtr->unicode + numOrigChars; numAppendChars-- > 0; dst++) { - bytes += TclUtfToUniChar(bytes, dst); + bytes += TclUtfToUniChar(bytes, &unichar); + *dst = unichar; } *dst = 0; } |
