]> git.proxmox.com Git - systemd.git/blob - src/test/test-strv.c
Merge branch 'master' into experimental
[systemd.git] / src / test / test-strv.c
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
7 Copyright 2013 Thomas H.P. Andersen
8
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.
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
17 Lesser General Public License for more details.
18
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/>.
21 ***/
22
23 #include <string.h>
24
25 #include "util.h"
26 #include "specifier.h"
27 #include "strv.h"
28
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 },
37 {}
38 };
39
40 _cleanup_free_ char *w = NULL;
41 int r;
42
43 r = specifier_printf("xxx a=%a b=%b yyy", table, NULL, &w);
44 assert_se(r >= 0);
45 assert_se(w);
46
47 puts(w);
48 assert_se(streq(w, "xxx a=AAAA b=BBBB yyy"));
49
50 free(w);
51 r = specifier_printf("machine=%m, boot=%B, host=%H, version=%v", table, NULL, &w);
52 assert_se(r >= 0);
53 assert_se(w);
54 puts(w);
55 }
56
57 static const char* const input_table_multiple[] = {
58 "one",
59 "two",
60 "three",
61 NULL,
62 };
63
64 static const char* const input_table_one[] = {
65 "one",
66 NULL,
67 };
68
69 static const char* const input_table_none[] = {
70 NULL,
71 };
72
73 static const char* const input_table_quotes[] = {
74 "\"",
75 "'",
76 "\"\"",
77 "\\",
78 "\\\\",
79 NULL,
80 };
81 #define QUOTES_STRING \
82 "\"\\\"\" " \
83 "\"\\\'\" " \
84 "\"\\\"\\\"\" " \
85 "\"\\\\\" " \
86 "\"\\\\\\\\\""
87
88 static const char * const input_table_spaces[] = {
89 " ",
90 "' '",
91 "\" ",
92 " \"",
93 " \\\\ ",
94 NULL,
95 };
96 #define SPACES_STRING \
97 "\" \" " \
98 "\"\\' \\'\" " \
99 "\"\\\" \" " \
100 "\" \\\"\" " \
101 "\" \\\\\\\\ \""
102
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"));
106 }
107
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"));
114 }
115
116 static void test_strv_join(void) {
117 _cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL;
118
119 p = strv_join((char **)input_table_multiple, ", ");
120 assert_se(p);
121 assert_se(streq(p, "one, two, three"));
122
123 q = strv_join((char **)input_table_multiple, ";");
124 assert_se(q);
125 assert_se(streq(q, "one;two;three"));
126
127 r = strv_join((char **)input_table_multiple, NULL);
128 assert_se(r);
129 assert_se(streq(r, "one two three"));
130
131 s = strv_join((char **)input_table_one, ", ");
132 assert_se(s);
133 assert_se(streq(s, "one"));
134
135 t = strv_join((char **)input_table_none, ", ");
136 assert_se(t);
137 assert_se(streq(t, ""));
138 }
139
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;
143 char **t;
144
145 p = strv_join_quoted((char **)split);
146 assert_se(p);
147 printf("-%s- --- -%s-\n", p, quoted); /* fprintf deals with NULL, puts does not */
148 assert_se(p);
149 assert_se(streq(p, quoted));
150
151 s = strv_split_quoted(quoted);
152 assert_se(s);
153 STRV_FOREACH(t, s) {
154 assert_se(*t);
155 assert_se(streq(*t, *split));
156 split++;
157 }
158 }
159
160 static void test_strv_quote_unquote2(const char *quoted, const char ** list) {
161 _cleanup_strv_free_ char **s;
162 unsigned i = 0;
163 char **t;
164
165 s = strv_split_quoted(quoted);
166 assert_se(s);
167
168 STRV_FOREACH(t, s)
169 assert_se(streq(list[i++], *t));
170
171 assert_se(list[i] == NULL);
172 }
173
174 static void test_strv_split(void) {
175 char **s;
176 unsigned i = 0;
177 _cleanup_strv_free_ char **l = NULL;
178 const char str[] = "one,two,three";
179
180 l = strv_split(str, ",");
181
182 assert(l);
183
184 STRV_FOREACH(s, l) {
185 assert_se(streq(*s, input_table_multiple[i++]));
186 }
187 }
188
189 static void test_strv_split_newlines(void) {
190 unsigned i = 0;
191 char **s;
192 _cleanup_strv_free_ char **l = NULL;
193 const char str[] = "one\ntwo\nthree";
194
195 l = strv_split_newlines(str);
196
197 assert(l);
198
199 STRV_FOREACH(s, l) {
200 assert_se(streq(*s, input_table_multiple[i++]));
201 }
202 }
203
204 static void test_strv_split_nulstr(void) {
205 _cleanup_strv_free_ char **l = NULL;
206 const char nulstr[] = "str0\0str1\0str2\0str3\0";
207
208 l = strv_split_nulstr (nulstr);
209 assert_se(l);
210
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"));
215 }
216
217 static void test_strv_parse_nulstr(void) {
218 _cleanup_strv_free_ char **l = NULL;
219 const char nulstr[] = "fuck\0fuck2\0fuck3\0\0fuck5\0\0xxx";
220
221 l = strv_parse_nulstr(nulstr, sizeof(nulstr)-1);
222 assert_se(l);
223 puts("Parse nulstr:");
224 strv_print(l);
225
226 assert_se(streq(l[0], "fuck"));
227 assert_se(streq(l[1], "fuck2"));
228 assert_se(streq(l[2], "fuck3"));
229 assert_se(streq(l[3], ""));
230 assert_se(streq(l[4], "fuck5"));
231 assert_se(streq(l[5], ""));
232 assert_se(streq(l[6], "xxx"));
233 }
234
235 static void test_strv_overlap(void) {
236 const char * const input_table[] = {
237 "one",
238 "two",
239 "three",
240 NULL
241 };
242 const char * const input_table_overlap[] = {
243 "two",
244 NULL
245 };
246 const char * const input_table_unique[] = {
247 "four",
248 "five",
249 "six",
250 NULL
251 };
252
253 assert_se(strv_overlap((char **)input_table, (char**)input_table_overlap));
254 assert_se(!strv_overlap((char **)input_table, (char**)input_table_unique));
255 }
256
257 static void test_strv_sort(void) {
258 const char* input_table[] = {
259 "durian",
260 "apple",
261 "citrus",
262 "CAPITAL LETTERS FIRST",
263 "banana",
264 NULL
265 };
266
267 strv_sort((char **)input_table);
268
269 assert_se(streq(input_table[0], "CAPITAL LETTERS FIRST"));
270 assert_se(streq(input_table[1], "apple"));
271 assert_se(streq(input_table[2], "banana"));
272 assert_se(streq(input_table[3], "citrus"));
273 assert_se(streq(input_table[4], "durian"));
274 }
275
276 static void test_strv_extend_strv_concat(void) {
277 _cleanup_strv_free_ char **a = NULL, **b = NULL;
278
279 a = strv_new("without", "suffix", NULL);
280 b = strv_new("with", "suffix", NULL);
281 assert_se(a);
282 assert_se(b);
283
284 assert_se(strv_extend_strv_concat(&a, b, "_suffix") >= 0);
285
286 assert_se(streq(a[0], "without"));
287 assert_se(streq(a[1], "suffix"));
288 assert_se(streq(a[2], "with_suffix"));
289 assert_se(streq(a[3], "suffix_suffix"));
290 }
291
292 static void test_strv_extend_strv(void) {
293 _cleanup_strv_free_ char **a = NULL, **b = NULL;
294
295 a = strv_new("abc", "def", "ghi", NULL);
296 b = strv_new("jkl", "mno", "pqr", NULL);
297 assert_se(a);
298 assert_se(b);
299
300 assert_se(strv_extend_strv(&a, b) >= 0);
301
302 assert_se(streq(a[0], "abc"));
303 assert_se(streq(a[1], "def"));
304 assert_se(streq(a[2], "ghi"));
305 assert_se(streq(a[3], "jkl"));
306 assert_se(streq(a[4], "mno"));
307 assert_se(streq(a[5], "pqr"));
308
309 assert_se(strv_length(a) == 6);
310 }
311
312 static void test_strv_extend(void) {
313 _cleanup_strv_free_ char **a = NULL, **b = NULL;
314
315 a = strv_new("test", "test1", NULL);
316 assert_se(a);
317 assert_se(strv_extend(&a, "test2") >= 0);
318 assert_se(strv_extend(&b, "test3") >= 0);
319
320 assert_se(streq(a[0], "test"));
321 assert_se(streq(a[1], "test1"));
322 assert_se(streq(a[2], "test2"));
323 assert_se(streq(b[0], "test3"));
324 }
325
326 static void test_strv_foreach(void) {
327 _cleanup_strv_free_ char **a;
328 unsigned i = 0;
329 char **check;
330
331 a = strv_new("one", "two", "three", NULL);
332
333 assert_se(a);
334
335 STRV_FOREACH(check, a) {
336 assert_se(streq(*check, input_table_multiple[i++]));
337 }
338 }
339
340 static void test_strv_foreach_backwards(void) {
341 _cleanup_strv_free_ char **a;
342 unsigned i = 2;
343 char **check;
344
345 a = strv_new("one", "two", "three", NULL);
346
347 assert_se(a);
348
349 STRV_FOREACH_BACKWARDS(check, a) {
350 assert_se(streq_ptr(*check, input_table_multiple[i--]));
351 }
352 }
353
354 static void test_strv_foreach_pair(void) {
355 _cleanup_strv_free_ char **a = NULL;
356 char **x, **y;
357
358 a = strv_new("pair_one", "pair_one",
359 "pair_two", "pair_two",
360 "pair_three", "pair_three",
361 NULL);
362
363 STRV_FOREACH_PAIR(x, y, a) {
364 assert_se(streq(*x, *y));
365 }
366 }
367
368 static void test_strv_from_stdarg_alloca_one(char **l, const char *first, ...) {
369 char **j;
370 unsigned i;
371
372 j = strv_from_stdarg_alloca(first);
373
374 for (i = 0;; i++) {
375 assert_se(streq_ptr(l[i], j[i]));
376
377 if (!l[i])
378 break;
379 }
380 }
381
382 static void test_strv_from_stdarg_alloca(void) {
383 test_strv_from_stdarg_alloca_one(STRV_MAKE("foo", "bar"), "foo", "bar", NULL);
384 test_strv_from_stdarg_alloca_one(STRV_MAKE("foo"), "foo", NULL);
385 test_strv_from_stdarg_alloca_one(STRV_MAKE_EMPTY, NULL);
386 }
387
388 int main(int argc, char *argv[]) {
389 test_specifier_printf();
390 test_strv_foreach();
391 test_strv_foreach_backwards();
392 test_strv_foreach_pair();
393 test_strv_find();
394 test_strv_find_prefix();
395 test_strv_join();
396
397 test_strv_quote_unquote(input_table_multiple, "\"one\" \"two\" \"three\"");
398 test_strv_quote_unquote(input_table_one, "\"one\"");
399 test_strv_quote_unquote(input_table_none, "");
400 test_strv_quote_unquote(input_table_quotes, QUOTES_STRING);
401 test_strv_quote_unquote(input_table_spaces, SPACES_STRING);
402
403 test_strv_quote_unquote2(" foo=bar \"waldo\" zzz ", (const char*[]) { "foo=bar", "waldo", "zzz", NULL });
404 test_strv_quote_unquote2("", (const char*[]) { NULL });
405 test_strv_quote_unquote2(" ", (const char*[]) { NULL });
406 test_strv_quote_unquote2(" ", (const char*[]) { NULL });
407 test_strv_quote_unquote2(" x", (const char*[]) { "x", NULL });
408 test_strv_quote_unquote2("x ", (const char*[]) { "x", NULL });
409 test_strv_quote_unquote2(" x ", (const char*[]) { "x", NULL });
410 test_strv_quote_unquote2(" \"x\" ", (const char*[]) { "x", NULL });
411 test_strv_quote_unquote2(" \'x\' ", (const char*[]) { "x", NULL });
412 test_strv_quote_unquote2(" \'x\"\' ", (const char*[]) { "x\"", NULL });
413 test_strv_quote_unquote2(" \"x\'\" ", (const char*[]) { "x\'", NULL });
414
415 test_strv_split();
416 test_strv_split_newlines();
417 test_strv_split_nulstr();
418 test_strv_parse_nulstr();
419 test_strv_overlap();
420 test_strv_sort();
421 test_strv_extend_strv();
422 test_strv_extend_strv_concat();
423 test_strv_extend();
424 test_strv_from_stdarg_alloca();
425
426 return 0;
427 }