blob: 96e048975d882245d967050fae04321f331f8538 [file] [log] [blame]
Simon Glassd0509282020-04-08 08:32:55 -06001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright 2020 Google LLC
4 */
5
Simon Glassd0509282020-04-08 08:32:55 -06006#include <vsprintf.h>
7#include <test/suites.h>
8#include <test/test.h>
9#include <test/ut.h>
10
11/* This is large enough for any of the test strings */
12#define TEST_STR_SIZE 200
13
14static const char str1[] = "I'm sorry I'm late.";
15static const char str2[] = "1099abNo, don't bother apologising.";
16static const char str3[] = "0xbI'm sorry you're alive.";
Simon Glass238efc22021-07-24 09:03:33 -060017static const char str4[] = "1234567890123 I lost closer friends";
18static const char str5[] = "0x9876543210the last time I was deloused";
Simon Glassb9efdf52021-07-24 09:03:34 -060019static const char str6[] = "0778octal is seldom used";
20static const char str7[] = "707it is a piece of computing history";
Simon Glassd0509282020-04-08 08:32:55 -060021
22/* Declare a new str test */
23#define STR_TEST(_name, _flags) UNIT_TEST(_name, _flags, str_test)
24
Patrick Delaunayc8cdd492020-11-19 10:08:43 +010025static int str_upper(struct unit_test_state *uts)
Simon Glass811a2602020-04-08 08:32:56 -060026{
27 char out[TEST_STR_SIZE];
28
29 /* Make sure it adds a terminator */
30 out[strlen(str1)] = 'a';
31 str_to_upper(str1, out, SIZE_MAX);
32 ut_asserteq_str("I'M SORRY I'M LATE.", out);
33
34 /* In-place operation */
35 strcpy(out, str2);
36 str_to_upper(out, out, SIZE_MAX);
37 ut_asserteq_str("1099ABNO, DON'T BOTHER APOLOGISING.", out);
38
39 /* Limited length */
40 str_to_upper(str1, out, 7);
41 ut_asserteq_str("I'M SORO, DON'T BOTHER APOLOGISING.", out);
42
43 /* In-place with limited length */
44 strcpy(out, str2);
45 str_to_upper(out, out, 7);
46 ut_asserteq_str("1099ABNo, don't bother apologising.", out);
47
48 /* Copy an empty string to a buffer with space*/
49 out[1] = 0x7f;
50 str_to_upper("", out, SIZE_MAX);
51 ut_asserteq('\0', *out);
52 ut_asserteq(0x7f, out[1]);
53
54 /* Copy an empty string to a buffer with no space*/
55 out[0] = 0x7f;
56 str_to_upper("", out, 0);
57 ut_asserteq(0x7f, out[0]);
58
59 return 0;
60}
Patrick Delaunayc8cdd492020-11-19 10:08:43 +010061STR_TEST(str_upper, 0);
Simon Glass811a2602020-04-08 08:32:56 -060062
Simon Glassd0509282020-04-08 08:32:55 -060063static int run_strtoul(struct unit_test_state *uts, const char *str, int base,
Simon Glass811a2602020-04-08 08:32:56 -060064 ulong expect_val, int expect_endp_offset, bool upper)
Simon Glassd0509282020-04-08 08:32:55 -060065{
Simon Glass811a2602020-04-08 08:32:56 -060066 char out[TEST_STR_SIZE];
Simon Glassd0509282020-04-08 08:32:55 -060067 char *endp;
68 ulong val;
69
Simon Glass811a2602020-04-08 08:32:56 -060070 strcpy(out, str);
71 if (upper)
72 str_to_upper(out, out, -1);
73
74 val = simple_strtoul(out, &endp, base);
Simon Glassd0509282020-04-08 08:32:55 -060075 ut_asserteq(expect_val, val);
Simon Glass811a2602020-04-08 08:32:56 -060076 ut_asserteq(expect_endp_offset, endp - out);
Simon Glassd0509282020-04-08 08:32:55 -060077
78 return 0;
79}
80
81static int str_simple_strtoul(struct unit_test_state *uts)
82{
Simon Glass811a2602020-04-08 08:32:56 -060083 int upper;
Simon Glassd0509282020-04-08 08:32:55 -060084
Simon Glass811a2602020-04-08 08:32:56 -060085 /* Check that it is case-insentive */
86 for (upper = 0; upper < 2; upper++) {
87 /* Base 10 and base 16 */
88 ut_assertok(run_strtoul(uts, str2, 10, 1099, 4, upper));
89 ut_assertok(run_strtoul(uts, str2, 16, 0x1099ab, 6, upper));
Simon Glass8be8eab2021-07-24 09:03:32 -060090 ut_assertok(run_strtoul(uts, str3, 16, 0xb, 3, upper));
Simon Glass90877bb2021-07-24 09:03:38 -060091 ut_assertok(run_strtoul(uts, str3, 10, 0xb, 3, upper));
Simon Glassd0509282020-04-08 08:32:55 -060092
Simon Glassb9efdf52021-07-24 09:03:34 -060093 /* Octal */
94 ut_assertok(run_strtoul(uts, str6, 0, 63, 3, upper));
95 ut_assertok(run_strtoul(uts, str7, 8, 0x1c7, 3, upper));
96
Simon Glass811a2602020-04-08 08:32:56 -060097 /* Invalid string */
98 ut_assertok(run_strtoul(uts, str1, 10, 0, 0, upper));
99
100 /* Base 0 */
101 ut_assertok(run_strtoul(uts, str1, 0, 0, 0, upper));
102 ut_assertok(run_strtoul(uts, str2, 0, 1099, 4, upper));
103 ut_assertok(run_strtoul(uts, str3, 0, 0xb, 3, upper));
Simon Glassd0509282020-04-08 08:32:55 -0600104
Simon Glass811a2602020-04-08 08:32:56 -0600105 /* Base 2 */
106 ut_assertok(run_strtoul(uts, str1, 2, 0, 0, upper));
107 ut_assertok(run_strtoul(uts, str2, 2, 2, 2, upper));
108 }
Simon Glassd0509282020-04-08 08:32:55 -0600109
110 /* Check endp being NULL */
111 ut_asserteq(1099, simple_strtoul(str2, NULL, 0));
112
113 return 0;
114}
115STR_TEST(str_simple_strtoul, 0);
116
Simon Glass238efc22021-07-24 09:03:33 -0600117static int run_strtoull(struct unit_test_state *uts, const char *str, int base,
118 unsigned long long expect_val, int expect_endp_offset,
119 bool upper)
120{
121 char out[TEST_STR_SIZE];
122 char *endp;
123 unsigned long long val;
124
125 strcpy(out, str);
126 if (upper)
127 str_to_upper(out, out, -1);
128
129 val = simple_strtoull(out, &endp, base);
130 ut_asserteq(expect_val, val);
131 ut_asserteq(expect_endp_offset, endp - out);
132
133 return 0;
134}
135
136static int str_simple_strtoull(struct unit_test_state *uts)
137{
138 int upper;
139
140 /* Check that it is case-insentive */
141 for (upper = 0; upper < 2; upper++) {
142 /* Base 10 and base 16 */
143 ut_assertok(run_strtoull(uts, str2, 10, 1099, 4, upper));
144 ut_assertok(run_strtoull(uts, str2, 16, 0x1099ab, 6, upper));
145 ut_assertok(run_strtoull(uts, str3, 16, 0xb, 3, upper));
Simon Glass90877bb2021-07-24 09:03:38 -0600146 ut_assertok(run_strtoull(uts, str3, 10, 0xb, 3, upper));
Simon Glass238efc22021-07-24 09:03:33 -0600147
Simon Glassb9efdf52021-07-24 09:03:34 -0600148 /* Octal */
149 ut_assertok(run_strtoull(uts, str6, 0, 63, 3, upper));
150 ut_assertok(run_strtoull(uts, str7, 8, 0x1c7, 3, upper));
151
Simon Glass238efc22021-07-24 09:03:33 -0600152 /* Large values */
153 ut_assertok(run_strtoull(uts, str4, 10, 1234567890123, 13,
154 upper));
155 ut_assertok(run_strtoull(uts, str4, 16, 0x1234567890123, 13,
156 upper));
157 ut_assertok(run_strtoull(uts, str5, 0, 0x9876543210, 12,
158 upper));
159
160 /* Invalid string */
161 ut_assertok(run_strtoull(uts, str1, 10, 0, 0, upper));
162
163 /* Base 0 */
164 ut_assertok(run_strtoull(uts, str1, 0, 0, 0, upper));
165 ut_assertok(run_strtoull(uts, str2, 0, 1099, 4, upper));
166 ut_assertok(run_strtoull(uts, str3, 0, 0xb, 3, upper));
167
168 /* Base 2 */
169 ut_assertok(run_strtoull(uts, str1, 2, 0, 0, upper));
170 ut_assertok(run_strtoull(uts, str2, 2, 2, 2, upper));
171 }
172
173 /* Check endp being NULL */
174 ut_asserteq(1099, simple_strtoull(str2, NULL, 0));
175
176 return 0;
177}
178STR_TEST(str_simple_strtoull, 0);
179
Simon Glass3ff49ec2021-07-24 09:03:29 -0600180static int str_hextoul(struct unit_test_state *uts)
181{
182 char *endp;
183
184 /* Just a simple test, since we know this uses simple_strtoul() */
185 ut_asserteq(0x1099ab, hextoul(str2, &endp));
186 ut_asserteq(6, endp - str2);
187
188 return 0;
189}
190STR_TEST(str_hextoul, 0);
191
Simon Glassff9b9032021-07-24 09:03:30 -0600192static int str_dectoul(struct unit_test_state *uts)
193{
194 char *endp;
195
196 /* Just a simple test, since we know this uses simple_strtoul() */
197 ut_asserteq(1099, dectoul(str2, &endp));
198 ut_asserteq(4, endp - str2);
199
200 return 0;
201}
202STR_TEST(str_dectoul, 0);
203
Simon Glass8c2d6392022-04-24 23:30:54 -0600204static int str_itoa(struct unit_test_state *uts)
205{
206 ut_asserteq_str("123", simple_itoa(123));
207 ut_asserteq_str("0", simple_itoa(0));
208 ut_asserteq_str("2147483647", simple_itoa(0x7fffffff));
209 ut_asserteq_str("4294967295", simple_itoa(0xffffffff));
210
211 /* Use #ifdef here to avoid a compiler warning on 32-bit machines */
212#ifdef CONFIG_PHYS_64BIT
213 if (sizeof(ulong) == 8) {
214 ut_asserteq_str("9223372036854775807",
215 simple_itoa((1UL << 63) - 1));
216 ut_asserteq_str("18446744073709551615", simple_itoa(-1));
217 }
218#endif /* CONFIG_PHYS_64BIT */
219
220 return 0;
221}
222STR_TEST(str_itoa, 0);
223
224static int str_xtoa(struct unit_test_state *uts)
225{
226 ut_asserteq_str("7f", simple_xtoa(127));
227 ut_asserteq_str("00", simple_xtoa(0));
228 ut_asserteq_str("7fffffff", simple_xtoa(0x7fffffff));
229 ut_asserteq_str("ffffffff", simple_xtoa(0xffffffff));
230
231 /* Use #ifdef here to avoid a compiler warning on 32-bit machines */
232#ifdef CONFIG_PHYS_64BIT
233 if (sizeof(ulong) == 8) {
234 ut_asserteq_str("7fffffffffffffff",
235 simple_xtoa((1UL << 63) - 1));
236 ut_asserteq_str("ffffffffffffffff", simple_xtoa(-1));
237 }
238#endif /* CONFIG_PHYS_64BIT */
239
240 return 0;
241}
242STR_TEST(str_xtoa, 0);
243
Simon Glasse74efcd2022-04-24 23:30:55 -0600244static int str_trailing(struct unit_test_state *uts)
245{
Simon Glass4bf2fc12022-04-24 23:30:58 -0600246 const char str1[] = "abc123def";
247 const char str2[] = "abc123def456";
248 const char *end;
Simon Glasse74efcd2022-04-24 23:30:55 -0600249
250 ut_asserteq(-1, trailing_strtol(""));
251 ut_asserteq(-1, trailing_strtol("123"));
252 ut_asserteq(123, trailing_strtol("abc123"));
253 ut_asserteq(4, trailing_strtol("12c4"));
254 ut_asserteq(-1, trailing_strtol("abd"));
255 ut_asserteq(-1, trailing_strtol("abc123def"));
256
257 ut_asserteq(-1, trailing_strtoln(str1, NULL));
258 ut_asserteq(123, trailing_strtoln(str1, str1 + 6));
259 ut_asserteq(-1, trailing_strtoln(str1, str1 + 9));
260
Simon Glass20888f32022-04-24 23:30:57 -0600261 ut_asserteq(3, trailing_strtol("a3"));
262
Simon Glass4bf2fc12022-04-24 23:30:58 -0600263 ut_asserteq(123, trailing_strtoln_end(str1, str1 + 6, &end));
264 ut_asserteq(3, end - str1);
265
266 ut_asserteq(-1, trailing_strtoln_end(str1, str1 + 7, &end));
267 ut_asserteq(7, end - str1);
268
269 ut_asserteq(456, trailing_strtoln_end(str2, NULL, &end));
270 ut_asserteq(9, end - str2);
271
Simon Glasse74efcd2022-04-24 23:30:55 -0600272 return 0;
273}
274STR_TEST(str_trailing, 0);
275
Simon Glass6a9de552023-01-17 10:47:14 -0700276static int test_str_to_list(struct unit_test_state *uts)
277{
278 const char **ptr;
279 ulong start;
280
281 /* check out of memory */
282 start = ut_check_delta(0);
283 malloc_enable_testing(0);
284 ut_assertnull(str_to_list(""));
285 ut_assertok(ut_check_delta(start));
286
287 ut_assertnull(str_to_list("this is a test"));
288 ut_assertok(ut_check_delta(start));
289
290 malloc_enable_testing(1);
291 ut_assertnull(str_to_list("this is a test"));
292 ut_assertok(ut_check_delta(start));
293
294 /* for an empty string, only one nalloc is needed */
295 malloc_enable_testing(1);
296 ptr = str_to_list("");
297 ut_assertnonnull(ptr);
298 ut_assertnull(ptr[0]);
299 str_free_list(ptr);
300 ut_assertok(ut_check_delta(start));
301
302 malloc_disable_testing();
303
304 /* test the same again, without any nalloc restrictions */
305 ptr = str_to_list("");
306 ut_assertnonnull(ptr);
307 ut_assertnull(ptr[0]);
308 str_free_list(ptr);
309 ut_assertok(ut_check_delta(start));
310
311 /* test a single string */
312 start = ut_check_delta(0);
313 ptr = str_to_list("hi");
314 ut_assertnonnull(ptr);
315 ut_assertnonnull(ptr[0]);
316 ut_asserteq_str("hi", ptr[0]);
317 ut_assertnull(ptr[1]);
318 str_free_list(ptr);
319 ut_assertok(ut_check_delta(start));
320
321 /* test two strings */
322 ptr = str_to_list("hi there");
323 ut_assertnonnull(ptr);
324 ut_assertnonnull(ptr[0]);
325 ut_asserteq_str("hi", ptr[0]);
326 ut_assertnonnull(ptr[1]);
327 ut_asserteq_str("there", ptr[1]);
328 ut_assertnull(ptr[2]);
329 str_free_list(ptr);
330 ut_assertok(ut_check_delta(start));
331
332 /* test leading, trailing and multiple spaces */
333 ptr = str_to_list(" more space ");
334 ut_assertnonnull(ptr);
335 ut_assertnonnull(ptr[0]);
336 ut_asserteq_str("", ptr[0]);
337 ut_assertnonnull(ptr[1]);
338 ut_asserteq_str("more", ptr[1]);
339 ut_assertnonnull(ptr[2]);
340 ut_asserteq_str("", ptr[2]);
341 ut_assertnonnull(ptr[3]);
342 ut_asserteq_str("space", ptr[3]);
343 ut_assertnonnull(ptr[4]);
344 ut_asserteq_str("", ptr[4]);
Simon Glass6667c012024-07-30 08:39:36 -0600345 ut_assertnull(ptr[5]);
Simon Glass6a9de552023-01-17 10:47:14 -0700346 str_free_list(ptr);
347 ut_assertok(ut_check_delta(start));
348
349 /* test freeing a NULL pointer */
350 str_free_list(NULL);
351
352 return 0;
353}
354STR_TEST(test_str_to_list, 0);
355
Simon Glassed38aef2020-05-10 11:40:03 -0600356int do_ut_str(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
Simon Glassd0509282020-04-08 08:32:55 -0600357{
Simon Glassb50211f2021-03-07 17:35:10 -0700358 struct unit_test *tests = UNIT_TEST_SUITE_START(str_test);
359 const int n_ents = UNIT_TEST_SUITE_COUNT(str_test);
Simon Glassd0509282020-04-08 08:32:55 -0600360
361 return cmd_ut_category("str", "str_", tests, n_ents, argc, argv);
362}