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 | |
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')
-rw-r--r-- | lib/libc/stdlib/Makefile.inc | 9 | ||||
-rw-r--r-- | lib/libc/stdlib/strtol.3 | 37 | ||||
-rw-r--r-- | lib/libc/stdlib/strtoll.c | 20 | ||||
-rw-r--r-- | lib/libc/stdlib/strtoq.c | 91 | ||||
-rw-r--r-- | lib/libc/stdlib/strtoul.3 | 39 | ||||
-rw-r--r-- | lib/libc/stdlib/strtoull.c | 21 | ||||
-rw-r--r-- | lib/libc/stdlib/strtouq.c | 69 |
7 files changed, 111 insertions, 175 deletions
diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc index 12ec5d4..bd82afe 100644 --- a/lib/libc/stdlib/Makefile.inc +++ b/lib/libc/stdlib/Makefile.inc @@ -7,8 +7,9 @@ MISRCS+=abort.c abs.c atexit.c atof.c atoi.c atol.c bsearch.c calloc.c div.c \ exit.c getenv.c getopt.c getsubopt.c heapsort.c labs.c ldiv.c \ malloc.c merge.c putenv.c qsort.c radixsort.c rand.c random.c \ - reallocf.c realpath.c setenv.c strhash.c strtol.c strtoq.c strtoul.c \ - strtouq.c system.c tdelete.c tfind.c tsearch.c twalk.c + reallocf.c realpath.c setenv.c strhash.c strtol.c strtoll.c strtoq.c \ + strtoul.c strtoull.c strtouq.c system.c tdelete.c tfind.c tsearch.c \ + twalk.c .if ${MACHINE_ARCH} == "alpha" # XXX Temporary until the assumption that a long is 32-bits is resolved @@ -33,7 +34,7 @@ MLINKS+=qsort.3 heapsort.3 qsort.3 mergesort.3 MLINKS+=rand.3 rand_r.3 rand.3 srand.3 MLINKS+=random.3 initstate.3 random.3 setstate.3 random.3 srandom.3 \ random.3 srandomdev.3 -MLINKS+=strtol.3 strtoq.3 -MLINKS+=strtoul.3 strtouq.3 +MLINKS+=strtol.3 strtoll.3 strtol.3 strtoq.3 +MLINKS+=strtoul.3 strtoull.3 strtoul.3 strtouq.3 MLINKS+=malloc.3 calloc.3 malloc.3 free.3 malloc.3 realloc.3 malloc.3 reallocf.3 .endif diff --git a/lib/libc/stdlib/strtol.3 b/lib/libc/stdlib/strtol.3 index 3f28713..eef3031 100644 --- a/lib/libc/stdlib/strtol.3 +++ b/lib/libc/stdlib/strtol.3 @@ -40,8 +40,8 @@ .Dt STRTOL 3 .Os .Sh NAME -.Nm strtol , strtoq -.Nd convert string value to a long or quad_t integer +.Nm strtol , strtoll , strtoq +.Nd convert string value to a long , long long , or quad_t integer .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -49,6 +49,8 @@ .Fd #include <limits.h> .Ft long .Fn strtol "const char *nptr" "char **endptr" "int base" +.Ft long long +.Fn strtoll "const char *nptr" "char **endptr" "int base" .Fd #include <sys/types.h> .Fd #include <stdlib.h> .Fd #include <limits.h> @@ -64,6 +66,14 @@ to a .Em long value. The +.Fn strtoll +function +converts the string in +.Fa nptr +to a +.Em long long +value. +The .Fn strtoq function converts the string in @@ -145,7 +155,20 @@ If an overflow occurs, .Fn strtol returns .Dv LONG_MAX . -In both cases, +The +.Fn strtoll +function +returns the result of the conversion, +unless the value would underflow or overflow. +If an underflow occurs, +.Fn strtoll +returns +.Dv LLONG_MIN . +If an overflow occurs, +.Fn strtoll +returns +.Dv LLONG_MAX . +In all cases, .Va errno is set to .Er ERANGE . @@ -166,5 +189,13 @@ The function conforms to .St -isoC . +The +.Fn strtoll +function +conforms to +.St -isoC-99 . +The BSD +.Fn strtoq +function is deprecated. .Sh BUGS Ignores the current locale. diff --git a/lib/libc/stdlib/strtoll.c b/lib/libc/stdlib/strtoll.c index f84e030..b7a7590 100644 --- a/lib/libc/stdlib/strtoll.c +++ b/lib/libc/stdlib/strtoll.c @@ -35,6 +35,11 @@ static char sccsid[] = "@(#)strtoq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ +#ifndef lint +static const char rcsid[] = + "$FreeBSD$"; +#endif + #include <sys/types.h> #include <limits.h> @@ -43,21 +48,21 @@ static char sccsid[] = "@(#)strtoq.c 8.1 (Berkeley) 6/4/93"; #include <stdlib.h> /* - * Convert a string to a quad integer. + * Convert a string to a long long integer. * * Ignores `locale' stuff. Assumes that the upper and lower case * alphabets and digits are each contiguous. */ -quad_t -strtoq(nptr, endptr, base) +long long +strtoll(nptr, endptr, base) const char *nptr; char **endptr; register int base; { register const char *s; - register u_quad_t acc; + register unsigned long long acc; register unsigned char c; - register u_quad_t qbase, cutoff; + register unsigned long long qbase, cutoff; register int neg, any, cutlim; /* @@ -105,7 +110,8 @@ strtoq(nptr, endptr, base) * overflow. */ qbase = (unsigned)base; - cutoff = neg ? (u_quad_t)-(QUAD_MIN + QUAD_MAX) + QUAD_MAX : QUAD_MAX; + cutoff = neg ? (unsigned long long)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX + : LLONG_MAX; cutlim = cutoff % qbase; cutoff /= qbase; for (acc = 0, any = 0;; c = *s++) { @@ -128,7 +134,7 @@ strtoq(nptr, endptr, base) } } if (any < 0) { - acc = neg ? QUAD_MIN : QUAD_MAX; + acc = neg ? LLONG_MIN : LLONG_MAX; errno = ERANGE; } else if (neg) acc = -acc; 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); } diff --git a/lib/libc/stdlib/strtoul.3 b/lib/libc/stdlib/strtoul.3 index d3e9696..ebd9268 100644 --- a/lib/libc/stdlib/strtoul.3 +++ b/lib/libc/stdlib/strtoul.3 @@ -40,8 +40,8 @@ .Dt STRTOUL 3 .Os .Sh NAME -.Nm strtoul , strtouq -.Nd "convert a string to an unsigned long or uquad_t integer" +.Nm strtoul , strtoull , strtouq +.Nd "convert a string to an unsigned long , unsigned long long , or uquad_t integer" .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -49,6 +49,8 @@ .Fd #include <limits.h> .Ft unsigned long .Fn strtoul "const char *nptr" "char **endptr" "int base" +.Ft unsigned long long +.Fn strtoull "const char *nptr" "char **endptr" "int base" .Fd #include <sys/types.h> .Fd #include <stdlib.h> .Fd #include <limits.h> @@ -64,6 +66,14 @@ to an .Em unsigned long value. The +.Fn strtoull +function +converts the string in +.Fa nptr +to an +.Em unsigned long long +value. +The .Fn strtouq function converts the string in @@ -143,10 +153,21 @@ unless the original (non-negated) value would overflow; in the latter case, .Fn strtoul returns -.Dv ULONG_MAX -and sets the global variable +.Dv ULONG_MAX . +The +.Fn strtoull +function +returns either the result of the conversion +or, if there was a leading minus sign, +the negation of the result of the conversion, +unless the original (non-negated) value would overflow; +in the latter case, +.Fn strtoull +returns +.Dv ULLONG_MAX . +In all cases, .Va errno -to +is set to .Er ERANGE . .Sh ERRORS .Bl -tag -width Er @@ -161,5 +182,13 @@ The function conforms to .St -isoC . +The +.Fn strtoull +function +conforms to +.St -isoC-99 . +The BSD +.Fn strtoq +function is deprecated. .Sh BUGS Ignores the current locale. diff --git a/lib/libc/stdlib/strtoull.c b/lib/libc/stdlib/strtoull.c index 7656a3c..3e7c943 100644 --- a/lib/libc/stdlib/strtoull.c +++ b/lib/libc/stdlib/strtoull.c @@ -35,6 +35,11 @@ static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ +#ifndef lint +static const char rcsid[] = + "$FreeBSD$"; +#endif + #include <sys/types.h> #include <limits.h> @@ -43,21 +48,21 @@ static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93"; #include <stdlib.h> /* - * Convert a string to an unsigned quad integer. + * Convert a string to an unsigned long long integer. * * Ignores `locale' stuff. Assumes that the upper and lower case * alphabets and digits are each contiguous. */ -u_quad_t -strtouq(nptr, endptr, base) +unsigned long long +strtoull(nptr, endptr, base) const char *nptr; char **endptr; register int base; { register const char *s = nptr; - register u_quad_t acc; + register unsigned long long acc; register unsigned char c; - register u_quad_t qbase, cutoff; + register unsigned long long qbase, cutoff; register int neg, any, cutlim; /* @@ -84,8 +89,8 @@ strtouq(nptr, endptr, base) if (base == 0) base = c == '0' ? 8 : 10; qbase = (unsigned)base; - cutoff = (u_quad_t)UQUAD_MAX / qbase; - cutlim = (u_quad_t)UQUAD_MAX % qbase; + cutoff = (unsigned long long)ULLONG_MAX / qbase; + cutlim = (unsigned long long)ULLONG_MAX % qbase; for (acc = 0, any = 0;; c = *s++) { if (!isascii(c)) break; @@ -106,7 +111,7 @@ strtouq(nptr, endptr, base) } } if (any < 0) { - acc = UQUAD_MAX; + acc = ULLONG_MAX; errno = ERANGE; } else if (neg) acc = -acc; diff --git a/lib/libc/stdlib/strtouq.c b/lib/libc/stdlib/strtouq.c index 7656a3c..6005e5b 100644 --- a/lib/libc/stdlib/strtouq.c +++ b/lib/libc/stdlib/strtouq.c @@ -35,11 +35,11 @@ static char sccsid[] = "@(#)strtouq.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,65 +52,8 @@ u_quad_t strtouq(nptr, endptr, base) const char *nptr; char **endptr; - register int base; + int base; { - register const char *s = nptr; - register u_quad_t acc; - register unsigned char c; - register u_quad_t qbase, cutoff; - register int neg, any, cutlim; - /* - * See strtoq for comments as to the logic used. - */ - 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; - qbase = (unsigned)base; - cutoff = (u_quad_t)UQUAD_MAX / qbase; - cutlim = (u_quad_t)UQUAD_MAX % 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 = UQUAD_MAX; - errno = ERANGE; - } else if (neg) - acc = -acc; - if (endptr != 0) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); + return strtoull(nptr, endptr, base); } |