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_join(void) {
117 _cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL;
119 p = strv_join((char **)input_table_multiple, ", ");
121 assert_se(streq(p, "one, two, three"));
123 q = strv_join((char **)input_table_multiple, ";");
125 assert_se(streq(q, "one;two;three"));
127 r = strv_join((char **)input_table_multiple, NULL);
129 assert_se(streq(r, "one two three"));
131 s = strv_join((char **)input_table_one, ", ");
133 assert_se(streq(s, "one"));
135 t = strv_join((char **)input_table_none, ", ");
137 assert_se(streq(t, ""));
140 static void test_strv_quote_unquote(const char* const *split, const char *quoted) {
141 _cleanup_free_ char *p;
142 _cleanup_strv_free_ char **s;
145 p = strv_join_quoted((char **)split);
147 printf("-%s- --- -%s-\n", p, quoted); /* fprintf deals with NULL, puts does not */
149 assert_se(streq(p, quoted));
151 s = strv_split_quoted(quoted);
155 assert_se(streq(*t, *split));
160 static void test_strv_unquote(const char *quoted, const char **list) {
161 _cleanup_strv_free_ char **s;
162 _cleanup_free_ char *j;
166 s = strv_split_quoted(quoted);
168 j = strv_join(s, " | ");
173 assert_se(streq(list[i++], *t));
175 assert_se(list[i] == NULL);
178 static void test_invalid_unquote(const char *quoted) {
181 s = strv_split_quoted(quoted);
185 static void test_strv_split(void) {
188 _cleanup_strv_free_ char **l = NULL;
189 const char str[] = "one,two,three";
191 l = strv_split(str, ",");
196 assert_se(streq(*s, input_table_multiple[i++]));
200 static void test_strv_split_newlines(void) {
203 _cleanup_strv_free_ char **l = NULL;
204 const char str[] = "one\ntwo\nthree";
206 l = strv_split_newlines(str);
211 assert_se(streq(*s, input_table_multiple[i++]));
215 static void test_strv_split_nulstr(void) {
216 _cleanup_strv_free_ char **l = NULL;
217 const char nulstr[] = "str0\0str1\0str2\0str3\0";
219 l = strv_split_nulstr (nulstr);
222 assert_se(streq(l[0], "str0"));
223 assert_se(streq(l[1], "str1"));
224 assert_se(streq(l[2], "str2"));
225 assert_se(streq(l[3], "str3"));
228 static void test_strv_parse_nulstr(void) {
229 _cleanup_strv_free_ char **l = NULL;
230 const char nulstr[] = "fuck\0fuck2\0fuck3\0\0fuck5\0\0xxx";
232 l = strv_parse_nulstr(nulstr, sizeof(nulstr)-1);
234 puts("Parse nulstr:");
237 assert_se(streq(l[0], "fuck"));
238 assert_se(streq(l[1], "fuck2"));
239 assert_se(streq(l[2], "fuck3"));
240 assert_se(streq(l[3], ""));
241 assert_se(streq(l[4], "fuck5"));
242 assert_se(streq(l[5], ""));
243 assert_se(streq(l[6], "xxx"));
246 static void test_strv_overlap(void) {
247 const char * const input_table[] = {
253 const char * const input_table_overlap[] = {
257 const char * const input_table_unique[] = {
264 assert_se(strv_overlap((char **)input_table, (char**)input_table_overlap));
265 assert_se(!strv_overlap((char **)input_table, (char**)input_table_unique));
268 static void test_strv_sort(void) {
269 const char* input_table[] = {
273 "CAPITAL LETTERS FIRST",
278 strv_sort((char **)input_table);
280 assert_se(streq(input_table[0], "CAPITAL LETTERS FIRST"));
281 assert_se(streq(input_table[1], "apple"));
282 assert_se(streq(input_table[2], "banana"));
283 assert_se(streq(input_table[3], "citrus"));
284 assert_se(streq(input_table[4], "durian"));
287 static void test_strv_extend_strv_concat(void) {
288 _cleanup_strv_free_ char **a = NULL, **b = NULL;
290 a = strv_new("without", "suffix", NULL);
291 b = strv_new("with", "suffix", NULL);
295 assert_se(strv_extend_strv_concat(&a, b, "_suffix") >= 0);
297 assert_se(streq(a[0], "without"));
298 assert_se(streq(a[1], "suffix"));
299 assert_se(streq(a[2], "with_suffix"));
300 assert_se(streq(a[3], "suffix_suffix"));
303 static void test_strv_extend_strv(void) {
304 _cleanup_strv_free_ char **a = NULL, **b = NULL;
306 a = strv_new("abc", "def", "ghi", NULL);
307 b = strv_new("jkl", "mno", "pqr", NULL);
311 assert_se(strv_extend_strv(&a, b) >= 0);
313 assert_se(streq(a[0], "abc"));
314 assert_se(streq(a[1], "def"));
315 assert_se(streq(a[2], "ghi"));
316 assert_se(streq(a[3], "jkl"));
317 assert_se(streq(a[4], "mno"));
318 assert_se(streq(a[5], "pqr"));
320 assert_se(strv_length(a) == 6);
323 static void test_strv_extend(void) {
324 _cleanup_strv_free_ char **a = NULL, **b = NULL;
326 a = strv_new("test", "test1", NULL);
328 assert_se(strv_extend(&a, "test2") >= 0);
329 assert_se(strv_extend(&b, "test3") >= 0);
331 assert_se(streq(a[0], "test"));
332 assert_se(streq(a[1], "test1"));
333 assert_se(streq(a[2], "test2"));
334 assert_se(streq(b[0], "test3"));
337 static void test_strv_extendf(void) {
338 _cleanup_strv_free_ char **a = NULL, **b = NULL;
340 a = strv_new("test", "test1", NULL);
342 assert_se(strv_extendf(&a, "test2 %s %d %s", "foo", 128, "bar") >= 0);
343 assert_se(strv_extendf(&b, "test3 %s %s %d", "bar", "foo", 128) >= 0);
345 assert_se(streq(a[0], "test"));
346 assert_se(streq(a[1], "test1"));
347 assert_se(streq(a[2], "test2 foo 128 bar"));
348 assert_se(streq(b[0], "test3 bar foo 128"));
351 static void test_strv_foreach(void) {
352 _cleanup_strv_free_ char **a;
356 a = strv_new("one", "two", "three", NULL);
360 STRV_FOREACH(check, a) {
361 assert_se(streq(*check, input_table_multiple[i++]));
365 static void test_strv_foreach_backwards(void) {
366 _cleanup_strv_free_ char **a;
370 a = strv_new("one", "two", "three", NULL);
374 STRV_FOREACH_BACKWARDS(check, a) {
375 assert_se(streq_ptr(*check, input_table_multiple[i--]));
379 static void test_strv_foreach_pair(void) {
380 _cleanup_strv_free_ char **a = NULL;
383 a = strv_new("pair_one", "pair_one",
384 "pair_two", "pair_two",
385 "pair_three", "pair_three",
388 STRV_FOREACH_PAIR(x, y, a) {
389 assert_se(streq(*x, *y));
393 static void test_strv_from_stdarg_alloca_one(char **l, const char *first, ...) {
397 j = strv_from_stdarg_alloca(first);
400 assert_se(streq_ptr(l[i], j[i]));
407 static void test_strv_from_stdarg_alloca(void) {
408 test_strv_from_stdarg_alloca_one(STRV_MAKE("foo", "bar"), "foo", "bar", NULL);
409 test_strv_from_stdarg_alloca_one(STRV_MAKE("foo"), "foo", NULL);
410 test_strv_from_stdarg_alloca_one(STRV_MAKE_EMPTY, NULL);
413 int main(int argc, char *argv[]) {
414 test_specifier_printf();
416 test_strv_foreach_backwards();
417 test_strv_foreach_pair();
419 test_strv_find_prefix();
422 test_strv_quote_unquote(input_table_multiple, "\"one\" \"two\" \"three\"");
423 test_strv_quote_unquote(input_table_one, "\"one\"");
424 test_strv_quote_unquote(input_table_none, "");
425 test_strv_quote_unquote(input_table_quotes, QUOTES_STRING);
426 test_strv_quote_unquote(input_table_spaces, SPACES_STRING);
428 test_strv_unquote(" foo=bar \"waldo\" zzz ", (const char*[]) { "foo=bar", "waldo", "zzz", NULL });
429 test_strv_unquote("", (const char*[]) { NULL });
430 test_strv_unquote(" ", (const char*[]) { NULL });
431 test_strv_unquote(" ", (const char*[]) { NULL });
432 test_strv_unquote(" x", (const char*[]) { "x", NULL });
433 test_strv_unquote("x ", (const char*[]) { "x", NULL });
434 test_strv_unquote(" x ", (const char*[]) { "x", NULL });
435 test_strv_unquote(" \"x\" ", (const char*[]) { "x", NULL });
436 test_strv_unquote(" 'x' ", (const char*[]) { "x", NULL });
437 test_strv_unquote(" 'x\"' ", (const char*[]) { "x\"", NULL });
438 test_strv_unquote(" \"x'\" ", (const char*[]) { "x'", NULL });
439 test_strv_unquote("a '--b=c \"d e\"'", (const char*[]) { "a", "--b=c \"d e\"", NULL });
441 test_invalid_unquote("a --b='c \"d e\"'");
442 test_invalid_unquote("a --b='c \"d e\" '");
443 test_invalid_unquote("a --b='c \"d e\"garbage");
446 test_strv_split_newlines();
447 test_strv_split_nulstr();
448 test_strv_parse_nulstr();
451 test_strv_extend_strv();
452 test_strv_extend_strv_concat();
455 test_strv_from_stdarg_alloca();