From 77ea728b96e00e063b2243487a35e5c395639bfc Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Thu, 12 Feb 2009 23:10:01 +0000 Subject: 2009-02-12 Corinna Vinschen * libc/include/wchar.h (_wcstod_r): Declare. (_wcstof_r): Declare. (wcstod): Declare. (wcstof): Declare. * libc/stdlib/Makefile.am (GENERAL_SOURCES): Add wcstod.c. (CHEWOUT_FILES): Add wcstod.def. * libc/stdlib/Makefile.in: Regenerate. * libc/stdlib/stdlib.tex: Add wcstod. * libc/stdlib/wcstod.c: New file. --- newlib/libc/stdlib/wcstod.c | 209 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 newlib/libc/stdlib/wcstod.c (limited to 'newlib/libc/stdlib/wcstod.c') diff --git a/newlib/libc/stdlib/wcstod.c b/newlib/libc/stdlib/wcstod.c new file mode 100644 index 000000000..403415705 --- /dev/null +++ b/newlib/libc/stdlib/wcstod.c @@ -0,0 +1,209 @@ +/* +FUNCTION + <>, <>---wide char string to double or float + +INDEX + wcstod +INDEX + _wcstod_r +INDEX + wcstof +INDEX + _wcstof_r + +ANSI_SYNOPSIS + #include + double wcstod(const wchar_t *<[str]>, wchar_t **<[tail]>); + float wcstof(const wchar_t *<[str]>, wchar_t **<[tail]>); + + double _wcstod_r(void *<[reent]>, + const wchar_t *<[str]>, wchar_t **<[tail]>); + float _wcstof_r(void *<[reent]>, + const wchar_t *<[str]>, wchar_t **<[tail]>); + +TRAD_SYNOPSIS + #include + double wcstod(<[str]>,<[tail]>) + wchar_t *<[str]>; + wchar_t **<[tail]>; + + float wcstof(<[str]>,<[tail]>) + wchar_t *<[str]>; + wchar_t **<[tail]>; + + double _wcstod_r(<[reent]>,<[str]>,<[tail]>) + wchar_t *<[reent]>; + wchar_t *<[str]>; + wchar_t **<[tail]>; + + float _wcstof_r(<[reent]>,<[str]>,<[tail]>) + wchar_t *<[reent]>; + wchar_t *<[str]>; + wchar_t **<[tail]>; + +DESCRIPTION + The function <> parses the wide character string <[str]>, + producing a substring which can be converted to a double + value. The substring converted is the longest initial + subsequence of <[str]>, beginning with the first + non-whitespace character, that has one of these formats: + .[+|-]<[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)] + .[+|-](n|N)(a|A)(n|N)[<(>[<[hexdigits]>]<)>] + .[+|-]0(x|X)<[hexdigits]>[.[<[hexdigits]>]][(p|P)[+|-]<[digits]>] + .[+|-]0(x|X).<[hexdigits]>[(p|P)[+|-]<[digits]>] + The substring contains no characters if <[str]> is empty, consists + entirely of whitespace, or if the first non-whitespace + character is something other than <<+>>, <<->>, <<.>>, or a + digit, and cannot be parsed as infinity or NaN. If the platform + does not support NaN, then NaN is treated as an empty substring. + If the substring is empty, no conversion is done, and + the value of <[str]> is stored in <<*<[tail]>>>. Otherwise, + the substring is converted, and a pointer to the final string + (which will contain at least the terminating null character of + <[str]>) is stored in <<*<[tail]>>>. If you want no + assignment to <<*<[tail]>>>, pass a null pointer as <[tail]>. + <> is identical to <> except for its return type. + + This implementation returns the nearest machine number to the + input decimal string. Ties are broken by using the IEEE + round-even rule. However, <> is currently subject to + double rounding errors. + + The alternate functions <<_wcstod_r>> and <<_wcstof_r>:> are + reentrant versions of <> and <>, respectively. + The extra argument <[reent]> is a pointer to a reentrancy structure. + +RETURNS + Return the converted substring value, if any. If + no conversion could be performed, 0 is returned. If the + correct value is out of the range of representable values, + plus or minus <> is returned, and <> is + stored in errno. If the correct value would cause underflow, 0 + is returned and <> is stored in errno. + +Supporting OS subroutines required: <>, <>, <>, +<>, <>, <>, <>. +*/ + +/*- + * Copyright (c) 2002 Tim J. Robbins + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <_ansi.h> +#include +#include +#include + +double +_DEFUN (_wcstod_r, (ptr, nptr, endptr), + struct _reent *ptr _AND + _CONST wchar_t *nptr _AND + wchar_t **endptr) +{ + static const mbstate_t initial; + mbstate_t mbs; + double val; + char *buf, *end; + const wchar_t *wcp; + size_t len; + + while (iswspace(*nptr)) + nptr++; + + /* + * Convert the supplied numeric wide char. string to multibyte. + * + * We could attempt to find the end of the numeric portion of the + * wide char. string to avoid converting unneeded characters but + * choose not to bother; optimising the uncommon case where + * the input string contains a lot of text after the number + * duplicates a lot of strtod()'s functionality and slows down the + * most common cases. + */ + wcp = nptr; + mbs = initial; + if ((len = _wcsrtombs_r(ptr, NULL, &wcp, 0, &mbs)) == (size_t)-1) { + if (endptr != NULL) + *endptr = (wchar_t *)nptr; + return (0.0); + } + if ((buf = _malloc_r(ptr, len + 1)) == NULL) + return (0.0); + mbs = initial; + _wcsrtombs_r(ptr, buf, &wcp, len + 1, &mbs); + + /* Let strtod() do most of the work for us. */ + val = _strtod_r(ptr, buf, &end); + + /* + * We only know where the number ended in the _multibyte_ + * representation of the string. If the caller wants to know + * where it ended, count multibyte characters to find the + * corresponding position in the wide char string. + */ + if (endptr != NULL) + /* XXX Assume each wide char is one byte. */ + *endptr = (wchar_t *)nptr + (end - buf); + + _free_r(ptr, buf); + + return (val); +} + +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); + if (isnan (retval)) + return nanf (NULL); + return (float)retval; +} + +#ifndef NO_REENT + +double +_DEFUN (wcstod, (nptr, endptr), + _CONST wchar_t *nptr _AND wchar_t **endptr) +{ + return _wcstod_r (_REENT, nptr, endptr); +} + +float +_DEFUN (wcstof, (nptr, endptr), + _CONST wchar_t *nptr _AND + wchar_t **endptr) +{ + double retval = _wcstod_r (_REENT, nptr, endptr); + if (isnan (retval)) + return nanf (NULL); + return (float)retval; +} + +#endif -- cgit v1.2.3