From dd5515b863438db34ae9c2c44ff353de38442092 Mon Sep 17 00:00:00 2001 From: Joris Giovannangeli Date: Wed, 2 Oct 2013 00:31:50 +0200 Subject: [PATCH] libc/stdlib : revert to dragonfly implementation * Revert to 2d5c7e410ffcb72d10994a0d1d324b7265e29647. The dragonfly version shares code for the various functions of the strtol familly, using macros. * add locale aware version for the functions the strtol familly. Only isspace calls are concerned. --- lib/libc/stdlib/_strtol.h | 18 ++++- lib/libc/stdlib/_strtoul.h | 18 ++++- lib/libc/stdlib/strtoimax.c | 137 ++++-------------------------------- lib/libc/stdlib/strtol.c | 137 ++++-------------------------------- lib/libc/stdlib/strtoll.c | 1 + lib/libc/stdlib/strtoul.c | 1 + lib/libc/stdlib/strtoull.c | 1 + lib/libc/stdlib/strtoumax.c | 114 ++++-------------------------- 8 files changed, 78 insertions(+), 349 deletions(-) diff --git a/lib/libc/stdlib/_strtol.h b/lib/libc/stdlib/_strtol.h index c593b61180..d170f1bc4f 100644 --- a/lib/libc/stdlib/_strtol.h +++ b/lib/libc/stdlib/_strtol.h @@ -30,6 +30,10 @@ * $NetBSD: src/lib/libc/locale/_wcstol.h,v 1.2 2003/08/07 16:43:03 agc Exp $ */ +#define _LOCALE_NAME(func) func ## _l +#define _MAKE_LOCALE_NAME(func) _LOCALE_NAME(func) +#define _FUNCNAME_L _MAKE_LOCALE_NAME(_FUNCNAME) + /* * function template for strtol, strtoll and strtoimax. * @@ -39,9 +43,9 @@ * __INT_MIN : lower limit of the return type * __INT_MAX : upper limit of the return type */ - __INT -_FUNCNAME(const char *nptr, char **endptr, int base) +_FUNCNAME_L(const char * __restrict nptr, char ** __restrict endptr, int base, + locale_t locale) { const char *s; __INT acc, cutoff; @@ -51,6 +55,8 @@ _FUNCNAME(const char *nptr, char **endptr, int base) _DIAGASSERT(nptr != NULL); /* endptr may be NULL */ + FIX_LOCALE(locale); + /* check base value */ if (base && (base < 2 || base > 36)) { errno = EINVAL; @@ -65,7 +71,7 @@ _FUNCNAME(const char *nptr, char **endptr, int base) s = nptr; do { c = *s++; - } while (isspace(c)); + } while (isspace_l((unsigned char)c, locale)); if (c == '-') { neg = 1; c = *s++; @@ -150,3 +156,9 @@ _FUNCNAME(const char *nptr, char **endptr, int base) *endptr = __DECONST(char *, (any ? s - 1 : nptr)); return(acc); } + +__INT +_FUNCNAME(const char * __restrict nptr, char ** __restrict endptr, int base) +{ + return _FUNCNAME_L(nptr, endptr, base, __get_locale()); +} diff --git a/lib/libc/stdlib/_strtoul.h b/lib/libc/stdlib/_strtoul.h index 598aa50314..23e74c9d0d 100644 --- a/lib/libc/stdlib/_strtoul.h +++ b/lib/libc/stdlib/_strtoul.h @@ -30,6 +30,10 @@ * $NetBSD: src/lib/libc/locale/_wcstoul.h,v 1.2 2003/08/07 16:43:03 agc Exp $ */ +#define _LOCALE_NAME(func) func ## _l +#define _MAKE_LOCALE_NAME(func) _LOCALE_NAME(func) +#define _FUNCNAME_L _MAKE_LOCALE_NAME(_FUNCNAME) + /* * function template for strtoul, strtoull and strtoumax. * @@ -40,7 +44,8 @@ */ __UINT -_FUNCNAME(const char *nptr, char **endptr, int base) +_FUNCNAME_L(const char * __restrict nptr, char ** __restrict endptr, int base, + locale_t locale) { const char *s; __UINT acc, cutoff; @@ -50,6 +55,8 @@ _FUNCNAME(const char *nptr, char **endptr, int base) _DIAGASSERT(nptr != NULL); /* endptr may be NULL */ + FIX_LOCALE(locale); + /* check base value */ if (base && (base < 2 || base > 36)) { errno = EINVAL; @@ -64,7 +71,7 @@ _FUNCNAME(const char *nptr, char **endptr, int base) s = nptr; do { c = *s++; - } while (isspace(c)); + } while (isspace_l((unsigned char)c, locale)); if (c == '-') { neg = 1; c = *s++; @@ -117,3 +124,10 @@ _FUNCNAME(const char *nptr, char **endptr, int base) *endptr = __DECONST(char *, (any ? s - 1 : nptr)); return(acc); } + + +__UINT +_FUNCNAME(const char * __restrict nptr, char ** __restrict endptr, int base) +{ + return _FUNCNAME_L(nptr, endptr, base, __get_locale()); +} diff --git a/lib/libc/stdlib/strtoimax.c b/lib/libc/stdlib/strtoimax.c index 7b1ce8f098..dfb9dda788 100644 --- a/lib/libc/stdlib/strtoimax.c +++ b/lib/libc/stdlib/strtoimax.c @@ -1,11 +1,9 @@ +/* $DragonFly: src/lib/libc/stdlib/strtoimax.c,v 1.2 2008/08/19 15:50:24 joerg Exp $ */ + /*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Copyright (c) 2011 The FreeBSD Foundation + * Copyright (c) 2005 The DragonFly Project. All rights reserved. + * Copyright (c) 2003 Citrus Project, * All rights reserved. - * Portions of this software were developed by David Chisnall - * under sponsorship from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -15,14 +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. 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) @@ -30,122 +25,20 @@ * 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. - * - * from @(#)strtol.c 8.1 (Berkeley) 6/4/93 - * $FreeBSD: head/lib/libc/stdlib/strtoimax.c 251672 2013-06-13 00:19:30Z emaste $ */ - +#include #include #include -#include #include +#include +#include +#include #include "xlocale_private.h" -/* - * Convert a string to an intmax_t integer. - * - * Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -intmax_t -strtoimax_l(const char * __restrict nptr, char ** __restrict endptr, int base, - locale_t locale) -{ - const char *s; - uintmax_t acc; - char c; - uintmax_t cutoff; - int neg, any, cutlim; - FIX_LOCALE(locale); - - /* - * 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_l((unsigned char)c, locale)); - if (c == '-') { - neg = 1; - c = *s++; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X') && - ((s[1] >= '0' && s[1] <= '9') || - (s[1] >= 'A' && s[1] <= 'F') || - (s[1] >= 'a' && s[1] <= 'f'))) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - acc = any = 0; - if (base < 2 || base > 36) - goto noconv; +#define _FUNCNAME strtoimax +#define __INT intmax_t +#define __INT_MIN INTMAX_MIN +#define __INT_MAX INTMAX_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 intmax_t 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. - */ - cutoff = neg ? (uintmax_t)-(INTMAX_MIN + INTMAX_MAX) + INTMAX_MAX - : INTMAX_MAX; - cutlim = cutoff % base; - cutoff /= base; - for ( ; ; c = *s++) { - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'A' && c <= 'Z') - c -= 'A' - 10; - else if (c >= 'a' && c <= 'z') - c -= '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 ? INTMAX_MIN : INTMAX_MAX; - errno = ERANGE; - } else if (!any) { -noconv: - errno = EINVAL; - } else if (neg) - acc = -acc; - if (endptr != NULL) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); -} -intmax_t -strtoimax(const char * __restrict nptr, char ** __restrict endptr, int base) -{ - return strtoimax_l(nptr, endptr, base, __get_locale()); -} +#include "_strtol.h" diff --git a/lib/libc/stdlib/strtol.c b/lib/libc/stdlib/strtol.c index 2310b2fd8b..b555be0c36 100644 --- a/lib/libc/stdlib/strtol.c +++ b/lib/libc/stdlib/strtol.c @@ -1,11 +1,9 @@ +/* $DragonFly: src/lib/libc/stdlib/strtol.c,v 1.5 2008/08/19 15:50:24 joerg Exp $ */ + /*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Copyright (c) 2011 The FreeBSD Foundation + * Copyright (c) 2005 The DragonFly Project. All rights reserved. + * Copyright (c) 2003 Citrus Project, * All rights reserved. - * Portions of this software were developed by David Chisnall - * under sponsorship from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -15,14 +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. 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) @@ -30,127 +25,25 @@ * 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 - * $FreeBSD: head/lib/libc/stdlib/strtol.c 251672 2013-06-13 00:19:30Z emaste $ */ - -#include +#include #include #include +#include +#include #include #include "xlocale_private.h" +#define _FUNCNAME strtol +#define __INT long +#define __INT_MIN LONG_MIN +#define __INT_MAX LONG_MAX -/* - * Convert a string to a long integer. - * - * Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -long -strtol_l(const char * __restrict nptr, char ** __restrict endptr, int base, - locale_t locale) -{ - const char *s; - unsigned long acc; - char c; - unsigned long cutoff; - int neg, any, cutlim; - FIX_LOCALE(locale); - - /* - * 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_l((unsigned char)c, locale)); - if (c == '-') { - neg = 1; - c = *s++; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X') && - ((s[1] >= '0' && s[1] <= '9') || - (s[1] >= 'A' && s[1] <= 'F') || - (s[1] >= 'a' && s[1] <= 'f'))) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - acc = any = 0; - if (base < 2 || base > 36) - goto noconv; +#include "_strtol.h" - /* - * 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) + LONG_MAX - : LONG_MAX; - cutlim = cutoff % base; - cutoff /= base; - for ( ; ; c = *s++) { - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'A' && c <= 'Z') - c -= 'A' - 10; - else if (c >= 'a' && c <= 'z') - c -= '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 (!any) { -noconv: - errno = EINVAL; - } else if (neg) - acc = -acc; - if (endptr != NULL) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); -} -long -strtol(const char * __restrict nptr, char ** __restrict endptr, int base) -{ - return strtol_l(nptr, endptr, base, __get_locale()); -} long double strtold(const char * __restrict nptr, char ** __restrict endptr) { - return strtold_l(nptr, endptr, __get_locale()); + return strtold_l(nptr, endptr, __get_locale()); } diff --git a/lib/libc/stdlib/strtoll.c b/lib/libc/stdlib/strtoll.c index 6d45ae0082..e489079513 100644 --- a/lib/libc/stdlib/strtoll.c +++ b/lib/libc/stdlib/strtoll.c @@ -33,6 +33,7 @@ #include #include #include +#include "xlocale_private.h" #define _FUNCNAME strtoll #define __INT long long diff --git a/lib/libc/stdlib/strtoul.c b/lib/libc/stdlib/strtoul.c index 244fd45955..f5c85d74db 100644 --- a/lib/libc/stdlib/strtoul.c +++ b/lib/libc/stdlib/strtoul.c @@ -33,6 +33,7 @@ #include #include #include +#include "xlocale_private.h" #define _FUNCNAME strtoul #define __UINT unsigned long int diff --git a/lib/libc/stdlib/strtoull.c b/lib/libc/stdlib/strtoull.c index 18954d5d85..f7ade94cea 100644 --- a/lib/libc/stdlib/strtoull.c +++ b/lib/libc/stdlib/strtoull.c @@ -33,6 +33,7 @@ #include #include #include +#include "xlocale_private.h" #define _FUNCNAME strtoull #define __UINT unsigned long long int diff --git a/lib/libc/stdlib/strtoumax.c b/lib/libc/stdlib/strtoumax.c index 3bd82abd27..dd053a0519 100644 --- a/lib/libc/stdlib/strtoumax.c +++ b/lib/libc/stdlib/strtoumax.c @@ -1,11 +1,9 @@ +/* $DragonFly: src/lib/libc/stdlib/strtoumax.c,v 1.2 2008/08/19 15:50:24 joerg Exp $ */ + /*- - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * Copyright (c) 2011 The FreeBSD Foundation + * Copyright (c) 2005 The DragonFly Project. All rights reserved. + * Copyright (c) 2003 Citrus Project, * All rights reserved. - * Portions of this software were developed by David Chisnall - * under sponsorship from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -15,14 +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. 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) @@ -30,100 +25,19 @@ * 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. - * - * from @(#)strtoul.c 8.1 (Berkeley) 6/4/93 - * $FreeBSD: head/lib/libc/stdlib/strtoumax.c 251672 2013-06-13 00:19:30Z emaste $ */ - +#include #include #include -#include #include +#include +#include +#include #include "xlocale_private.h" -/* - * Convert a string to a uintmax_t integer. - * - * Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -uintmax_t -strtoumax_l(const char * __restrict nptr, char ** __restrict endptr, int base, - locale_t locale) -{ - const char *s; - uintmax_t acc; - char c; - uintmax_t cutoff; - int neg, any, cutlim; - FIX_LOCALE(locale); - - /* - * See strtoimax for comments as to the logic used. - */ - s = nptr; - do { - c = *s++; - } while (isspace_l((unsigned char)c, locale)); - if (c == '-') { - neg = 1; - c = *s++; - } else { - neg = 0; - if (c == '+') - c = *s++; - } - if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X') && - ((s[1] >= '0' && s[1] <= '9') || - (s[1] >= 'A' && s[1] <= 'F') || - (s[1] >= 'a' && s[1] <= 'f'))) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - acc = any = 0; - if (base < 2 || base > 36) - goto noconv; +#define _FUNCNAME strtoumax +#define __UINT uintmax_t +#define __UINT_MAX UINTMAX_MAX - cutoff = UINTMAX_MAX / base; - cutlim = UINTMAX_MAX % base; - for ( ; ; c = *s++) { - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'A' && c <= 'Z') - c -= 'A' - 10; - else if (c >= 'a' && c <= 'z') - c -= '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 = UINTMAX_MAX; - errno = ERANGE; - } else if (!any) { -noconv: - errno = EINVAL; - } else if (neg) - acc = -acc; - if (endptr != NULL) - *endptr = (char *)(any ? s - 1 : nptr); - return (acc); -} -uintmax_t -strtoumax(const char * __restrict nptr, char ** __restrict endptr, int base) -{ - return strtoumax_l(nptr, endptr, base, __get_locale()); -} +#include "_strtoul.h" -- 2.41.0