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