]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-strv.c
strv: make iterator in STRV_FOREACH() declaread in the loop
[thirdparty/systemd.git] / src / test / test-strv.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
f90cf44c 2
b5efdb8a 3#include "alloc-util.h"
e7b2ea7c 4#include "escape.h"
d8b4d14d 5#include "nulstr-util.h"
07630cea 6#include "string-util.h"
682cfdff 7#include "strv.h"
4f7452a8 8#include "tests.h"
f90cf44c 9
4f7452a8 10TEST(str_in_set) {
c7bf9d51
ZJS
11 assert_se(STR_IN_SET("x", "x", "y", "z"));
12 assert_se(!STR_IN_SET("X", "x", "y", "z"));
13 assert_se(!STR_IN_SET("", "x", "y", "z"));
14 assert_se(STR_IN_SET("x", "w", "x"));
15}
16
4f7452a8 17TEST(strptr_in_set) {
c7bf9d51
ZJS
18 assert_se(STRPTR_IN_SET("x", "x", "y", "z"));
19 assert_se(!STRPTR_IN_SET("X", "x", "y", "z"));
20 assert_se(!STRPTR_IN_SET("", "x", "y", "z"));
21 assert_se(STRPTR_IN_SET("x", "w", "x"));
22
23 assert_se(!STRPTR_IN_SET(NULL, "x", "y", "z"));
24 assert_se(!STRPTR_IN_SET(NULL, ""));
25 /* strv cannot contain a null, hence the result below */
26 assert_se(!STRPTR_IN_SET(NULL, NULL));
27}
28
4f7452a8 29TEST(startswith_set) {
52f15520
LP
30 assert_se(!STARTSWITH_SET("foo", "bar", "baz", "waldo"));
31 assert_se(!STARTSWITH_SET("foo", "bar"));
32
33 assert_se(STARTSWITH_SET("abc", "a", "ab", "abc"));
34 assert_se(STARTSWITH_SET("abc", "ax", "ab", "abc"));
35 assert_se(STARTSWITH_SET("abc", "ax", "abx", "abc"));
36 assert_se(!STARTSWITH_SET("abc", "ax", "abx", "abcx"));
37
38 assert_se(streq_ptr(STARTSWITH_SET("foobar", "hhh", "kkk", "foo", "zzz"), "bar"));
39 assert_se(streq_ptr(STARTSWITH_SET("foobar", "hhh", "kkk", "", "zzz"), "foobar"));
40 assert_se(streq_ptr(STARTSWITH_SET("", "hhh", "kkk", "zzz", ""), ""));
41}
42
a6fde353
ZJS
43static const char* const input_table_multiple[] = {
44 "one",
45 "two",
46 "three",
47 NULL,
48};
49
1f938af8
YW
50static const char* const input_table_quoted[] = {
51 "one",
52 " two\t three ",
53 " four five",
54 NULL,
55};
56
0645b83a
ZJS
57static const char* const input_table_quoted_joined[] = {
58 "one",
59 " two\t three " " four five",
60 NULL,
61};
62
a6fde353
ZJS
63static const char* const input_table_one[] = {
64 "one",
65 NULL,
66};
67
68static const char* const input_table_none[] = {
69 NULL,
70};
71
afe773b0
ZJS
72static const char* const input_table_two_empties[] = {
73 "",
74 "",
75 NULL,
76};
77
78static const char* const input_table_one_empty[] = {
79 "",
80 NULL,
81};
82
f385c447
YW
83static const char* const input_table_unescape[] = {
84 "ID_VENDOR=QEMU",
85 "ID_VENDOR_ENC=QEMUx20x20x20x20",
86 "ID_MODEL_ENC=QEMUx20HARDDISKx20x20x20",
87 NULL,
88};
89
90static const char* const input_table_retain_escape[] = {
91 "ID_VENDOR=QEMU",
92 "ID_VENDOR_ENC=QEMU\\x20\\x20\\x20\\x20",
93 "ID_MODEL_ENC=QEMU\\x20HARDDISK\\x20\\x20\\x20",
94 NULL,
95};
96
4f7452a8 97TEST(strv_find) {
a6fde353
ZJS
98 assert_se(strv_find((char **)input_table_multiple, "three"));
99 assert_se(!strv_find((char **)input_table_multiple, "four"));
539ad707
TA
100}
101
4f7452a8 102TEST(strv_find_prefix) {
a6fde353
ZJS
103 assert_se(strv_find_prefix((char **)input_table_multiple, "o"));
104 assert_se(strv_find_prefix((char **)input_table_multiple, "one"));
105 assert_se(strv_find_prefix((char **)input_table_multiple, ""));
106 assert_se(!strv_find_prefix((char **)input_table_multiple, "xxx"));
107 assert_se(!strv_find_prefix((char **)input_table_multiple, "onee"));
3a7719d3 108}
f90cf44c 109
4f7452a8 110TEST(strv_find_startswith) {
7bd57a87
RC
111 char *r;
112
113 r = strv_find_startswith((char **)input_table_multiple, "o");
114 assert_se(r && streq(r, "ne"));
115
116 r = strv_find_startswith((char **)input_table_multiple, "one");
117 assert_se(r && streq(r, ""));
118
119 r = strv_find_startswith((char **)input_table_multiple, "");
120 assert_se(r && streq(r, "one"));
121
122 assert_se(!strv_find_startswith((char **)input_table_multiple, "xxx"));
123 assert_se(!strv_find_startswith((char **)input_table_multiple, "onee"));
124}
125
4f7452a8 126TEST(strv_join) {
d4d9f034 127 _cleanup_free_ char *p = strv_join((char **)input_table_multiple, ", ");
04045d84 128 assert_se(p);
7b68d618 129 assert_se(streq(p, "one, two, three"));
682cfdff 130
d4d9f034 131 _cleanup_free_ char *q = strv_join((char **)input_table_multiple, ";");
04045d84 132 assert_se(q);
7b68d618 133 assert_se(streq(q, "one;two;three"));
682cfdff 134
d4d9f034 135 _cleanup_free_ char *r = strv_join((char **)input_table_multiple, NULL);
04045d84 136 assert_se(r);
7b68d618 137 assert_se(streq(r, "one two three"));
539ad707 138
d4d9f034 139 _cleanup_free_ char *s = strv_join(STRV_MAKE("1", "2", "3,3"), ",");
04045d84 140 assert_se(s);
d4d9f034 141 assert_se(streq(s, "1,2,3,3"));
539ad707 142
d4d9f034 143 _cleanup_free_ char *t = strv_join((char **)input_table_one, ", ");
04045d84 144 assert_se(t);
d4d9f034
ZJS
145 assert_se(streq(t, "one"));
146
147 _cleanup_free_ char *u = strv_join((char **)input_table_none, ", ");
148 assert_se(u);
149 assert_se(streq(u, ""));
afe773b0 150
d4d9f034 151 _cleanup_free_ char *v = strv_join((char **)input_table_two_empties, ", ");
afe773b0
ZJS
152 assert_se(v);
153 assert_se(streq(v, ", "));
154
d4d9f034 155 _cleanup_free_ char *w = strv_join((char **)input_table_one_empty, ", ");
afe773b0
ZJS
156 assert_se(w);
157 assert_se(streq(w, ""));
682cfdff
DB
158}
159
4f7452a8 160TEST(strv_join_full) {
d4d9f034 161 _cleanup_free_ char *p = strv_join_full((char **)input_table_multiple, ", ", "foo", false);
474a595a
YW
162 assert_se(p);
163 assert_se(streq(p, "fooone, footwo, foothree"));
164
d4d9f034 165 _cleanup_free_ char *q = strv_join_full((char **)input_table_multiple, ";", "foo", false);
474a595a
YW
166 assert_se(q);
167 assert_se(streq(q, "fooone;footwo;foothree"));
168
d4d9f034 169 _cleanup_free_ char *r = strv_join_full(STRV_MAKE("a", "a;b", "a:c"), ";", NULL, true);
474a595a 170 assert_se(r);
d4d9f034 171 assert_se(streq(r, "a;a\\;b;a:c"));
474a595a 172
d4d9f034 173 _cleanup_free_ char *s = strv_join_full(STRV_MAKE("a", "a;b", "a;;c", ";", ";x"), ";", NULL, true);
474a595a 174 assert_se(s);
d4d9f034 175 assert_se(streq(s, "a;a\\;b;a\\;\\;c;\\;;\\;x"));
474a595a 176
d4d9f034 177 _cleanup_free_ char *t = strv_join_full(STRV_MAKE("a", "a;b", "a:c", ";"), ";", "=", true);
474a595a 178 assert_se(t);
d4d9f034
ZJS
179 assert_se(streq(t, "=a;=a\\;b;=a:c;=\\;"));
180 t = mfree(t);
181
182 _cleanup_free_ char *u = strv_join_full((char **)input_table_multiple, NULL, "foo", false);
183 assert_se(u);
184 assert_se(streq(u, "fooone footwo foothree"));
474a595a 185
d4d9f034 186 _cleanup_free_ char *v = strv_join_full((char **)input_table_one, ", ", "foo", false);
474a595a 187 assert_se(v);
d4d9f034 188 assert_se(streq(v, "fooone"));
474a595a 189
d4d9f034 190 _cleanup_free_ char *w = strv_join_full((char **)input_table_none, ", ", "foo", false);
474a595a 191 assert_se(w);
d4d9f034
ZJS
192 assert_se(streq(w, ""));
193
194 _cleanup_free_ char *x = strv_join_full((char **)input_table_two_empties, ", ", "foo", false);
195 assert_se(x);
196 assert_se(streq(x, "foo, foo"));
197
198 _cleanup_free_ char *y = strv_join_full((char **)input_table_one_empty, ", ", "foo", false);
199 assert_se(y);
200 assert_se(streq(y, "foo"));
474a595a
YW
201}
202
4f7452a8 203static void test_strv_unquote_one(const char *quoted, char **list) {
70f75a52 204 _cleanup_strv_free_ char **s;
a2a5291b 205 _cleanup_free_ char *j;
70f75a52 206 unsigned i = 0;
b2fadec6 207 int r;
70f75a52 208
0bf2c5e5
ZJS
209 log_info("/* %s */", __func__);
210
90e30d76 211 r = strv_split_full(&s, quoted, WHITESPACE, EXTRACT_UNQUOTE);
8dd4c05b 212 assert_se(r == (int) strv_length(list));
70f75a52 213 assert_se(s);
a2a5291b 214 j = strv_join(s, " | ");
bdf7026e 215 assert_se(j);
a2a5291b 216 puts(j);
70f75a52
LP
217
218 STRV_FOREACH(t, s)
219 assert_se(streq(list[i++], *t));
220
221 assert_se(list[i] == NULL);
222}
223
4f7452a8
JJ
224TEST(strv_unquote) {
225 test_strv_unquote_one(" foo=bar \"waldo\" zzz ", STRV_MAKE("foo=bar", "waldo", "zzz"));
226 test_strv_unquote_one("", STRV_MAKE_EMPTY);
227 test_strv_unquote_one(" ", STRV_MAKE_EMPTY);
228 test_strv_unquote_one(" ", STRV_MAKE_EMPTY);
229 test_strv_unquote_one(" x", STRV_MAKE("x"));
230 test_strv_unquote_one("x ", STRV_MAKE("x"));
231 test_strv_unquote_one(" x ", STRV_MAKE("x"));
232 test_strv_unquote_one(" \"x\" ", STRV_MAKE("x"));
233 test_strv_unquote_one(" 'x' ", STRV_MAKE("x"));
234 test_strv_unquote_one(" 'x\"' ", STRV_MAKE("x\""));
235 test_strv_unquote_one(" \"x'\" ", STRV_MAKE("x'"));
236 test_strv_unquote_one("a '--b=c \"d e\"'", STRV_MAKE("a", "--b=c \"d e\""));
237
238 /* trailing backslashes */
239 test_strv_unquote_one(" x\\\\", STRV_MAKE("x\\"));
240}
241
242static void test_invalid_unquote_one(const char *quoted) {
b2fadec6
ZJS
243 char **s = NULL;
244 int r;
a2a5291b 245
0bf2c5e5
ZJS
246 log_info("/* %s */", __func__);
247
90e30d76 248 r = strv_split_full(&s, quoted, WHITESPACE, EXTRACT_UNQUOTE);
bdf7026e
TA
249 assert_se(s == NULL);
250 assert_se(r == -EINVAL);
a2a5291b
ZJS
251}
252
4f7452a8
JJ
253TEST(invalid_unquote) {
254 test_invalid_unquote_one(" x\\");
255 test_invalid_unquote_one("a --b='c \"d e\"''");
256 test_invalid_unquote_one("a --b='c \"d e\" '\"");
257 test_invalid_unquote_one("a --b='c \"d e\"garbage");
258 test_invalid_unquote_one("'");
259 test_invalid_unquote_one("\"");
260 test_invalid_unquote_one("'x'y'g");
261}
262
263TEST(strv_split) {
b4f386d5 264 _cleanup_(strv_free_erasep) char **l = NULL;
aed2ebfe
DB
265 const char str[] = "one,two,three";
266
267 l = strv_split(str, ",");
bdf7026e 268 assert_se(l);
1f938af8 269 assert_se(strv_equal(l, (char**) input_table_multiple));
aed2ebfe 270
b4f386d5 271 strv_free_erase(l);
0745ce75
YW
272
273 l = strv_split(" one two\t three", WHITESPACE);
274 assert_se(l);
1f938af8
YW
275 assert_se(strv_equal(l, (char**) input_table_multiple));
276
b4f386d5 277 strv_free_erase(l);
1f938af8
YW
278
279 /* Setting NULL for separator is equivalent to WHITESPACE */
280 l = strv_split(" one two\t three", NULL);
281 assert_se(l);
282 assert_se(strv_equal(l, (char**) input_table_multiple));
283
b4f386d5 284 strv_free_erase(l);
1f938af8 285
90e30d76 286 assert_se(strv_split_full(&l, " one two\t three", NULL, 0) == 3);
1f938af8
YW
287 assert_se(strv_equal(l, (char**) input_table_multiple));
288
b4f386d5 289 strv_free_erase(l);
1f938af8 290
90e30d76 291 assert_se(strv_split_full(&l, " 'one' \" two\t three \" ' four five'", NULL, EXTRACT_UNQUOTE) == 3);
1f938af8
YW
292 assert_se(strv_equal(l, (char**) input_table_quoted));
293
0645b83a 294 l = strv_free_erase(l);
1f938af8 295
0645b83a 296 /* missing last quote causes extraction to fail. */
90e30d76 297 assert_se(strv_split_full(&l, " 'one' \" two\t three \" ' four five", NULL, EXTRACT_UNQUOTE) == -EINVAL);
0645b83a 298 assert_se(!l);
1f938af8 299
0645b83a 300 /* missing last quote, but the last element is _not_ ignored with EXTRACT_RELAX. */
90e30d76 301 assert_se(strv_split_full(&l, " 'one' \" two\t three \" ' four five", NULL, EXTRACT_UNQUOTE | EXTRACT_RELAX) == 3);
1f938af8
YW
302 assert_se(strv_equal(l, (char**) input_table_quoted));
303
0645b83a 304 l = strv_free_erase(l);
1f938af8 305
0645b83a 306 /* missing separator between items */
90e30d76 307 assert_se(strv_split_full(&l, " 'one' \" two\t three \"' four five'", NULL, EXTRACT_UNQUOTE | EXTRACT_RELAX) == 2);
0645b83a 308 assert_se(strv_equal(l, (char**) input_table_quoted_joined));
1f938af8 309
0645b83a 310 l = strv_free_erase(l);
1f938af8 311
90e30d76 312 assert_se(strv_split_full(&l, " 'one' \" two\t three \"' four five", NULL,
3141089f 313 EXTRACT_UNQUOTE | EXTRACT_RELAX | EXTRACT_UNESCAPE_RELAX) == 2);
0645b83a 314 assert_se(strv_equal(l, (char**) input_table_quoted_joined));
29965a2a 315
0645b83a 316 l = strv_free_erase(l);
29965a2a 317
3141089f 318 assert_se(strv_split_full(&l, "\\", NULL, EXTRACT_UNQUOTE | EXTRACT_RELAX | EXTRACT_UNESCAPE_RELAX) == 1);
29965a2a 319 assert_se(strv_equal(l, STRV_MAKE("\\")));
0745ce75
YW
320}
321
4f7452a8 322TEST(strv_split_empty) {
0745ce75
YW
323 _cleanup_strv_free_ char **l = NULL;
324
325 l = strv_split("", WHITESPACE);
326 assert_se(l);
327 assert_se(strv_isempty(l));
0645b83a 328 l = strv_free(l);
0745ce75 329
0645b83a 330 assert_se(l = strv_split("", NULL));
1f938af8 331 assert_se(strv_isempty(l));
0645b83a 332 l = strv_free(l);
1f938af8 333
90e30d76 334 assert_se(strv_split_full(&l, "", NULL, 0) == 0);
1f938af8
YW
335 assert_se(l);
336 assert_se(strv_isempty(l));
0645b83a 337 l = strv_free(l);
1f938af8 338
90e30d76 339 assert_se(strv_split_full(&l, "", NULL, EXTRACT_UNQUOTE) == 0);
1f938af8
YW
340 assert_se(l);
341 assert_se(strv_isempty(l));
0645b83a 342 l = strv_free(l);
1f938af8 343
90e30d76 344 assert_se(strv_split_full(&l, "", WHITESPACE, EXTRACT_UNQUOTE) == 0);
1f938af8
YW
345 assert_se(l);
346 assert_se(strv_isempty(l));
0645b83a 347 l = strv_free(l);
1f938af8 348
90e30d76 349 assert_se(strv_split_full(&l, "", WHITESPACE, EXTRACT_UNQUOTE | EXTRACT_RELAX) == 0);
1f938af8
YW
350 assert_se(l);
351 assert_se(strv_isempty(l));
0745ce75 352 strv_free(l);
0645b83a 353
0745ce75
YW
354 l = strv_split(" ", WHITESPACE);
355 assert_se(l);
356 assert_se(strv_isempty(l));
1f938af8 357 strv_free(l);
0645b83a 358
1f938af8
YW
359 l = strv_split(" ", NULL);
360 assert_se(l);
361 assert_se(strv_isempty(l));
0645b83a 362 l = strv_free(l);
1f938af8 363
90e30d76 364 assert_se(strv_split_full(&l, " ", NULL, 0) == 0);
1f938af8
YW
365 assert_se(l);
366 assert_se(strv_isempty(l));
0645b83a 367 l = strv_free(l);
1f938af8 368
90e30d76 369 assert_se(strv_split_full(&l, " ", WHITESPACE, EXTRACT_UNQUOTE) == 0);
1f938af8
YW
370 assert_se(l);
371 assert_se(strv_isempty(l));
0645b83a 372 l = strv_free(l);
1f938af8 373
90e30d76 374 assert_se(strv_split_full(&l, " ", NULL, EXTRACT_UNQUOTE) == 0);
1f938af8
YW
375 assert_se(l);
376 assert_se(strv_isempty(l));
0645b83a 377 l = strv_free(l);
1f938af8 378
90e30d76 379 assert_se(strv_split_full(&l, " ", NULL, EXTRACT_UNQUOTE | EXTRACT_RELAX) == 0);
1f938af8
YW
380 assert_se(l);
381 assert_se(strv_isempty(l));
aed2ebfe
DB
382}
383
4f7452a8 384TEST(strv_split_full) {
8adaf7bd
RM
385 _cleanup_strv_free_ char **l = NULL;
386 const char *str = ":foo\\:bar::waldo:";
387 int r;
388
90e30d76 389 r = strv_split_full(&l, str, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
8dd4c05b 390 assert_se(r == (int) strv_length(l));
8adaf7bd
RM
391 assert_se(streq_ptr(l[0], ""));
392 assert_se(streq_ptr(l[1], "foo:bar"));
393 assert_se(streq_ptr(l[2], ""));
394 assert_se(streq_ptr(l[3], "waldo"));
395 assert_se(streq_ptr(l[4], ""));
396 assert_se(streq_ptr(l[5], NULL));
397}
398
4f7452a8 399TEST(strv_split_and_extend_full) {
3c318caa
FS
400 _cleanup_strv_free_ char **l = NULL;
401 const char *str1 = ":foo\\:bar:";
402 const char *str2 = "waldo::::::baz";
403 int r;
404
3c318caa
FS
405 r = strv_split_and_extend(&l, "", ":", false);
406 assert_se(r == (int) strv_length(l));
407 r = strv_split_and_extend_full(&l, str1, ":", false, EXTRACT_DONT_COALESCE_SEPARATORS);
408 assert_se(r == (int) strv_length(l));
409 assert_se(streq_ptr(l[0], ""));
410 assert_se(streq_ptr(l[1], "foo:bar"));
411 assert_se(streq_ptr(l[2], ""));
412 r = strv_split_and_extend_full(&l, str2, ":", false, 0);
413 assert_se(r == (int) strv_length(l));
414 assert_se(streq_ptr(l[3], "waldo"));
415 assert_se(streq_ptr(l[4], "baz"));
416 assert_se(streq_ptr(l[5], NULL));
417}
418
4f7452a8 419TEST(strv_split_colon_pairs) {
a082edd5
LB
420 _cleanup_strv_free_ char **l = NULL;
421 const char *str = "one:two three four:five six seven:eight\\:nine ten\\:eleven\\\\",
422 *str_inval="one:two three:four:five";
423 int r;
424
a082edd5
LB
425 r = strv_split_colon_pairs(&l, str);
426 assert_se(r == (int) strv_length(l));
427 assert_se(r == 12);
428 assert_se(streq_ptr(l[0], "one"));
429 assert_se(streq_ptr(l[1], "two"));
430 assert_se(streq_ptr(l[2], "three"));
431 assert_se(streq_ptr(l[3], ""));
432 assert_se(streq_ptr(l[4], "four"));
433 assert_se(streq_ptr(l[5], "five"));
434 assert_se(streq_ptr(l[6], "six"));
435 assert_se(streq_ptr(l[7], ""));
436 assert_se(streq_ptr(l[8], "seven"));
437 assert_se(streq_ptr(l[9], "eight:nine"));
438 assert_se(streq_ptr(l[10], "ten:eleven\\"));
439 assert_se(streq_ptr(l[11], ""));
440 assert_se(streq_ptr(l[12], NULL));
441
442 r = strv_split_colon_pairs(&l, str_inval);
443 assert_se(r == -EINVAL);
444}
445
4f7452a8 446TEST(strv_split_newlines) {
aed2ebfe 447 unsigned i = 0;
aed2ebfe
DB
448 _cleanup_strv_free_ char **l = NULL;
449 const char str[] = "one\ntwo\nthree";
450
0bf2c5e5 451 l = strv_split_newlines(str);
bdf7026e 452 assert_se(l);
aed2ebfe 453
38cd55b0 454 STRV_FOREACH(s, l)
aed2ebfe 455 assert_se(streq(*s, input_table_multiple[i++]));
aed2ebfe
DB
456}
457
4f7452a8 458TEST(strv_split_newlines_full) {
f385c447
YW
459 const char str[] =
460 "ID_VENDOR=QEMU\n"
461 "ID_VENDOR_ENC=QEMU\\x20\\x20\\x20\\x20\n"
462 "ID_MODEL_ENC=QEMU\\x20HARDDISK\\x20\\x20\\x20\n"
463 "\n\n\n";
464 _cleanup_strv_free_ char **l = NULL;
465
f385c447
YW
466 assert_se(strv_split_newlines_full(&l, str, 0) == 3);
467 assert_se(strv_equal(l, (char**) input_table_unescape));
468
469 l = strv_free(l);
470
471 assert_se(strv_split_newlines_full(&l, str, EXTRACT_RETAIN_ESCAPE) == 3);
472 assert_se(strv_equal(l, (char**) input_table_retain_escape));
473}
474
4f7452a8 475TEST(strv_split_nulstr) {
2f213f74
DB
476 _cleanup_strv_free_ char **l = NULL;
477 const char nulstr[] = "str0\0str1\0str2\0str3\0";
478
479 l = strv_split_nulstr (nulstr);
04045d84 480 assert_se(l);
2f213f74
DB
481
482 assert_se(streq(l[0], "str0"));
483 assert_se(streq(l[1], "str1"));
484 assert_se(streq(l[2], "str2"));
485 assert_se(streq(l[3], "str3"));
486}
487
4f7452a8 488TEST(strv_parse_nulstr) {
10ddd913 489 _cleanup_strv_free_ char **l = NULL;
a2917d3d 490 const char nulstr[] = "hoge\0hoge2\0hoge3\0\0hoge5\0\0xxx";
10ddd913
TA
491
492 l = strv_parse_nulstr(nulstr, sizeof(nulstr)-1);
04045d84 493 assert_se(l);
10ddd913
TA
494 puts("Parse nulstr:");
495 strv_print(l);
496
a2917d3d
YW
497 assert_se(streq(l[0], "hoge"));
498 assert_se(streq(l[1], "hoge2"));
499 assert_se(streq(l[2], "hoge3"));
7b68d618 500 assert_se(streq(l[3], ""));
a2917d3d 501 assert_se(streq(l[4], "hoge5"));
7b68d618
DB
502 assert_se(streq(l[5], ""));
503 assert_se(streq(l[6], "xxx"));
10ddd913
TA
504}
505
4f7452a8 506TEST(strv_overlap) {
539ad707
TA
507 const char * const input_table[] = {
508 "one",
509 "two",
510 "three",
511 NULL
512 };
513 const char * const input_table_overlap[] = {
514 "two",
515 NULL
516 };
517 const char * const input_table_unique[] = {
518 "four",
519 "five",
520 "six",
521 NULL
522 };
523
7b68d618
DB
524 assert_se(strv_overlap((char **)input_table, (char**)input_table_overlap));
525 assert_se(!strv_overlap((char **)input_table, (char**)input_table_unique));
539ad707
TA
526}
527
4f7452a8 528TEST(strv_sort) {
1e64bbc1 529 const char* input_table[] = {
539ad707
TA
530 "durian",
531 "apple",
532 "citrus",
533 "CAPITAL LETTERS FIRST",
534 "banana",
535 NULL
536 };
537
538 strv_sort((char **)input_table);
539
7b68d618
DB
540 assert_se(streq(input_table[0], "CAPITAL LETTERS FIRST"));
541 assert_se(streq(input_table[1], "apple"));
542 assert_se(streq(input_table[2], "banana"));
543 assert_se(streq(input_table[3], "citrus"));
544 assert_se(streq(input_table[4], "durian"));
3a7719d3 545}
e3aa71c3 546
4f7452a8 547TEST(strv_extend_strv_concat) {
7d6884b6 548 _cleanup_strv_free_ char **a = NULL, **b = NULL;
343a8969 549
bea1a013
LP
550 a = strv_new("without", "suffix");
551 b = strv_new("with", "suffix");
04045d84
DB
552 assert_se(a);
553 assert_se(b);
343a8969 554
e3e45d4f 555 assert_se(strv_extend_strv_concat(&a, b, "_suffix") >= 0);
343a8969 556
e3e45d4f
SP
557 assert_se(streq(a[0], "without"));
558 assert_se(streq(a[1], "suffix"));
559 assert_se(streq(a[2], "with_suffix"));
560 assert_se(streq(a[3], "suffix_suffix"));
343a8969
DB
561}
562
4f7452a8 563TEST(strv_extend_strv) {
ea9b54f8 564 _cleanup_strv_free_ char **a = NULL, **b = NULL, **n = NULL;
a1022300 565
bea1a013
LP
566 a = strv_new("abc", "def", "ghi");
567 b = strv_new("jkl", "mno", "abc", "pqr");
04045d84
DB
568 assert_se(a);
569 assert_se(b);
a1022300 570
e287086b 571 assert_se(strv_extend_strv(&a, b, true) == 3);
a1022300 572
e3e45d4f
SP
573 assert_se(streq(a[0], "abc"));
574 assert_se(streq(a[1], "def"));
575 assert_se(streq(a[2], "ghi"));
576 assert_se(streq(a[3], "jkl"));
577 assert_se(streq(a[4], "mno"));
578 assert_se(streq(a[5], "pqr"));
e3e45d4f 579 assert_se(strv_length(a) == 6);
ea9b54f8
ZJS
580
581 assert_se(strv_extend_strv(&n, b, false) >= 0);
582 assert_se(streq(n[0], "jkl"));
583 assert_se(streq(n[1], "mno"));
584 assert_se(streq(n[2], "abc"));
585 assert_se(streq(n[3], "pqr"));
586 assert_se(strv_length(n) == 4);
a1022300
DB
587}
588
4f7452a8 589TEST(strv_extend) {
e3e45d4f 590 _cleanup_strv_free_ char **a = NULL, **b = NULL;
40857008 591
bea1a013 592 a = strv_new("test", "test1");
04045d84 593 assert_se(a);
e3e45d4f
SP
594 assert_se(strv_extend(&a, "test2") >= 0);
595 assert_se(strv_extend(&b, "test3") >= 0);
40857008 596
e3e45d4f
SP
597 assert_se(streq(a[0], "test"));
598 assert_se(streq(a[1], "test1"));
599 assert_se(streq(a[2], "test2"));
600 assert_se(streq(b[0], "test3"));
40857008
DB
601}
602
4f7452a8 603TEST(strv_extendf) {
4a336a69
RC
604 _cleanup_strv_free_ char **a = NULL, **b = NULL;
605
bea1a013 606 a = strv_new("test", "test1");
4a336a69
RC
607 assert_se(a);
608 assert_se(strv_extendf(&a, "test2 %s %d %s", "foo", 128, "bar") >= 0);
609 assert_se(strv_extendf(&b, "test3 %s %s %d", "bar", "foo", 128) >= 0);
610
611 assert_se(streq(a[0], "test"));
612 assert_se(streq(a[1], "test1"));
613 assert_se(streq(a[2], "test2 foo 128 bar"));
614 assert_se(streq(b[0], "test3 bar foo 128"));
615}
616
4f7452a8 617TEST(strv_foreach) {
250a918d
LP
618 _cleanup_strv_free_ char **a;
619 unsigned i = 0;
02f19706 620
0bf2c5e5 621 a = strv_new("one", "two", "three");
250a918d 622 assert_se(a);
02f19706 623
0bf2c5e5 624 STRV_FOREACH(check, a)
250a918d 625 assert_se(streq(*check, input_table_multiple[i++]));
02f19706
DB
626}
627
4f7452a8 628TEST(strv_foreach_backwards) {
250a918d
LP
629 _cleanup_strv_free_ char **a;
630 unsigned i = 2;
02f19706 631
bea1a013 632 a = strv_new("one", "two", "three");
02f19706 633
250a918d 634 assert_se(a);
02f19706 635
4a39c774 636 STRV_FOREACH_BACKWARDS(check, a)
5fba7bbf 637 assert_se(streq_ptr(*check, input_table_multiple[i--]));
4a39c774
LP
638
639 STRV_FOREACH_BACKWARDS(check, (char**) NULL)
04499a70 640 assert_not_reached();
4a39c774
LP
641
642 STRV_FOREACH_BACKWARDS(check, (char**) { NULL })
04499a70 643 assert_not_reached();
02f19706
DB
644}
645
4f7452a8 646TEST(strv_foreach_pair) {
4c325b2e 647 _cleanup_strv_free_ char **a = NULL;
4c325b2e
DB
648
649 a = strv_new("pair_one", "pair_one",
650 "pair_two", "pair_two",
bea1a013 651 "pair_three", "pair_three");
0bf2c5e5 652 STRV_FOREACH_PAIR(x, y, a)
4c325b2e 653 assert_se(streq(*x, *y));
4c325b2e
DB
654}
655
897e7561 656static void test_strv_from_stdarg_alloca_one(char **l, const char *first, ...) {
250a918d
LP
657 char **j;
658 unsigned i;
659
0bf2c5e5
ZJS
660 log_info("/* %s */", __func__);
661
250a918d
LP
662 j = strv_from_stdarg_alloca(first);
663
664 for (i = 0;; i++) {
665 assert_se(streq_ptr(l[i], j[i]));
666
667 if (!l[i])
668 break;
669 }
670}
671
4f7452a8 672TEST(strv_from_stdarg_alloca) {
897e7561
LP
673 test_strv_from_stdarg_alloca_one(STRV_MAKE("foo", "bar"), "foo", "bar", NULL);
674 test_strv_from_stdarg_alloca_one(STRV_MAKE("foo"), "foo", NULL);
675 test_strv_from_stdarg_alloca_one(STRV_MAKE_EMPTY, NULL);
250a918d
LP
676}
677
4f7452a8 678TEST(strv_insert) {
6e888894
ZJS
679 _cleanup_strv_free_ char **a = NULL;
680
681 assert_se(strv_insert(&a, 0, strdup("first")) == 0);
682 assert_se(streq(a[0], "first"));
683 assert_se(!a[1]);
684
685 assert_se(strv_insert(&a, 0, NULL) == 0);
686 assert_se(streq(a[0], "first"));
687 assert_se(!a[1]);
688
689 assert_se(strv_insert(&a, 1, strdup("two")) == 0);
690 assert_se(streq(a[0], "first"));
691 assert_se(streq(a[1], "two"));
692 assert_se(!a[2]);
693
694 assert_se(strv_insert(&a, 4, strdup("tri")) == 0);
695 assert_se(streq(a[0], "first"));
696 assert_se(streq(a[1], "two"));
697 assert_se(streq(a[2], "tri"));
698 assert_se(!a[3]);
699
700 assert_se(strv_insert(&a, 1, strdup("duo")) == 0);
701 assert_se(streq(a[0], "first"));
702 assert_se(streq(a[1], "duo"));
703 assert_se(streq(a[2], "two"));
704 assert_se(streq(a[3], "tri"));
705 assert_se(!a[4]);
706}
707
4f7452a8 708TEST(strv_push_prepend) {
7bd57a87
RC
709 _cleanup_strv_free_ char **a = NULL;
710
42b97781 711 assert_se(a = strv_new("foo", "bar", "three"));
7bd57a87
RC
712
713 assert_se(strv_push_prepend(&a, strdup("first")) >= 0);
714 assert_se(streq(a[0], "first"));
715 assert_se(streq(a[1], "foo"));
716 assert_se(streq(a[2], "bar"));
717 assert_se(streq(a[3], "three"));
718 assert_se(!a[4]);
719
720 assert_se(strv_consume_prepend(&a, strdup("first2")) >= 0);
721 assert_se(streq(a[0], "first2"));
722 assert_se(streq(a[1], "first"));
723 assert_se(streq(a[2], "foo"));
724 assert_se(streq(a[3], "bar"));
725 assert_se(streq(a[4], "three"));
726 assert_se(!a[5]);
727}
728
4f7452a8 729TEST(strv_push) {
98940a3c
LP
730 _cleanup_strv_free_ char **a = NULL;
731 char *i, *j;
732
733 assert_se(i = strdup("foo"));
734 assert_se(strv_push(&a, i) >= 0);
735
736 assert_se(i = strdup("a"));
737 assert_se(j = strdup("b"));
738 assert_se(strv_push_pair(&a, i, j) >= 0);
739
740 assert_se(streq_ptr(a[0], "foo"));
741 assert_se(streq_ptr(a[1], "a"));
742 assert_se(streq_ptr(a[2], "b"));
743 assert_se(streq_ptr(a[3], NULL));
744}
745
4f7452a8 746TEST(strv_compare) {
e74aa253
RC
747 _cleanup_strv_free_ char **a = NULL;
748 _cleanup_strv_free_ char **b = NULL;
749 _cleanup_strv_free_ char **c = NULL;
8b75798d 750 _cleanup_strv_free_ char **d = NULL;
e74aa253 751
bea1a013 752 a = strv_new("one", "two", "three");
e74aa253 753 assert_se(a);
bea1a013 754 b = strv_new("one", "two", "three");
8b75798d 755 assert_se(b);
bea1a013 756 c = strv_new("one", "two", "three", "four");
8b75798d
YW
757 assert_se(c);
758 d = strv_new(NULL);
759 assert_se(d);
e74aa253 760
8b75798d
YW
761 assert_se(strv_compare(a, a) == 0);
762 assert_se(strv_compare(a, b) == 0);
763 assert_se(strv_compare(d, d) == 0);
764 assert_se(strv_compare(d, NULL) == 0);
765 assert_se(strv_compare(NULL, NULL) == 0);
e74aa253 766
8b75798d
YW
767 assert_se(strv_compare(a, c) < 0);
768 assert_se(strv_compare(b, c) < 0);
769 assert_se(strv_compare(b, d) == 1);
770 assert_se(strv_compare(b, NULL) == 1);
e74aa253
RC
771}
772
4f7452a8 773TEST(strv_is_uniq) {
e1dd6790
LP
774 _cleanup_strv_free_ char **a = NULL, **b = NULL, **c = NULL, **d = NULL;
775
bea1a013 776 a = strv_new(NULL);
e1dd6790
LP
777 assert_se(a);
778 assert_se(strv_is_uniq(a));
779
bea1a013 780 b = strv_new("foo");
e1dd6790
LP
781 assert_se(b);
782 assert_se(strv_is_uniq(b));
783
bea1a013 784 c = strv_new("foo", "bar");
e1dd6790
LP
785 assert_se(c);
786 assert_se(strv_is_uniq(c));
787
bea1a013 788 d = strv_new("foo", "bar", "waldo", "bar", "piep");
e1dd6790
LP
789 assert_se(d);
790 assert_se(!strv_is_uniq(d));
791}
792
4f7452a8 793TEST(strv_reverse) {
e1dd6790
LP
794 _cleanup_strv_free_ char **a = NULL, **b = NULL, **c = NULL, **d = NULL;
795
bea1a013 796 a = strv_new(NULL);
e1dd6790
LP
797 assert_se(a);
798
799 strv_reverse(a);
800 assert_se(strv_isempty(a));
801
bea1a013 802 b = strv_new("foo");
e1dd6790
LP
803 assert_se(b);
804 strv_reverse(b);
805 assert_se(streq_ptr(b[0], "foo"));
806 assert_se(streq_ptr(b[1], NULL));
807
bea1a013 808 c = strv_new("foo", "bar");
e1dd6790
LP
809 assert_se(c);
810 strv_reverse(c);
811 assert_se(streq_ptr(c[0], "bar"));
812 assert_se(streq_ptr(c[1], "foo"));
813 assert_se(streq_ptr(c[2], NULL));
814
bea1a013 815 d = strv_new("foo", "bar", "waldo");
e1dd6790
LP
816 assert_se(d);
817 strv_reverse(d);
818 assert_se(streq_ptr(d[0], "waldo"));
819 assert_se(streq_ptr(d[1], "bar"));
820 assert_se(streq_ptr(d[2], "foo"));
821 assert_se(streq_ptr(d[3], NULL));
822}
823
4f7452a8 824TEST(strv_shell_escape) {
04c14b25
RM
825 _cleanup_strv_free_ char **v = NULL;
826
bea1a013 827 v = strv_new("foo:bar", "bar,baz", "wal\\do");
04c14b25
RM
828 assert_se(v);
829 assert_se(strv_shell_escape(v, ",:"));
830 assert_se(streq_ptr(v[0], "foo\\:bar"));
831 assert_se(streq_ptr(v[1], "bar\\,baz"));
832 assert_se(streq_ptr(v[2], "wal\\\\do"));
833 assert_se(streq_ptr(v[3], NULL));
834}
835
e3ead6bb
LP
836static void test_strv_skip_one(char **a, size_t n, char **b) {
837 a = strv_skip(a, n);
838 assert_se(strv_equal(a, b));
839}
840
4f7452a8 841TEST(strv_skip) {
e3ead6bb
LP
842 test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 0, STRV_MAKE("foo", "bar", "baz"));
843 test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 1, STRV_MAKE("bar", "baz"));
844 test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 2, STRV_MAKE("baz"));
845 test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 3, STRV_MAKE(NULL));
846 test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 4, STRV_MAKE(NULL));
847 test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 55, STRV_MAKE(NULL));
848
849 test_strv_skip_one(STRV_MAKE("quux"), 0, STRV_MAKE("quux"));
850 test_strv_skip_one(STRV_MAKE("quux"), 1, STRV_MAKE(NULL));
851 test_strv_skip_one(STRV_MAKE("quux"), 55, STRV_MAKE(NULL));
852
853 test_strv_skip_one(STRV_MAKE(NULL), 0, STRV_MAKE(NULL));
854 test_strv_skip_one(STRV_MAKE(NULL), 1, STRV_MAKE(NULL));
855 test_strv_skip_one(STRV_MAKE(NULL), 55, STRV_MAKE(NULL));
856}
857
4f7452a8 858TEST(strv_extend_n) {
8dd4c05b
LP
859 _cleanup_strv_free_ char **v = NULL;
860
bea1a013 861 v = strv_new("foo", "bar");
8dd4c05b
LP
862 assert_se(v);
863
864 assert_se(strv_extend_n(&v, "waldo", 3) >= 0);
865 assert_se(strv_extend_n(&v, "piep", 2) >= 0);
866
867 assert_se(streq(v[0], "foo"));
868 assert_se(streq(v[1], "bar"));
869 assert_se(streq(v[2], "waldo"));
870 assert_se(streq(v[3], "waldo"));
871 assert_se(streq(v[4], "waldo"));
872 assert_se(streq(v[5], "piep"));
873 assert_se(streq(v[6], "piep"));
874 assert_se(v[7] == NULL);
875
876 v = strv_free(v);
877
878 assert_se(strv_extend_n(&v, "foo", 1) >= 0);
879 assert_se(strv_extend_n(&v, "bar", 0) >= 0);
880
881 assert_se(streq(v[0], "foo"));
882 assert_se(v[1] == NULL);
883}
884
e287086b
LP
885static void test_strv_make_nulstr_one(char **l) {
886 _cleanup_free_ char *b = NULL, *c = NULL;
887 _cleanup_strv_free_ char **q = NULL;
f41794d0 888 const char *s = NULL;
e287086b 889 size_t n, m;
f41794d0 890 unsigned i = 0;
e287086b 891
0bf2c5e5
ZJS
892 log_info("/* %s */", __func__);
893
e287086b
LP
894 assert_se(strv_make_nulstr(l, &b, &n) >= 0);
895 assert_se(q = strv_parse_nulstr(b, n));
896 assert_se(strv_equal(l, q));
897
898 assert_se(strv_make_nulstr(q, &c, &m) >= 0);
899 assert_se(m == n);
900 assert_se(memcmp(b, c, m) == 0);
f41794d0 901
b60df13b 902 NULSTR_FOREACH(s, b)
f41794d0 903 assert_se(streq(s, l[i++]));
f41794d0 904 assert_se(i == strv_length(l));
e287086b
LP
905}
906
4f7452a8 907TEST(strv_make_nulstr) {
e287086b
LP
908 test_strv_make_nulstr_one(NULL);
909 test_strv_make_nulstr_one(STRV_MAKE(NULL));
910 test_strv_make_nulstr_one(STRV_MAKE("foo"));
911 test_strv_make_nulstr_one(STRV_MAKE("foo", "bar"));
912 test_strv_make_nulstr_one(STRV_MAKE("foo", "bar", "quuux"));
913}
914
4f7452a8 915TEST(foreach_string) {
ebde5cb2
RC
916 const char * const t[] = {
917 "foo",
918 "bar",
919 "waldo",
920 NULL
921 };
922 const char *x;
923 unsigned i = 0;
924
925 FOREACH_STRING(x, "foo", "bar", "waldo")
926 assert_se(streq_ptr(t[i++], x));
927
928 assert_se(i == 3);
929
930 FOREACH_STRING(x, "zzz")
931 assert_se(streq(x, "zzz"));
932}
933
4f7452a8 934TEST(strv_fnmatch) {
57681e84 935 _cleanup_strv_free_ char **v = NULL;
0ef84b80 936 size_t pos;
2027927b 937
191a3f16 938 assert_se(!strv_fnmatch(STRV_MAKE_EMPTY, "a"));
2027927b 939
0ef84b80
ZJS
940 v = strv_new("xxx", "*\\*", "yyy");
941 assert_se(!strv_fnmatch_full(v, "\\", 0, NULL));
942 assert_se(strv_fnmatch_full(v, "\\", FNM_NOESCAPE, &pos));
f21b863e 943 assert_se(pos == 1);
2027927b
EV
944}
945
4f7452a8 946DEFINE_TEST_MAIN(LOG_INFO);