diff options
| author | David E. O'Brien <obrien@FreeBSD.org> | 2001-03-02 09:45:20 +0000 |
|---|---|---|
| committer | David E. O'Brien <obrien@FreeBSD.org> | 2001-03-02 09:45:20 +0000 |
| commit | 77151c207255e021c90b2b7e67374f3487156f8f (patch) | |
| tree | 85bc201aea5aa3e50c83eea2626be3150960f8f9 /lib/libc/stdlib | |
| parent | 6d79b0605089d5b8f248073e140755db35859824 (diff) | |
Notes
Diffstat (limited to 'lib/libc/stdlib')
| -rw-r--r-- | lib/libc/stdlib/Makefile.inc | 9 | ||||
| -rw-r--r-- | lib/libc/stdlib/strtol.3 | 40 | ||||
| -rw-r--r-- | lib/libc/stdlib/strtoq.c | 91 | ||||
| -rw-r--r-- | lib/libc/stdlib/strtoul.3 | 42 | ||||
| -rw-r--r-- | lib/libc/stdlib/strtouq.c | 69 |
5 files changed, 91 insertions, 160 deletions
diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc index 12ec5d4cad78..bd82afe96e47 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 efa4385f164e..00a65c58c433 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 a 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 . @@ -165,6 +188,15 @@ The .Fn strtol function conforms to -.St -ansiC . +.St -isoC . +The +.Fn strtoll +function +conforms to +.St -isoC-99 . +The +.Bx +.Fn strtoq +function is deprecated. .Sh BUGS Ignores the current locale. diff --git a/lib/libc/stdlib/strtoq.c b/lib/libc/stdlib/strtoq.c index f84e030531bb..ee68b4e56a33 100644 --- a/lib/libc/stdlib/strtoq.c +++ b/lib/libc/stdlib/strtoq.c @@ -35,11 +35,13 @@ 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> -#include <errno.h> -#include <ctype.h> #include <stdlib.h> /* @@ -52,87 +54,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 1bde3e931204..6f89af8e444e 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 @@ -160,6 +181,15 @@ The .Fn strtoul function conforms to -.St -ansiC . +.St -isoC . +The +.Fn strtoull +function +conforms to +.St -isoC-99 . +The +.Bx +.Fn strtoq +function is deprecated. .Sh BUGS Ignores the current locale. diff --git a/lib/libc/stdlib/strtouq.c b/lib/libc/stdlib/strtouq.c index 7656a3c53b14..926000e6e7f4 100644 --- a/lib/libc/stdlib/strtouq.c +++ b/lib/libc/stdlib/strtouq.c @@ -35,11 +35,13 @@ 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> -#include <errno.h> -#include <ctype.h> #include <stdlib.h> /* @@ -52,65 +54,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); } |
