summaryrefslogtreecommitdiff
path: root/stdlib/strtod_l.c
diff options
context:
space:
mode:
Diffstat (limited to 'stdlib/strtod_l.c')
-rw-r--r--stdlib/strtod_l.c79
1 files changed, 20 insertions, 59 deletions
diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c
index e13ab1e7e1..3d66eac706 100644
--- a/stdlib/strtod_l.c
+++ b/stdlib/strtod_l.c
@@ -1,5 +1,5 @@
/* Convert string representing a number to float value, using given locale.
- Copyright (C) 1997-2015 Free Software Foundation, Inc.
+ Copyright (C) 1997-2016 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -20,8 +20,6 @@
#include <xlocale.h>
extern double ____strtod_l_internal (const char *, char **, int, __locale_t);
-extern unsigned long long int ____strtoull_l_internal (const char *, char **,
- int, int, __locale_t);
/* Configuration part. These macros are defined by `strtold.c',
`strtof.c', `wcstod.c', `wcstold.c', and `wcstof.c' to produce the
@@ -33,30 +31,24 @@ extern unsigned long long int ____strtoull_l_internal (const char *, char **,
# ifdef USE_WIDE_CHAR
# define STRTOF wcstod_l
# define __STRTOF __wcstod_l
+# define STRTOF_NAN __wcstod_nan
# else
# define STRTOF strtod_l
# define __STRTOF __strtod_l
+# define STRTOF_NAN __strtod_nan
# endif
# define MPN2FLOAT __mpn_construct_double
# define FLOAT_HUGE_VAL HUGE_VAL
-# define SET_MANTISSA(flt, mant) \
- do { union ieee754_double u; \
- u.d = (flt); \
- u.ieee_nan.mantissa0 = (mant) >> 32; \
- u.ieee_nan.mantissa1 = (mant); \
- if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0) \
- (flt) = u.d; \
- } while (0)
#endif
/* End of configuration part. */
#include <ctype.h>
#include <errno.h>
#include <float.h>
-#include <ieee754.h>
#include "../locale/localeinfo.h"
#include <locale.h>
#include <math.h>
+#include <math_private.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
@@ -104,7 +96,6 @@ extern unsigned long long int ____strtoull_l_internal (const char *, char **,
# define TOLOWER_C(Ch) __towlower_l ((Ch), _nl_C_locobj_ptr)
# define STRNCASECMP(S1, S2, N) \
__wcsncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr)
-# define STRTOULL(S, E, B) ____wcstoull_l_internal ((S), (E), (B), 0, loc)
#else
# define STRING_TYPE char
# define CHAR_TYPE char
@@ -116,7 +107,6 @@ extern unsigned long long int ____strtoull_l_internal (const char *, char **,
# define TOLOWER_C(Ch) __tolower_l ((Ch), _nl_C_locobj_ptr)
# define STRNCASECMP(S1, S2, N) \
__strncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr)
-# define STRTOULL(S, E, B) ____strtoull_l_internal ((S), (E), (B), 0, loc)
#endif
@@ -181,10 +171,8 @@ static FLOAT
overflow_value (int negative)
{
__set_errno (ERANGE);
-#if FLT_EVAL_METHOD != 0
- volatile
-#endif
- FLOAT result = (negative ? -MAX_VALUE : MAX_VALUE) * MAX_VALUE;
+ FLOAT result = math_narrow_eval ((negative ? -MAX_VALUE : MAX_VALUE)
+ * MAX_VALUE);
return result;
}
@@ -195,10 +183,8 @@ static FLOAT
underflow_value (int negative)
{
__set_errno (ERANGE);
-#if FLT_EVAL_METHOD != 0
- volatile
-#endif
- FLOAT result = (negative ? -MIN_VALUE : MIN_VALUE) * MIN_VALUE;
+ FLOAT result = math_narrow_eval ((negative ? -MIN_VALUE : MIN_VALUE)
+ * MIN_VALUE);
return result;
}
@@ -300,8 +286,8 @@ round_and_return (mp_limb_t *retval, intmax_t exponent, int negative,
|| (round_limb & ((((mp_limb_t) 1) << round_bit) - 1)) != 0))
{
__set_errno (ERANGE);
- volatile FLOAT force_underflow_exception = MIN_VALUE * MIN_VALUE;
- (void) force_underflow_exception;
+ FLOAT force_underflow = MIN_VALUE * MIN_VALUE;
+ math_force_eval (force_underflow);
}
}
@@ -490,11 +476,8 @@ str_to_mpn (const STRING_TYPE *str, int digcnt, mp_limb_t *n, mp_size_t *nsize,
return 0.0. If the number is too big to be represented, set `errno' to
ERANGE and return HUGE_VAL with the appropriate sign. */
FLOAT
-____STRTOF_INTERNAL (nptr, endptr, group, loc)
- const STRING_TYPE *nptr;
- STRING_TYPE **endptr;
- int group;
- __locale_t loc;
+____STRTOF_INTERNAL (const STRING_TYPE *nptr, STRING_TYPE **endptr, int group,
+ __locale_t loc)
{
int negative; /* The sign of the number. */
MPN_VAR (num); /* MP representation of the number. */
@@ -655,33 +638,14 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc)
if (*cp == L_('('))
{
const STRING_TYPE *startp = cp;
- do
- ++cp;
- while ((*cp >= L_('0') && *cp <= L_('9'))
- || ({ CHAR_TYPE lo = TOLOWER (*cp);
- lo >= L_('a') && lo <= L_('z'); })
- || *cp == L_('_'));
-
- if (*cp != L_(')'))
- /* The closing brace is missing. Only match the NAN
- part. */
- cp = startp;
+ STRING_TYPE *endp;
+ retval = STRTOF_NAN (cp + 1, &endp, L_(')'));
+ if (*endp == L_(')'))
+ /* Consume the closing parenthesis. */
+ cp = endp + 1;
else
- {
- /* This is a system-dependent way to specify the
- bitmask used for the NaN. We expect it to be
- a number which is put in the mantissa of the
- number. */
- STRING_TYPE *endp;
- unsigned long long int mant;
-
- mant = STRTOULL (startp + 1, &endp, 0);
- if (endp == cp)
- SET_MANTISSA (retval, mant);
-
- /* Consume the closing brace. */
- ++cp;
- }
+ /* Only match the NAN part. */
+ cp = startp;
}
if (endptr != NULL)
@@ -1787,10 +1751,7 @@ FLOAT
#ifdef weak_function
weak_function
#endif
-__STRTOF (nptr, endptr, loc)
- const STRING_TYPE *nptr;
- STRING_TYPE **endptr;
- __locale_t loc;
+__STRTOF (const STRING_TYPE *nptr, STRING_TYPE **endptr, __locale_t loc)
{
return ____STRTOF_INTERNAL (nptr, endptr, 0, loc);
}