]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-string-util.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / test / test-string-util.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
9fe4ea21
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2015 Lennart Poettering
6
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.
11
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.
16
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/>.
19***/
20
6571a64e
RC
21#include "alloc-util.h"
22#include "macro.h"
9fe4ea21 23#include "string-util.h"
6571a64e 24#include "strv.h"
9fe4ea21
LP
25
26static void test_string_erase(void) {
27 char *x;
28
29 x = strdupa("");
30 assert_se(streq(string_erase(x), ""));
31
32 x = strdupa("1");
2d26d8e0 33 assert_se(streq(string_erase(x), ""));
9fe4ea21
LP
34
35 x = strdupa("123456789");
2d26d8e0
ZJS
36 assert_se(streq(string_erase(x), ""));
37
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');
9fe4ea21
LP
47}
48
522d85ae
LP
49static void test_ascii_strcasecmp_n(void) {
50
51 assert_se(ascii_strcasecmp_n("", "", 0) == 0);
52 assert_se(ascii_strcasecmp_n("", "", 1) == 0);
53 assert_se(ascii_strcasecmp_n("", "a", 1) < 0);
54 assert_se(ascii_strcasecmp_n("", "a", 2) < 0);
55 assert_se(ascii_strcasecmp_n("a", "", 1) > 0);
56 assert_se(ascii_strcasecmp_n("a", "", 2) > 0);
57 assert_se(ascii_strcasecmp_n("a", "a", 1) == 0);
58 assert_se(ascii_strcasecmp_n("a", "a", 2) == 0);
59 assert_se(ascii_strcasecmp_n("a", "b", 1) < 0);
60 assert_se(ascii_strcasecmp_n("a", "b", 2) < 0);
61 assert_se(ascii_strcasecmp_n("b", "a", 1) > 0);
62 assert_se(ascii_strcasecmp_n("b", "a", 2) > 0);
63 assert_se(ascii_strcasecmp_n("xxxxyxxxx", "xxxxYxxxx", 9) == 0);
64 assert_se(ascii_strcasecmp_n("xxxxxxxxx", "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
69 assert_se(ascii_strcasecmp_n("xxxxYxxxx", "xxxxYxxxx", 9) == 0);
70 assert_se(ascii_strcasecmp_n("xxxxyxxxx", "xxxxxxxxx", 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}
75
c1749834
LP
76static void test_ascii_strcasecmp_nn(void) {
77 assert_se(ascii_strcasecmp_nn("", 0, "", 0) == 0);
78 assert_se(ascii_strcasecmp_nn("", 0, "", 1) < 0);
79 assert_se(ascii_strcasecmp_nn("", 1, "", 0) > 0);
80 assert_se(ascii_strcasecmp_nn("", 1, "", 1) == 0);
81
82 assert_se(ascii_strcasecmp_nn("aaaa", 4, "aaAa", 4) == 0);
83 assert_se(ascii_strcasecmp_nn("aaa", 3, "aaAa", 4) < 0);
84 assert_se(ascii_strcasecmp_nn("aaa", 4, "aaAa", 4) < 0);
85 assert_se(ascii_strcasecmp_nn("aaaa", 4, "aaA", 3) > 0);
86 assert_se(ascii_strcasecmp_nn("aaaa", 4, "AAA", 4) > 0);
87
88 assert_se(ascii_strcasecmp_nn("aaaa", 4, "bbbb", 4) < 0);
89 assert_se(ascii_strcasecmp_nn("aaAA", 4, "BBbb", 4) < 0);
90 assert_se(ascii_strcasecmp_nn("BBbb", 4, "aaaa", 4) > 0);
91}
92
6571a64e
RC
93static void test_streq_ptr(void) {
94 assert_se(streq_ptr(NULL, NULL));
95 assert_se(!streq_ptr("abc", "cdef"));
96}
97
98static void test_strstrip(void) {
99 char *r;
100 char input[] = " hello, waldo. ";
101
102 r = strstrip(input);
103 assert_se(streq(r, "hello, waldo."));
104}
105
106static void test_strextend(void) {
107 _cleanup_free_ char *str = strdup("0123");
108 strextend(&str, "456", "78", "9", NULL);
109 assert_se(streq(str, "0123456789"));
110}
111
112static void test_strrep(void) {
113 _cleanup_free_ char *one, *three, *zero;
114 one = strrep("waldo", 1);
115 three = strrep("waldo", 3);
116 zero = strrep("waldo", 0);
117
118 assert_se(streq(one, "waldo"));
119 assert_se(streq(three, "waldowaldowaldo"));
120 assert_se(streq(zero, ""));
121}
122
123
124static void test_strappend(void) {
125 _cleanup_free_ char *t1, *t2, *t3, *t4;
126
127 t1 = strappend(NULL, NULL);
128 assert_se(streq(t1, ""));
129
130 t2 = strappend(NULL, "suf");
131 assert_se(streq(t2, "suf"));
132
133 t3 = strappend("pre", NULL);
134 assert_se(streq(t3, "pre"));
135
136 t4 = strappend("pre", "suf");
137 assert_se(streq(t4, "presuf"));
138}
139
140static void test_string_has_cc(void) {
141 assert_se(string_has_cc("abc\1", NULL));
142 assert_se(string_has_cc("abc\x7f", NULL));
143 assert_se(string_has_cc("abc\x7f", NULL));
144 assert_se(string_has_cc("abc\t\x7f", "\t"));
145 assert_se(string_has_cc("abc\t\x7f", "\t"));
146 assert_se(string_has_cc("\x7f", "\t"));
147 assert_se(string_has_cc("\x7f", "\t\a"));
148
149 assert_se(!string_has_cc("abc\t\t", "\t"));
150 assert_se(!string_has_cc("abc\t\t\a", "\t\a"));
151 assert_se(!string_has_cc("a\ab\tc", "\t\a"));
152}
153
154static void test_ascii_strlower(void) {
155 char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
156 assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
157}
158
159static void test_strshorten(void) {
160 char s[] = "foobar";
161
162 assert_se(strlen(strshorten(s, 6)) == 6);
163 assert_se(strlen(strshorten(s, 12)) == 6);
164 assert_se(strlen(strshorten(s, 2)) == 2);
165 assert_se(strlen(strshorten(s, 0)) == 0);
166}
167
168static void test_strjoina(void) {
169 char *actual;
170
171 actual = strjoina("", "foo", "bar");
172 assert_se(streq(actual, "foobar"));
173
174 actual = strjoina("foo", "bar", "baz");
175 assert_se(streq(actual, "foobarbaz"));
176
177 actual = strjoina("foo", "", "bar", "baz");
178 assert_se(streq(actual, "foobarbaz"));
179
180 actual = strjoina("foo");
181 assert_se(streq(actual, "foo"));
182
183 actual = strjoina(NULL);
184 assert_se(streq(actual, ""));
185
186 actual = strjoina(NULL, "foo");
187 assert_se(streq(actual, ""));
188
189 actual = strjoina("foo", NULL, "bar");
190 assert_se(streq(actual, "foo"));
191}
192
193static void test_strcmp_ptr(void) {
194 assert_se(strcmp_ptr(NULL, NULL) == 0);
195 assert_se(strcmp_ptr("", NULL) > 0);
196 assert_se(strcmp_ptr("foo", NULL) > 0);
197 assert_se(strcmp_ptr(NULL, "") < 0);
198 assert_se(strcmp_ptr(NULL, "bar") < 0);
199 assert_se(strcmp_ptr("foo", "bar") > 0);
200 assert_se(strcmp_ptr("bar", "baz") < 0);
201 assert_se(strcmp_ptr("foo", "foo") == 0);
202 assert_se(strcmp_ptr("", "") == 0);
203}
204
205static void test_foreach_word(void) {
206 const char *word, *state;
207 size_t l;
208 int i = 0;
209 const char test[] = "test abc d\te f ";
210 const char * const expected[] = {
211 "test",
212 "abc",
213 "d",
214 "e",
215 "f",
216 "",
217 NULL
218 };
219
220 FOREACH_WORD(word, l, test, state)
221 assert_se(strneq(expected[i++], word, l));
222}
223
224static void check(const char *test, char** expected, bool trailing) {
bc8ec170 225 int i = 0, r;
6571a64e
RC
226
227 printf("<<<%s>>>\n", test);
bc8ec170
ZJS
228 for (;;) {
229 _cleanup_free_ char *word = NULL;
230
231 r = extract_first_word(&test, &word, NULL, EXTRACT_QUOTES);
232 if (r == 0) {
233 assert_se(!trailing);
234 break;
235 } else if (r < 0) {
236 assert_se(trailing);
237 break;
238 }
239
240 assert_se(streq(word, expected[i++]));
241 printf("<%s>\n", word);
6571a64e 242 }
6571a64e 243 assert_se(expected[i] == NULL);
6571a64e
RC
244}
245
246static void test_foreach_word_quoted(void) {
247 check("test a b c 'd' e '' '' hhh '' '' \"a b c\"",
248 STRV_MAKE("test",
249 "a",
250 "b",
251 "c",
252 "d",
253 "e",
254 "",
255 "",
256 "hhh",
257 "",
258 "",
259 "a b c"),
260 false);
261
262 check("test \"xxx",
263 STRV_MAKE("test"),
264 true);
265
266 check("test\\",
267 STRV_MAKE_EMPTY,
268 true);
269}
270
271static void test_endswith(void) {
272 assert_se(endswith("foobar", "bar"));
273 assert_se(endswith("foobar", ""));
274 assert_se(endswith("foobar", "foobar"));
275 assert_se(endswith("", ""));
276
277 assert_se(!endswith("foobar", "foo"));
278 assert_se(!endswith("foobar", "foobarfoofoo"));
279}
280
281static void test_endswith_no_case(void) {
282 assert_se(endswith_no_case("fooBAR", "bar"));
283 assert_se(endswith_no_case("foobar", ""));
284 assert_se(endswith_no_case("foobar", "FOOBAR"));
285 assert_se(endswith_no_case("", ""));
286
287 assert_se(!endswith_no_case("foobar", "FOO"));
288 assert_se(!endswith_no_case("foobar", "FOOBARFOOFOO"));
289}
290
291static void test_delete_chars(void) {
7546145e
LP
292 char *s, input[] = " hello, waldo. abc";
293
294 s = delete_chars(input, WHITESPACE);
295 assert_se(streq(s, "hello,waldo.abc"));
296 assert_se(s == input);
297}
298
299static void test_delete_trailing_chars(void) {
300
301 char *s,
302 input1[] = " \n \r k \n \r ",
303 input2[] = "kkkkthiskkkiskkkaktestkkk",
304 input3[] = "abcdef";
305
306 s = delete_trailing_chars(input1, WHITESPACE);
307 assert_se(streq(s, " \n \r k"));
308 assert_se(s == input1);
309
310 s = delete_trailing_chars(input2, "kt");
311 assert_se(streq(s, "kkkkthiskkkiskkkaktes"));
312 assert_se(s == input2);
313
314 s = delete_trailing_chars(input3, WHITESPACE);
315 assert_se(streq(s, "abcdef"));
316 assert_se(s == input3);
317
318 s = delete_trailing_chars(input3, "fe");
319 assert_se(streq(s, "abcd"));
320 assert_se(s == input3);
321}
322
323static void test_skip_leading_chars(void) {
324 char input1[] = " \n \r k \n \r ",
325 input2[] = "kkkkthiskkkiskkkaktestkkk",
326 input3[] = "abcdef";
6571a64e 327
7546145e
LP
328 assert_se(streq(skip_leading_chars(input1, WHITESPACE), "k \n \r "));
329 assert_se(streq(skip_leading_chars(input2, "k"), "thiskkkiskkkaktestkkk"));
330 assert_se(streq(skip_leading_chars(input2, "tk"), "hiskkkiskkkaktestkkk"));
331 assert_se(streq(skip_leading_chars(input3, WHITESPACE), "abcdef"));
332 assert_se(streq(skip_leading_chars(input3, "bcaef"), "def"));
6571a64e
RC
333}
334
335static void test_in_charset(void) {
336 assert_se(in_charset("dddaaabbbcccc", "abcd"));
337 assert_se(!in_charset("dddaaabbbcccc", "abc f"));
338}
339
340static void test_split_pair(void) {
341 _cleanup_free_ char *a = NULL, *b = NULL;
342
343 assert_se(split_pair("", "", &a, &b) == -EINVAL);
344 assert_se(split_pair("foo=bar", "", &a, &b) == -EINVAL);
345 assert_se(split_pair("", "=", &a, &b) == -EINVAL);
346 assert_se(split_pair("foo=bar", "=", &a, &b) >= 0);
347 assert_se(streq(a, "foo"));
348 assert_se(streq(b, "bar"));
349 free(a);
350 free(b);
351 assert_se(split_pair("==", "==", &a, &b) >= 0);
352 assert_se(streq(a, ""));
353 assert_se(streq(b, ""));
354 free(a);
355 free(b);
356
357 assert_se(split_pair("===", "==", &a, &b) >= 0);
358 assert_se(streq(a, ""));
359 assert_se(streq(b, "="));
360}
361
362static void test_first_word(void) {
363 assert_se(first_word("Hello", ""));
364 assert_se(first_word("Hello", "Hello"));
365 assert_se(first_word("Hello world", "Hello"));
366 assert_se(first_word("Hello\tworld", "Hello"));
367 assert_se(first_word("Hello\nworld", "Hello"));
368 assert_se(first_word("Hello\rworld", "Hello"));
369 assert_se(first_word("Hello ", "Hello"));
370
371 assert_se(!first_word("Hello", "Hellooo"));
372 assert_se(!first_word("Hello", "xxxxx"));
373 assert_se(!first_word("Hellooo", "Hello"));
374}
375
7bf7ce28
LP
376static void test_strlen_ptr(void) {
377 assert_se(strlen_ptr("foo") == 3);
378 assert_se(strlen_ptr("") == 0);
379 assert_se(strlen_ptr(NULL) == 0);
380}
381
9fe4ea21
LP
382int main(int argc, char *argv[]) {
383 test_string_erase();
522d85ae 384 test_ascii_strcasecmp_n();
c1749834 385 test_ascii_strcasecmp_nn();
6571a64e
RC
386 test_streq_ptr();
387 test_strstrip();
388 test_strextend();
389 test_strrep();
390 test_strappend();
391 test_string_has_cc();
392 test_ascii_strlower();
393 test_strshorten();
394 test_strjoina();
395 test_strcmp_ptr();
396 test_foreach_word();
397 test_foreach_word_quoted();
398 test_endswith();
399 test_endswith_no_case();
400 test_delete_chars();
7546145e
LP
401 test_delete_trailing_chars();
402 test_skip_leading_chars();
6571a64e
RC
403 test_in_charset();
404 test_split_pair();
405 test_first_word();
7bf7ce28 406 test_strlen_ptr();
6571a64e 407
9fe4ea21
LP
408 return 0;
409}