From: Paul Eggert Date: Sun, 27 Aug 2023 06:19:12 +0000 (-0700) Subject: trim: do not over-allocate result X-Git-Tag: v1.0~857 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=5f27affb42337dc605a9a59f1c6a99516cd9747a;p=gnulib.git trim: do not over-allocate result * lib/trim.c: Include mbuiterf.h, not mbiterf.h, since we no longer compute strlen at first. (trim2): Do not over-allocate result and then trim the parts we don’t want. Instead, skip unwanted input before allocating, so that the result is just the right size. Use mempcpy instead of memmove. Simplify. * modules/trim (Depends-on): Remove mbiterf, memmove, strdup, xalloc. Add mbuiterf, mempcpy, xalloc-die. --- diff --git a/ChangeLog b/ChangeLog index 64db236853..5c858366d5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2023-08-26 Paul Eggert + + trim: do not over-allocate result + * lib/trim.c: Include mbuiterf.h, not mbiterf.h, since we no + longer compute strlen at first. + (trim2): Do not over-allocate result and then trim the parts we + don’t want. Instead, skip unwanted input before allocating, + so that the result is just the right size. Use mempcpy + instead of memmove. Simplify. + * modules/trim (Depends-on): Remove mbiterf, memmove, strdup, xalloc. + Add mbuiterf, mempcpy, xalloc-die. + 2023-08-26 Paul Eggert propername: tune single-byte code diff --git a/lib/trim.c b/lib/trim.c index 23ee5a2e2d..8ebbc29658 100644 --- a/lib/trim.c +++ b/lib/trim.c @@ -27,88 +27,61 @@ #include #include "mbchar.h" -#include "mbiterf.h" +#include "mbuiterf.h" #include "xalloc.h" char * trim2 (const char *s, int how) { - char *d; - - d = strdup (s); - - if (!d) - xalloc_die (); + const char *start = s; + const char *end; if (MB_CUR_MAX > 1) { - /* Trim leading whitespaces. */ - if (how != TRIM_TRAILING) - { - const char *d_end = d + strlen (d); - mbif_state_t state; - char *iter; - for (mbif_init (state), iter = d; mbif_avail (state, iter, d_end); ) - { - mbchar_t cur = mbif_next (state, iter, d_end); + mbuif_state_t state; + mbuif_init (state); - if (!mb_isspace (cur)) - break; - - iter += mb_len (cur); - } - - memmove (d, iter, strlen (iter) + 1); - } - - /* Trim trailing whitespaces. */ + /* Skip leading whitespace. */ + if (how != TRIM_TRAILING) + while (mbuif_avail (state, start)) + { + mbchar_t cur = mbuif_next (state, start); + if (!mb_isspace (cur)) + break; + start += mb_len (cur); + } + + /* Find start of any trailing whitespace. */ if (how != TRIM_LEADING) - { - char *start_of_spaces = NULL; - - const char *d_end = d + strlen (d); - mbif_state_t state; - char *iter; - for (mbif_init (state), iter = d; mbif_avail (state, iter, d_end); ) - { - mbchar_t cur = mbif_next (state, iter, d_end); - - if (mb_isspace (cur)) - { - if (start_of_spaces == NULL) - start_of_spaces = iter; - } - else - start_of_spaces = NULL; - - iter += mb_len (cur); - } - - if (start_of_spaces != NULL) - *start_of_spaces = '\0'; - } + for (const char *p = end = start; mbuif_avail (state, p); ) + { + mbchar_t cur = mbuif_next (state, p); + p += mb_len (cur); + if (!mb_isspace (cur)) + end = p; + } } else { - char *p; - - /* Trim leading whitespaces. */ + /* Skip leading whitespace. */ if (how != TRIM_TRAILING) - { - for (p = d; *p && isspace ((unsigned char) *p); p++) - ; + while (isspace ((unsigned char) *start)) + start++; - memmove (d, p, strlen (p) + 1); - } - - /* Trim trailing whitespaces. */ + /* Find start of any trailing whitespace. */ if (how != TRIM_LEADING) - { - for (p = d + strlen (d) - 1; - p >= d && isspace ((unsigned char) *p); p--) - *p = '\0'; - } + for (const char *p = end = start; *p; ) + if (!isspace ((unsigned char) *p++)) + end = p; } + /* Create trimmed copy. */ + size_t dlen = how == TRIM_LEADING ? strlen (start) : end - start; + char *d = malloc (dlen + 1); + if (!d) + xalloc_die (); + char *d_end = mempcpy (d, start, dlen); + *d_end = '\0'; + return d; } diff --git a/modules/trim b/modules/trim index 90f553076a..9f45dade80 100644 --- a/modules/trim +++ b/modules/trim @@ -6,11 +6,10 @@ lib/trim.h lib/trim.c Depends-on: -xalloc mbchar -mbiterf -memmove -strdup +mbuiterf +mempcpy +xalloc-die configure.ac: