From 238455adfab4f8070ac65400aac22bb8a9e502fc Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 10 Aug 2016 16:30:46 +0200 Subject: [PATCH] Implement strto[dflu]_l/wcsto[dflu]_l Implement GNU extensions strtod_l, strtof_l, strtol_l, strtold_l, strtoll_l, strtoul_l, strtoull_l, wcstod_l, wcstof_l, wcstol_l, wcstold_l, wcstoll_l, wcstoul_l, wcstoull_l. Export from Cygwin, fix posix.xml. Signed-off-by: Corinna Vinschen --- newlib/libc/include/stdlib.h | 19 ++++ newlib/libc/include/wchar.h | 13 +++ newlib/libc/locale/setlocale.h | 3 + newlib/libc/stdlib/gdtoa-gethex.c | 13 +-- newlib/libc/stdlib/mprec.h | 12 ++- newlib/libc/stdlib/strtod.c | 110 ++++++++++++++----- newlib/libc/stdlib/strtodg.c | 89 +++++----------- newlib/libc/stdlib/strtol.c | 75 +++++++++---- newlib/libc/stdlib/strtold.c | 28 ++++- newlib/libc/stdlib/strtoll.c | 137 ++++++++++++++++++++++-- newlib/libc/stdlib/strtoll_r.c | 141 +------------------------ newlib/libc/stdlib/strtorx.c | 7 +- newlib/libc/stdlib/strtoul.c | 74 +++++++++---- newlib/libc/stdlib/strtoull.c | 117 +++++++++++++++++--- newlib/libc/stdlib/strtoull_r.c | 121 +-------------------- newlib/libc/stdlib/wcsnrtombs.c | 28 +++-- newlib/libc/stdlib/wcstod.c | 110 ++++++++++++++----- newlib/libc/stdlib/wcstol.c | 73 +++++++++---- newlib/libc/stdlib/wcstold.c | 28 +++-- newlib/libc/stdlib/wcstoll.c | 137 ++++++++++++++++++++++-- newlib/libc/stdlib/wcstoll_r.c | 141 +------------------------ newlib/libc/stdlib/wcstoul.c | 68 ++++++++---- newlib/libc/stdlib/wcstoull.c | 131 +++++++++++++++++++++-- newlib/libc/stdlib/wcstoull_r.c | 131 +---------------------- winsup/cygwin/common.din | 14 +++ winsup/cygwin/include/cygwin/version.h | 5 +- winsup/doc/posix.xml | 22 +++- 27 files changed, 1035 insertions(+), 812 deletions(-) diff --git a/newlib/libc/include/stdlib.h b/newlib/libc/include/stdlib.h index 3d1b8a9b0..7b62e004f 100644 --- a/newlib/libc/include/stdlib.h +++ b/newlib/libc/include/stdlib.h @@ -26,6 +26,10 @@ #include #endif +#if __GNU_VISIBLE +#include +#endif + _BEGIN_STD_C typedef struct @@ -164,6 +168,21 @@ long _EXFUN(_strtol_r,(struct _reent *,const char *__restrict __n, char **__rest unsigned long _EXFUN(strtoul,(const char *__restrict __n, char **__restrict __end_PTR, int __base)); unsigned long _EXFUN(_strtoul_r,(struct _reent *,const char *__restrict __n, char **__restrict __end_PTR, int __base)); +#if __GNU_VISIBLE +double strtod_l (const char *__restrict, char **__restrict, locale_t); +float strtof_l (const char *__restrict, char **__restrict, locale_t); +#ifdef _HAVE_LONG_DOUBLE +extern long double strtold_l (const char *__restrict, char **__restrict, + locale_t); +#endif /* _HAVE_LONG_DOUBLE */ +long strtol_l (const char *__restrict, char **__restrict, int, locale_t); +unsigned long strtoul_l (const char *__restrict, char **__restrict, int, + locale_t __loc); +long long strtoll_l (const char *__restrict, char **__restrict, int, locale_t); +unsigned long long strtoull_l (const char *__restrict, char **__restrict, int, + locale_t __loc); +#endif + int _EXFUN(system,(const char *__string)); #if __SVID_VISIBLE || __XSI_VISIBLE >= 4 diff --git a/newlib/libc/include/wchar.h b/newlib/libc/include/wchar.h index 4df60b4c2..b7f8374e5 100644 --- a/newlib/libc/include/wchar.h +++ b/newlib/libc/include/wchar.h @@ -203,6 +203,19 @@ unsigned long long _EXFUN(_wcstoull_r, (struct _reent *, const wchar_t *, wchar_ long double _EXFUN(wcstold, (const wchar_t *, wchar_t **)); #endif +#if __GNU_VISIBLE +long wcstol_l (const wchar_t *__restrict, wchar_t **__restrict, int, locale_t); +long long wcstoll_l (const wchar_t *__restrict, wchar_t **__restrict, int, + locale_t); +unsigned long wcstoul_l (const wchar_t *__restrict, wchar_t **__restrict, int, + locale_t); +unsigned long long wcstoull_l (const wchar_t *__restrict, wchar_t **__restrict, + int, locale_t); +double wcstod_l (const wchar_t *, wchar_t **, locale_t); +float wcstof_l (const wchar_t *, wchar_t **, locale_t); +long double wcstold_l (const wchar_t *, wchar_t **, locale_t); +#endif + wint_t _EXFUN(fgetwc, (__FILE *)); wchar_t *_EXFUN(fgetws, (wchar_t *__restrict, int, __FILE *__restrict)); wint_t _EXFUN(fputwc, (wchar_t, __FILE *)); diff --git a/newlib/libc/locale/setlocale.h b/newlib/libc/locale/setlocale.h index b528ab92f..de2bd6733 100644 --- a/newlib/libc/locale/setlocale.h +++ b/newlib/libc/locale/setlocale.h @@ -202,6 +202,9 @@ extern const char *__get_locale_env(struct _reent *, int); extern struct lconv *__localeconv_l (struct __locale_t *locale); +extern size_t _wcsnrtombs_l (struct _reent *, char *, const wchar_t **, + size_t, size_t, mbstate_t *, locale_t); + /* In POSIX terms the global locale is the process-wide locale. Use this function to always refer to the global locale. */ _ELIDABLE_INLINE struct __locale_t * diff --git a/newlib/libc/stdlib/gdtoa-gethex.c b/newlib/libc/stdlib/gdtoa-gethex.c index 3449c989e..fd3903c4f 100644 --- a/newlib/libc/stdlib/gdtoa-gethex.c +++ b/newlib/libc/stdlib/gdtoa-gethex.c @@ -32,10 +32,10 @@ THIS SOFTWARE. #include <_ansi.h> #include #include +#include #include "mprec.h" #include "gdtoa.h" #include "gd_qnan.h" -#include "locale.h" #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) && !defined(_SMALL_HEXDIG) _CONST unsigned char __hexdig[256]= @@ -145,13 +145,8 @@ _DEFUN (increment, (ptr, b), int -_DEFUN(gethex, (ptr, sp, fpi, exp, bp, sign), - struct _reent *ptr _AND - _CONST char **sp _AND - _CONST FPI *fpi _AND - Long *exp _AND - _Bigint **bp _AND - int sign) +gethex (struct _reent *ptr, const char **sp, const FPI *fpi, + Long *exp, _Bigint **bp, int sign, locale_t loc) { _Bigint *b; _CONST unsigned char *decpt, *s0, *s, *s1; @@ -159,7 +154,7 @@ _DEFUN(gethex, (ptr, sp, fpi, exp, bp, sign), __ULong L, lostbits, *x; Long e, e1; unsigned char *decimalpoint = (unsigned char *) - _localeconv_r (ptr)->decimal_point; + __localeconv_l (loc)->decimal_point; size_t decp_len = strlen ((const char *) decimalpoint); unsigned char decp_end = decimalpoint[decp_len - 1]; diff --git a/newlib/libc/stdlib/mprec.h b/newlib/libc/stdlib/mprec.h index afda63e73..330c3981b 100644 --- a/newlib/libc/stdlib/mprec.h +++ b/newlib/libc/stdlib/mprec.h @@ -32,6 +32,7 @@ #include #include #include +#include "../locale/setlocale.h" #ifdef __IEEE_LITTLE_ENDIAN #define IEEE_8087 @@ -400,13 +401,18 @@ _Bigint * _EXFUN(lshift,(struct _reent *p, _Bigint *b, int k)); int _EXFUN(match,(const char**, char*)); _Bigint * _EXFUN(diff,(struct _reent *p, _Bigint *a, _Bigint *b)); int _EXFUN(cmp,(_Bigint *a, _Bigint *b)); -int _EXFUN(gethex,(struct _reent *p, _CONST char **sp, _CONST struct FPI *fpi, Long *exp, _Bigint **bp, int sign)); +int _EXFUN(gethex,(struct _reent *p, _CONST char **sp, _CONST struct FPI *fpi, Long *exp, _Bigint **bp, int sign, locale_t loc)); double _EXFUN(ratio,(_Bigint *a, _Bigint *b)); __ULong _EXFUN(any_on,(_Bigint *b, int k)); void _EXFUN(copybits,(__ULong *c, int n, _Bigint *b)); +double _strtod_l (struct _reent *ptr, const char *__restrict s00, + char **__restrict se, locale_t loc); #if defined (_HAVE_LONG_DOUBLE) && !defined (_LDBL_EQ_DBL) -int _EXFUN(_strtorx_r,(struct _reent *, _CONST char *, char **, int, void *)); -int _EXFUN(_strtodg_r,(struct _reent *p, _CONST char *s00, char **se, struct FPI *fpi, Long *exp, __ULong *bits)); +int _strtorx_l (struct _reent *, const char *, char **, int, + void *, locale_t); +int _strtodg_l (struct _reent *p, const char *s00, char **se, + struct FPI *fpi, Long *exp, __ULong *bits, + locale_t); #endif /* _HAVE_LONG_DOUBLE && !_LDBL_EQ_DBL */ #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) || defined(_SMALL_HEXDIG) diff --git a/newlib/libc/stdlib/strtod.c b/newlib/libc/stdlib/strtod.c index 433dc7f32..e908fcbbc 100644 --- a/newlib/libc/stdlib/strtod.c +++ b/newlib/libc/stdlib/strtod.c @@ -1,18 +1,43 @@ /* FUNCTION - <>, <>---string to double or float + <>, <>, <>, <>, <>, <>---string to double or float INDEX strtod -INDEX - _strtod_r + INDEX strtof +INDEX + strtold + +INDEX + strtod_l + +INDEX + strtof_l + +INDEX + strtold_l + +INDEX + _strtod_r + ANSI_SYNOPSIS #include double strtod(const char *restrict <[str]>, char **restrict <[tail]>); float strtof(const char *restrict <[str]>, char **restrict <[tail]>); + long double strtold(const char *restrict <[str]>, + char **restrict <[tail]>); + + #include + double strtod_l(const char *restrict <[str]>, char **restrict <[tail]>, + locale_t <[locale]>); + float strtof_l(const char *restrict <[str]>, char **restrict <[tail]>, + locale_t <[locale]>); + long double strtold_l(const char *restrict <[str]>, + char **restrict <[tail]>, + locale_t <[locale]>); double _strtod_r(void *<[reent]>, const char *restrict <[str]>, char **restrict <[tail]>); @@ -33,11 +58,11 @@ TRAD_SYNOPSIS char **<[tail]>; DESCRIPTION - The function <> parses the character string <[str]>, - producing a substring which can be converted to a double - value. The substring converted is the longest initial - subsequence of <[str]>, beginning with the first - non-whitespace character, that has one of these formats: + <>, <>, <> parse the character string + <[str]>, producing a substring which can be converted to a double, + float, or long double value, respectively. The substring converted + is the longest initial subsequence of <[str]>, beginning with the + first non-whitespace character, that has one of these formats: .[+|-]<[digits]>[.[<[digits]>]][(e|E)[+|-]<[digits]>] .[+|-].<[digits]>[(e|E)[+|-]<[digits]>] .[+|-](i|I)(n|N)(f|F)[(i|I)(n|N)(i|I)(t|T)(y|Y)] @@ -55,23 +80,33 @@ DESCRIPTION (which will contain at least the terminating null character of <[str]>) is stored in <<*<[tail]>>>. If you want no assignment to <<*<[tail]>>>, pass a null pointer as <[tail]>. - <> is identical to <> except for its return type. This implementation returns the nearest machine number to the input decimal string. Ties are broken by using the IEEE round-even rule. However, <> is currently subject to double rounding errors. + <>, <>, <> are like <>, + <>, <> but perform the conversion based on the + locale specified by the locale object locale. If <[locale]> is + LC_GLOBAL_LOCALE or not a valid locale object, the behaviour is + undefined. + The alternate function <<_strtod_r>> is a reentrant version. The extra argument <[reent]> is a pointer to a reentrancy structure. RETURNS - <> returns the converted substring value, if any. If - no conversion could be performed, 0 is returned. If the - correct value is out of the range of representable values, - plus or minus <> is returned, and <> is - stored in errno. If the correct value would cause underflow, 0 - is returned and <> is stored in errno. + These functions return the converted substring value, if any. If + no conversion could be performed, 0 is returned. If the correct + value is out of the range of representable values, plus or minus + <> (<>, <>) is returned, and + <> is stored in errno. If the correct value would cause + underflow, 0 is returned and <> is stored in errno. + +PORTABILITY +<> is ANSI. +<>, <> are C99. +<>, <>, <> are GNU extensions. Supporting OS subroutines required: <>, <>, <>, <>, <>, <>, <>. @@ -110,6 +145,7 @@ THIS SOFTWARE. /* Original file gdtoa-strtod.c Modified 06-21-2006 by Jeff Johnston to work within newlib. */ +#define _GNU_SOURCE #include <_ansi.h> #include #include @@ -117,6 +153,7 @@ THIS SOFTWARE. #include "mprec.h" #include "gdtoa.h" #include "gd_qnan.h" +#include "../locale/setlocale.h" /* #ifndef NO_FENV_H */ /* #include */ @@ -213,10 +250,8 @@ _DEFUN (ULtod, (L, bits, exp, k), #endif /* !NO_HEX_FP */ double -_DEFUN (_strtod_r, (ptr, s00, se), - struct _reent *ptr _AND - _CONST char *__restrict s00 _AND - char **__restrict se) +_strtod_l (struct _reent *ptr, const char *__restrict s00, char **__restrict se, + locale_t loc) { #ifdef Avoid_Underflow int scale; @@ -238,6 +273,8 @@ _DEFUN (_strtod_r, (ptr, s00, se), #ifdef Honor_FLT_ROUNDS int rounding; #endif + struct lconv *lconv = __localeconv_l (loc); + int dec_len = strlen (lconv->decimal_point); delta = bs = bd = NULL; sign = nz0 = nz = decpt = 0; @@ -286,7 +323,7 @@ _DEFUN (_strtod_r, (ptr, s00, se), #else #define fpi1 fpi #endif - switch((i = gethex(ptr, &s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) { + switch((i = gethex(ptr, &s, &fpi1, &exp, &bb, sign, loc)) & STRTOG_Retmask) { case STRTOG_NoNumber: s = s00; sign = 0; @@ -317,11 +354,10 @@ _DEFUN (_strtod_r, (ptr, s00, se), else z = 10*z + c - '0'; nd0 = nd; - if (strncmp (s, _localeconv_r (ptr)->decimal_point, - strlen (_localeconv_r (ptr)->decimal_point)) == 0) + if (strncmp (s, lconv->decimal_point, dec_len) == 0) { decpt = 1; - c = *(s += strlen (_localeconv_r (ptr)->decimal_point)); + c = *(s += dec_len); if (!nd) { for(; c == '0'; c = *++s) nz++; @@ -1230,13 +1266,37 @@ _DEFUN (_strtod_r, (ptr, s00, se), return sign ? -dval(rv) : dval(rv); } +double +_DEFUN (_strtod_r, (ptr, s00, se), + struct _reent *ptr _AND + _CONST char *__restrict s00 _AND + char **__restrict se) +{ + return _strtod_l (ptr, s00, se, __get_current_locale ()); +} + #ifndef _REENT_ONLY +double +strtod_l (const char *__restrict s00, char **__restrict se, locale_t loc) +{ + return _strtod_l (_REENT, s00, se, loc); +} + double _DEFUN (strtod, (s00, se), _CONST char *__restrict s00 _AND char **__restrict se) { - return _strtod_r (_REENT, s00, se); + return _strtod_l (_REENT, s00, se, __get_current_locale ()); +} + +float +strtof_l (const char *__restrict s00, char **__restrict se, locale_t loc) +{ + double retval = _strtod_l (_REENT, s00, se, loc); + if (isnan (retval)) + return nanf (NULL); + return (float)retval; } float @@ -1244,7 +1304,7 @@ _DEFUN (strtof, (s00, se), _CONST char *__restrict s00 _AND char **__restrict se) { - double retval = _strtod_r (_REENT, s00, se); + double retval = _strtod_l (_REENT, s00, se, __get_current_locale ()); if (isnan (retval)) return nanf (NULL); return (float)retval; diff --git a/newlib/libc/stdlib/strtodg.c b/newlib/libc/stdlib/strtodg.c index a6b32908b..d8546c336 100644 --- a/newlib/libc/stdlib/strtodg.c +++ b/newlib/libc/stdlib/strtodg.c @@ -53,11 +53,7 @@ fivesbits[] = { 0, 3, 5, 7, 10, 12, 14, 17, 19, 21, }; static _Bigint * -#ifdef KR_headers -sum(p, a, b) struct _reent *p; _Bigint *a; _Bigint *b; -#else -sum(struct _reent *p, _Bigint *a, _Bigint *b) -#endif +sum (struct _reent *p, _Bigint *a, _Bigint *b) { _Bigint *c; __ULong carry, *xc, *xa, *xb, *xe, y; @@ -119,11 +115,7 @@ sum(struct _reent *p, _Bigint *a, _Bigint *b) } static void -#ifdef KR_headers -rshift(b, k) _Bigint *b; int k; -#else -rshift(_Bigint *b, int k) -#endif +rshift (_Bigint *b, int k) { __ULong *x, *x1, *xe, y; int n; @@ -152,11 +144,7 @@ rshift(_Bigint *b, int k) } static int -#ifdef KR_headers -trailz(b) _Bigint *b; -#else -trailz(_Bigint *b) -#endif +trailz (_Bigint *b) { __ULong L, *x, *xe; int n = 0; @@ -172,12 +160,8 @@ trailz(_Bigint *b) return n; } - _Bigint * -#ifdef KR_headers -increment(p, b) struct _reent *p; _Bigint *b; -#else -increment(struct _reent *p, _Bigint *b) -#endif +_Bigint * +increment (struct _reent *p, _Bigint *b) { __ULong *x, *xe; _Bigint *b1; @@ -217,12 +201,8 @@ increment(struct _reent *p, _Bigint *b) return b; } - int -#ifdef KR_headers -decrement(b) _Bigint *b; -#else -decrement(_Bigint *b) -#endif +int +decrement (_Bigint *b) { __ULong *x, *xe; #ifdef Pack_16 @@ -250,12 +230,8 @@ decrement(_Bigint *b) return STRTOG_Inexlo; } - static int -#ifdef KR_headers -all_on(b, n) _Bigint *b; int n; -#else -all_on(_Bigint *b, int n) -#endif +static int +all_on (_Bigint *b, int n) { __ULong *x, *xe; @@ -269,12 +245,8 @@ all_on(_Bigint *b, int n) return 1; } - _Bigint * -#ifdef KR_headers -set_ones(p, b, n) struct _reent *p; _Bigint *b; int n; -#else -set_ones(struct _reent *p, _Bigint *b, int n) -#endif +_Bigint * +set_ones (struct _reent *p, _Bigint *b, int n) { int k; __ULong *x, *xe; @@ -297,14 +269,9 @@ set_ones(struct _reent *p, _Bigint *b, int n) return b; } - static int -rvOK -#ifdef KR_headers - (p, d, fpi, exp, bits, exact, rd, irv) - struct _reent *p; double d; FPI *fpi; Long *exp; __ULong *bits; int exact, rd, *irv; -#else - (struct _reent *p, double d, FPI *fpi, Long *exp, __ULong *bits, int exact, int rd, int *irv) -#endif +static int +rvOK (struct _reent *p, double d, FPI *fpi, Long *exp, __ULong *bits, int exact, + int rd, int *irv) { _Bigint *b; __ULong carry, inex, lostbits; @@ -418,12 +385,8 @@ rvOK return rv; } - static int -#ifdef KR_headers -mantbits(d) double d; -#else -mantbits(U d) -#endif +static int +mantbits (U d) { __ULong L; #ifdef VAX @@ -441,14 +404,9 @@ mantbits(U d) return P - 32 - lo0bits(&L); } - int -_strtodg_r -#ifdef KR_headers - (p, s00, se, fpi, exp, bits) - struct _reent *p; const char *s00; char **se; FPI *fpi; Long *exp; __ULong *bits; -#else - (struct _reent *p, const char *s00, char **se, FPI *fpi, Long *exp, __ULong *bits) -#endif +int +_strtodg_l (struct _reent *p, const char *s00, char **se, FPI *fpi, Long *exp, + __ULong *bits, locale_t loc) { int abe, abits, asub; int bb0, bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, denorm; @@ -462,6 +420,8 @@ _strtodg_r Long L; __ULong y, z; _Bigint *ab, *bb, *bb1, *bd, *bd0, *bs, *delta, *rvb, *rvb0; + struct lconv *lconv = __localeconv_l (loc); + int dec_len = strlen (lconv->decimal_point); irv = STRTOG_Zero; denorm = sign = nz0 = nz = 0; @@ -497,7 +457,7 @@ _strtodg_r switch(s[1]) { case 'x': case 'X': - irv = gethex(p, &s, fpi, exp, &rvb, sign); + irv = gethex(p, &s, fpi, exp, &rvb, sign, loc); if (irv == STRTOG_NoNumber) { s = s00; sign = 0; @@ -520,15 +480,14 @@ _strtodg_r z = 10*z + c - '0'; nd0 = nd; #ifdef USE_LOCALE - if (strncmp (s, _localeconv_r (p)->decimal_point, - strlen (_localeconv_r (p)->decimal_point)) == 0) + if (strncmp (s, lconv->decimal_point, dec_len) == 0) #else if (c == '.') #endif { decpt = 1; #ifdef USE_LOCALE - c = *(s += strlen (_localeconv_r (p)->decimal_point)); + c = *(s += dec_len); #else c = *++s; #endif diff --git a/newlib/libc/stdlib/strtol.c b/newlib/libc/stdlib/strtol.c index 7273c7d4b..276ad1340 100644 --- a/newlib/libc/stdlib/strtol.c +++ b/newlib/libc/stdlib/strtol.c @@ -1,18 +1,27 @@ /* FUNCTION - <>---string to long + <>, <>---string to long INDEX strtol + +INDEX + strtol_l + INDEX _strtol_r ANSI_SYNOPSIS #include - long strtol(const char *restrict <[s]>, char **restrict <[ptr]>,int <[base]>); + long strtol(const char *restrict <[s]>, char **restrict <[ptr]>, + int <[base]>); - long _strtol_r(void *<[reent]>, - const char *restrict <[s]>, char **restrict <[ptr]>,int <[base]>); + #include + long strtol_l(const char *restrict <[s]>, char **restrict <[ptr]>, + int <[base]>, locale_t <[locale]>); + + long _strtol_r(void *<[reent]>, const char *restrict <[s]>, + char **restrict <[ptr]>,int <[base]>); TRAD_SYNOPSIS #include @@ -67,18 +76,24 @@ If the subject string is empty (or not in acceptable form), no conversion is performed and the value of <[s]> is stored in <[ptr]> (if <[ptr]> is not <>). +<> is like <> but performs the conversion based on the +locale specified by the locale object locale. If <[locale]> is +LC_GLOBAL_LOCALE or not a valid locale object, the behaviour is undefined. + The alternate function <<_strtol_r>> is a reentrant version. The extra argument <[reent]> is a pointer to a reentrancy structure. RETURNS -<> returns the converted value, if any. If no conversion was -made, 0 is returned. +<>, <> return the converted value, if any. If no +conversion was made, 0 is returned. -<> returns <> or <> if the magnitude of -the converted value is too large, and sets <> to <>. +<>, <> return <> or <> if the +magnitude of the converted value is too large, and sets <> +to <>. PORTABILITY <> is ANSI. +<> is a GNU extension. No supporting OS subroutines are required. */ @@ -116,26 +131,21 @@ No supporting OS subroutines are required. * SUCH DAMAGE. */ - +#define _GNU_SOURCE #include <_ansi.h> #include #include #include #include #include +#include "../locale/setlocale.h" /* * Convert a string to a long integer. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. */ -long -_DEFUN (_strtol_r, (rptr, nptr, endptr, base), - struct _reent *rptr _AND - _CONST char *__restrict nptr _AND - char **__restrict endptr _AND - int base) +static long +_strtol_l (struct _reent *rptr, const char *__restrict nptr, + char **__restrict endptr, int base, locale_t loc) { register const unsigned char *s = (const unsigned char *)nptr; register unsigned long acc; @@ -150,7 +160,7 @@ _DEFUN (_strtol_r, (rptr, nptr, endptr, base), */ do { c = *s++; - } while (isspace(c)); + } while (isspace_l(c, loc)); if (c == '-') { neg = 1; c = *s++; @@ -186,10 +196,12 @@ _DEFUN (_strtol_r, (rptr, nptr, endptr, base), cutlim = cutoff % (unsigned long)base; cutoff /= (unsigned long)base; for (acc = 0, any = 0;; c = *s++) { - if (isdigit(c)) + if (c >= '0' && c <= '9') c -= '0'; - else if (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; else break; if (c >= base) @@ -212,15 +224,32 @@ _DEFUN (_strtol_r, (rptr, nptr, endptr, base), return (acc); } +long +_DEFUN (_strtol_r, (rptr, nptr, endptr, base), + struct _reent *rptr _AND + _CONST char *__restrict nptr _AND + char **__restrict endptr _AND + int base) +{ + return _strtol_l (rptr, nptr, endptr, base, __get_current_locale ()); +} + #ifndef _REENT_ONLY +long +strtol_l (const char *__restrict s, char **__restrict ptr, int base, + locale_t loc) +{ + return _strtol_l (_REENT, s, ptr, base, loc); +} + long _DEFUN (strtol, (s, ptr, base), _CONST char *__restrict s _AND char **__restrict ptr _AND int base) { - return _strtol_r (_REENT, s, ptr, base); + return _strtol_l (_REENT, s, ptr, base, __get_current_locale ()); } #endif diff --git a/newlib/libc/stdlib/strtold.c b/newlib/libc/stdlib/strtold.c index 1128b747a..6bd1c2cbb 100644 --- a/newlib/libc/stdlib/strtold.c +++ b/newlib/libc/stdlib/strtold.c @@ -64,11 +64,25 @@ _strtold_r (struct _reent *ptr, const char *__restrict s00, { #ifdef _LDBL_EQ_DBL /* On platforms where long double is as wide as double. */ - return _strtod_r (ptr, s00, se); + return _strtod_l (ptr, s00, se, __get_current_locale ()); #else long double result; - _strtorx_r (ptr, s00, se, FLT_ROUNDS, &result); + _strtorx_l (ptr, s00, se, FLT_ROUNDS, &result, __get_current_locale ()); + return result; +#endif +} + +long double +strtold_l (const char *__restrict s00, char **__restrict se, locale_t loc) +{ +#ifdef _LDBL_EQ_DBL + /* On platforms where long double is as wide as double. */ + return _strtod_l (_REENT, s00, se, loc); +#else + long double result; + + _strtorx_l (_REENT, s00, se, FLT_ROUNDS, &result, loc); return result; #endif } @@ -76,7 +90,15 @@ _strtold_r (struct _reent *ptr, const char *__restrict s00, long double strtold (const char *__restrict s00, char **__restrict se) { - return _strtold_r (_REENT, s00, se); +#ifdef _LDBL_EQ_DBL + /* On platforms where long double is as wide as double. */ + return _strtod_l (_REENT, s00, se, __get_current_locale ()); +#else + long double result; + + _strtorx_l (_REENT, s00, se, FLT_ROUNDS, &result, __get_current_locale ()); + return result; +#endif } #endif /* _HAVE_LONG_DOUBLE */ diff --git a/newlib/libc/stdlib/strtoll.c b/newlib/libc/stdlib/strtoll.c index 3ad8199a0..e61a62a7d 100644 --- a/newlib/libc/stdlib/strtoll.c +++ b/newlib/libc/stdlib/strtoll.c @@ -1,18 +1,29 @@ /* FUNCTION - <>---string to long long + <>, <>---string to long long INDEX strtoll + +INDEX + strtoll_l + INDEX _strtoll_r ANSI_SYNOPSIS #include - long long strtoll(const char *restrict <[s]>, char **restrict <[ptr]>,int <[base]>); + long long strtoll(const char *restrict <[s]>, char **restrict <[ptr]>, + int <[base]>); + + #include + long long strtoll_l(const char *restrict <[s]>, + char **restrict <[ptr]>, int <[base]>, + locale_t <[locale]>); long long _strtoll_r(void *<[reent]>, - const char *restrict <[s]>, char **restrict <[ptr]>,int <[base]>); + const char *restrict <[s]>, + char **restrict <[ptr]>, int <[base]>); TRAD_SYNOPSIS #include @@ -67,18 +78,24 @@ If the subject string is empty (or not in acceptable form), no conversion is performed and the value of <[s]> is stored in <[ptr]> (if <[ptr]> is not <>). +<> is like <> but performs the conversion based on the +locale specified by the locale object locale. If <[locale]> is +LC_GLOBAL_LOCALE or not a valid locale object, the behaviour is undefined. + The alternate function <<_strtoll_r>> is a reentrant version. The extra argument <[reent]> is a pointer to a reentrancy structure. RETURNS -<> returns the converted value, if any. If no conversion was -made, 0 is returned. +<>, <> return the converted value, if any. If no +conversion was made, 0 is returned. -<> returns <> or <> if the magnitude of -the converted value is too large, and sets <> to <>. +<>, <> return <> or <> +if the magnitude of the converted value is too large, and sets <> +to <>. PORTABILITY <> is ANSI. +<> is a GNU extension. No supporting OS subroutines are required. */ @@ -116,23 +133,125 @@ No supporting OS subroutines are required. * SUCH DAMAGE. */ - +#define _GNU_SOURCE #include <_ansi.h> #include #include #include #include #include +#include "../locale/setlocale.h" + +/* + * Convert a string to a long long integer. + */ +static long long +_strtoll_l (struct _reent *rptr, _CONST char *__restrict nptr, + char **__restrict endptr, int base, locale_t loc) +{ + register const unsigned char *s = (const unsigned char *)nptr; + register unsigned long long acc; + register int c; + register unsigned long long cutoff; + register 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_l(c, loc)); + 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)LONG_LONG_MIN : LONG_LONG_MAX; + cutlim = cutoff % (unsigned long long)base; + cutoff /= (unsigned long long)base; + for (acc = 0, any = 0;; 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_LONG_MIN : LONG_LONG_MAX; + rptr->_errno = ERANGE; + } else if (neg) + acc = -acc; + if (endptr != 0) + *endptr = (char *) (any ? (char *)s - 1 : nptr); + return (acc); +} + +long long +_DEFUN (_strtoll_r, (rptr, nptr, endptr, base), + struct _reent *rptr _AND + _CONST char *__restrict nptr _AND + char **__restrict endptr _AND + int base) +{ + return _strtoll_l (rptr, nptr, endptr, base, __get_current_locale ()); +} #ifndef _REENT_ONLY +long long +strtoll_l (const char *__restrict s, char **__restrict ptr, int base, + locale_t loc) +{ + return _strtoll_l (_REENT, s, ptr, base, loc); +} + long long _DEFUN (strtoll, (s, ptr, base), _CONST char *__restrict s _AND char **__restrict ptr _AND int base) { - return _strtoll_r (_REENT, s, ptr, base); + return _strtoll_l (_REENT, s, ptr, base, __get_current_locale ()); } #endif diff --git a/newlib/libc/stdlib/strtoll_r.c b/newlib/libc/stdlib/strtoll_r.c index 515464db1..2997587d8 100644 --- a/newlib/libc/stdlib/strtoll_r.c +++ b/newlib/libc/stdlib/strtoll_r.c @@ -1,140 +1 @@ -/* - This code is based on strtoul.c which has the following copyright. - It is used to convert a string into a signed long long. - - long long _strtoll_r (struct _reent *rptr, const char *s, - char **ptr, int base); -*/ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * 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. - * 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 - * 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 - * 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. - */ - -#ifdef __GNUC__ - -#define _GNU_SOURCE -#include <_ansi.h> -#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 -_DEFUN (_strtoll_r, (rptr, nptr, endptr, base), - struct _reent *rptr _AND - _CONST char *__restrict nptr _AND - char **__restrict endptr _AND - int base) -{ - register const unsigned char *s = (const unsigned char *)nptr; - register unsigned long long acc; - register int c; - register unsigned long long cutoff; - register 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)LONG_LONG_MIN : LONG_LONG_MAX; - cutlim = cutoff % (unsigned long long)base; - cutoff /= (unsigned long long)base; - for (acc = 0, any = 0;; c = *s++) { - 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_LONG_MIN : LONG_LONG_MAX; - rptr->_errno = ERANGE; - } else if (neg) - acc = -acc; - if (endptr != 0) - *endptr = (char *) (any ? (char *)s - 1 : nptr); - return (acc); -} - -#endif /* __GNUC__ */ +/* dummy */ diff --git a/newlib/libc/stdlib/strtorx.c b/newlib/libc/stdlib/strtorx.c index 961ecd2f2..aeeb25066 100644 --- a/newlib/libc/stdlib/strtorx.c +++ b/newlib/libc/stdlib/strtorx.c @@ -105,9 +105,10 @@ ULtox(__UShort *L, __ULong *bits, Long exp, int k) int #ifdef KR_headers -_strtorx_r(p, s, sp, rounding, L) struct _reent *p; const char *s; char **sp; int rounding; void *L; +_strtorx_l(p, s, sp, rounding, L, loc) struct _reent *p; const char *s; char **sp; int rounding; void *L; locale_t loc; #else -_strtorx_r(struct _reent *p, const char *s, char **sp, int rounding, void *L) +_strtorx_l(struct _reent *p, const char *s, char **sp, int rounding, void *L, + locale_t loc) #endif { static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, SI }; @@ -122,7 +123,7 @@ _strtorx_r(struct _reent *p, const char *s, char **sp, int rounding, void *L) fpi1.rounding = rounding; fpi = &fpi1; } - k = _strtodg_r(p, s, sp, fpi, &exp, bits); + k = _strtodg_l(p, s, sp, fpi, &exp, bits, loc); ULtox((__UShort*)L, bits, exp, k); return k; } diff --git a/newlib/libc/stdlib/strtoul.c b/newlib/libc/stdlib/strtoul.c index 12c6834dc..062606f4e 100644 --- a/newlib/libc/stdlib/strtoul.c +++ b/newlib/libc/stdlib/strtoul.c @@ -1,19 +1,28 @@ /* FUNCTION - <>---string to unsigned long + <>, <>---string to unsigned long INDEX strtoul + +INDEX + strtoul_l + INDEX _strtoul_r ANSI_SYNOPSIS #include - unsigned long strtoul(const char *restrict <[s]>, char **restrict <[ptr]>, - int <[base]>); + unsigned long strtoul(const char *restrict <[s]>, + char **restrict <[ptr]>, int <[base]>); + + #include + unsigned long strtoul_l(const char *restrict <[s]>, + char **restrict <[ptr]>, int <[base]>, + locale_t <[locale]>); unsigned long _strtoul_r(void *<[reent]>, const char *restrict <[s]>, - char **restrict <[ptr]>, int <[base]>); + char **restrict <[ptr]>, int <[base]>); TRAD_SYNOPSIS #include @@ -68,19 +77,23 @@ with a substring in acceptable form), no conversion is performed and the value of <[s]> is stored in <[ptr]> (if <[ptr]> is not <>). +<> is like <> but performs the conversion based on the +locale specified by the locale object locale. If <[locale]> is +LC_GLOBAL_LOCALE or not a valid locale object, the behaviour is undefined. + The alternate function <<_strtoul_r>> is a reentrant version. The extra argument <[reent]> is a pointer to a reentrancy structure. - RETURNS -<> returns the converted value, if any. If no conversion was -made, <<0>> is returned. +<>, > return the converted value, if any. If no +conversion was made, <<0>> is returned. -<> returns <> if the magnitude of the converted -value is too large, and sets <> to <>. +<>, > return <> if the magnitude of the +converted value is too large, and sets <> to <>. PORTABILITY <> is ANSI. +<> is a GNU extension. <> requires no supporting OS subroutines. */ @@ -118,25 +131,21 @@ PORTABILITY * SUCH DAMAGE. */ +#define _GNU_SOURCE #include <_ansi.h> #include #include #include #include #include +#include "../locale/setlocale.h" /* * 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 -_DEFUN (_strtoul_r, (rptr, nptr, endptr, base), - struct _reent *rptr _AND - _CONST char *__restrict nptr _AND - char **__restrict endptr _AND - int base) +static unsigned long +_strtoul_l (struct _reent *rptr, const char *__restrict nptr, + char **__restrict endptr, int base, locale_t loc) { register const unsigned char *s = (const unsigned char *)nptr; register unsigned long acc; @@ -149,7 +158,7 @@ _DEFUN (_strtoul_r, (rptr, nptr, endptr, base), */ do { c = *s++; - } while (isspace(c)); + } while (isspace_l(c, loc)); if (c == '-') { neg = 1; c = *s++; @@ -166,10 +175,12 @@ _DEFUN (_strtoul_r, (rptr, nptr, endptr, base), cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; for (acc = 0, any = 0;; c = *s++) { - if (isdigit(c)) + if (c >= '0' && c <= '9') c -= '0'; - else if (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; else break; if (c >= base) @@ -192,15 +203,32 @@ _DEFUN (_strtoul_r, (rptr, nptr, endptr, base), return (acc); } +unsigned long +_DEFUN (_strtoul_r, (rptr, nptr, endptr, base), + struct _reent *rptr _AND + _CONST char *__restrict nptr _AND + char **__restrict endptr _AND + int base) +{ + return _strtoul_l (rptr, nptr, endptr, base, __get_current_locale ()); +} + #ifndef _REENT_ONLY +unsigned long +strtoul_l (const char *__restrict s, char **__restrict ptr, int base, + locale_t loc) +{ + return _strtoul_l (_REENT, s, ptr, base, loc); +} + unsigned long _DEFUN (strtoul, (s, ptr, base), _CONST char *__restrict s _AND char **__restrict ptr _AND int base) { - return _strtoul_r (_REENT, s, ptr, base); + return _strtoul_l (_REENT, s, ptr, base, __get_current_locale ()); } #endif diff --git a/newlib/libc/stdlib/strtoull.c b/newlib/libc/stdlib/strtoull.c index 13a54dbb4..ba6452e62 100644 --- a/newlib/libc/stdlib/strtoull.c +++ b/newlib/libc/stdlib/strtoull.c @@ -1,19 +1,26 @@ /* FUNCTION - <>---string to unsigned long long + <>, <>---string to unsigned long long INDEX strtoull + INDEX - _strtoull_r + strtoull_l ANSI_SYNOPSIS #include - unsigned long long strtoull(const char *restrict <[s]>, char **restrict <[ptr]>, - int <[base]>); + unsigned long long strtoull(const char *restrict <[s]>, + char **restrict <[ptr]>, int <[base]>); + + #include + unsigned long long strtoull_l(const char *restrict <[s]>, + char **restrict <[ptr]>, int <[base]>, + locale_t <[locale]>); - unsigned long long _strtoull_r(void *<[reent]>, const char *restrict <[s]>, - char **restrict <[ptr]>, int <[base]>); + unsigned long long _strtoull_r(void *<[reent]>, + const char *restrict <[s]>, + char **restrict <[ptr]>, int <[base]>); TRAD_SYNOPSIS #include @@ -68,19 +75,23 @@ with a substring in acceptable form), no conversion is performed and the value of <[s]> is stored in <[ptr]> (if <[ptr]> is not <>). +<> is like <> but performs the conversion based on the +locale specified by the locale object locale. If <[locale]> is +LC_GLOBAL_LOCALE or not a valid locale object, the behaviour is undefined. + The alternate function <<_strtoull_r>> is a reentrant version. The extra argument <[reent]> is a pointer to a reentrancy structure. - RETURNS -<> returns the converted value, if any. If no conversion was -made, <<0>> is returned. +<>, <> return the converted value, if any. If no +conversion was made, <<0>> is returned. -<> returns <> if the magnitude of the converted -value is too large, and sets <> to <>. +<>, <> return <> if the magnitude +of the converted value is too large, and sets <> to <>. PORTABILITY <> is ANSI. +<> is a GNU extension. <> requires no supporting OS subroutines. */ @@ -118,22 +129,104 @@ PORTABILITY * SUCH DAMAGE. */ +#define _GNU_SOURCE #include <_ansi.h> #include #include #include #include #include +#include "../locale/setlocale.h" + +/* + * Convert a string to an unsigned long long integer. + */ +static unsigned long long +_strtoull_l (struct _reent *rptr, const char *__restrict nptr, + char **__restrict endptr, int base, locale_t loc) +{ + register const unsigned char *s = (const unsigned char *)nptr; + register unsigned long long acc; + register int c; + register unsigned long long cutoff; + register int neg = 0, any, cutlim; + + /* + * See strtol for comments as to the logic used. + */ + do { + c = *s++; + } while (isspace_l(c, loc)); + 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 long)ULONG_LONG_MAX / (unsigned long long)base; + cutlim = (unsigned long long)ULONG_LONG_MAX % (unsigned long long)base; + for (acc = 0, any = 0;; 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 = ULONG_LONG_MAX; + rptr->_errno = ERANGE; + } else if (neg) + acc = -acc; + if (endptr != 0) + *endptr = (char *) (any ? (char *)s - 1 : nptr); + return (acc); +} + +unsigned long long +_DEFUN (_strtoull_r, (rptr, nptr, endptr, base), + struct _reent *rptr _AND + _CONST char *__restrict nptr _AND + char **__restrict endptr _AND + int base) +{ + return _strtoull_l (rptr, nptr, endptr, base, __get_current_locale ()); +} #ifndef _REENT_ONLY +unsigned long long +strtoull_l (const char *__restrict s, char **__restrict ptr, int base, + locale_t loc) +{ + return _strtoull_l (_REENT, s, ptr, base, loc); +} + unsigned long long _DEFUN (strtoull, (s, ptr, base), _CONST char *__restrict s _AND char **__restrict ptr _AND int base) { - return _strtoull_r (_REENT, s, ptr, base); + return _strtoull_l (_REENT, s, ptr, base, __get_current_locale ()); } #endif diff --git a/newlib/libc/stdlib/strtoull_r.c b/newlib/libc/stdlib/strtoull_r.c index d0868adf2..2997587d8 100644 --- a/newlib/libc/stdlib/strtoull_r.c +++ b/newlib/libc/stdlib/strtoull_r.c @@ -1,120 +1 @@ -/* - This code is based on strtoul.c which has the following copyright. - It is used to convert a string into an unsigned long long. - - long long _strtoull_r (struct _reent *rptr, const char *s, - char **ptr, int base); - -*/ - -/* - * Copyright (c) 1990 Regents of the University of California. - * 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. - * 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 - * 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 - * 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. - */ - -#ifdef __GNUC__ - -#define _GNU_SOURCE -#include <_ansi.h> -#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 -_DEFUN (_strtoull_r, (rptr, nptr, endptr, base), - struct _reent *rptr _AND - _CONST char *__restrict nptr _AND - char **__restrict endptr _AND - int base) -{ - register const unsigned char *s = (const unsigned char *)nptr; - register unsigned long long acc; - register int c; - register unsigned long long cutoff; - register int neg = 0, any, cutlim; - - /* - * 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 long)ULONG_LONG_MAX / (unsigned long long)base; - cutlim = (unsigned long long)ULONG_LONG_MAX % (unsigned long long)base; - for (acc = 0, any = 0;; c = *s++) { - 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_LONG_MAX; - rptr->_errno = ERANGE; - } else if (neg) - acc = -acc; - if (endptr != 0) - *endptr = (char *) (any ? (char *)s - 1 : nptr); - return (acc); -} - -#endif /* __GNUC__ */ +/* dummy */ diff --git a/newlib/libc/stdlib/wcsnrtombs.c b/newlib/libc/stdlib/wcsnrtombs.c index b09f7e19e..8ad8bcd2c 100644 --- a/newlib/libc/stdlib/wcsnrtombs.c +++ b/newlib/libc/stdlib/wcsnrtombs.c @@ -103,15 +103,11 @@ PORTABILITY #include #include #include "local.h" +#include "../locale/setlocale.h" size_t -_DEFUN (_wcsnrtombs_r, (r, dst, src, nwc, len, ps), - struct _reent *r _AND - char *dst _AND - const wchar_t **src _AND - size_t nwc _AND - size_t len _AND - mbstate_t *ps) +_wcsnrtombs_l (struct _reent *r, char *dst, const wchar_t **src, size_t nwc, + size_t len, mbstate_t *ps, locale_t loc) { char *ptr = dst; char buff[10]; @@ -138,7 +134,7 @@ _DEFUN (_wcsnrtombs_r, (r, dst, src, nwc, len, ps), { int count = ps->__count; wint_t wch = ps->__value.__wch; - int bytes = __WCTOMB (r, buff, *pwcs, ps); + int bytes = loc->wctomb (r, buff, *pwcs, ps); if (bytes == -1) { r->_errno = EILSEQ; @@ -174,6 +170,19 @@ _DEFUN (_wcsnrtombs_r, (r, dst, src, nwc, len, ps), return n; } +size_t +_DEFUN (_wcsnrtombs_r, (r, dst, src, nwc, len, ps), + struct _reent *r _AND + char *dst _AND + const wchar_t **src _AND + size_t nwc _AND + size_t len _AND + mbstate_t *ps) +{ + return _wcsnrtombs_l (_REENT, dst, src, nwc, len, ps, + __get_current_locale ()); +} + #ifndef _REENT_ONLY size_t _DEFUN (wcsnrtombs, (dst, src, nwc, len, ps), @@ -183,6 +192,7 @@ _DEFUN (wcsnrtombs, (dst, src, nwc, len, ps), size_t len _AND mbstate_t *__restrict ps) { - return _wcsnrtombs_r (_REENT, dst, src, nwc, len, ps); + return _wcsnrtombs_l (_REENT, dst, src, nwc, len, ps, + __get_current_locale ()); } #endif /* !_REENT_ONLY */ diff --git a/newlib/libc/stdlib/wcstod.c b/newlib/libc/stdlib/wcstod.c index c91ecf2fe..43f7b4eec 100644 --- a/newlib/libc/stdlib/wcstod.c +++ b/newlib/libc/stdlib/wcstod.c @@ -1,22 +1,48 @@ /* FUNCTION - <>, <>---wide char string to double or float + <>, <>, <>, <>, <>, <>---wide char string to double or float INDEX wcstod -INDEX - _wcstod_r + INDEX wcstof + +INDEX + wcstold + +INDEX + wcstod_l + +INDEX + wcstof_l + +INDEX + wcstold_l + +INDEX + _wcstod_r + INDEX _wcstof_r ANSI_SYNOPSIS #include double wcstod(const wchar_t *__restrict <[str]>, - wchar_t **__restrict <[tail]>); + wchar_t **__restrict <[tail]>); float wcstof(const wchar_t *__restrict <[str]>, - wchar_t **__restrict <[tail]>); + wchar_t **__restrict <[tail]>); + long double wcstold(const wchar_t *__restrict <[str]>, + wchar_t **__restrict <[tail]>); + + #include + double wcstod_l(const wchar_t *__restrict <[str]>, + wchar_t **__restrict <[tail]>, locale_t <[locale]>); + float wcstof_l(const wchar_t *__restrict <[str]>, + wchar_t **__restrict <[tail]>, locale_t <[locale]>); + long double wcstold_l(const wchar_t *__restrict <[str]>, + wchar_t **__restrict <[tail]>, + locale_t <[locale]>); double _wcstod_r(void *<[reent]>, const wchar_t *<[str]>, wchar_t **<[tail]>); @@ -44,11 +70,11 @@ TRAD_SYNOPSIS wchar_t **<[tail]>; DESCRIPTION - The function <> parses the wide character string <[str]>, - producing a substring which can be converted to a double - value. The substring converted is the longest initial - subsequence of <[str]>, beginning with the first - non-whitespace character, that has one of these formats: + <>, <>, <> parse the wide-character string + <[str]>, producing a substring which can be converted to a double, + float, or long double value. The substring converted is the longest + initial subsequence of <[str]>, beginning with the first non-whitespace + character, that has one of these formats: .[+|-]<[digits]>[.[<[digits]>]][(e|E)[+|-]<[digits]>] .[+|-].<[digits]>[(e|E)[+|-]<[digits]>] .[+|-](i|I)(n|N)(f|F)[(i|I)(n|N)(i|I)(t|T)(y|Y)] @@ -66,13 +92,18 @@ DESCRIPTION (which will contain at least the terminating null character of <[str]>) is stored in <<*<[tail]>>>. If you want no assignment to <<*<[tail]>>>, pass a null pointer as <[tail]>. - <> is identical to <> except for its return type. This implementation returns the nearest machine number to the input decimal string. Ties are broken by using the IEEE round-even rule. However, <> is currently subject to double rounding errors. + <>, <>, <> are like <>, + <>, <> but perform the conversion based on the + locale specified by the locale object locale. If <[locale]> is + LC_GLOBAL_LOCALE or not a valid locale object, the behaviour is + undefined. + The alternate functions <<_wcstod_r>> and <<_wcstof_r>> are reentrant versions of <> and <>, respectively. The extra argument <[reent]> is a pointer to a reentrancy structure. @@ -85,6 +116,11 @@ RETURNS stored in errno. If the correct value would cause underflow, 0 is returned and <> is stored in errno. +PORTABILITY +<> is ANSI. +<>, <> are C99. +<>, <>, <> are GNU extensions. + Supporting OS subroutines required: <>, <>, <>, <>, <>, <>, <>. */ @@ -123,12 +159,11 @@ Supporting OS subroutines required: <>, <>, <>, #include #include #include +#include "mprec.h" double -_DEFUN (_wcstod_r, (ptr, nptr, endptr), - struct _reent *ptr _AND - _CONST wchar_t *nptr _AND - wchar_t **endptr) +_wcstod_l (struct _reent *ptr, const wchar_t *nptr, wchar_t **endptr, + locale_t loc) { static const mbstate_t initial; mbstate_t mbs; @@ -137,7 +172,7 @@ _DEFUN (_wcstod_r, (ptr, nptr, endptr), const wchar_t *wcp; size_t len; - while (iswspace(*nptr)) + while (iswspace_l(*nptr, loc)) nptr++; /* @@ -152,7 +187,8 @@ _DEFUN (_wcstod_r, (ptr, nptr, endptr), */ wcp = nptr; mbs = initial; - if ((len = _wcsrtombs_r(ptr, NULL, &wcp, 0, &mbs)) == (size_t)-1) { + if ((len = _wcsnrtombs_l(ptr, NULL, &wcp, (size_t) -1, 0, &mbs, loc)) + == (size_t) -1) { if (endptr != NULL) *endptr = (wchar_t *)nptr; return (0.0); @@ -160,10 +196,10 @@ _DEFUN (_wcstod_r, (ptr, nptr, endptr), if ((buf = _malloc_r(ptr, len + 1)) == NULL) return (0.0); mbs = initial; - _wcsrtombs_r(ptr, buf, &wcp, len + 1, &mbs); + _wcsnrtombs_l(ptr, buf, &wcp, (size_t) -1, len + 1, &mbs, loc); /* Let strtod() do most of the work for us. */ - val = _strtod_r(ptr, buf, &end); + val = _strtod_l(ptr, buf, &end, loc); /* * We only know where the number ended in the _multibyte_ @@ -182,10 +218,10 @@ _DEFUN (_wcstod_r, (ptr, nptr, endptr), just one byte long. The resulting difference (end - buf) is then equivalent to the number of valid wide characters in the input string. */ - len = strlen (_localeconv_r (ptr)->decimal_point); + len = strlen (__localeconv_l (loc)->decimal_point); if (len > 1) { char *d = strstr (buf, - _localeconv_r (ptr)->decimal_point); + __localeconv_l (loc)->decimal_point); if (d && d < end) end -= len - 1; } @@ -197,13 +233,22 @@ _DEFUN (_wcstod_r, (ptr, nptr, endptr), return (val); } +double +_DEFUN (_wcstod_r, (ptr, nptr, endptr), + struct _reent *ptr _AND + _CONST wchar_t *nptr _AND + wchar_t **endptr) +{ + return _wcstod_l (ptr, nptr, endptr, __get_current_locale ()); +} + float _DEFUN (_wcstof_r, (ptr, nptr, endptr), struct _reent *ptr _AND _CONST wchar_t *nptr _AND wchar_t **endptr) { - double retval = _wcstod_r (ptr, nptr, endptr); + double retval = _wcstod_l (ptr, nptr, endptr, __get_current_locale ()); if (isnan (retval)) return nanf (NULL); return (float)retval; @@ -211,11 +256,28 @@ _DEFUN (_wcstof_r, (ptr, nptr, endptr), #ifndef _REENT_ONLY +double +wcstod_l (const wchar_t *__restrict nptr, wchar_t **__restrict endptr, + locale_t loc) +{ + return _wcstod_l (_REENT, nptr, endptr, loc); +} + double _DEFUN (wcstod, (nptr, endptr), _CONST wchar_t *__restrict nptr _AND wchar_t **__restrict endptr) { - return _wcstod_r (_REENT, nptr, endptr); + return _wcstod_l (_REENT, nptr, endptr, __get_current_locale ()); +} + +float +wcstof_l (const wchar_t *__restrict nptr, wchar_t **__restrict endptr, + locale_t loc) +{ + double retval = _wcstod_l (_REENT, nptr, endptr, loc); + if (isnan (retval)) + return nanf (NULL); + return (float)retval; } float @@ -223,7 +285,7 @@ _DEFUN (wcstof, (nptr, endptr), _CONST wchar_t *__restrict nptr _AND wchar_t **__restrict endptr) { - double retval = _wcstod_r (_REENT, nptr, endptr); + double retval = _wcstod_l (_REENT, nptr, endptr, __get_current_locale ()); if (isnan (retval)) return nanf (NULL); return (float)retval; diff --git a/newlib/libc/stdlib/wcstol.c b/newlib/libc/stdlib/wcstol.c index adda9c296..4c7480594 100644 --- a/newlib/libc/stdlib/wcstol.c +++ b/newlib/libc/stdlib/wcstol.c @@ -1,19 +1,28 @@ /* FUNCTION - <>---wide string to long + <>, <>---wide string to long INDEX wcstol + +INDEX + wcstol_l + INDEX _wcstol_r ANSI_SYNOPSIS #include long wcstol(const wchar_t *__restrict <[s]>, - wchar_t **__restrict <[ptr]>,int <[base]>); + wchar_t **__restrict <[ptr]>, int <[base]>); - long _wcstol_r(void *<[reent]>, - const wchar_t *<[s]>, wchar_t **<[ptr]>,int <[base]>); + #include + long wcstol_l(const wchar_t *__restrict <[s]>, + wchar_t **__restrict <[ptr]>, int <[base]>, + locale_t <[locale]>); + + long _wcstol_r(void *<[reent]>, const wchar_t *<[s]>, + wchar_t **<[ptr]>, int <[base]>); TRAD_SYNOPSIS #include @@ -71,15 +80,21 @@ not <>). The alternate function <<_wcstol_r>> is a reentrant version. The extra argument <[reent]> is a pointer to a reentrancy structure. +<> is like <> but performs the conversion based on the +locale specified by the locale object locale. If <[locale]> is +LC_GLOBAL_LOCALE or not a valid locale object, the behaviour is undefined. + RETURNS -<> returns the converted value, if any. If no conversion was -made, 0 is returned. +<>, <> return the converted value, if any. If no +conversion was made, 0 is returned. -<> returns <> or <> if the magnitude of -the converted value is too large, and sets <> to <>. +<>, <> return <> or <> if the +magnitude of the converted value is too large, and sets <> +to <>. PORTABILITY <> is ANSI. +<> is a GNU extension. No supporting OS subroutines are required. */ @@ -124,19 +139,14 @@ No supporting OS subroutines are required. #include #include #include +#include "../locale/setlocale.h" /* * Convert a wide string to a long integer. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. */ -long -_DEFUN (_wcstol_r, (rptr, nptr, endptr, base), - struct _reent *rptr _AND - _CONST wchar_t *nptr _AND - wchar_t **endptr _AND - int base) +static long +_wcstol_l (struct _reent *rptr, const wchar_t *nptr, wchar_t **endptr, + int base, locale_t loc) { register const wchar_t *s = nptr; register unsigned long acc; @@ -151,7 +161,7 @@ _DEFUN (_wcstol_r, (rptr, nptr, endptr, base), */ do { c = *s++; - } while (iswspace(c)); + } while (iswspace_l(c, loc)); if (c == L'-') { neg = 1; c = *s++; @@ -187,10 +197,12 @@ _DEFUN (_wcstol_r, (rptr, nptr, endptr, base), cutlim = cutoff % (unsigned long)base; cutoff /= (unsigned long)base; for (acc = 0, any = 0;; c = *s++) { - if (iswdigit(c)) + if (c >= L'0' && c <= L'9') c -= L'0'; - else if (iswalpha(c)) - c -= iswupper(c) ? L'A' - 10 : L'a' - 10; + else if (c >= L'A' && c <= L'Z') + c -= L'A' - 10; + else if (c >= L'a' && c <= L'z') + c -= L'a' - 10; else break; if (c >= base) @@ -213,15 +225,32 @@ _DEFUN (_wcstol_r, (rptr, nptr, endptr, base), return (acc); } +long +_DEFUN (_wcstol_r, (rptr, nptr, endptr, base), + struct _reent *rptr _AND + _CONST wchar_t *nptr _AND + wchar_t **endptr _AND + int base) +{ + return _wcstol_l (rptr, nptr, endptr, base, __get_current_locale ()); +} + #ifndef _REENT_ONLY +long +wcstol_l (const wchar_t *__restrict s, wchar_t **__restrict ptr, int base, + locale_t loc) +{ + return _wcstol_l (_REENT, s, ptr, base, loc); +} + long _DEFUN (wcstol, (s, ptr, base), _CONST wchar_t *__restrict s _AND wchar_t **__restrict ptr _AND int base) { - return _wcstol_r (_REENT, s, ptr, base); + return _wcstol_l (_REENT, s, ptr, base, __get_current_locale ()); } #endif diff --git a/newlib/libc/stdlib/wcstold.c b/newlib/libc/stdlib/wcstold.c index e94aca919..c57def21d 100644 --- a/newlib/libc/stdlib/wcstold.c +++ b/newlib/libc/stdlib/wcstold.c @@ -34,13 +34,15 @@ POSSIBILITY OF SUCH DAMAGE. #include #include #include "local.h" +#include "../locale/setlocale.h" long double -wcstold (const wchar_t *__restrict nptr, wchar_t **__restrict endptr) +wcstold_l (const wchar_t *__restrict nptr, wchar_t **__restrict endptr, + locale_t loc) { #ifdef _LDBL_EQ_DBL /* On platforms where long double is as wide as double. */ - return wcstod(nptr, endptr); + return wcstod_l(nptr, endptr, loc); #else /* This is a duplicate of the code in wcstod.c, but converted to long double. */ @@ -57,7 +59,8 @@ wcstold (const wchar_t *__restrict nptr, wchar_t **__restrict endptr) /* Convert the supplied numeric wide char string to multibyte. */ wcp = nptr; mbs = initial; - if ((len = wcsrtombs (NULL, &wcp, 0, &mbs)) == (size_t)-1) + if ((len = _wcsnrtombs_l (_REENT, NULL, &wcp, (size_t) -1, 0, &mbs, loc)) + == (size_t) -1) { if (endptr != NULL) *endptr = (wchar_t *) nptr; @@ -68,9 +71,9 @@ wcstold (const wchar_t *__restrict nptr, wchar_t **__restrict endptr) return 0.0L; mbs = initial; - wcsrtombs (buf, &wcp, len + 1, &mbs); + _wcsnrtombs_l (_REENT, buf, &wcp, (size_t) -1, len + 1, &mbs, loc); - val = strtold (buf, &end); + val = strtold_l (buf, &end, loc); /* We only know where the number ended in the _multibyte_ representation of the string. If the caller wants to know @@ -89,10 +92,10 @@ wcstold (const wchar_t *__restrict nptr, wchar_t **__restrict endptr) just one byte long. The resulting difference (end - buf) is then equivalent to the number of valid wide characters in the input string. */ - len = strlen (localeconv ()->decimal_point); + len = strlen (__localeconv_l (loc)->decimal_point); if (len > 1) { - char *d = strstr (buf, localeconv ()->decimal_point); + char *d = strstr (buf, __localeconv_l (loc)->decimal_point); if (d && d < end) end -= len - 1; @@ -106,3 +109,14 @@ wcstold (const wchar_t *__restrict nptr, wchar_t **__restrict endptr) return val; #endif /* _LDBL_EQ_DBL */ } + +long double +wcstold (const wchar_t *__restrict nptr, wchar_t **__restrict endptr) +{ +#ifdef _LDBL_EQ_DBL +/* On platforms where long double is as wide as double. */ + return wcstod_l(nptr, endptr, __get_current_locale ()); +#else + return wcstold_l(nptr, endptr, __get_current_locale ()); +#endif +} diff --git a/newlib/libc/stdlib/wcstoll.c b/newlib/libc/stdlib/wcstoll.c index 2c36d6d00..2996b11a6 100644 --- a/newlib/libc/stdlib/wcstoll.c +++ b/newlib/libc/stdlib/wcstoll.c @@ -1,19 +1,28 @@ /* FUNCTION - <>---wide string to long long + <>, <>---wide string to long long INDEX wcstoll + +INDEX + wcstoll_l + INDEX _wcstoll_r ANSI_SYNOPSIS #include long long wcstoll(const wchar_t *__restrict <[s]>, - wchar_t **__restrict <[ptr]>,int <[base]>); + wchar_t **__restrict <[ptr]>,int <[base]>); - long long _wcstoll_r(void *<[reent]>, - const wchar_t *<[s]>, wchar_t **<[ptr]>,int <[base]>); + #include + long long wcstoll_l(const wchar_t *__restrict <[s]>, + wchar_t **__restrict <[ptr]>, int <[base]>, + locale_t <[locale]>); + + long long _wcstoll_r(void *<[reent]>, const wchar_t *<[s]>, + wchar_t **<[ptr]>, int <[base]>); TRAD_SYNOPSIS #include @@ -71,15 +80,21 @@ not <>). The alternate function <<_wcstoll_r>> is a reentrant version. The extra argument <[reent]> is a pointer to a reentrancy structure. +<> is like <> but performs the conversion based on the +locale specified by the locale object locale. If <[locale]> is +LC_GLOBAL_LOCALE or not a valid locale object, the behaviour is undefined. + RETURNS -<> returns the converted value, if any. If no conversion was -made, 0 is returned. +<>, <> return the converted value, if any. If no +conversion was made, 0 is returned. -<> returns <> or <> if the magnitude of -the converted value is too large, and sets <> to <>. +<>, <> return <> or <> +if the magnitude of the converted value is too large, and sets <> +to <>. PORTABILITY <> is ANSI. +<> is a GNU extension. No supporting OS subroutines are required. */ @@ -117,23 +132,125 @@ No supporting OS subroutines are required. * SUCH DAMAGE. */ - +#define _GNU_SOURCE #include <_ansi.h> #include #include #include #include #include +#include "../locale/setlocale.h" + +/* + * Convert a wide string to a long long integer. + */ +long long +_wcstoll_l (struct _reent *rptr, const wchar_t *nptr, wchar_t **endptr, + int base, locale_t loc) +{ + register const wchar_t *s = nptr; + register unsigned long long acc; + register int c; + register unsigned long long cutoff; + register 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 (iswspace_l(c, loc)); + if (c == L'-') { + neg = 1; + c = *s++; + } else if (c == L'+') + c = *s++; + if ((base == 0 || base == 16) && + c == L'0' && (*s == L'x' || *s == L'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == L'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)LONG_LONG_MIN : LONG_LONG_MAX; + cutlim = cutoff % (unsigned long long)base; + cutoff /= (unsigned long long)base; + for (acc = 0, any = 0;; c = *s++) { + if (c >= L'0' && c <= L'9') + c -= L'0'; + else if (c >= L'A' && c <= L'Z') + c -= L'A' - 10; + else if (c >= L'a' && c <= L'z') + c -= L'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_LONG_MIN : LONG_LONG_MAX; + rptr->_errno = ERANGE; + } else if (neg) + acc = -acc; + if (endptr != 0) + *endptr = (wchar_t *) (any ? s - 1 : nptr); + return (acc); +} + +long long +_DEFUN (_wcstoll_r, (rptr, nptr, endptr, base), + struct _reent *rptr _AND + _CONST wchar_t *nptr _AND + wchar_t **endptr _AND + int base) +{ + return _wcstoll_l (rptr, nptr, endptr, base, __get_current_locale ()); +} #ifndef _REENT_ONLY +long long +wcstoll_l (const wchar_t *__restrict s, wchar_t **__restrict ptr, int base, + locale_t loc) +{ + return _wcstoll_l (_REENT, s, ptr, base, loc); +} + long long _DEFUN (wcstoll, (s, ptr, base), _CONST wchar_t *__restrict s _AND wchar_t **__restrict ptr _AND int base) { - return _wcstoll_r (_REENT, s, ptr, base); + return _wcstoll_l (_REENT, s, ptr, base, __get_current_locale ()); } #endif diff --git a/newlib/libc/stdlib/wcstoll_r.c b/newlib/libc/stdlib/wcstoll_r.c index d6baacaf5..2997587d8 100644 --- a/newlib/libc/stdlib/wcstoll_r.c +++ b/newlib/libc/stdlib/wcstoll_r.c @@ -1,140 +1 @@ -/* - This code is based on strtoul.c which has the following copyright. - It is used to convert a wide string into a signed long long. - - long long _wcstoll_r (struct _reent *rptr, const wchar_t *s, - wchar_t **ptr, int base); -*/ - -/*- - * Copyright (c) 1990 The Regents of the University of California. - * 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. - * 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 - * 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 - * 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. - */ - -#ifdef __GNUC__ - -#define _GNU_SOURCE -#include <_ansi.h> -#include -#include -#include -#include -#include - -/* - * Convert a wide string to a long long integer. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. - */ -long long -_DEFUN (_wcstoll_r, (rptr, nptr, endptr, base), - struct _reent *rptr _AND - _CONST wchar_t *nptr _AND - wchar_t **endptr _AND - int base) -{ - register const wchar_t *s = nptr; - register unsigned long long acc; - register int c; - register unsigned long long cutoff; - register 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 (iswspace(c)); - if (c == L'-') { - neg = 1; - c = *s++; - } else if (c == L'+') - c = *s++; - if ((base == 0 || base == 16) && - c == L'0' && (*s == L'x' || *s == L'X')) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == L'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)LONG_LONG_MIN : LONG_LONG_MAX; - cutlim = cutoff % (unsigned long long)base; - cutoff /= (unsigned long long)base; - for (acc = 0, any = 0;; c = *s++) { - if (iswdigit(c)) - c -= L'0'; - else if (iswalpha(c)) - c -= iswupper(c) ? L'A' - 10 : L'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_LONG_MIN : LONG_LONG_MAX; - rptr->_errno = ERANGE; - } else if (neg) - acc = -acc; - if (endptr != 0) - *endptr = (wchar_t *) (any ? s - 1 : nptr); - return (acc); -} - -#endif /* __GNUC__ */ +/* dummy */ diff --git a/newlib/libc/stdlib/wcstoul.c b/newlib/libc/stdlib/wcstoul.c index 4b0a95031..e87b2ecc9 100644 --- a/newlib/libc/stdlib/wcstoul.c +++ b/newlib/libc/stdlib/wcstoul.c @@ -1,19 +1,28 @@ /* FUNCTION - <>---wide string to unsigned long + <>, <>---wide string to unsigned long INDEX wcstoul + +INDEX + wcstoul_l + INDEX _wcstoul_r ANSI_SYNOPSIS #include unsigned long wcstoul(const wchar_t *__restrict <[s]>, - wchar_t **__restrict <[ptr]>, int <[base]>); + wchar_t **__restrict <[ptr]>, int <[base]>); + + #include + unsigned long wcstoul_l(const wchar_t *__restrict <[s]>, + wchar_t **__restrict <[ptr]>, int <[base]>, + locale_t <[locale]>); unsigned long _wcstoul_r(void *<[reent]>, const wchar_t *<[s]>, - wchar_t **<[ptr]>, int <[base]>); + wchar_t **<[ptr]>, int <[base]>); TRAD_SYNOPSIS #include @@ -72,15 +81,20 @@ The alternate function <<_wcstoul_r>> is a reentrant version. The extra argument <[reent]> is a pointer to a reentrancy structure. +<> is like <> but performs the conversion based on the +locale specified by the locale object locale. If <[locale]> is +LC_GLOBAL_LOCALE or not a valid locale object, the behaviour is undefined. + RETURNS -<> returns the converted value, if any. If no conversion was -made, <<0>> is returned. +<>, <> return the converted value, if any. If no +conversion was made, <<0>> is returned. -<> returns <> if the magnitude of the converted -value is too large, and sets <> to <>. +<>, <> return <> if the magnitude of the +converted value is too large, and sets <> to <>. PORTABILITY <> is ANSI. +<> is a GNU extension. <> requires no supporting OS subroutines. */ @@ -125,19 +139,14 @@ PORTABILITY #include #include #include +#include "../locale/setlocale.h" /* * Convert a wide string to an unsigned long integer. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. */ unsigned long -_DEFUN (_wcstoul_r, (rptr, nptr, endptr, base), - struct _reent *rptr _AND - _CONST wchar_t *nptr _AND - wchar_t **endptr _AND - int base) +_wcstoul_l (struct _reent *rptr, const wchar_t *nptr, wchar_t **endptr, + int base, locale_t loc) { register const wchar_t *s = nptr; register unsigned long acc; @@ -150,7 +159,7 @@ _DEFUN (_wcstoul_r, (rptr, nptr, endptr, base), */ do { c = *s++; - } while (iswspace(c)); + } while (iswspace_l(c, loc)); if (c == L'-') { neg = 1; c = *s++; @@ -167,10 +176,12 @@ _DEFUN (_wcstoul_r, (rptr, nptr, endptr, base), cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; for (acc = 0, any = 0;; c = *s++) { - if (iswdigit(c)) + if (c >= L'0' && c <= L'9') c -= L'0'; - else if (iswalpha(c)) - c -= iswupper(c) ? L'A' - 10 : L'a' - 10; + else if (c >= L'A' && c <= L'Z') + c -= L'A' - 10; + else if (c >= L'a' && c <= L'z') + c -= L'a' - 10; else break; if (c >= base) @@ -193,15 +204,32 @@ _DEFUN (_wcstoul_r, (rptr, nptr, endptr, base), return (acc); } +unsigned long +_DEFUN (_wcstoul_r, (rptr, nptr, endptr, base), + struct _reent *rptr _AND + _CONST wchar_t *nptr _AND + wchar_t **endptr _AND + int base) +{ + return _wcstoul_l (rptr, nptr, endptr, base, __get_current_locale ()); +} + #ifndef _REENT_ONLY +unsigned long +wcstoul_l (const wchar_t *__restrict s, wchar_t **__restrict ptr, int base, + locale_t loc) +{ + return _wcstoul_l (_REENT, s, ptr, base, loc); +} + unsigned long _DEFUN (wcstoul, (s, ptr, base), _CONST wchar_t *__restrict s _AND wchar_t **__restrict ptr _AND int base) { - return _wcstoul_r (_REENT, s, ptr, base); + return _wcstoul_l (_REENT, s, ptr, base, __get_current_locale ()); } #endif diff --git a/newlib/libc/stdlib/wcstoull.c b/newlib/libc/stdlib/wcstoull.c index 206bb3428..131a83795 100644 --- a/newlib/libc/stdlib/wcstoull.c +++ b/newlib/libc/stdlib/wcstoull.c @@ -1,19 +1,30 @@ /* FUNCTION - <>---wide string to unsigned long long + <>, <>---wide string to unsigned long long INDEX wcstoull + +INDEX + wcstoull_l + INDEX _wcstoull_r ANSI_SYNOPSIS #include unsigned long long wcstoull(const wchar_t *__restrict <[s]>, - wchar_t **__restrict <[ptr]>, int <[base]>); + wchar_t **__restrict <[ptr]>, + int <[base]>); + + #include + unsigned long long wcstoull_l(const wchar_t *__restrict <[s]>, + wchar_t **__restrict <[ptr]>, + int <[base]>, + locale_t <[locale]>); unsigned long long _wcstoull_r(void *<[reent]>, const wchar_t *<[s]>, - wchar_t **<[ptr]>, int <[base]>); + wchar_t **<[ptr]>, int <[base]>); TRAD_SYNOPSIS #include @@ -73,18 +84,23 @@ The alternate function <<_wcstoull_r>> is a reentrant version. The extra argument <[reent]> is a pointer to a reentrancy structure. +<> is like <> but performs the conversion based on the +locale specified by the locale object locale. If <[locale]> is +LC_GLOBAL_LOCALE or not a valid locale object, the behaviour is undefined. + RETURNS -<> returns <<0>> and sets <> to <> if the value of -<[base]> is not supported. +<>, <> return <<0>> and sets <> to <> +if the value of <[base]> is not supported. -<> returns the converted value, if any. If no conversion was -made, <<0>> is returned. +<>, <> return the converted value, if any. If no +conversion was made, <<0>> is returned. -<> returns <> if the magnitude of the converted -value is too large, and sets <> to <>. +<>, <> return <> if the magnitude of +the converted value is too large, and sets <> to <>. PORTABILITY <> is ANSI. +<> is a GNU extension. <> requires no supporting OS subroutines. */ @@ -122,19 +138,114 @@ PORTABILITY * SUCH DAMAGE. */ +#define _GNU_SOURCE #include <_ansi.h> +#include #include +#include +#include #include +#include "../locale/setlocale.h" + +/* Make up for older non-compliant limits.h. (This is a C99/POSIX function, + * and both require ULLONG_MAX in limits.h.) */ +#if !defined(ULLONG_MAX) +# define ULLONG_MAX ULONG_LONG_MAX +#endif + +/* + * Convert a wide string to an unsigned long long integer. + */ +unsigned long long +_wcstoull_l (struct _reent *rptr, const wchar_t *nptr, wchar_t **endptr, + int base, locale_t loc) +{ + register const wchar_t *s = nptr; + register unsigned long long acc; + register int c; + register unsigned long long cutoff; + register int neg = 0, any, cutlim; + + if(base < 0 || base == 1 || base > 36) { + rptr->_errno = EINVAL; + return(0ULL); + } + /* + * See strtol for comments as to the logic used. + */ + do { + c = *s++; + } while (iswspace_l(c, loc)); + if (c == L'-') { + neg = 1; + c = *s++; + } else if (c == L'+') + c = *s++; + if ((base == 0 || base == 16) && + c == L'0' && (*s == L'x' || *s == L'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == L'0' ? 8 : 10; + cutoff = (unsigned long long)ULLONG_MAX / (unsigned long long)base; + cutlim = (unsigned long long)ULLONG_MAX % (unsigned long long)base; + for (acc = 0, any = 0;; c = *s++) { + if (c >= L'0' && c <= L'9') + c -= L'0'; + else if (c >= L'A' && c <= L'Z') + c -= L'A' - 10; + else if (c >= L'a' && c <= L'z') + c -= L'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 = ULLONG_MAX; + rptr->_errno = ERANGE; + } else if (neg) + acc = -acc; + if (endptr != 0) + *endptr = (wchar_t *) (any ? s - 1 : nptr); + return (acc); +} + +unsigned long long +_DEFUN (_wcstoull_r, (rptr, nptr, endptr, base), + struct _reent *rptr _AND + _CONST wchar_t *nptr _AND + wchar_t **endptr _AND + int base) +{ + return _wcstoull_l (rptr, nptr, endptr, base, __get_current_locale ()); +} #ifndef _REENT_ONLY +unsigned long long +wcstoull_l (const wchar_t *__restrict s, wchar_t **__restrict ptr, int base, + locale_t loc) +{ + return _wcstoull_l (_REENT, s, ptr, base, loc); +} + unsigned long long _DEFUN (wcstoull, (s, ptr, base), _CONST wchar_t *__restrict s _AND wchar_t **__restrict ptr _AND int base) { - return _wcstoull_r (_REENT, s, ptr, base); + return _wcstoull_l (_REENT, s, ptr, base, __get_current_locale ()); } #endif diff --git a/newlib/libc/stdlib/wcstoull_r.c b/newlib/libc/stdlib/wcstoull_r.c index abad681a3..2997587d8 100644 --- a/newlib/libc/stdlib/wcstoull_r.c +++ b/newlib/libc/stdlib/wcstoull_r.c @@ -1,130 +1 @@ -/* - This code is based on wcstoul.c which has the following copyright. - It is used to convert a wide string into an unsigned long long. - - unsigned long long _wcstoull_r (struct _reent *rptr, const wchar_t *s, - wchar_t **ptr, int base); - -*/ - -/* - * Copyright (c) 1990 Regents of the University of California. - * 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. - * 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 - * 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 - * 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. - */ - -#ifdef __GNUC__ - -#define _GNU_SOURCE -#include <_ansi.h> -#include -#include -#include -#include -#include - -/* Make up for older non-compliant limits.h. (This is a C99/POSIX function, - * and both require ULLONG_MAX in limits.h.) */ -#if !defined(ULLONG_MAX) -# define ULLONG_MAX ULONG_LONG_MAX -#endif - -/* - * Convert a wide 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 -_DEFUN (_wcstoull_r, (rptr, nptr, endptr, base), - struct _reent *rptr _AND - _CONST wchar_t *nptr _AND - wchar_t **endptr _AND - int base) -{ - register const wchar_t *s = nptr; - register unsigned long long acc; - register int c; - register unsigned long long cutoff; - register int neg = 0, any, cutlim; - - if(base < 0 || base == 1 || base > 36) { - rptr->_errno = EINVAL; - return(0ULL); - } - /* - * See strtol for comments as to the logic used. - */ - do { - c = *s++; - } while (iswspace(c)); - if (c == L'-') { - neg = 1; - c = *s++; - } else if (c == L'+') - c = *s++; - if ((base == 0 || base == 16) && - c == L'0' && (*s == L'x' || *s == L'X')) { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == L'0' ? 8 : 10; - cutoff = (unsigned long long)ULLONG_MAX / (unsigned long long)base; - cutlim = (unsigned long long)ULLONG_MAX % (unsigned long long)base; - for (acc = 0, any = 0;; c = *s++) { - if (iswdigit(c)) - c -= L'0'; - else if (iswalpha(c)) - c -= iswupper(c) ? L'A' - 10 : L'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 = ULLONG_MAX; - rptr->_errno = ERANGE; - } else if (neg) - acc = -acc; - if (endptr != 0) - *endptr = (wchar_t *) (any ? s - 1 : nptr); - return (acc); -} - -#endif /* __GNUC__ */ +/* dummy */ diff --git a/winsup/cygwin/common.din b/winsup/cygwin/common.din index 2cc826459..f945078df 100644 --- a/winsup/cygwin/common.din +++ b/winsup/cygwin/common.din @@ -1366,16 +1366,23 @@ strsignal SIGFE strspn NOSIGFE strstr NOSIGFE strtod SIGFE +strtod_l SIGFE strtof SIGFE +strtof_l SIGFE strtoimax = strtoll NOSIGFE strtok NOSIGFE strtok_r NOSIGFE strtol NOSIGFE +strtol_l NOSIGFE strtold SIGFE +strtold_l SIGFE strtoll NOSIGFE +strtoll_l NOSIGFE strtosigno NOSIGFE strtoul NOSIGFE +strtoul_l NOSIGFE strtoull NOSIGFE +strtoull_l NOSIGFE strtoumax = strtoull NOSIGFE strupr NOSIGFE strxfrm NOSIGFE @@ -1527,15 +1534,22 @@ wcsrtombs NOSIGFE wcsspn NOSIGFE wcsstr NOSIGFE wcstod NOSIGFE +wcstod_l NOSIGFE wcstof NOSIGFE +wcstof_l NOSIGFE wcstoimax = wcstoll NOSIGFE wcstok NOSIGFE wcstol NOSIGFE +wcstol_l NOSIGFE wcstold NOSIGFE +wcstold_l NOSIGFE wcstoll NOSIGFE +wcstoll_l NOSIGFE wcstombs NOSIGFE wcstoul NOSIGFE +wcstoul_l NOSIGFE wcstoull NOSIGFE +wcstoull_l NOSIGFE wcstoumax = wcstoull NOSIGFE wcswidth NOSIGFE wcsxfrm NOSIGFE diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h index ee8011de8..0e00ae1a7 100644 --- a/winsup/cygwin/include/cygwin/version.h +++ b/winsup/cygwin/include/cygwin/version.h @@ -463,12 +463,15 @@ details. */ toupper_l, towctrans_l, towlower_l, towupper_l, wctrans_l, wctype_l. 300: Export strcasecmp_l, strcoll_l, strfmon_l, strftime_l, strncasecmp_l, strxfrm_l, wcscasecmp_l, wcscoll_l, wcstrncasecmp_l, wcstrxfrm_l. + 301: Export strtod_l, strtof_l, strtol_l, strtold_l, strtoll_l, strtoul_l, + strtoull_l, wcstod_l, wcstof_l, wcstol_l, wcstold_l, wcstoll_l, + wcstoul_l, wcstoull_l. Note that we forgot to bump the api for ualarm, strtoll, strtoull, sigaltstack, sethostname. */ #define CYGWIN_VERSION_API_MAJOR 0 -#define CYGWIN_VERSION_API_MINOR 300 +#define CYGWIN_VERSION_API_MINOR 301 /* There is also a compatibity version number associated with the shared memory regions. It is incremented when incompatible changes are made to the shared diff --git a/winsup/doc/posix.xml b/winsup/doc/posix.xml index 48499fb4e..5a1e0406c 100644 --- a/winsup/doc/posix.xml +++ b/winsup/doc/posix.xml @@ -1290,11 +1290,11 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008). exp10l fcloseall fcloseall_r - fegetprec - fesetprec - feenableexcept fedisableexcept + feenableexcept fegetexcept + fegetprec + fesetprec ffsl ffsll fgets_unlocked @@ -1310,9 +1310,9 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008). fsetxattr get_avphys_pages get_current_dir_name - get_phys_pages get_nprocs get_nprocs_conf + get_phys_pages getmntent_r getopt_long getopt_long_only @@ -1350,6 +1350,13 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008). sincosf sincosl strchrnul + strtod_l + strtof_l + strtol_l + strtold_l + strtoll_l + strtoul_l + strtoull_l sysinfo tdestroy timegm @@ -1360,6 +1367,13 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008). vasnprintf vasprintf vasprintf_r + wcstod_l + wcstof_l + wcstol_l + wcstold_l + wcstoll_l + wcstoul_l + wcstoull_l -- 2.43.5