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