Refactor NumberParsing.cpp + a lot of comments
This commit is contained in:
parent
97cb57d521
commit
ee6387e7b5
@ -1,7 +1,14 @@
|
||||
#pragma once
|
||||
#include <luna/Types.h>
|
||||
|
||||
// Parse an unsigned integer and advance *str to point to the first non-digit character after the number.
|
||||
usize scan_unsigned_integer(const char** str);
|
||||
|
||||
// Parse a signed integer and advance *str to point to the first non-digit character after the number.
|
||||
isize scan_signed_integer(const char** str);
|
||||
|
||||
// Parse an unsigned integer, similar to strtoull().
|
||||
usize parse_unsigned_integer(const char* str, const char** endptr, int base);
|
||||
|
||||
// Parse a signed integer, similar to strtoll().
|
||||
isize parse_signed_integer(const char* str, const char** endptr, int base);
|
@ -17,12 +17,13 @@ static bool is_valid_digit_for_base(int base, char c)
|
||||
return true;
|
||||
}
|
||||
|
||||
usize parse_unsigned_integer(const char* str, const char** endptr, int base)
|
||||
static usize do_unsigned_parse(const char* str, const char** endptr, int base)
|
||||
{
|
||||
usize val = 0;
|
||||
|
||||
while (_isspace(*str)) str++;
|
||||
|
||||
// 1. If base is zero or 16, the string may then include a "0x" prefix, and the number will be read in base 16;
|
||||
// otherwise, a zero base is taken as 10 (decimal) unless the next character is '0', in which case it is taken as
|
||||
// 8 (octal).
|
||||
if ((base == 0 || base == 16) && *str == '0')
|
||||
{
|
||||
str++;
|
||||
@ -37,17 +38,32 @@ usize parse_unsigned_integer(const char* str, const char** endptr, int base)
|
||||
else if (base == 0)
|
||||
base = 10;
|
||||
|
||||
// 2. The remainder of the string is converted to an unsigned long value in
|
||||
// the obvious manner, stopping at the first character which is not a
|
||||
// valid digit in the given base.
|
||||
while (is_valid_digit_for_base(base, *str))
|
||||
{
|
||||
val = ((usize)base * val) + (usize)parse_digit_unchecked(*str);
|
||||
str++;
|
||||
}
|
||||
|
||||
// 3. If endptr is not NULL, this function stores the address of the first invalid character in *endptr.
|
||||
if (endptr) *endptr = str;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
usize parse_unsigned_integer(const char* str, const char** endptr, int base)
|
||||
{
|
||||
// The string may begin with an arbitrary amount of white space (as determined by isspace(3)),
|
||||
while (_isspace(*str)) str++;
|
||||
|
||||
// followed by a single optional '+' or '-' sign.
|
||||
if (*str == '-' || *str == '+') str++;
|
||||
|
||||
return do_unsigned_parse(str, endptr, base);
|
||||
}
|
||||
|
||||
#define SSIZE_MAX LONG_MAX
|
||||
#define SSIZE_MIN (-SSIZE_MAX - (isize)1)
|
||||
|
||||
@ -55,16 +71,19 @@ isize parse_signed_integer(const char* str, const char** endptr, int base)
|
||||
{
|
||||
bool negative = false;
|
||||
|
||||
// The string may begin with an arbitrary amount of white space (as determined by isspace(3)),
|
||||
while (_isspace(*str)) str++;
|
||||
|
||||
// followed by a single optional '+' or '-' sign.
|
||||
if (*str == '-' || *str == '+')
|
||||
{
|
||||
if (*str == '-') negative = true;
|
||||
str++;
|
||||
}
|
||||
|
||||
usize rc = parse_unsigned_integer(str, endptr, base);
|
||||
usize rc = do_unsigned_parse(str, endptr, base);
|
||||
|
||||
// If an underflow occurs, this function returns SSIZE_MIN. If an overflow occurs, this function returns SSIZE_MAX.
|
||||
if (rc > SSIZE_MAX) { return negative ? SSIZE_MIN : SSIZE_MAX; }
|
||||
|
||||
return negative ? -(isize)rc : (isize)rc;
|
||||
|
Loading…
Reference in New Issue
Block a user