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