]> sourceware.org Git - newlib-cygwin.git/commitdiff
Implement strto[dflu]_l/wcsto[dflu]_l
authorCorinna Vinschen <corinna@vinschen.de>
Wed, 10 Aug 2016 14:30:46 +0000 (16:30 +0200)
committerCorinna Vinschen <corinna@vinschen.de>
Mon, 15 Aug 2016 15:35:21 +0000 (17:35 +0200)
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 <corinna@vinschen.de>
27 files changed:
newlib/libc/include/stdlib.h
newlib/libc/include/wchar.h
newlib/libc/locale/setlocale.h
newlib/libc/stdlib/gdtoa-gethex.c
newlib/libc/stdlib/mprec.h
newlib/libc/stdlib/strtod.c
newlib/libc/stdlib/strtodg.c
newlib/libc/stdlib/strtol.c
newlib/libc/stdlib/strtold.c
newlib/libc/stdlib/strtoll.c
newlib/libc/stdlib/strtoll_r.c
newlib/libc/stdlib/strtorx.c
newlib/libc/stdlib/strtoul.c
newlib/libc/stdlib/strtoull.c
newlib/libc/stdlib/strtoull_r.c
newlib/libc/stdlib/wcsnrtombs.c
newlib/libc/stdlib/wcstod.c
newlib/libc/stdlib/wcstol.c
newlib/libc/stdlib/wcstold.c
newlib/libc/stdlib/wcstoll.c
newlib/libc/stdlib/wcstoll_r.c
newlib/libc/stdlib/wcstoul.c
newlib/libc/stdlib/wcstoull.c
newlib/libc/stdlib/wcstoull_r.c
winsup/cygwin/common.din
winsup/cygwin/include/cygwin/version.h
winsup/doc/posix.xml

index 3d1b8a9b015297adc9069b3ea95efe67ab2f9a24..7b62e004f51710441120c8708fce54fe83d7d5f2 100644 (file)
 #include <cygwin/stdlib.h>
 #endif
 
+#if __GNU_VISIBLE
+#include <sys/_locale.h>
+#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
index 4df60b4c2525efd240610a3921aa2eae3d1ad8a4..b7f8374e583d0e4f13f68c0fa6131d3005a8e4c9 100644 (file)
@@ -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 *));
index b528ab92f7e3dbd8f60ea8dee182d185de02516d..de2bd6733c00979a4b3d1651b08acdddcbb438a3 100644 (file)
@@ -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 *
index 3449c989e497cde3e3b27f612db4e01245e1e9a9..fd3903c4fcdd6a730f58237c70dc0b9240c10e04 100644 (file)
@@ -32,10 +32,10 @@ THIS SOFTWARE.
 #include <_ansi.h>
 #include <reent.h>
 #include <string.h>
+#include <locale.h>
 #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];
 
index afda63e73be88ee42ba8ce6b86b40db3fb32ecb8..330c3981b38a8061e40f4b45e5a5356f8648ca5a 100644 (file)
@@ -32,6 +32,7 @@
 #include <errno.h>
 #include <sys/config.h>
 #include <sys/types.h>
