chiark / gitweb /
journal: optimize bisection logic a bit by caching the last position
[elogind.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         printf("-%s- --- -%s-\n", p, quoted); /* fprintf deals with NULL, puts does not */
147         assert_se(p);
148         assert_se(streq(p, quoted));
149
150         s = strv_split_quoted(quoted);
151         assert_se(s);
152         STRV_FOREACH(t, s) {
153                 assert_se(*t);
154                 assert_se(streq(*t, *split));
155                 split++;
156         }
157 }
158
159 static void test_strv_split(void) {
160         char **s;
161         unsigned i = 0;
162         _cleanup_strv_free_ char **l = NULL;
163         const char str[] = "one,two,three";
164
165         l = strv_split(str, ",");
166
167         assert(l);
168
169         STRV_FOREACH(s, l) {
170                 assert_se(streq(*s, input_table_multiple[i++]));
171         }
172 }
173
174 static void test_strv_split_newlines(void) {
175         unsigned i = 0;
176         char **s;
177         _cleanup_strv_free_ char **l = NULL;
178         const char str[] = "one\ntwo\nthree";
179
180         l = strv_split_newlines(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_nulstr(void) {
190         _cleanup_strv_free_ char **l = NULL;
191         const char nulstr[] = "str0\0str1\0str2\0str3\0";
192
193         l = strv_split_nulstr (nulstr);
194         assert_se(l);
195
196         assert_se(streq(l[0], "str0"));
197         assert_se(streq(l[1], "str1"));
198         assert_se(streq(l[2], "str2"));
199         assert_se(streq(l[3], "str3"));
200 }
201
202 static void test_strv_remove_prefix(void) {
203         unsigned i = 0;
204         char **s;
205         _cleanup_strv_free_ char **l = NULL;
206
207         l = strv_new("_one", "_two", "_three", NULL);
208         assert(l);
209
210         l = strv_remove_prefix(l, "_");
211         assert(l);
212
213         STRV_FOREACH(s, l) {
214                 assert_se(streq(*s, input_table_multiple[i++]));
215         }
216 }
217
218 static void test_strv_parse_nulstr(void) {
219         _cleanup_strv_free_ char **l = NULL;
220         const char nulstr[] = "fuck\0fuck2\0fuck3\0\0fuck5\0\0xxx";
221
222         l = strv_parse_nulstr(nulstr, sizeof(nulstr)-1);
223         assert_se(l);
224         puts("Parse nulstr:");
225         strv_print(l);
226
227         assert_se(streq(l[0], "fuck"));
228         assert_se(streq(l[1], "fuck2"));
229         assert_se(streq(l[2], "fuck3"));
230         assert_se(streq(l[3], ""));
231         assert_se(streq(l[4], "fuck5"));
232         assert_se(streq(l[5], ""));
233         assert_se(streq(l[6], "xxx"));
234 }
235
236 static void test_strv_overlap(void) {
237         const char * const input_table[] = {
238                 "one",
239                 "two",
240                 "three",
241                 NULL
242         };
243         const char * const input_table_overlap[] = {
244                 "two",
245                 NULL
246         };
247         const char * const input_table_unique[] = {
248                 "four",
249                 "five",
250                 "six",
251                 NULL
252         };
253
254         assert_se(strv_overlap((char **)input_table, (char**)input_table_overlap));
255         assert_se(!strv_overlap((char **)input_table, (char**)input_table_unique));
256 }
257
258 static void test_strv_sort(void) {
259         const char* input_table[] = {
260                 "durian",
261                 "apple",
262                 "citrus",
263                  "CAPITAL LETTERS FIRST",
264                 "banana",
265                 NULL
266         };
267
268         strv_sort((char **)input_table);
269
270         assert_se(streq(input_table[0], "CAPITAL LETTERS FIRST"));
271         assert_se(streq(input_table[1], "apple"));
272         assert_se(streq(input_table[2], "banana"));
273         assert_se(streq(input_table[3], "citrus"));
274         assert_se(streq(input_table[4], "durian"));
275 }
276
277 static void test_strv_merge_concat(void) {
278          _cleanup_strv_free_ char **a = NULL, **b = NULL, **c = NULL;
279
280         a = strv_new("without", "suffix", NULL);
281         b = strv_new("with", "suffix", NULL);
282         assert_se(a);
283         assert_se(b);
284
285         c = strv_merge_concat(a, b, "_suffix");
286         assert_se(c);
287
288         assert_se(streq(c[0], "without"));
289         assert_se(streq(c[1], "suffix"));
290         assert_se(streq(c[2], "with_suffix"));
291         assert_se(streq(c[3], "suffix_suffix"));
292 }
293
294 static void test_strv_merge(void) {
295          _cleanup_strv_free_ char **a = NULL, **b = NULL, **c = NULL;
296
297         a = strv_new("abc", "def", "ghi", NULL);
298         b = strv_new("jkl", "mno", "pqr", NULL);
299         assert_se(a);
300         assert_se(b);
301
302         c = strv_merge(a, b);
303         assert_se(c);
304
305         assert_se(streq(c[0], "abc"));
306         assert_se(streq(c[1], "def"));
307         assert_se(streq(c[2], "ghi"));
308         assert_se(streq(c[3], "jkl"));
309         assert_se(streq(c[4], "mno"));
310         assert_se(streq(c[5], "pqr"));
311
312         assert_se(strv_length(c) == 6);
313 }
314
315 static void test_strv_append(void) {
316         _cleanup_strv_free_ char **a = NULL, **b = NULL, **c = NULL;
317
318         a = strv_new("test", "test1", NULL);
319         assert_se(a);
320         b = strv_append(a, "test2");
321         c = strv_append(NULL, "test3");
322         assert_se(b);
323         assert_se(c);
324
325         assert_se(streq(b[0], "test"));
326         assert_se(streq(b[1], "test1"));
327         assert_se(streq(b[2], "test2"));
328         assert_se(streq(c[0], "test3"));
329 }
330
331 static void test_strv_foreach(void) {
332         _cleanup_strv_free_ char **a;
333         unsigned i = 0;
334         char **check;
335
336         a = strv_new("one", "two", "three", NULL);
337
338         assert_se(a);
339
340         STRV_FOREACH(check, a) {
341                 assert_se(streq(*check, input_table_multiple[i++]));
342         }
343 }
344
345 static void test_strv_foreach_backwards(void) {
346         _cleanup_strv_free_ char **a;
347         unsigned i = 2;
348         char **check;
349
350         a = strv_new("one", "two", "three", NULL);
351
352         assert_se(a);
353
354         STRV_FOREACH_BACKWARDS(check, a) {
355                 assert_se(streq(*check, input_table_multiple[i--]));
356         }
357 }
358
359 static void test_strv_foreach_pair(void) {
360         _cleanup_strv_free_ char **a = NULL;
361         char **x, **y;
362
363         a = strv_new("pair_one",   "pair_one",
364                      "pair_two",   "pair_two",
365                      "pair_three", "pair_three",
366                      NULL);
367
368         STRV_FOREACH_PAIR(x, y, a) {
369                 assert_se(streq(*x, *y));
370         }
371 }
372
373 static void test_strv_from_stdarg_alloca_one(char **l, const char *first, ...) {
374         char **j;
375         unsigned i;
376
377         j = strv_from_stdarg_alloca(first);
378
379         for (i = 0;; i++) {
380                 assert_se(streq_ptr(l[i], j[i]));
381
382                 if (!l[i])
383                         break;
384         }
385 }
386
387 static void test_strv_from_stdarg_alloca(void) {
388         test_strv_from_stdarg_alloca_one(STRV_MAKE("foo", "bar"), "foo", "bar", NULL);
389         test_strv_from_stdarg_alloca_one(STRV_MAKE("foo"), "foo", NULL);
390         test_strv_from_stdarg_alloca_one(STRV_MAKE_EMPTY, NULL);
391 }
392
393 int main(int argc, char *argv[]) {
394         test_specifier_printf();
395         test_strv_foreach();
396         test_strv_foreach_backwards();
397         test_strv_foreach_pair();
398         test_strv_find();
399         test_strv_find_prefix();
400         test_strv_join();
401
402         test_strv_quote_unquote(input_table_multiple, "\"one\" \"two\" \"three\"");
403         test_strv_quote_unquote(input_table_one, "\"one\"");
404         test_strv_quote_unquote(input_table_none, "");
405         test_strv_quote_unquote(input_table_quotes, QUOTES_STRING);
406         test_strv_quote_unquote(input_table_spaces, SPACES_STRING);
407
408         test_strv_split();
409         test_strv_split_newlines();
410         test_strv_split_nulstr();
411         test_strv_parse_nulstr();
412         test_strv_remove_prefix();
413         test_strv_overlap();
414         test_strv_sort();
415         test_strv_merge();
416         test_strv_merge_concat();
417         test_strv_append();
418         test_strv_from_stdarg_alloca();
419
420         return 0;
421 }