1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2015 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 #include "alloc-util.h"
23 #include "string-util.h"
26 static void test_string_erase(void) {
30 assert_se(streq(string_erase(x), ""));
33 assert_se(streq(string_erase(x), ""));
35 x = strdupa("123456789");
36 assert_se(streq(string_erase(x), ""));
38 assert_se(x[1] == '\0');
39 assert_se(x[2] == '\0');
40 assert_se(x[3] == '\0');
41 assert_se(x[4] == '\0');
42 assert_se(x[5] == '\0');
43 assert_se(x[6] == '\0');
44 assert_se(x[7] == '\0');
45 assert_se(x[8] == '\0');
46 assert_se(x[9] == '\0');
49 #if 0 /// UNNEEDED by elogind
50 static void test_ascii_strcasecmp_n(void) {
52 assert_se(ascii_strcasecmp_n("", "", 0) == 0);
53 assert_se(ascii_strcasecmp_n("", "", 1) == 0);
54 assert_se(ascii_strcasecmp_n("", "a", 1) < 0);
55 assert_se(ascii_strcasecmp_n("", "a", 2) < 0);
56 assert_se(ascii_strcasecmp_n("a", "", 1) > 0);
57 assert_se(ascii_strcasecmp_n("a", "", 2) > 0);
58 assert_se(ascii_strcasecmp_n("a", "a", 1) == 0);
59 assert_se(ascii_strcasecmp_n("a", "a", 2) == 0);
60 assert_se(ascii_strcasecmp_n("a", "b", 1) < 0);
61 assert_se(ascii_strcasecmp_n("a", "b", 2) < 0);
62 assert_se(ascii_strcasecmp_n("b", "a", 1) > 0);
63 assert_se(ascii_strcasecmp_n("b", "a", 2) > 0);
64 assert_se(ascii_strcasecmp_n("xxxxyxxxx", "xxxxYxxxx", 9) == 0);
65 assert_se(ascii_strcasecmp_n("xxxxxxxxx", "xxxxyxxxx", 9) < 0);
66 assert_se(ascii_strcasecmp_n("xxxxXxxxx", "xxxxyxxxx", 9) < 0);
67 assert_se(ascii_strcasecmp_n("xxxxxxxxx", "xxxxYxxxx", 9) < 0);
68 assert_se(ascii_strcasecmp_n("xxxxXxxxx", "xxxxYxxxx", 9) < 0);
70 assert_se(ascii_strcasecmp_n("xxxxYxxxx", "xxxxYxxxx", 9) == 0);
71 assert_se(ascii_strcasecmp_n("xxxxyxxxx", "xxxxxxxxx", 9) > 0);
72 assert_se(ascii_strcasecmp_n("xxxxyxxxx", "xxxxXxxxx", 9) > 0);
73 assert_se(ascii_strcasecmp_n("xxxxYxxxx", "xxxxxxxxx", 9) > 0);
74 assert_se(ascii_strcasecmp_n("xxxxYxxxx", "xxxxXxxxx", 9) > 0);
77 static void test_ascii_strcasecmp_nn(void) {
78 assert_se(ascii_strcasecmp_nn("", 0, "", 0) == 0);
79 assert_se(ascii_strcasecmp_nn("", 0, "", 1) < 0);
80 assert_se(ascii_strcasecmp_nn("", 1, "", 0) > 0);
81 assert_se(ascii_strcasecmp_nn("", 1, "", 1) == 0);
83 assert_se(ascii_strcasecmp_nn("aaaa", 4, "aaAa", 4) == 0);
84 assert_se(ascii_strcasecmp_nn("aaa", 3, "aaAa", 4) < 0);
85 assert_se(ascii_strcasecmp_nn("aaa", 4, "aaAa", 4) < 0);
86 assert_se(ascii_strcasecmp_nn("aaaa", 4, "aaA", 3) > 0);
87 assert_se(ascii_strcasecmp_nn("aaaa", 4, "AAA", 4) > 0);
89 assert_se(ascii_strcasecmp_nn("aaaa", 4, "bbbb", 4) < 0);
90 assert_se(ascii_strcasecmp_nn("aaAA", 4, "BBbb", 4) < 0);
91 assert_se(ascii_strcasecmp_nn("BBbb", 4, "aaaa", 4) > 0);
95 static void test_streq_ptr(void) {
96 assert_se(streq_ptr(NULL, NULL));
97 assert_se(!streq_ptr("abc", "cdef"));
100 static void test_strstrip(void) {
102 char input[] = " hello, waldo. ";
105 assert_se(streq(r, "hello, waldo."));
108 static void test_strextend(void) {
109 _cleanup_free_ char *str = NULL;
111 assert_se(strextend(&str, NULL));
112 assert_se(streq_ptr(str, ""));
113 assert_se(strextend(&str, "", "0", "", "", "123", NULL));
114 assert_se(streq_ptr(str, "0123"));
115 assert_se(strextend(&str, "456", "78", "9", NULL));
116 assert_se(streq_ptr(str, "0123456789"));
119 static void test_strextend_with_separator(void) {
120 _cleanup_free_ char *str = NULL;
122 assert_se(strextend_with_separator(&str, NULL, NULL));
123 assert_se(streq_ptr(str, ""));
126 assert_se(strextend_with_separator(&str, "...", NULL));
127 assert_se(streq_ptr(str, ""));
128 assert_se(strextend_with_separator(&str, "...", NULL));
129 assert_se(streq_ptr(str, ""));
132 assert_se(strextend_with_separator(&str, "xyz", "a", "bb", "ccc", NULL));
133 assert_se(streq_ptr(str, "axyzbbxyzccc"));
136 assert_se(strextend_with_separator(&str, ",", "start", "", "1", "234", NULL));
137 assert_se(streq_ptr(str, "start,,1,234"));
138 assert_se(strextend_with_separator(&str, ";", "more", "5", "678", NULL));
139 assert_se(streq_ptr(str, "start,,1,234;more;5;678"));
142 static void test_strrep(void) {
143 _cleanup_free_ char *one, *three, *zero;
144 one = strrep("waldo", 1);
145 three = strrep("waldo", 3);
146 zero = strrep("waldo", 0);
148 assert_se(streq(one, "waldo"));
149 assert_se(streq(three, "waldowaldowaldo"));
150 assert_se(streq(zero, ""));
154 static void test_strappend(void) {
155 _cleanup_free_ char *t1, *t2, *t3, *t4;
157 t1 = strappend(NULL, NULL);
158 assert_se(streq(t1, ""));
160 t2 = strappend(NULL, "suf");
161 assert_se(streq(t2, "suf"));
163 t3 = strappend("pre", NULL);
164 assert_se(streq(t3, "pre"));
166 t4 = strappend("pre", "suf");
167 assert_se(streq(t4, "presuf"));
170 static void test_string_has_cc(void) {
171 assert_se(string_has_cc("abc\1", NULL));
172 assert_se(string_has_cc("abc\x7f", NULL));
173 assert_se(string_has_cc("abc\x7f", NULL));
174 assert_se(string_has_cc("abc\t\x7f", "\t"));
175 assert_se(string_has_cc("abc\t\x7f", "\t"));
176 assert_se(string_has_cc("\x7f", "\t"));
177 assert_se(string_has_cc("\x7f", "\t\a"));
179 assert_se(!string_has_cc("abc\t\t", "\t"));
180 assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
181 assert_se(!string_has_cc("a\ab\tc", "\t\a"));
184 #if 0 /// UNNEEDED by elogind
185 static void test_ascii_strlower(void) {
186 char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
187 assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
191 static void test_strshorten(void) {
194 assert_se(strlen(strshorten(s, 6)) == 6);
195 assert_se(strlen(strshorten(s, 12)) == 6);
196 assert_se(strlen(strshorten(s, 2)) == 2);
197 assert_se(strlen(strshorten(s, 0)) == 0);
200 static void test_strjoina(void) {
203 actual = strjoina("", "foo", "bar");
204 assert_se(streq(actual, "foobar"));
206 actual = strjoina("foo", "bar", "baz");
207 assert_se(streq(actual, "foobarbaz"));
209 actual = strjoina("foo", "", "bar", "baz");
210 assert_se(streq(actual, "foobarbaz"));
212 actual = strjoina("foo");
213 assert_se(streq(actual, "foo"));
215 actual = strjoina(NULL);
216 assert_se(streq(actual, ""));
218 actual = strjoina(NULL, "foo");
219 assert_se(streq(actual, ""));
221 actual = strjoina("foo", NULL, "bar");
222 assert_se(streq(actual, "foo"));
225 static void test_strcmp_ptr(void) {
226 assert_se(strcmp_ptr(NULL, NULL) == 0);
227 assert_se(strcmp_ptr("", NULL) > 0);
228 assert_se(strcmp_ptr("foo", NULL) > 0);
229 assert_se(strcmp_ptr(NULL, "") < 0);
230 assert_se(strcmp_ptr(NULL, "bar") < 0);
231 assert_se(strcmp_ptr("foo", "bar") > 0);
232 assert_se(strcmp_ptr("bar", "baz") < 0);
233 assert_se(strcmp_ptr("foo", "foo") == 0);
234 assert_se(strcmp_ptr("", "") == 0);
237 static void test_foreach_word(void) {
238 const char *word, *state;
241 const char test[] = "test abc d\te f ";
242 const char * const expected[] = {
252 FOREACH_WORD(word, l, test, state)
253 assert_se(strneq(expected[i++], word, l));
256 static void check(const char *test, char** expected, bool trailing) {
259 printf("<<<%s>>>\n", test);
261 _cleanup_free_ char *word = NULL;
263 r = extract_first_word(&test, &word, NULL, EXTRACT_QUOTES);
265 assert_se(!trailing);
272 assert_se(streq(word, expected[i++]));
273 printf("<%s>\n", word);
275 assert_se(expected[i] == NULL);
278 static void test_foreach_word_quoted(void) {
279 check("test a b c 'd' e '' '' hhh '' '' \"a b c\"",
303 static void test_endswith(void) {
304 assert_se(endswith("foobar", "bar"));
305 assert_se(endswith("foobar", ""));
306 assert_se(endswith("foobar", "foobar"));
307 assert_se(endswith("", ""));
309 assert_se(!endswith("foobar", "foo"));
310 assert_se(!endswith("foobar", "foobarfoofoo"));
313 static void test_endswith_no_case(void) {
314 assert_se(endswith_no_case("fooBAR", "bar"));
315 assert_se(endswith_no_case("foobar", ""));
316 assert_se(endswith_no_case("foobar", "FOOBAR"));
317 assert_se(endswith_no_case("", ""));
319 assert_se(!endswith_no_case("foobar", "FOO"));
320 assert_se(!endswith_no_case("foobar", "FOOBARFOOFOO"));
323 #if 0 /// UNNEEDED by elogind
324 static void test_delete_chars(void) {
325 char *s, input[] = " hello, waldo. abc";
327 s = delete_chars(input, WHITESPACE);
328 assert_se(streq(s, "hello,waldo.abc"));
329 assert_se(s == input);
333 static void test_delete_trailing_chars(void) {
336 input1[] = " \n \r k \n \r ",
337 input2[] = "kkkkthiskkkiskkkaktestkkk",
340 s = delete_trailing_chars(input1, WHITESPACE);
341 assert_se(streq(s, " \n \r k"));
342 assert_se(s == input1);
344 s = delete_trailing_chars(input2, "kt");
345 assert_se(streq(s, "kkkkthiskkkiskkkaktes"));
346 assert_se(s == input2);
348 s = delete_trailing_chars(input3, WHITESPACE);
349 assert_se(streq(s, "abcdef"));
350 assert_se(s == input3);
352 s = delete_trailing_chars(input3, "fe");
353 assert_se(streq(s, "abcd"));
354 assert_se(s == input3);
357 static void test_delete_trailing_slashes(void) {
358 char s1[] = "foobar//",
363 assert_se(streq(delete_trailing_chars(s1, "_"), "foobar//"));
364 assert_se(streq(delete_trailing_chars(s1, "/"), "foobar"));
365 assert_se(streq(delete_trailing_chars(s2, "/"), "foobar"));
366 assert_se(streq(delete_trailing_chars(s3, "/"), "foobar"));
367 assert_se(streq(delete_trailing_chars(s4, "/"), ""));
370 #if 0 /// UNNEEDED by elogind
371 static void test_skip_leading_chars(void) {
372 char input1[] = " \n \r k \n \r ",
373 input2[] = "kkkkthiskkkiskkkaktestkkk",
376 assert_se(streq(skip_leading_chars(input1, WHITESPACE), "k \n \r "));
377 assert_se(streq(skip_leading_chars(input2, "k"), "thiskkkiskkkaktestkkk"));
378 assert_se(streq(skip_leading_chars(input2, "tk"), "hiskkkiskkkaktestkkk"));
379 assert_se(streq(skip_leading_chars(input3, WHITESPACE), "abcdef"));
380 assert_se(streq(skip_leading_chars(input3, "bcaef"), "def"));
384 static void test_in_charset(void) {
385 assert_se(in_charset("dddaaabbbcccc", "abcd"));
386 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
389 static void test_split_pair(void) {
390 _cleanup_free_ char *a = NULL, *b = NULL;
392 assert_se(split_pair("", "", &a, &b) == -EINVAL);
393 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
394 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
395 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
396 assert_se(streq(a, "foo"));
397 assert_se(streq(b, "bar"));
400 assert_se(split_pair("==", "==", &a, &b) >= 0);
401 assert_se(streq(a, ""));
402 assert_se(streq(b, ""));
406 assert_se(split_pair("===", "==", &a, &b) >= 0);
407 assert_se(streq(a, ""));
408 assert_se(streq(b, "="));
411 static void test_first_word(void) {
412 assert_se(first_word("Hello", ""));
413 assert_se(first_word("Hello", "Hello"));
414 assert_se(first_word("Hello world", "Hello"));
415 assert_se(first_word("Hello\tworld", "Hello"));
416 assert_se(first_word("Hello\nworld", "Hello"));
417 assert_se(first_word("Hello\rworld", "Hello"));
418 assert_se(first_word("Hello ", "Hello"));
420 assert_se(!first_word("Hello", "Hellooo"));
421 assert_se(!first_word("Hello", "xxxxx"));
422 assert_se(!first_word("Hellooo", "Hello"));
425 static void test_strlen_ptr(void) {
426 assert_se(strlen_ptr("foo") == 3);
427 assert_se(strlen_ptr("") == 0);
428 assert_se(strlen_ptr(NULL) == 0);
431 int main(int argc, char *argv[]) {
433 #if 0 /// UNNEEDED by elogind
434 test_ascii_strcasecmp_n();
435 test_ascii_strcasecmp_nn();
440 test_strextend_with_separator();
443 test_string_has_cc();
444 #if 0 /// UNNEEDED by elogind
445 test_ascii_strlower();
451 test_foreach_word_quoted();
453 test_endswith_no_case();
454 #if 0 /// UNNEEDED by elogind
457 test_delete_trailing_chars();
458 test_delete_trailing_slashes();
459 #if 0 /// UNNEEDED by elogind
460 test_skip_leading_chars();