2 * Convert integer string representation to an integer.
3 * If an integer doesn't fit into specified type, -E is returned.
5 * Integer starts with optional sign.
6 * kstrtou*() functions do not accept sign "-".
8 * Radix 0 means autodetection: leading "0x" implies radix 16,
9 * leading "0" implies radix 8, otherwise radix is 10.
10 * Autodetection hints work after optional sign, but not before.
12 * If -E is returned, result is not touched.
14 #include <linux/kernel.h>
16 #ifndef CONFIG_COMPAT_IS_KSTRTOX
18 * kstrto* was included in kernel 2.6.38.4 and causes conflicts with the
19 * version included in compat-wireless. We use strict_strtol to check if
20 * kstrto* is already available.
22 #ifndef strict_strtoll
24 #include <linux/ctype.h>
25 #include <linux/errno.h>
26 #include <linux/kernel.h>
27 #include <linux/math64.h>
28 #include <linux/module.h>
29 #include <linux/types.h>
31 static inline char _tolower(const char c)
36 static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
38 unsigned long long acc;
43 if (_tolower(s[1]) == 'x' && isxdigit(s[2]))
50 if (base == 16 && s[0] == '0' && _tolower(s[1]) == 'x')
58 if ('0' <= *s && *s <= '9')
60 else if ('a' <= _tolower(*s) && _tolower(*s) <= 'f')
61 val = _tolower(*s) - 'a' + 10;
62 else if (*s == '\n') {
72 if (acc > div_u64(ULLONG_MAX - val, base))
74 acc = acc * base + val;
85 int kstrtoull(const char *s, unsigned int base, unsigned long long *res)
89 return _kstrtoull(s, base, res);
91 EXPORT_SYMBOL_GPL(kstrtoull);
93 int kstrtoll(const char *s, unsigned int base, long long *res)
95 unsigned long long tmp;
99 rv = _kstrtoull(s + 1, base, &tmp);
102 if ((long long)(-tmp) >= 0)
106 rv = kstrtoull(s, base, &tmp);
109 if ((long long)tmp < 0)
115 EXPORT_SYMBOL_GPL(kstrtoll);
117 /* Internal, do not use. */
118 int _kstrtoul(const char *s, unsigned int base, unsigned long *res)
120 unsigned long long tmp;
123 rv = kstrtoull(s, base, &tmp);
126 if (tmp != (unsigned long long)(unsigned long)tmp)
131 EXPORT_SYMBOL_GPL(_kstrtoul);
133 /* Internal, do not use. */
134 int _kstrtol(const char *s, unsigned int base, long *res)
139 rv = kstrtoll(s, base, &tmp);
142 if (tmp != (long long)(long)tmp)
147 EXPORT_SYMBOL_GPL(_kstrtol);
149 int kstrtouint(const char *s, unsigned int base, unsigned int *res)
151 unsigned long long tmp;
154 rv = kstrtoull(s, base, &tmp);
157 if (tmp != (unsigned long long)(unsigned int)tmp)
162 EXPORT_SYMBOL_GPL(kstrtouint);
164 int kstrtoint(const char *s, unsigned int base, int *res)
169 rv = kstrtoll(s, base, &tmp);
172 if (tmp != (long long)(int)tmp)
177 EXPORT_SYMBOL_GPL(kstrtoint);
179 int kstrtou16(const char *s, unsigned int base, u16 *res)
181 unsigned long long tmp;
184 rv = kstrtoull(s, base, &tmp);
187 if (tmp != (unsigned long long)(u16)tmp)
192 EXPORT_SYMBOL_GPL(kstrtou16);
194 int kstrtos16(const char *s, unsigned int base, s16 *res)
199 rv = kstrtoll(s, base, &tmp);
202 if (tmp != (long long)(s16)tmp)
207 EXPORT_SYMBOL_GPL(kstrtos16);
209 int kstrtou8(const char *s, unsigned int base, u8 *res)
211 unsigned long long tmp;
214 rv = kstrtoull(s, base, &tmp);
217 if (tmp != (unsigned long long)(u8)tmp)
222 EXPORT_SYMBOL_GPL(kstrtou8);
224 int kstrtos8(const char *s, unsigned int base, s8 *res)
229 rv = kstrtoll(s, base, &tmp);
232 if (tmp != (long long)(s8)tmp)
237 EXPORT_SYMBOL_GPL(kstrtos8);
238 #endif /* #ifndef strict_strtol */
239 #endif /* #ifndef CONFIG_COMPAT_IS_KSTRTOX */