diff options
| author | David E. O'Brien <obrien@FreeBSD.org> | 2001-02-27 13:33:07 +0000 | 
|---|---|---|
| committer | David E. O'Brien <obrien@FreeBSD.org> | 2001-02-27 13:33:07 +0000 | 
| commit | 4c0440cb8652801c1c3750a474f7ddbb17897cdf (patch) | |
| tree | eb116378d50e15fc35d1602c0784e9b8bd920e36 | |
| parent | 1b0dabf0c01e7ada145b752392609ed5438971df (diff) | |
Notes
| -rw-r--r-- | include/stdlib.h | 4 | ||||
| -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 | 
8 files changed, 115 insertions, 175 deletions
| diff --git a/include/stdlib.h b/include/stdlib.h index 96724bc2f282..372bbcd93954 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -104,8 +104,12 @@ void	*realloc __P((void *, size_t));  void	 srand __P((unsigned));  double	 strtod __P((const char *, char **));  long	 strtol __P((const char *, char **, int)); +long long	  +	 strtoll __P((const char *, char **, int));  unsigned long  	 strtoul __P((const char *, char **, int)); +unsigned long long +	 strtoull __P((const char *, char **, int));  int	 system __P((const char *));  int	 mblen __P((const char *, size_t)); 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 3f28713235b6..eef3031c1e6d 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 f84e030531bb..b7a75903e5e7 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 f84e030531bb..65e87d6618a4 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 d3e9696570ee..ebd92681e146 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 7656a3c53b14..3e7c943fc7f1 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 7656a3c53b14..6005e5bf2d2f 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);  } | 
