]> git.proxmox.com Git - systemd.git/blame - src/test/test-strv.c
New upstream version 236
[systemd.git] / src / test / test-strv.c
CommitLineData
52ad194e 1/* SPDX-License-Identifier: LGPL-2.1+ */
663996b3
MS
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
db2df898 24#include "alloc-util.h"
663996b3 25#include "specifier.h"
db2df898 26#include "string-util.h"
663996b3 27#include "strv.h"
db2df898 28#include "util.h"
663996b3
MS
29
30static void test_specifier_printf(void) {
14228c0d 31 static const Specifier table[] = {
663996b3
MS
32 { 'a', specifier_string, (char*) "AAAA" },
33 { 'b', specifier_string, (char*) "BBBB" },
14228c0d
MB
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 {}
663996b3
MS
39 };
40
14228c0d
MB
41 _cleanup_free_ char *w = NULL;
42 int r;
663996b3 43
14228c0d
MB
44 r = specifier_printf("xxx a=%a b=%b yyy", table, NULL, &w);
45 assert_se(r >= 0);
663996b3 46 assert_se(w);
14228c0d
MB
47
48 puts(w);
663996b3 49 assert_se(streq(w, "xxx a=AAAA b=BBBB yyy"));
14228c0d
MB
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);
663996b3
MS
56}
57
8a584da2
MP
58static 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
65static 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
14228c0d
MB
77static const char* const input_table_multiple[] = {
78 "one",
79 "two",
80 "three",
81 NULL,
82};
83
84static const char* const input_table_one[] = {
85 "one",
86 NULL,
87};
88
89static const char* const input_table_none[] = {
90 NULL,
91};
92
aa27b158
MP
93static const char* const input_table_two_empties[] = {
94 "",
95 "",
96 NULL,
97};
98
99static const char* const input_table_one_empty[] = {
100 "",
101 NULL,
102};
103
104
14228c0d
MB
105static const char* const input_table_quotes[] = {
106 "\"",
107 "'",
108 "\"\"",
109 "\\",
110 "\\\\",
111 NULL,
112};
113#define QUOTES_STRING \
114 "\"\\\"\" " \
115 "\"\\\'\" " \
116 "\"\\\"\\\"\" " \
117 "\"\\\\\" " \
118 "\"\\\\\\\\\""
119
120static const char * const input_table_spaces[] = {
121 " ",
122 "' '",
123 "\" ",
124 " \"",
125 " \\\\ ",
126 NULL,
127};
128#define SPACES_STRING \
129 "\" \" " \
130 "\"\\' \\'\" " \
131 "\"\\\" \" " \
132 "\" \\\"\" " \
133 "\" \\\\\\\\ \""
663996b3 134
14228c0d
MB
135static 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"));
663996b3
MS
138}
139
140static void test_strv_find_prefix(void) {
14228c0d
MB
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"));
663996b3
MS
146}
147
f47781d8
MP
148static 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
663996b3 164static void test_strv_join(void) {
aa27b158 165 _cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL, *v = NULL, *w = NULL;
663996b3 166
663996b3
MS
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, ""));
aa27b158
MP
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, ""));
663996b3
MS
194}
195
14228c0d
MB
196static void test_strv_quote_unquote(const char* const *split, const char *quoted) {
197 _cleanup_free_ char *p;
6300502b 198 _cleanup_strv_free_ char **s = NULL;
14228c0d 199 char **t;
5eef597e 200 int r;
14228c0d
MB
201
202 p = strv_join_quoted((char **)split);
60f067b4 203 assert_se(p);
14228c0d
MB
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
13d276d0 208 r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_QUOTES);
6300502b 209 assert_se(r == (int) strv_length(s));
14228c0d
MB
210 assert_se(s);
211 STRV_FOREACH(t, s) {
212 assert_se(*t);
213 assert_se(streq(*t, *split));
214 split++;
215 }
216}
217
e735f4d4 218static void test_strv_unquote(const char *quoted, char **list) {
60f067b4 219 _cleanup_strv_free_ char **s;
5eef597e 220 _cleanup_free_ char *j;
60f067b4
JS
221 unsigned i = 0;
222 char **t;
5eef597e 223 int r;
60f067b4 224
13d276d0 225 r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_QUOTES);
6300502b 226 assert_se(r == (int) strv_length(list));
60f067b4 227 assert_se(s);
5eef597e
MP
228 j = strv_join(s, " | ");
229 assert_se(j);
230 puts(j);
60f067b4
JS
231
232 STRV_FOREACH(t, s)
233 assert_se(streq(list[i++], *t));
234
235 assert_se(list[i] == NULL);
236}
237
5eef597e
MP
238static void test_invalid_unquote(const char *quoted) {
239 char **s = NULL;
240 int r;
241
13d276d0 242 r = strv_split_extract(&s, quoted, WHITESPACE, EXTRACT_QUOTES);
5eef597e
MP
243 assert_se(s == NULL);
244 assert_se(r == -EINVAL);
245}
246
60f067b4
JS
247static 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
5eef597e 255 assert_se(l);
60f067b4
JS
256
257 STRV_FOREACH(s, l) {
258 assert_se(streq(*s, input_table_multiple[i++]));
259 }
260}
261
13d276d0
MP
262static 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);
6300502b 268 assert_se(r == (int) strv_length(l));
13d276d0
MP
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
60f067b4
JS
277static 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
5eef597e 285 assert_se(l);
60f067b4
JS
286
287 STRV_FOREACH(s, l) {
288 assert_se(streq(*s, input_table_multiple[i++]));
289 }
290}
291
663996b3
MS
292static 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
305static 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
323static 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
345static 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
60f067b4 364static void test_strv_extend_strv_concat(void) {
13d276d0 365 _cleanup_strv_free_ char **a = NULL, **b = NULL;
663996b3
MS
366
367 a = strv_new("without", "suffix", NULL);
368 b = strv_new("with", "suffix", NULL);
369 assert_se(a);
370 assert_se(b);
371
60f067b4 372 assert_se(strv_extend_strv_concat(&a, b, "_suffix") >= 0);
663996b3 373
60f067b4
JS
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"));
663996b3
MS
378}
379
60f067b4 380static void test_strv_extend_strv(void) {
aa27b158 381 _cleanup_strv_free_ char **a = NULL, **b = NULL, **n = NULL;
663996b3
MS
382
383 a = strv_new("abc", "def", "ghi", NULL);
6300502b 384 b = strv_new("jkl", "mno", "abc", "pqr", NULL);
663996b3
MS
385 assert_se(a);
386 assert_se(b);
387
6300502b 388 assert_se(strv_extend_strv(&a, b, true) == 3);
663996b3 389
60f067b4
JS
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"));
60f067b4 396 assert_se(strv_length(a) == 6);
aa27b158
MP
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);
663996b3
MS
404}
405
60f067b4
JS
406static void test_strv_extend(void) {
407 _cleanup_strv_free_ char **a = NULL, **b = NULL;
663996b3
MS
408
409 a = strv_new("test", "test1", NULL);
410 assert_se(a);
60f067b4
JS
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
e842803a
MB
420static 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
60f067b4
JS
434static 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);
663996b3 442
60f067b4
JS
443 STRV_FOREACH(check, a) {
444 assert_se(streq(*check, input_table_multiple[i++]));
445 }
446}
447
448static 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
8a584da2 457 STRV_FOREACH_BACKWARDS(check, a)
60f067b4 458 assert_se(streq_ptr(*check, input_table_multiple[i--]));
8a584da2
MP
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.");
663996b3
MS
465}
466
467static 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
60f067b4
JS
481static 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
495static 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
f47781d8
MP
501static 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
522static 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
e735f4d4
MP
539static 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
560static 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
580static 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
13d276d0
MP
611static 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
6300502b
MP
623static 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
628static 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
645static 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
672static void test_strv_make_nulstr_one(char **l) {
673 _cleanup_free_ char *b = NULL, *c = NULL;
674 _cleanup_strv_free_ char **q = NULL;
5a920b42 675 const char *s = NULL;
6300502b 676 size_t n, m;
5a920b42 677 unsigned i = 0;
6300502b
MP
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);
5a920b42
MP
686
687 NULSTR_FOREACH(s, b)
688 assert_se(streq(s, l[i++]));
689 assert_se(i == strv_length(l));
6300502b
MP
690}
691
692static 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
aa27b158
MP
700static 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
5a920b42
MP
719static 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
663996b3
MS
729int main(int argc, char *argv[]) {
730 test_specifier_printf();
8a584da2
MP
731 test_str_in_set();
732 test_strptr_in_set();
60f067b4
JS
733 test_strv_foreach();
734 test_strv_foreach_backwards();
663996b3
MS
735 test_strv_foreach_pair();
736 test_strv_find();
737 test_strv_find_prefix();
f47781d8 738 test_strv_find_startswith();
663996b3 739 test_strv_join();
14228c0d
MB
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, "");
aa27b158
MP
744 test_strv_quote_unquote(input_table_one_empty, "\"\"");
745 test_strv_quote_unquote(input_table_two_empties, "\"\" \"\"");
14228c0d
MB
746 test_strv_quote_unquote(input_table_quotes, QUOTES_STRING);
747 test_strv_quote_unquote(input_table_spaces, SPACES_STRING);
748
e735f4d4
MP
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\\");
5eef597e 765
f47781d8
MP
766 test_invalid_unquote("a --b='c \"d e\"''");
767 test_invalid_unquote("a --b='c \"d e\" '\"");
5eef597e
MP
768 test_invalid_unquote("a --b='c \"d e\"garbage");
769 test_invalid_unquote("'");
770 test_invalid_unquote("\"");
f47781d8 771 test_invalid_unquote("'x'y'g");
60f067b4
JS
772
773 test_strv_split();
13d276d0 774 test_strv_split_extract();
60f067b4 775 test_strv_split_newlines();
663996b3
MS
776 test_strv_split_nulstr();
777 test_strv_parse_nulstr();
778 test_strv_overlap();
779 test_strv_sort();
60f067b4
JS
780 test_strv_extend_strv();
781 test_strv_extend_strv_concat();
782 test_strv_extend();
e842803a 783 test_strv_extendf();
60f067b4 784 test_strv_from_stdarg_alloca();
f47781d8
MP
785 test_strv_push_prepend();
786 test_strv_push();
e735f4d4
MP
787 test_strv_equal();
788 test_strv_is_uniq();
789 test_strv_reverse();
13d276d0 790 test_strv_shell_escape();
6300502b
MP
791 test_strv_skip();
792 test_strv_extend_n();
793 test_strv_make_nulstr();
663996b3 794
aa27b158 795 test_foreach_string();
5a920b42 796 test_strv_fnmatch();
aa27b158 797
663996b3
MS
798 return 0;
799}