diff options
Diffstat (limited to 'libc/stdlib/strto_ll.c')
-rw-r--r-- | libc/stdlib/strto_ll.c | 203 |
1 files changed, 0 insertions, 203 deletions
diff --git a/libc/stdlib/strto_ll.c b/libc/stdlib/strto_ll.c deleted file mode 100644 index 76a1a95b3..000000000 --- a/libc/stdlib/strto_ll.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (C) 2000 Manuel Novoa III - * - * Notes: - * - * The primary objective of this implementation was minimal size. - * - * Note: Assumes char layout 0-9.*A-Z.*a-z for ordinals values. - * - * There are a couple of compile-time options below. - * - */ - -/*****************************************************************************/ -/* OPTIONS */ -/*****************************************************************************/ - -/* Set if we want errno set appropriately. */ -/* NOTE: Implies _STRTO_ENDPTR below */ -#define _STRTO_ERRNO 0 - -/* Set if we want support for the endptr arg. */ -/* Implied by _STRTO_ERRNO. */ -#define _STRTO_ENDPTR 1 - -/*****************************************************************************/ -/* Don't change anything that follows. */ -/*****************************************************************************/ - -#if _STRTO_ERRNO -#undef _STRTO_ENDPTR -#define _STRTO_ENDPTR 1 -#endif - -/*****************************************************************************/ - -/* Are there actually any machines where this might fail? */ -#if 'A' > 'a' -#error ordering assumption violated : 'A' > 'a' -#endif - -#include <stdlib.h> -#define __USE_GNU -#include <limits.h> -#include <ctype.h> - -#if _STRTO_ERRNO -#include <errno.h> -#endif - -unsigned long long _strto_ll(const char *str, char **endptr, int base, int uflag); - -#if L_strto_ll - -/* - * This is the main work fuction which handles both strtol (uflag = 0) and - * strtoul (uflag = 1). - */ - -unsigned long long _strto_ll(const char *str, char **endptr, int base, int uflag) -{ - unsigned long long number = 0; - unsigned long long cutoff; - char *pos = (char *) str; -#if _STRTO_ENDPTR - char *fail_char = (char *) str; -#endif - int digit, cutoff_digit; - int negative; - - while (isspace(*pos)) { /* skip leading whitespace */ - ++pos; - } - - /* handle optional sign */ - negative = 0; - switch(*pos) { - case '-': negative = 1; /* fall through to increment pos */ - case '+': ++pos; - } - - if ((base == 16) && (*pos == '0')) { /* handle option prefix */ - ++pos; -#if _STRTO_ENDPTR - fail_char = pos; -#endif - if ((*pos == 'x') || (*pos == 'X')) { - ++pos; - } - } - - if (base == 0) { /* dynamic base */ - base = 10; /* default is 10 */ - if (*pos == '0') { - ++pos; - base -= 2; /* now base is 8 (or 16) */ -#if _STRTO_ENDPTR - fail_char = pos; -#endif - if ((*pos == 'x') || (*pos == 'X')) { - base += 8; /* base is 16 */ - ++pos; - } - } - } - - if ((base < 2) || (base > 36)) { /* illegal base */ - goto DONE; - } - - cutoff_digit = ULONG_LONG_MAX % base; - cutoff = ULONG_LONG_MAX / base; - - while (1) { - digit = 40; - if ((*pos >= '0') && (*pos <= '9')) { - digit = (*pos - '0'); - } else if (*pos >= 'a') { - digit = (*pos - 'a' + 10); - } else if (*pos >= 'A') { - digit = (*pos - 'A' + 10); - } else break; - - if (digit >= base) { - break; - } - - ++pos; -#if _STRTO_ENDPTR - fail_char = pos; -#endif - - /* adjust number, with overflow check */ - if ((number > cutoff) - || ((number == cutoff) && (digit > cutoff_digit))) { - number = ULONG_LONG_MAX; - if (uflag) { - negative = 0; /* since unsigned returns ULONG_LONG_MAX */ - } -#if _STRTO_ERRNO - __set_errno(ERANGE); -#endif - } else { - number = number * base + digit; - } - - } - - DONE: -#if _STRTO_ENDPTR - if (endptr) { - *endptr = fail_char; - } -#endif - - if (negative) { - if (!uflag && (number > ((unsigned long long)(-(1+LONG_LONG_MIN)))+1)) { -#if _STRTO_ERRNO - __set_errno(ERANGE); -#endif - return (unsigned long long) LONG_LONG_MIN; - } - return (unsigned long long)(-((long long)number)); - } else { - if (!uflag && (number > (unsigned long long) LONG_LONG_MAX)) { -#if _STRTO_ERRNO - __set_errno(ERANGE); -#endif - return LONG_LONG_MAX; - } - return number; - } -} - -#endif - -#if L_strtoull - -unsigned long long strtoull(const char *str, char **endptr, int base) -{ - return _strto_ll(str, endptr, base, 1); -} - -#endif - -#if L_strtoll - -long long strtoll(const char *str, char **endptr, int base) -{ - return _strto_ll(str, endptr, base, 0); -} - -#endif - -#ifdef L_atoll -long long atoll(const char *str) -{ - return(_strto_ll((str),(char**)0,10,0)); -} -#endif - - - |