+#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)
index 433dc7f32499cc291ce76d9aeb4674d0874a2816..e908fcbbc6e57833c7a967466df835f9d45030d1 100644 (file)
@@ -1,18 +1,43 @@
 /*
 FUNCTION
-        <<strtod>>, <<strtof>>---string to double or float
+        <<strtod>>, <<strtof>>, <<strtold>>, <<strtod_l>>, <<strtof_l>>, <<strtold_l>>---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 <stdlib.h>
         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 <stdlib.h>
+        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 <<strtod>> 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:
+       <<strtod>>, <<strtof>>, <<strtold>> 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]>.
-       <<strtof>> is identical to <<strtod>> 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, <<strtof>> is currently subject to
        double rounding errors.
 
+       <<strtod_l>>, <<strtof_l>>, <<strtold_l>> are like <<strtod>>,
+       <<strtof>>, <<strtold>> 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
-       <<strtod>> 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 <<HUGE_VAL>> is returned, and <<ERANGE>> is
-       stored in errno. If the correct value would cause underflow, 0
-       is returned and <<ERANGE>> 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
+       <<HUGE_VAL>> (<<HUGE_VALF>>, <<HUGE_VALL>>) is returned, and
+       <<ERANGE>> is stored in errno. If the correct value would cause
+       underflow, 0 is returned and <<ERANGE>> is stored in errno.
+
+PORTABILITY
+<<strtod>> is ANSI.
+<<strtof>>, <<strtold>> are C99.
+<<strtod_l>>, <<strtof_l>>, <<strtold_l>> are GNU extensions.
 
 Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
 <<lseek>>, <<read>>, <<sbrk>>, <<write>>.
@@ -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 <errno.h>
 #include <stdlib.h>
@@ -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 <fenv.h> */
@@ -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;
index a6b32908beb9d3ca465ec8e24771d55215f7f74a..d8546c336941e6c3370d6445fb26fc3cd9871ad9 100644 (file)
@@ -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
index 7273c7d4b736d3027b89a2b06ff14ff17263a681..276ad13401b2606116eadcdcf133174ede55babe 100644 (file)
@@ -1,18 +1,27 @@
 /*
 FUNCTION
-   <<strtol>>---string to long
+   <<strtol>>, <<strtol_l>>---string to long
 
 INDEX
        strtol
+
+INDEX
+       strtol_l
+
 INDEX
        _strtol_r
 
 ANSI_SYNOPSIS
        #include <stdlib.h>
-        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 <stdlib.h>
+        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 <stdlib.h>
@@ -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 <<NULL>>).
 
+<<strtol_l>> is like <<strtol>> 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
-<<strtol>> returns the converted value, if any. If no conversion was
-made, 0 is returned.
+<<strtol>>, <<strtol_l>> return the converted value, if any. If no
+conversion was made, 0 is returned.
 
-<<strtol>> returns <<LONG_MAX>> or <<LONG_MIN>> if the magnitude of
-the converted value is too large, and sets <<errno>> to <<ERANGE>>.
+<<strtol>>, <<strtol_l>> return <<LONG_MAX>> or <<LONG_MIN>> if the
+magnitude of the converted value is too large, and sets <<errno>>
+to <<ERANGE>>.
 
 PORTABILITY
 <<strtol>> is ANSI.
+<<strtol_l>> 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 <limits.h>
 #include <ctype.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <reent.h>
+#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
index 1128b747a7b41bceb1aeb8d66ae102dd532169db..6bd1c2cbb00cd601936d09c70762acd4969ebd18 100644 (file)
@@ -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 */
index 3ad8199a0dfc75406b3c1304fb9f484055d0a75d..e61a62a7d130febc3260403da99ec882b8c7d1b4 100644 (file)
@@ -1,18 +1,29 @@
 /*
 FUNCTION
-   <<strtoll>>---string to long long
+   <<strtoll>>, <<strtoll_l>>---string to long long
 
 INDEX
        strtoll
+
+INDEX
+       strtoll_l
+
 INDEX
        _strtoll_r
 
 ANSI_SYNOPSIS
        #include <stdlib.h>
-        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 <stdlib.h>
+        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 <stdlib.h>
@@ -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 <<NULL>>).
 
+<<strtoll_l>> is like <<strtoll>> 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
-<<strtoll>> returns the converted value, if any. If no conversion was
-made, 0 is returned.
+<<strtoll>>, <<strtoll_l>> return the converted value, if any. If no
+conversion was made, 0 is returned.
 
-<<strtoll>> returns <<LONG_LONG_MAX>> or <<LONG_LONG_MIN>> if the magnitude of
-the converted value is too large, and sets <<errno>> to <<ERANGE>>.
+<<strtoll>>, <<strtoll_l>> return <<LONG_LONG_MAX>> or <<LONG_LONG_MIN>>
+if the magnitude of the converted value is too large, and sets <<errno>>
+to <<ERANGE>>.
 
 PORTABILITY
 <<strtoll>> is ANSI.
+<<strtoll_l>> 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 <limits.h>
 #include <ctype.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <reent.h>
+#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
index 515464db1f06e0cf24cef4d6cd5d9bd978dcc72c..2997587d820c928c3417c55cbe184b900144c292 100644 (file)
@@ -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 <limits.h>
-#include <ctype.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <reent.h>
-
-/*
- * 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 */
index 961ecd2f2c33560028ad911f6be638bb6bd979bf..aeeb25066dd8948720bc0b58d77f52c06ac0a6cd 100644 (file)
@@ -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;
        }
