]> git.sesse.net Git - bcachefs-tools-debian/blob - linux/kstrtox.c
bcache in userspace; userspace fsck
[bcachefs-tools-debian] / linux / kstrtox.c
1 /*
2  * Convert integer string representation to an integer.
3  * If an integer doesn't fit into specified type, -E is returned.
4  *
5  * Integer starts with optional sign.
6  * kstrtou*() functions do not accept sign "-".
7  *
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.
11  *
12  * If -E is returned, result is not touched.
13  */
14 #include <linux/ctype.h>
15 #include <linux/errno.h>
16 #include <linux/kernel.h>
17 #include <linux/math64.h>
18 #include <linux/export.h>
19 #include <linux/types.h>
20 #include "kstrtox.h"
21
22 const char *_parse_integer_fixup_radix(const char *s, unsigned int *base)
23 {
24         if (*base == 0) {
25                 if (s[0] == '0') {
26                         if (_tolower(s[1]) == 'x' && isxdigit(s[2]))
27                                 *base = 16;
28                         else
29                                 *base = 8;
30                 } else
31                         *base = 10;
32         }
33         if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x')
34                 s += 2;
35         return s;
36 }
37
38 /*
39  * Convert non-negative integer string representation in explicitly given radix
40  * to an integer.
41  * Return number of characters consumed maybe or-ed with overflow bit.
42  * If overflow occurs, result integer (incorrect) is still returned.
43  *
44  * Don't you dare use this function.
45  */
46 unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *p)
47 {
48         unsigned long long res;
49         unsigned int rv;
50         int overflow;
51
52         res = 0;
53         rv = 0;
54         overflow = 0;
55         while (*s) {
56                 unsigned int val;
57
58                 if ('0' <= *s && *s <= '9')
59                         val = *s - '0';
60                 else if ('a' <= _tolower(*s) && _tolower(*s) <= 'f')
61                         val = _tolower(*s) - 'a' + 10;
62                 else
63                         break;
64
65                 if (val >= base)
66                         break;
67                 /*
68                  * Check for overflow only if we are within range of
69                  * it in the max base we support (16)
70                  */
71                 if (unlikely(res & (~0ull << 60))) {
72                         if (res > div_u64(ULLONG_MAX - val, base))
73                                 overflow = 1;
74                 }
75                 res = res * base + val;
76                 rv++;
77                 s++;
78         }
79         *p = res;
80         if (overflow)
81                 rv |= KSTRTOX_OVERFLOW;
82         return rv;
83 }
84
85 static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
86 {
87         unsigned long long _res;
88         unsigned int rv;
89
90         s = _parse_integer_fixup_radix(s, &base);
91         rv = _parse_integer(s, base, &_res);
92         if (rv & KSTRTOX_OVERFLOW)
93                 return -ERANGE;
94         if (rv == 0)
95                 return -EINVAL;
96         s += rv;
97         if (*s == '\n')
98                 s++;
99         if (*s)
100                 return -EINVAL;
101         *res = _res;
102         return 0;
103 }
104
105 /**
106  * kstrtoull - convert a string to an unsigned long long
107  * @s: The start of the string. The string must be null-terminated, and may also
108  *  include a single newline before its terminating null. The first character
109  *  may also be a plus sign, but not a minus sign.
110  * @base: The number base to use. The maximum supported base is 16. If base is
111  *  given as 0, then the base of the string is automatically detected with the
112  *  conventional semantics - If it begins with 0x the number will be parsed as a
113  *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
114  *  parsed as an octal number. Otherwise it will be parsed as a decimal.
115  * @res: Where to write the result of the conversion on success.
116  *
117  * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
118  * Used as a replacement for the obsolete simple_strtoull. Return code must
119  * be checked.
120  */
121 int kstrtoull(const char *s, unsigned int base, unsigned long long *res)
122 {
123         if (s[0] == '+')
124                 s++;
125         return _kstrtoull(s, base, res);
126 }
127 EXPORT_SYMBOL(kstrtoull);
128
129 /**
130  * kstrtoll - convert a string to a long long
131  * @s: The start of the string. The string must be null-terminated, and may also
132  *  include a single newline before its terminating null. The first character
133  *  may also be a plus sign or a minus sign.
134  * @base: The number base to use. The maximum supported base is 16. If base is
135  *  given as 0, then the base of the string is automatically detected with the
136  *  conventional semantics - If it begins with 0x the number will be parsed as a
137  *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
138  *  parsed as an octal number. Otherwise it will be parsed as a decimal.
139  * @res: Where to write the result of the conversion on success.
140  *
141  * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
142  * Used as a replacement for the obsolete simple_strtoull. Return code must
143  * be checked.
144  */
145 int kstrtoll(const char *s, unsigned int base, long long *res)
146 {
147         unsigned long long tmp;
148         int rv;
149
150         if (s[0] == '-') {
151                 rv = _kstrtoull(s + 1, base, &tmp);
152                 if (rv < 0)
153                         return rv;
154                 if ((long long)-tmp > 0)
155                         return -ERANGE;
156                 *res = -tmp;
157         } else {
158                 rv = kstrtoull(s, base, &tmp);
159                 if (rv < 0)
160                         return rv;
161                 if ((long long)tmp < 0)
162                         return -ERANGE;
163                 *res = tmp;
164         }
165         return 0;
166 }
167 EXPORT_SYMBOL(kstrtoll);
168
169 /* Internal, do not use. */
170 int _kstrtoul(const char *s, unsigned int base, unsigned long *res)
171 {
172         unsigned long long tmp;
173         int rv;
174
175         rv = kstrtoull(s, base, &tmp);
176         if (rv < 0)
177                 return rv;
178         if (tmp != (unsigned long long)(unsigned long)tmp)
179                 return -ERANGE;
180         *res = tmp;
181         return 0;
182 }
183 EXPORT_SYMBOL(_kstrtoul);
184
185 /* Internal, do not use. */
186 int _kstrtol(const char *s, unsigned int base, long *res)
187 {
188         long long tmp;
189         int rv;
190
191         rv = kstrtoll(s, base, &tmp);
192         if (rv < 0)
193                 return rv;
194         if (tmp != (long long)(long)tmp)
195                 return -ERANGE;
196         *res = tmp;
197         return 0;
198 }
199 EXPORT_SYMBOL(_kstrtol);
200
201 /**
202  * kstrtouint - convert a string to an unsigned int
203  * @s: The start of the string. The string must be null-terminated, and may also
204  *  include a single newline before its terminating null. The first character
205  *  may also be a plus sign, but not a minus sign.
206  * @base: The number base to use. The maximum supported base is 16. If base is
207  *  given as 0, then the base of the string is automatically detected with the
208  *  conventional semantics - If it begins with 0x the number will be parsed as a
209  *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
210  *  parsed as an octal number. Otherwise it will be parsed as a decimal.
211  * @res: Where to write the result of the conversion on success.
212  *
213  * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
214  * Used as a replacement for the obsolete simple_strtoull. Return code must
215  * be checked.
216  */
217 int kstrtouint(const char *s, unsigned int base, unsigned int *res)
218 {
219         unsigned long long tmp;
220         int rv;
221
222         rv = kstrtoull(s, base, &tmp);
223         if (rv < 0)
224                 return rv;
225         if (tmp != (unsigned long long)(unsigned int)tmp)
226                 return -ERANGE;
227         *res = tmp;
228         return 0;
229 }
230 EXPORT_SYMBOL(kstrtouint);
231
232 /**
233  * kstrtoint - convert a string to an int
234  * @s: The start of the string. The string must be null-terminated, and may also
235  *  include a single newline before its terminating null. The first character
236  *  may also be a plus sign or a minus sign.
237  * @base: The number base to use. The maximum supported base is 16. If base is
238  *  given as 0, then the base of the string is automatically detected with the
239  *  conventional semantics - If it begins with 0x the number will be parsed as a
240  *  hexadecimal (case insensitive), if it otherwise begins with 0, it will be
241  *  parsed as an octal number. Otherwise it will be parsed as a decimal.
242  * @res: Where to write the result of the conversion on success.
243  *
244  * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
245  * Used as a replacement for the obsolete simple_strtoull. Return code must
246  * be checked.
247  */
248 int kstrtoint(const char *s, unsigned int base, int *res)
249 {
250         long long tmp;
251         int rv;
252
253         rv = kstrtoll(s, base, &tmp);
254         if (rv < 0)
255                 return rv;
256         if (tmp != (long long)(int)tmp)
257                 return -ERANGE;
258         *res = tmp;
259         return 0;
260 }
261 EXPORT_SYMBOL(kstrtoint);
262
263 int kstrtou16(const char *s, unsigned int base, u16 *res)
264 {
265         unsigned long long tmp;
266         int rv;
267
268         rv = kstrtoull(s, base, &tmp);
269         if (rv < 0)
270                 return rv;
271         if (tmp != (unsigned long long)(u16)tmp)
272                 return -ERANGE;
273         *res = tmp;
274         return 0;
275 }
276 EXPORT_SYMBOL(kstrtou16);
277
278 int kstrtos16(const char *s, unsigned int base, s16 *res)
279 {
280         long long tmp;
281         int rv;
282
283         rv = kstrtoll(s, base, &tmp);
284         if (rv < 0)
285                 return rv;
286         if (tmp != (long long)(s16)tmp)
287                 return -ERANGE;
288         *res = tmp;
289         return 0;
290 }
291 EXPORT_SYMBOL(kstrtos16);
292
293 int kstrtou8(const char *s, unsigned int base, u8 *res)
294 {
295         unsigned long long tmp;
296         int rv;
297
298         rv = kstrtoull(s, base, &tmp);
299         if (rv < 0)
300                 return rv;
301         if (tmp != (unsigned long long)(u8)tmp)
302                 return -ERANGE;
303         *res = tmp;
304         return 0;
305 }
306 EXPORT_SYMBOL(kstrtou8);
307
308 int kstrtos8(const char *s, unsigned int base, s8 *res)
309 {
310         long long tmp;
311         int rv;
312
313         rv = kstrtoll(s, base, &tmp);
314         if (rv < 0)
315                 return rv;
316         if (tmp != (long long)(s8)tmp)
317                 return -ERANGE;
318         *res = tmp;
319         return 0;
320 }
321 EXPORT_SYMBOL(kstrtos8);
322
323 /**
324  * kstrtobool - convert common user inputs into boolean values
325  * @s: input string
326  * @res: result
327  *
328  * This routine returns 0 iff the first character is one of 'Yy1Nn0', or
329  * [oO][NnFf] for "on" and "off". Otherwise it will return -EINVAL.  Value
330  * pointed to by res is updated upon finding a match.
331  */
332 int kstrtobool(const char *s, bool *res)
333 {
334         if (!s)
335                 return -EINVAL;
336
337         switch (s[0]) {
338         case 'y':
339         case 'Y':
340         case '1':
341                 *res = true;
342                 return 0;
343         case 'n':
344         case 'N':
345         case '0':
346                 *res = false;
347                 return 0;
348         case 'o':
349         case 'O':
350                 switch (s[1]) {
351                 case 'n':
352                 case 'N':
353                         *res = true;
354                         return 0;
355                 case 'f':
356                 case 'F':
357                         *res = false;
358                         return 0;
359                 default:
360                         break;
361                 }
362         default:
363                 break;
364         }
365
366         return -EINVAL;
367 }
368 EXPORT_SYMBOL(kstrtobool);