]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/test/test-strv.c
basic/strv: add an extra NUL after strings in strv_make_nulstr
[thirdparty/systemd.git] / src / test / test-strv.c
index 6e3c81395c81189312a52e60beebdb54e1e308b4..841a36782f4f6a080195b518a447943b45cc01af 100644 (file)
@@ -1,5 +1,3 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
 /***
   This file is part of systemd.
 
 
 #include <string.h>
 
-#include "util.h"
+#include "alloc-util.h"
 #include "specifier.h"
+#include "string-util.h"
 #include "strv.h"
+#include "util.h"
 
 static void test_specifier_printf(void) {
         static const Specifier table[] = {
@@ -70,6 +70,18 @@ static const char* const input_table_none[] = {
         NULL,
 };
 
+static const char* const input_table_two_empties[] = {
+        "",
+        "",
+        NULL,
+};
+
+static const char* const input_table_one_empty[] = {
+        "",
+        NULL,
+};
+
+
 static const char* const input_table_quotes[] = {
         "\"",
         "'",
@@ -130,7 +142,7 @@ static void test_strv_find_startswith(void) {
 }
 
 static void test_strv_join(void) {
-        _cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL;
+        _cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL, *v = NULL, *w = NULL;
 
         p = strv_join((char **)input_table_multiple, ", ");
         assert_se(p);
@@ -151,11 +163,19 @@ static void test_strv_join(void) {
         t = strv_join((char **)input_table_none, ", ");
         assert_se(t);
         assert_se(streq(t, ""));
+
+        v = strv_join((char **)input_table_two_empties, ", ");
+        assert_se(v);
+        assert_se(streq(v, ", "));
+
+        w = strv_join((char **)input_table_one_empty, ", ");
+        assert_se(w);
+        assert_se(streq(w, ""));
 }
 
 static void test_strv_quote_unquote(const char* const *split, const char *quoted) {
         _cleanup_free_ char *p;
-        _cleanup_strv_free_ char **s;
+        _cleanup_strv_free_ char **s = NULL;
         char **t;
         int r;
 
@@ -165,8 +185,8 @@ static void test_strv_quote_unquote(const char* const *split, const char *quoted
         assert_se(p);
         assert_se(streq(p, quoted));
 
-        r = strv_split_quoted(&s, quoted, 0);
-        assert_se(r == 0);
+        r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_QUOTES);
+        assert_se(r == (int) strv_length(s));
         assert_se(s);
         STRV_FOREACH(t, s) {
                 assert_se(*t);
@@ -182,8 +202,8 @@ static void test_strv_unquote(const char *quoted, char **list) {
         char **t;
         int r;
 
-        r = strv_split_quoted(&s, quoted, 0);
-        assert_se(r == 0);
+        r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_QUOTES);
+        assert_se(r == (int) strv_length(list));
         assert_se(s);
         j = strv_join(s, " | ");
         assert_se(j);
@@ -199,7 +219,7 @@ static void test_invalid_unquote(const char *quoted) {
         char **s = NULL;
         int r;
 
-        r = strv_split_quoted(&s, quoted, 0);
+        r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_QUOTES);
         assert_se(s == NULL);
         assert_se(r == -EINVAL);
 }
@@ -219,6 +239,21 @@ static void test_strv_split(void) {
         }
 }
 
+static void test_strv_split_extract(void) {
+        _cleanup_strv_free_ char **l = NULL;
+        const char *str = ":foo\\:bar::waldo:";
+        int r;
+
+        r = strv_split_extract(&l, str, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
+        assert_se(r == (int) strv_length(l));
+        assert_se(streq_ptr(l[0], ""));
+        assert_se(streq_ptr(l[1], "foo:bar"));
+        assert_se(streq_ptr(l[2], ""));
+        assert_se(streq_ptr(l[3], "waldo"));
+        assert_se(streq_ptr(l[4], ""));
+        assert_se(streq_ptr(l[5], NULL));
+}
+
 static void test_strv_split_newlines(void) {
         unsigned i = 0;
         char **s;
@@ -323,14 +358,14 @@ static void test_strv_extend_strv_concat(void) {
 }
 
 static void test_strv_extend_strv(void) {
-        _cleanup_strv_free_ char **a = NULL, **b = NULL;
+        _cleanup_strv_free_ char **a = NULL, **b = NULL, **n = NULL;
 
         a = strv_new("abc", "def", "ghi", NULL);
-        b = strv_new("jkl", "mno", "pqr", NULL);
+        b = strv_new("jkl", "mno", "abc", "pqr", NULL);
         assert_se(a);
         assert_se(b);
 
-        assert_se(strv_extend_strv(&a, b) >= 0);
+        assert_se(strv_extend_strv(&a, b, true) == 3);
 
         assert_se(streq(a[0], "abc"));
         assert_se(streq(a[1], "def"));
@@ -338,8 +373,14 @@ static void test_strv_extend_strv(void) {
         assert_se(streq(a[3], "jkl"));
         assert_se(streq(a[4], "mno"));
         assert_se(streq(a[5], "pqr"));
-
         assert_se(strv_length(a) == 6);
+
+        assert_se(strv_extend_strv(&n, b, false) >= 0);
+        assert_se(streq(n[0], "jkl"));
+        assert_se(streq(n[1], "mno"));
+        assert_se(streq(n[2], "abc"));
+        assert_se(streq(n[3], "pqr"));
+        assert_se(strv_length(n) == 4);
 }
 
 static void test_strv_extend(void) {
@@ -542,6 +583,124 @@ static void test_strv_reverse(void) {
         assert_se(streq_ptr(d[3], NULL));
 }
 
+static void test_strv_shell_escape(void) {
+        _cleanup_strv_free_ char **v = NULL;
+
+        v = strv_new("foo:bar", "bar,baz", "wal\\do", NULL);
+        assert_se(v);
+        assert_se(strv_shell_escape(v, ",:"));
+        assert_se(streq_ptr(v[0], "foo\\:bar"));
+        assert_se(streq_ptr(v[1], "bar\\,baz"));
+        assert_se(streq_ptr(v[2], "wal\\\\do"));
+        assert_se(streq_ptr(v[3], NULL));
+}
+
+static void test_strv_skip_one(char **a, size_t n, char **b) {
+        a = strv_skip(a, n);
+        assert_se(strv_equal(a, b));
+}
+
+static void test_strv_skip(void) {
+        test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 0, STRV_MAKE("foo", "bar", "baz"));
+        test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 1, STRV_MAKE("bar", "baz"));
+        test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 2, STRV_MAKE("baz"));
+        test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 3, STRV_MAKE(NULL));
+        test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 4, STRV_MAKE(NULL));
+        test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 55, STRV_MAKE(NULL));
+
+        test_strv_skip_one(STRV_MAKE("quux"), 0, STRV_MAKE("quux"));
+        test_strv_skip_one(STRV_MAKE("quux"), 1, STRV_MAKE(NULL));
+        test_strv_skip_one(STRV_MAKE("quux"), 55, STRV_MAKE(NULL));
+
+        test_strv_skip_one(STRV_MAKE(NULL), 0, STRV_MAKE(NULL));
+        test_strv_skip_one(STRV_MAKE(NULL), 1, STRV_MAKE(NULL));
+        test_strv_skip_one(STRV_MAKE(NULL), 55, STRV_MAKE(NULL));
+}
+
+static void test_strv_extend_n(void) {
+        _cleanup_strv_free_ char **v = NULL;
+
+        v = strv_new("foo", "bar", NULL);
+        assert_se(v);
+
+        assert_se(strv_extend_n(&v, "waldo", 3) >= 0);
+        assert_se(strv_extend_n(&v, "piep", 2) >= 0);
+
+        assert_se(streq(v[0], "foo"));
+        assert_se(streq(v[1], "bar"));
+        assert_se(streq(v[2], "waldo"));
+        assert_se(streq(v[3], "waldo"));
+        assert_se(streq(v[4], "waldo"));
+        assert_se(streq(v[5], "piep"));
+        assert_se(streq(v[6], "piep"));
+        assert_se(v[7] == NULL);
+
+        v = strv_free(v);
+
+        assert_se(strv_extend_n(&v, "foo", 1) >= 0);
+        assert_se(strv_extend_n(&v, "bar", 0) >= 0);
+
+        assert_se(streq(v[0], "foo"));
+        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;
+        const char *s = NULL;
+        size_t n, m;
+        unsigned i = 0;
+
+        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));
+}
+
+static void test_strv_make_nulstr(void) {
+        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"));
+}
+
+static void test_foreach_string(void) {
+        const char * const t[] = {
+                "foo",
+                "bar",
+                "waldo",
+                NULL
+        };
+        const char *x;
+        unsigned i = 0;
+
+        FOREACH_STRING(x, "foo", "bar", "waldo")
+                assert_se(streq_ptr(t[i++], x));
+
+        assert_se(i == 3);
+
+        FOREACH_STRING(x, "zzz")
+                assert_se(streq(x, "zzz"));
+}
+
+static void test_strv_fnmatch(void) {
+        _cleanup_strv_free_ char **v = NULL;
+
+        assert_se(!strv_fnmatch(STRV_MAKE_EMPTY, "a", 0));
+
+        v = strv_new("*\\*", NULL);
+        assert_se(!strv_fnmatch(v, "\\", 0));
+        assert_se(strv_fnmatch(v, "\\", FNM_NOESCAPE));
+}
+
 int main(int argc, char *argv[]) {
         test_specifier_printf();
         test_strv_foreach();
@@ -555,6 +714,8 @@ int main(int argc, char *argv[]) {
         test_strv_quote_unquote(input_table_multiple, "\"one\" \"two\" \"three\"");
         test_strv_quote_unquote(input_table_one, "\"one\"");
         test_strv_quote_unquote(input_table_none, "");
+        test_strv_quote_unquote(input_table_one_empty, "\"\"");
+        test_strv_quote_unquote(input_table_two_empties, "\"\" \"\"");
         test_strv_quote_unquote(input_table_quotes, QUOTES_STRING);
         test_strv_quote_unquote(input_table_spaces, SPACES_STRING);
 
@@ -583,6 +744,7 @@ int main(int argc, char *argv[]) {
         test_invalid_unquote("'x'y'g");
 
         test_strv_split();
+        test_strv_split_extract();
         test_strv_split_newlines();
         test_strv_split_nulstr();
         test_strv_parse_nulstr();
@@ -598,6 +760,13 @@ int main(int argc, char *argv[]) {
         test_strv_equal();
         test_strv_is_uniq();
         test_strv_reverse();
+        test_strv_shell_escape();
+        test_strv_skip();
+        test_strv_extend_n();
+        test_strv_make_nulstr();
+
+        test_foreach_string();
+        test_strv_fnmatch();
 
         return 0;
 }