]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
strv: move nulstr utilities to nulstr-util.[ch]
authorLennart Poettering <lennart@poettering.net>
Fri, 11 Nov 2022 20:55:00 +0000 (21:55 +0100)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 13 Nov 2022 08:39:08 +0000 (17:39 +0900)
Let's move them out of the generic, already very long strv.[ch] module
into the more specific nulst-util.[ch]

No code changes.

17 files changed:
src/basic/conf-files.c
src/basic/fileio.c
src/basic/nulstr-util.c
src/basic/nulstr-util.h
src/basic/process-util.c
src/basic/strv.c
src/basic/strv.h
src/libsystemd/sd-bus/bus-creds.c
src/libsystemd/sd-path/sd-path.c
src/shared/ask-password-api.c
src/shared/condition.c
src/systemctl/fuzz-systemctl-parse-argv.c
src/test/meson.build
src/test/test-nulstr-util.c [new file with mode: 0644]
src/test/test-strbuf.c
src/test/test-strv.c
src/tmpfiles/tmpfiles.c

index 348f7dcc7018a87dd6befe427d19a8ebda1ec154..3fbb2cda0010957de24fc4a5c7fab65bd36084c2 100644 (file)
@@ -13,6 +13,7 @@
 #include "hashmap.h"
 #include "log.h"
 #include "macro.h"
+#include "nulstr-util.h"
 #include "path-util.h"
 #include "set.h"
 #include "sort-util.h"
index a5c44f184a9cae5c901a5d018d684217e877bdac..5078cae2df1ec4f3b7fec0a766965d629ccae49c 100644 (file)
@@ -21,6 +21,7 @@
 #include "log.h"
 #include "macro.h"
 #include "mkdir.h"
+#include "nulstr-util.h"
 #include "parse-util.h"
 #include "path-util.h"
 #include "socket-util.h"
index 8eb19256a96dfde8f78539bf7783a13cf11d3fd5..05154d71c2f1c3b9c50279dce68cd2db8d0f14be 100644 (file)
@@ -2,6 +2,119 @@
 
 #include "nulstr-util.h"
 #include "string-util.h"
