1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-28 01:57:35 +00:00

LibC: New implementation of strtol (NIH) (#263)

Fixes #189.
This commit is contained in:
Christopher Dumas 2019-06-30 21:07:10 -07:00 committed by Andreas Kling
parent c70fbca23a
commit df34de369b

View file

@ -331,58 +331,44 @@ size_t mbstowcs(wchar_t*, const char*, size_t)
long strtol(const char* str, char** endptr, int base) long strtol(const char* str, char** endptr, int base)
{ {
const char* s = str; int sign = 1;
unsigned long acc; while (isspace(*str))
int c; str++;
unsigned long cutoff; if (*str == '-' || *str == '+') {
int neg = 0; if (*str == '-')
int any; sign = -1;
int cutlim; str++;
do {
c = *s++;
} while (isspace(c));
if (c == '-') {
neg = 1;
c = *s++;
} else if (c == '+')
c = *s++;
if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) {
c = s[1];
s += 2;
base = 16;
} }
if (base == 0) if (base == 0 || base == 16) {
base = c == '0' ? 8 : 10; if (base == 0)
base = 10;
cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; if (*str == '0') {
cutlim = cutoff % (unsigned long)base; str++;
cutoff /= (unsigned long)base; if (*str == 'X' || *str == 'x') {
for (acc = 0, any = 0;; c = *s++) { str++;
if (isdigit(c)) base = 16;
c -= '0'; } else if (base != 16) {
else if (isalpha(c)) base = 8;
c -= isupper(c) ? 'A' - 10 : 'a' - 10; }
else
break;
if (c >= base)
break;
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
any = -1;
else {
any = 1;
acc *= base;
acc += c;
} }
} }
if (any < 0) { const char* estr = str + strlen(str) - 1;
acc = neg ? LONG_MIN : LONG_MAX; long track = 1;
errno = ERANGE; long num = 0;
} else if (neg) while (estr >= str) {
acc = -acc; if ((*estr >= '0' && *estr <= '9') || (base > 10 && (*estr >= 'A' && *estr <= 'Z'))) {
if (endptr) int digit_value = *estr - '0';
*endptr = const_cast<char*>((any ? s - 1 : str)); if (*estr >= 'A' && *estr <= 'Z')
return acc; digit_value = 10 + (*estr - 'A');
num += (track *= base) / base * digit_value;
} else {
if (endptr != NULL)
*endptr = estr;
return 0;
};
estr--;
}
return num * sign;
} }
unsigned long strtoul(const char* str, char** endptr, int base) unsigned long strtoul(const char* str, char** endptr, int base)