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_quote_unquote2(const char *quoted, const char ** list) {
161 _cleanup_strv_free_ char **s;
165 s = strv_split_quoted(quoted);
169 assert_se(streq(list[i++], *t));
171 assert_se(list[i] == NULL);
174 static void test_strv_split(void) {
177 _cleanup_strv_free_ char **l = NULL;
178 const char str[] = "one,two,three";
180 l = strv_split(str, ",");
185 assert_se(streq(*s, input_table_multiple[i++]));
189 static void test_strv_split_newlines(void) {
192 _cleanup_strv_free_ char **l = NULL;
193 const char str[] = "one\ntwo\nthree";
195 l = strv_split_newlines(str);
200 assert_se(streq(*s, input_table_multiple[i++]));
204 static void test_strv_split_nulstr(void) {
205 _cleanup_strv_free_ char **l = NULL;
206 const char nulstr[] = "str0\0str1\0str2\0str3\0";
208 l = strv_split_nulstr (nulstr);
211 assert_se(streq(l[0], "str0"));
212 assert_se(streq(l[1], "str1"));
213 assert_se(streq(l[2], "str2"));
214 assert_se(streq(l[3], "str3"));
217 static void test_strv_remove_prefix(void) {
220 _cleanup_strv_free_ char **l = NULL;
222 l = strv_new("_one", "_two", "_three", NULL);
225 l = strv_remove_prefix(l, "_");
229 assert_se(streq(*s, input_table_multiple[i++]));
233 static void test_strv_parse_nulstr(void) {
234 _cleanup_strv_free_ char **l = NULL;
235 const char nulstr[] = "fuck\0fuck2\0fuck3\0\0fuck5\0\0xxx";
237 l = strv_parse_nulstr(nulstr, sizeof(nulstr)-1);
239 puts("Parse nulstr:");
242 assert_se(streq(l[0], "fuck"));
243 assert_se(streq(l[1], "fuck2"));
244 assert_se(streq(l[2], "fuck3"));
245 assert_se(streq(l[3], ""));
246 assert_se(streq(l[4], "fuck5"));
247 assert_se(streq(l[5], ""));
248 assert_se(streq(l[6], "xxx"));
251 static void test_strv_overlap(void) {
252 const char * const input_table[] = {
258 const char * const input_table_overlap[] = {
262 const char * const input_table_unique[] = {
269 assert_se(strv_overlap((char **)input_table, (char**)input_table_overlap));
270 assert_se(!strv_overlap((char **)input_table, (char**)input_table_unique));
273 static void test_strv_sort(void) {
274 const char* input_table[] = {
278 "CAPITAL LETTERS FIRST",
283 strv_sort((char **)input_table);
285 assert_se(streq(input_table[0], "CAPITAL LETTERS FIRST"));
286 assert_se(streq(input_table[1], "apple"));
287 assert_se(streq(input_table[2], "banana"));
288 assert_se(streq(input_table[3], "citrus"));
289 assert_se(streq(input_table[4], "durian"));
292 static void test_strv_merge_concat(void) {
293 _cleanup_strv_free_ char **a = NULL, **b = NULL, **c = NULL;
295 a = strv_new("without", "suffix", NULL);
296 b = strv_new("with", "suffix", NULL);
300 c = strv_merge_concat(a, b, "_suffix");
303 assert_se(streq(c[0], "without"));
304 assert_se(streq(c[1], "suffix"));
305 assert_se(streq(c[2], "with_suffix"));
306 assert_se(streq(c[3], "suffix_suffix"));
309 static void test_strv_merge(void) {
310 _cleanup_strv_free_ char **a = NULL, **b = NULL, **c = NULL;
312 a = strv_new("abc", "def", "ghi", NULL);
313 b = strv_new("jkl", "mno", "pqr", NULL);
317 c = strv_merge(a, b);
320 assert_se(streq(c[0], "abc"));
321 assert_se(streq(c[1], "def"));
322 assert_se(streq(c[2], "ghi"));
323 assert_se(streq(c[3], "jkl"));
324 assert_se(streq(c[4], "mno"));
325 assert_se(streq(c[5], "pqr"));
327 assert_se(strv_length(c) == 6);
330 static void test_strv_append(void) {
331 _cleanup_strv_free_ char **a = NULL, **b = NULL, **c = NULL;
333 a = strv_new("test", "test1", NULL);
335 b = strv_append(a, "test2");
336 c = strv_append(NULL, "test3");
340 assert_se(streq(b[0], "test"));
341 assert_se(streq(b[1], "test1"));
342 assert_se(streq(b[2], "test2"));
343 assert_se(streq(c[0], "test3"));
346 static void test_strv_foreach(void) {
347 _cleanup_strv_free_ char **a;
351 a = strv_new("one", "two", "three", NULL);
355 STRV_FOREACH(check, a) {
356 assert_se(streq(*check, input_table_multiple[i++]));
360 static void test_strv_foreach_backwards(void) {
361 _cleanup_strv_free_ char **a;
365 a = strv_new("one", "two", "three", NULL);
369 STRV_FOREACH_BACKWARDS(check, a) {
370 assert_se(streq_ptr(*check, input_table_multiple[i--]));
374 static void test_strv_foreach_pair(void) {
375 _cleanup_strv_free_ char **a = NULL;
378 a = strv_new("pair_one", "pair_one",
379 "pair_two", "pair_two",
380 "pair_three", "pair_three",
383 STRV_FOREACH_PAIR(x, y, a) {
384 assert_se(streq(*x, *y));
388 static void test_strv_from_stdarg_alloca_one(char **l, const char *first, ...) {
392 j = strv_from_stdarg_alloca(first);
395 assert_se(streq_ptr(l[i], j[i]));
402 static void test_strv_from_stdarg_alloca(void) {
403 test_strv_from_stdarg_alloca_one(STRV_MAKE("foo", "bar"), "foo", "bar", NULL);
404 test_strv_from_stdarg_alloca_one(STRV_MAKE("foo"), "foo", NULL);
405 test_strv_from_stdarg_alloca_one(STRV_MAKE_EMPTY, NULL);
408 int main(int argc, char *argv[]) {
409 test_specifier_printf();
411 test_strv_foreach_backwards();
412 test_strv_foreach_pair();
414 test_strv_find_prefix();
417 test_strv_quote_unquote(input_table_multiple, "\"one\" \"two\" \"three\"");
418 test_strv_quote_unquote(input_table_one, "\"one\"");
419 test_strv_quote_unquote(input_table_none, "");
420 test_strv_quote_unquote(input_table_quotes, QUOTES_STRING);
421 test_strv_quote_unquote(input_table_spaces, SPACES_STRING);
423 test_strv_quote_unquote2(" foo=bar \"waldo\" zzz ", (const char*[]) { "foo=bar", "waldo", "zzz", NULL });
424 test_strv_quote_unquote2("", (const char*[]) { NULL });
425 test_strv_quote_unquote2(" ", (const char*[]) { NULL });
426 test_strv_quote_unquote2(" ", (const char*[]) { NULL });
427 test_strv_quote_unquote2(" x", (const char*[]) { "x", NULL });
428 test_strv_quote_unquote2("x ", (const char*[]) { "x", NULL });
429 test_strv_quote_unquote2(" x ", (const char*[]) { "x", NULL });
430 test_strv_quote_unquote2(" \"x\" ", (const char*[]) { "x", NULL });
431 test_strv_quote_unquote2(" \'x\' ", (const char*[]) { "x", NULL });
432 test_strv_quote_unquote2(" \'x\"\' ", (const char*[]) { "x\"", NULL });
433 test_strv_quote_unquote2(" \"x\'\" ", (const char*[]) { "x\'", NULL });
436 test_strv_split_newlines();
437 test_strv_split_nulstr();
438 test_strv_parse_nulstr();
439 test_strv_remove_prefix();
443 test_strv_merge_concat();
445 test_strv_from_stdarg_alloca();