+#include "strv.h"
+
+char** strv_parse_nulstr(const char *s, size_t l) {
+        /* l is the length of the input data, which will be split at NULs into
+         * elements of the resulting strv. Hence, the number of items in the resulting strv
+         * will be equal to one plus the number of NUL bytes in the l bytes starting at s,
+         * unless s[l-1] is NUL, in which case the final empty string is not stored in
+         * the resulting strv, and length is equal to the number of NUL bytes.
+         *
+         * Note that contrary to a normal nulstr which cannot contain empty strings, because
+         * the input data is terminated by any two consequent NUL bytes, this parser accepts
+         * empty strings in s.
+         */
+
+        size_t c = 0, i = 0;
+        char **v;
+
+        assert(s || l <= 0);
+
+        if (l <= 0)
+                return new0(char*, 1);
+
+        for (const char *p = s; p < s + l; p++)
+                if (*p == 0)
+                        c++;
+
+        if (s[l-1] != 0)
+                c++;
+
+        v = new0(char*, c+1);
+        if (!v)
+                return NULL;
+
+        for (const char *p = s; p < s + l; ) {
+                const char *e;
+
+                e = memchr(p, 0, s + l - p);
+
+                v[i] = strndup(p, e ? e - p : s + l - p);
+                if (!v[i]) {
+                        strv_free(v);
+                        return NULL;
+                }
+
+                i++;
+
+                if (!e)
+                        break;
+
+                p = e + 1;
+        }
+
+        assert(i == c);
+
+        return v;
+}
+
+char** strv_split_nulstr(const char *s) {
+        char **r = NULL;
+
+        NULSTR_FOREACH(i, s)
+                if (strv_extend(&r, i) < 0) {
+                        strv_free(r);
+                        return NULL;
+                }
+
+        if (!r)
+                return strv_new(NULL);
+
+        return r;
+}
+
+int strv_make_nulstr(char * const *l, char **ret, size_t *ret_size) {
+        /* A valid nulstr with two NULs at the end will be created, but
+         * q will be the length without the two trailing NULs. Thus the output
+         * string is a valid nulstr and can be iterated over using NULSTR_FOREACH,
+         * and can also be parsed by strv_parse_nulstr as long as the length
+         * is provided separately.
+         */
+
+        _cleanup_free_ char *m = NULL;
+        size_t n = 0;
+
+        assert(ret);
+        assert(ret_size);
+
+        STRV_FOREACH(i, l) {
+                size_t z;
+
+                z = strlen(*i);
+
+                if (!GREEDY_REALLOC(m, n + z + 2))
+                        return -ENOMEM;
+
+                memcpy(m + n, *i, z + 1);
+                n += z + 1;
+        }
+
+        if (!m) {
+                m = new0(char, 2);
+                if (!m)
+                        return -ENOMEM;
+                n = 1;
+        } else
+                /* make sure there is a second extra NUL at the end of resulting nulstr */
+                m[n] = '\0';
+
+        assert(n > 0);
+        *ret = TAKE_PTR(m);
+        *ret_size = n - 1;
+
+        return 0;
+}
 
 const char* nulstr_get(const char *nulstr, const char *needle) {
         if (!nulstr)
index 26bf7be871dc7da5d00863a2da74079e4c42dde8..8c2849b11101673efa4f7818232de0c70869fb53 100644 (file)
@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 #pragma once
 
+#include <errno.h>
 #include <stdbool.h>
 #include <string.h>
 
@@ -15,3 +16,17 @@ const char* nulstr_get(const char *nulstr, const char *needle);
 static inline bool nulstr_contains(const char *nulstr, const char *needle) {
         return nulstr_get(nulstr, needle);
 }
+
+char** strv_parse_nulstr(const char *s, size_t l);
+char** strv_split_nulstr(const char *s);
+int strv_make_nulstr(char * const *l, char **p, size_t *n);
+
+static inline int strv_from_nulstr(char ***a, const char *nulstr) {
+        char **t;
+
+        t = strv_split_nulstr(nulstr);
+        if (!t)
+                return -ENOMEM;
+        *a = t;
+        return 0;
+}
index dd913bc3238e6a9fe90a6aee57d22bc11124d83c..183ff8b84eb4f7b408047f82028b3bc909ffccf5 100644 (file)
@@ -37,6 +37,7 @@
 #include "missing_sched.h"
 #include "missing_syscall.h"
 #include "namespace-util.h"
+#include "nulstr-util.h"
 #include "parse-util.h"
 #include "path-util.h"
 #include "process-util.h"
index 7d9bf8d63a36815354ccea99a709b397ba8246dd..74e87046cca9dac00e30a8361a6021acb33f184d 100644 (file)
@@ -623,118 +623,6 @@ char** strv_remove(char **l, const char *s) {
         return l;
 }
 
-char** strv_parse_nulstr(const char *s, size_t l) {
-        /* l is the length of the input data, which will be split at NULs into
-         * elements of the resulting strv. Hence, the number of items in the resulting strv
-         * will be equal to one plus the number of NUL bytes in the l bytes starting at s,
-         * unless s[l-1] is NUL, in which case the final empty string is not stored in
-         * the resulting strv, and length is equal to the number of NUL bytes.
-         *
-         * Note that contrary to a normal nulstr which cannot contain empty strings, because
-         * the input data is terminated by any two consequent NUL bytes, this parser accepts
-         * empty strings in s.
-         */
-
-        size_t c = 0, i = 0;
-        char **v;
-
-        assert(s || l <= 0);
-
-        if (l <= 0)
-                return new0(char*, 1);
-
-        for (const char *p = s; p < s + l; p++)
-                if (*p == 0)
-                        c++;
-
-        if (s[l-1] != 0)
-                c++;
-
-        v = new0(char*, c+1);
-        if (!v)
-                return NULL;
-
-        for (const char *p = s; p < s + l; ) {
-                const char *e;
-
-                e = memchr(p, 0, s + l - p);
-
-                v[i] = strndup(p, e ? e - p : s + l - p);
-                if (!v[i]) {
-                        strv_free(v);
-                        return NULL;
-                }
-
-                i++;
-
-                if (!e)
-                        break;
-
-                p = e + 1;
-        }
-
-        assert(i == c);
-
-        return v;
-}
-
-char** strv_split_nulstr(const char *s) {
-        char **r = NULL;
-
-        NULSTR_FOREACH(i, s)
-                if (strv_extend(&r, i) < 0) {
-                        strv_free(r);
-                        return NULL;
-                }
-
-        if (!r)
-                return strv_new(NULL);
-
-        return r;
-}
-
-int strv_make_nulstr(char * const *l, char **ret, size_t *ret_size) {
-        /* A valid nulstr with two NULs at the end will be created, but
-         * q will be the length without the two trailing NULs. Thus the output
-         * string is a valid nulstr and can be iterated over using NULSTR_FOREACH,
-         * and can also be parsed by strv_parse_nulstr as long as the length
-         * is provided separately.
-         */
-
-        _cleanup_free_ char *m = NULL;
-        size_t n = 0;
-
-        assert(ret);
-        assert(ret_size);
-
-        STRV_FOREACH(i, l) {
-                size_t z;
-
-                z = strlen(*i);
-
-                if (!GREEDY_REALLOC(m, n + z + 2))
-                        return -ENOMEM;
-
-                memcpy(m + n, *i, z + 1);
-                n += z + 1;
-        }
-
-        if (!m) {
-                m = new0(char, 2);
-                if (!m)
-                        return -ENOMEM;
-                n = 1;
-        } else
-                /* make sure there is a second extra NUL at the end of resulting nulstr */
-                m[n] = '\0';
-
-        assert(n > 0);
-        *ret = TAKE_PTR(m);
-        *ret_size = n - 1;
-
-        return 0;
-}
-
 bool strv_overlap(char * const *a, char * const *b) {
         STRV_FOREACH(i, a)
                 if (strv_contains(b, *i))
index d6f5ac6ba581958471b9499c356020b59ba061b1..87a7038a54744ab18b9cf4b89a00ed86db4e5a78 100644 (file)
@@ -124,20 +124,6 @@ static inline char *strv_join(char * const *l, const char *separator) {
         return strv_join_full(l, separator, NULL, false);
 }
 
-char** strv_parse_nulstr(const char *s, size_t l);
-char** strv_split_nulstr(const char *s);
-int strv_make_nulstr(char * const *l, char **p, size_t *n);
-
-static inline int strv_from_nulstr(char ***a, const char *nulstr) {
-        char **t;
-
-        t = strv_split_nulstr(nulstr);
-        if (!t)
-                return -ENOMEM;
-        *a = t;
-        return 0;
-}
-
 bool strv_overlap(char * const *a, char * const *b) _pure_;
 
 #define _STRV_FOREACH_BACKWARDS(s, l, h, i)                             \
index 45e7473c29f2eaea39d03f782d80bfb543a058ff..6e53e942dff232b95939da8462a47f9b96a41786 100644 (file)
@@ -15,6 +15,7 @@
 #include "fileio.h"
 #include "format-util.h"
 #include "hexdecoct.h"
+#include "nulstr-util.h"
 #include "parse-util.h"
 #include "process-util.h"
 #include "string-util.h"
index 601f61bf639f2bae1a451044a5a92c7c1613d93a..ded64a66efad22e7b367b752a616047f6c084b3f 100644 (file)
@@ -7,6 +7,7 @@
 #include "fd-util.h"
 #include "fileio.h"
 #include "fs-util.h"
+#include "nulstr-util.h"
 #include "path-lookup.h"
 #include "path-util.h"
 #include "string-util.h"
index 84d7b31bad7db78d33e03b7fb0cd050566780ed0..e0488ff1940369306f332231f0b7d5b107781758 100644 (file)
@@ -34,6 +34,7 @@
 #include "memory-util.h"
 #include "missing_syscall.h"
 #include "mkdir-label.h"
+#include "nulstr-util.h"
 #include "process-util.h"
 #include "random-util.h"
 #include "signal-util.h"
index f404d99878b023ba6b07e838ff619789ecef7249..d5fdbbf9e07d5c57916112ed21b79388a0059245 100644 (file)
 #include "fs-util.h"
 #include "glob-util.h"
 #include "hostname-util.h"
-#include "initrd-util.h"
 #include "ima-util.h"
+#include "initrd-util.h"
 #include "limits-util.h"
 #include "list.h"
 #include "macro.h"
 #include "mountpoint-util.h"
+#include "nulstr-util.h"
 #include "os-util.h"
 #include "parse-util.h"
 #include "path-util.h"
index 588c8b56c5cebc518e0e45a229e94452d92a694d..92f6ecaa8d044145b87ae87f91ec71c66e48f7d8 100644 (file)
@@ -6,6 +6,7 @@
 #include "env-util.h"
 #include "fd-util.h"
 #include "fuzz.h"
+#include "nulstr-util.h"
 #include "selinux-util.h"
 #include "static-destruct.h"
 #include "stdio-util.h"
index 9d193651edb88c9dd6cfc4a29e9eb2dc55c100f8..4f72e00f57da25a3e64810cf0e3ed4d0acdce04a 100644 (file)
@@ -557,6 +557,8 @@ tests += [
 
         [files('test-strv.c')],
 
+        [files('test-nulstr-util.c')],
+
         [files('test-path-util.c')],
 
         [files('test-rm-rf.c')],
diff --git a/src/test/test-nulstr-util.c b/src/test/test-nulstr-util.c
new file mode 100644 (file)
index 0000000..e707416
--- /dev/null
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "alloc-util.h"
+#include "nulstr-util.h"
+#include "strv.h"
+#include "tests.h"
+
+TEST(strv_split_nulstr) {
+        _cleanup_strv_free_ char **l = NULL;
+        const char nulstr[] = "str0\0str1\0str2\0str3\0";
+
+        l = strv_split_nulstr(nulstr);
+        assert_se(l);
+
+        assert_se(streq(l[0], "str0"));
+        assert_se(streq(l[1], "str1"));
+        assert_se(streq(l[2], "str2"));
+        assert_se(streq(l[3], "str3"));
+}
+
+TEST(strv_parse_nulstr) {
+        _cleanup_strv_free_ char **l = NULL;
+        const char nulstr[] = "hoge\0hoge2\0hoge3\0\0hoge5\0\0xxx";
+
+        l = strv_parse_nulstr(nulstr, sizeof(nulstr)-1);
+        assert_se(l);
+        puts("Parse nulstr:");
+        strv_print(l);
+
+        assert_se(streq(l[0], "hoge"));
+        assert_se(streq(l[1], "hoge2"));
+        assert_se(streq(l[2], "hoge3"));
+        assert_se(streq(l[3], ""));
+        assert_se(streq(l[4], "hoge5"));
+        assert_se(streq(l[5], ""));
+        assert_se(streq(l[6], "xxx"));
+}
+
+DEFINE_TEST_MAIN(LOG_INFO);
index 5c12a0597ad29321793e734761356371b315a813..f69e80ca5a84911b65342722c408b589c24fb0e3 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <stdlib.h>
 
+#include "nulstr-util.h"
 #include "strbuf.h"
 #include "string-util.h"
 #include "strv.h"
index debb922f856d9caad4fff4b3cf55cf980967a5f0..9208faafa47d22c482090a71d0be038a97e01955 100644 (file)
@@ -2,7 +2,6 @@
 
 #include "alloc-util.h"
 #include "escape.h"
-#include "nulstr-util.h"
 #include "string-util.h"
 #include "strv.h"
 #include "tests.h"
@@ -487,37 +486,6 @@ TEST(strv_split_newlines_full) {
         assert_se(strv_equal(l, (char**) input_table_retain_escape));
 }
 
-TEST(strv_split_nulstr) {
-        _cleanup_strv_free_ char **l = NULL;
-        const char nulstr[] = "str0\0str1\0str2\0str3\0";
-
-        l = strv_split_nulstr (nulstr);
-        assert_se(l);
-
-        assert_se(streq(l[0], "str0"));
-        assert_se(streq(l[1], "str1"));
-        assert_se(streq(l[2], "str2"));
-        assert_se(streq(l[3], "str3"));
-}
-
-TEST(strv_parse_nulstr) {
-        _cleanup_strv_free_ char **l = NULL;
-        const char nulstr[] = "hoge\0hoge2\0hoge3\0\0hoge5\0\0xxx";
-
-        l = strv_parse_nulstr(nulstr, sizeof(nulstr)-1);
-        assert_se(l);
-        puts("Parse nulstr:");
-        strv_print(l);
-
-        assert_se(streq(l[0], "hoge"));
-        assert_se(streq(l[1], "hoge2"));
-        assert_se(streq(l[2], "hoge3"));
-        assert_se(streq(l[3], ""));
-        assert_se(streq(l[4], "hoge5"));
-        assert_se(streq(l[5], ""));
-        assert_se(streq(l[6], "xxx"));
-}
-
 TEST(strv_overlap) {
         const char * const input_table[] = {
                 "one",
@@ -945,35 +913,6 @@ TEST(strv_extend_n) {
         assert_se(v[1] == NULL);
 }
 
-static void test_strv_make_nulstr_one(char **l) {
-        _cleanup_free_ char *b = NULL, *c = NULL;
-        _cleanup_strv_free_ char **q = NULL;
-        size_t n, m;
-        unsigned i = 0;
-
-        log_info("/* %s */", __func__);
-
-        assert_se(strv_make_nulstr(l, &b, &n) >= 0);
-        assert_se(q = strv_parse_nulstr(b, n));
-        assert_se(strv_equal(l, q));
-
-        assert_se(strv_make_nulstr(q, &c, &m) >= 0);
-        assert_se(m == n);
-        assert_se(memcmp(b, c, m) == 0);
-
-        NULSTR_FOREACH(s, b)
-                assert_se(streq(s, l[i++]));
-        assert_se(i == strv_length(l));
-}
-
-TEST(strv_make_nulstr) {
-        test_strv_make_nulstr_one(NULL);
-        test_strv_make_nulstr_one(STRV_MAKE(NULL));
-        test_strv_make_nulstr_one(STRV_MAKE("foo"));
-        test_strv_make_nulstr_one(STRV_MAKE("foo", "bar"));
-        test_strv_make_nulstr_one(STRV_MAKE("foo", "bar", "quuux"));
-}
-
 TEST(foreach_string) {
         const char * const t[] = {
                 "foo",
index d3258ec70117dca2bcfe4a057b74d3b4e22d5f13..557492f958f9be3aeca3a1e434ee146ca3e5d7c8 100644 (file)
@@ -50,6 +50,7 @@
 #include "mkdir-label.h"
 #include "mount-util.h"
 #include "mountpoint-util.h"
+#include "nulstr-util.h"
 #include "offline-passwd.h"
 #include "pager.h"
 #include "parse-argument.h"