]>
git.proxmox.com Git - wasi-libc.git/blob - libc-bottom-half/cloudlibc/src/common/parser_strtoint.h
1 // Copyright (c) 2015 Nuxi, https://nuxi.nl/
3 // SPDX-License-Identifier: BSD-2-Clause
5 // Parser of integer literals as performed by strtol(), scanf(), etc.
8 bool have_number
= false;
9 bool have_overflow
= false;
13 // Negative or positive number?
14 bool negative
= false;
15 if (allow_negative
&& PEEK(0) == '-') {
18 } else if (PEEK(0) == '+') {
22 // Determine the base.
23 if ((base
== 0 || base
== 16) && PEEK(0) == '0' &&
24 (PEEK(1) == 'x' || PEEK(1) == 'X') &&
25 ((PEEK(2) >= '0' && PEEK(2) <= '9') ||
26 (PEEK(2) >= 'A' && PEEK(2) <= 'F') ||
27 (PEEK(2) >= 'a' && PEEK(2) <= 'f'))) {
30 } else if (base
== 0) {
31 base
= PEEK(0) == '0' ? 8 : 10;
34 // Only perform conversion if the base is valid.
35 if (base
>= 2 && base
<= 36) {
36 uint_fast8_t radix
= base
;
38 // Determine the highest value up to which we can parse so that the
39 // next digit does not cause an overflow.
41 uint_fast8_t last_digit
;
43 ceil
= -(min
/ radix
);
44 last_digit
= -(min
% radix
);
47 last_digit
= max
% radix
;
54 if (PEEK(0) >= '0' && PEEK(0) <= '9')
55 digit
= PEEK(0) - '0';
56 else if (PEEK(0) >= 'A' && PEEK(0) <= 'Z')
57 digit
= PEEK(0) - 'A' + 10;
58 else if (PEEK(0) >= 'a' && PEEK(0) <= 'z')
59 digit
= PEEK(0) - 'a' + 10;
68 if (value
> ceil
|| (value
== ceil
&& digit
> last_digit
)) {
69 // Addition of the new digit would cause an overflow.
72 value
= value
* radix
+ digit
;
77 // Set value to min or max depending whether the input is negative
78 // and whether the output type is signed.
79 number
= (int_t
)-1 >= 0 || !negative
? max
: min
;
81 // Return parsed value.
82 number
= negative
? -value
: value
;