index 12c6834dc38fc9243c78df717ec30d457d9f2f88..062606f4e7890046a3321febb8d30f134058ab50 100644 (file)
@@ -1,19 +1,28 @@
 /*
 FUNCTION
-       <<strtoul>>---string to unsigned long
+       <<strtoul>>, <<strtoul_l>>---string to unsigned long
 
 INDEX
        strtoul
+
+INDEX
+       strtoul_l
+
 INDEX
        _strtoul_r
 
 ANSI_SYNOPSIS
        #include <stdlib.h>
-        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 <stdlib.h>
+        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 <stdlib.h>
@@ -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 <<NULL>>).
 
+<<strtoul_l>> is like <<strtoul>> 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
-<<strtoul>> returns the converted value, if any. If no conversion was
-made, <<0>> is returned.
+<<strtoul>>, <strtoul_l>> return the converted value, if any. If no
+conversion was made, <<0>> is returned.
 
-<<strtoul>> returns <<ULONG_MAX>> if the magnitude of the converted
-value is too large, and sets <<errno>> to <<ERANGE>>.
+<<strtoul>>, <strtoul_l>> return <<ULONG_MAX>> if the magnitude of the
+converted value is too large, and sets <<errno>> to <<ERANGE>>.
 
 PORTABILITY
 <<strtoul>> is ANSI.
+<<strtoul_l>> is a GNU extension.
 
 <<strtoul>> requires no supporting OS subroutines.
 */
@@ -118,25 +131,21 @@ PORTABILITY
  * SUCH DAMAGE.
  */
 
+#define _GNU_SOURCE
 #include <_ansi.h>
 #include <limits.h>
 #include <ctype.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <reent.h>
+#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
index 13a54dbb4d00541b505953f8f188bc1a32d5409d..ba6452e62212b6946f69f5e6bcd64797d26e599a 100644 (file)
@@ -1,19 +1,26 @@
 /*
 FUNCTION
-       <<strtoull>>---string to unsigned long long
+       <<strtoull>>, <<strtoull_l>>---string to unsigned long long
 
 INDEX
        strtoull
+
 INDEX
-       _strtoull_r
+       strtoull_l
 
 ANSI_SYNOPSIS
        #include <stdlib.h>
-        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 <stdlib.h>
+        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 <stdlib.h>
@@ -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 <<NULL>>).
 
+<<strtoull_l>> is like <<strtoull>> 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
-<<strtoull>> returns the converted value, if any. If no conversion was
-made, <<0>> is returned.
+<<strtoull>>, <<strtoull_l>> return the converted value, if any. If no
+conversion was made, <<0>> is returned.
 
-<<strtoull>> returns <<ULONG_LONG_MAX>> if the magnitude of the converted
-value is too large, and sets <<errno>> to <<ERANGE>>.
+<<strtoull>>, <<strtoull_l>> return <<ULONG_LONG_MAX>> if the magnitude
+of the converted value is too large, and sets <<errno>> to <<ERANGE>>.
 
 PORTABILITY
 <<strtoull>> is ANSI.
+<<strtoull_l>> is a GNU extension.
 
 <<strtoull>> requires no supporting OS subroutines.
 */
@@ -118,22 +129,104 @@ PORTABILITY
  * SUCH DAMAGE.
  */
 
+#define _GNU_SOURCE
 #include <_ansi.h>
 #include <limits.h>
 #include <ctype.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <reent.h>
