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