diff options
Diffstat (limited to 'newlib/libc/stdlib/wcstod.c')
-rw-r--r-- | newlib/libc/stdlib/wcstod.c | 110 |
1 files changed, 86 insertions, 24 deletions
diff --git a/newlib/libc/stdlib/wcstod.c b/newlib/libc/stdlib/wcstod.c index c91ecf2..43f7b4e 100644 --- a/newlib/libc/stdlib/wcstod.c +++ b/newlib/libc/stdlib/wcstod.c @@ -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; @@ -212,10 +257,27 @@ _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; |