+#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
index d0868adf2b98e10ab2c89ff3af79edbbdd0882d1..2997587d820c928c3417c55cbe184b900144c292 100644 (file)
@@ -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 <limits.h>
-#include <ctype.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <reent.h>
-
-/*
- * 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 */
index b09f7e19e02d137410f4138e21040758ddc101d3..8ad8bcd2c3ee2224fab6f9105a4e2063e17257bd 100644 (file)
@@ -103,15 +103,11 @@ PORTABILITY
 #include <stdio.h>
 #include <errno.h>
 #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 */
index c91ecf2fee04772331d2c40f4f91f5c39b1cdc85..43f7b4eecd785e17d9a20f0400157a9b12bee2b8 100644 (file)
@@ -1,22 +1,48 @@
 /*
 FUNCTION
-        <<wcstod>>, <<wcstof>>---wide char string to double or float
+        <<wcstod>>, <<wcstof>>, <<wcstold>>, <<wcstod_l>>, <<wcstof_l>>, <<wcstold_l>>---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 <stdlib.h>
         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 <stdlib.h>
+        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 <<wcstod>> 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:
+       <<wcstod>>, <<wcstof>>, <<wcstold>> 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]>.
-       <<wcstof>> is identical to <<wcstod>> 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, <<wcstof>> is currently subject to
        double rounding errors.
 
+       <<wcstod_l>>, <<wcstof_l>>, <<wcstold_l>> are like <<wcstod>>,
+       <<wcstof>>, <<wcstold>> 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 <<wcstod>> and <<wcstof>>, 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 <<ERANGE>> is stored in errno.
 
+PORTABILITY
+<<wcstod>> is ANSI.
+<<wcstof>>, <<wcstold>> are C99.
+<<wcstod_l>>, <<wcstof_l>>, <<wcstold_l>> are GNU extensions.
+
 Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
 <<lseek>>, <<read>>, <<sbrk>>, <<write>>.
 */
@@ -123,12 +159,11 @@ Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
 #include <wctype.h>
 #include <locale.h>
 #include <math.h>
+#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;
index adda9c296dcccb3d8adcdf951c8d4c80219759df..4c74805946f7e96038cfa8a5552d5c5a9cc7a0eb 100644 (file)
@@ -1,19 +1,28 @@
 /*
 FUNCTION
-   <<wcstol>>---wide string to long
+   <<wcstol>>, <<wcstol_l>>---wide string to long
 
 INDEX
        wcstol
+
+INDEX
+       wcstol_l
+
 INDEX
        _wcstol_r
 
 ANSI_SYNOPSIS
        #include <wchar.h>
         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 <wchar.h>
+        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 <stdlib.h>
@@ -71,15 +80,21 @@ not <<NULL>>).
 The alternate function <<_wcstol_r>> is a reentrant version.  The
 extra argument <[reent]> is a pointer to a reentrancy structure.
 
+<<wcstol_l>> is like <<wcstol>> 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
-<<wcstol>> returns the converted value, if any. If no conversion was
-made, 0 is returned.
+<<wcstol>>, <<wcstol_l>> return the converted value, if any. If no
+conversion was made, 0 is returned.
 
-<<wcstol>> returns <<LONG_MAX>> or <<LONG_MIN>> if the magnitude of
-the converted value is too large, and sets <<errno>> to <<ERANGE>>.
+<<wcstol>>, <<wcstol_l>> return <<LONG_MAX>> or <<LONG_MIN>> if the
+magnitude of the converted value is too large, and sets <<errno>>
+to <<ERANGE>>.
 
 PORTABILITY
 <<wcstol>> is ANSI.
+<<wcstol_l>> is a GNU extension.
 
 No supporting OS subroutines are required.
 */
@@ -124,19 +139,14 @@ No supporting OS subroutines are required.
 #include <errno.h>
 #include <wchar.h>
 #include <reent.h>
+#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
index e94aca9198b448f1c18acf0e37bb9e48e6dffacd..c57def21d643a6ba0964844e4520777c0f78171b 100644 (file)
@@ -34,13 +34,15 @@ POSSIBILITY OF SUCH DAMAGE.
 #include <wctype.h>
 #include <locale.h>
 #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
