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