]> Savannah Git Hosting - gnulib.git/commitdiff
trim: do not over-allocate result
authorPaul Eggert <eggert@cs.ucla.edu>
Sun, 27 Aug 2023 06:19:12 +0000 (23:19 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sun, 27 Aug 2023 06:34:02 +0000 (23:34 -0700)
* 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.

ChangeLog
lib/trim.c
modules/trim

index 64db236853b4740f2cdfa6fef2e47fb18e92b860..5c858366d559ae3c6a20db50d10343dcc8628401 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2023-08-26  Paul Eggert  <eggert@cs.ucla.edu>
+
+       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  <eggert@cs.ucla.edu>
 
        propername: tune single-byte code
index 23ee5a2e2d05fc46f2c028252d4def58440c4f31..8ebbc296580db698f9f32e60b338fa4f8035b957 100644 (file)
 #include <stdlib.h>
 
 #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;
 }
index 90f553076a4895a381ffce744e3ce26be347f1c4..9f45dade80edef748e9c23f8bad5c0387be78b3a 100644 (file)
@@ -6,11 +6,10 @@ lib/trim.h
 lib/trim.c
 
 Depends-on:
-xalloc
 mbchar
-mbiterf
-memmove
-strdup
+mbuiterf
+mempcpy
+xalloc-die
 
 configure.ac: