summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2020-04-13 14:21:09 (GMT)
committerdgp <dgp@users.sourceforge.net>2020-04-13 14:21:09 (GMT)
commit5ca0fff784edcbd2b7eabe15c8aa7ed414ca12f2 (patch)
tree960b03d06f48b343c95e4f85e9c5431e0844ed0a
parent787517aa7fc113fcd554b0da726b0ba74585812b (diff)
downloadtcl-5ca0fff784edcbd2b7eabe15c8aa7ed414ca12f2.zip
tcl-5ca0fff784edcbd2b7eabe15c8aa7ed414ca12f2.tar.gz
tcl-5ca0fff784edcbd2b7eabe15c8aa7ed414ca12f2.tar.bz2
TclTrim() can also demand NUL-terminated arguments, and be simplified.
-rw-r--r--generic/tclUtil.c85
1 files changed, 21 insertions, 64 deletions
diff --git a/generic/tclUtil.c b/generic/tclUtil.c
index b6eebdc..82ef9b7 100644
--- a/generic/tclUtil.c
+++ b/generic/tclUtil.c
@@ -1516,42 +1516,6 @@ Tcl_Backslash(
/*
*----------------------------------------------------------------------
*
- * UtfWellFormedEnd --
- * Checks the end of utf string is malformed, if yes - wraps bytes
- * to the given buffer (as well-formed NTS string). The buffer
- * argument should be initialized by the caller and ready to use.
- *
- * Results:
- * The bytes with well-formed end of the string.
- *
- * Side effects:
- * Buffer (DString) may be allocated, so must be released.
- *
- *----------------------------------------------------------------------
- */
-
-static inline const char*
-UtfWellFormedEnd(
- Tcl_DString *buffer, /* Buffer used to hold well-formed string. */
- CONST char *bytes, /* Pointer to the beginning of the string. */
- int length) /* Length of the string. */
-{
- CONST char *l = bytes + length;
- CONST char *p = Tcl_UtfPrev(l, bytes);
-
- if (Tcl_UtfCharComplete(p, l - p)) {
- return bytes;
- }
- /*
- * Malformed utf-8 end, be sure we've NTS to safe compare of end-character,
- * avoid segfault by access violation out of range.
- */
- Tcl_DStringAppend(buffer, bytes, length);
- return Tcl_DStringValue(buffer);
-}
-/*
- *----------------------------------------------------------------------
- *
* TclTrimRight --
* Takes two counted strings in the Tcl encoding. Conceptually
* finds the sub string (offset) to trim from the right side of the
@@ -1712,39 +1676,32 @@ TclTrim(
int numTrim, /* ...and its length in bytes */
/* Calls in this routine
* rely on (trim[numTrim] == '\0'). */
- int *trimRight) /* Offset from the end of the string. */
+ int *trimRightPtr) /* Offset from the end of the string. */
{
- int trimLeft;
- Tcl_DString bytesBuf, trimBuf;
+ int trimLeft = 0, trimRight = 0;
- *trimRight = 0;
/* Empty strings -> nothing to do */
- if ((numBytes == 0) || (numTrim == 0)) {
- return 0;
- }
-
- Tcl_DStringInit(&bytesBuf);
- Tcl_DStringInit(&trimBuf);
- bytes = UtfWellFormedEnd(&bytesBuf, bytes, numBytes);
- trim = UtfWellFormedEnd(&trimBuf, trim, numTrim);
-
- trimLeft = TclTrimLeft(bytes, numBytes, trim, numTrim);
- if (trimLeft > numBytes) {
- trimLeft = numBytes;
- }
- numBytes -= trimLeft;
- /* have to trim yet (first char was already verified within TrimLeft) */
- if (numBytes > 1) {
- bytes += trimLeft;
- *trimRight = TclTrimRight(bytes, numBytes, trim, numTrim);
- if (*trimRight > numBytes) {
- *trimRight = numBytes;
+ if ((numBytes > 0) && (numTrim > 0)) {
+
+ /* When bytes is NUL-terminated, returns 0 <= trimLeft <= numBytes */
+ trimLeft = TclTrimLeft(bytes, numBytes, trim, numTrim);
+ numBytes -= trimLeft;
+
+ /* If we did not trim the whole string, it starts with a character
+ * that we will not trim. Skip over it. */
+ if (numBytes > 0) {
+ const char *first = bytes + trimLeft;
+ bytes = Tcl_UtfNext(first);
+ numBytes -= (bytes - first);
+
+ if (numBytes > 0) {
+ /* When bytes is NUL-terminated, returns
+ * 0 <= trimRight <= numBytes */
+ trimRight = TclTrimRight(bytes, numBytes, trim, numTrim);
+ }
}
}
-
- Tcl_DStringFree(&bytesBuf);
- Tcl_DStringFree(&trimBuf);
-
+ *trimRightPtr = trimRight;
return trimLeft;
}