+}
index 2c36d6d009317edeb53b7043a8f770023895f114..2996b11a68d17828b2b277fea609e7fa33e10753 100644 (file)
@@ -1,19 +1,28 @@
 /*
 FUNCTION
-   <<wcstoll>>---wide string to long long
+   <<wcstoll>>, <<wcstoll_l>>---wide string to long long
 
 INDEX
        wcstoll
+
+INDEX
+       wcstoll_l
+
 INDEX
        _wcstoll_r
 
 ANSI_SYNOPSIS
        #include <wchar.h>
         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 <wchar.h>
+        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 <stdlib.h>
@@ -71,15 +80,21 @@ not <<NULL>>).
 The alternate function <<_wcstoll_r>> is a reentrant version.  The
 extra argument <[reent]> is a pointer to a reentrancy structure.
 
+<<wcstoll_l>> is like <<wcstoll>> 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
-<<wcstoll>> returns the converted value, if any. If no conversion was
-made, 0 is returned.
+<<wcstoll>>, <<wcstoll_l>> return the converted value, if any. If no
+conversion was made, 0 is returned.
 
-<<wcstoll>> returns <<LONG_LONG_MAX>> or <<LONG_LONG_MIN>> if the magnitude of
-the converted value is too large, and sets <<errno>> to <<ERANGE>>.
+<<wcstoll>>, <<wcstoll_l>> return <<LONG_LONG_MAX>> or <<LONG_LONG_MIN>>
+if the magnitude of the converted value is too large, and sets <<errno>>
+to <<ERANGE>>.
 
 PORTABILITY
 <<wcstoll>> is ANSI.
+<<wcstoll_l>> 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 <limits.h>
 #include <wctype.h>
 #include <errno.h>
 #include <wchar.h>
 #include <reent.h>
+#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
index d6baacaf5c3d3838ea1eb7fdfeda60d5e9a638af..2997587d820c928c3417c55cbe184b900144c292 100644 (file)
@@ -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 <limits.h>
-#include <wctype.h>
-#include <errno.h>
-#include <wchar.h>
-#include <reent.h>
-
-/*
- * 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 */
index 4b0a95031bc57a6c8083fb86ff65899489d96237..e87b2ecc9cb38fb62006f74cbdf3fb743de9b7a5 100644 (file)
@@ -1,19 +1,28 @@
 /*
 FUNCTION
-       <<wcstoul>>---wide string to unsigned long
+       <<wcstoul>>, <<wcstoul_l>>---wide string to unsigned long
 
 INDEX
        wcstoul
+
+INDEX
+       wcstoul_l
+
 INDEX
        _wcstoul_r
 
 ANSI_SYNOPSIS
        #include <wchar.h>
         unsigned long wcstoul(const wchar_t *__restrict <[s]>,
-                             wchar_t **__restrict <[ptr]>, int <[base]>);
+                             wchar_t **__restrict <[ptr]>, int <[base]>);
+
+       #include <wchar.h>
+        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 <wchar.h>
@@ -72,15 +81,20 @@ The alternate function <<_wcstoul_r>> is a reentrant version.  The
 extra argument <[reent]> is a pointer to a reentrancy structure.
 
 
+<<wcstoul_l>> is like <<wcstoul>> 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
-<<wcstoul>> returns the converted value, if any. If no conversion was
-made, <<0>> is returned.
+<<wcstoul>>, <<wcstoul_l>> return the converted value, if any. If no
+conversion was made, <<0>> is returned.
 
-<<wcstoul>> returns <<ULONG_MAX>> if the magnitude of the converted
-value is too large, and sets <<errno>> to <<ERANGE>>.
+<<wcstoul>>, <<wcstoul_l>> return <<ULONG_MAX>> if the magnitude of the
+converted value is too large, and sets <<errno>> to <<ERANGE>>.
 
 PORTABILITY
 <<wcstoul>> is ANSI.
+<<wcstoul_l>> is a GNU extension.
 
 <<wcstoul>> requires no supporting OS subroutines.
 */
