summaryrefslogtreecommitdiff
path: root/libc/stdlib/strto_l.c
diff options
context:
space:
mode:
authorManuel Novoa III <mjn3@codepoet.org>2002-03-13 23:28:57 +0000
committerManuel Novoa III <mjn3@codepoet.org>2002-03-13 23:28:57 +0000
commit29d3e23bab8e53ed8653aafb8af9d2999769f17f (patch)
treeac0e55fc8f2894d00686e2048df3b0fadf38980d /libc/stdlib/strto_l.c
parent347b1fc3b66b3fcffdc9da6f928b0e6caaf9de9d (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.c207
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
-