]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-strv.c
Merge pull request #10138 from yuwata/test-check-container
[thirdparty/systemd.git] / src / test / test-strv.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <string.h>
4
5 #include "alloc-util.h"
6 #include "escape.h"
7 #include "specifier.h"
8 #include "string-util.h"
9 #include "strv.h"
10 #include "util.h"
11
12 static void test_specifier_printf(void) {
13 static const Specifier table[] = {
14 { 'a', specifier_string, (char*) "AAAA" },
15 { 'b', specifier_string, (char*) "BBBB" },
16 { 'm', specifier_machine_id, NULL },
17 { 'B', specifier_boot_id, NULL },
18 { 'H', specifier_host_name, NULL },
19 { 'v', specifier_kernel_release, NULL },
20 {}
21 };
22
23 _cleanup_free_ char *w = NULL;
24 int r;
25
26 r = specifier_printf("xxx a=%a b=%b yyy", table, NULL, &w);
27 assert_se(r >= 0);
28 assert_se(w);
29
30 puts(w);
31 assert_se(streq(w, "xxx a=AAAA b=BBBB yyy"));
32
33 free(w);
34 r = specifier_printf("machine=%m, boot=%B, host=%H, version=%v", table, NULL, &w);
35 assert_se(r >= 0);
36 assert_se(w);
37 puts(w);
38 }
39
40 static void test_str_in_set(void) {
41 assert_se(STR_IN_SET("x", "x", "y", "z"));
42 assert_se(!STR_IN_SET("X", "x", "y", "z"));
43 assert_se(!STR_IN_SET("", "x", "y", "z"));
44 assert_se(STR_IN_SET("x", "w", "x"));
45 }
46
47 static void test_strptr_in_set(void) {
48 assert_se(STRPTR_IN_SET("x", "x", "y", "z"));
49 assert_se(!STRPTR_IN_SET("X", "x", "y", "z"));
50 assert_se(!STRPTR_IN_SET("", "x", "y", "z"));
51 assert_se(STRPTR_IN_SET("x", "w", "x"));
52
53 assert_se(!STRPTR_IN_SET(NULL, "x", "y", "z"));
54 assert_se(!STRPTR_IN_SET(NULL, ""));
55 /* strv cannot contain a null, hence the result below */
56 assert_se(!STRPTR_IN_SET(NULL, NULL));
57 }
58
59 static const char* const input_table_multiple[] = {
60 "one",
61 "two",
62 "three",
63 NULL,
64 };
65
66 static const char* const input_table_one[] = {
67 "one",
68 NULL,
69 };
70
71 static const char* const input_table_none[] = {
72 NULL,
73 };
74
75 static const char* const input_table_two_empties[] = {
76 "",
77 "",
78 NULL,
79 };
80
81 static const char* const input_table_one_empty[] = {
82 "",
83 NULL,
84 };
85
86 static void test_strv_find(void) {
87 assert_se(strv_find((char **)input_table_multiple, "three"));
88 assert_se(!strv_find((char **)input_table_multiple, "four"));
89 }
90
91 static void test_strv_find_prefix(void) {
92 assert_se(strv_find_prefix((char **)input_table_multiple, "o"));
93 assert_se(strv_find_prefix((char **)input_table_multiple, "one"));
94 assert_se(strv_find_prefix((char **)input_table_multiple, ""));
95 assert_se(!strv_find_prefix((char **)input_table_multiple, "xxx"));
96 assert_se(!strv_find_prefix((char **)input_table_multiple, "onee"));
97 }
98
99 static void test_strv_find_startswith(void) {
100 char *r;
101
102 r = strv_find_startswith((char **)input_table_multiple, "o");
103 assert_se(r && streq(r, "ne"));
104
105 r = strv_find_startswith((char **)input_table_multiple, "one");
106 assert_se(r && streq(r, ""));
107
108 r = strv_find_startswith((char **)input_table_multiple, "");
109 assert_se(r && streq(r, "one"));
110
111 assert_se(!strv_find_startswith((char **)input_table_multiple, "xxx"));
112 assert_se(!strv_find_startswith((char **)input_table_multiple, "onee"));
113 }
114
115 static void test_strv_join(void) {
116 _cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL, *v = NULL, *w = NULL;
117
118 p = strv_join((char **)input_table_multiple, ", ");
119 assert_se(p);
120 assert_se(streq(p, "one, two, three"));
121
122 q = strv_join((char **)input_table_multiple, ";");
123 assert_se(q);
124 assert_se(streq(q, "one;two;three"));
125
126 r = strv_join((char **)input_table_multiple, NULL);
127 assert_se(r);
128 assert_se(streq(r, "one two three"));
129
130 s = strv_join((char **)input_table_one, ", ");
131 assert_se(s);
132 assert_se(streq(s, "one"));
133
134 t = strv_join((char **)input_table_none, ", ");
135 assert_se(t);
136 assert_se(streq(t, ""));
137
138 v = strv_join((char **)input_table_two_empties, ", ");
139 assert_se(v);
140 assert_se(streq(v, ", "));
141
142 w = strv_join((char **)input_table_one_empty, ", ");
143 assert_se(w);
144 assert_se(streq(w, ""));
145 }
146
147 static void test_strv_join_prefix(void) {
148 _cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL, *v = NULL, *w = NULL;
149
150 p = strv_join_prefix((char **)input_table_multiple, ", ", "foo");
151 assert_se(p);
152 assert_se(streq(p, "fooone, footwo, foothree"));
153
154 q = strv_join_prefix((char **)input_table_multiple, ";", "foo");
155 assert_se(q);
156 assert_se(streq(q, "fooone;footwo;foothree"));
157
158 r = strv_join_prefix((char **)input_table_multiple, NULL, "foo");
159 assert_se(r);
160 assert_se(streq(r, "fooone footwo foothree"));
161
162 s = strv_join_prefix((char **)input_table_one, ", ", "foo");
163 assert_se(s);
164 assert_se(streq(s, "fooone"));
165
166 t = strv_join_prefix((char **)input_table_none, ", ", "foo");
167 assert_se(t);
168 assert_se(streq(t, ""));
169
170 v = strv_join_prefix((char **)input_table_two_empties, ", ", "foo");
171 assert_se(v);
172 assert_se(streq(v, "foo, foo"));
173
174 w = strv_join_prefix((char **)input_table_one_empty, ", ", "foo");
175 assert_se(w);
176 assert_se(streq(w, "foo"));
177 }
178
179 static void test_strv_unquote(const char *quoted, char **list) {
180 _cleanup_strv_free_ char **s;
181 _cleanup_free_ char *j;
182 unsigned i = 0;
183 char **t;
184 int r;
185
186 r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_QUOTES);
187 assert_se(r == (int) strv_length(list));
188 assert_se(s);
189 j = strv_join(s, " | ");
190 assert_se(j);
191 puts(j);
192
193 STRV_FOREACH(t, s)
194 assert_se(streq(list[i++], *t));
195
196 assert_se(list[i] == NULL);
197 }
198
199 static void test_invalid_unquote(const char *quoted) {
200 char **s = NULL;
201 int r;
202
203 r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_QUOTES);
204 assert_se(s == NULL);
205 assert_se(r == -EINVAL);
206 }
207
208 static void test_strv_split(void) {
209 char **s;
210 unsigned i = 0;
211 _cleanup_strv_free_ char **l = NULL;
212 const char str[] = "one,two,three";
213
214 l = strv_split(str, ",");
215 assert_se(l);
216 STRV_FOREACH(s, l)
217 assert_se(streq(*s, input_table_multiple[i++]));
218
219 i = 0;
220 strv_free(l);
221
222 l = strv_split(" one two\t three", WHITESPACE);
223 assert_se(l);
224 STRV_FOREACH(s, l)
225 assert_se(streq(*s, input_table_multiple[i++]));
226 }
227
228 static void test_strv_split_empty(void) {
229 _cleanup_strv_free_ char **l = NULL;
230
231 l = strv_split("", WHITESPACE);
232 assert_se(l);
233 assert_se(strv_isempty(l));
234
235 strv_free(l);
236 l = strv_split(" ", WHITESPACE);
237 assert_se(l);
238 assert_se(strv_isempty(l));
239
240 }
241
242 static void test_strv_split_extract(void) {
243 _cleanup_strv_free_ char **l = NULL;
244 const char *str = ":foo\\:bar::waldo:";
245 int r;
246
247 r = strv_split_extract(&l, str, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
248 assert_se(r == (int) strv_length(l));
249 assert_se(streq_ptr(l[0], ""));
250 assert_se(streq_ptr(l[1], "foo:bar"));
251 assert_se(streq_ptr(l[2], ""));
252 assert_se(streq_ptr(l[3], "waldo"));
253 assert_se(streq_ptr(l[4], ""));
254 assert_se(streq_ptr(l[5], NULL));
255 }
256
257 static void test_strv_split_newlines(void) {
258 unsigned i = 0;
259 char **s;
260 _cleanup_strv_free_ char **l = NULL;
261 const char str[] = "one\ntwo\nthree";
262
263 l = strv_split_newlines(str);
264
265 assert_se(l);
266
267 STRV_FOREACH(s, l) {
268 assert_se(streq(*s, input_table_multiple[i++]));
269 }
270 }
271
272 static void test_strv_split_nulstr(void) {
273 _cleanup_strv_free_ char **l = NULL;
274 const char nulstr[] = "str0\0str1\0str2\0str3\0";
275
276 l = strv_split_nulstr (nulstr);
277 assert_se(l);
278
279 assert_se(streq(l[0], "str0"));
280 assert_se(streq(l[1], "str1"));
281 assert_se(streq(l[2], "str2"));
282 assert_se(streq(l[3], "str3"));
283 }
284
285 static void test_strv_parse_nulstr(void) {
286 _cleanup_strv_free_ char **l = NULL;
287 const char nulstr[] = "hoge\0hoge2\0hoge3\0\0hoge5\0\0xxx";
288
289 l = strv_parse_nulstr(nulstr, sizeof(nulstr)-1);
290 assert_se(l);
291 puts("Parse nulstr:");
292 strv_print(l);
293
294 assert_se(streq(l[0], "hoge"));
295 assert_se(streq(l[1], "hoge2"));
296 assert_se(streq(l[2], "hoge3"));
297 assert_se(streq(l[3], ""));
298 assert_se(streq(l[4], "hoge5"));
299 assert_se(streq(l[5], ""));
300 assert_se(streq(l[6], "xxx"));
301 }
302
303 static void test_strv_overlap(void) {
304 const char * const input_table[] = {
305 "one",
306 "two",
307 "three",
308 NULL
309 };
310 const char * const input_table_overlap[] = {
311 "two",
312 NULL
313 };
314 const char * const input_table_unique[] = {
315 "four",
316 "five",
317 "six",
318 NULL
319 };
320
321 assert_se(strv_overlap((char **)input_table, (char**)input_table_overlap));
322 assert_se(!strv_overlap((char **)input_table, (char**)input_table_unique));
323 }
324
325 static void test_strv_sort(void) {
326 const char* input_table[] = {
327 "durian",
328 "apple",
329 "citrus",
330 "CAPITAL LETTERS FIRST",
331 "banana",
332 NULL
333 };
334
335 strv_sort((char **)input_table);
336
337 assert_se(streq(input_table[0], "CAPITAL LETTERS FIRST"));
338 assert_se(streq(input_table[1], "apple"));
339 assert_se(streq(input_table[2], "banana"));
340 assert_se(streq(input_table[3], "citrus"));
341 assert_se(streq(input_table[4], "durian"));
342 }
343
344 static void test_strv_extend_strv_concat(void) {
345 _cleanup_strv_free_ char **a = NULL, **b = NULL;
346
347 a = strv_new("without", "suffix", NULL);
348 b = strv_new("with", "suffix", NULL);
349 assert_se(a);
350 assert_se(b);
351
352 assert_se(strv_extend_strv_concat(&a, b, "_suffix") >= 0);
353
354 assert_se(streq(a[0], "without"));
355 assert_se(streq(a[1], "suffix"));
356 assert_se(streq(a[2], "with_suffix"));
357 assert_se(streq(a[3], "suffix_suffix"));
358 }
359
360 static void test_strv_extend_strv(void) {
361 _cleanup_strv_free_ char **a = NULL, **b = NULL, **n = NULL;
362
363 a = strv_new("abc", "def", "ghi", NULL);
364 b = strv_new("jkl", "mno", "abc", "pqr", NULL);
365 assert_se(a);
366 assert_se(b);
367
368 assert_se(strv_extend_strv(&a, b, true) == 3);
369
370 assert_se(streq(a[0], "abc"));
371 assert_se(streq(a[1], "def"));
372 assert_se(streq(a[2], "ghi"));
373 assert_se(streq(a[3], "jkl"));
374 assert_se(streq(a[4], "mno"));
375 assert_se(streq(a[5], "pqr"));
376 assert_se(strv_length(a) == 6);
377
378 assert_se(strv_extend_strv(&n, b, false) >= 0);
379 assert_se(streq(n[0], "jkl"));
380 assert_se(streq(n[1], "mno"));
381 assert_se(streq(n[2], "abc"));
382 assert_se(streq(n[3], "pqr"));
383 assert_se(strv_length(n) == 4);
384 }
385
386 static void test_strv_extend(void) {
387 _cleanup_strv_free_ char **a = NULL, **b = NULL;
388
389 a = strv_new("test", "test1", NULL);
390 assert_se(a);
391 assert_se(strv_extend(&a, "test2") >= 0);
392 assert_se(strv_extend(&b, "test3") >= 0);
393
394 assert_se(streq(a[0], "test"));
395 assert_se(streq(a[1], "test1"));
396 assert_se(streq(a[2], "test2"));
397 assert_se(streq(b[0], "test3"));
398 }
399
400 static void test_strv_extendf(void) {
401 _cleanup_strv_free_ char **a = NULL, **b = NULL;
402
403 a = strv_new("test", "test1", NULL);
404 assert_se(a);
405 assert_se(strv_extendf(&a, "test2 %s %d %s", "foo", 128, "bar") >= 0);
406 assert_se(strv_extendf(&b, "test3 %s %s %d", "bar", "foo", 128) >= 0);
407
408 assert_se(streq(a[0], "test"));
409 assert_se(streq(a[1], "test1"));
410 assert_se(streq(a[2], "test2 foo 128 bar"));
411 assert_se(streq(b[0], "test3 bar foo 128"));
412 }
413
414 static void test_strv_foreach(void) {
415 _cleanup_strv_free_ char **a;
416 unsigned i = 0;
417 char **check;
418
419 a = strv_new("one", "two", "three", NULL);
420
421 assert_se(a);
422
423 STRV_FOREACH(check, a) {
424 assert_se(streq(*check, input_table_multiple[i++]));
425 }
426 }
427
428 static void test_strv_foreach_backwards(void) {
429 _cleanup_strv_free_ char **a;
430 unsigned i = 2;
431 char **check;
432
433 a = strv_new("one", "two", "three", NULL);
434
435 assert_se(a);
436
437 STRV_FOREACH_BACKWARDS(check, a)
438 assert_se(streq_ptr(*check, input_table_multiple[i--]));
439
440 STRV_FOREACH_BACKWARDS(check, (char**) NULL)
441 assert_not_reached("Let's see that we check empty strv right, too.");
442
443 STRV_FOREACH_BACKWARDS(check, (char**) { NULL })
444 assert_not_reached("Let's see that we check empty strv right, too.");
445 }
446
447 static void test_strv_foreach_pair(void) {
448 _cleanup_strv_free_ char **a = NULL;
449 char **x, **y;
450
451 a = strv_new("pair_one", "pair_one",
452 "pair_two", "pair_two",
453 "pair_three", "pair_three",
454 NULL);
455
456 STRV_FOREACH_PAIR(x, y, a) {
457 assert_se(streq(*x, *y));
458 }
459 }
460
461 static void test_strv_from_stdarg_alloca_one(char **l, const char *first, ...) {
462 char **j;
463 unsigned i;
464
465 j = strv_from_stdarg_alloca(first);
466
467 for (i = 0;; i++) {
468 assert_se(streq_ptr(l[i], j[i]));
469
470 if (!l[i])
471 break;
472 }
473 }
474
475 static void test_strv_from_stdarg_alloca(void) {
476 test_strv_from_stdarg_alloca_one(STRV_MAKE("foo", "bar"), "foo", "bar", NULL);
477 test_strv_from_stdarg_alloca_one(STRV_MAKE("foo"), "foo", NULL);
478 test_strv_from_stdarg_alloca_one(STRV_MAKE_EMPTY, NULL);
479 }
480
481 static void test_strv_insert(void) {
482 _cleanup_strv_free_ char **a = NULL;
483
484 assert_se(strv_insert(&a, 0, strdup("first")) == 0);
485 assert_se(streq(a[0], "first"));
486 assert_se(!a[1]);
487
488 assert_se(strv_insert(&a, 0, NULL) == 0);
489 assert_se(streq(a[0], "first"));
490 assert_se(!a[1]);
491
492 assert_se(strv_insert(&a, 1, strdup("two")) == 0);
493 assert_se(streq(a[0], "first"));
494 assert_se(streq(a[1], "two"));
495 assert_se(!a[2]);
496
497 assert_se(strv_insert(&a, 4, strdup("tri")) == 0);
498 assert_se(streq(a[0], "first"));
499 assert_se(streq(a[1], "two"));
500 assert_se(streq(a[2], "tri"));
501 assert_se(!a[3]);
502
503 assert_se(strv_insert(&a, 1, strdup("duo")) == 0);
504 assert_se(streq(a[0], "first"));
505 assert_se(streq(a[1], "duo"));
506 assert_se(streq(a[2], "two"));
507 assert_se(streq(a[3], "tri"));
508 assert_se(!a[4]);
509 }
510
511 static void test_strv_push_prepend(void) {
512 _cleanup_strv_free_ char **a = NULL;
513
514 a = strv_new("foo", "bar", "three", NULL);
515
516 assert_se(strv_push_prepend(&a, strdup("first")) >= 0);
517 assert_se(streq(a[0], "first"));
518 assert_se(streq(a[1], "foo"));
519 assert_se(streq(a[2], "bar"));
520 assert_se(streq(a[3], "three"));
521 assert_se(!a[4]);
522
523 assert_se(strv_consume_prepend(&a, strdup("first2")) >= 0);
524 assert_se(streq(a[0], "first2"));
525 assert_se(streq(a[1], "first"));
526 assert_se(streq(a[2], "foo"));
527 assert_se(streq(a[3], "bar"));
528 assert_se(streq(a[4], "three"));
529 assert_se(!a[5]);
530 }
531
532 static void test_strv_push(void) {
533 _cleanup_strv_free_ char **a = NULL;
534 char *i, *j;
535
536 assert_se(i = strdup("foo"));
537 assert_se(strv_push(&a, i) >= 0);
538
539 assert_se(i = strdup("a"));
540 assert_se(j = strdup("b"));
541 assert_se(strv_push_pair(&a, i, j) >= 0);
542
543 assert_se(streq_ptr(a[0], "foo"));
544 assert_se(streq_ptr(a[1], "a"));
545 assert_se(streq_ptr(a[2], "b"));
546 assert_se(streq_ptr(a[3], NULL));
547 }
548
549 static void test_strv_equal(void) {
550 _cleanup_strv_free_ char **a = NULL;
551 _cleanup_strv_free_ char **b = NULL;
552 _cleanup_strv_free_ char **c = NULL;
553
554 a = strv_new("one", "two", "three", NULL);
555 assert_se(a);
556 b = strv_new("one", "two", "three", NULL);
557 assert_se(a);
558 c = strv_new("one", "two", "three", "four", NULL);
559 assert_se(a);
560
561 assert_se(strv_equal(a, a));
562 assert_se(strv_equal(a, b));
563 assert_se(strv_equal(NULL, NULL));
564
565 assert_se(!strv_equal(a, c));
566 assert_se(!strv_equal(b, c));
567 assert_se(!strv_equal(b, NULL));
568 }
569
570 static void test_strv_is_uniq(void) {
571 _cleanup_strv_free_ char **a = NULL, **b = NULL, **c = NULL, **d = NULL;
572
573 a = strv_new(NULL, NULL);
574 assert_se(a);
575 assert_se(strv_is_uniq(a));
576
577 b = strv_new("foo", NULL);
578 assert_se(b);
579 assert_se(strv_is_uniq(b));
580
581 c = strv_new("foo", "bar", NULL);
582 assert_se(c);
583 assert_se(strv_is_uniq(c));
584
585 d = strv_new("foo", "bar", "waldo", "bar", "piep", NULL);
586 assert_se(d);
587 assert_se(!strv_is_uniq(d));
588 }
589
590 static void test_strv_reverse(void) {
591 _cleanup_strv_free_ char **a = NULL, **b = NULL, **c = NULL, **d = NULL;
592
593 a = strv_new(NULL, NULL);
594 assert_se(a);
595
596 strv_reverse(a);
597 assert_se(strv_isempty(a));
598
599 b = strv_new("foo", NULL);
600 assert_se(b);
601 strv_reverse(b);
602 assert_se(streq_ptr(b[0], "foo"));
603 assert_se(streq_ptr(b[1], NULL));
604
605 c = strv_new("foo", "bar", NULL);
606 assert_se(c);
607 strv_reverse(c);
608 assert_se(streq_ptr(c[0], "bar"));
609 assert_se(streq_ptr(c[1], "foo"));
610 assert_se(streq_ptr(c[2], NULL));
611
612 d = strv_new("foo", "bar", "waldo", NULL);
613 assert_se(d);
614 strv_reverse(d);
615 assert_se(streq_ptr(d[0], "waldo"));
616 assert_se(streq_ptr(d[1], "bar"));
617 assert_se(streq_ptr(d[2], "foo"));
618 assert_se(streq_ptr(d[3], NULL));
619 }
620
621 static void test_strv_shell_escape(void) {
622 _cleanup_strv_free_ char **v = NULL;
623
624 v = strv_new("foo:bar", "bar,baz", "wal\\do", NULL);
625 assert_se(v);
626 assert_se(strv_shell_escape(v, ",:"));
627 assert_se(streq_ptr(v[0], "foo\\:bar"));
628 assert_se(streq_ptr(v[1], "bar\\,baz"));
629 assert_se(streq_ptr(v[2], "wal\\\\do"));
630 assert_se(streq_ptr(v[3], NULL));
631 }
632
633 static void test_strv_skip_one(char **a, size_t n, char **b) {
634 a = strv_skip(a, n);
635 assert_se(strv_equal(a, b));
636 }
637
638 static void test_strv_skip(void) {
639 test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 0, STRV_MAKE("foo", "bar", "baz"));
640 test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 1, STRV_MAKE("bar", "baz"));
641 test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 2, STRV_MAKE("baz"));
642 test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 3, STRV_MAKE(NULL));
643 test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 4, STRV_MAKE(NULL));
644 test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 55, STRV_MAKE(NULL));
645
646 test_strv_skip_one(STRV_MAKE("quux"), 0, STRV_MAKE("quux"));
647 test_strv_skip_one(STRV_MAKE("quux"), 1, STRV_MAKE(NULL));
648 test_strv_skip_one(STRV_MAKE("quux"), 55, STRV_MAKE(NULL));
649
650 test_strv_skip_one(STRV_MAKE(NULL), 0, STRV_MAKE(NULL));
651 test_strv_skip_one(STRV_MAKE(NULL), 1, STRV_MAKE(NULL));
652 test_strv_skip_one(STRV_MAKE(NULL), 55, STRV_MAKE(NULL));
653 }
654
655 static void test_strv_extend_n(void) {
656 _cleanup_strv_free_ char **v = NULL;
657
658 v = strv_new("foo", "bar", NULL);
659 assert_se(v);
660
661 assert_se(strv_extend_n(&v, "waldo", 3) >= 0);
662 assert_se(strv_extend_n(&v, "piep", 2) >= 0);
663
664 assert_se(streq(v[0], "foo"));
665 assert_se(streq(v[1], "bar"));
666 assert_se(streq(v[2], "waldo"));
667 assert_se(streq(v[3], "waldo"));
668 assert_se(streq(v[4], "waldo"));
669 assert_se(streq(v[5], "piep"));
670 assert_se(streq(v[6], "piep"));
671 assert_se(v[7] == NULL);
672
673 v = strv_free(v);
674
675 assert_se(strv_extend_n(&v, "foo", 1) >= 0);
676 assert_se(strv_extend_n(&v, "bar", 0) >= 0);
677
678 assert_se(streq(v[0], "foo"));
679 assert_se(v[1] == NULL);
680 }
681
682 static void test_strv_make_nulstr_one(char **l) {
683 _cleanup_free_ char *b = NULL, *c = NULL;
684 _cleanup_strv_free_ char **q = NULL;
685 const char *s = NULL;
686 size_t n, m;
687 unsigned i = 0;
688
689 assert_se(strv_make_nulstr(l, &b, &n) >= 0);
690 assert_se(q = strv_parse_nulstr(b, n));
691 assert_se(strv_equal(l, q));
692
693 assert_se(strv_make_nulstr(q, &c, &m) >= 0);
694 assert_se(m == n);
695 assert_se(memcmp(b, c, m) == 0);
696
697 NULSTR_FOREACH(s, b)
698 assert_se(streq(s, l[i++]));
699 assert_se(i == strv_length(l));
700 }
701
702 static void test_strv_make_nulstr(void) {
703 test_strv_make_nulstr_one(NULL);
704 test_strv_make_nulstr_one(STRV_MAKE(NULL));
705 test_strv_make_nulstr_one(STRV_MAKE("foo"));
706 test_strv_make_nulstr_one(STRV_MAKE("foo", "bar"));
707 test_strv_make_nulstr_one(STRV_MAKE("foo", "bar", "quuux"));
708 }
709
710 static void test_strv_free_free(void) {
711 char ***t;
712
713 assert_se(t = new(char**, 3));
714 assert_se(t[0] = strv_new("a", "b", NULL));
715 assert_se(t[1] = strv_new("c", "d", "e", NULL));
716 t[2] = NULL;
717
718 t = strv_free_free(t);
719 }
720
721 static void test_foreach_string(void) {
722 const char * const t[] = {
723 "foo",
724 "bar",
725 "waldo",
726 NULL
727 };
728 const char *x;
729 unsigned i = 0;
730
731 FOREACH_STRING(x, "foo", "bar", "waldo")
732 assert_se(streq_ptr(t[i++], x));
733
734 assert_se(i == 3);
735
736 FOREACH_STRING(x, "zzz")
737 assert_se(streq(x, "zzz"));
738 }
739
740 static void test_strv_fnmatch(void) {
741 _cleanup_strv_free_ char **v = NULL;
742
743 assert_se(!strv_fnmatch(STRV_MAKE_EMPTY, "a", 0));
744
745 v = strv_new("*\\*", NULL);
746 assert_se(!strv_fnmatch(v, "\\", 0));
747 assert_se(strv_fnmatch(v, "\\", FNM_NOESCAPE));
748 }
749
750 int main(int argc, char *argv[]) {
751 test_specifier_printf();
752 test_str_in_set();
753 test_strptr_in_set();
754 test_strv_foreach();
755 test_strv_foreach_backwards();
756 test_strv_foreach_pair();
757 test_strv_find();
758 test_strv_find_prefix();
759 test_strv_find_startswith();
760 test_strv_join();
761 test_strv_join_prefix();
762
763 test_strv_unquote(" foo=bar \"waldo\" zzz ", STRV_MAKE("foo=bar", "waldo", "zzz"));
764 test_strv_unquote("", STRV_MAKE_EMPTY);
765 test_strv_unquote(" ", STRV_MAKE_EMPTY);
766 test_strv_unquote(" ", STRV_MAKE_EMPTY);
767 test_strv_unquote(" x", STRV_MAKE("x"));
768 test_strv_unquote("x ", STRV_MAKE("x"));
769 test_strv_unquote(" x ", STRV_MAKE("x"));
770 test_strv_unquote(" \"x\" ", STRV_MAKE("x"));
771 test_strv_unquote(" 'x' ", STRV_MAKE("x"));
772 test_strv_unquote(" 'x\"' ", STRV_MAKE("x\""));
773 test_strv_unquote(" \"x'\" ", STRV_MAKE("x'"));
774 test_strv_unquote("a '--b=c \"d e\"'", STRV_MAKE("a", "--b=c \"d e\""));
775
776 /* trailing backslashes */
777 test_strv_unquote(" x\\\\", STRV_MAKE("x\\"));
778 test_invalid_unquote(" x\\");
779
780 test_invalid_unquote("a --b='c \"d e\"''");
781 test_invalid_unquote("a --b='c \"d e\" '\"");
782 test_invalid_unquote("a --b='c \"d e\"garbage");
783 test_invalid_unquote("'");
784 test_invalid_unquote("\"");
785 test_invalid_unquote("'x'y'g");
786
787 test_strv_split();
788 test_strv_split_empty();
789 test_strv_split_extract();
790 test_strv_split_newlines();
791 test_strv_split_nulstr();
792 test_strv_parse_nulstr();
793 test_strv_overlap();
794 test_strv_sort();
795 test_strv_extend_strv();
796 test_strv_extend_strv_concat();
797 test_strv_extend();
798 test_strv_extendf();
799 test_strv_from_stdarg_alloca();
800 test_strv_insert();
801 test_strv_push_prepend();
802 test_strv_push();
803 test_strv_equal();
804 test_strv_is_uniq();
805 test_strv_reverse();
806 test_strv_shell_escape();
807 test_strv_skip();
808 test_strv_extend_n();
809 test_strv_make_nulstr();
810 test_strv_free_free();
811
812 test_foreach_string();
813 test_strv_fnmatch();
814
815 return 0;
816 }