| #include <linux/init.h> |
| #include <linux/kernel.h> |
| #include <linux/module.h> |
| |
| #define for_each_test(i, test) \ |
| for (i = 0; i < ARRAY_SIZE(test); i++) |
| |
| struct test_fail { |
| const char *str; |
| unsigned int base; |
| }; |
| |
| #define DEFINE_TEST_FAIL(test) \ |
| const struct test_fail test[] __initconst |
| |
| #define DECLARE_TEST_OK(type, test_type) \ |
| test_type { \ |
| const char *str; \ |
| unsigned int base; \ |
| type expected_res; \ |
| } |
| |
| #define DEFINE_TEST_OK(type, test) \ |
| const type test[] __initconst |
| |
| #define TEST_FAIL(fn, type, fmt, test) \ |
| { \ |
| unsigned int i; \ |
| \ |
| for_each_test(i, test) { \ |
| const struct test_fail *t = &test[i]; \ |
| type tmp; \ |
| int rv; \ |
| \ |
| tmp = 0; \ |
| rv = fn(t->str, t->base, &tmp); \ |
| if (rv >= 0) { \ |
| WARN(1, "str '%s', base %u, expected -E, got %d/" fmt "\n", \ |
| t->str, t->base, rv, tmp); \ |
| continue; \ |
| } \ |
| } \ |
| } |
| |
| #define TEST_OK(fn, type, fmt, test) \ |
| { \ |
| unsigned int i; \ |
| \ |
| for_each_test(i, test) { \ |
| const typeof(test[0]) *t = &test[i]; \ |
| type res; \ |
| int rv; \ |
| \ |
| rv = fn(t->str, t->base, &res); \ |
| if (rv != 0) { \ |
| WARN(1, "str '%s', base %u, expected 0/" fmt ", got %d\n", \ |
| t->str, t->base, t->expected_res, rv); \ |
| continue; \ |
| } \ |
| if (res != t->expected_res) { \ |
| WARN(1, "str '%s', base %u, expected " fmt ", got " fmt "\n", \ |
| t->str, t->base, t->expected_res, res); \ |
| continue; \ |
| } \ |
| } \ |
| } |
| |
| static void __init test_kstrtoull_ok(void) |
| { |
| DECLARE_TEST_OK(unsigned long long, struct test_ull); |
| static DEFINE_TEST_OK(struct test_ull, test_ull_ok) = { |
| {"0", 10, 0ULL}, |
| {"1", 10, 1ULL}, |
| {"127", 10, 127ULL}, |
| {"128", 10, 128ULL}, |
| {"129", 10, 129ULL}, |
| {"255", 10, 255ULL}, |
| {"256", 10, 256ULL}, |
| {"257", 10, 257ULL}, |
| {"32767", 10, 32767ULL}, |
| {"32768", 10, 32768ULL}, |
| {"32769", 10, 32769ULL}, |
| {"65535", 10, 65535ULL}, |
| {"65536", 10, 65536ULL}, |
| {"65537", 10, 65537ULL}, |
| {"2147483647", 10, 2147483647ULL}, |
| {"2147483648", 10, 2147483648ULL}, |
| {"2147483649", 10, 2147483649ULL}, |
| {"4294967295", 10, 4294967295ULL}, |
| {"4294967296", 10, 4294967296ULL}, |
| {"4294967297", 10, 4294967297ULL}, |
| {"9223372036854775807", 10, 9223372036854775807ULL}, |
| {"9223372036854775808", 10, 9223372036854775808ULL}, |
| {"9223372036854775809", 10, 9223372036854775809ULL}, |
| {"18446744073709551614", 10, 18446744073709551614ULL}, |
| {"18446744073709551615", 10, 18446744073709551615ULL}, |
| |
| {"00", 8, 00ULL}, |
| {"01", 8, 01ULL}, |
| {"0177", 8, 0177ULL}, |
| {"0200", 8, 0200ULL}, |
| {"0201", 8, 0201ULL}, |
| {"0377", 8, 0377ULL}, |
| {"0400", 8, 0400ULL}, |
| {"0401", 8, 0401ULL}, |
| {"077777", 8, 077777ULL}, |
| {"0100000", 8, 0100000ULL}, |
| {"0100001", 8, 0100001ULL}, |
| {"0177777", 8, 0177777ULL}, |
| {"0200000", 8, 0200000ULL}, |
| {"0200001", 8, 0200001ULL}, |
| {"017777777777", 8, 017777777777ULL}, |
| {"020000000000", 8, 020000000000ULL}, |
| {"020000000001", 8, 020000000001ULL}, |
| {"037777777777", 8, 037777777777ULL}, |
| {"040000000000", 8, 040000000000ULL}, |
| {"040000000001", 8, 040000000001ULL}, |
| {"0777777777777777777777", 8, 0777777777777777777777ULL}, |
| {"01000000000000000000000", 8, 01000000000000000000000ULL}, |
| {"01000000000000000000001", 8, 01000000000000000000001ULL}, |
| {"01777777777777777777776", 8, 01777777777777777777776ULL}, |
| {"01777777777777777777777", 8, 01777777777777777777777ULL}, |
| |
| {"0x0", 16, 0x0ULL}, |
| {"0x1", 16, 0x1ULL}, |
| {"0x7f", 16, 0x7fULL}, |
| {"0x80", 16, 0x80ULL}, |
| {"0x81", 16, 0x81ULL}, |
| {"0xff", 16, 0xffULL}, |
| {"0x100", 16, 0x100ULL}, |
| {"0x101", 16, 0x101ULL}, |
| {"0x7fff", 16, 0x7fffULL}, |
| {"0x8000", 16, 0x8000ULL}, |
| {"0x8001", 16, 0x8001ULL}, |
| {"0xffff", 16, 0xffffULL}, |
| {"0x10000", 16, 0x10000ULL}, |
| {"0x10001", 16, 0x10001ULL}, |
| {"0x7fffffff", 16, 0x7fffffffULL}, |
| {"0x80000000", 16, 0x80000000ULL}, |
| {"0x80000001", 16, 0x80000001ULL}, |
| {"0xffffffff", 16, 0xffffffffULL}, |
| {"0x100000000", 16, 0x100000000ULL}, |
| {"0x100000001", 16, 0x100000001ULL}, |
| {"0x7fffffffffffffff", 16, 0x7fffffffffffffffULL}, |
| {"0x8000000000000000", 16, 0x8000000000000000ULL}, |
| {"0x8000000000000001", 16, 0x8000000000000001ULL}, |
| {"0xfffffffffffffffe", 16, 0xfffffffffffffffeULL}, |
| {"0xffffffffffffffff", 16, 0xffffffffffffffffULL}, |
| |
| {"0\n", 0, 0ULL}, |
| }; |
| TEST_OK(kstrtoull, unsigned long long, "%llu", test_ull_ok); |
| } |
| |
| static void __init test_kstrtoull_fail(void) |
| { |
| static DEFINE_TEST_FAIL(test_ull_fail) = { |
| {"", 0}, |
| {"", 8}, |
| {"", 10}, |
| {"", 16}, |
| {"\n", 0}, |
| {"\n", 8}, |
| {"\n", 10}, |
| {"\n", 16}, |
| {"\n0", 0}, |
| {"\n0", 8}, |
| {"\n0", 10}, |
| {"\n0", 16}, |
| {"+", 0}, |
| {"+", 8}, |
| {"+", 10}, |
| {"+", 16}, |
| {"-", 0}, |
| {"-", 8}, |
| {"-", 10}, |
| {"-", 16}, |
| {"0x", 0}, |
| {"0x", 16}, |
| {"0X", 0}, |
| {"0X", 16}, |
| {"0 ", 0}, |
| {"1+", 0}, |
| {"1-", 0}, |
| {" 2", 0}, |
| /* base autodetection */ |
| {"0x0z", 0}, |
| {"0z", 0}, |
| {"a", 0}, |
| /* digit >= base */ |
| {"2", 2}, |
| {"8", 8}, |
| {"a", 10}, |
| {"A", 10}, |
| {"g", 16}, |
| {"G", 16}, |
| /* overflow */ |
| {"10000000000000000000000000000000000000000000000000000000000000000", 2}, |
| {"2000000000000000000000", 8}, |
| {"18446744073709551616", 10}, |
| {"569202370375329612767", 10}, |
| {"10000000000000000", 16}, |
| /* negative */ |
| {"-0", 0}, |
| {"-0", 8}, |
| {"-0", 10}, |
| {"-0", 16}, |
| {"-1", 0}, |
| {"-1", 8}, |
| {"-1", 10}, |
| {"-1", 16}, |
| /* sign is first character if any */ |
| {"-+1", 0}, |
| {"-+1", 8}, |
| {"-+1", 10}, |
| {"-+1", 16}, |
| /* nothing after \n */ |
| {"0\n0", 0}, |
| {"0\n0", 8}, |
| {"0\n0", 10}, |
| {"0\n0", 16}, |
| {"0\n+", 0}, |
| {"0\n+", 8}, |
| {"0\n+", 10}, |
| {"0\n+", 16}, |
| {"0\n-", 0}, |
| {"0\n-", 8}, |
| {"0\n-", 10}, |
| {"0\n-", 16}, |
| {"0\n ", 0}, |
| {"0\n ", 8}, |
| {"0\n ", 10}, |
| {"0\n ", 16}, |
| }; |
| TEST_FAIL(kstrtoull, unsigned long long, "%llu", test_ull_fail); |
| } |
| |
| static void __init test_kstrtoll_ok(void) |
| { |
| DECLARE_TEST_OK(long long, struct test_ll); |
| static DEFINE_TEST_OK(struct test_ll, test_ll_ok) = { |
| {"0", 10, 0LL}, |
| {"1", 10, 1LL}, |
| {"127", 10, 127LL}, |
| {"128", 10, 128LL}, |
| {"129", 10, 129LL}, |
| {"255", 10, 255LL}, |
| {"256", 10, 256LL}, |
| {"257", 10, 257LL}, |
| {"32767", 10, 32767LL}, |
| {"32768", 10, 32768LL}, |
| {"32769", 10, 32769LL}, |
| {"65535", 10, 65535LL}, |
| {"65536", 10, 65536LL}, |
| {"65537", 10, 65537LL}, |
| {"2147483647", 10, 2147483647LL}, |
| {"2147483648", 10, 2147483648LL}, |
| {"2147483649", 10, 2147483649LL}, |
| {"4294967295", 10, 4294967295LL}, |
| {"4294967296", 10, 4294967296LL}, |
| {"4294967297", 10, 4294967297LL}, |
| {"9223372036854775807", 10, 9223372036854775807LL}, |
| |
| {"-0", 10, 0LL}, |
| {"-1", 10, -1LL}, |
| {"-2", 10, -2LL}, |
| {"-9223372036854775808", 10, LLONG_MIN}, |
| }; |
| TEST_OK(kstrtoll, long long, "%lld", test_ll_ok); |
| } |
| |
| static void __init test_kstrtoll_fail(void) |
| { |
| static DEFINE_TEST_FAIL(test_ll_fail) = { |
| {"9223372036854775808", 10}, |
| {"9223372036854775809", 10}, |
| {"18446744073709551614", 10}, |
| {"18446744073709551615", 10}, |
| {"569202370375329612767", 10}, |
| {"-9223372036854775809", 10}, |
| {"-18446744073709551614", 10}, |
| {"-18446744073709551615", 10}, |
| {"-569202370375329612767", 10}, |
| /* sign is first character if any */ |
| {"-+1", 0}, |
| {"-+1", 8}, |
| {"-+1", 10}, |
| {"-+1", 16}, |
| }; |
| TEST_FAIL(kstrtoll, long long, "%lld", test_ll_fail); |
| } |
| |
| static void __init test_kstrtou64_ok(void) |
| { |
| DECLARE_TEST_OK(u64, struct test_u64); |
| static DEFINE_TEST_OK(struct test_u64, test_u64_ok) = { |
| {"0", 10, 0}, |
| {"1", 10, 1}, |
| {"126", 10, 126}, |
| {"127", 10, 127}, |
| {"128", 10, 128}, |
| {"129", 10, 129}, |
| {"254", 10, 254}, |
| {"255", 10, 255}, |
| {"256", 10, 256}, |
| {"257", 10, 257}, |
| {"32766", 10, 32766}, |
| {"32767", 10, 32767}, |
| {"32768", 10, 32768}, |
| {"32769", 10, 32769}, |
| {"65534", 10, 65534}, |
| {"65535", 10, 65535}, |
| {"65536", 10, 65536}, |
| {"65537", 10, 65537}, |
| {"2147483646", 10, 2147483646}, |
| {"2147483647", 10, 2147483647}, |
| {"2147483648", 10, 2147483648ULL}, |
| {"2147483649", 10, 2147483649ULL}, |
| {"4294967294", 10, 4294967294ULL}, |
| {"4294967295", 10, 4294967295ULL}, |
| {"4294967296", 10, 4294967296ULL}, |
| {"4294967297", 10, 4294967297ULL}, |
| {"9223372036854775806", 10, 9223372036854775806ULL}, |
| {"9223372036854775807", 10, 9223372036854775807ULL}, |
| {"9223372036854775808", 10, 9223372036854775808ULL}, |
| {"9223372036854775809", 10, 9223372036854775809ULL}, |
| {"18446744073709551614", 10, 18446744073709551614ULL}, |
| {"18446744073709551615", 10, 18446744073709551615ULL}, |
| }; |
| TEST_OK(kstrtou64, u64, "%llu", test_u64_ok); |
| } |
| |
| static void __init test_kstrtou64_fail(void) |
| { |
| static DEFINE_TEST_FAIL(test_u64_fail) = { |
| {"-2", 10}, |
| {"-1", 10}, |
| {"18446744073709551616", 10}, |
| {"18446744073709551617", 10}, |
| {"569202370375329612767", 10}, |
| }; |
| TEST_FAIL(kstrtou64, u64, "%llu", test_u64_fail); |
| } |
| |
| static void __init test_kstrtos64_ok(void) |
| { |
| DECLARE_TEST_OK(s64, struct test_s64); |
| static DEFINE_TEST_OK(struct test_s64, test_s64_ok) = { |
| {"-128", 10, -128}, |
| {"-127", 10, -127}, |
| {"-1", 10, -1}, |
| {"0", 10, 0}, |
| {"1", 10, 1}, |
| {"126", 10, 126}, |
| {"127", 10, 127}, |
| {"128", 10, 128}, |
| {"129", 10, 129}, |
| {"254", 10, 254}, |
| {"255", 10, 255}, |
| {"256", 10, 256}, |
| {"257", 10, 257}, |
| {"32766", 10, 32766}, |
| {"32767", 10, 32767}, |
| {"32768", 10, 32768}, |
| {"32769", 10, 32769}, |
| {"65534", 10, 65534}, |
| {"65535", 10, 65535}, |
| {"65536", 10, 65536}, |
| {"65537", 10, 65537}, |
| {"2147483646", 10, 2147483646}, |
| {"2147483647", 10, 2147483647}, |
| {"2147483648", 10, 2147483648LL}, |
| {"2147483649", 10, 2147483649LL}, |
| {"4294967294", 10, 4294967294LL}, |
| {"4294967295", 10, 4294967295LL}, |
| {"4294967296", 10, 4294967296LL}, |
| {"4294967297", 10, 4294967297LL}, |
| {"9223372036854775806", 10, 9223372036854775806LL}, |
| {"9223372036854775807", 10, 9223372036854775807LL}, |
| }; |
| TEST_OK(kstrtos64, s64, "%lld", test_s64_ok); |
| } |
| |
| static void __init test_kstrtos64_fail(void) |
| { |
| static DEFINE_TEST_FAIL(test_s64_fail) = { |
| {"9223372036854775808", 10}, |
| {"9223372036854775809", 10}, |
| {"18446744073709551614", 10}, |
| {"18446744073709551615", 10}, |
| {"18446744073709551616", 10}, |
| {"18446744073709551617", 10}, |
| {"569202370375329612767", 10}, |
| {"-569202370375329612767", 10}, |
| }; |
| TEST_FAIL(kstrtos64, s64, "%lld", test_s64_fail); |
| } |
| |
| static void __init test_kstrtou32_ok(void) |
| { |
| DECLARE_TEST_OK(u32, struct test_u32); |
| static DEFINE_TEST_OK(struct test_u32, test_u32_ok) = { |
| {"0", 10, 0}, |
| {"1", 10, 1}, |
| {"126", 10, 126}, |
| {"127", 10, 127}, |
| {"128", 10, 128}, |
| {"129", 10, 129}, |
| {"254", 10, 254}, |
| {"255", 10, 255}, |
| {"256", 10, 256}, |
| {"257", 10, 257}, |
| {"32766", 10, 32766}, |
| {"32767", 10, 32767}, |
| {"32768", 10, 32768}, |
| {"32769", 10, 32769}, |
| {"65534", 10, 65534}, |
| {"65535", 10, 65535}, |
| {"65536", 10, 65536}, |
| {"65537", 10, 65537}, |
| {"2147483646", 10, 2147483646}, |
| {"2147483647", 10, 2147483647}, |
| {"2147483648", 10, 2147483648U}, |
| {"2147483649", 10, 2147483649U}, |
| {"4294967294", 10, 4294967294U}, |
| {"4294967295", 10, 4294967295U}, |
| }; |
| TEST_OK(kstrtou32, u32, "%u", test_u32_ok); |
| } |
| |
| static void __init test_kstrtou32_fail(void) |
| { |
| static DEFINE_TEST_FAIL(test_u32_fail) = { |
| {"-2", 10}, |
| {"-1", 10}, |
| {"4294967296", 10}, |
| {"4294967297", 10}, |
| {"9223372036854775806", 10}, |
| {"9223372036854775807", 10}, |
| {"9223372036854775808", 10}, |
| {"9223372036854775809", 10}, |
| {"18446744073709551614", 10}, |
| {"18446744073709551615", 10}, |
| {"18446744073709551616", 10}, |
| {"18446744073709551617", 10}, |
| }; |
| TEST_FAIL(kstrtou32, u32, "%u", test_u32_fail); |
| } |
| |
| static void __init test_kstrtos32_ok(void) |
| { |
| DECLARE_TEST_OK(s32, struct test_s32); |
| static DEFINE_TEST_OK(struct test_s32, test_s32_ok) = { |
| {"-128", 10, -128}, |
| {"-127", 10, -127}, |
| {"-1", 10, -1}, |
| {"0", 10, 0}, |
| {"1", 10, 1}, |
| {"126", 10, 126}, |
| {"127", 10, 127}, |
| {"128", 10, 128}, |
| {"129", 10, 129}, |
| {"254", 10, 254}, |
| {"255", 10, 255}, |
| {"256", 10, 256}, |
| {"257", 10, 257}, |
| {"32766", 10, 32766}, |
| {"32767", 10, 32767}, |
| {"32768", 10, 32768}, |
| {"32769", 10, 32769}, |
| {"65534", 10, 65534}, |
| {"65535", 10, 65535}, |
| {"65536", 10, 65536}, |
| {"65537", 10, 65537}, |
| {"2147483646", 10, 2147483646}, |
| {"2147483647", 10, 2147483647}, |
| }; |
| TEST_OK(kstrtos32, s32, "%d", test_s32_ok); |
| } |
| |
| static void __init test_kstrtos32_fail(void) |
| { |
| static DEFINE_TEST_FAIL(test_s32_fail) = { |
| {"2147483648", 10}, |
| {"2147483649", 10}, |
| {"4294967294", 10}, |
| {"4294967295", 10}, |
| {"4294967296", 10}, |
| {"4294967297", 10}, |
| {"9223372036854775806", 10}, |
| {"9223372036854775807", 10}, |
| {"9223372036854775808", 10}, |
| {"9223372036854775809", 10}, |
| {"18446744073709551614", 10}, |
| {"18446744073709551615", 10}, |
| {"18446744073709551616", 10}, |
| {"18446744073709551617", 10}, |
| }; |
| TEST_FAIL(kstrtos32, s32, "%d", test_s32_fail); |
| } |
| |
| static void __init test_kstrtou16_ok(void) |
| { |
| DECLARE_TEST_OK(u16, struct test_u16); |
| static DEFINE_TEST_OK(struct test_u16, test_u16_ok) = { |
| {"0", 10, 0}, |
| {"1", 10, 1}, |
| {"126", 10, 126}, |
| {"127", 10, 127}, |
| {"128", 10, 128}, |
| {"129", 10, 129}, |
| {"254", 10, 254}, |
| {"255", 10, 255}, |
| {"256", 10, 256}, |
| {"257", 10, 257}, |
| {"32766", 10, 32766}, |
| {"32767", 10, 32767}, |
| {"32768", 10, 32768}, |
| {"32769", 10, 32769}, |
| {"65534", 10, 65534}, |
| {"65535", 10, 65535}, |
| }; |
| TEST_OK(kstrtou16, u16, "%hu", test_u16_ok); |
| } |
| |
| static void __init test_kstrtou16_fail(void) |
| { |
| static DEFINE_TEST_FAIL(test_u16_fail) = { |
| {"-2", 10}, |
| {"-1", 10}, |
| {"65536", 10}, |
| {"65537", 10}, |
| {"2147483646", 10}, |
| {"2147483647", 10}, |
| {"2147483648", 10}, |
| {"2147483649", 10}, |
| {"4294967294", 10}, |
| {"4294967295", 10}, |
| {"4294967296", 10}, |
| {"4294967297", 10}, |
| {"9223372036854775806", 10}, |
| {"9223372036854775807", 10}, |
| {"9223372036854775808", 10}, |
| {"9223372036854775809", 10}, |
| {"18446744073709551614", 10}, |
| {"18446744073709551615", 10}, |
| {"18446744073709551616", 10}, |
| {"18446744073709551617", 10}, |
| }; |
| TEST_FAIL(kstrtou16, u16, "%hu", test_u16_fail); |
| } |
| |
| static void __init test_kstrtos16_ok(void) |
| { |
| DECLARE_TEST_OK(s16, struct test_s16); |
| static DEFINE_TEST_OK(struct test_s16, test_s16_ok) = { |
| {"-130", 10, -130}, |
| {"-129", 10, -129}, |
| {"-128", 10, -128}, |
| {"-127", 10, -127}, |
| {"-1", 10, -1}, |
| {"0", 10, 0}, |
| {"1", 10, 1}, |
| {"126", 10, 126}, |
| {"127", 10, 127}, |
| {"128", 10, 128}, |
| {"129", 10, 129}, |
| {"254", 10, 254}, |
| {"255", 10, 255}, |
| {"256", 10, 256}, |
| {"257", 10, 257}, |
| {"32766", 10, 32766}, |
| {"32767", 10, 32767}, |
| }; |
| TEST_OK(kstrtos16, s16, "%hd", test_s16_ok); |
| } |
| |
| static void __init test_kstrtos16_fail(void) |
| { |
| static DEFINE_TEST_FAIL(test_s16_fail) = { |
| {"32768", 10}, |
| {"32769", 10}, |
| {"65534", 10}, |
| {"65535", 10}, |
| {"65536", 10}, |
| {"65537", 10}, |
| {"2147483646", 10}, |
| {"2147483647", 10}, |
| {"2147483648", 10}, |
| {"2147483649", 10}, |
| {"4294967294", 10}, |
| {"4294967295", 10}, |
| {"4294967296", 10}, |
| {"4294967297", 10}, |
| {"9223372036854775806", 10}, |
| {"9223372036854775807", 10}, |
| {"9223372036854775808", 10}, |
| {"9223372036854775809", 10}, |
| {"18446744073709551614", 10}, |
| {"18446744073709551615", 10}, |
| {"18446744073709551616", 10}, |
| {"18446744073709551617", 10}, |
| }; |
| TEST_FAIL(kstrtos16, s16, "%hd", test_s16_fail); |
| } |
| |
| static void __init test_kstrtou8_ok(void) |
| { |
| DECLARE_TEST_OK(u8, struct test_u8); |
| static DEFINE_TEST_OK(struct test_u8, test_u8_ok) = { |
| {"0", 10, 0}, |
| {"1", 10, 1}, |
| {"126", 10, 126}, |
| {"127", 10, 127}, |
| {"128", 10, 128}, |
| {"129", 10, 129}, |
| {"254", 10, 254}, |
| {"255", 10, 255}, |
| }; |
| TEST_OK(kstrtou8, u8, "%hhu", test_u8_ok); |
| } |
| |
| static void __init test_kstrtou8_fail(void) |
| { |
| static DEFINE_TEST_FAIL(test_u8_fail) = { |
| {"-2", 10}, |
| {"-1", 10}, |
| {"256", 10}, |
| {"257", 10}, |
| {"32766", 10}, |
| {"32767", 10}, |
| {"32768", 10}, |
| {"32769", 10}, |
| {"65534", 10}, |
| {"65535", 10}, |
| {"65536", 10}, |
| {"65537", 10}, |
| {"2147483646", 10}, |
| {"2147483647", 10}, |
| {"2147483648", 10}, |
| {"2147483649", 10}, |
| {"4294967294", 10}, |
| {"4294967295", 10}, |
| {"4294967296", 10}, |
| {"4294967297", 10}, |
| {"9223372036854775806", 10}, |
| {"9223372036854775807", 10}, |
| {"9223372036854775808", 10}, |
| {"9223372036854775809", 10}, |
| {"18446744073709551614", 10}, |
| {"18446744073709551615", 10}, |
| {"18446744073709551616", 10}, |
| {"18446744073709551617", 10}, |
| }; |
| TEST_FAIL(kstrtou8, u8, "%hhu", test_u8_fail); |
| } |
| |
| static void __init test_kstrtos8_ok(void) |
| { |
| DECLARE_TEST_OK(s8, struct test_s8); |
| static DEFINE_TEST_OK(struct test_s8, test_s8_ok) = { |
| {"-128", 10, -128}, |
| {"-127", 10, -127}, |
| {"-1", 10, -1}, |
| {"0", 10, 0}, |
| {"1", 10, 1}, |
| {"126", 10, 126}, |
| {"127", 10, 127}, |
| }; |
| TEST_OK(kstrtos8, s8, "%hhd", test_s8_ok); |
| } |
| |
| static void __init test_kstrtos8_fail(void) |
| { |
| static DEFINE_TEST_FAIL(test_s8_fail) = { |
| {"-130", 10}, |
| {"-129", 10}, |
| {"128", 10}, |
| {"129", 10}, |
| {"254", 10}, |
| {"255", 10}, |
| {"256", 10}, |
| {"257", 10}, |
| {"32766", 10}, |
| {"32767", 10}, |
| {"32768", 10}, |
| {"32769", 10}, |
| {"65534", 10}, |
| {"65535", 10}, |
| {"65536", 10}, |
| {"65537", 10}, |
| {"2147483646", 10}, |
| {"2147483647", 10}, |
| {"2147483648", 10}, |
| {"2147483649", 10}, |
| {"4294967294", 10}, |
| {"4294967295", 10}, |
| {"4294967296", 10}, |
| {"4294967297", 10}, |
| {"9223372036854775806", 10}, |
| {"9223372036854775807", 10}, |
| {"9223372036854775808", 10}, |
| {"9223372036854775809", 10}, |
| {"18446744073709551614", 10}, |
| {"18446744073709551615", 10}, |
| {"18446744073709551616", 10}, |
| {"18446744073709551617", 10}, |
| }; |
| TEST_FAIL(kstrtos8, s8, "%hhd", test_s8_fail); |
| } |
| |
| static void __init test_kstrtoudec64_ok(void) |
| { |
| DECLARE_TEST_OK(u64, struct test_udec64); |
| static DEFINE_TEST_OK(struct test_udec64, test_udec64_ok) = { |
| /* basic: integer.fraction, exact digits */ |
| {"0.0", 1, 0}, |
| {"1.5", 1, 15}, |
| {"1.234", 3, 1234}, |
| {"42.0", 1, 420}, |
| /* zero */ |
| {"0.0", 1, 0}, |
| {"0.000", 3, 0}, |
| /* integer only */ |
| {"0", 1, 0}, |
| {"42", 3, 42000}, |
| {"123.", 2, 12300}, |
| {"1", 1, 10}, |
| /* fractional only (leading dot) */ |
| {".5", 1, 5}, |
| {".5", 0, 0}, |
| {".123", 3, 123}, |
| {".001", 3, 1}, |
| /* zero padding: fewer fractional digits than scale */ |
| {"1.2", 3, 1200}, |
| {"1.2", 6, 1200000}, |
| {"0.01", 3, 10}, |
| {"0.1", 9, 100000000ULL}, |
| {"0.01", 9, 10000000}, |
| /* truncation: more fractional digits than scale */ |
| {"1.23456", 3, 1234}, |
| {"3.1415926535", 6, 3141592}, |
| {"0.999999999", 3, 999}, |
| {"1.99", 1, 19}, |
| {"1.234", 0, 1}, |
| /* trailing newline */ |
| {"1.5\n", 1, 15}, |
| {"42\n", 3, 42000}, |
| /* plus sign */ |
| {"+1.5", 1, 15}, |
| {"+.5", 1, 5}, |
| /* scale progression */ |
| {"1.", 0, 1}, |
| {"1.0", 1, 10}, |
| {"1.00", 2, 100}, |
| {"1.000", 3, 1000}, |
| {"1.000000", 6, 1000000}, |
| {"1.000000000", 9, 1000000000ULL}, |
| /* max limit check */ |
| {"18446744073.709551615", 9, ULLONG_MAX}, |
| {"18446744073709.551615", 6, ULLONG_MAX}, |
| {"0.18446744073709551615", 20, ULLONG_MAX}, |
| /* scale > 19: representable when integer part is small */ |
| {"0.00000000000000000001", 20, 1}, |
| {"0.1", 20, 10000000000000000000ULL}, |
| {"0.00000000000000000000001", 23, 1}, |
| /* truncation with scale > 19 */ |
| {"0.0000000000000000000012345", 23, 123}, |
| /* truncation with many excess digits */ |
| {"0.00000000000000000000000000000000423", 34, 42}, |
| {"1.99999999999999999999999999999999999", 3, 1999}, |
| }; |
| TEST_OK(kstrtoudec64, u64, "%llu", test_udec64_ok); |
| } |
| |
| static void __init test_kstrtoudec64_fail(void) |
| { |
| static DEFINE_TEST_FAIL(test_udec64_fail) = { |
| /* empty / whitespace */ |
| {"", 3}, |
| {"\n", 3}, |
| /* minus sign (unsigned) */ |
| {"-1.5", 1}, |
| {"-0.5", 1}, |
| /* only a decimal point */ |
| {".", 3}, |
| {".", 0}, |
| /* only a sign */ |
| {"+", 3}, |
| /* non-digit characters */ |
| {"abc", 3}, |
| {"1.2x", 3}, |
| /* leading/trailing space */ |
| {" 1.5", 1}, |
| {"1.5 ", 1}, |
| /* overflow */ |
| {"18446744073710.551615", 6}, |
| {"99999999999999999999", 1}, |
| /* overflow with scale > 19 */ |
| {"1.0", 21}, |
| {"0.2", 20}, |
| {"0.18446744073709551616", 20}, |
| {"1", 20}, |
| }; |
| TEST_FAIL(kstrtoudec64, u64, "%llu", test_udec64_fail); |
| } |
| |
| static void __init test_kstrtodec64_ok(void) |
| { |
| DECLARE_TEST_OK(s64, struct test_dec64); |
| static DEFINE_TEST_OK(struct test_dec64, test_dec64_ok) = { |
| /* basic positive */ |
| {"0.0", 1, 0}, |
| {"1.5", 1, 15}, |
| {"1.234", 3, 1234}, |
| /* basic negative */ |
| {"-1.5", 1, -15}, |
| {"-1.234", 3, -1234}, |
| {"-0.5", 1, -5}, |
| {"-0.001", 3, -1}, |
| /* zero (signed) */ |
| {"-0", 1, 0}, |
| {"-0.0", 1, 0}, |
| {"0.000", 3, 0}, |
| /* integer only */ |
| {"42", 3, 42000}, |
| {"-42", 3, -42000}, |
| /* fractional only */ |
| {".5", 1, 5}, |
| {"-.5", 1, -5}, |
| /* zero padding */ |
| {"1.2", 3, 1200}, |
| {"-1.2", 3, -1200}, |
| {"0.01", 3, 10}, |
| {"-0.01", 3, -10}, |
| /* truncation */ |
| {"1.23456", 3, 1234}, |
| {"-1.23456", 3, -1234}, |
| {"0.999999999", 3, 999}, |
| {"-0.999999999", 3, -999}, |
| /* trailing newline */ |
| {"1.5\n", 1, 15}, |
| {"-1.5\n", 1, -15}, |
| /* plus sign */ |
| {"+1.5", 1, 15}, |
| /* limits */ |
| {"9223372036.854775807", 9, LLONG_MAX}, |
| {"-9223372036.854775808", 9, LLONG_MIN}, |
| /* scale > 19 */ |
| {"0.0", 20, 0}, |
| {"-0.0", 20, 0}, |
| {"0.00000000000000000001", 20, 1}, |
| {"-0.00000000000000000001", 20, -1}, |
| {"0.009223372036854775807", 21, LLONG_MAX}, |
| {"-0.009223372036854775808", 21, LLONG_MIN}, |
| }; |
| TEST_OK(kstrtodec64, s64, "%lld", test_dec64_ok); |
| } |
| |
| static void __init test_kstrtodec64_fail(void) |
| { |
| static DEFINE_TEST_FAIL(test_dec64_fail) = { |
| /* empty / whitespace */ |
| {"", 3}, |
| {"\n", 3}, |
| /* no digits after dot */ |
| {".", 3}, |
| {"-.", 3}, |
| /* no digits at all */ |
| {"+", 3}, |
| {"-", 3}, |
| /* non-digit characters */ |
| {"abc", 3}, |
| {"-1.2x", 3}, |
| /* signed overflow */ |
| {"9223372036.854775808", 9}, |
| {"-9223372036.854775809", 9}, |
| {"99999999999999999999", 1}, |
| /* signed overflow with scale > 19 */ |
| {"0.1", 20}, |
| {"-0.1", 20}, |
| {"0.09223372036854775808", 20}, |
| {"-0.09223372036854775809", 20}, |
| }; |
| TEST_FAIL(kstrtodec64, s64, "%lld", test_dec64_fail); |
| } |
| |
| static int __init test_kstrtox_init(void) |
| { |
| test_kstrtoull_ok(); |
| test_kstrtoull_fail(); |
| test_kstrtoll_ok(); |
| test_kstrtoll_fail(); |
| |
| test_kstrtou64_ok(); |
| test_kstrtou64_fail(); |
| test_kstrtos64_ok(); |
| test_kstrtos64_fail(); |
| |
| test_kstrtou32_ok(); |
| test_kstrtou32_fail(); |
| test_kstrtos32_ok(); |
| test_kstrtos32_fail(); |
| |
| test_kstrtou16_ok(); |
| test_kstrtou16_fail(); |
| test_kstrtos16_ok(); |
| test_kstrtos16_fail(); |
| |
| test_kstrtou8_ok(); |
| test_kstrtou8_fail(); |
| test_kstrtos8_ok(); |
| test_kstrtos8_fail(); |
| |
| test_kstrtoudec64_ok(); |
| test_kstrtoudec64_fail(); |
| test_kstrtodec64_ok(); |
| test_kstrtodec64_fail(); |
| |
| return -EINVAL; |
| } |
| module_init(test_kstrtox_init); |
| MODULE_DESCRIPTION("Module test for kstrto*() APIs"); |
| MODULE_LICENSE("Dual BSD/GPL"); |