1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 Copyright © 2013 Thomas H.P. Andersen
10 #include "extract-word.h"
12 #include "string-util.h"
14 static void test_extract_first_word(void) {
15 const char *p, *original;
18 p = original = "foobar waldo";
19 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
20 assert_se(streq(t, "foobar"));
22 assert_se(p == original + 7);
24 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
25 assert_se(streq(t, "waldo"));
27 assert_se(isempty(p));
29 assert_se(extract_first_word(&p, &t, NULL, 0) == 0);
31 assert_se(isempty(p));
33 p = original = "\"foobar\" \'waldo\'";
34 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
35 assert_se(streq(t, "\"foobar\""));
37 assert_se(p == original + 9);
39 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
40 assert_se(streq(t, "\'waldo\'"));
42 assert_se(isempty(p));
44 assert_se(extract_first_word(&p, &t, NULL, 0) == 0);
46 assert_se(isempty(p));
48 p = original = "\"foobar\" \'waldo\'";
49 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
50 assert_se(streq(t, "foobar"));
52 assert_se(p == original + 9);
54 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
55 assert_se(streq(t, "waldo"));
57 assert_se(isempty(p));
59 assert_se(extract_first_word(&p, &t, NULL, 0) == 0);
61 assert_se(isempty(p));
64 assert_se(extract_first_word(&p, &t, NULL, 0) == 1);
65 assert_se(streq(t, "\""));
67 assert_se(isempty(p));
70 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) == -EINVAL);
71 assert_se(p == original + 1);
74 assert_se(extract_first_word(&p, &t, NULL, 0) == 1);
75 assert_se(streq(t, "\'"));
77 assert_se(isempty(p));
80 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) == -EINVAL);
81 assert_se(p == original + 1);
83 p = original = "\'fooo";
84 assert_se(extract_first_word(&p, &t, NULL, 0) == 1);
85 assert_se(streq(t, "\'fooo"));
87 assert_se(isempty(p));
89 p = original = "\'fooo";
90 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) == -EINVAL);
91 assert_se(p == original + 5);
93 p = original = "\'fooo";
94 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX) > 0);
95 assert_se(streq(t, "fooo"));
97 assert_se(isempty(p));
99 p = original = "\"fooo";
100 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX) > 0);
101 assert_se(streq(t, "fooo"));
103 assert_se(isempty(p));
105 p = original = "yay\'foo\'bar";
106 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
107 assert_se(streq(t, "yay\'foo\'bar"));
109 assert_se(isempty(p));
111 p = original = "yay\'foo\'bar";
112 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
113 assert_se(streq(t, "yayfoobar"));
115 assert_se(isempty(p));
117 p = original = " foobar ";
118 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
119 assert_se(streq(t, "foobar"));
121 assert_se(isempty(p));
123 p = original = " foo\\ba\\x6ar ";
124 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) > 0);
125 assert_se(streq(t, "foo\ba\x6ar"));
127 assert_se(isempty(p));
129 p = original = " foo\\ba\\x6ar ";
130 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
131 assert_se(streq(t, "foobax6ar"));
133 assert_se(isempty(p));
135 p = original = " f\\u00f6o \"pi\\U0001F4A9le\" ";
136 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) > 0);
137 assert_se(streq(t, "föo"));
139 assert_se(p == original + 13);
141 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE) > 0);
142 assert_se(streq(t, "pi\360\237\222\251le"));
144 assert_se(isempty(p));
146 p = original = "fooo\\";
147 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RELAX) > 0);
148 assert_se(streq(t, "fooo"));
150 assert_se(isempty(p));
152 p = original = "fooo\\";
153 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX) > 0);
154 assert_se(streq(t, "fooo\\"));
156 assert_se(isempty(p));
158 p = original = "fooo\\";
159 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
160 assert_se(streq(t, "fooo\\"));
162 assert_se(isempty(p));
164 p = original = "fooo\\";
165 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
166 assert_se(streq(t, "fooo\\"));
168 assert_se(isempty(p));
170 p = original = "\"foo\\";
171 assert_se(extract_first_word(&p, &t, NULL, 0) == -EINVAL);
172 assert_se(p == original + 5);
174 p = original = "\"foo\\";
175 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX) > 0);
176 assert_se(streq(t, "foo"));
178 assert_se(isempty(p));
180 p = original = "foo::bar";
181 assert_se(extract_first_word(&p, &t, ":", 0) == 1);
182 assert_se(streq(t, "foo"));
184 assert_se(p == original + 5);
186 assert_se(extract_first_word(&p, &t, ":", 0) == 1);
187 assert_se(streq(t, "bar"));
189 assert_se(isempty(p));
191 assert_se(extract_first_word(&p, &t, ":", 0) == 0);
193 assert_se(isempty(p));
195 p = original = "foo\\:bar::waldo";
196 assert_se(extract_first_word(&p, &t, ":", 0) == 1);
197 assert_se(streq(t, "foo:bar"));
199 assert_se(p == original + 10);
201 assert_se(extract_first_word(&p, &t, ":", 0) == 1);
202 assert_se(streq(t, "waldo"));
204 assert_se(isempty(p));
206 assert_se(extract_first_word(&p, &t, ":", 0) == 0);
208 assert_se(isempty(p));
210 p = original = "\"foo\\";
211 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE_RELAX) == -EINVAL);
212 assert_se(p == original + 5);
214 p = original = "\"foo\\";
215 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
216 assert_se(streq(t, "foo\\"));
218 assert_se(isempty(p));
220 p = original = "\"foo\\";
221 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
222 assert_se(streq(t, "foo\\"));
224 assert_se(isempty(p));
226 p = original = "fooo\\ bar quux";
227 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RELAX) > 0);
228 assert_se(streq(t, "fooo bar"));
230 assert_se(p == original + 10);
232 p = original = "fooo\\ bar quux";
233 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX) > 0);
234 assert_se(streq(t, "fooo bar"));
236 assert_se(p == original + 10);
238 p = original = "fooo\\ bar quux";
239 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE_RELAX|EXTRACT_RELAX) > 0);
240 assert_se(streq(t, "fooo bar"));
242 assert_se(p == original + 10);
244 p = original = "fooo\\ bar quux";
245 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) == -EINVAL);
246 assert_se(p == original + 5);
248 p = original = "fooo\\ bar quux";
249 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
250 assert_se(streq(t, "fooo\\ bar"));
252 assert_se(p == original + 10);
254 p = original = "\\w+@\\K[\\d.]+";
255 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE) == -EINVAL);
256 assert_se(p == original + 1);
258 p = original = "\\w+@\\K[\\d.]+";
259 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
260 assert_se(streq(t, "\\w+@\\K[\\d.]+"));
262 assert_se(isempty(p));
264 p = original = "\\w+\\b";
265 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_CUNESCAPE|EXTRACT_CUNESCAPE_RELAX) > 0);
266 assert_se(streq(t, "\\w+\b"));
268 assert_se(isempty(p));
270 p = original = "-N ''";
271 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
272 assert_se(streq(t, "-N"));
274 assert_se(p == original + 3);
276 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_QUOTES) > 0);
277 assert_se(streq(t, ""));
279 assert_se(isempty(p));
281 p = original = ":foo\\:bar::waldo:";
282 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
284 assert_se(streq(t, ""));
286 assert_se(p == original + 1);
288 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
289 assert_se(streq(t, "foo:bar"));
291 assert_se(p == original + 10);
293 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
295 assert_se(streq(t, ""));
297 assert_se(p == original + 11);
299 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
300 assert_se(streq(t, "waldo"));
302 assert_se(p == original + 17);
304 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 1);
305 assert_se(streq(t, ""));
307 assert_se(p == NULL);
309 assert_se(extract_first_word(&p, &t, ":", EXTRACT_DONT_COALESCE_SEPARATORS) == 0);
314 assert_se(extract_first_word(&p, &t, NULL, 0) > 0);
315 assert_se(streq(t, "fooxbar"));
317 assert_se(p == NULL);
320 assert_se(extract_first_word(&p, &t, NULL, EXTRACT_RETAIN_ESCAPE) > 0);
321 assert_se(streq(t, "foo\\xbar"));
323 assert_se(p == NULL);
326 #if 0 /// UNNEEDED by elogind
327 static void test_extract_first_word_and_warn(void) {
328 const char *p, *original;
331 p = original = "foobar waldo";
332 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
333 assert_se(streq(t, "foobar"));
335 assert_se(p == original + 7);
337 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
338 assert_se(streq(t, "waldo"));
340 assert_se(isempty(p));
342 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) == 0);
344 assert_se(isempty(p));
346 p = original = "\"foobar\" \'waldo\'";
347 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) > 0);
348 assert_se(streq(t, "foobar"));
350 assert_se(p == original + 9);
352 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) > 0);
353 assert_se(streq(t, "waldo"));
355 assert_se(isempty(p));
357 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) == 0);
359 assert_se(isempty(p));
362 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
363 assert_se(p == original + 1);
366 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
367 assert_se(p == original + 1);
369 p = original = "\'fooo";
370 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
371 assert_se(p == original + 5);
373 p = original = "\'fooo";
374 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
375 assert_se(streq(t, "fooo"));
377 assert_se(isempty(p));
379 p = original = " foo\\ba\\x6ar ";
380 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
381 assert_se(streq(t, "foo\ba\x6ar"));
383 assert_se(isempty(p));
385 p = original = " foo\\ba\\x6ar ";
386 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
387 assert_se(streq(t, "foobax6ar"));
389 assert_se(isempty(p));
391 p = original = " f\\u00f6o \"pi\\U0001F4A9le\" ";
392 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
393 assert_se(streq(t, "föo"));
395 assert_se(p == original + 13);
397 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
398 assert_se(streq(t, "pi\360\237\222\251le"));
400 assert_se(isempty(p));
402 p = original = "fooo\\";
403 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
404 assert_se(streq(t, "fooo"));
406 assert_se(isempty(p));
408 p = original = "fooo\\";
409 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
410 assert_se(streq(t, "fooo\\"));
412 assert_se(isempty(p));
414 p = original = "fooo\\";
415 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
416 assert_se(streq(t, "fooo\\"));
418 assert_se(isempty(p));
420 p = original = "\"foo\\";
421 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES, NULL, "fake", 1, original) == -EINVAL);
422 assert_se(p == original + 5);
424 p = original = "\"foo\\";
425 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
426 assert_se(streq(t, "foo"));
428 assert_se(isempty(p));
430 p = original = "\"foo\\";
431 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE, NULL, "fake", 1, original) == -EINVAL);
432 assert_se(p == original + 5);
434 p = original = "\"foo\\";
435 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE|EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
436 assert_se(streq(t, "foo"));
438 assert_se(isempty(p));
440 p = original = "fooo\\ bar quux";
441 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_RELAX, NULL, "fake", 1, original) > 0);
442 assert_se(streq(t, "fooo bar"));
444 assert_se(p == original + 10);
446 p = original = "fooo\\ bar quux";
447 assert_se(extract_first_word_and_warn(&p, &t, NULL, 0, NULL, "fake", 1, original) > 0);
448 assert_se(streq(t, "fooo bar"));
450 assert_se(p == original + 10);
452 p = original = "fooo\\ bar quux";
453 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
454 assert_se(streq(t, "fooo\\ bar"));
456 assert_se(p == original + 10);
458 p = original = "\\w+@\\K[\\d.]+";
459 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
460 assert_se(streq(t, "\\w+@\\K[\\d.]+"));
462 assert_se(isempty(p));
464 p = original = "\\w+\\b";
465 assert_se(extract_first_word_and_warn(&p, &t, NULL, EXTRACT_CUNESCAPE, NULL, "fake", 1, original) > 0);
466 assert_se(streq(t, "\\w+\b"));
468 assert_se(isempty(p));
471 static void test_extract_many_words(void) {
472 const char *p, *original;
475 p = original = "foobar waldi piep";
476 assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 3);
477 assert_se(isempty(p));
478 assert_se(streq_ptr(a, "foobar"));
479 assert_se(streq_ptr(b, "waldi"));
480 assert_se(streq_ptr(c, "piep"));
485 p = original = "'foobar' wa\"ld\"i ";
486 assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 2);
487 assert_se(isempty(p));
488 assert_se(streq_ptr(a, "'foobar'"));
489 assert_se(streq_ptr(b, "wa\"ld\"i"));
490 assert_se(streq_ptr(c, NULL));
494 p = original = "'foobar' wa\"ld\"i ";
495 assert_se(extract_many_words(&p, NULL, EXTRACT_QUOTES, &a, &b, &c, NULL) == 2);
496 assert_se(isempty(p));
497 assert_se(streq_ptr(a, "foobar"));
498 assert_se(streq_ptr(b, "waldi"));
499 assert_se(streq_ptr(c, NULL));
504 assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 0);
505 assert_se(isempty(p));
506 assert_se(streq_ptr(a, NULL));
507 assert_se(streq_ptr(b, NULL));
508 assert_se(streq_ptr(c, NULL));
511 assert_se(extract_many_words(&p, NULL, 0, &a, &b, &c, NULL) == 0);
512 assert_se(isempty(p));
513 assert_se(streq_ptr(a, NULL));
514 assert_se(streq_ptr(b, NULL));
515 assert_se(streq_ptr(c, NULL));
517 p = original = "foobar";
518 assert_se(extract_many_words(&p, NULL, 0, NULL) == 0);
519 assert_se(p == original);
521 p = original = "foobar waldi";
522 assert_se(extract_many_words(&p, NULL, 0, &a, NULL) == 1);
523 assert_se(p == original+7);
524 assert_se(streq_ptr(a, "foobar"));
527 p = original = " foobar ";
528 assert_se(extract_many_words(&p, NULL, 0, &a, NULL) == 1);
529 assert_se(isempty(p));
530 assert_se(streq_ptr(a, "foobar"));
535 int main(int argc, char *argv[]) {
536 log_parse_environment();
539 test_extract_first_word();
540 #if 0 /// UNNEEDED by elogind
541 test_extract_first_word_and_warn();
542 test_extract_many_words();