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