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