diff options
author | Eric Blake <eblake@redhat.com> | 2008-02-21 17:14:14 +0000 |
---|---|---|
committer | Eric Blake <eblake@redhat.com> | 2008-02-21 17:14:14 +0000 |
commit | 7a44c13ecb8b0b83367875e2db4add4a53ed9188 (patch) | |
tree | fc285cbae225c8e283c3babe42e50746dc01bc2c /newlib/libc/stdlib/strtod.c | |
parent | 1f71763a62630d4e4baf86f7fa90f1c9a3242cc6 (diff) | |
download | cygnal-7a44c13ecb8b0b83367875e2db4add4a53ed9188.tar.gz cygnal-7a44c13ecb8b0b83367875e2db4add4a53ed9188.tar.bz2 cygnal-7a44c13ecb8b0b83367875e2db4add4a53ed9188.zip |
Fix strtod("-0x", NULL).
* libc/stdlib/strtod.c (_strtod_r): Fall back to 0 if hex parse
fails.
Diffstat (limited to 'newlib/libc/stdlib/strtod.c')
-rw-r--r-- | newlib/libc/stdlib/strtod.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/newlib/libc/stdlib/strtod.c b/newlib/libc/stdlib/strtod.c index e206d0587..80e5aacef 100644 --- a/newlib/libc/stdlib/strtod.c +++ b/newlib/libc/stdlib/strtod.c @@ -14,7 +14,7 @@ ANSI_SYNOPSIS double strtod(const char *<[str]>, char **<[tail]>); float strtof(const char *<[str]>, char **<[tail]>); - double _strtod_r(void *<[reent]>, + double _strtod_r(void *<[reent]>, const char *<[str]>, char **<[tail]>); TRAD_SYNOPSIS @@ -37,12 +37,19 @@ DESCRIPTION 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 the format: - .[+|-]<[digits]>[.][<[digits]>][(e|E)[+|-]<[digits]>] + 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. If the substring is empty, no conversion is done, and + 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 @@ -52,7 +59,8 @@ DESCRIPTION This implementation returns the nearest machine number to the input decimal string. Ties are broken by using the IEEE - round-even rule. + round-even rule. However, <<strtof>> is currently subject to + double rounding errors. The alternate function <<_strtod_r>> is a reentrant version. The extra argument <[reent]> is a pointer to a reentrancy structure. @@ -176,7 +184,7 @@ _DEFUN (ULtod, (L, bits, exp, k), L[_0] |= 0x80000000L; } #endif /* !NO_HEX_FP */ - + #ifdef INFNAN_CHECK static int _DEFUN (match, (sp, t), @@ -254,6 +262,9 @@ _DEFUN (_strtod_r, (ptr, s00, se), switch(s[1]) { case 'x': case 'X': + /* If the number is not hex, then the parse of + 0 is still valid. */ + s00 = s + 1; { #if defined(FE_DOWNWARD) && defined(FE_TONEAREST) && defined(FE_TOWARDZERO) && defined(FE_UPWARD) FPI fpi1 = fpi; @@ -268,7 +279,6 @@ _DEFUN (_strtod_r, (ptr, s00, se), switch((i = gethex(ptr, &s, &fpi1, &exp, &bb, sign)) & STRTOG_Retmask) { case STRTOG_NoNumber: s = s00; - sign = 0; case STRTOG_Zero: break; default: |