1 // SPDX-License-Identifier: GPL-2.0-only
3 * Test cases for sscanf facility.
6 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8 #include <linux/bitops.h>
9 #include <linux/init.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/overflow.h>
13 #include <linux/printk.h>
14 #include <linux/random.h>
15 #include <linux/slab.h>
16 #include <linux/string.h>
18 #include "../tools/testing/selftests/kselftest_module.h"
22 KSTM_MODULE_GLOBALS();
23 static char *test_buffer __initdata;
24 static char *fmt_buffer __initdata;
25 static struct rnd_state rnd_state __initdata;
27 typedef int (*check_fn)(const void *check_data, const char *string,
28 const char *fmt, int n_args, va_list ap);
30 static void __scanf(4, 6) __init
31 _test(check_fn fn, const void *check_data, const char *string, const char *fmt,
41 ret = vsscanf(string, fmt, ap_copy);
45 pr_warn("vsscanf(\"%s\", \"%s\", ...) returned %d expected %d\n",
46 string, fmt, ret, n_args);
50 ret = (*fn)(check_data, string, fmt, n_args, ap);
63 #define _check_numbers_template(arg_fmt, expect, str, fmt, n_args, ap) \
65 pr_debug("\"%s\", \"%s\" ->\n", str, fmt); \
66 for (; n_args > 0; n_args--, expect++) { \
67 typeof(*expect) got = *va_arg(ap, typeof(expect)); \
68 pr_debug("\t" arg_fmt "\n", got); \
69 if (got != *expect) { \
70 pr_warn("vsscanf(\"%s\", \"%s\", ...) expected " arg_fmt " got " arg_fmt "\n", \
71 str, fmt, *expect, got); \
78 static int __init check_ull(const void *check_data, const char *string,
79 const char *fmt, int n_args, va_list ap)
81 const unsigned long long *pval = check_data;
83 _check_numbers_template("%llu", pval, string, fmt, n_args, ap);
86 static int __init check_ll(const void *check_data, const char *string,
87 const char *fmt, int n_args, va_list ap)
89 const long long *pval = check_data;
91 _check_numbers_template("%lld", pval, string, fmt, n_args, ap);
94 static int __init check_ulong(const void *check_data, const char *string,
95 const char *fmt, int n_args, va_list ap)
97 const unsigned long *pval = check_data;
99 _check_numbers_template("%lu", pval, string, fmt, n_args, ap);
102 static int __init check_long(const void *check_data, const char *string,
103 const char *fmt, int n_args, va_list ap)
105 const long *pval = check_data;
107 _check_numbers_template("%ld", pval, string, fmt, n_args, ap);
110 static int __init check_uint(const void *check_data, const char *string,
111 const char *fmt, int n_args, va_list ap)
113 const unsigned int *pval = check_data;
115 _check_numbers_template("%u", pval, string, fmt, n_args, ap);
118 static int __init check_int(const void *check_data, const char *string,
119 const char *fmt, int n_args, va_list ap)
121 const int *pval = check_data;
123 _check_numbers_template("%d", pval, string, fmt, n_args, ap);
126 static int __init check_ushort(const void *check_data, const char *string,
127 const char *fmt, int n_args, va_list ap)
129 const unsigned short *pval = check_data;
131 _check_numbers_template("%hu", pval, string, fmt, n_args, ap);
134 static int __init check_short(const void *check_data, const char *string,
135 const char *fmt, int n_args, va_list ap)
137 const short *pval = check_data;
139 _check_numbers_template("%hd", pval, string, fmt, n_args, ap);
142 static int __init check_uchar(const void *check_data, const char *string,
143 const char *fmt, int n_args, va_list ap)
145 const unsigned char *pval = check_data;
147 _check_numbers_template("%hhu", pval, string, fmt, n_args, ap);
150 static int __init check_char(const void *check_data, const char *string,
151 const char *fmt, int n_args, va_list ap)
153 const signed char *pval = check_data;
155 _check_numbers_template("%hhd", pval, string, fmt, n_args, ap);
158 /* Selection of interesting numbers to test, copied from test-kstrtox.c */
159 static const unsigned long long numbers[] __initconst = {
180 0x7fffffffffffffffULL,
181 0x8000000000000000ULL,
182 0x8000000000000001ULL,
183 0xfffffffffffffffeULL,
184 0xffffffffffffffffULL,
187 #define value_representable_in_type(T, val) \
189 ? ((long long)(val) >= type_min(T)) && ((long long)(val) <= type_max(T)) \
190 : ((unsigned long long)(val) <= type_max(T)))
193 #define test_one_number(T, gen_fmt, scan_fmt, val, fn) \
195 const T expect_val = (T)(val); \
196 T result = ~expect_val; /* should be overwritten */ \
198 snprintf(test_buffer, BUF_SIZE, gen_fmt, expect_val); \
199 _test(fn, &expect_val, test_buffer, "%" scan_fmt, 1, &result); \
202 #define simple_numbers_loop(T, gen_fmt, scan_fmt, fn) \
206 for (i = 0; i < ARRAY_SIZE(numbers); i++) { \
207 if (value_representable_in_type(T, numbers[i])) \
208 test_one_number(T, gen_fmt, scan_fmt, \
211 if (value_representable_in_type(T, -numbers[i])) \
212 test_one_number(T, gen_fmt, scan_fmt, \
217 static void __init numbers_simple(void)
219 simple_numbers_loop(unsigned long long, "%llu", "llu", check_ull);
220 simple_numbers_loop(long long, "%lld", "lld", check_ll);
221 simple_numbers_loop(long long, "%lld", "lli", check_ll);
222 simple_numbers_loop(unsigned long long, "%llx", "llx", check_ull);
223 simple_numbers_loop(long long, "%llx", "llx", check_ll);
224 simple_numbers_loop(long long, "0x%llx", "lli", check_ll);
225 simple_numbers_loop(unsigned long long, "0x%llx", "llx", check_ull);
226 simple_numbers_loop(long long, "0x%llx", "llx", check_ll);
228 simple_numbers_loop(unsigned long, "%lu", "lu", check_ulong);
229 simple_numbers_loop(long, "%ld", "ld", check_long);
230 simple_numbers_loop(long, "%ld", "li", check_long);
231 simple_numbers_loop(unsigned long, "%lx", "lx", check_ulong);
232 simple_numbers_loop(long, "%lx", "lx", check_long);
233 simple_numbers_loop(long, "0x%lx", "li", check_long);
234 simple_numbers_loop(unsigned long, "0x%lx", "lx", check_ulong);
235 simple_numbers_loop(long, "0x%lx", "lx", check_long);
237 simple_numbers_loop(unsigned int, "%u", "u", check_uint);
238 simple_numbers_loop(int, "%d", "d", check_int);
239 simple_numbers_loop(int, "%d", "i", check_int);
240 simple_numbers_loop(unsigned int, "%x", "x", check_uint);
241 simple_numbers_loop(int, "%x", "x", check_int);
242 simple_numbers_loop(int, "0x%x", "i", check_int);
243 simple_numbers_loop(unsigned int, "0x%x", "x", check_uint);
244 simple_numbers_loop(int, "0x%x", "x", check_int);
246 simple_numbers_loop(unsigned short, "%hu", "hu", check_ushort);
247 simple_numbers_loop(short, "%hd", "hd", check_short);
248 simple_numbers_loop(short, "%hd", "hi", check_short);
249 simple_numbers_loop(unsigned short, "%hx", "hx", check_ushort);
250 simple_numbers_loop(short, "%hx", "hx", check_short);
251 simple_numbers_loop(short, "0x%hx", "hi", check_short);
252 simple_numbers_loop(unsigned short, "0x%hx", "hx", check_ushort);
253 simple_numbers_loop(short, "0x%hx", "hx", check_short);
255 simple_numbers_loop(unsigned char, "%hhu", "hhu", check_uchar);
256 simple_numbers_loop(signed char, "%hhd", "hhd", check_char);
257 simple_numbers_loop(signed char, "%hhd", "hhi", check_char);
258 simple_numbers_loop(unsigned char, "%hhx", "hhx", check_uchar);
259 simple_numbers_loop(signed char, "%hhx", "hhx", check_char);
260 simple_numbers_loop(signed char, "0x%hhx", "hhi", check_char);
261 simple_numbers_loop(unsigned char, "0x%hhx", "hhx", check_uchar);
262 simple_numbers_loop(signed char, "0x%hhx", "hhx", check_char);
266 * This gives a better variety of number "lengths" in a small sample than
267 * the raw prandom*() functions (Not mathematically rigorous!!).
268 * Variabilty of length and value is more important than perfect randomness.
270 static u32 __init next_test_random(u32 max_bits)
272 u32 n_bits = hweight32(prandom_u32_state(&rnd_state)) % (max_bits + 1);
274 return prandom_u32_state(&rnd_state) & GENMASK(n_bits, 0);
277 static unsigned long long __init next_test_random_ull(void)
279 u32 rand1 = prandom_u32_state(&rnd_state);
280 u32 n_bits = (hweight32(rand1) * 3) % 64;
281 u64 val = (u64)prandom_u32_state(&rnd_state) * rand1;
283 return val & GENMASK_ULL(n_bits, 0);
286 #define random_for_type(T) \
287 ((T)(sizeof(T) <= sizeof(u32) \
288 ? next_test_random(BITS_PER_TYPE(T)) \
289 : next_test_random_ull()))
292 * Define a pattern of negative and positive numbers to ensure we get
293 * some of both within the small number of samples in a test string.
295 #define NEGATIVES_PATTERN 0x3246 /* 00110010 01000110 */
297 #define fill_random_array(arr) \
299 unsigned int neg_pattern = NEGATIVES_PATTERN; \
302 for (i = 0; i < ARRAY_SIZE(arr); i++, neg_pattern >>= 1) { \
303 (arr)[i] = random_for_type(typeof((arr)[0])); \
304 if (is_signed_type(typeof((arr)[0])) && (neg_pattern & 1)) \
305 (arr)[i] = -(arr)[i]; \
310 * Convenience wrapper around snprintf() to append at buf_pos in buf,
311 * updating buf_pos and returning the number of characters appended.
312 * On error buf_pos is not changed and return value is 0.
314 static int __init __printf(4, 5)
315 append_fmt(char *buf, int *buf_pos, int buf_len, const char *val_fmt, ...)
320 va_start(ap, val_fmt);
321 field_len = vsnprintf(buf + *buf_pos, buf_len - *buf_pos, val_fmt, ap);
327 *buf_pos += field_len;
333 * Convenience function to append the field delimiter string
334 * to both the value string and format string buffers.
336 static void __init append_delim(char *str_buf, int *str_buf_pos, int str_buf_len,
337 char *fmt_buf, int *fmt_buf_pos, int fmt_buf_len,
338 const char *delim_str)
340 append_fmt(str_buf, str_buf_pos, str_buf_len, delim_str);
341 append_fmt(fmt_buf, fmt_buf_pos, fmt_buf_len, delim_str);
344 #define test_array_8(fn, check_data, string, fmt, arr) \
346 BUILD_BUG_ON(ARRAY_SIZE(arr) != 8); \
347 _test(fn, check_data, string, fmt, 8, \
348 &(arr)[0], &(arr)[1], &(arr)[2], &(arr)[3], \
349 &(arr)[4], &(arr)[5], &(arr)[6], &(arr)[7]); \
352 #define numbers_list_8(T, gen_fmt, field_sep, scan_fmt, fn) \
354 int i, pos = 0, fmt_pos = 0; \
355 T expect[8], result[8]; \
357 fill_random_array(expect); \
359 for (i = 0; i < ARRAY_SIZE(expect); i++) { \
361 append_delim(test_buffer, &pos, BUF_SIZE, \
362 fmt_buffer, &fmt_pos, BUF_SIZE, \
365 append_fmt(test_buffer, &pos, BUF_SIZE, gen_fmt, expect[i]); \
366 append_fmt(fmt_buffer, &fmt_pos, BUF_SIZE, "%%%s", scan_fmt); \
369 test_array_8(fn, expect, test_buffer, fmt_buffer, result); \
372 #define numbers_list_fix_width(T, gen_fmt, field_sep, width, scan_fmt, fn) \
376 snprintf(full_fmt, sizeof(full_fmt), "%u%s", width, scan_fmt); \
377 numbers_list_8(T, gen_fmt, field_sep, full_fmt, fn); \
380 #define numbers_list_val_width(T, gen_fmt, field_sep, scan_fmt, fn) \
382 int i, val_len, pos = 0, fmt_pos = 0; \
383 T expect[8], result[8]; \
385 fill_random_array(expect); \
387 for (i = 0; i < ARRAY_SIZE(expect); i++) { \
389 append_delim(test_buffer, &pos, BUF_SIZE, \
390 fmt_buffer, &fmt_pos, BUF_SIZE, field_sep);\
392 val_len = append_fmt(test_buffer, &pos, BUF_SIZE, gen_fmt, \
394 append_fmt(fmt_buffer, &fmt_pos, BUF_SIZE, \
395 "%%%u%s", val_len, scan_fmt); \
398 test_array_8(fn, expect, test_buffer, fmt_buffer, result); \
401 static void __init numbers_list_ll(const char *delim)
403 numbers_list_8(unsigned long long, "%llu", delim, "llu", check_ull);
404 numbers_list_8(long long, "%lld", delim, "lld", check_ll);
405 numbers_list_8(long long, "%lld", delim, "lli", check_ll);
406 numbers_list_8(unsigned long long, "%llx", delim, "llx", check_ull);
407 numbers_list_8(unsigned long long, "0x%llx", delim, "llx", check_ull);
408 numbers_list_8(long long, "0x%llx", delim, "lli", check_ll);
411 static void __init numbers_list_l(const char *delim)
413 numbers_list_8(unsigned long, "%lu", delim, "lu", check_ulong);
414 numbers_list_8(long, "%ld", delim, "ld", check_long);
415 numbers_list_8(long, "%ld", delim, "li", check_long);
416 numbers_list_8(unsigned long, "%lx", delim, "lx", check_ulong);
417 numbers_list_8(unsigned long, "0x%lx", delim, "lx", check_ulong);
418 numbers_list_8(long, "0x%lx", delim, "li", check_long);
421 static void __init numbers_list_d(const char *delim)
423 numbers_list_8(unsigned int, "%u", delim, "u", check_uint);
424 numbers_list_8(int, "%d", delim, "d", check_int);
425 numbers_list_8(int, "%d", delim, "i", check_int);
426 numbers_list_8(unsigned int, "%x", delim, "x", check_uint);
427 numbers_list_8(unsigned int, "0x%x", delim, "x", check_uint);
428 numbers_list_8(int, "0x%x", delim, "i", check_int);
431 static void __init numbers_list_h(const char *delim)
433 numbers_list_8(unsigned short, "%hu", delim, "hu", check_ushort);
434 numbers_list_8(short, "%hd", delim, "hd", check_short);
435 numbers_list_8(short, "%hd", delim, "hi", check_short);
436 numbers_list_8(unsigned short, "%hx", delim, "hx", check_ushort);
437 numbers_list_8(unsigned short, "0x%hx", delim, "hx", check_ushort);
438 numbers_list_8(short, "0x%hx", delim, "hi", check_short);
441 static void __init numbers_list_hh(const char *delim)
443 numbers_list_8(unsigned char, "%hhu", delim, "hhu", check_uchar);
444 numbers_list_8(signed char, "%hhd", delim, "hhd", check_char);
445 numbers_list_8(signed char, "%hhd", delim, "hhi", check_char);
446 numbers_list_8(unsigned char, "%hhx", delim, "hhx", check_uchar);
447 numbers_list_8(unsigned char, "0x%hhx", delim, "hhx", check_uchar);
448 numbers_list_8(signed char, "0x%hhx", delim, "hhi", check_char);
451 static void __init numbers_list(const char *delim)
453 numbers_list_ll(delim);
454 numbers_list_l(delim);
455 numbers_list_d(delim);
456 numbers_list_h(delim);
457 numbers_list_hh(delim);
460 static void __init numbers_list_field_width_ll(const char *delim)
462 numbers_list_fix_width(unsigned long long, "%llu", delim, 20, "llu", check_ull);
463 numbers_list_fix_width(long long, "%lld", delim, 20, "lld", check_ll);
464 numbers_list_fix_width(long long, "%lld", delim, 20, "lli", check_ll);
465 numbers_list_fix_width(unsigned long long, "%llx", delim, 16, "llx", check_ull);
466 numbers_list_fix_width(unsigned long long, "0x%llx", delim, 18, "llx", check_ull);
467 numbers_list_fix_width(long long, "0x%llx", delim, 18, "lli", check_ll);
470 static void __init numbers_list_field_width_l(const char *delim)
472 #if BITS_PER_LONG == 64
473 numbers_list_fix_width(unsigned long, "%lu", delim, 20, "lu", check_ulong);
474 numbers_list_fix_width(long, "%ld", delim, 20, "ld", check_long);
475 numbers_list_fix_width(long, "%ld", delim, 20, "li", check_long);
476 numbers_list_fix_width(unsigned long, "%lx", delim, 16, "lx", check_ulong);
477 numbers_list_fix_width(unsigned long, "0x%lx", delim, 18, "lx", check_ulong);
478 numbers_list_fix_width(long, "0x%lx", delim, 18, "li", check_long);
480 numbers_list_fix_width(unsigned long, "%lu", delim, 10, "lu", check_ulong);
481 numbers_list_fix_width(long, "%ld", delim, 11, "ld", check_long);
482 numbers_list_fix_width(long, "%ld", delim, 11, "li", check_long);
483 numbers_list_fix_width(unsigned long, "%lx", delim, 8, "lx", check_ulong);
484 numbers_list_fix_width(unsigned long, "0x%lx", delim, 10, "lx", check_ulong);
485 numbers_list_fix_width(long, "0x%lx", delim, 10, "li", check_long);
489 static void __init numbers_list_field_width_d(const char *delim)
491 numbers_list_fix_width(unsigned int, "%u", delim, 10, "u", check_uint);
492 numbers_list_fix_width(int, "%d", delim, 11, "d", check_int);
493 numbers_list_fix_width(int, "%d", delim, 11, "i", check_int);
494 numbers_list_fix_width(unsigned int, "%x", delim, 8, "x", check_uint);
495 numbers_list_fix_width(unsigned int, "0x%x", delim, 10, "x", check_uint);
496 numbers_list_fix_width(int, "0x%x", delim, 10, "i", check_int);
499 static void __init numbers_list_field_width_h(const char *delim)
501 numbers_list_fix_width(unsigned short, "%hu", delim, 5, "hu", check_ushort);
502 numbers_list_fix_width(short, "%hd", delim, 6, "hd", check_short);
503 numbers_list_fix_width(short, "%hd", delim, 6, "hi", check_short);
504 numbers_list_fix_width(unsigned short, "%hx", delim, 4, "hx", check_ushort);
505 numbers_list_fix_width(unsigned short, "0x%hx", delim, 6, "hx", check_ushort);
506 numbers_list_fix_width(short, "0x%hx", delim, 6, "hi", check_short);
509 static void __init numbers_list_field_width_hh(const char *delim)
511 numbers_list_fix_width(unsigned char, "%hhu", delim, 3, "hhu", check_uchar);
512 numbers_list_fix_width(signed char, "%hhd", delim, 4, "hhd", check_char);
513 numbers_list_fix_width(signed char, "%hhd", delim, 4, "hhi", check_char);
514 numbers_list_fix_width(unsigned char, "%hhx", delim, 2, "hhx", check_uchar);
515 numbers_list_fix_width(unsigned char, "0x%hhx", delim, 4, "hhx", check_uchar);
516 numbers_list_fix_width(signed char, "0x%hhx", delim, 4, "hhi", check_char);
520 * List of numbers separated by delim. Each field width specifier is the
521 * maximum possible digits for the given type and base.
523 static void __init numbers_list_field_width_typemax(const char *delim)
525 numbers_list_field_width_ll(delim);
526 numbers_list_field_width_l(delim);
527 numbers_list_field_width_d(delim);
528 numbers_list_field_width_h(delim);
529 numbers_list_field_width_hh(delim);
532 static void __init numbers_list_field_width_val_ll(const char *delim)
534 numbers_list_val_width(unsigned long long, "%llu", delim, "llu", check_ull);
535 numbers_list_val_width(long long, "%lld", delim, "lld", check_ll);
536 numbers_list_val_width(long long, "%lld", delim, "lli", check_ll);
537 numbers_list_val_width(unsigned long long, "%llx", delim, "llx", check_ull);
538 numbers_list_val_width(unsigned long long, "0x%llx", delim, "llx", check_ull);
539 numbers_list_val_width(long long, "0x%llx", delim, "lli", check_ll);
542 static void __init numbers_list_field_width_val_l(const char *delim)
544 numbers_list_val_width(unsigned long, "%lu", delim, "lu", check_ulong);
545 numbers_list_val_width(long, "%ld", delim, "ld", check_long);
546 numbers_list_val_width(long, "%ld", delim, "li", check_long);
547 numbers_list_val_width(unsigned long, "%lx", delim, "lx", check_ulong);
548 numbers_list_val_width(unsigned long, "0x%lx", delim, "lx", check_ulong);
549 numbers_list_val_width(long, "0x%lx", delim, "li", check_long);
552 static void __init numbers_list_field_width_val_d(const char *delim)
554 numbers_list_val_width(unsigned int, "%u", delim, "u", check_uint);
555 numbers_list_val_width(int, "%d", delim, "d", check_int);
556 numbers_list_val_width(int, "%d", delim, "i", check_int);
557 numbers_list_val_width(unsigned int, "%x", delim, "x", check_uint);
558 numbers_list_val_width(unsigned int, "0x%x", delim, "x", check_uint);
559 numbers_list_val_width(int, "0x%x", delim, "i", check_int);
562 static void __init numbers_list_field_width_val_h(const char *delim)
564 numbers_list_val_width(unsigned short, "%hu", delim, "hu", check_ushort);
565 numbers_list_val_width(short, "%hd", delim, "hd", check_short);
566 numbers_list_val_width(short, "%hd", delim, "hi", check_short);
567 numbers_list_val_width(unsigned short, "%hx", delim, "hx", check_ushort);
568 numbers_list_val_width(unsigned short, "0x%hx", delim, "hx", check_ushort);
569 numbers_list_val_width(short, "0x%hx", delim, "hi", check_short);
572 static void __init numbers_list_field_width_val_hh(const char *delim)
574 numbers_list_val_width(unsigned char, "%hhu", delim, "hhu", check_uchar);
575 numbers_list_val_width(signed char, "%hhd", delim, "hhd", check_char);
576 numbers_list_val_width(signed char, "%hhd", delim, "hhi", check_char);
577 numbers_list_val_width(unsigned char, "%hhx", delim, "hhx", check_uchar);
578 numbers_list_val_width(unsigned char, "0x%hhx", delim, "hhx", check_uchar);
579 numbers_list_val_width(signed char, "0x%hhx", delim, "hhi", check_char);
583 * List of numbers separated by delim. Each field width specifier is the
584 * exact length of the corresponding value digits in the string being scanned.
586 static void __init numbers_list_field_width_val_width(const char *delim)
588 numbers_list_field_width_val_ll(delim);
589 numbers_list_field_width_val_l(delim);
590 numbers_list_field_width_val_d(delim);
591 numbers_list_field_width_val_h(delim);
592 numbers_list_field_width_val_hh(delim);
596 * Slice a continuous string of digits without field delimiters, containing
597 * numbers of varying length, using the field width to extract each group
598 * of digits. For example the hex values c0,3,bf01,303 would have a
599 * string representation of "c03bf01303" and extracted with "%2x%1x%4x%3x".
601 static void __init numbers_slice(void)
603 numbers_list_field_width_val_width("");
606 #define test_number_prefix(T, str, scan_fmt, expect0, expect1, n_args, fn) \
608 const T expect[2] = { expect0, expect1 }; \
609 T result[2] = {~expect[0], ~expect[1]}; \
611 _test(fn, &expect, str, scan_fmt, n_args, &result[0], &result[1]); \
615 * Number prefix is >= field width.
616 * Expected behaviour is derived from testing userland sscanf.
618 static void __init numbers_prefix_overflow(void)
621 * Negative decimal with a field of width 1, should quit scanning
624 test_number_prefix(long long, "-1 1", "%1lld %lld", 0, 0, 0, check_ll);
625 test_number_prefix(long, "-1 1", "%1ld %ld", 0, 0, 0, check_long);
626 test_number_prefix(int, "-1 1", "%1d %d", 0, 0, 0, check_int);
627 test_number_prefix(short, "-1 1", "%1hd %hd", 0, 0, 0, check_short);
628 test_number_prefix(signed char, "-1 1", "%1hhd %hhd", 0, 0, 0, check_char);
630 test_number_prefix(long long, "-1 1", "%1lli %lli", 0, 0, 0, check_ll);
631 test_number_prefix(long, "-1 1", "%1li %li", 0, 0, 0, check_long);
632 test_number_prefix(int, "-1 1", "%1i %i", 0, 0, 0, check_int);
633 test_number_prefix(short, "-1 1", "%1hi %hi", 0, 0, 0, check_short);
634 test_number_prefix(signed char, "-1 1", "%1hhi %hhi", 0, 0, 0, check_char);
637 * 0x prefix in a field of width 1: 0 is a valid digit so should
638 * convert. Next field scan starts at the 'x' which isn't a digit so
639 * scan quits with one field converted.
641 test_number_prefix(unsigned long long, "0xA7", "%1llx%llx", 0, 0, 1, check_ull);
642 test_number_prefix(unsigned long, "0xA7", "%1lx%lx", 0, 0, 1, check_ulong);
643 test_number_prefix(unsigned int, "0xA7", "%1x%x", 0, 0, 1, check_uint);
644 test_number_prefix(unsigned short, "0xA7", "%1hx%hx", 0, 0, 1, check_ushort);
645 test_number_prefix(unsigned char, "0xA7", "%1hhx%hhx", 0, 0, 1, check_uchar);
646 test_number_prefix(long long, "0xA7", "%1lli%llx", 0, 0, 1, check_ll);
647 test_number_prefix(long, "0xA7", "%1li%lx", 0, 0, 1, check_long);
648 test_number_prefix(int, "0xA7", "%1i%x", 0, 0, 1, check_int);
649 test_number_prefix(short, "0xA7", "%1hi%hx", 0, 0, 1, check_short);
650 test_number_prefix(char, "0xA7", "%1hhi%hhx", 0, 0, 1, check_char);
653 * 0x prefix in a field of width 2 using %x conversion: first field
654 * converts to 0. Next field scan starts at the character after "0x".
655 * Both fields will convert.
657 test_number_prefix(unsigned long long, "0xA7", "%2llx%llx", 0, 0xa7, 2, check_ull);
658 test_number_prefix(unsigned long, "0xA7", "%2lx%lx", 0, 0xa7, 2, check_ulong);
659 test_number_prefix(unsigned int, "0xA7", "%2x%x", 0, 0xa7, 2, check_uint);
660 test_number_prefix(unsigned short, "0xA7", "%2hx%hx", 0, 0xa7, 2, check_ushort);
661 test_number_prefix(unsigned char, "0xA7", "%2hhx%hhx", 0, 0xa7, 2, check_uchar);
664 * 0x prefix in a field of width 2 using %i conversion: first field
665 * converts to 0. Next field scan starts at the character after "0x",
666 * which will convert if can be interpreted as decimal but will fail
667 * if it contains any hex digits (since no 0x prefix).
669 test_number_prefix(long long, "0x67", "%2lli%lli", 0, 67, 2, check_ll);
670 test_number_prefix(long, "0x67", "%2li%li", 0, 67, 2, check_long);
671 test_number_prefix(int, "0x67", "%2i%i", 0, 67, 2, check_int);
672 test_number_prefix(short, "0x67", "%2hi%hi", 0, 67, 2, check_short);
673 test_number_prefix(char, "0x67", "%2hhi%hhi", 0, 67, 2, check_char);
675 test_number_prefix(long long, "0xA7", "%2lli%lli", 0, 0, 1, check_ll);
676 test_number_prefix(long, "0xA7", "%2li%li", 0, 0, 1, check_long);
677 test_number_prefix(int, "0xA7", "%2i%i", 0, 0, 1, check_int);
678 test_number_prefix(short, "0xA7", "%2hi%hi", 0, 0, 1, check_short);
679 test_number_prefix(char, "0xA7", "%2hhi%hhi", 0, 0, 1, check_char);
682 #define _test_simple_strtoxx(T, fn, gen_fmt, expect, base) \
690 len = snprintf(test_buffer, BUF_SIZE, gen_fmt, expect); \
691 got = (fn)(test_buffer, &endp, base); \
692 pr_debug(#fn "(\"%s\", %d) -> " gen_fmt "\n", test_buffer, base, got); \
693 if (got != (expect)) { \
695 pr_warn(#fn "(\"%s\", %d): got " gen_fmt " expected " gen_fmt "\n", \
696 test_buffer, base, got, expect); \
697 } else if (endp != test_buffer + len) { \
699 pr_warn(#fn "(\"%s\", %d) startp=0x%px got endp=0x%px expected 0x%px\n", \
700 test_buffer, base, test_buffer, \
701 test_buffer + len, endp); \
708 #define test_simple_strtoxx(T, fn, gen_fmt, base) \
712 for (i = 0; i < ARRAY_SIZE(numbers); i++) { \
713 _test_simple_strtoxx(T, fn, gen_fmt, (T)numbers[i], base); \
715 if (is_signed_type(T)) \
716 _test_simple_strtoxx(T, fn, gen_fmt, \
717 -(T)numbers[i], base); \
721 static void __init test_simple_strtoull(void)
723 test_simple_strtoxx(unsigned long long, simple_strtoull, "%llu", 10);
724 test_simple_strtoxx(unsigned long long, simple_strtoull, "%llu", 0);
725 test_simple_strtoxx(unsigned long long, simple_strtoull, "%llx", 16);
726 test_simple_strtoxx(unsigned long long, simple_strtoull, "0x%llx", 16);
727 test_simple_strtoxx(unsigned long long, simple_strtoull, "0x%llx", 0);
730 static void __init test_simple_strtoll(void)
732 test_simple_strtoxx(long long, simple_strtoll, "%lld", 10);
733 test_simple_strtoxx(long long, simple_strtoll, "%lld", 0);
734 test_simple_strtoxx(long long, simple_strtoll, "%llx", 16);
735 test_simple_strtoxx(long long, simple_strtoll, "0x%llx", 16);
736 test_simple_strtoxx(long long, simple_strtoll, "0x%llx", 0);
739 static void __init test_simple_strtoul(void)
741 test_simple_strtoxx(unsigned long, simple_strtoul, "%lu", 10);
742 test_simple_strtoxx(unsigned long, simple_strtoul, "%lu", 0);
743 test_simple_strtoxx(unsigned long, simple_strtoul, "%lx", 16);
744 test_simple_strtoxx(unsigned long, simple_strtoul, "0x%lx", 16);
745 test_simple_strtoxx(unsigned long, simple_strtoul, "0x%lx", 0);
748 static void __init test_simple_strtol(void)
750 test_simple_strtoxx(long, simple_strtol, "%ld", 10);
751 test_simple_strtoxx(long, simple_strtol, "%ld", 0);
752 test_simple_strtoxx(long, simple_strtol, "%lx", 16);
753 test_simple_strtoxx(long, simple_strtol, "0x%lx", 16);
754 test_simple_strtoxx(long, simple_strtol, "0x%lx", 0);
757 /* Selection of common delimiters/separators between numbers in a string. */
758 static const char * const number_delimiters[] __initconst = {
759 " ", ":", ",", "-", "/",
762 static void __init test_numbers(void)
766 /* String containing only one number. */
769 /* String with multiple numbers separated by delimiter. */
770 for (i = 0; i < ARRAY_SIZE(number_delimiters); i++) {
771 numbers_list(number_delimiters[i]);
773 /* Field width may be longer than actual field digits. */
774 numbers_list_field_width_typemax(number_delimiters[i]);
776 /* Each field width exactly length of actual field digits. */
777 numbers_list_field_width_val_width(number_delimiters[i]);
780 /* Slice continuous sequence of digits using field widths. */
783 numbers_prefix_overflow();
786 static void __init selftest(void)
788 test_buffer = kmalloc(BUF_SIZE, GFP_KERNEL);
792 fmt_buffer = kmalloc(BUF_SIZE, GFP_KERNEL);
798 prandom_seed_state(&rnd_state, 3141592653589793238ULL);
802 test_simple_strtoull();
803 test_simple_strtoll();
804 test_simple_strtoul();
805 test_simple_strtol();
811 KSTM_MODULE_LOADERS(test_scanf);
812 MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
813 MODULE_LICENSE("GPL v2");