@@ -125,19 +139,14 @@ PORTABILITY
 #include <errno.h>
 #include <stdlib.h>
 #include <reent.h>
+#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
index 206bb3428b5cde66c4c445ed99534dc584933c5b..131a8379518465514e1762b7a2ed97ea252929ab 100644 (file)
@@ -1,19 +1,30 @@
 /*
 FUNCTION
-       <<wcstoull>>---wide string to unsigned long long
+       <<wcstoull>>, <<wcstoull_l>>---wide string to unsigned long long
 
 INDEX
        wcstoull
+
+INDEX
+       wcstoull_l
+
 INDEX
        _wcstoull_r
 
 ANSI_SYNOPSIS
        #include <wchar.h>
         unsigned long long wcstoull(const wchar_t *__restrict <[s]>,
-                              wchar_t **__restrict <[ptr]>, int <[base]>);
+                                   wchar_t **__restrict <[ptr]>,
+                                   int <[base]>);
+
+       #include <wchar.h>
+        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 <wchar.h>
@@ -73,18 +84,23 @@ The alternate function <<_wcstoull_r>> is a reentrant version.  The
 extra argument <[reent]> is a pointer to a reentrancy structure.
 
 
+<<wcstoull_l>> is like <<wcstoull>> 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
-<<wcstoull>> returns <<0>> and sets <<errno>> to <<EINVAL>> if the value of
-<[base]> is not supported.
+<<wcstoull>>, <<wcstoull_l>> return <<0>> and sets <<errno>> to <<EINVAL>>
+if the value of <[base]> is not supported.
 
-<<wcstoull>> returns the converted value, if any. If no conversion was
-made, <<0>> is returned.
+<<wcstoull>>, <<wcstoull_l>> return the converted value, if any. If no
+conversion was made, <<0>> is returned.
 
-<<wcstoull>> returns <<ULLONG_MAX>> if the magnitude of the converted
-value is too large, and sets <<errno>> to <<ERANGE>>.
+<<wcstoull>>, <<wcstoull_l>> return <<ULLONG_MAX>> if the magnitude of
+the converted value is too large, and sets <<errno>> to <<ERANGE>>.
 
 PORTABILITY
 <<wcstoull>> is ANSI.
+<<wcstoull_l>> is a GNU extension.
 
 <<wcstoull>> requires no supporting OS subroutines.
 */
@@ -122,19 +138,114 @@ PORTABILITY
  * SUCH DAMAGE.
  */
 
+#define _GNU_SOURCE
 #include <_ansi.h>
+#include <limits.h>
 #include <wchar.h>
+#include <wctype.h>
+#include <errno.h>
 #include <reent.h>
+#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
index abad681a3c814f651eff65e36c48fc305daa3ecd..2997587d820c928c3417c55cbe184b900144c292 100644 (file)
@@ -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 <limits.h>
-#include <wchar.h>
-#include <wctype.h>
-#include <errno.h>
-#include <reent.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.
- *
- * 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 */
index 2cc82645931f4354f4a398d9603a40a1726a18b2..f945078df5f00aa28ff3acfaebb55ceeb0acb428 100644 (file)
@@ -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
index ee8011de875c7ba385cf3ed3fff25f0355515cab..0e00ae1a76938542fd5fba56d9b39e280c34f974 100644 (file)
@@ -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
index 48499fb4e560c30f59d4c3289e3cfd5de83f9e33..5a1e0406ce818640de62b87214542f5cfddfee10 100644 (file)
@@ -1290,11 +1290,11 @@ also IEEE Std 1003.1-2008 (POSIX.1-2008).</para>
     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).</para>
     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).</para>
     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).</para>
     vasnprintf
     vasprintf
     vasprintf_r
+    wcstod_l
+    wcstof_l
+    wcstol_l
+    wcstold_l
+    wcstoll_l
+    wcstoul_l
+    wcstoull_l
 </screen>
 
 </sect1>
This page took 0.124206 seconds and 5 git commands to generate.