]>
git.proxmox.com Git - systemd.git/blob - src/test/test-strv.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Thomas H.P. Andersen
9 systemd is free software; you can redistribute it and/or modify it
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
12 (at your option) any later version.
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
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
26 #include "specifier.h"
29 static void test_specifier_printf(void) {
30 static const Specifier table
[] = {
31 { 'a', specifier_string
, (char*) "AAAA" },
32 { 'b', specifier_string
, (char*) "BBBB" },
33 { 'm', specifier_machine_id
, NULL
},
34 { 'B', specifier_boot_id
, NULL
},
35 { 'H', specifier_host_name
, NULL
},
36 { 'v', specifier_kernel_release
, NULL
},
40 _cleanup_free_
char *w
= NULL
;
43 r
= specifier_printf("xxx a=%a b=%b yyy", table
, NULL
, &w
);
48 assert_se(streq(w
, "xxx a=AAAA b=BBBB yyy"));
51 r
= specifier_printf("machine=%m, boot=%B, host=%H, version=%v", table
, NULL
, &w
);
57 static const char* const input_table_multiple
[] = {
64 static const char* const input_table_one
[] = {
69 static const char* const input_table_none
[] = {
73 static const char* const input_table_quotes
[] = {
81 #define QUOTES_STRING \
88 static const char * const input_table_spaces
[] = {
96 #define SPACES_STRING \
103 static 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"));
108 static void test_strv_find_prefix(void) {
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"));
116 static void test_strv_find_startswith(void) {
119 r
= strv_find_startswith((char **)input_table_multiple
, "o");
120 assert_se(r
&& streq(r
, "ne"));
122 r
= strv_find_startswith((char **)input_table_multiple
, "one");
123 assert_se(r
&& streq(r
, ""));
125 r
= strv_find_startswith((char **)input_table_multiple
, "");
126 assert_se(r
&& streq(r
, "one"));
128 assert_se(!strv_find_startswith((char **)input_table_multiple
, "xxx"));
129 assert_se(!strv_find_startswith((char **)input_table_multiple
, "onee"));
132 static void test_strv_join(void) {
133 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *r
= NULL
, *s
= NULL
, *t
= NULL
;
135 p
= strv_join((char **)input_table_multiple
, ", ");
137 assert_se(streq(p
, "one, two, three"));
139 q
= strv_join((char **)input_table_multiple
, ";");
141 assert_se(streq(q
, "one;two;three"));
143 r
= strv_join((char **)input_table_multiple
, NULL
);
145 assert_se(streq(r
, "one two three"));
147 s
= strv_join((char **)input_table_one
, ", ");
149 assert_se(streq(s
, "one"));
151 t
= strv_join((char **)input_table_none
, ", ");
153 assert_se(streq(t
, ""));
156 static void test_strv_quote_unquote(const char* const *split
, const char *quoted
) {
157 _cleanup_free_
char *p
;
158 _cleanup_strv_free_
char **s
;
162 p
= strv_join_quoted((char **)split
);
164 printf("-%s- --- -%s-\n", p
, quoted
); /* fprintf deals with NULL, puts does not */
166 assert_se(streq(p
, quoted
));
168 r
= strv_split_quoted(&s
, quoted
, false);
173 assert_se(streq(*t
, *split
));
178 static void test_strv_unquote(const char *quoted
, const char **list
) {
179 _cleanup_strv_free_
char **s
;
180 _cleanup_free_
char *j
;
185 r
= strv_split_quoted(&s
, quoted
, false);
188 j
= strv_join(s
, " | ");
193 assert_se(streq(list
[i
++], *t
));
195 assert_se(list
[i
] == NULL
);
198 static void test_invalid_unquote(const char *quoted
) {
202 r
= strv_split_quoted(&s
, quoted
, false);
203 assert_se(s
== NULL
);
204 assert_se(r
== -EINVAL
);
207 static void test_strv_split(void) {
210 _cleanup_strv_free_
char **l
= NULL
;
211 const char str
[] = "one,two,three";
213 l
= strv_split(str
, ",");
218 assert_se(streq(*s
, input_table_multiple
[i
++]));
222 static void test_strv_split_newlines(void) {
225 _cleanup_strv_free_
char **l
= NULL
;
226 const char str
[] = "one\ntwo\nthree";
228 l
= strv_split_newlines(str
);
233 assert_se(streq(*s
, input_table_multiple
[i
++]));
237 static void test_strv_split_nulstr(void) {
238 _cleanup_strv_free_
char **l
= NULL
;
239 const char nulstr
[] = "str0\0str1\0str2\0str3\0";
241 l
= strv_split_nulstr (nulstr
);
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"));
250 static void test_strv_parse_nulstr(void) {
251 _cleanup_strv_free_
char **l
= NULL
;
252 const char nulstr
[] = "fuck\0fuck2\0fuck3\0\0fuck5\0\0xxx";
254 l
= strv_parse_nulstr(nulstr
, sizeof(nulstr
)-1);
256 puts("Parse nulstr:");
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"));
268 static void test_strv_overlap(void) {
269 const char * const input_table
[] = {
275 const char * const input_table_overlap
[] = {
279 const char * const input_table_unique
[] = {
286 assert_se(strv_overlap((char **)input_table
, (char**)input_table_overlap
));
287 assert_se(!strv_overlap((char **)input_table
, (char**)input_table_unique
));
290 static void test_strv_sort(void) {
291 const char* input_table
[] = {
295 "CAPITAL LETTERS FIRST",
300 strv_sort((char **)input_table
);
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"));
309 static void test_strv_extend_strv_concat(void) {
310 _cleanup_strv_free_
char **a
= NULL
, **b
= NULL
;
312 a
= strv_new("without", "suffix", NULL
);
313 b
= strv_new("with", "suffix", NULL
);
317 assert_se(strv_extend_strv_concat(&a
, b
, "_suffix") >= 0);
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"));
325 static void test_strv_extend_strv(void) {
326 _cleanup_strv_free_
char **a
= NULL
, **b
= NULL
;
328 a
= strv_new("abc", "def", "ghi", NULL
);
329 b
= strv_new("jkl", "mno", "pqr", NULL
);
333 assert_se(strv_extend_strv(&a
, b
) >= 0);
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"));
342 assert_se(strv_length(a
) == 6);
345 static void test_strv_extend(void) {
346 _cleanup_strv_free_
char **a
= NULL
, **b
= NULL
;
348 a
= strv_new("test", "test1", NULL
);
350 assert_se(strv_extend(&a
, "test2") >= 0);
351 assert_se(strv_extend(&b
, "test3") >= 0);
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"));
359 static void test_strv_extendf(void) {
360 _cleanup_strv_free_
char **a
= NULL
, **b
= NULL
;
362 a
= strv_new("test", "test1", NULL
);
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);
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"));
373 static void test_strv_foreach(void) {
374 _cleanup_strv_free_
char **a
;
378 a
= strv_new("one", "two", "three", NULL
);
382 STRV_FOREACH(check
, a
) {
383 assert_se(streq(*check
, input_table_multiple
[i
++]));
387 static void test_strv_foreach_backwards(void) {
388 _cleanup_strv_free_
char **a
;
392 a
= strv_new("one", "two", "three", NULL
);
396 STRV_FOREACH_BACKWARDS(check
, a
) {
397 assert_se(streq_ptr(*check
, input_table_multiple
[i
--]));
401 static void test_strv_foreach_pair(void) {
402 _cleanup_strv_free_
char **a
= NULL
;
405 a
= strv_new("pair_one", "pair_one",
406 "pair_two", "pair_two",
407 "pair_three", "pair_three",
410 STRV_FOREACH_PAIR(x
, y
, a
) {
411 assert_se(streq(*x
, *y
));
415 static void test_strv_from_stdarg_alloca_one(char **l
, const char *first
, ...) {
419 j
= strv_from_stdarg_alloca(first
);
422 assert_se(streq_ptr(l
[i
], j
[i
]));
429 static void test_strv_from_stdarg_alloca(void) {
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
);
435 static void test_strv_push_prepend(void) {
436 _cleanup_strv_free_
char **a
= NULL
;
438 a
= strv_new("foo", "bar", "three", NULL
);
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"));
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"));
456 static void test_strv_push(void) {
457 _cleanup_strv_free_
char **a
= NULL
;
460 assert_se(i
= strdup("foo"));
461 assert_se(strv_push(&a
, i
) >= 0);
463 assert_se(i
= strdup("a"));
464 assert_se(j
= strdup("b"));
465 assert_se(strv_push_pair(&a
, i
, j
) >= 0);
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
));
473 int main(int argc
, char *argv
[]) {
474 test_specifier_printf();
476 test_strv_foreach_backwards();
477 test_strv_foreach_pair();
479 test_strv_find_prefix();
480 test_strv_find_startswith();
483 test_strv_quote_unquote(input_table_multiple
, "\"one\" \"two\" \"three\"");
484 test_strv_quote_unquote(input_table_one
, "\"one\"");
485 test_strv_quote_unquote(input_table_none
, "");
486 test_strv_quote_unquote(input_table_quotes
, QUOTES_STRING
);
487 test_strv_quote_unquote(input_table_spaces
, SPACES_STRING
);
489 test_strv_unquote(" foo=bar \"waldo\" zzz ", (const char*[]) { "foo=bar", "waldo", "zzz", NULL
});
490 test_strv_unquote("", (const char*[]) { NULL
});
491 test_strv_unquote(" ", (const char*[]) { NULL
});
492 test_strv_unquote(" ", (const char*[]) { NULL
});
493 test_strv_unquote(" x", (const char*[]) { "x", NULL
});
494 test_strv_unquote("x ", (const char*[]) { "x", NULL
});
495 test_strv_unquote(" x ", (const char*[]) { "x", NULL
});
496 test_strv_unquote(" \"x\" ", (const char*[]) { "x", NULL
});
497 test_strv_unquote(" 'x' ", (const char*[]) { "x", NULL
});
498 test_strv_unquote(" 'x\"' ", (const char*[]) { "x\"", NULL
});
499 test_strv_unquote(" \"x'\" ", (const char*[]) { "x'", NULL
});
500 test_strv_unquote("a '--b=c \"d e\"'", (const char*[]) { "a", "--b=c \"d e\"", NULL
});
502 test_invalid_unquote("a --b='c \"d e\"''");
503 test_invalid_unquote("a --b='c \"d e\" '\"");
504 test_invalid_unquote("a --b='c \"d e\"garbage");
505 test_invalid_unquote("'");
506 test_invalid_unquote("\"");
507 test_invalid_unquote("'x'y'g");
510 test_strv_split_newlines();
511 test_strv_split_nulstr();
512 test_strv_parse_nulstr();
515 test_strv_extend_strv();
516 test_strv_extend_strv_concat();
519 test_strv_from_stdarg_alloca();
520 test_strv_push_prepend();