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