1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-28 07:17:34 +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 || base == 16) {
if (base == 0) if (base == 0)
base = c == '0' ? 8 : 10; base = 10;
if (*str == '0') {
cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; str++;
cutlim = cutoff % (unsigned long)base; if (*str == 'X' || *str == 'x') {
cutoff /= (unsigned long)base; str++;
for (acc = 0, any = 0;; c = *s++) { base = 16;
if (isdigit(c)) } else if (base != 16) {
c -= '0'; base = 8;
else if (isalpha(c))
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) { }
acc = neg ? LONG_MIN : LONG_MAX; const char* estr = str + strlen(str) - 1;
errno = ERANGE; long track = 1;
} else if (neg) long num = 0;
acc = -acc; while (estr >= str) {
if (endptr) if ((*estr >= '0' && *estr <= '9') || (base > 10 && (*estr >= 'A' && *estr <= 'Z'))) {
*endptr = const_cast<char*>((any ? s - 1 : str)); int digit_value = *estr - '0';
return acc; if (*estr >= 'A' && *estr <= 'Z')
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)