]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lib/strutils: improve normalize_whitespace()
authorKarel Zak <kzak@redhat.com>
Mon, 14 Jun 2021 14:24:59 +0000 (16:24 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 14 Jun 2021 14:24:59 +0000 (16:24 +0200)
Let's make it possible to use the function to normalize the string
between two buffers (from source to destination).

Signed-off-by: Karel Zak <kzak@redhat.com>
include/strutils.h
lib/strutils.c

index 7969a84d0ccaa357f0fc34aa26e77d134c5ce650..a62f724933822e23b7cfd14f10245b118e9751fd 100644 (file)
@@ -315,16 +315,20 @@ static inline size_t ltrim_whitespace(unsigned char *str)
 
 /* Removes left-hand, right-hand and repeating whitespaces.
  */
-static inline size_t normalize_whitespace(unsigned char *str)
+static inline size_t __normalize_whitespace(
+                               const unsigned char *src,
+                               size_t sz,
+                               unsigned char *dst,
+                               size_t len)
 {
-       size_t i, x, sz = strlen((char *) str);
+       size_t i, x = 0;
        int nsp = 0, intext = 0;
 
        if (!sz)
-               return 0;
+               goto done;
 
-       for (i = 0, x = 0; i < sz; ) {
-               if (isspace(str[i]))
+       for (i = 0, x = 0; i < sz && x < len - 1;  ) {
+               if (isspace(src[i]))
                        nsp++;
                else
                        nsp = 0, intext = 1;
@@ -332,14 +336,21 @@ static inline size_t normalize_whitespace(unsigned char *str)
                if (nsp > 1 || (nsp && !intext))
                        i++;
                else
-                       str[x++] = str[i++];
+                       dst[x++] = src[i++];
        }
-       if (nsp               /* tailing space */
+       if (nsp && x > 0)               /* tailing space */
                x--;
-       str[x] = '\0';
+done:
+       dst[x] = '\0';
        return x;
 }
 
+static inline size_t normalize_whitespace(unsigned char *str)
+{
+       size_t sz = strlen((char *) str);
+       return __normalize_whitespace(str, sz, str, sz + 1);
+}
+
 static inline void strrep(char *s, int find, int replace)
 {
        while (s && *s && (s = strchr(s, find)) != NULL)
index 5b5e686aa0c31b0cea891951a8e88557a54e0874..68b664748cfc6adaf771bb67f5db47565398ff25 100644 (file)
@@ -1175,17 +1175,26 @@ static int test_strutils_cmp_paths(int argc, char *argv[])
 
 static int test_strutils_normalize(int argc, char *argv[])
 {
-       unsigned char *str;
-       size_t sz;
+       unsigned char *src, *dst;
+       size_t sz, len;
 
        if (argc < 2)
                return EXIT_FAILURE;
 
-       str = (unsigned char *) strdup(argv[1]);
-       sz = normalize_whitespace(str);
+       src =  (unsigned char *) strdup(argv[1]);
+       len = strlen((char *) src);
+       dst = malloc(len + 1);
 
-       printf("'%s' --> '%s' [sz=%zu]\n", argv[1], str, sz);
-       free(str);
+       /* two buffers */
+       sz = __normalize_whitespace(src, len, dst, len + 1);
+       printf("1: '%s' --> '%s' [sz=%zu]\n", src, dst, sz);
+
+       /* one buffer */
+       sz = normalize_whitespace(src);
+       printf("2: '%s' --> '%s' [sz=%zu]\n", argv[1], src, sz);
+
+       free(src);
+       free(dst);
 
        return EXIT_SUCCESS;
 }