Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.4.
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Test cases for sscanf facility.
  4 */
  5
  6#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  7
  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>
 17
 18#include "../tools/testing/selftests/kselftest_module.h"
 19
 20#define BUF_SIZE 1024
 21
 22KSTM_MODULE_GLOBALS();
 23static char *test_buffer __initdata;
 24static char *fmt_buffer __initdata;
 25static struct rnd_state rnd_state __initdata;
 26
 27typedef int (*check_fn)(const void *check_data, const char *string,
 28			const char *fmt, int n_args, va_list ap);
 29
 30static void __scanf(4, 6) __init
 31_test(check_fn fn, const void *check_data, const char *string, const char *fmt,
 32	int n_args, ...)
 33{
 34	va_list ap, ap_copy;
 35	int ret;
 36
 37	total_tests++;
 38
 39	va_start(ap, n_args);
 40	va_copy(ap_copy, ap);
 41	ret = vsscanf(string, fmt, ap_copy);
 42	va_end(ap_copy);
 43
 44	if (ret != n_args) {
 45		pr_warn("vsscanf(\"%s\", \"%s\", ...) returned %d expected %d\n",
 46			string, fmt, ret, n_args);
 47		goto fail;
 48	}
 49
 50	ret = (*fn)(check_data, string, fmt, n_args, ap);
 51	if (ret)
 52		goto fail;
 53
 54	va_end(ap);
 55
 56	return;
 57
 58fail:
 59	failed_tests++;
 60	va_end(ap);
 61}
 62
 63#define _check_numbers_template(arg_fmt, expect, str, fmt, n_args, ap)		\
 64do {										\
 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);			\
 72			return 1;						\
 73		}								\
 74	}									\
 75	return 0;								\
 76} while (0)
 77
 78static int __init check_ull(const void *check_data, const char *string,
 79			    const char *fmt, int n_args, va_list ap)
 80{
 81	const unsigned long long *pval = check_data;
 82
 83	_check_numbers_template("%llu", pval, string, fmt, n_args, ap);
 84}
 85
 86static int __init check_ll(const void *check_data, const char *string,
 87			   const char *fmt, int n_args, va_list ap)
 88{
 89	const long long *pval = check_data;
 90
 91	_check_numbers_template("%lld", pval, string, fmt, n_args, ap);
 92}
 93
 94static int __init check_ulong(const void *check_data, const char *string,
 95			   const char *fmt, int n_args, va_list ap)
 96{
 97	const unsigned long *pval = check_data;
 98
 99	_check_numbers_template("%lu", pval, string, fmt, n_args, ap);
100}
101
102static int __init check_long(const void *check_data, const char *string,
103			  const char *fmt, int n_args, va_list ap)
104{
105	const long *pval = check_data;
106
107	_check_numbers_template("%ld", pval, string, fmt, n_args, ap);
108}
109
110static int __init check_uint(const void *check_data, const char *string,
111			     const char *fmt, int n_args, va_list ap)
112{
113	const unsigned int *pval = check_data;
114
115	_check_numbers_template("%u", pval, string, fmt, n_args, ap);
116}
117
118static int __init check_int(const void *check_data, const char *string,
119			    const char *fmt, int n_args, va_list ap)
120{
121	const int *pval = check_data;
122
123	_check_numbers_template("%d", pval, string, fmt, n_args, ap);
124}
125
126static int __init check_ushort(const void *check_data, const char *string,
127			       const char *fmt, int n_args, va_list ap)
128{
129	const unsigned short *pval = check_data;
130
131	_check_numbers_template("%hu", pval, string, fmt, n_args, ap);
132}
133
134static int __init check_short(const void *check_data, const char *string,
135			       const char *fmt, int n_args, va_list ap)
136{
137	const short *pval = check_data;
138
139	_check_numbers_template("%hd", pval, string, fmt, n_args, ap);
140}
141
142static int __init check_uchar(const void *check_data, const char *string,
143			       const char *fmt, int n_args, va_list ap)
144{
145	const unsigned char *pval = check_data;
146
147	_check_numbers_template("%hhu", pval, string, fmt, n_args, ap);
148}
149
150static int __init check_char(const void *check_data, const char *string,
151			       const char *fmt, int n_args, va_list ap)
152{
153	const signed char *pval = check_data;
154
155	_check_numbers_template("%hhd", pval, string, fmt, n_args, ap);
156}
157
158/* Selection of interesting numbers to test, copied from test-kstrtox.c */
159static const unsigned long long numbers[] __initconst = {
160	0x0ULL,
161	0x1ULL,
162	0x7fULL,
163	0x80ULL,
164	0x81ULL,
165	0xffULL,
166	0x100ULL,
167	0x101ULL,
168	0x7fffULL,
169	0x8000ULL,
170	0x8001ULL,
171	0xffffULL,
172	0x10000ULL,
173	0x10001ULL,
174	0x7fffffffULL,
175	0x80000000ULL,
176	0x80000001ULL,
177	0xffffffffULL,
178	0x100000000ULL,
179	0x100000001ULL,
180	0x7fffffffffffffffULL,
181	0x8000000000000000ULL,
182	0x8000000000000001ULL,
183	0xfffffffffffffffeULL,
184	0xffffffffffffffffULL,
185};
186
187#define value_representable_in_type(T, val)					 \
188(is_signed_type(T)								 \
189	? ((long long)(val) >= type_min(T)) && ((long long)(val) <= type_max(T)) \
190	: ((unsigned long long)(val) <= type_max(T)))
191
192
193#define test_one_number(T, gen_fmt, scan_fmt, val, fn)			\
194do {									\
195	const T expect_val = (T)(val);					\
196	T result = ~expect_val; /* should be overwritten */		\
197									\
198	snprintf(test_buffer, BUF_SIZE, gen_fmt, expect_val);		\
199	_test(fn, &expect_val, test_buffer, "%" scan_fmt, 1, &result);	\
200} while (0)
201
202#define simple_numbers_loop(T, gen_fmt, scan_fmt, fn)			\
203do {									\
204	int i;								\
205									\
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,		\
209					numbers[i], fn);		\
210									\
211		if (value_representable_in_type(T, -numbers[i]))	\
212			test_one_number(T, gen_fmt, scan_fmt,		\
213					-numbers[i], fn);		\
214	}								\
215} while (0)
216
217static void __init numbers_simple(void)
218{
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);
227
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);
236
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);
245
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);
254
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);
263}
264
265/*
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.
269 */
270static u32 __init next_test_random(u32 max_bits)
271{
272	u32 n_bits = hweight32(prandom_u32_state(&rnd_state)) % (max_bits + 1);
273
274	return prandom_u32_state(&rnd_state) & GENMASK(n_bits, 0);
275}
276
277static unsigned long long __init next_test_random_ull(void)
278{
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;
282
283	return val & GENMASK_ULL(n_bits, 0);
284}
285
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()))
290
291/*
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.
294 */
295#define NEGATIVES_PATTERN 0x3246	/* 00110010 01000110 */
296
297#define fill_random_array(arr)							\
298do {										\
299	unsigned int neg_pattern = NEGATIVES_PATTERN;				\
300	int i;									\
301										\
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];					\
306	}									\
307} while (0)
308
309/*
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.
313 */
314static int __init __printf(4, 5)
315append_fmt(char *buf, int *buf_pos, int buf_len, const char *val_fmt, ...)
316{
317	va_list ap;
318	int field_len;
319
320	va_start(ap, val_fmt);
321	field_len = vsnprintf(buf + *buf_pos, buf_len - *buf_pos, val_fmt, ap);
322	va_end(ap);
323
324	if (field_len < 0)
325		field_len = 0;
326
327	*buf_pos += field_len;
328
329	return field_len;
330}
331
332/*
333 * Convenience function to append the field delimiter string
334 * to both the value string and format string buffers.
335 */
336static 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)
339{
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);
342}
343
344#define test_array_8(fn, check_data, string, fmt, arr)				\
345do {										\
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]);			\
350} while (0)
351
352#define numbers_list_8(T, gen_fmt, field_sep, scan_fmt, fn)			\
353do {										\
354	int i, pos = 0, fmt_pos = 0;						\
355	T expect[8], result[8];							\
356										\
357	fill_random_array(expect);						\
358										\
359	for (i = 0; i < ARRAY_SIZE(expect); i++) {				\
360		if (i != 0)							\
361			append_delim(test_buffer, &pos, BUF_SIZE,		\
362				     fmt_buffer, &fmt_pos, BUF_SIZE,		\
363				     field_sep);				\
364										\
365		append_fmt(test_buffer, &pos, BUF_SIZE, gen_fmt, expect[i]);	\
366		append_fmt(fmt_buffer, &fmt_pos, BUF_SIZE, "%%%s", scan_fmt);	\
367	}									\
368										\
369	test_array_8(fn, expect, test_buffer, fmt_buffer, result);		\
370} while (0)
371
372#define numbers_list_fix_width(T, gen_fmt, field_sep, width, scan_fmt, fn)	\
373do {										\
374	char full_fmt[16];							\
375										\
376	snprintf(full_fmt, sizeof(full_fmt), "%u%s", width, scan_fmt);		\
377	numbers_list_8(T, gen_fmt, field_sep, full_fmt, fn);			\
378} while (0)
379
380#define numbers_list_val_width(T, gen_fmt, field_sep, scan_fmt, fn)		\
381do {										\
382	int i, val_len, pos = 0, fmt_pos = 0;					\
383	T expect[8], result[8];							\
384										\
385	fill_random_array(expect);						\
386										\
387	for (i = 0; i < ARRAY_SIZE(expect); i++) {				\
388		if (i != 0)							\
389			append_delim(test_buffer, &pos, BUF_SIZE,		\
390				     fmt_buffer, &fmt_pos, BUF_SIZE, field_sep);\
391										\
392		val_len = append_fmt(test_buffer, &pos, BUF_SIZE, gen_fmt,	\
393				     expect[i]);				\
394		append_fmt(fmt_buffer, &fmt_pos, BUF_SIZE,			\
395			   "%%%u%s", val_len, scan_fmt);			\
396	}									\
397										\
398	test_array_8(fn, expect, test_buffer, fmt_buffer, result);		\
399} while (0)
400
401static void __init numbers_list(const char *delim)
402{
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);
409
410	numbers_list_8(unsigned long,	   "%lu",    delim, "lu", check_ulong);
411	numbers_list_8(long,		   "%ld",    delim, "ld", check_long);
412	numbers_list_8(long,		   "%ld",    delim, "li", check_long);
413	numbers_list_8(unsigned long,	   "%lx",    delim, "lx", check_ulong);
414	numbers_list_8(unsigned long,	   "0x%lx",  delim, "lx", check_ulong);
415	numbers_list_8(long,		   "0x%lx",  delim, "li", check_long);
416
417	numbers_list_8(unsigned int,	   "%u",     delim, "u", check_uint);
418	numbers_list_8(int,		   "%d",     delim, "d", check_int);
419	numbers_list_8(int,		   "%d",     delim, "i", check_int);
420	numbers_list_8(unsigned int,	   "%x",     delim, "x", check_uint);
421	numbers_list_8(unsigned int,	   "0x%x",   delim, "x", check_uint);
422	numbers_list_8(int,		   "0x%x",   delim, "i", check_int);
423
424	numbers_list_8(unsigned short,	   "%hu",    delim, "hu", check_ushort);
425	numbers_list_8(short,		   "%hd",    delim, "hd", check_short);
426	numbers_list_8(short,		   "%hd",    delim, "hi", check_short);
427	numbers_list_8(unsigned short,	   "%hx",    delim, "hx", check_ushort);
428	numbers_list_8(unsigned short,	   "0x%hx",  delim, "hx", check_ushort);
429	numbers_list_8(short,		   "0x%hx",  delim, "hi", check_short);
430
431	numbers_list_8(unsigned char,	   "%hhu",   delim, "hhu", check_uchar);
432	numbers_list_8(signed char,	   "%hhd",   delim, "hhd", check_char);
433	numbers_list_8(signed char,	   "%hhd",   delim, "hhi", check_char);
434	numbers_list_8(unsigned char,	   "%hhx",   delim, "hhx", check_uchar);
435	numbers_list_8(unsigned char,	   "0x%hhx", delim, "hhx", check_uchar);
436	numbers_list_8(signed char,	   "0x%hhx", delim, "hhi", check_char);
437}
438
439/*
440 * List of numbers separated by delim. Each field width specifier is the
441 * maximum possible digits for the given type and base.
442 */
443static void __init numbers_list_field_width_typemax(const char *delim)
444{
445	numbers_list_fix_width(unsigned long long, "%llu",   delim, 20, "llu", check_ull);
446	numbers_list_fix_width(long long,	   "%lld",   delim, 20, "lld", check_ll);
447	numbers_list_fix_width(long long,	   "%lld",   delim, 20, "lli", check_ll);
448	numbers_list_fix_width(unsigned long long, "%llx",   delim, 16, "llx", check_ull);
449	numbers_list_fix_width(unsigned long long, "0x%llx", delim, 18, "llx", check_ull);
450	numbers_list_fix_width(long long,	   "0x%llx", delim, 18, "lli", check_ll);
451
452#if BITS_PER_LONG == 64
453	numbers_list_fix_width(unsigned long,	"%lu",	     delim, 20, "lu", check_ulong);
454	numbers_list_fix_width(long,		"%ld",	     delim, 20, "ld", check_long);
455	numbers_list_fix_width(long,		"%ld",	     delim, 20, "li", check_long);
456	numbers_list_fix_width(unsigned long,	"%lx",	     delim, 16, "lx", check_ulong);
457	numbers_list_fix_width(unsigned long,	"0x%lx",     delim, 18, "lx", check_ulong);
458	numbers_list_fix_width(long,		"0x%lx",     delim, 18, "li", check_long);
459#else
460	numbers_list_fix_width(unsigned long,	"%lu",	     delim, 10, "lu", check_ulong);
461	numbers_list_fix_width(long,		"%ld",	     delim, 11, "ld", check_long);
462	numbers_list_fix_width(long,		"%ld",	     delim, 11, "li", check_long);
463	numbers_list_fix_width(unsigned long,	"%lx",	     delim, 8,  "lx", check_ulong);
464	numbers_list_fix_width(unsigned long,	"0x%lx",     delim, 10, "lx", check_ulong);
465	numbers_list_fix_width(long,		"0x%lx",     delim, 10, "li", check_long);
466#endif
467
468	numbers_list_fix_width(unsigned int,	"%u",	     delim, 10, "u", check_uint);
469	numbers_list_fix_width(int,		"%d",	     delim, 11, "d", check_int);
470	numbers_list_fix_width(int,		"%d",	     delim, 11, "i", check_int);
471	numbers_list_fix_width(unsigned int,	"%x",	     delim, 8,  "x", check_uint);
472	numbers_list_fix_width(unsigned int,	"0x%x",	     delim, 10, "x", check_uint);
473	numbers_list_fix_width(int,		"0x%x",	     delim, 10, "i", check_int);
474
475	numbers_list_fix_width(unsigned short,	"%hu",	     delim, 5, "hu", check_ushort);
476	numbers_list_fix_width(short,		"%hd",	     delim, 6, "hd", check_short);
477	numbers_list_fix_width(short,		"%hd",	     delim, 6, "hi", check_short);
478	numbers_list_fix_width(unsigned short,	"%hx",	     delim, 4, "hx", check_ushort);
479	numbers_list_fix_width(unsigned short,	"0x%hx",     delim, 6, "hx", check_ushort);
480	numbers_list_fix_width(short,		"0x%hx",     delim, 6, "hi", check_short);
481
482	numbers_list_fix_width(unsigned char,	"%hhu",	     delim, 3, "hhu", check_uchar);
483	numbers_list_fix_width(signed char,	"%hhd",	     delim, 4, "hhd", check_char);
484	numbers_list_fix_width(signed char,	"%hhd",	     delim, 4, "hhi", check_char);
485	numbers_list_fix_width(unsigned char,	"%hhx",	     delim, 2, "hhx", check_uchar);
486	numbers_list_fix_width(unsigned char,	"0x%hhx",    delim, 4, "hhx", check_uchar);
487	numbers_list_fix_width(signed char,	"0x%hhx",    delim, 4, "hhi", check_char);
488}
489
490/*
491 * List of numbers separated by delim. Each field width specifier is the
492 * exact length of the corresponding value digits in the string being scanned.
493 */
494static void __init numbers_list_field_width_val_width(const char *delim)
495{
496	numbers_list_val_width(unsigned long long, "%llu",   delim, "llu", check_ull);
497	numbers_list_val_width(long long,	   "%lld",   delim, "lld", check_ll);
498	numbers_list_val_width(long long,	   "%lld",   delim, "lli", check_ll);
499	numbers_list_val_width(unsigned long long, "%llx",   delim, "llx", check_ull);
500	numbers_list_val_width(unsigned long long, "0x%llx", delim, "llx", check_ull);
501	numbers_list_val_width(long long,	   "0x%llx", delim, "lli", check_ll);
502
503	numbers_list_val_width(unsigned long,	"%lu",	     delim, "lu", check_ulong);
504	numbers_list_val_width(long,		"%ld",	     delim, "ld", check_long);
505	numbers_list_val_width(long,		"%ld",	     delim, "li", check_long);
506	numbers_list_val_width(unsigned long,	"%lx",	     delim, "lx", check_ulong);
507	numbers_list_val_width(unsigned long,	"0x%lx",     delim, "lx", check_ulong);
508	numbers_list_val_width(long,		"0x%lx",     delim, "li", check_long);
509
510	numbers_list_val_width(unsigned int,	"%u",	     delim, "u", check_uint);
511	numbers_list_val_width(int,		"%d",	     delim, "d", check_int);
512	numbers_list_val_width(int,		"%d",	     delim, "i", check_int);
513	numbers_list_val_width(unsigned int,	"%x",	     delim, "x", check_uint);
514	numbers_list_val_width(unsigned int,	"0x%x",	     delim, "x", check_uint);
515	numbers_list_val_width(int,		"0x%x",	     delim, "i", check_int);
516
517	numbers_list_val_width(unsigned short,	"%hu",	     delim, "hu", check_ushort);
518	numbers_list_val_width(short,		"%hd",	     delim, "hd", check_short);
519	numbers_list_val_width(short,		"%hd",	     delim, "hi", check_short);
520	numbers_list_val_width(unsigned short,	"%hx",	     delim, "hx", check_ushort);
521	numbers_list_val_width(unsigned short,	"0x%hx",     delim, "hx", check_ushort);
522	numbers_list_val_width(short,		"0x%hx",     delim, "hi", check_short);
523
524	numbers_list_val_width(unsigned char,	"%hhu",	     delim, "hhu", check_uchar);
525	numbers_list_val_width(signed char,	"%hhd",	     delim, "hhd", check_char);
526	numbers_list_val_width(signed char,	"%hhd",	     delim, "hhi", check_char);
527	numbers_list_val_width(unsigned char,	"%hhx",	     delim, "hhx", check_uchar);
528	numbers_list_val_width(unsigned char,	"0x%hhx",    delim, "hhx", check_uchar);
529	numbers_list_val_width(signed char,	"0x%hhx",    delim, "hhi", check_char);
530}
531
532/*
533 * Slice a continuous string of digits without field delimiters, containing
534 * numbers of varying length, using the field width to extract each group
535 * of digits. For example the hex values c0,3,bf01,303 would have a
536 * string representation of "c03bf01303" and extracted with "%2x%1x%4x%3x".
537 */
538static void __init numbers_slice(void)
539{
540	numbers_list_field_width_val_width("");
541}
542
543#define test_number_prefix(T, str, scan_fmt, expect0, expect1, n_args, fn)	\
544do {										\
545	const T expect[2] = { expect0, expect1 };				\
546	T result[2] = {~expect[0], ~expect[1]};					\
547										\
548	_test(fn, &expect, str, scan_fmt, n_args, &result[0], &result[1]);	\
549} while (0)
550
551/*
552 * Number prefix is >= field width.
553 * Expected behaviour is derived from testing userland sscanf.
554 */
555static void __init numbers_prefix_overflow(void)
556{
557	/*
558	 * Negative decimal with a field of width 1, should quit scanning
559	 * and return 0.
560	 */
561	test_number_prefix(long long,	"-1 1", "%1lld %lld",	0, 0, 0, check_ll);
562	test_number_prefix(long,	"-1 1", "%1ld %ld",	0, 0, 0, check_long);
563	test_number_prefix(int,		"-1 1", "%1d %d",	0, 0, 0, check_int);
564	test_number_prefix(short,	"-1 1", "%1hd %hd",	0, 0, 0, check_short);
565	test_number_prefix(signed char,	"-1 1", "%1hhd %hhd",	0, 0, 0, check_char);
566
567	test_number_prefix(long long,	"-1 1", "%1lli %lli",	0, 0, 0, check_ll);
568	test_number_prefix(long,	"-1 1", "%1li %li",	0, 0, 0, check_long);
569	test_number_prefix(int,		"-1 1", "%1i %i",	0, 0, 0, check_int);
570	test_number_prefix(short,	"-1 1", "%1hi %hi",	0, 0, 0, check_short);
571	test_number_prefix(signed char,	"-1 1", "%1hhi %hhi",	0, 0, 0, check_char);
572
573	/*
574	 * 0x prefix in a field of width 1: 0 is a valid digit so should
575	 * convert. Next field scan starts at the 'x' which isn't a digit so
576	 * scan quits with one field converted.
577	 */
578	test_number_prefix(unsigned long long,	"0xA7", "%1llx%llx", 0, 0, 1, check_ull);
579	test_number_prefix(unsigned long,	"0xA7", "%1lx%lx",   0, 0, 1, check_ulong);
580	test_number_prefix(unsigned int,	"0xA7", "%1x%x",     0, 0, 1, check_uint);
581	test_number_prefix(unsigned short,	"0xA7", "%1hx%hx",   0, 0, 1, check_ushort);
582	test_number_prefix(unsigned char,	"0xA7", "%1hhx%hhx", 0, 0, 1, check_uchar);
583	test_number_prefix(long long,		"0xA7", "%1lli%llx", 0, 0, 1, check_ll);
584	test_number_prefix(long,		"0xA7", "%1li%lx",   0, 0, 1, check_long);
585	test_number_prefix(int,			"0xA7", "%1i%x",     0, 0, 1, check_int);
586	test_number_prefix(short,		"0xA7", "%1hi%hx",   0, 0, 1, check_short);
587	test_number_prefix(char,		"0xA7", "%1hhi%hhx", 0, 0, 1, check_char);
588
589	/*
590	 * 0x prefix in a field of width 2 using %x conversion: first field
591	 * converts to 0. Next field scan starts at the character after "0x".
592	 * Both fields will convert.
593	 */
594	test_number_prefix(unsigned long long,	"0xA7", "%2llx%llx", 0, 0xa7, 2, check_ull);
595	test_number_prefix(unsigned long,	"0xA7", "%2lx%lx",   0, 0xa7, 2, check_ulong);
596	test_number_prefix(unsigned int,	"0xA7", "%2x%x",     0, 0xa7, 2, check_uint);
597	test_number_prefix(unsigned short,	"0xA7", "%2hx%hx",   0, 0xa7, 2, check_ushort);
598	test_number_prefix(unsigned char,	"0xA7", "%2hhx%hhx", 0, 0xa7, 2, check_uchar);
599
600	/*
601	 * 0x prefix in a field of width 2 using %i conversion: first field
602	 * converts to 0. Next field scan starts at the character after "0x",
603	 * which will convert if can be interpreted as decimal but will fail
604	 * if it contains any hex digits (since no 0x prefix).
605	 */
606	test_number_prefix(long long,	"0x67", "%2lli%lli", 0, 67, 2, check_ll);
607	test_number_prefix(long,	"0x67", "%2li%li",   0, 67, 2, check_long);
608	test_number_prefix(int,		"0x67", "%2i%i",     0, 67, 2, check_int);
609	test_number_prefix(short,	"0x67", "%2hi%hi",   0, 67, 2, check_short);
610	test_number_prefix(char,	"0x67", "%2hhi%hhi", 0, 67, 2, check_char);
611
612	test_number_prefix(long long,	"0xA7", "%2lli%lli", 0, 0,  1, check_ll);
613	test_number_prefix(long,	"0xA7", "%2li%li",   0, 0,  1, check_long);
614	test_number_prefix(int,		"0xA7", "%2i%i",     0, 0,  1, check_int);
615	test_number_prefix(short,	"0xA7", "%2hi%hi",   0, 0,  1, check_short);
616	test_number_prefix(char,	"0xA7", "%2hhi%hhi", 0, 0,  1, check_char);
617}
618
619#define _test_simple_strtoxx(T, fn, gen_fmt, expect, base)			\
620do {										\
621	T got;									\
622	char *endp;								\
623	int len;								\
624	bool fail = false;							\
625										\
626	total_tests++;								\
627	len = snprintf(test_buffer, BUF_SIZE, gen_fmt, expect);			\
628	got = (fn)(test_buffer, &endp, base);					\
629	pr_debug(#fn "(\"%s\", %d) -> " gen_fmt "\n", test_buffer, base, got);	\
630	if (got != (expect)) {							\
631		fail = true;							\
632		pr_warn(#fn "(\"%s\", %d): got " gen_fmt " expected " gen_fmt "\n", \
633			test_buffer, base, got, expect);			\
634	} else if (endp != test_buffer + len) {					\
635		fail = true;							\
636		pr_warn(#fn "(\"%s\", %d) startp=0x%px got endp=0x%px expected 0x%px\n", \
637			test_buffer, base, test_buffer,				\
638			test_buffer + len, endp);				\
639	}									\
640										\
641	if (fail)								\
642		failed_tests++;							\
643} while (0)
644
645#define test_simple_strtoxx(T, fn, gen_fmt, base)				\
646do {										\
647	int i;									\
648										\
649	for (i = 0; i < ARRAY_SIZE(numbers); i++) {				\
650		_test_simple_strtoxx(T, fn, gen_fmt, (T)numbers[i], base);	\
651										\
652		if (is_signed_type(T))						\
653			_test_simple_strtoxx(T, fn, gen_fmt,			\
654					      -(T)numbers[i], base);		\
655	}									\
656} while (0)
657
658static void __init test_simple_strtoull(void)
659{
660	test_simple_strtoxx(unsigned long long, simple_strtoull, "%llu",   10);
661	test_simple_strtoxx(unsigned long long, simple_strtoull, "%llu",   0);
662	test_simple_strtoxx(unsigned long long, simple_strtoull, "%llx",   16);
663	test_simple_strtoxx(unsigned long long, simple_strtoull, "0x%llx", 16);
664	test_simple_strtoxx(unsigned long long, simple_strtoull, "0x%llx", 0);
665}
666
667static void __init test_simple_strtoll(void)
668{
669	test_simple_strtoxx(long long, simple_strtoll, "%lld",	 10);
670	test_simple_strtoxx(long long, simple_strtoll, "%lld",	 0);
671	test_simple_strtoxx(long long, simple_strtoll, "%llx",	 16);
672	test_simple_strtoxx(long long, simple_strtoll, "0x%llx", 16);
673	test_simple_strtoxx(long long, simple_strtoll, "0x%llx", 0);
674}
675
676static void __init test_simple_strtoul(void)
677{
678	test_simple_strtoxx(unsigned long, simple_strtoul, "%lu",   10);
679	test_simple_strtoxx(unsigned long, simple_strtoul, "%lu",   0);
680	test_simple_strtoxx(unsigned long, simple_strtoul, "%lx",   16);
681	test_simple_strtoxx(unsigned long, simple_strtoul, "0x%lx", 16);
682	test_simple_strtoxx(unsigned long, simple_strtoul, "0x%lx", 0);
683}
684
685static void __init test_simple_strtol(void)
686{
687	test_simple_strtoxx(long, simple_strtol, "%ld",   10);
688	test_simple_strtoxx(long, simple_strtol, "%ld",   0);
689	test_simple_strtoxx(long, simple_strtol, "%lx",   16);
690	test_simple_strtoxx(long, simple_strtol, "0x%lx", 16);
691	test_simple_strtoxx(long, simple_strtol, "0x%lx", 0);
692}
693
694/* Selection of common delimiters/separators between numbers in a string. */
695static const char * const number_delimiters[] __initconst = {
696	" ", ":", ",", "-", "/",
697};
698
699static void __init test_numbers(void)
700{
701	int i;
702
703	/* String containing only one number. */
704	numbers_simple();
705
706	/* String with multiple numbers separated by delimiter. */
707	for (i = 0; i < ARRAY_SIZE(number_delimiters); i++) {
708		numbers_list(number_delimiters[i]);
709
710		/* Field width may be longer than actual field digits. */
711		numbers_list_field_width_typemax(number_delimiters[i]);
712
713		/* Each field width exactly length of actual field digits. */
714		numbers_list_field_width_val_width(number_delimiters[i]);
715	}
716
717	/* Slice continuous sequence of digits using field widths. */
718	numbers_slice();
719
720	numbers_prefix_overflow();
721}
722
723static void __init selftest(void)
724{
725	test_buffer = kmalloc(BUF_SIZE, GFP_KERNEL);
726	if (!test_buffer)
727		return;
728
729	fmt_buffer = kmalloc(BUF_SIZE, GFP_KERNEL);
730	if (!fmt_buffer) {
731		kfree(test_buffer);
732		return;
733	}
734
735	prandom_seed_state(&rnd_state, 3141592653589793238ULL);
736
737	test_numbers();
738
739	test_simple_strtoull();
740	test_simple_strtoll();
741	test_simple_strtoul();
742	test_simple_strtol();
743
744	kfree(fmt_buffer);
745	kfree(test_buffer);
746}
747
748KSTM_MODULE_LOADERS(test_scanf);
749MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
750MODULE_LICENSE("GPL v2");