diff options
author | obrien <obrien@FreeBSD.org> | 2001-02-27 13:33:07 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2001-02-27 13:33:07 +0000 |
commit | bb70e1687a5a72cc582496d32293aed2b63f5647 (patch) | |
tree | a6ddbcda2c8416d0bced69bd65a91d752bc75d50 /lib/libc/stdlib/strtoq.c | |
parent | a7aa01b9b6a44b97d7111edaa5ab21b829093ccd (diff) | |
download | FreeBSD-src-bb70e1687a5a72cc582496d32293aed2b63f5647.zip FreeBSD-src-bb70e1687a5a72cc582496d32293aed2b63f5647.tar.gz |
Impliment the ISO-C99 strto[u]ll()
and rewrite strto[u]q() in terms of it.
Diffstat (limited to 'lib/libc/stdlib/strtoq.c')
-rw-r--r-- | lib/libc/stdlib/strtoq.c | 91 |
1 files changed, 6 insertions, 85 deletions
diff --git a/lib/libc/stdlib/strtoq.c b/lib/libc/stdlib/strtoq.c index f84e030..65e87d6 100644 --- a/lib/libc/stdlib/strtoq.c +++ b/lib/libc/stdlib/strtoq.c @@ -35,11 +35,11 @@ static char sccsid[] = "@(#)strtoq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ -#include <sys/types.h> +#ifndef lint +static const char rcsid[] = + "$FreeBSD$"; +#endif -#include <limits.h> -#include <errno.h> -#include <ctype.h> #include <stdlib.h> /* @@ -52,87 +52,8 @@ quad_t strtoq(nptr, endptr, base) const char *nptr; char **endptr; - register int base; + int base; { - register const char *s; - register u_quad_t acc; - register unsigned char c; - register u_quad_t qbase, cutoff; - register int neg, any, cutlim; - /* - * Skip white space and pick up leading +/- sign if any. - * If base is 0, allow 0x for hex and 0 for octal, else - * assume decimal; if base is already 16, allow 0x. - */ - s = nptr; - do { - c = *s++; - } while (isspace(c)); - if (c == '-') { - neg = 1; - c = *s++; - } else { - neg = 0; - 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 = c == '0' ? 8 : 10; - - /* - * Compute the cutoff value between legal numbers and illegal - * numbers. That is the largest legal value, divided by the - * base. An input number that is greater than this value, if - * followed by a legal input character, is too big. One that - * is equal to this value may be valid or not; the limit - * between valid and invalid numbers is then based on the last - * digit. For instance, if the range for quads is - * [-9223372036854775808..9223372036854775807] and the input base - * is 10, cutoff will be set to 922337203685477580 and cutlim to - * either 7 (neg==0) or 8 (neg==1), meaning that if we have - * accumulated a value > 922337203685477580, or equal but the - * next digit is > 7 (or 8), the number is too big, and we will - * return a range error. - * - * Set any if any `digits' consumed; make it negative to indicate - * overflow. - */ - qbase = (unsigned)base; - cutoff = neg ? (u_quad_t)-(QUAD_MIN + QUAD_MAX) + QUAD_MAX : QUAD_MAX; - cutlim = cutoff % qbase; - cutoff /= qbase; - for (acc = 0, any = 0;; c = *s++) { - if (!isascii(c)) - break; - if (isdigit(c)) - c -= '0'; - 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 *= qbase; - acc += c; - } - } - if (any < 0) { - acc = neg ? QUAD_MIN : QUAD_MAX; - errno = ERANGE; - } else if (neg) - acc = -acc; - if (endptr != 0) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); + return strtoll(nptr, endptr, base); } |