From d06bfb1e72b062590705c3818a2c771ae87864cf Mon Sep 17 00:00:00 2001 From: Joerg Sonnenberger Date: Thu, 17 Mar 2005 15:09:01 +0000 Subject: [PATCH] Use a common source for the string to integer conversion. Add strtoimax and strtoumax. Inspired-by: wide char versions. --- lib/libc/stdlib/Makefile.inc | 8 +- lib/libc/stdlib/{strtol.c => _strtol.h} | 118 ++++++++++++-------- lib/libc/stdlib/{strtoul.c => _strtoul.h} | 101 +++++++++-------- lib/libc/stdlib/strtoimax.c | 43 ++++++++ lib/libc/stdlib/strtol.c | 118 +++----------------- lib/libc/stdlib/strtoll.c | 129 +++------------------- lib/libc/stdlib/strtoul.c | 97 +++------------- lib/libc/stdlib/strtoull.c | 105 +++--------------- lib/libc/stdlib/strtoumax.c | 42 +++++++ 9 files changed, 278 insertions(+), 483 deletions(-) copy lib/libc/stdlib/{strtol.c => _strtol.h} (64%) copy lib/libc/stdlib/{strtoul.c => _strtoul.h} (58%) create mode 100644 lib/libc/stdlib/strtoimax.c create mode 100644 lib/libc/stdlib/strtoumax.c diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc index d71d877c10..4abd0d93b5 100644 --- a/lib/libc/stdlib/Makefile.inc +++ b/lib/libc/stdlib/Makefile.inc @@ -1,6 +1,6 @@ # from @(#)Makefile.inc 8.3 (Berkeley) 2/4/95 # $FreeBSD: src/lib/libc/stdlib/Makefile.inc,v 1.19.2.4 2001/10/02 11:15:38 ru Exp $ -# $DragonFly: src/lib/libc/stdlib/Makefile.inc,v 1.10 2005/03/14 14:26:16 joerg Exp $ +# $DragonFly: src/lib/libc/stdlib/Makefile.inc,v 1.11 2005/03/17 15:09:01 joerg Exp $ # machine-independent stdlib sources .PATH: ${.CURDIR}/../libc/${MACHINE_ARCH}/stdlib ${.CURDIR}/../libc/stdlib @@ -8,9 +8,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 getopt_long.c getsubopt.c hcreate.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 strtod.c strtol.c strtoll.c \ - strtonum.c strtoq.c strtoul.c strtoull.c strtouq.c system.c tdelete.c \ - tfind.c tsearch.c twalk.c + random.c reallocf.c realpath.c setenv.c strtod.c strtoimax.c strtol.c \ + strtoll.c strtonum.c strtoq.c strtoul.c strtoull.c strtoumax.c \ + strtouq.c system.c tdelete.c tfind.c tsearch.c twalk.c # machine-dependent stdlib sources .if exists(${.CURDIR}/../libc/${MACHINE_ARCH}/stdlib/Makefile.inc) diff --git a/lib/libc/stdlib/strtol.c b/lib/libc/stdlib/_strtol.h similarity index 64% copy from lib/libc/stdlib/strtol.c copy to lib/libc/stdlib/_strtol.h index 6d81f83f03..ea605640d1 100644 --- a/lib/libc/stdlib/strtol.c +++ b/lib/libc/stdlib/_strtol.h @@ -1,3 +1,5 @@ +/* $DragonFly: src/lib/libc/stdlib/_strtol.h,v 1.1 2005/03/17 15:09:01 joerg Exp $ */ + /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -10,11 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -30,47 +28,54 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)strtol.c 8.1 (Berkeley) 6/4/93 - * $DragonFly: src/lib/libc/stdlib/strtol.c,v 1.3 2003/09/06 08:10:46 asmodai Exp $ + * Original version ID: + * $NetBSD: src/lib/libc/locale/_wcstol.h,v 1.2 2003/08/07 16:43:03 agc Exp $ */ -#include -#include -#include -#include - - /* - * Convert a string to a long integer. + * function template for strtol, strtoll and strtoimax. * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. + * parameters: + * _FUNCNAME : function name + * __INT : return type + * __INT_MIN : lower limit of the return type + * __INT_MAX : upper limit of the return type */ -long -strtol(nptr, endptr, base) - const char *nptr; - char **endptr; - int base; + +__INT +_FUNCNAME(const char *nptr, char **endptr, int base) { - const char *s = nptr; - unsigned long acc; - unsigned char c; - unsigned long cutoff; - int neg = 0, any, cutlim; + const char *s; + __INT acc, cutoff; + char c; + int i, neg, any, cutlim; + + _DIAGASSERT(nptr != NULL); + /* endptr may be NULL */ + + /* check base value */ + if (base && (base < 2 || base > 36)) { + errno = EINVAL; + return(0); + } /* * 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 if (c == '+') - c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { c = s[1]; @@ -97,34 +102,53 @@ strtol(nptr, endptr, base) * Set any if any `digits' consumed; make it negative to indicate * overflow. */ - cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; - cutlim = cutoff % (unsigned long)base; - cutoff /= (unsigned long)base; + cutoff = neg ? __INT_MIN : __INT_MAX; + cutlim = (int)(cutoff % base); + cutoff /= base; + if (neg) { + if (cutlim > 0) { + cutlim -= base; + cutoff += 1; + } + cutlim = -cutlim; + } for (acc = 0, any = 0;; c = *s++) { if (!isascii(c)) break; if (isdigit(c)) - c -= '0'; + i = c - '0'; else if (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; + i = c - (isupper(c) ? 'A' - 10 : 'a' - 10); else break; - if (c >= base) + if (i >= base) break; - if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) - any = -1; - else { - any = 1; - acc *= base; - acc += c; + if (any < 0) + continue; + if (neg) { + if (acc < cutoff || (acc == cutoff && i > cutlim)) { + any = -1; + acc = __INT_MIN; + errno = ERANGE; + } else { + any = 1; + acc *= base; + acc -= i; + } + } else { + if (acc > cutoff || (acc == cutoff && i > cutlim)) { + any = -1; + acc = __INT_MAX; + errno = ERANGE; + } else { + any = 1; + acc *= base; + acc += i; + } } } - if (any < 0) { - acc = neg ? LONG_MIN : LONG_MAX; - errno = ERANGE; - } else if (neg) - acc = -acc; if (endptr != 0) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); + /* LINTED interface specification */ + *endptr = __DECONST(char *, (any ? s - 1 : nptr)); + return(acc); } diff --git a/lib/libc/stdlib/strtoul.c b/lib/libc/stdlib/_strtoul.h similarity index 58% copy from lib/libc/stdlib/strtoul.c copy to lib/libc/stdlib/_strtoul.h index 5516350947..2a89c1da2d 100644 --- a/lib/libc/stdlib/strtoul.c +++ b/lib/libc/stdlib/_strtoul.h @@ -1,4 +1,6 @@ -/* +/* $DragonFly: src/lib/libc/stdlib/_strtoul.h,v 1.1 2005/03/17 15:09:01 joerg Exp $ */ + +/*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * @@ -10,11 +12,7 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * @@ -30,44 +28,53 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)strtoul.c 8.1 (Berkeley) 6/4/93 - * $DragonFly: src/lib/libc/stdlib/strtoul.c,v 1.3 2003/09/06 08:10:46 asmodai Exp $ + * Original version ID: + * $NetBSD: src/lib/libc/locale/_wcstoul.h,v 1.2 2003/08/07 16:43:03 agc Exp $ */ -#include -#include -#include -#include - /* - * Convert a string to an unsigned long integer. + * function template for strtoul, strtoull and strtoumax. * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. + * parameters: + * _FUNCNAME : function name + * __UINT : return type + * __UINT_MAX : upper limit of the return type */ -unsigned long -strtoul(nptr, endptr, base) - const char *nptr; - char **endptr; - int base; + +__UINT +_FUNCNAME(const char *nptr, char **endptr, int base) { - const char *s = nptr; - unsigned long acc; - unsigned char c; - unsigned long cutoff; - int neg = 0, any, cutlim; + const char *s; + __UINT acc, cutoff; + char c; + int i, neg, any, cutlim; + + _DIAGASSERT(nptr != NULL); + /* endptr may be NULL */ + + /* check base value */ + if (base && (base < 2 || base > 36)) { + errno = EINVAL; + return(0); + } /* - * See strtol for comments as to the logic used. + * 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 if (c == '+') - c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { c = s[1]; @@ -76,33 +83,39 @@ strtoul(nptr, endptr, base) } if (base == 0) base = c == '0' ? 8 : 10; - cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; - cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; + + /* + * See strtol for comments as to the logic used. + */ + cutoff = __UINT_MAX / (__UINT)base; + cutlim = (int)(__UINT_MAX % (__UINT)base); for (acc = 0, any = 0;; c = *s++) { if (!isascii(c)) break; if (isdigit(c)) - c -= '0'; + i = c - '0'; else if (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; + i = c - (isupper(c) ? 'A' - 10 : 'a' - 10); else break; - if (c >= base) + if (i >= base) break; - if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) + if (any < 0) + continue; + if (acc > cutoff || (acc == cutoff && i > cutlim)) { any = -1; - else { + acc = __UINT_MAX; + errno = ERANGE; + } else { any = 1; - acc *= base; - acc += c; + acc *= (__UINT)base; + acc += i; } } - if (any < 0) { - acc = ULONG_MAX; - errno = ERANGE; - } else if (neg) + if (neg && any > 0) acc = -acc; if (endptr != 0) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); + /* LINTED interface specification */ + *endptr = __DECONST(char *, (any ? s - 1 : nptr)); + return(acc); } diff --git a/lib/libc/stdlib/strtoimax.c b/lib/libc/stdlib/strtoimax.c new file mode 100644 index 0000000000..228fb44b8d --- /dev/null +++ b/lib/libc/stdlib/strtoimax.c @@ -0,0 +1,43 @@ +/* $DragonFly: src/lib/libc/stdlib/strtoimax.c,v 1.1 2005/03/17 15:09:01 joerg Exp $ */ + +/*- + * Copyright (c) 2005 The DragonFly Project. All rigths reserved. + * Copyright (c)2003 Citrus Project, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define _FUNCNAME strtoimax +#define __INT intmax_t +#define __INT_MIN INTMAX_MIN +#define __INT_MAX INTMAX_MAX + +#include "_strtol.h" diff --git a/lib/libc/stdlib/strtol.c b/lib/libc/stdlib/strtol.c index 6d81f83f03..f3e66498c5 100644 --- a/lib/libc/stdlib/strtol.c +++ b/lib/libc/stdlib/strtol.c @@ -1,6 +1,9 @@ +/* $DragonFly: src/lib/libc/stdlib/strtol.c,v 1.4 2005/03/17 15:09:01 joerg Exp $ */ + /*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. + * Copyright (c) 2005 The DragonFly Project. All rigths reserved. + * Copyright (c)2003 Citrus Project, + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,18 +13,11 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) @@ -29,102 +25,18 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)strtol.c 8.1 (Berkeley) 6/4/93 - * $DragonFly: src/lib/libc/stdlib/strtol.c,v 1.3 2003/09/06 08:10:46 asmodai Exp $ */ -#include +#include #include #include +#include +#include #include +#define _FUNCNAME strtol +#define __INT long +#define __INT_MIN LONG_MIN +#define __INT_MAX LONG_MAX -/* - * Convert a string to a long integer. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -long -strtol(nptr, endptr, base) - const char *nptr; - char **endptr; - int base; -{ - const char *s = nptr; - unsigned long acc; - unsigned char c; - unsigned long cutoff; - int neg = 0, 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. - */ - do { - c = *s++; - } while (isspace(c)); - if (c == '-') { - neg = 1; - c = *s++; - } else 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 longs is - * [-2147483648..2147483647] and the input base is 10, - * cutoff will be set to 214748364 and cutlim to either - * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated - * a value > 214748364, 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. - */ - cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; - cutlim = cutoff % (unsigned long)base; - cutoff /= (unsigned long)base; - 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 *= base; - acc += c; - } - } - if (any < 0) { - acc = neg ? LONG_MIN : LONG_MAX; - errno = ERANGE; - } else if (neg) - acc = -acc; - if (endptr != 0) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); -} +#include "_strtol.h" diff --git a/lib/libc/stdlib/strtoll.c b/lib/libc/stdlib/strtoll.c index b1038091f5..df554f308f 100644 --- a/lib/libc/stdlib/strtoll.c +++ b/lib/libc/stdlib/strtoll.c @@ -1,6 +1,9 @@ +/* $DragonFly: src/lib/libc/stdlib/strtoll.c,v 1.4 2005/03/17 15:09:01 joerg Exp $ */ + /*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. + * Copyright (c) 2005 The DragonFly Project. All rigths reserved. + * Copyright (c)2003 Citrus Project, + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,18 +13,11 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) @@ -29,111 +25,18 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)strtoq.c 8.1 (Berkeley) 6/4/93 - * $FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $ - * $DragonFly: src/lib/libc/stdlib/strtoll.c,v 1.3 2003/09/06 08:10:46 asmodai Exp $ */ -#include - -#include -#include +#include #include +#include +#include +#include #include -/* - * Convert a string to a long long integer. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -long long -strtoll(nptr, endptr, base) - const char *nptr; - char **endptr; - int base; -{ - const char *s; - unsigned long long acc; - unsigned char c; - unsigned long long qbase, cutoff; - 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; +#define _FUNCNAME strtoll +#define __INT long long +#define __INT_MIN LLONG_MIN +#define __INT_MAX LLONG_MAX - /* - * 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 ? (unsigned long long)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX - : LLONG_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 ? LLONG_MIN : LLONG_MAX; - errno = ERANGE; - } else if (neg) - acc = -acc; - if (endptr != 0) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); -} +#include "_strtol.h" diff --git a/lib/libc/stdlib/strtoul.c b/lib/libc/stdlib/strtoul.c index 5516350947..068d0fe6d4 100644 --- a/lib/libc/stdlib/strtoul.c +++ b/lib/libc/stdlib/strtoul.c @@ -1,6 +1,9 @@ -/* - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. +/* $DragonFly: src/lib/libc/stdlib/strtoul.c,v 1.4 2005/03/17 15:09:01 joerg Exp $ */ + +/*- + * Copyright (c) 2005 The DragonFly Project. All rigths reserved. + * Copyright (c)2003 Citrus Project, + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,18 +13,11 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) @@ -29,80 +25,17 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)strtoul.c 8.1 (Berkeley) 6/4/93 - * $DragonFly: src/lib/libc/stdlib/strtoul.c,v 1.3 2003/09/06 08:10:46 asmodai Exp $ */ -#include +#include #include #include +#include +#include #include -/* - * Convert a string to an unsigned long integer. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -unsigned long -strtoul(nptr, endptr, base) - const char *nptr; - char **endptr; - int base; -{ - const char *s = nptr; - unsigned long acc; - unsigned char c; - unsigned long cutoff; - int neg = 0, any, cutlim; +#define _FUNCNAME strtoul +#define __UINT unsigned long int +#define __UINT_MAX ULONG_MAX - /* - * See strtol for comments as to the logic used. - */ - do { - c = *s++; - } while (isspace(c)); - if (c == '-') { - neg = 1; - c = *s++; - } else 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; - cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; - cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; - 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 *= base; - acc += c; - } - } - if (any < 0) { - acc = ULONG_MAX; - errno = ERANGE; - } else if (neg) - acc = -acc; - if (endptr != 0) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); -} +#include "_strtoul.h" diff --git a/lib/libc/stdlib/strtoull.c b/lib/libc/stdlib/strtoull.c index ebff14b71d..489bf8ee71 100644 --- a/lib/libc/stdlib/strtoull.c +++ b/lib/libc/stdlib/strtoull.c @@ -1,6 +1,9 @@ +/* $DragonFly: src/lib/libc/stdlib/strtoull.c,v 1.4 2005/03/17 15:09:01 joerg Exp $ */ + /*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. + * Copyright (c) 2005 The DragonFly Project. All rigths reserved. + * Copyright (c)2003 Citrus Project, + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -10,18 +13,11 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) @@ -29,88 +25,17 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * @(#)strtouq.c 8.1 (Berkeley) 6/4/93 - * $FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $ - * $DragonFly: src/lib/libc/stdlib/strtoull.c,v 1.3 2003/09/06 08:10:46 asmodai Exp $ */ -#include - -#include -#include +#include #include +#include +#include +#include #include -/* - * 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. - */ -unsigned long long -strtoull(nptr, endptr, base) - const char *nptr; - char **endptr; - int base; -{ - const char *s = nptr; - unsigned long long acc; - unsigned char c; - unsigned long long qbase, cutoff; - int neg, any, cutlim; +#define _FUNCNAME strtoull +#define __UINT unsigned long long int +#define __UINT_MAX ULLONG_MAX - /* - * 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 = (unsigned long long)ULLONG_MAX / qbase; - cutlim = (unsigned long long)ULLONG_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 = ULLONG_MAX; - errno = ERANGE; - } else if (neg) - acc = -acc; - if (endptr != 0) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); -} +#include "_strtoul.h" diff --git a/lib/libc/stdlib/strtoumax.c b/lib/libc/stdlib/strtoumax.c new file mode 100644 index 0000000000..4fe98a1de6 --- /dev/null +++ b/lib/libc/stdlib/strtoumax.c @@ -0,0 +1,42 @@ +/* $DragonFly: src/lib/libc/stdlib/strtoumax.c,v 1.1 2005/03/17 15:09:01 joerg Exp $ */ + +/*- + * Copyright (c) 2005 The DragonFly Project. All rigths reserved. + * Copyright (c)2003 Citrus Project, + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define _FUNCNAME strtoumax +#define __UINT uintmax_t +#define __UINT_MAX UINTMAX_MAX + +#include "_strtoul.h" -- 2.41.0