diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2021-02-16 12:00:21 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2021-02-16 12:00:21 (GMT) |
commit | bb836a307116d682cb08f1cec66271cd3b0ce6b6 (patch) | |
tree | e555a98eb8a2b06d31f900cfd2e655bb0548dd17 /generic | |
parent | 635b0327a6edcdd57f406ec19bf6f3659756c2ce (diff) | |
parent | 999decddb383b6dbe467570cb9e3997a48286fa2 (diff) | |
download | tcl-bb836a307116d682cb08f1cec66271cd3b0ce6b6.zip tcl-bb836a307116d682cb08f1cec66271cd3b0ce6b6.tar.gz tcl-bb836a307116d682cb08f1cec66271cd3b0ce6b6.tar.bz2 |
Merge 8.6
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tclStringObj.c | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 50b473a..0777018 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -3809,6 +3809,9 @@ TclStringReverse( String *stringPtr; Tcl_UniChar ch = 0; int inPlace = flags & TCL_STRING_IN_PLACE; +#if TCL_UTF_MAX < 4 + int needFlip = 0; +#endif if (TclIsPureByteArray(objPtr)) { int numBytes; @@ -3827,10 +3830,9 @@ TclStringReverse( if (stringPtr->hasUnicode) { Tcl_UniChar *from = Tcl_GetUnicode(objPtr); Tcl_UniChar *src = from + stringPtr->numChars; + Tcl_UniChar *to; if (!inPlace || Tcl_IsShared(objPtr)) { - Tcl_UniChar *to; - /* * Create a non-empty, pure unicode value, so we can coax * Tcl_SetObjLength into growing the unicode rep buffer. @@ -3840,19 +3842,54 @@ TclStringReverse( Tcl_SetObjLength(objPtr, stringPtr->numChars); to = Tcl_GetUnicode(objPtr); while (--src >= from) { +#if TCL_UTF_MAX < 4 + ch = *src; + if ((ch & 0xF800) == 0xD800) { + needFlip = 1; + } + *to++ = ch; +#else *to++ = *src; +#endif } } else { /* * Reversing in place. */ +#if TCL_UTF_MAX < 4 + to = src; +#endif while (--src > from) { ch = *src; +#if TCL_UTF_MAX < 4 + if ((ch & 0xF800) == 0xD800) { + needFlip = 1; + } +#endif *src = *from; *from++ = ch; } } +#if TCL_UTF_MAX < 4 + if (needFlip) { + /* + * Flip back surrogate pairs. + */ + + from = to - stringPtr->numChars; + while (--to >= from) { + ch = *to; + if ((ch & 0xFC00) == 0xD800) { + if ((to-1 >= from) && ((to[-1] & 0xFC00) == 0xDC00)) { + to[0] = to[-1]; + to[-1] = ch; + --to; + } + } + } + } +#endif } if (objPtr->bytes) { @@ -3876,8 +3913,8 @@ TclStringReverse( * Pass 1. Reverse the bytes of each multi-byte character. */ - int charCount = 0; int bytesLeft = numBytes; + int chw; while (bytesLeft) { /* @@ -3886,18 +3923,16 @@ TclStringReverse( * skip calling Tcl_UtfCharComplete() here. */ - int bytesInChar = TclUtfToUniChar(from, &ch); + int bytesInChar = TclUtfToUCS4(from, &chw); ReverseBytes((unsigned char *)to, (unsigned char *)from, bytesInChar); to += bytesInChar; from += bytesInChar; bytesLeft -= bytesInChar; - charCount++; } from = to = objPtr->bytes; - stringPtr->numChars = charCount; } /* Pass 2. Reverse all the bytes. */ ReverseBytes((unsigned char *)to, (unsigned char *)from, numBytes); |