summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authorobrien <obrien@FreeBSD.org>2001-02-27 13:33:07 +0000
committerobrien <obrien@FreeBSD.org>2001-02-27 13:33:07 +0000
commitbb70e1687a5a72cc582496d32293aed2b63f5647 (patch)
treea6ddbcda2c8416d0bced69bd65a91d752bc75d50 /lib/libc
parenta7aa01b9b6a44b97d7111edaa5ab21b829093ccd (diff)
downloadFreeBSD-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.inc9
-rw-r--r--lib/libc/stdlib/strtol.337
-rw-r--r--lib/libc/stdlib/strtoll.c20
-rw-r--r--lib/libc/stdlib/strtoq.c91
-rw-r--r--lib/libc/stdlib/strtoul.339
-rw-r--r--lib/libc/stdlib/strtoull.c21
-rw-r--r--lib/libc/stdlib/strtouq.c69
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);
}
OpenPOWER on IntegriCloud