]>
Commit | Line | Data |
---|---|---|
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 | 10 | static 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 | 50 | static 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 | ||
59 | static 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 | 73 | static 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 |
89 | static const char* const input_table_multiple[] = { |
90 | "one", | |
91 | "two", | |
92 | "three", | |
93 | NULL, | |
94 | }; | |
95 | ||
1f938af8 YW |
96 | static const char* const input_table_quoted[] = { |
97 | "one", | |
98 | " two\t three ", | |
99 | " four five", | |
100 | NULL, | |
101 | }; | |
102 | ||
0645b83a ZJS |
103 | static const char* const input_table_quoted_joined[] = { |
104 | "one", | |
105 | " two\t three " " four five", | |
106 | NULL, | |
107 | }; | |
108 | ||
a6fde353 ZJS |
109 | static const char* const input_table_one[] = { |
110 | "one", | |
111 | NULL, | |
112 | }; | |
113 | ||
114 | static const char* const input_table_none[] = { | |
115 | NULL, | |
116 | }; | |
117 | ||
afe773b0 ZJS |
118 | static const char* const input_table_two_empties[] = { |
119 | "", | |
120 | "", | |
121 | NULL, | |
122 | }; | |
123 | ||
124 | static const char* const input_table_one_empty[] = { | |
125 | "", | |
126 | NULL, | |
127 | }; | |
128 | ||
a6fde353 | 129 | static 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 | ||
136 | static 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 |
146 | static 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 | 164 | static 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 | 200 | static 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 | 245 | static 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 | 267 | static 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 | 278 | static 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 | ||
339 | static 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 | 403 | static 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 |
420 | static 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 |
449 | static 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 |
464 | static 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 |
479 | static 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 |
499 | static 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 | ||
523 | static 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 | 544 | static 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 | 562 | static 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 |
590 | static 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 |
606 | static 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 | 622 | static 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 | ||
636 | static 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 |
657 | static 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 | 670 | static 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 | ||
686 | static 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 |
694 | static 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 |
726 | static 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 |
749 | static 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 | 768 | static 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 |
797 | static 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 | ||
819 | static 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 |
852 | static 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 |
866 | static 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 | ||
871 | static 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 |
890 | static 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 |
919 | static 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 | ||
941 | static 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 |
951 | static 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 |
964 | static 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 | 985 | static 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 | 999 | int 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 | } |