diff options
author | Manuel Novoa III <mjn3@codepoet.org> | 2002-03-13 23:28:57 +0000 |
---|---|---|
committer | Manuel Novoa III <mjn3@codepoet.org> | 2002-03-13 23:28:57 +0000 |
commit | 29d3e23bab8e53ed8653aafb8af9d2999769f17f (patch) | |
tree | ac0e55fc8f2894d00686e2048df3b0fadf38980d /libc/stdlib/strto_l.c | |
parent | 347b1fc3b66b3fcffdc9da6f928b0e6caaf9de9d (diff) |
New versions of the various string to int functions which are smaller
than the old ones, even with errno setting turned on now. Also, at
least on i386, we no longer need the long long helper functions for
division and mod from libgcc.a.
Diffstat (limited to 'libc/stdlib/strto_l.c')
-rw-r--r-- | libc/stdlib/strto_l.c | 207 |
1 files changed, 0 insertions, 207 deletions
diff --git a/libc/stdlib/strto_l.c b/libc/stdlib/strto_l.c deleted file mode 100644 index 666433927..000000000 --- a/libc/stdlib/strto_l.c +++ /dev/null @@ -1,207 +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> -#include <limits.h> -#include <ctype.h> - -#if _STRTO_ERRNO -#include <errno.h> -#endif - -unsigned long _strto_l(const char *str, char **endptr, int base, int uflag); - -#if L_strto_l - -/* - * This is the main work fuction which handles both strtol (uflag = 0) and - * strtoul (uflag = 1). - */ - -unsigned long _strto_l(const char *str, char **endptr, int base, int uflag) -{ - unsigned long number = 0; - unsigned 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_MAX % base; - cutoff = ULONG_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_MAX; - if (uflag) { - negative = 0; /* since unsigned returns ULONG_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)(-(1+LONG_MIN)))+1)) { -#if _STRTO_ERRNO - __set_errno(ERANGE); -#endif - return (unsigned long) LONG_MIN; - } - return (unsigned long)(-((long)number)); - } else { - if (!uflag && (number > (unsigned long) LONG_MAX)) { -#if _STRTO_ERRNO - __set_errno(ERANGE); -#endif - return LONG_MAX; - } - return number; - } -} - -#endif - -#if L_strtoul - -unsigned long strtoul(const char *str, char **endptr, int base) -{ - return _strto_l(str, endptr, base, 1); -} - -#endif - -#if L_strtol -long strtol(const char *str, char **endptr, int base) -{ - return _strto_l(str, endptr, base, 0); -} - -#endif - -#ifdef L_atoi -int atoi(const char *str) -{ - return((int)_strto_l((str),(char**)0,10, 0)); - -} -#endif - -#ifdef L_atol -long atol(const char *str) -{ - return(_strto_l((str),(char**)0,10, 0)); -} -#endif - |