]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-strv.c
license: LGPL-2.1+ -> LGPL-2.1-or-later
[thirdparty/systemd.git] / src / test / test-strv.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
f90cf44c 2
b5efdb8a 3#include "alloc-util.h"
e7b2ea7c 4#include "escape.h"
d8b4d14d 5#include "nulstr-util.h"
2c4b304e 6#include "specifier.h"
07630cea 7#include "string-util.h"
682cfdff 8#include "strv.h"
f90cf44c 9
3a7719d3 10static void test_specifier_printf(void) {
1731e34a 11 static const Specifier table[] = {
268f5a54
LP
12 { 'X', specifier_string, (char*) "AAAA" },
13 { 'Y', specifier_string, (char*) "BBBB" },
14 { 'm', specifier_machine_id, NULL },
15 { 'b', specifier_boot_id, NULL },
16 { 'H', specifier_host_name, NULL },
19f6d710 17 { 'v', specifier_kernel_release, NULL },
268f5a54
LP
18 { 'a', specifier_architecture, NULL },
19 { 'o', specifier_os_id, NULL },
20 { 'w', specifier_os_version_id, NULL },
21 { 'B', specifier_os_build_id, NULL },
22 { 'W', specifier_os_variant_id, NULL },
1731e34a 23 {}
2c4b304e
LP
24 };
25
1731e34a
LP
26 _cleanup_free_ char *w = NULL;
27 int r;
28
0bf2c5e5
ZJS
29 log_info("/* %s */", __func__);
30
268f5a54 31 r = specifier_printf("xxx a=%X b=%Y yyy", table, NULL, &w);
19f6d710
LP
32 assert_se(r >= 0);
33 assert_se(w);
34
9f316366 35 puts(w);
19f6d710 36 assert_se(streq(w, "xxx a=AAAA b=BBBB yyy"));
9f316366 37
19f6d710 38 free(w);
268f5a54 39 r = specifier_printf("machine=%m, boot=%b, host=%H, version=%v, arch=%a", table, NULL, &w);
19f6d710 40 assert_se(r >= 0);
9f316366 41 assert_se(w);
19f6d710 42 puts(w);
268f5a54
LP
43
44 w = mfree(w);
45 specifier_printf("os=%o, os-version=%w, build=%B, variant=%W", table, NULL, &w);
46 if (w)
47 puts(w);
3a7719d3
DB
48}
49
c7bf9d51 50static void test_str_in_set(void) {
0bf2c5e5
ZJS
51 log_info("/* %s */", __func__);
52
c7bf9d51
ZJS
53 assert_se(STR_IN_SET("x", "x", "y", "z"));
54 assert_se(!STR_IN_SET("X", "x", "y", "z"));
55 assert_se(!STR_IN_SET("", "x", "y", "z"));
56 assert_se(STR_IN_SET("x", "w", "x"));
57}
58
59static void test_strptr_in_set(void) {
0bf2c5e5
ZJS
60 log_info("/* %s */", __func__);
61
c7bf9d51
ZJS
62 assert_se(STRPTR_IN_SET("x", "x", "y", "z"));
63 assert_se(!STRPTR_IN_SET("X", "x", "y", "z"));
64 assert_se(!STRPTR_IN_SET("", "x", "y", "z"));
65 assert_se(STRPTR_IN_SET("x", "w", "x"));
66
67 assert_se(!STRPTR_IN_SET(NULL, "x", "y", "z"));
68 assert_se(!STRPTR_IN_SET(NULL, ""));
69 /* strv cannot contain a null, hence the result below */
70 assert_se(!STRPTR_IN_SET(NULL, NULL));
71}
72
52f15520 73static void test_startswith_set(void) {
0bf2c5e5
ZJS
74 log_info("/* %s */", __func__);
75
52f15520
LP
76 assert_se(!STARTSWITH_SET("foo", "bar", "baz", "waldo"));
77 assert_se(!STARTSWITH_SET("foo", "bar"));
78
79 assert_se(STARTSWITH_SET("abc", "a", "ab", "abc"));
80 assert_se(STARTSWITH_SET("abc", "ax", "ab", "abc"));
81 assert_se(STARTSWITH_SET("abc", "ax", "abx", "abc"));
82 assert_se(!STARTSWITH_SET("abc", "ax", "abx", "abcx"));
83
84 assert_se(streq_ptr(STARTSWITH_SET("foobar", "hhh", "kkk", "foo", "zzz"), "bar"));
85 assert_se(streq_ptr(STARTSWITH_SET("foobar", "hhh", "kkk", "", "zzz"), "foobar"));
86 assert_se(streq_ptr(STARTSWITH_SET("", "hhh", "kkk", "zzz", ""), ""));
87}
88
a6fde353
ZJS
89static const char* const input_table_multiple[] = {
90 "one",
91 "two",
92 "three",
93 NULL,
94};
95
1f938af8
YW
96static const char* const input_table_quoted[] = {
97 "one",
98 " two\t three ",
99 " four five",
100 NULL,
101};
102
0645b83a
ZJS
103static const char* const input_table_quoted_joined[] = {
104 "one",
105 " two\t three " " four five",
106 NULL,
107};
108
a6fde353
ZJS
109static const char* const input_table_one[] = {
110 "one",
111 NULL,
112};
113
114static const char* const input_table_none[] = {
115 NULL,
116};
117
afe773b0
ZJS
118static const char* const input_table_two_empties[] = {
119 "",
120 "",
121 NULL,
122};
123
124static const char* const input_table_one_empty[] = {
125 "",
126 NULL,
127};
128
a6fde353 129static void test_strv_find(void) {
0bf2c5e5
ZJS
130 log_info("/* %s */", __func__);
131
a6fde353
ZJS
132 assert_se(strv_find((char **)input_table_multiple, "three"));
133 assert_se(!strv_find((char **)input_table_multiple, "four"));
539ad707
TA
134}
135
136static void test_strv_find_prefix(void) {
0bf2c5e5
ZJS
137 log_info("/* %s */", __func__);
138
a6fde353
ZJS
139 assert_se(strv_find_prefix((char **)input_table_multiple, "o"));
140 assert_se(strv_find_prefix((char **)input_table_multiple, "one"));
141 assert_se(strv_find_prefix((char **)input_table_multiple, ""));
142 assert_se(!strv_find_prefix((char **)input_table_multiple, "xxx"));
143 assert_se(!strv_find_prefix((char **)input_table_multiple, "onee"));
3a7719d3 144}
f90cf44c 145
7bd57a87
RC
146static void test_strv_find_startswith(void) {
147 char *r;
148
0bf2c5e5
ZJS
149 log_info("/* %s */", __func__);
150
7bd57a87
RC
151 r = strv_find_startswith((char **)input_table_multiple, "o");
152 assert_se(r && streq(r, "ne"));
153
154 r = strv_find_startswith((char **)input_table_multiple, "one");
155 assert_se(r && streq(r, ""));
156
157 r = strv_find_startswith((char **)input_table_multiple, "");
158 assert_se(r && streq(r, "one"));
159
160 assert_se(!strv_find_startswith((char **)input_table_multiple, "xxx"));
161 assert_se(!strv_find_startswith((char **)input_table_multiple, "onee"));
162}
163
682cfdff 164static void test_strv_join(void) {
0bf2c5e5
ZJS
165 log_info("/* %s */", __func__);
166
d4d9f034 167 _cleanup_free_ char *p = strv_join((char **)input_table_multiple, ", ");
04045d84 168 assert_se(p);
7b68d618 169 assert_se(streq(p, "one, two, three"));
682cfdff 170
d4d9f034 171 _cleanup_free_ char *q = strv_join((char **)input_table_multiple, ";");
04045d84 172 assert_se(q);
7b68d618 173 assert_se(streq(q, "one;two;three"));
682cfdff 174
d4d9f034 175 _cleanup_free_ char *r = strv_join((char **)input_table_multiple, NULL);
04045d84 176 assert_se(r);
7b68d618 177 assert_se(streq(r, "one two three"));
539ad707 178
d4d9f034 179 _cleanup_free_ char *s = strv_join(STRV_MAKE("1", "2", "3,3"), ",");
04045d84 180 assert_se(s);
d4d9f034 181 assert_se(streq(s, "1,2,3,3"));
539ad707 182
d4d9f034 183 _cleanup_free_ char *t = strv_join((char **)input_table_one, ", ");
04045d84 184 assert_se(t);
d4d9f034
ZJS
185 assert_se(streq(t, "one"));
186
187 _cleanup_free_ char *u = strv_join((char **)input_table_none, ", ");
188 assert_se(u);
189 assert_se(streq(u, ""));
afe773b0 190
d4d9f034 191 _cleanup_free_ char *v = strv_join((char **)input_table_two_empties, ", ");
afe773b0
ZJS
192 assert_se(v);
193 assert_se(streq(v, ", "));
194
d4d9f034 195 _cleanup_free_ char *w = strv_join((char **)input_table_one_empty, ", ");
afe773b0
ZJS
196 assert_se(w);
197 assert_se(streq(w, ""));
682cfdff
DB
198}
199
d4d9f034 200static void test_strv_join_full(void) {
0bf2c5e5
ZJS
201 log_info("/* %s */", __func__);
202
d4d9f034 203 _cleanup_free_ char *p = strv_join_full((char **)input_table_multiple, ", ", "foo", false);
474a595a
YW
204 assert_se(p);
205 assert_se(streq(p, "fooone, footwo, foothree"));
206
d4d9f034 207 _cleanup_free_ char *q = strv_join_full((char **)input_table_multiple, ";", "foo", false);
474a595a
YW
208 assert_se(q);
209 assert_se(streq(q, "fooone;footwo;foothree"));
210
d4d9f034 211 _cleanup_free_ char *r = strv_join_full(STRV_MAKE("a", "a;b", "a:c"), ";", NULL, true);
474a595a 212 assert_se(r);
d4d9f034 213 assert_se(streq(r, "a;a\\;b;a:c"));
474a595a 214
d4d9f034 215 _cleanup_free_ char *s = strv_join_full(STRV_MAKE("a", "a;b", "a;;c", ";", ";x"), ";", NULL, true);
474a595a 216 assert_se(s);
d4d9f034 217 assert_se(streq(s, "a;a\\;b;a\\;\\;c;\\;;\\;x"));
474a595a 218
d4d9f034 219 _cleanup_free_ char *t = strv_join_full(STRV_MAKE("a", "a;b", "a:c", ";"), ";", "=", true);
474a595a 220 assert_se(t);
d4d9f034
ZJS
221 assert_se(streq(t, "=a;=a\\;b;=a:c;=\\;"));
222 t = mfree(t);
223
224 _cleanup_free_ char *u = strv_join_full((char **)input_table_multiple, NULL, "foo", false);
225 assert_se(u);
226 assert_se(streq(u, "fooone footwo foothree"));
474a595a 227
d4d9f034 228 _cleanup_free_ char *v = strv_join_full((char **)input_table_one, ", ", "foo", false);
474a595a 229 assert_se(v);
d4d9f034 230 assert_se(streq(v, "fooone"));
474a595a 231
d4d9f034 232 _cleanup_free_ char *w = strv_join_full((char **)input_table_none, ", ", "foo", false);
474a595a 233 assert_se(w);
d4d9f034
ZJS
234 assert_se(streq(w, ""));
235
236 _cleanup_free_ char *x = strv_join_full((char **)input_table_two_empties, ", ", "foo", false);
237 assert_se(x);
238 assert_se(streq(x, "foo, foo"));
239
240 _cleanup_free_ char *y = strv_join_full((char **)input_table_one_empty, ", ", "foo", false);
241 assert_se(y);
242 assert_se(streq(y, "foo"));
474a595a
YW
243}
244
30bcc052 245static void test_strv_unquote(const char *quoted, char **list) {
70f75a52 246 _cleanup_strv_free_ char **s;
a2a5291b 247 _cleanup_free_ char *j;
70f75a52
LP
248 unsigned i = 0;
249 char **t;
b2fadec6 250 int r;
70f75a52 251
0bf2c5e5
ZJS
252 log_info("/* %s */", __func__);
253
90e30d76 254 r = strv_split_full(&s, quoted, WHITESPACE, EXTRACT_UNQUOTE);
8dd4c05b 255 assert_se(r == (int) strv_length(list));
70f75a52 256 assert_se(s);
a2a5291b 257 j = strv_join(s, " | ");
bdf7026e 258 assert_se(j);
a2a5291b 259 puts(j);
70f75a52
LP
260
261 STRV_FOREACH(t, s)
262 assert_se(streq(list[i++], *t));
263
264 assert_se(list[i] == NULL);
265}
266
a2a5291b 267static void test_invalid_unquote(const char *quoted) {
b2fadec6
ZJS
268 char **s = NULL;
269 int r;
a2a5291b 270
0bf2c5e5
ZJS
271 log_info("/* %s */", __func__);
272
90e30d76 273 r = strv_split_full(&s, quoted, WHITESPACE, EXTRACT_UNQUOTE);
bdf7026e
TA
274 assert_se(s == NULL);
275 assert_se(r == -EINVAL);
a2a5291b
ZJS
276}
277
aed2ebfe 278static void test_strv_split(void) {
b4f386d5 279 _cleanup_(strv_free_erasep) char **l = NULL;
aed2ebfe
DB
280 const char str[] = "one,two,three";
281
0bf2c5e5
ZJS
282 log_info("/* %s */", __func__);
283
aed2ebfe 284 l = strv_split(str, ",");
bdf7026e 285 assert_se(l);
1f938af8 286 assert_se(strv_equal(l, (char**) input_table_multiple));
aed2ebfe 287
b4f386d5 288 strv_free_erase(l);
0745ce75
YW
289
290 l = strv_split(" one two\t three", WHITESPACE);
291 assert_se(l);
1f938af8
YW
292 assert_se(strv_equal(l, (char**) input_table_multiple));
293
b4f386d5 294 strv_free_erase(l);
1f938af8
YW
295
296 /* Setting NULL for separator is equivalent to WHITESPACE */
297 l = strv_split(" one two\t three", NULL);
298 assert_se(l);
299 assert_se(strv_equal(l, (char**) input_table_multiple));
300
b4f386d5 301 strv_free_erase(l);
1f938af8 302
90e30d76 303 assert_se(strv_split_full(&l, " one two\t three", NULL, 0) == 3);
1f938af8
YW
304 assert_se(strv_equal(l, (char**) input_table_multiple));
305
b4f386d5 306 strv_free_erase(l);
1f938af8 307
90e30d76 308 assert_se(strv_split_full(&l, " 'one' \" two\t three \" ' four five'", NULL, EXTRACT_UNQUOTE) == 3);
1f938af8
YW
309 assert_se(strv_equal(l, (char**) input_table_quoted));
310
0645b83a 311 l = strv_free_erase(l);
1f938af8 312
0645b83a 313 /* missing last quote causes extraction to fail. */
90e30d76 314 assert_se(strv_split_full(&l, " 'one' \" two\t three \" ' four five", NULL, EXTRACT_UNQUOTE) == -EINVAL);
0645b83a 315 assert_se(!l);
1f938af8 316
0645b83a 317 /* missing last quote, but the last element is _not_ ignored with EXTRACT_RELAX. */
90e30d76 318 assert_se(strv_split_full(&l, " 'one' \" two\t three \" ' four five", NULL, EXTRACT_UNQUOTE | EXTRACT_RELAX) == 3);
1f938af8
YW
319 assert_se(strv_equal(l, (char**) input_table_quoted));
320
0645b83a 321 l = strv_free_erase(l);
1f938af8 322
0645b83a 323 /* missing separator between items */
90e30d76 324 assert_se(strv_split_full(&l, " 'one' \" two\t three \"' four five'", NULL, EXTRACT_UNQUOTE | EXTRACT_RELAX) == 2);
0645b83a 325 assert_se(strv_equal(l, (char**) input_table_quoted_joined));
1f938af8 326
0645b83a 327 l = strv_free_erase(l);
1f938af8 328
90e30d76 329 assert_se(strv_split_full(&l, " 'one' \" two\t three \"' four five", NULL,
0645b83a
ZJS
330 EXTRACT_UNQUOTE | EXTRACT_RELAX | EXTRACT_CUNESCAPE_RELAX) == 2);
331 assert_se(strv_equal(l, (char**) input_table_quoted_joined));
29965a2a 332
0645b83a 333 l = strv_free_erase(l);
29965a2a 334
90e30d76 335 assert_se(strv_split_full(&l, "\\", NULL, EXTRACT_UNQUOTE | EXTRACT_RELAX | EXTRACT_CUNESCAPE_RELAX) == 1);
29965a2a 336 assert_se(strv_equal(l, STRV_MAKE("\\")));
0745ce75
YW
337}
338
339static void test_strv_split_empty(void) {
340 _cleanup_strv_free_ char **l = NULL;
341
0bf2c5e5
ZJS
342 log_info("/* %s */", __func__);
343
0745ce75
YW
344 l = strv_split("", WHITESPACE);
345 assert_se(l);
346 assert_se(strv_isempty(l));
0645b83a 347 l = strv_free(l);
0745ce75 348
0645b83a 349 assert_se(l = strv_split("", NULL));
1f938af8 350 assert_se(strv_isempty(l));
0645b83a 351 l = strv_free(l);
1f938af8 352
90e30d76 353 assert_se(strv_split_full(&l, "", NULL, 0) == 0);
1f938af8
YW
354 assert_se(l);
355 assert_se(strv_isempty(l));
0645b83a 356 l = strv_free(l);
1f938af8 357
90e30d76 358 assert_se(strv_split_full(&l, "", NULL, EXTRACT_UNQUOTE) == 0);
1f938af8
YW
359 assert_se(l);
360 assert_se(strv_isempty(l));
0645b83a 361 l = strv_free(l);
1f938af8 362
90e30d76 363 assert_se(strv_split_full(&l, "", WHITESPACE, EXTRACT_UNQUOTE) == 0);
1f938af8
YW
364 assert_se(l);
365 assert_se(strv_isempty(l));
0645b83a 366 l = strv_free(l);
1f938af8 367
90e30d76 368 assert_se(strv_split_full(&l, "", WHITESPACE, EXTRACT_UNQUOTE | EXTRACT_RELAX) == 0);
1f938af8
YW
369 assert_se(l);
370 assert_se(strv_isempty(l));
0745ce75 371 strv_free(l);
0645b83a 372
0745ce75
YW
373 l = strv_split(" ", WHITESPACE);
374 assert_se(l);
375 assert_se(strv_isempty(l));
1f938af8 376 strv_free(l);
0645b83a 377
1f938af8
YW
378 l = strv_split(" ", NULL);
379 assert_se(l);
380 assert_se(strv_isempty(l));
0645b83a 381 l = strv_free(l);
1f938af8 382
90e30d76 383 assert_se(strv_split_full(&l, " ", NULL, 0) == 0);
1f938af8
YW
384 assert_se(l);
385 assert_se(strv_isempty(l));
0645b83a 386 l = strv_free(l);
1f938af8 387
90e30d76 388 assert_se(strv_split_full(&l, " ", WHITESPACE, EXTRACT_UNQUOTE) == 0);
1f938af8
YW
389 assert_se(l);
390 assert_se(strv_isempty(l));
0645b83a 391 l = strv_free(l);
1f938af8 392
90e30d76 393 assert_se(strv_split_full(&l, " ", NULL, EXTRACT_UNQUOTE) == 0);
1f938af8
YW
394 assert_se(l);
395 assert_se(strv_isempty(l));
0645b83a 396 l = strv_free(l);
1f938af8 397
90e30d76 398 assert_se(strv_split_full(&l, " ", NULL, EXTRACT_UNQUOTE | EXTRACT_RELAX) == 0);
1f938af8
YW
399 assert_se(l);
400 assert_se(strv_isempty(l));
aed2ebfe
DB
401}
402
90e30d76 403static void test_strv_split_full(void) {
8adaf7bd
RM
404 _cleanup_strv_free_ char **l = NULL;
405 const char *str = ":foo\\:bar::waldo:";
406 int r;
407
0bf2c5e5
ZJS
408 log_info("/* %s */", __func__);
409
90e30d76 410 r = strv_split_full(&l, str, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
8dd4c05b 411 assert_se(r == (int) strv_length(l));
8adaf7bd
RM
412 assert_se(streq_ptr(l[0], ""));
413 assert_se(streq_ptr(l[1], "foo:bar"));
414 assert_se(streq_ptr(l[2], ""));
415 assert_se(streq_ptr(l[3], "waldo"));
416 assert_se(streq_ptr(l[4], ""));
417 assert_se(streq_ptr(l[5], NULL));
418}
419
a082edd5
LB
420static void test_strv_split_colon_pairs(void) {
421 _cleanup_strv_free_ char **l = NULL;
422 const char *str = "one:two three four:five six seven:eight\\:nine ten\\:eleven\\\\",
423 *str_inval="one:two three:four:five";
424 int r;
425
426 log_info("/* %s */", __func__);
427
428 r = strv_split_colon_pairs(&l, str);
429 assert_se(r == (int) strv_length(l));
430 assert_se(r == 12);
431 assert_se(streq_ptr(l[0], "one"));
432 assert_se(streq_ptr(l[1], "two"));
433 assert_se(streq_ptr(l[2], "three"));
434 assert_se(streq_ptr(l[3], ""));
435 assert_se(streq_ptr(l[4], "four"));
436 assert_se(streq_ptr(l[5], "five"));
437 assert_se(streq_ptr(l[6], "six"));
438 assert_se(streq_ptr(l[7], ""));
439 assert_se(streq_ptr(l[8], "seven"));
440 assert_se(streq_ptr(l[9], "eight:nine"));
441 assert_se(streq_ptr(l[10], "ten:eleven\\"));
442 assert_se(streq_ptr(l[11], ""));
443 assert_se(streq_ptr(l[12], NULL));
444
445 r = strv_split_colon_pairs(&l, str_inval);
446 assert_se(r == -EINVAL);
447}
448
aed2ebfe
DB
449static void test_strv_split_newlines(void) {
450 unsigned i = 0;
451 char **s;
452 _cleanup_strv_free_ char **l = NULL;
453 const char str[] = "one\ntwo\nthree";
454
0bf2c5e5 455 log_info("/* %s */", __func__);
aed2ebfe 456
0bf2c5e5 457 l = strv_split_newlines(str);
bdf7026e 458 assert_se(l);
aed2ebfe 459
38cd55b0 460 STRV_FOREACH(s, l)
aed2ebfe 461 assert_se(streq(*s, input_table_multiple[i++]));
aed2ebfe
DB
462}
463
2f213f74
DB
464static void test_strv_split_nulstr(void) {
465 _cleanup_strv_free_ char **l = NULL;
466 const char nulstr[] = "str0\0str1\0str2\0str3\0";
467
0bf2c5e5
ZJS
468 log_info("/* %s */", __func__);
469
2f213f74 470 l = strv_split_nulstr (nulstr);
04045d84 471 assert_se(l);
2f213f74
DB
472
473 assert_se(streq(l[0], "str0"));
474 assert_se(streq(l[1], "str1"));
475 assert_se(streq(l[2], "str2"));
476 assert_se(streq(l[3], "str3"));
477}
478
10ddd913
TA
479static void test_strv_parse_nulstr(void) {
480 _cleanup_strv_free_ char **l = NULL;
a2917d3d 481 const char nulstr[] = "hoge\0hoge2\0hoge3\0\0hoge5\0\0xxx";
10ddd913 482
0bf2c5e5
ZJS
483 log_info("/* %s */", __func__);
484
10ddd913 485 l = strv_parse_nulstr(nulstr, sizeof(nulstr)-1);
04045d84 486 assert_se(l);
10ddd913
TA
487 puts("Parse nulstr:");
488 strv_print(l);
489
a2917d3d
YW
490 assert_se(streq(l[0], "hoge"));
491 assert_se(streq(l[1], "hoge2"));
492 assert_se(streq(l[2], "hoge3"));
7b68d618 493 assert_se(streq(l[3], ""));
a2917d3d 494 assert_se(streq(l[4], "hoge5"));
7b68d618
DB
495 assert_se(streq(l[5], ""));
496 assert_se(streq(l[6], "xxx"));
10ddd913
TA
497}
498
539ad707
TA
499static void test_strv_overlap(void) {
500 const char * const input_table[] = {
501 "one",
502 "two",
503 "three",
504 NULL
505 };
506 const char * const input_table_overlap[] = {
507 "two",
508 NULL
509 };
510 const char * const input_table_unique[] = {
511 "four",
512 "five",
513 "six",
514 NULL
515 };
516
0bf2c5e5
ZJS
517 log_info("/* %s */", __func__);
518
7b68d618
DB
519 assert_se(strv_overlap((char **)input_table, (char**)input_table_overlap));
520 assert_se(!strv_overlap((char **)input_table, (char**)input_table_unique));
539ad707
TA
521}
522
523static void test_strv_sort(void) {
1e64bbc1 524 const char* input_table[] = {
539ad707
TA
525 "durian",
526 "apple",
527 "citrus",
528 "CAPITAL LETTERS FIRST",
529 "banana",
530 NULL
531 };
532
0bf2c5e5
ZJS
533 log_info("/* %s */", __func__);
534
539ad707
TA
535 strv_sort((char **)input_table);
536
7b68d618
DB
537 assert_se(streq(input_table[0], "CAPITAL LETTERS FIRST"));
538 assert_se(streq(input_table[1], "apple"));
539 assert_se(streq(input_table[2], "banana"));
540 assert_se(streq(input_table[3], "citrus"));
541 assert_se(streq(input_table[4], "durian"));
3a7719d3 542}
e3aa71c3 543
e3e45d4f 544static void test_strv_extend_strv_concat(void) {
7d6884b6 545 _cleanup_strv_free_ char **a = NULL, **b = NULL;
343a8969 546
0bf2c5e5
ZJS
547 log_info("/* %s */", __func__);
548
bea1a013
LP
549 a = strv_new("without", "suffix");
550 b = strv_new("with", "suffix");
04045d84
DB
551 assert_se(a);
552 assert_se(b);
343a8969 553
e3e45d4f 554 assert_se(strv_extend_strv_concat(&a, b, "_suffix") >= 0);
343a8969 555
e3e45d4f
SP
556 assert_se(streq(a[0], "without"));
557 assert_se(streq(a[1], "suffix"));
558 assert_se(streq(a[2], "with_suffix"));
559 assert_se(streq(a[3], "suffix_suffix"));
343a8969
DB
560}
561
e3e45d4f 562static void test_strv_extend_strv(void) {
ea9b54f8 563 _cleanup_strv_free_ char **a = NULL, **b = NULL, **n = NULL;
a1022300 564
0bf2c5e5
ZJS
565 log_info("/* %s */", __func__);
566
bea1a013
LP
567 a = strv_new("abc", "def", "ghi");
568 b = strv_new("jkl", "mno", "abc", "pqr");
04045d84
DB
569 assert_se(a);
570 assert_se(b);
a1022300 571
e287086b 572 assert_se(strv_extend_strv(&a, b, true) == 3);
a1022300 573
e3e45d4f
SP
574 assert_se(streq(a[0], "abc"));
575 assert_se(streq(a[1], "def"));
576 assert_se(streq(a[2], "ghi"));
577 assert_se(streq(a[3], "jkl"));
578 assert_se(streq(a[4], "mno"));
579 assert_se(streq(a[5], "pqr"));
e3e45d4f 580 assert_se(strv_length(a) == 6);
ea9b54f8
ZJS
581
582 assert_se(strv_extend_strv(&n, b, false) >= 0);
583 assert_se(streq(n[0], "jkl"));
584 assert_se(streq(n[1], "mno"));
585 assert_se(streq(n[2], "abc"));
586 assert_se(streq(n[3], "pqr"));
587 assert_se(strv_length(n) == 4);
a1022300
DB
588}
589
e3e45d4f
SP
590static void test_strv_extend(void) {
591 _cleanup_strv_free_ char **a = NULL, **b = NULL;
40857008 592
0bf2c5e5
ZJS
593 log_info("/* %s */", __func__);
594
bea1a013 595 a = strv_new("test", "test1");
04045d84 596 assert_se(a);
e3e45d4f
SP
597 assert_se(strv_extend(&a, "test2") >= 0);
598 assert_se(strv_extend(&b, "test3") >= 0);
40857008 599
e3e45d4f
SP
600 assert_se(streq(a[0], "test"));
601 assert_se(streq(a[1], "test1"));
602 assert_se(streq(a[2], "test2"));
603 assert_se(streq(b[0], "test3"));
40857008
DB
604}
605
4a336a69
RC
606static void test_strv_extendf(void) {
607 _cleanup_strv_free_ char **a = NULL, **b = NULL;
608
0bf2c5e5
ZJS
609 log_info("/* %s */", __func__);
610
bea1a013 611 a = strv_new("test", "test1");
4a336a69
RC
612 assert_se(a);
613 assert_se(strv_extendf(&a, "test2 %s %d %s", "foo", 128, "bar") >= 0);
614 assert_se(strv_extendf(&b, "test3 %s %s %d", "bar", "foo", 128) >= 0);
615
616 assert_se(streq(a[0], "test"));
617 assert_se(streq(a[1], "test1"));
618 assert_se(streq(a[2], "test2 foo 128 bar"));
619 assert_se(streq(b[0], "test3 bar foo 128"));
620}
621
02f19706 622static void test_strv_foreach(void) {
250a918d
LP
623 _cleanup_strv_free_ char **a;
624 unsigned i = 0;
625 char **check;
02f19706 626
0bf2c5e5 627 log_info("/* %s */", __func__);
02f19706 628
0bf2c5e5 629 a = strv_new("one", "two", "three");
250a918d 630 assert_se(a);
02f19706 631
0bf2c5e5 632 STRV_FOREACH(check, a)
250a918d 633 assert_se(streq(*check, input_table_multiple[i++]));
02f19706
DB
634}
635
636static void test_strv_foreach_backwards(void) {
250a918d
LP
637 _cleanup_strv_free_ char **a;
638 unsigned i = 2;
639 char **check;
02f19706 640
0bf2c5e5
ZJS
641 log_info("/* %s */", __func__);
642
bea1a013 643 a = strv_new("one", "two", "three");
02f19706 644
250a918d 645 assert_se(a);
02f19706 646
4a39c774 647 STRV_FOREACH_BACKWARDS(check, a)
5fba7bbf 648 assert_se(streq_ptr(*check, input_table_multiple[i--]));
4a39c774
LP
649
650 STRV_FOREACH_BACKWARDS(check, (char**) NULL)
651 assert_not_reached("Let's see that we check empty strv right, too.");
652
653 STRV_FOREACH_BACKWARDS(check, (char**) { NULL })
654 assert_not_reached("Let's see that we check empty strv right, too.");
02f19706
DB
655}
656
4c325b2e
DB
657static void test_strv_foreach_pair(void) {
658 _cleanup_strv_free_ char **a = NULL;
659 char **x, **y;
660
0bf2c5e5
ZJS
661 log_info("/* %s */", __func__);
662
4c325b2e
DB
663 a = strv_new("pair_one", "pair_one",
664 "pair_two", "pair_two",
bea1a013 665 "pair_three", "pair_three");
0bf2c5e5 666 STRV_FOREACH_PAIR(x, y, a)
4c325b2e 667 assert_se(streq(*x, *y));
4c325b2e
DB
668}
669
897e7561 670static void test_strv_from_stdarg_alloca_one(char **l, const char *first, ...) {
250a918d
LP
671 char **j;
672 unsigned i;
673
0bf2c5e5
ZJS
674 log_info("/* %s */", __func__);
675
250a918d
LP
676 j = strv_from_stdarg_alloca(first);
677
678 for (i = 0;; i++) {
679 assert_se(streq_ptr(l[i], j[i]));
680
681 if (!l[i])
682 break;
683 }
684}
685
686static void test_strv_from_stdarg_alloca(void) {
0bf2c5e5
ZJS
687 log_info("/* %s */", __func__);
688
897e7561
LP
689 test_strv_from_stdarg_alloca_one(STRV_MAKE("foo", "bar"), "foo", "bar", NULL);
690 test_strv_from_stdarg_alloca_one(STRV_MAKE("foo"), "foo", NULL);
691 test_strv_from_stdarg_alloca_one(STRV_MAKE_EMPTY, NULL);
250a918d
LP
692}
693
6e888894
ZJS
694static void test_strv_insert(void) {
695 _cleanup_strv_free_ char **a = NULL;
696
0bf2c5e5
ZJS
697 log_info("/* %s */", __func__);
698
6e888894
ZJS
699 assert_se(strv_insert(&a, 0, strdup("first")) == 0);
700 assert_se(streq(a[0], "first"));
701 assert_se(!a[1]);
702
703 assert_se(strv_insert(&a, 0, NULL) == 0);
704 assert_se(streq(a[0], "first"));
705 assert_se(!a[1]);
706
707 assert_se(strv_insert(&a, 1, strdup("two")) == 0);
708 assert_se(streq(a[0], "first"));
709 assert_se(streq(a[1], "two"));
710 assert_se(!a[2]);
711
712 assert_se(strv_insert(&a, 4, strdup("tri")) == 0);
713 assert_se(streq(a[0], "first"));
714 assert_se(streq(a[1], "two"));
715 assert_se(streq(a[2], "tri"));
716 assert_se(!a[3]);
717
718 assert_se(strv_insert(&a, 1, strdup("duo")) == 0);
719 assert_se(streq(a[0], "first"));
720 assert_se(streq(a[1], "duo"));
721 assert_se(streq(a[2], "two"));
722 assert_se(streq(a[3], "tri"));
723 assert_se(!a[4]);
724}
725
7bd57a87
RC
726static void test_strv_push_prepend(void) {
727 _cleanup_strv_free_ char **a = NULL;
728
0bf2c5e5
ZJS
729 log_info("/* %s */", __func__);
730
42b97781 731 assert_se(a = strv_new("foo", "bar", "three"));
7bd57a87
RC
732
733 assert_se(strv_push_prepend(&a, strdup("first")) >= 0);
734 assert_se(streq(a[0], "first"));
735 assert_se(streq(a[1], "foo"));
736 assert_se(streq(a[2], "bar"));
737 assert_se(streq(a[3], "three"));
738 assert_se(!a[4]);
739
740 assert_se(strv_consume_prepend(&a, strdup("first2")) >= 0);
741 assert_se(streq(a[0], "first2"));
742 assert_se(streq(a[1], "first"));
743 assert_se(streq(a[2], "foo"));
744 assert_se(streq(a[3], "bar"));
745 assert_se(streq(a[4], "three"));
746 assert_se(!a[5]);
747}
748
98940a3c
LP
749static void test_strv_push(void) {
750 _cleanup_strv_free_ char **a = NULL;
751 char *i, *j;
752
0bf2c5e5
ZJS
753 log_info("/* %s */", __func__);
754
98940a3c
LP
755 assert_se(i = strdup("foo"));
756 assert_se(strv_push(&a, i) >= 0);
757
758 assert_se(i = strdup("a"));
759 assert_se(j = strdup("b"));
760 assert_se(strv_push_pair(&a, i, j) >= 0);
761
762 assert_se(streq_ptr(a[0], "foo"));
763 assert_se(streq_ptr(a[1], "a"));
764 assert_se(streq_ptr(a[2], "b"));
765 assert_se(streq_ptr(a[3], NULL));
766}
767
8b75798d 768static void test_strv_compare(void) {
e74aa253
RC
769 _cleanup_strv_free_ char **a = NULL;
770 _cleanup_strv_free_ char **b = NULL;
771 _cleanup_strv_free_ char **c = NULL;
8b75798d 772 _cleanup_strv_free_ char **d = NULL;
e74aa253 773
0bf2c5e5
ZJS
774 log_info("/* %s */", __func__);
775
bea1a013 776 a = strv_new("one", "two", "three");
e74aa253 777 assert_se(a);
bea1a013 778 b = strv_new("one", "two", "three");
8b75798d 779 assert_se(b);
bea1a013 780 c = strv_new("one", "two", "three", "four");
8b75798d
YW
781 assert_se(c);
782 d = strv_new(NULL);
783 assert_se(d);
e74aa253 784
8b75798d
YW
785 assert_se(strv_compare(a, a) == 0);
786 assert_se(strv_compare(a, b) == 0);
787 assert_se(strv_compare(d, d) == 0);
788 assert_se(strv_compare(d, NULL) == 0);
789 assert_se(strv_compare(NULL, NULL) == 0);
e74aa253 790
8b75798d
YW
791 assert_se(strv_compare(a, c) < 0);
792 assert_se(strv_compare(b, c) < 0);
793 assert_se(strv_compare(b, d) == 1);
794 assert_se(strv_compare(b, NULL) == 1);
e74aa253
RC
795}
796
e1dd6790
LP
797static void test_strv_is_uniq(void) {
798 _cleanup_strv_free_ char **a = NULL, **b = NULL, **c = NULL, **d = NULL;
799
0bf2c5e5
ZJS
800 log_info("/* %s */", __func__);
801
bea1a013 802 a = strv_new(NULL);
e1dd6790
LP
803 assert_se(a);
804 assert_se(strv_is_uniq(a));
805
bea1a013 806 b = strv_new("foo");
e1dd6790
LP
807 assert_se(b);
808 assert_se(strv_is_uniq(b));
809
bea1a013 810 c = strv_new("foo", "bar");
e1dd6790
LP
811 assert_se(c);
812 assert_se(strv_is_uniq(c));
813
bea1a013 814 d = strv_new("foo", "bar", "waldo", "bar", "piep");
e1dd6790
LP
815 assert_se(d);
816 assert_se(!strv_is_uniq(d));
817}
818
819static void test_strv_reverse(void) {
820 _cleanup_strv_free_ char **a = NULL, **b = NULL, **c = NULL, **d = NULL;
821
0bf2c5e5
ZJS
822 log_info("/* %s */", __func__);
823
bea1a013 824 a = strv_new(NULL);
e1dd6790
LP
825 assert_se(a);
826
827 strv_reverse(a);
828 assert_se(strv_isempty(a));
829
bea1a013 830 b = strv_new("foo");
e1dd6790
LP
831 assert_se(b);
832 strv_reverse(b);
833 assert_se(streq_ptr(b[0], "foo"));
834 assert_se(streq_ptr(b[1], NULL));
835
bea1a013 836 c = strv_new("foo", "bar");
e1dd6790
LP
837 assert_se(c);
838 strv_reverse(c);
839 assert_se(streq_ptr(c[0], "bar"));
840 assert_se(streq_ptr(c[1], "foo"));
841 assert_se(streq_ptr(c[2], NULL));
842
bea1a013 843 d = strv_new("foo", "bar", "waldo");
e1dd6790
LP
844 assert_se(d);
845 strv_reverse(d);
846 assert_se(streq_ptr(d[0], "waldo"));
847 assert_se(streq_ptr(d[1], "bar"));
848 assert_se(streq_ptr(d[2], "foo"));
849 assert_se(streq_ptr(d[3], NULL));
850}
851
04c14b25
RM
852static void test_strv_shell_escape(void) {
853 _cleanup_strv_free_ char **v = NULL;
854
0bf2c5e5
ZJS
855 log_info("/* %s */", __func__);
856
bea1a013 857 v = strv_new("foo:bar", "bar,baz", "wal\\do");
04c14b25
RM
858 assert_se(v);
859 assert_se(strv_shell_escape(v, ",:"));
860 assert_se(streq_ptr(v[0], "foo\\:bar"));
861 assert_se(streq_ptr(v[1], "bar\\,baz"));
862 assert_se(streq_ptr(v[2], "wal\\\\do"));
863 assert_se(streq_ptr(v[3], NULL));
864}
865
e3ead6bb
LP
866static void test_strv_skip_one(char **a, size_t n, char **b) {
867 a = strv_skip(a, n);
868 assert_se(strv_equal(a, b));
869}
870
871static void test_strv_skip(void) {
0bf2c5e5
ZJS
872 log_info("/* %s */", __func__);
873
e3ead6bb
LP
874 test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 0, STRV_MAKE("foo", "bar", "baz"));
875 test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 1, STRV_MAKE("bar", "baz"));
876 test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 2, STRV_MAKE("baz"));
877 test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 3, STRV_MAKE(NULL));
878 test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 4, STRV_MAKE(NULL));
879 test_strv_skip_one(STRV_MAKE("foo", "bar", "baz"), 55, STRV_MAKE(NULL));
880
881 test_strv_skip_one(STRV_MAKE("quux"), 0, STRV_MAKE("quux"));
882 test_strv_skip_one(STRV_MAKE("quux"), 1, STRV_MAKE(NULL));
883 test_strv_skip_one(STRV_MAKE("quux"), 55, STRV_MAKE(NULL));
884
885 test_strv_skip_one(STRV_MAKE(NULL), 0, STRV_MAKE(NULL));
886 test_strv_skip_one(STRV_MAKE(NULL), 1, STRV_MAKE(NULL));
887 test_strv_skip_one(STRV_MAKE(NULL), 55, STRV_MAKE(NULL));
888}
889
8dd4c05b
LP
890static void test_strv_extend_n(void) {
891 _cleanup_strv_free_ char **v = NULL;
892
0bf2c5e5
ZJS
893 log_info("/* %s */", __func__);
894
bea1a013 895 v = strv_new("foo", "bar");
8dd4c05b
LP
896 assert_se(v);
897
898 assert_se(strv_extend_n(&v, "waldo", 3) >= 0);
899 assert_se(strv_extend_n(&v, "piep", 2) >= 0);
900
901 assert_se(streq(v[0], "foo"));
902 assert_se(streq(v[1], "bar"));
903 assert_se(streq(v[2], "waldo"));
904 assert_se(streq(v[3], "waldo"));
905 assert_se(streq(v[4], "waldo"));
906 assert_se(streq(v[5], "piep"));
907 assert_se(streq(v[6], "piep"));
908 assert_se(v[7] == NULL);
909
910 v = strv_free(v);
911
912 assert_se(strv_extend_n(&v, "foo", 1) >= 0);
913 assert_se(strv_extend_n(&v, "bar", 0) >= 0);
914
915 assert_se(streq(v[0], "foo"));
916 assert_se(v[1] == NULL);
917}
918
e287086b
LP
919static void test_strv_make_nulstr_one(char **l) {
920 _cleanup_free_ char *b = NULL, *c = NULL;
921 _cleanup_strv_free_ char **q = NULL;
f41794d0 922 const char *s = NULL;
e287086b 923 size_t n, m;
f41794d0 924 unsigned i = 0;
e287086b 925
0bf2c5e5
ZJS
926 log_info("/* %s */", __func__);
927
e287086b
LP
928 assert_se(strv_make_nulstr(l, &b, &n) >= 0);
929 assert_se(q = strv_parse_nulstr(b, n));
930 assert_se(strv_equal(l, q));
931
932 assert_se(strv_make_nulstr(q, &c, &m) >= 0);
933 assert_se(m == n);
934 assert_se(memcmp(b, c, m) == 0);
f41794d0 935
b60df13b 936 NULSTR_FOREACH(s, b)
f41794d0 937 assert_se(streq(s, l[i++]));
f41794d0 938 assert_se(i == strv_length(l));
e287086b
LP
939}
940
941static void test_strv_make_nulstr(void) {
0bf2c5e5
ZJS
942 log_info("/* %s */", __func__);
943
e287086b
LP
944 test_strv_make_nulstr_one(NULL);
945 test_strv_make_nulstr_one(STRV_MAKE(NULL));
946 test_strv_make_nulstr_one(STRV_MAKE("foo"));
947 test_strv_make_nulstr_one(STRV_MAKE("foo", "bar"));
948 test_strv_make_nulstr_one(STRV_MAKE("foo", "bar", "quuux"));
949}
950
bff8f950
ZJS
951static void test_strv_free_free(void) {
952 char ***t;
953
0bf2c5e5
ZJS
954 log_info("/* %s */", __func__);
955
bff8f950 956 assert_se(t = new(char**, 3));
bea1a013
LP
957 assert_se(t[0] = strv_new("a", "b"));
958 assert_se(t[1] = strv_new("c", "d", "e"));
bff8f950
ZJS
959 t[2] = NULL;
960
961 t = strv_free_free(t);
962}
963
ebde5cb2
RC
964static void test_foreach_string(void) {
965 const char * const t[] = {
966 "foo",
967 "bar",
968 "waldo",
969 NULL
970 };
971 const char *x;
972 unsigned i = 0;
973
0bf2c5e5
ZJS
974 log_info("/* %s */", __func__);
975
ebde5cb2
RC
976 FOREACH_STRING(x, "foo", "bar", "waldo")
977 assert_se(streq_ptr(t[i++], x));
978
979 assert_se(i == 3);
980
981 FOREACH_STRING(x, "zzz")
982 assert_se(streq(x, "zzz"));
983}
984
2027927b 985static void test_strv_fnmatch(void) {
57681e84 986 _cleanup_strv_free_ char **v = NULL;
0ef84b80 987 size_t pos;
2027927b 988
0bf2c5e5
ZJS
989 log_info("/* %s */", __func__);
990
191a3f16 991 assert_se(!strv_fnmatch(STRV_MAKE_EMPTY, "a"));
2027927b 992
0ef84b80
ZJS
993 v = strv_new("xxx", "*\\*", "yyy");
994 assert_se(!strv_fnmatch_full(v, "\\", 0, NULL));
995 assert_se(strv_fnmatch_full(v, "\\", FNM_NOESCAPE, &pos));
996 assert(pos == 1);
2027927b
EV
997}
998
3a7719d3 999int main(int argc, char *argv[]) {
3a7719d3 1000 test_specifier_printf();
c7bf9d51
ZJS
1001 test_str_in_set();
1002 test_strptr_in_set();
52f15520 1003 test_startswith_set();
02f19706
DB
1004 test_strv_foreach();
1005 test_strv_foreach_backwards();
4c325b2e 1006 test_strv_foreach_pair();
539ad707
TA
1007 test_strv_find();
1008 test_strv_find_prefix();
7bd57a87 1009 test_strv_find_startswith();
682cfdff 1010 test_strv_join();
d4d9f034 1011 test_strv_join_full();
a6fde353 1012
30bcc052
ZJS
1013 test_strv_unquote(" foo=bar \"waldo\" zzz ", STRV_MAKE("foo=bar", "waldo", "zzz"));
1014 test_strv_unquote("", STRV_MAKE_EMPTY);
1015 test_strv_unquote(" ", STRV_MAKE_EMPTY);
1016 test_strv_unquote(" ", STRV_MAKE_EMPTY);
1017 test_strv_unquote(" x", STRV_MAKE("x"));
1018 test_strv_unquote("x ", STRV_MAKE("x"));
1019 test_strv_unquote(" x ", STRV_MAKE("x"));
1020 test_strv_unquote(" \"x\" ", STRV_MAKE("x"));
1021 test_strv_unquote(" 'x' ", STRV_MAKE("x"));
1022 test_strv_unquote(" 'x\"' ", STRV_MAKE("x\""));
1023 test_strv_unquote(" \"x'\" ", STRV_MAKE("x'"));
1024 test_strv_unquote("a '--b=c \"d e\"'", STRV_MAKE("a", "--b=c \"d e\""));
73381fcf 1025
ba774317
ZJS
1026 /* trailing backslashes */
1027 test_strv_unquote(" x\\\\", STRV_MAKE("x\\"));
1028 test_invalid_unquote(" x\\");
1029
f88e6be5
LP
1030 test_invalid_unquote("a --b='c \"d e\"''");
1031 test_invalid_unquote("a --b='c \"d e\" '\"");
a2a5291b 1032 test_invalid_unquote("a --b='c \"d e\"garbage");
b2fadec6
ZJS
1033 test_invalid_unquote("'");
1034 test_invalid_unquote("\"");
f88e6be5 1035 test_invalid_unquote("'x'y'g");
70f75a52 1036
aed2ebfe 1037 test_strv_split();
0745ce75 1038 test_strv_split_empty();
90e30d76 1039 test_strv_split_full();
a082edd5 1040 test_strv_split_colon_pairs();
aed2ebfe 1041 test_strv_split_newlines();
2f213f74 1042 test_strv_split_nulstr();
10ddd913 1043 test_strv_parse_nulstr();
539ad707
TA
1044 test_strv_overlap();
1045 test_strv_sort();
e3e45d4f
SP
1046 test_strv_extend_strv();
1047 test_strv_extend_strv_concat();
1048 test_strv_extend();
4a336a69 1049 test_strv_extendf();
250a918d 1050 test_strv_from_stdarg_alloca();
6e888894 1051 test_strv_insert();
7bd57a87 1052 test_strv_push_prepend();
98940a3c 1053 test_strv_push();
8b75798d 1054 test_strv_compare();
e1dd6790
LP
1055 test_strv_is_uniq();
1056 test_strv_reverse();
04c14b25 1057 test_strv_shell_escape();
e3ead6bb 1058 test_strv_skip();
8dd4c05b 1059 test_strv_extend_n();
e287086b 1060 test_strv_make_nulstr();
bff8f950 1061 test_strv_free_free();
2c4b304e 1062
ebde5cb2 1063 test_foreach_string();
2027927b 1064 test_strv_fnmatch();
ebde5cb2 1065
f90cf44c
LP
1066 return 0;
1067}