]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-strv.c
Merge pull request #756 from ldzhong/fix
[thirdparty/systemd.git] / src / test / test-strv.c
CommitLineData
f90cf44c
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
539ad707 7 Copyright 2013 Thomas H.P. Andersen
f90cf44c
LP
8
9 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
f90cf44c
LP
12 (at your option) any later version.
13
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 17 Lesser General Public License for more details.
f90cf44c 18
5430f7f2 19 You should have received a copy of the GNU Lesser General Public License
f90cf44c
LP
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21***/
22
23#include <string.h>
2c4b304e 24
f90cf44c 25#include "util.h"
2c4b304e 26#include "specifier.h"
682cfdff 27#include "strv.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
73static const char* const input_table_quotes[] = {
74 "\"",
75 "'",
76 "\"\"",
77 "\\",
78 "\\\\",
79 NULL,
80};
81#define QUOTES_STRING \
82 "\"\\\"\" " \
83 "\"\\\'\" " \
84 "\"\\\"\\\"\" " \
85 "\"\\\\\" " \
86 "\"\\\\\\\\\""
87
88static const char * const input_table_spaces[] = {
89 " ",
90 "' '",
91 "\" ",
92 " \"",
93 " \\\\ ",
94 NULL,
95};
96#define SPACES_STRING \
97 "\" \" " \
98 "\"\\' \\'\" " \
99 "\"\\\" \" " \
100 "\" \\\"\" " \
101 "\" \\\\\\\\ \""
539ad707 102
a6fde353
ZJS
103static void test_strv_find(void) {
104 assert_se(strv_find((char **)input_table_multiple, "three"));
105 assert_se(!strv_find((char **)input_table_multiple, "four"));
539ad707
TA
106}
107
108static void test_strv_find_prefix(void) {
a6fde353
ZJS
109 assert_se(strv_find_prefix((char **)input_table_multiple, "o"));
110 assert_se(strv_find_prefix((char **)input_table_multiple, "one"));
111 assert_se(strv_find_prefix((char **)input_table_multiple, ""));
112 assert_se(!strv_find_prefix((char **)input_table_multiple, "xxx"));
113 assert_se(!strv_find_prefix((char **)input_table_multiple, "onee"));
3a7719d3 114}
f90cf44c 115
7bd57a87
RC
116static void test_strv_find_startswith(void) {
117 char *r;
118
119 r = strv_find_startswith((char **)input_table_multiple, "o");
120 assert_se(r && streq(r, "ne"));
121
122 r = strv_find_startswith((char **)input_table_multiple, "one");
123 assert_se(r && streq(r, ""));
124
125 r = strv_find_startswith((char **)input_table_multiple, "");
126 assert_se(r && streq(r, "one"));
127
128 assert_se(!strv_find_startswith((char **)input_table_multiple, "xxx"));
129 assert_se(!strv_find_startswith((char **)input_table_multiple, "onee"));
130}
131
682cfdff 132static void test_strv_join(void) {
539ad707 133 _cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL;
682cfdff 134
539ad707 135 p = strv_join((char **)input_table_multiple, ", ");
04045d84 136 assert_se(p);
7b68d618 137 assert_se(streq(p, "one, two, three"));
682cfdff 138
539ad707 139 q = strv_join((char **)input_table_multiple, ";");
04045d84 140 assert_se(q);
7b68d618 141 assert_se(streq(q, "one;two;three"));
682cfdff
DB
142
143 r = strv_join((char **)input_table_multiple, NULL);
04045d84 144 assert_se(r);
7b68d618 145 assert_se(streq(r, "one two three"));
539ad707
TA
146
147 s = strv_join((char **)input_table_one, ", ");
04045d84 148 assert_se(s);
7b68d618 149 assert_se(streq(s, "one"));
539ad707
TA
150
151 t = strv_join((char **)input_table_none, ", ");
04045d84 152 assert_se(t);
7b68d618 153 assert_se(streq(t, ""));
682cfdff
DB
154}
155
a6fde353
ZJS
156static void test_strv_quote_unquote(const char* const *split, const char *quoted) {
157 _cleanup_free_ char *p;
158 _cleanup_strv_free_ char **s;
159 char **t;
b2fadec6 160 int r;
a6fde353
ZJS
161
162 p = strv_join_quoted((char **)split);
70f75a52 163 assert_se(p);
a6fde353
ZJS
164 printf("-%s- --- -%s-\n", p, quoted); /* fprintf deals with NULL, puts does not */
165 assert_se(p);
166 assert_se(streq(p, quoted));
167
4034a06d 168 r = strv_split_quoted(&s, quoted, 0);
b2fadec6 169 assert_se(r == 0);
a6fde353
ZJS
170 assert_se(s);
171 STRV_FOREACH(t, s) {
172 assert_se(*t);
173 assert_se(streq(*t, *split));
174 split++;
175 }
176}
177
30bcc052 178static void test_strv_unquote(const char *quoted, char **list) {
70f75a52 179 _cleanup_strv_free_ char **s;
a2a5291b 180 _cleanup_free_ char *j;
70f75a52
LP
181 unsigned i = 0;
182 char **t;
b2fadec6 183 int r;
70f75a52 184
4034a06d 185 r = strv_split_quoted(&s, quoted, 0);
b2fadec6 186 assert_se(r == 0);
70f75a52 187 assert_se(s);
a2a5291b 188 j = strv_join(s, " | ");
bdf7026e 189 assert_se(j);
a2a5291b 190 puts(j);
70f75a52
LP
191
192 STRV_FOREACH(t, s)
193 assert_se(streq(list[i++], *t));
194
195 assert_se(list[i] == NULL);
196}
197
a2a5291b 198static void test_invalid_unquote(const char *quoted) {
b2fadec6
ZJS
199 char **s = NULL;
200 int r;
a2a5291b 201
4034a06d 202 r = strv_split_quoted(&s, quoted, 0);
bdf7026e
TA
203 assert_se(s == NULL);
204 assert_se(r == -EINVAL);
a2a5291b
ZJS
205}
206
aed2ebfe
DB
207static void test_strv_split(void) {
208 char **s;
209 unsigned i = 0;
210 _cleanup_strv_free_ char **l = NULL;
211 const char str[] = "one,two,three";
212
213 l = strv_split(str, ",");
214
bdf7026e 215 assert_se(l);
aed2ebfe
DB
216
217 STRV_FOREACH(s, l) {
218 assert_se(streq(*s, input_table_multiple[i++]));
219 }
220}
221
222static void test_strv_split_newlines(void) {
223 unsigned i = 0;
224 char **s;
225 _cleanup_strv_free_ char **l = NULL;
226 const char str[] = "one\ntwo\nthree";
227
228 l = strv_split_newlines(str);
229
bdf7026e 230 assert_se(l);
aed2ebfe
DB
231
232 STRV_FOREACH(s, l) {
233 assert_se(streq(*s, input_table_multiple[i++]));
234 }
235}
236
2f213f74
DB
237static void test_strv_split_nulstr(void) {
238 _cleanup_strv_free_ char **l = NULL;
239 const char nulstr[] = "str0\0str1\0str2\0str3\0";
240
241 l = strv_split_nulstr (nulstr);
04045d84 242 assert_se(l);
2f213f74
DB
243
244 assert_se(streq(l[0], "str0"));
245 assert_se(streq(l[1], "str1"));
246 assert_se(streq(l[2], "str2"));
247 assert_se(streq(l[3], "str3"));
248}
249
10ddd913
TA
250static void test_strv_parse_nulstr(void) {
251 _cleanup_strv_free_ char **l = NULL;
252 const char nulstr[] = "fuck\0fuck2\0fuck3\0\0fuck5\0\0xxx";
253
254 l = strv_parse_nulstr(nulstr, sizeof(nulstr)-1);
04045d84 255 assert_se(l);
10ddd913
TA
256 puts("Parse nulstr:");
257 strv_print(l);
258
7b68d618
DB
259 assert_se(streq(l[0], "fuck"));
260 assert_se(streq(l[1], "fuck2"));
261 assert_se(streq(l[2], "fuck3"));
262 assert_se(streq(l[3], ""));
263 assert_se(streq(l[4], "fuck5"));
264 assert_se(streq(l[5], ""));
265 assert_se(streq(l[6], "xxx"));
10ddd913
TA
266}
267
539ad707
TA
268static void test_strv_overlap(void) {
269 const char * const input_table[] = {
270 "one",
271 "two",
272 "three",
273 NULL
274 };
275 const char * const input_table_overlap[] = {
276 "two",
277 NULL
278 };
279 const char * const input_table_unique[] = {
280 "four",
281 "five",
282 "six",
283 NULL
284 };
285
7b68d618
DB
286 assert_se(strv_overlap((char **)input_table, (char**)input_table_overlap));
287 assert_se(!strv_overlap((char **)input_table, (char**)input_table_unique));
539ad707
TA
288}
289
290static void test_strv_sort(void) {
1e64bbc1 291 const char* input_table[] = {
539ad707
TA
292 "durian",
293 "apple",
294 "citrus",
295 "CAPITAL LETTERS FIRST",
296 "banana",
297 NULL
298 };
299
300 strv_sort((char **)input_table);
301
7b68d618
DB
302 assert_se(streq(input_table[0], "CAPITAL LETTERS FIRST"));
303 assert_se(streq(input_table[1], "apple"));
304 assert_se(streq(input_table[2], "banana"));
305 assert_se(streq(input_table[3], "citrus"));
306 assert_se(streq(input_table[4], "durian"));
3a7719d3 307}
e3aa71c3 308
e3e45d4f
SP
309static void test_strv_extend_strv_concat(void) {
310 _cleanup_strv_free_ char **a = NULL, **b = NULL;
343a8969 311
7b68d618
DB
312 a = strv_new("without", "suffix", NULL);
313 b = strv_new("with", "suffix", NULL);
04045d84
DB
314 assert_se(a);
315 assert_se(b);
343a8969 316
e3e45d4f 317 assert_se(strv_extend_strv_concat(&a, b, "_suffix") >= 0);
343a8969 318
e3e45d4f
SP
319 assert_se(streq(a[0], "without"));
320 assert_se(streq(a[1], "suffix"));
321 assert_se(streq(a[2], "with_suffix"));
322 assert_se(streq(a[3], "suffix_suffix"));
343a8969
DB
323}
324
e3e45d4f
SP
325static void test_strv_extend_strv(void) {
326 _cleanup_strv_free_ char **a = NULL, **b = NULL;
a1022300 327
7b68d618
DB
328 a = strv_new("abc", "def", "ghi", NULL);
329 b = strv_new("jkl", "mno", "pqr", NULL);
04045d84
DB
330 assert_se(a);
331 assert_se(b);
a1022300 332
e3e45d4f 333 assert_se(strv_extend_strv(&a, b) >= 0);
a1022300 334
e3e45d4f
SP
335 assert_se(streq(a[0], "abc"));
336 assert_se(streq(a[1], "def"));
337 assert_se(streq(a[2], "ghi"));
338 assert_se(streq(a[3], "jkl"));
339 assert_se(streq(a[4], "mno"));
340 assert_se(streq(a[5], "pqr"));
a1022300 341
e3e45d4f 342 assert_se(strv_length(a) == 6);
a1022300
DB
343}
344
e3e45d4f
SP
345static void test_strv_extend(void) {
346 _cleanup_strv_free_ char **a = NULL, **b = NULL;
40857008
DB
347
348 a = strv_new("test", "test1", NULL);
04045d84 349 assert_se(a);
e3e45d4f
SP
350 assert_se(strv_extend(&a, "test2") >= 0);
351 assert_se(strv_extend(&b, "test3") >= 0);
40857008 352
e3e45d4f
SP
353 assert_se(streq(a[0], "test"));
354 assert_se(streq(a[1], "test1"));
355 assert_se(streq(a[2], "test2"));
356 assert_se(streq(b[0], "test3"));
40857008
DB
357}
358
4a336a69
RC
359static void test_strv_extendf(void) {
360 _cleanup_strv_free_ char **a = NULL, **b = NULL;
361
362 a = strv_new("test", "test1", NULL);
363 assert_se(a);
364 assert_se(strv_extendf(&a, "test2 %s %d %s", "foo", 128, "bar") >= 0);
365 assert_se(strv_extendf(&b, "test3 %s %s %d", "bar", "foo", 128) >= 0);
366
367 assert_se(streq(a[0], "test"));
368 assert_se(streq(a[1], "test1"));
369 assert_se(streq(a[2], "test2 foo 128 bar"));
370 assert_se(streq(b[0], "test3 bar foo 128"));
371}
372
02f19706 373static void test_strv_foreach(void) {
250a918d
LP
374 _cleanup_strv_free_ char **a;
375 unsigned i = 0;
376 char **check;
02f19706 377
250a918d 378 a = strv_new("one", "two", "three", NULL);
02f19706 379
250a918d 380 assert_se(a);
02f19706 381
250a918d
LP
382 STRV_FOREACH(check, a) {
383 assert_se(streq(*check, input_table_multiple[i++]));
384 }
02f19706
DB
385}
386
387static void test_strv_foreach_backwards(void) {
250a918d
LP
388 _cleanup_strv_free_ char **a;
389 unsigned i = 2;
390 char **check;
02f19706 391
250a918d 392 a = strv_new("one", "two", "three", NULL);
02f19706 393
250a918d 394 assert_se(a);
02f19706 395
250a918d 396 STRV_FOREACH_BACKWARDS(check, a) {
5fba7bbf 397 assert_se(streq_ptr(*check, input_table_multiple[i--]));
250a918d 398 }
02f19706
DB
399}
400
4c325b2e
DB
401static void test_strv_foreach_pair(void) {
402 _cleanup_strv_free_ char **a = NULL;
403 char **x, **y;
404
405 a = strv_new("pair_one", "pair_one",
406 "pair_two", "pair_two",
407 "pair_three", "pair_three",
408 NULL);
409
410 STRV_FOREACH_PAIR(x, y, a) {
411 assert_se(streq(*x, *y));
412 }
413}
414
897e7561 415static void test_strv_from_stdarg_alloca_one(char **l, const char *first, ...) {
250a918d
LP
416 char **j;
417 unsigned i;
418
419 j = strv_from_stdarg_alloca(first);
420
421 for (i = 0;; i++) {
422 assert_se(streq_ptr(l[i], j[i]));
423
424 if (!l[i])
425 break;
426 }
427}
428
429static void test_strv_from_stdarg_alloca(void) {
897e7561
LP
430 test_strv_from_stdarg_alloca_one(STRV_MAKE("foo", "bar"), "foo", "bar", NULL);
431 test_strv_from_stdarg_alloca_one(STRV_MAKE("foo"), "foo", NULL);
432 test_strv_from_stdarg_alloca_one(STRV_MAKE_EMPTY, NULL);
250a918d
LP
433}
434
7bd57a87
RC
435static void test_strv_push_prepend(void) {
436 _cleanup_strv_free_ char **a = NULL;
437
438 a = strv_new("foo", "bar", "three", NULL);
439
440 assert_se(strv_push_prepend(&a, strdup("first")) >= 0);
441 assert_se(streq(a[0], "first"));
442 assert_se(streq(a[1], "foo"));
443 assert_se(streq(a[2], "bar"));
444 assert_se(streq(a[3], "three"));
445 assert_se(!a[4]);
446
447 assert_se(strv_consume_prepend(&a, strdup("first2")) >= 0);
448 assert_se(streq(a[0], "first2"));
449 assert_se(streq(a[1], "first"));
450 assert_se(streq(a[2], "foo"));
451 assert_se(streq(a[3], "bar"));
452 assert_se(streq(a[4], "three"));
453 assert_se(!a[5]);
454}
455
98940a3c
LP
456static void test_strv_push(void) {
457 _cleanup_strv_free_ char **a = NULL;
458 char *i, *j;
459
460 assert_se(i = strdup("foo"));
461 assert_se(strv_push(&a, i) >= 0);
462
463 assert_se(i = strdup("a"));
464 assert_se(j = strdup("b"));
465 assert_se(strv_push_pair(&a, i, j) >= 0);
466
467 assert_se(streq_ptr(a[0], "foo"));
468 assert_se(streq_ptr(a[1], "a"));
469 assert_se(streq_ptr(a[2], "b"));
470 assert_se(streq_ptr(a[3], NULL));
471}
472
e74aa253
RC
473static void test_strv_equal(void) {
474 _cleanup_strv_free_ char **a = NULL;
475 _cleanup_strv_free_ char **b = NULL;
476 _cleanup_strv_free_ char **c = NULL;
477
478 a = strv_new("one", "two", "three", NULL);
479 assert_se(a);
480 b = strv_new("one", "two", "three", NULL);
481 assert_se(a);
482 c = strv_new("one", "two", "three", "four", NULL);
483 assert_se(a);
484
485 assert_se(strv_equal(a, a));
486 assert_se(strv_equal(a, b));
487 assert_se(strv_equal(NULL, NULL));
488
489 assert_se(!strv_equal(a, c));
490 assert_se(!strv_equal(b, c));
491 assert_se(!strv_equal(b, NULL));
492}
493
e1dd6790
LP
494static void test_strv_is_uniq(void) {
495 _cleanup_strv_free_ char **a = NULL, **b = NULL, **c = NULL, **d = NULL;
496
497 a = strv_new(NULL, NULL);
498 assert_se(a);
499 assert_se(strv_is_uniq(a));
500
501 b = strv_new("foo", NULL);
502 assert_se(b);
503 assert_se(strv_is_uniq(b));
504
505 c = strv_new("foo", "bar", NULL);
506 assert_se(c);
507 assert_se(strv_is_uniq(c));
508
509 d = strv_new("foo", "bar", "waldo", "bar", "piep", NULL);
510 assert_se(d);
511 assert_se(!strv_is_uniq(d));
512}
513
514static void test_strv_reverse(void) {
515 _cleanup_strv_free_ char **a = NULL, **b = NULL, **c = NULL, **d = NULL;
516
517 a = strv_new(NULL, NULL);
518 assert_se(a);
519
520 strv_reverse(a);
521 assert_se(strv_isempty(a));
522
523 b = strv_new("foo", NULL);
524 assert_se(b);
525 strv_reverse(b);
526 assert_se(streq_ptr(b[0], "foo"));
527 assert_se(streq_ptr(b[1], NULL));
528
529 c = strv_new("foo", "bar", NULL);
530 assert_se(c);
531 strv_reverse(c);
532 assert_se(streq_ptr(c[0], "bar"));
533 assert_se(streq_ptr(c[1], "foo"));
534 assert_se(streq_ptr(c[2], NULL));
535
536 d = strv_new("foo", "bar", "waldo", NULL);
537 assert_se(d);
538 strv_reverse(d);
539 assert_se(streq_ptr(d[0], "waldo"));
540 assert_se(streq_ptr(d[1], "bar"));
541 assert_se(streq_ptr(d[2], "foo"));
542 assert_se(streq_ptr(d[3], NULL));
543}
544
3a7719d3 545int main(int argc, char *argv[]) {
3a7719d3 546 test_specifier_printf();
02f19706
DB
547 test_strv_foreach();
548 test_strv_foreach_backwards();
4c325b2e 549 test_strv_foreach_pair();
539ad707
TA
550 test_strv_find();
551 test_strv_find_prefix();
7bd57a87 552 test_strv_find_startswith();
682cfdff 553 test_strv_join();
a6fde353
ZJS
554
555 test_strv_quote_unquote(input_table_multiple, "\"one\" \"two\" \"three\"");
556 test_strv_quote_unquote(input_table_one, "\"one\"");
557 test_strv_quote_unquote(input_table_none, "");
558 test_strv_quote_unquote(input_table_quotes, QUOTES_STRING);
559 test_strv_quote_unquote(input_table_spaces, SPACES_STRING);
560
30bcc052
ZJS
561 test_strv_unquote(" foo=bar \"waldo\" zzz ", STRV_MAKE("foo=bar", "waldo", "zzz"));
562 test_strv_unquote("", STRV_MAKE_EMPTY);
563 test_strv_unquote(" ", STRV_MAKE_EMPTY);
564 test_strv_unquote(" ", STRV_MAKE_EMPTY);
565 test_strv_unquote(" x", STRV_MAKE("x"));
566 test_strv_unquote("x ", STRV_MAKE("x"));
567 test_strv_unquote(" x ", STRV_MAKE("x"));
568 test_strv_unquote(" \"x\" ", STRV_MAKE("x"));
569 test_strv_unquote(" 'x' ", STRV_MAKE("x"));
570 test_strv_unquote(" 'x\"' ", STRV_MAKE("x\""));
571 test_strv_unquote(" \"x'\" ", STRV_MAKE("x'"));
572 test_strv_unquote("a '--b=c \"d e\"'", STRV_MAKE("a", "--b=c \"d e\""));
73381fcf 573
ba774317
ZJS
574 /* trailing backslashes */
575 test_strv_unquote(" x\\\\", STRV_MAKE("x\\"));
576 test_invalid_unquote(" x\\");
577
f88e6be5
LP
578 test_invalid_unquote("a --b='c \"d e\"''");
579 test_invalid_unquote("a --b='c \"d e\" '\"");
a2a5291b 580 test_invalid_unquote("a --b='c \"d e\"garbage");
b2fadec6
ZJS
581 test_invalid_unquote("'");
582 test_invalid_unquote("\"");
f88e6be5 583 test_invalid_unquote("'x'y'g");
70f75a52 584
aed2ebfe
DB
585 test_strv_split();
586 test_strv_split_newlines();
2f213f74 587 test_strv_split_nulstr();
10ddd913 588 test_strv_parse_nulstr();
539ad707
TA
589 test_strv_overlap();
590 test_strv_sort();
e3e45d4f
SP
591 test_strv_extend_strv();
592 test_strv_extend_strv_concat();
593 test_strv_extend();
4a336a69 594 test_strv_extendf();
250a918d 595 test_strv_from_stdarg_alloca();
7bd57a87 596 test_strv_push_prepend();
98940a3c 597 test_strv_push();
e74aa253 598 test_strv_equal();
e1dd6790
LP
599 test_strv_is_uniq();
600 test_strv_reverse();
2c4b304e 601
f90cf44c
LP
602 return 0;
603}