summaryrefslogtreecommitdiff
path: root/libc/stdlib/strto_ll.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_ll.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_ll.c')
-rw-r--r--libc/stdlib/strto_ll.c203
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
-
-
-