Blame stdlib/strtod_l.c

Packit 6c4009
/* Convert string representing a number to float value, using given locale.
Packit 6c4009
   Copyright (C) 1997-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#include <bits/floatn.h>
Packit 6c4009
Packit 6c4009
#ifdef FLOAT
Packit 6c4009
# define BUILD_DOUBLE 0
Packit 6c4009
#else
Packit 6c4009
# define BUILD_DOUBLE 1
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#if BUILD_DOUBLE
Packit 6c4009
# if __HAVE_FLOAT64 && !__HAVE_DISTINCT_FLOAT64
Packit 6c4009
#  define strtof64_l __hide_strtof64_l
Packit 6c4009
#  define wcstof64_l __hide_wcstof64_l
Packit 6c4009
# endif
Packit 6c4009
# if __HAVE_FLOAT32X && !__HAVE_DISTINCT_FLOAT32X
Packit 6c4009
#  define strtof32x_l __hide_strtof32x_l
Packit 6c4009
#  define wcstof32x_l __hide_wcstof32x_l
Packit 6c4009
# endif
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#include <locale.h>
Packit 6c4009
Packit 6c4009
extern double ____strtod_l_internal (const char *, char **, int, locale_t);
Packit 6c4009
Packit 6c4009
/* Configuration part.  These macros are defined by `strtold.c',
Packit 6c4009
   `strtof.c', `wcstod.c', `wcstold.c', and `wcstof.c' to produce the
Packit 6c4009
   `long double' and `float' versions of the reader.  */
Packit 6c4009
#ifndef FLOAT
Packit 6c4009
# include <math_ldbl_opt.h>
Packit 6c4009
# define FLOAT		double
Packit 6c4009
# define FLT		DBL
Packit 6c4009
# ifdef USE_WIDE_CHAR
Packit 6c4009
#  define STRTOF	wcstod_l
Packit 6c4009
#  define __STRTOF	__wcstod_l
Packit 6c4009
#  define STRTOF_NAN	__wcstod_nan
Packit 6c4009
# else
Packit 6c4009
#  define STRTOF	strtod_l
Packit 6c4009
#  define __STRTOF	__strtod_l
Packit 6c4009
#  define STRTOF_NAN	__strtod_nan
Packit 6c4009
# endif
Packit 6c4009
# define MPN2FLOAT	__mpn_construct_double
Packit 6c4009
# define FLOAT_HUGE_VAL	HUGE_VAL
Packit 6c4009
#endif
Packit 6c4009
/* End of configuration part.  */
Packit 6c4009

Packit 6c4009
#include <ctype.h>
Packit 6c4009
#include <errno.h>
Packit 6c4009
#include <float.h>
Packit 6c4009
#include "../locale/localeinfo.h"
Packit 6c4009
#include <math.h>
Packit 6c4009
#include <math-barriers.h>
Packit 6c4009
#include <math-narrow-eval.h>
Packit 6c4009
#include <stdlib.h>
Packit 6c4009
#include <string.h>
Packit 6c4009
#include <stdint.h>
Packit 6c4009
#include <rounding-mode.h>
Packit 6c4009
#include <tininess.h>
Packit 6c4009
Packit 6c4009
/* The gmp headers need some configuration frobs.  */
Packit 6c4009
#define HAVE_ALLOCA 1
Packit 6c4009
Packit 6c4009
/* Include gmp-mparam.h first, such that definitions of _SHORT_LIMB
Packit 6c4009
   and _LONG_LONG_LIMB in it can take effect into gmp.h.  */
Packit 6c4009
#include <gmp-mparam.h>
Packit 6c4009
#include <gmp.h>
Packit 6c4009
#include "gmp-impl.h"
Packit 6c4009
#include "longlong.h"
Packit 6c4009
#include "fpioconst.h"
Packit 6c4009
Packit 6c4009
#include <assert.h>
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* We use this code for the extended locale handling where the
Packit 6c4009
   function gets as an additional argument the locale which has to be
Packit 6c4009
   used.  To access the values we have to redefine the _NL_CURRENT and
Packit 6c4009
   _NL_CURRENT_WORD macros.  */
Packit 6c4009
#undef _NL_CURRENT
Packit 6c4009
#define _NL_CURRENT(category, item) \
Packit 6c4009
  (current->values[_NL_ITEM_INDEX (item)].string)
Packit 6c4009
#undef _NL_CURRENT_WORD
Packit 6c4009
#define _NL_CURRENT_WORD(category, item) \
Packit 6c4009
  ((uint32_t) current->values[_NL_ITEM_INDEX (item)].word)
Packit 6c4009
Packit 6c4009
#if defined _LIBC || defined HAVE_WCHAR_H
Packit 6c4009
# include <wchar.h>
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#ifdef USE_WIDE_CHAR
Packit 6c4009
# include <wctype.h>
Packit 6c4009
# define STRING_TYPE wchar_t
Packit 6c4009
# define CHAR_TYPE wint_t
Packit 6c4009
# define L_(Ch) L##Ch
Packit 6c4009
# define ISSPACE(Ch) __iswspace_l ((Ch), loc)
Packit 6c4009
# define ISDIGIT(Ch) __iswdigit_l ((Ch), loc)
Packit 6c4009
# define ISXDIGIT(Ch) __iswxdigit_l ((Ch), loc)
Packit 6c4009
# define TOLOWER(Ch) __towlower_l ((Ch), loc)
Packit 6c4009
# define TOLOWER_C(Ch) __towlower_l ((Ch), _nl_C_locobj_ptr)
Packit 6c4009
# define STRNCASECMP(S1, S2, N) \
Packit 6c4009
  __wcsncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr)
Packit 6c4009
#else
Packit 6c4009
# define STRING_TYPE char
Packit 6c4009
# define CHAR_TYPE char
Packit 6c4009
# define L_(Ch) Ch
Packit 6c4009
# define ISSPACE(Ch) __isspace_l ((Ch), loc)
Packit 6c4009
# define ISDIGIT(Ch) __isdigit_l ((Ch), loc)
Packit 6c4009
# define ISXDIGIT(Ch) __isxdigit_l ((Ch), loc)
Packit 6c4009
# define TOLOWER(Ch) __tolower_l ((Ch), loc)
Packit 6c4009
# define TOLOWER_C(Ch) __tolower_l ((Ch), _nl_C_locobj_ptr)
Packit 6c4009
# define STRNCASECMP(S1, S2, N) \
Packit 6c4009
  __strncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr)
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Constants we need from float.h; select the set for the FLOAT precision.  */
Packit 6c4009
#define MANT_DIG	PASTE(FLT,_MANT_DIG)
Packit 6c4009
#define	DIG		PASTE(FLT,_DIG)
Packit 6c4009
#define	MAX_EXP		PASTE(FLT,_MAX_EXP)
Packit 6c4009
#define	MIN_EXP		PASTE(FLT,_MIN_EXP)
Packit 6c4009
#define MAX_10_EXP	PASTE(FLT,_MAX_10_EXP)
Packit 6c4009
#define MIN_10_EXP	PASTE(FLT,_MIN_10_EXP)
Packit 6c4009
#define MAX_VALUE	PASTE(FLT,_MAX)
Packit 6c4009
#define MIN_VALUE	PASTE(FLT,_MIN)
Packit 6c4009
Packit 6c4009
/* Extra macros required to get FLT expanded before the pasting.  */
Packit 6c4009
#define PASTE(a,b)	PASTE1(a,b)
Packit 6c4009
#define PASTE1(a,b)	a##b
Packit 6c4009
Packit 6c4009
/* Function to construct a floating point number from an MP integer
Packit 6c4009
   containing the fraction bits, a base 2 exponent, and a sign flag.  */
Packit 6c4009
extern FLOAT MPN2FLOAT (mp_srcptr mpn, int exponent, int negative);
Packit 6c4009

Packit 6c4009
/* Definitions according to limb size used.  */
Packit 6c4009
#if	BITS_PER_MP_LIMB == 32
Packit 6c4009
# define MAX_DIG_PER_LIMB	9
Packit 6c4009
# define MAX_FAC_PER_LIMB	1000000000UL
Packit 6c4009
#elif	BITS_PER_MP_LIMB == 64
Packit 6c4009
# define MAX_DIG_PER_LIMB	19
Packit 6c4009
# define MAX_FAC_PER_LIMB	10000000000000000000ULL
Packit 6c4009
#else
Packit 6c4009
# error "mp_limb_t size " BITS_PER_MP_LIMB "not accounted for"
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
extern const mp_limb_t _tens_in_limb[MAX_DIG_PER_LIMB + 1];
Packit 6c4009

Packit 6c4009
#ifndef	howmany
Packit 6c4009
#define	howmany(x,y)		(((x)+((y)-1))/(y))
Packit 6c4009
#endif
Packit 6c4009
#define SWAP(x, y)		({ typeof(x) _tmp = x; x = y; y = _tmp; })
Packit 6c4009
Packit 6c4009
#define	RETURN_LIMB_SIZE		howmany (MANT_DIG, BITS_PER_MP_LIMB)
Packit 6c4009
Packit 6c4009
#define RETURN(val,end)							      \
Packit 6c4009
    do { if (endptr != NULL) *endptr = (STRING_TYPE *) (end);		      \
Packit 6c4009
	 return val; } while (0)
Packit 6c4009
Packit 6c4009
/* Maximum size necessary for mpn integers to hold floating point
Packit 6c4009
   numbers.  The largest number we need to hold is 10^n where 2^-n is
Packit 6c4009
   1/4 ulp of the smallest representable value (that is, n = MANT_DIG
Packit 6c4009
   - MIN_EXP + 2).  Approximate using 10^3 < 2^10.  */
Packit 6c4009
#define	MPNSIZE		(howmany (1 + ((MANT_DIG - MIN_EXP + 2) * 10) / 3, \
Packit 6c4009
				  BITS_PER_MP_LIMB) + 2)
Packit 6c4009
/* Declare an mpn integer variable that big.  */
Packit 6c4009
#define	MPN_VAR(name)	mp_limb_t name[MPNSIZE]; mp_size_t name##size
Packit 6c4009
/* Copy an mpn integer value.  */
Packit 6c4009
#define MPN_ASSIGN(dst, src) \
Packit 6c4009
	memcpy (dst, src, (dst##size = src##size) * sizeof (mp_limb_t))
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Set errno and return an overflowing value with sign specified by
Packit 6c4009
   NEGATIVE.  */
Packit 6c4009
static FLOAT
Packit 6c4009
overflow_value (int negative)
Packit 6c4009
{
Packit 6c4009
  __set_errno (ERANGE);
Packit 6c4009
  FLOAT result = math_narrow_eval ((negative ? -MAX_VALUE : MAX_VALUE)
Packit 6c4009
				   * MAX_VALUE);
Packit 6c4009
  return result;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Set errno and return an underflowing value with sign specified by
Packit 6c4009
   NEGATIVE.  */
Packit 6c4009
static FLOAT
Packit 6c4009
underflow_value (int negative)
Packit 6c4009
{
Packit 6c4009
  __set_errno (ERANGE);
Packit 6c4009
  FLOAT result = math_narrow_eval ((negative ? -MIN_VALUE : MIN_VALUE)
Packit 6c4009
				   * MIN_VALUE);
Packit 6c4009
  return result;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Return a floating point number of the needed type according to the given
Packit 6c4009
   multi-precision number after possible rounding.  */
Packit 6c4009
static FLOAT
Packit 6c4009
round_and_return (mp_limb_t *retval, intmax_t exponent, int negative,
Packit 6c4009
		  mp_limb_t round_limb, mp_size_t round_bit, int more_bits)
Packit 6c4009
{
Packit 6c4009
  int mode = get_rounding_mode ();
Packit 6c4009
Packit 6c4009
  if (exponent < MIN_EXP - 1)
Packit 6c4009
    {
Packit 6c4009
      if (exponent < MIN_EXP - 1 - MANT_DIG)
Packit 6c4009
	return underflow_value (negative);
Packit 6c4009
Packit 6c4009
      mp_size_t shift = MIN_EXP - 1 - exponent;
Packit 6c4009
      bool is_tiny = true;
Packit 6c4009
Packit 6c4009
      more_bits |= (round_limb & ((((mp_limb_t) 1) << round_bit) - 1)) != 0;
Packit 6c4009
      if (shift == MANT_DIG)
Packit 6c4009
	/* This is a special case to handle the very seldom case where
Packit 6c4009
	   the mantissa will be empty after the shift.  */
Packit 6c4009
	{
Packit 6c4009
	  int i;
Packit 6c4009
Packit 6c4009
	  round_limb = retval[RETURN_LIMB_SIZE - 1];
Packit 6c4009
	  round_bit = (MANT_DIG - 1) % BITS_PER_MP_LIMB;
Packit 6c4009
	  for (i = 0; i < RETURN_LIMB_SIZE - 1; ++i)
Packit 6c4009
	    more_bits |= retval[i] != 0;
Packit 6c4009
	  MPN_ZERO (retval, RETURN_LIMB_SIZE);
Packit 6c4009
	}
Packit 6c4009
      else if (shift >= BITS_PER_MP_LIMB)
Packit 6c4009
	{
Packit 6c4009
	  int i;
Packit 6c4009
Packit 6c4009
	  round_limb = retval[(shift - 1) / BITS_PER_MP_LIMB];
Packit 6c4009
	  round_bit = (shift - 1) % BITS_PER_MP_LIMB;
Packit 6c4009
	  for (i = 0; i < (shift - 1) / BITS_PER_MP_LIMB; ++i)
Packit 6c4009
	    more_bits |= retval[i] != 0;
Packit 6c4009
	  more_bits |= ((round_limb & ((((mp_limb_t) 1) << round_bit) - 1))
Packit 6c4009
			!= 0);
Packit 6c4009
Packit 6c4009
	  /* __mpn_rshift requires 0 < shift < BITS_PER_MP_LIMB.  */
Packit 6c4009
	  if ((shift % BITS_PER_MP_LIMB) != 0)
Packit 6c4009
	    (void) __mpn_rshift (retval, &retval[shift / BITS_PER_MP_LIMB],
Packit 6c4009
			         RETURN_LIMB_SIZE - (shift / BITS_PER_MP_LIMB),
Packit 6c4009
			         shift % BITS_PER_MP_LIMB);
Packit 6c4009
	  else
Packit 6c4009
	    for (i = 0; i < RETURN_LIMB_SIZE - (shift / BITS_PER_MP_LIMB); i++)
Packit 6c4009
	      retval[i] = retval[i + (shift / BITS_PER_MP_LIMB)];
Packit 6c4009
	  MPN_ZERO (&retval[RETURN_LIMB_SIZE - (shift / BITS_PER_MP_LIMB)],
Packit 6c4009
		    shift / BITS_PER_MP_LIMB);
Packit 6c4009
	}
Packit 6c4009
      else if (shift > 0)
Packit 6c4009
	{
Packit 6c4009
	  if (TININESS_AFTER_ROUNDING && shift == 1)
Packit 6c4009
	    {
Packit 6c4009
	      /* Whether the result counts as tiny depends on whether,
Packit 6c4009
		 after rounding to the normal precision, it still has
Packit 6c4009
		 a subnormal exponent.  */
Packit 6c4009
	      mp_limb_t retval_normal[RETURN_LIMB_SIZE];
Packit 6c4009
	      if (round_away (negative,
Packit 6c4009
			      (retval[0] & 1) != 0,
Packit 6c4009
			      (round_limb
Packit 6c4009
			       & (((mp_limb_t) 1) << round_bit)) != 0,
Packit 6c4009
			      (more_bits
Packit 6c4009
			       || ((round_limb
Packit 6c4009
				    & ((((mp_limb_t) 1) << round_bit) - 1))
Packit 6c4009
				   != 0)),
Packit 6c4009
			      mode))
Packit 6c4009
		{
Packit 6c4009
		  mp_limb_t cy = __mpn_add_1 (retval_normal, retval,
Packit 6c4009
					      RETURN_LIMB_SIZE, 1);
Packit 6c4009
Packit 6c4009
		  if (((MANT_DIG % BITS_PER_MP_LIMB) == 0 && cy) ||
Packit 6c4009
		      ((MANT_DIG % BITS_PER_MP_LIMB) != 0 &&
Packit 6c4009
		       ((retval_normal[RETURN_LIMB_SIZE - 1]
Packit 6c4009
			& (((mp_limb_t) 1) << (MANT_DIG % BITS_PER_MP_LIMB)))
Packit 6c4009
			!= 0)))
Packit 6c4009
		    is_tiny = false;
Packit 6c4009
		}
Packit 6c4009
	    }
Packit 6c4009
	  round_limb = retval[0];
Packit 6c4009
	  round_bit = shift - 1;
Packit 6c4009
	  (void) __mpn_rshift (retval, retval, RETURN_LIMB_SIZE, shift);
Packit 6c4009
	}
Packit 6c4009
      /* This is a hook for the m68k long double format, where the
Packit 6c4009
	 exponent bias is the same for normalized and denormalized
Packit 6c4009
	 numbers.  */
Packit 6c4009
#ifndef DENORM_EXP
Packit 6c4009
# define DENORM_EXP (MIN_EXP - 2)
Packit 6c4009
#endif
Packit 6c4009
      exponent = DENORM_EXP;
Packit 6c4009
      if (is_tiny
Packit 6c4009
	  && ((round_limb & (((mp_limb_t) 1) << round_bit)) != 0
Packit 6c4009
	      || more_bits
Packit 6c4009
	      || (round_limb & ((((mp_limb_t) 1) << round_bit) - 1)) != 0))
Packit 6c4009
	{
Packit 6c4009
	  __set_errno (ERANGE);
Packit 6c4009
	  FLOAT force_underflow = MIN_VALUE * MIN_VALUE;
Packit 6c4009
	  math_force_eval (force_underflow);
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  if (exponent >= MAX_EXP)
Packit 6c4009
    goto overflow;
Packit 6c4009
Packit 6c4009
  bool half_bit = (round_limb & (((mp_limb_t) 1) << round_bit)) != 0;
Packit 6c4009
  bool more_bits_nonzero
Packit 6c4009
    = (more_bits
Packit 6c4009
       || (round_limb & ((((mp_limb_t) 1) << round_bit) - 1)) != 0);
Packit 6c4009
  if (round_away (negative,
Packit 6c4009
		  (retval[0] & 1) != 0,
Packit 6c4009
		  half_bit,
Packit 6c4009
		  more_bits_nonzero,
Packit 6c4009
		  mode))
Packit 6c4009
    {
Packit 6c4009
      mp_limb_t cy = __mpn_add_1 (retval, retval, RETURN_LIMB_SIZE, 1);
Packit 6c4009
Packit 6c4009
      if (((MANT_DIG % BITS_PER_MP_LIMB) == 0 && cy) ||
Packit 6c4009
	  ((MANT_DIG % BITS_PER_MP_LIMB) != 0 &&
Packit 6c4009
	   (retval[RETURN_LIMB_SIZE - 1]
Packit 6c4009
	    & (((mp_limb_t) 1) << (MANT_DIG % BITS_PER_MP_LIMB))) != 0))
Packit 6c4009
	{
Packit 6c4009
	  ++exponent;
Packit 6c4009
	  (void) __mpn_rshift (retval, retval, RETURN_LIMB_SIZE, 1);
Packit 6c4009
	  retval[RETURN_LIMB_SIZE - 1]
Packit 6c4009
	    |= ((mp_limb_t) 1) << ((MANT_DIG - 1) % BITS_PER_MP_LIMB);
Packit 6c4009
	}
Packit 6c4009
      else if (exponent == DENORM_EXP
Packit 6c4009
	       && (retval[RETURN_LIMB_SIZE - 1]
Packit 6c4009
		   & (((mp_limb_t) 1) << ((MANT_DIG - 1) % BITS_PER_MP_LIMB)))
Packit 6c4009
	       != 0)
Packit 6c4009
	  /* The number was denormalized but now normalized.  */
Packit 6c4009
	exponent = MIN_EXP - 1;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  if (exponent >= MAX_EXP)
Packit 6c4009
  overflow:
Packit 6c4009
    return overflow_value (negative);
Packit 6c4009
Packit 6c4009
  if (half_bit || more_bits_nonzero)
Packit 6c4009
    {
Packit 6c4009
      FLOAT force_inexact = (FLOAT) 1 + MIN_VALUE;
Packit 6c4009
      math_force_eval (force_inexact);
Packit 6c4009
    }
Packit 6c4009
  return MPN2FLOAT (retval, exponent, negative);
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Read a multi-precision integer starting at STR with exactly DIGCNT digits
Packit 6c4009
   into N.  Return the size of the number limbs in NSIZE at the first
Packit 6c4009
   character od the string that is not part of the integer as the function
Packit 6c4009
   value.  If the EXPONENT is small enough to be taken as an additional
Packit 6c4009
   factor for the resulting number (see code) multiply by it.  */
Packit 6c4009
static const STRING_TYPE *
Packit 6c4009
str_to_mpn (const STRING_TYPE *str, int digcnt, mp_limb_t *n, mp_size_t *nsize,
Packit 6c4009
	    intmax_t *exponent
Packit 6c4009
#ifndef USE_WIDE_CHAR
Packit 6c4009
	    , const char *decimal, size_t decimal_len, const char *thousands
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
	    )
Packit 6c4009
{
Packit 6c4009
  /* Number of digits for actual limb.  */
Packit 6c4009
  int cnt = 0;
Packit 6c4009
  mp_limb_t low = 0;
Packit 6c4009
  mp_limb_t start;
Packit 6c4009
Packit 6c4009
  *nsize = 0;
Packit 6c4009
  assert (digcnt > 0);
Packit 6c4009
  do
Packit 6c4009
    {
Packit 6c4009
      if (cnt == MAX_DIG_PER_LIMB)
Packit 6c4009
	{
Packit 6c4009
	  if (*nsize == 0)
Packit 6c4009
	    {
Packit 6c4009
	      n[0] = low;
Packit 6c4009
	      *nsize = 1;
Packit 6c4009
	    }
Packit 6c4009
	  else
Packit 6c4009
	    {
Packit 6c4009
	      mp_limb_t cy;
Packit 6c4009
	      cy = __mpn_mul_1 (n, n, *nsize, MAX_FAC_PER_LIMB);
Packit 6c4009
	      cy += __mpn_add_1 (n, n, *nsize, low);
Packit 6c4009
	      if (cy != 0)
Packit 6c4009
		{
Packit 6c4009
		  assert (*nsize < MPNSIZE);
Packit 6c4009
		  n[*nsize] = cy;
Packit 6c4009
		  ++(*nsize);
Packit 6c4009
		}
Packit 6c4009
	    }
Packit 6c4009
	  cnt = 0;
Packit 6c4009
	  low = 0;
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
      /* There might be thousands separators or radix characters in
Packit 6c4009
	 the string.  But these all can be ignored because we know the
Packit 6c4009
	 format of the number is correct and we have an exact number
Packit 6c4009
	 of characters to read.  */
Packit 6c4009
#ifdef USE_WIDE_CHAR
Packit 6c4009
      if (*str < L'0' || *str > L'9')
Packit 6c4009
	++str;
Packit 6c4009
#else
Packit 6c4009
      if (*str < '0' || *str > '9')
Packit 6c4009
	{
Packit 6c4009
	  int inner = 0;
Packit 6c4009
	  if (thousands != NULL && *str == *thousands
Packit 6c4009
	      && ({ for (inner = 1; thousands[inner] != '\0'; ++inner)
Packit 6c4009
		      if (thousands[inner] != str[inner])
Packit 6c4009
			break;
Packit 6c4009
		    thousands[inner] == '\0'; }))
Packit 6c4009
	    str += inner;
Packit 6c4009
	  else
Packit 6c4009
	    str += decimal_len;
Packit 6c4009
	}
Packit 6c4009
#endif
Packit 6c4009
      low = low * 10 + *str++ - L_('0');
Packit 6c4009
      ++cnt;
Packit 6c4009
    }
Packit 6c4009
  while (--digcnt > 0);
Packit 6c4009
Packit 6c4009
  if (*exponent > 0 && *exponent <= MAX_DIG_PER_LIMB - cnt)
Packit 6c4009
    {
Packit 6c4009
      low *= _tens_in_limb[*exponent];
Packit 6c4009
      start = _tens_in_limb[cnt + *exponent];
Packit 6c4009
      *exponent = 0;
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    start = _tens_in_limb[cnt];
Packit 6c4009
Packit 6c4009
  if (*nsize == 0)
Packit 6c4009
    {
Packit 6c4009
      n[0] = low;
Packit 6c4009
      *nsize = 1;
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      mp_limb_t cy;
Packit 6c4009
      cy = __mpn_mul_1 (n, n, *nsize, start);
Packit 6c4009
      cy += __mpn_add_1 (n, n, *nsize, low);
Packit 6c4009
      if (cy != 0)
Packit 6c4009
	{
Packit 6c4009
	  assert (*nsize < MPNSIZE);
Packit 6c4009
	  n[(*nsize)++] = cy;
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  return str;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Shift {PTR, SIZE} COUNT bits to the left, and fill the vacated bits
Packit 6c4009
   with the COUNT most significant bits of LIMB.
Packit 6c4009
Packit 6c4009
   Implemented as a macro, so that __builtin_constant_p works even at -O0.
Packit 6c4009
Packit 6c4009
   Tege doesn't like this macro so I have to write it here myself. :)
Packit 6c4009
   --drepper */
Packit 6c4009
#define __mpn_lshift_1(ptr, size, count, limb) \
Packit 6c4009
  do									\
Packit 6c4009
    {									\
Packit 6c4009
      mp_limb_t *__ptr = (ptr);						\
Packit 6c4009
      if (__builtin_constant_p (count) && count == BITS_PER_MP_LIMB)	\
Packit 6c4009
	{								\
Packit 6c4009
	  mp_size_t i;							\
Packit 6c4009
	  for (i = (size) - 1; i > 0; --i)				\
Packit 6c4009
	    __ptr[i] = __ptr[i - 1];					\
Packit 6c4009
	  __ptr[0] = (limb);						\
Packit 6c4009
	}								\
Packit 6c4009
      else								\
Packit 6c4009
	{								\
Packit 6c4009
	  /* We assume count > 0 && count < BITS_PER_MP_LIMB here.  */	\
Packit 6c4009
	  unsigned int __count = (count);				\
Packit 6c4009
	  (void) __mpn_lshift (__ptr, __ptr, size, __count);		\
Packit 6c4009
	  __ptr[0] |= (limb) >> (BITS_PER_MP_LIMB - __count);		\
Packit 6c4009
	}								\
Packit 6c4009
    }									\
Packit 6c4009
  while (0)
Packit 6c4009
Packit 6c4009
Packit 6c4009
#define INTERNAL(x) INTERNAL1(x)
Packit 6c4009
#define INTERNAL1(x) __##x##_internal
Packit 6c4009
#ifndef ____STRTOF_INTERNAL
Packit 6c4009
# define ____STRTOF_INTERNAL INTERNAL (__STRTOF)
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* This file defines a function to check for correct grouping.  */
Packit 6c4009
#include "grouping.h"
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Return a floating point number with the value of the given string NPTR.
Packit 6c4009
   Set *ENDPTR to the character after the last used one.  If the number is
Packit 6c4009
   smaller than the smallest representable number, set `errno' to ERANGE and
Packit 6c4009
   return 0.0.  If the number is too big to be represented, set `errno' to
Packit 6c4009
   ERANGE and return HUGE_VAL with the appropriate sign.  */
Packit 6c4009
FLOAT
Packit 6c4009
____STRTOF_INTERNAL (const STRING_TYPE *nptr, STRING_TYPE **endptr, int group,
Packit 6c4009
		     locale_t loc)
Packit 6c4009
{
Packit 6c4009
  int negative;			/* The sign of the number.  */
Packit 6c4009
  MPN_VAR (num);		/* MP representation of the number.  */
Packit 6c4009
  intmax_t exponent;		/* Exponent of the number.  */
Packit 6c4009
Packit 6c4009
  /* Numbers starting `0X' or `0x' have to be processed with base 16.  */
Packit 6c4009
  int base = 10;
Packit 6c4009
Packit 6c4009
  /* When we have to compute fractional digits we form a fraction with a
Packit 6c4009
     second multi-precision number (and we sometimes need a second for
Packit 6c4009
     temporary results).  */
Packit 6c4009
  MPN_VAR (den);
Packit 6c4009
Packit 6c4009
  /* Representation for the return value.  */
Packit 6c4009
  mp_limb_t retval[RETURN_LIMB_SIZE];
Packit 6c4009
  /* Number of bits currently in result value.  */
Packit 6c4009
  int bits;
Packit 6c4009
Packit 6c4009
  /* Running pointer after the last character processed in the string.  */
Packit 6c4009
  const STRING_TYPE *cp, *tp;
Packit 6c4009
  /* Start of significant part of the number.  */
Packit 6c4009
  const STRING_TYPE *startp, *start_of_digits;
Packit 6c4009
  /* Points at the character following the integer and fractional digits.  */
Packit 6c4009
  const STRING_TYPE *expp;
Packit 6c4009
  /* Total number of digit and number of digits in integer part.  */
Packit 6c4009
  size_t dig_no, int_no, lead_zero;
Packit 6c4009
  /* Contains the last character read.  */
Packit 6c4009
  CHAR_TYPE c;
Packit 6c4009
Packit 6c4009
/* We should get wint_t from <stddef.h>, but not all GCC versions define it
Packit 6c4009
   there.  So define it ourselves if it remains undefined.  */
Packit 6c4009
#ifndef _WINT_T
Packit 6c4009
  typedef unsigned int wint_t;
Packit 6c4009
#endif
Packit 6c4009
  /* The radix character of the current locale.  */
Packit 6c4009
#ifdef USE_WIDE_CHAR
Packit 6c4009
  wchar_t decimal;
Packit 6c4009
#else
Packit 6c4009
  const char *decimal;
Packit 6c4009
  size_t decimal_len;
Packit 6c4009
#endif
Packit 6c4009
  /* The thousands character of the current locale.  */
Packit 6c4009
#ifdef USE_WIDE_CHAR
Packit 6c4009
  wchar_t thousands = L'\0';
Packit 6c4009
#else
Packit 6c4009
  const char *thousands = NULL;
Packit 6c4009
#endif
Packit 6c4009
  /* The numeric grouping specification of the current locale,
Packit 6c4009
     in the format described in <locale.h>.  */
Packit 6c4009
  const char *grouping;
Packit 6c4009
  /* Used in several places.  */
Packit 6c4009
  int cnt;
Packit 6c4009
Packit 6c4009
  struct __locale_data *current = loc->__locales[LC_NUMERIC];
Packit 6c4009
Packit 6c4009
  if (__glibc_unlikely (group))
Packit 6c4009
    {
Packit 6c4009
      grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
Packit 6c4009
      if (*grouping <= 0 || *grouping == CHAR_MAX)
Packit 6c4009
	grouping = NULL;
Packit 6c4009
      else
Packit 6c4009
	{
Packit 6c4009
	  /* Figure out the thousands separator character.  */
Packit 6c4009
#ifdef USE_WIDE_CHAR
Packit 6c4009
	  thousands = _NL_CURRENT_WORD (LC_NUMERIC,
Packit 6c4009
					_NL_NUMERIC_THOUSANDS_SEP_WC);
Packit 6c4009
	  if (thousands == L'\0')
Packit 6c4009
	    grouping = NULL;
Packit 6c4009
#else
Packit 6c4009
	  thousands = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
Packit 6c4009
	  if (*thousands == '\0')
Packit 6c4009
	    {
Packit 6c4009
	      thousands = NULL;
Packit 6c4009
	      grouping = NULL;
Packit 6c4009
	    }
Packit 6c4009
#endif
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    grouping = NULL;
Packit 6c4009
Packit 6c4009
  /* Find the locale's decimal point character.  */
Packit 6c4009
#ifdef USE_WIDE_CHAR
Packit 6c4009
  decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
Packit 6c4009
  assert (decimal != L'\0');
Packit 6c4009
# define decimal_len 1
Packit 6c4009
#else
Packit 6c4009
  decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
Packit 6c4009
  decimal_len = strlen (decimal);
Packit 6c4009
  assert (decimal_len > 0);
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
  /* Prepare number representation.  */
Packit 6c4009
  exponent = 0;
Packit 6c4009
  negative = 0;
Packit 6c4009
  bits = 0;
Packit 6c4009
Packit 6c4009
  /* Parse string to get maximal legal prefix.  We need the number of
Packit 6c4009
     characters of the integer part, the fractional part and the exponent.  */
Packit 6c4009
  cp = nptr - 1;
Packit 6c4009
  /* Ignore leading white space.  */
Packit 6c4009
  do
Packit 6c4009
    c = *++cp;
Packit 6c4009
  while (ISSPACE (c));
Packit 6c4009
Packit 6c4009
  /* Get sign of the result.  */
Packit 6c4009
  if (c == L_('-'))
Packit 6c4009
    {
Packit 6c4009
      negative = 1;
Packit 6c4009
      c = *++cp;
Packit 6c4009
    }
Packit 6c4009
  else if (c == L_('+'))
Packit 6c4009
    c = *++cp;
Packit 6c4009
Packit 6c4009
  /* Return 0.0 if no legal string is found.
Packit 6c4009
     No character is used even if a sign was found.  */
Packit 6c4009
#ifdef USE_WIDE_CHAR
Packit 6c4009
  if (c == (wint_t) decimal
Packit 6c4009
      && (wint_t) cp[1] >= L'0' && (wint_t) cp[1] <= L'9')
Packit 6c4009
    {
Packit 6c4009
      /* We accept it.  This funny construct is here only to indent
Packit 6c4009
	 the code correctly.  */
Packit 6c4009
    }
Packit 6c4009
#else
Packit 6c4009
  for (cnt = 0; decimal[cnt] != '\0'; ++cnt)
Packit 6c4009
    if (cp[cnt] != decimal[cnt])
Packit 6c4009
      break;
Packit 6c4009
  if (decimal[cnt] == '\0' && cp[cnt] >= '0' && cp[cnt] <= '9')
Packit 6c4009
    {
Packit 6c4009
      /* We accept it.  This funny construct is here only to indent
Packit 6c4009
	 the code correctly.  */
Packit 6c4009
    }
Packit 6c4009
#endif
Packit 6c4009
  else if (c < L_('0') || c > L_('9'))
Packit 6c4009
    {
Packit 6c4009
      /* Check for `INF' or `INFINITY'.  */
Packit 6c4009
      CHAR_TYPE lowc = TOLOWER_C (c);
Packit 6c4009
Packit 6c4009
      if (lowc == L_('i') && STRNCASECMP (cp, L_("inf"), 3) == 0)
Packit 6c4009
	{
Packit 6c4009
	  /* Return +/- infinity.  */
Packit 6c4009
	  if (endptr != NULL)
Packit 6c4009
	    *endptr = (STRING_TYPE *)
Packit 6c4009
		      (cp + (STRNCASECMP (cp + 3, L_("inity"), 5) == 0
Packit 6c4009
			     ? 8 : 3));
Packit 6c4009
Packit 6c4009
	  return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL;
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
      if (lowc == L_('n') && STRNCASECMP (cp, L_("nan"), 3) == 0)
Packit 6c4009
	{
Packit 6c4009
	  /* Return NaN.  */
Packit 6c4009
	  FLOAT retval = NAN;
Packit 6c4009
Packit 6c4009
	  cp += 3;
Packit 6c4009
Packit 6c4009
	  /* Match `(n-char-sequence-digit)'.  */
Packit 6c4009
	  if (*cp == L_('('))
Packit 6c4009
	    {
Packit 6c4009
	      const STRING_TYPE *startp = cp;
Packit 6c4009
	      STRING_TYPE *endp;
Packit 6c4009
	      retval = STRTOF_NAN (cp + 1, &endp, L_(')'));
Packit 6c4009
	      if (*endp == L_(')'))
Packit 6c4009
		/* Consume the closing parenthesis.  */
Packit 6c4009
		cp = endp + 1;
Packit 6c4009
	      else
Packit 6c4009
		/* Only match the NAN part.  */
Packit 6c4009
		cp = startp;
Packit 6c4009
	    }
Packit 6c4009
Packit 6c4009
	  if (endptr != NULL)
Packit 6c4009
	    *endptr = (STRING_TYPE *) cp;
Packit 6c4009
Packit 6c4009
	  return negative ? -retval : retval;
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
      /* It is really a text we do not recognize.  */
Packit 6c4009
      RETURN (0.0, nptr);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* First look whether we are faced with a hexadecimal number.  */
Packit 6c4009
  if (c == L_('0') && TOLOWER (cp[1]) == L_('x'))
Packit 6c4009
    {
Packit 6c4009
      /* Okay, it is a hexa-decimal number.  Remember this and skip
Packit 6c4009
	 the characters.  BTW: hexadecimal numbers must not be
Packit 6c4009
	 grouped.  */
Packit 6c4009
      base = 16;
Packit 6c4009
      cp += 2;
Packit 6c4009
      c = *cp;
Packit 6c4009
      grouping = NULL;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Record the start of the digits, in case we will check their grouping.  */
Packit 6c4009
  start_of_digits = startp = cp;
Packit 6c4009
Packit 6c4009
  /* Ignore leading zeroes.  This helps us to avoid useless computations.  */
Packit 6c4009
#ifdef USE_WIDE_CHAR
Packit 6c4009
  while (c == L'0' || ((wint_t) thousands != L'\0' && c == (wint_t) thousands))
Packit 6c4009
    c = *++cp;
Packit 6c4009
#else
Packit 6c4009
  if (__glibc_likely (thousands == NULL))
Packit 6c4009
    while (c == '0')
Packit 6c4009
      c = *++cp;
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      /* We also have the multibyte thousands string.  */
Packit 6c4009
      while (1)
Packit 6c4009
	{
Packit 6c4009
	  if (c != '0')
Packit 6c4009
	    {
Packit 6c4009
	      for (cnt = 0; thousands[cnt] != '\0'; ++cnt)
Packit 6c4009
		if (thousands[cnt] != cp[cnt])
Packit 6c4009
		  break;
Packit 6c4009
	      if (thousands[cnt] != '\0')
Packit 6c4009
		break;
Packit 6c4009
	      cp += cnt - 1;
Packit 6c4009
	    }
Packit 6c4009
	  c = *++cp;
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
  /* If no other digit but a '0' is found the result is 0.0.
Packit 6c4009
     Return current read pointer.  */
Packit 6c4009
  CHAR_TYPE lowc = TOLOWER (c);
Packit 6c4009
  if (!((c >= L_('0') && c <= L_('9'))
Packit 6c4009
	|| (base == 16 && lowc >= L_('a') && lowc <= L_('f'))
Packit 6c4009
	|| (
Packit 6c4009
#ifdef USE_WIDE_CHAR
Packit 6c4009
	    c == (wint_t) decimal
Packit 6c4009
#else
Packit 6c4009
	    ({ for (cnt = 0; decimal[cnt] != '\0'; ++cnt)
Packit 6c4009
		 if (decimal[cnt] != cp[cnt])
Packit 6c4009
		   break;
Packit 6c4009
	       decimal[cnt] == '\0'; })
Packit 6c4009
#endif
Packit 6c4009
	    /* '0x.' alone is not a valid hexadecimal number.
Packit 6c4009
	       '.' alone is not valid either, but that has been checked
Packit 6c4009
	       already earlier.  */
Packit 6c4009
	    && (base != 16
Packit 6c4009
		|| cp != start_of_digits
Packit 6c4009
		|| (cp[decimal_len] >= L_('0') && cp[decimal_len] <= L_('9'))
Packit 6c4009
		|| ({ CHAR_TYPE lo = TOLOWER (cp[decimal_len]);
Packit 6c4009
		      lo >= L_('a') && lo <= L_('f'); })))
Packit 6c4009
	|| (base == 16 && (cp != start_of_digits
Packit 6c4009
			   && lowc == L_('p')))
Packit 6c4009
	|| (base != 16 && lowc == L_('e'))))
Packit 6c4009
    {
Packit 6c4009
#ifdef USE_WIDE_CHAR
Packit 6c4009
      tp = __correctly_grouped_prefixwc (start_of_digits, cp, thousands,
Packit 6c4009
					 grouping);
Packit 6c4009
#else
Packit 6c4009
      tp = __correctly_grouped_prefixmb (start_of_digits, cp, thousands,
Packit 6c4009
					 grouping);
Packit 6c4009
#endif
Packit 6c4009
      /* If TP is at the start of the digits, there was no correctly
Packit 6c4009
	 grouped prefix of the string; so no number found.  */
Packit 6c4009
      RETURN (negative ? -0.0 : 0.0,
Packit 6c4009
	      tp == start_of_digits ? (base == 16 ? cp - 1 : nptr) : tp);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Remember first significant digit and read following characters until the
Packit 6c4009
     decimal point, exponent character or any non-FP number character.  */
Packit 6c4009
  startp = cp;
Packit 6c4009
  dig_no = 0;
Packit 6c4009
  while (1)
Packit 6c4009
    {
Packit 6c4009
      if ((c >= L_('0') && c <= L_('9'))
Packit 6c4009
	  || (base == 16
Packit 6c4009
	      && ({ CHAR_TYPE lo = TOLOWER (c);
Packit 6c4009
		    lo >= L_('a') && lo <= L_('f'); })))
Packit 6c4009
	++dig_no;
Packit 6c4009
      else
Packit 6c4009
	{
Packit 6c4009
#ifdef USE_WIDE_CHAR
Packit 6c4009
	  if (__builtin_expect ((wint_t) thousands == L'\0', 1)
Packit 6c4009
	      || c != (wint_t) thousands)
Packit 6c4009
	    /* Not a digit or separator: end of the integer part.  */
Packit 6c4009
	    break;
Packit 6c4009
#else
Packit 6c4009
	  if (__glibc_likely (thousands == NULL))
Packit 6c4009
	    break;
Packit 6c4009
	  else
Packit 6c4009
	    {
Packit 6c4009
	      for (cnt = 0; thousands[cnt] != '\0'; ++cnt)
Packit 6c4009
		if (thousands[cnt] != cp[cnt])
Packit 6c4009
		  break;
Packit 6c4009
	      if (thousands[cnt] != '\0')
Packit 6c4009
		break;
Packit 6c4009
	      cp += cnt - 1;
Packit 6c4009
	    }
Packit 6c4009
#endif
Packit 6c4009
	}
Packit 6c4009
      c = *++cp;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  if (__builtin_expect (grouping != NULL, 0) && cp > start_of_digits)
Packit 6c4009
    {
Packit 6c4009
      /* Check the grouping of the digits.  */
Packit 6c4009
#ifdef USE_WIDE_CHAR
Packit 6c4009
      tp = __correctly_grouped_prefixwc (start_of_digits, cp, thousands,
Packit 6c4009
					 grouping);
Packit 6c4009
#else
Packit 6c4009
      tp = __correctly_grouped_prefixmb (start_of_digits, cp, thousands,
Packit 6c4009
					 grouping);
Packit 6c4009
#endif
Packit 6c4009
      if (cp != tp)
Packit 6c4009
	{
Packit 6c4009
	  /* Less than the entire string was correctly grouped.  */
Packit 6c4009
Packit 6c4009
	  if (tp == start_of_digits)
Packit 6c4009
	    /* No valid group of numbers at all: no valid number.  */
Packit 6c4009
	    RETURN (0.0, nptr);
Packit 6c4009
Packit 6c4009
	  if (tp < startp)
Packit 6c4009
	    /* The number is validly grouped, but consists
Packit 6c4009
	       only of zeroes.  The whole value is zero.  */
Packit 6c4009
	    RETURN (negative ? -0.0 : 0.0, tp);
Packit 6c4009
Packit 6c4009
	  /* Recompute DIG_NO so we won't read more digits than
Packit 6c4009
	     are properly grouped.  */
Packit 6c4009
	  cp = tp;
Packit 6c4009
	  dig_no = 0;
Packit 6c4009
	  for (tp = startp; tp < cp; ++tp)
Packit 6c4009
	    if (*tp >= L_('0') && *tp <= L_('9'))
Packit 6c4009
	      ++dig_no;
Packit 6c4009
Packit 6c4009
	  int_no = dig_no;
Packit 6c4009
	  lead_zero = 0;
Packit 6c4009
Packit 6c4009
	  goto number_parsed;
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* We have the number of digits in the integer part.  Whether these
Packit 6c4009
     are all or any is really a fractional digit will be decided
Packit 6c4009
     later.  */
Packit 6c4009
  int_no = dig_no;
Packit 6c4009
  lead_zero = int_no == 0 ? (size_t) -1 : 0;
Packit 6c4009
Packit 6c4009
  /* Read the fractional digits.  A special case are the 'american
Packit 6c4009
     style' numbers like `16.' i.e. with decimal point but without
Packit 6c4009
     trailing digits.  */
Packit 6c4009
  if (
Packit 6c4009
#ifdef USE_WIDE_CHAR
Packit 6c4009
      c == (wint_t) decimal
Packit 6c4009
#else
Packit 6c4009
      ({ for (cnt = 0; decimal[cnt] != '\0'; ++cnt)
Packit 6c4009
	   if (decimal[cnt] != cp[cnt])
Packit 6c4009
	     break;
Packit 6c4009
	 decimal[cnt] == '\0'; })
Packit 6c4009
#endif
Packit 6c4009
      )
Packit 6c4009
    {
Packit 6c4009
      cp += decimal_len;
Packit 6c4009
      c = *cp;
Packit 6c4009
      while ((c >= L_('0') && c <= L_('9')) ||
Packit 6c4009
	     (base == 16 && ({ CHAR_TYPE lo = TOLOWER (c);
Packit 6c4009
			       lo >= L_('a') && lo <= L_('f'); })))
Packit 6c4009
	{
Packit 6c4009
	  if (c != L_('0') && lead_zero == (size_t) -1)
Packit 6c4009
	    lead_zero = dig_no - int_no;
Packit 6c4009
	  ++dig_no;
Packit 6c4009
	  c = *++cp;
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
  assert (dig_no <= (uintmax_t) INTMAX_MAX);
Packit 6c4009
Packit 6c4009
  /* Remember start of exponent (if any).  */
Packit 6c4009
  expp = cp;
Packit 6c4009
Packit 6c4009
  /* Read exponent.  */
Packit 6c4009
  lowc = TOLOWER (c);
Packit 6c4009
  if ((base == 16 && lowc == L_('p'))
Packit 6c4009
      || (base != 16 && lowc == L_('e')))
Packit 6c4009
    {
Packit 6c4009
      int exp_negative = 0;
Packit 6c4009
Packit 6c4009
      c = *++cp;
Packit 6c4009
      if (c == L_('-'))
Packit 6c4009
	{
Packit 6c4009
	  exp_negative = 1;
Packit 6c4009
	  c = *++cp;
Packit 6c4009
	}
Packit 6c4009
      else if (c == L_('+'))
Packit 6c4009
	c = *++cp;
Packit 6c4009
Packit 6c4009
      if (c >= L_('0') && c <= L_('9'))
Packit 6c4009
	{
Packit 6c4009
	  intmax_t exp_limit;
Packit 6c4009
Packit 6c4009
	  /* Get the exponent limit. */
Packit 6c4009
	  if (base == 16)
Packit 6c4009
	    {
Packit 6c4009
	      if (exp_negative)
Packit 6c4009
		{
Packit 6c4009
		  assert (int_no <= (uintmax_t) (INTMAX_MAX
Packit 6c4009
						 + MIN_EXP - MANT_DIG) / 4);
Packit 6c4009
		  exp_limit = -MIN_EXP + MANT_DIG + 4 * (intmax_t) int_no;
Packit 6c4009
		}
Packit 6c4009
	      else
Packit 6c4009
		{
Packit 6c4009
		  if (int_no)
Packit 6c4009
		    {
Packit 6c4009
		      assert (lead_zero == 0
Packit 6c4009
			      && int_no <= (uintmax_t) INTMAX_MAX / 4);
Packit 6c4009
		      exp_limit = MAX_EXP - 4 * (intmax_t) int_no + 3;
Packit 6c4009
		    }
Packit 6c4009
		  else if (lead_zero == (size_t) -1)
Packit 6c4009
		    {
Packit 6c4009
		      /* The number is zero and this limit is
Packit 6c4009
			 arbitrary.  */
Packit 6c4009
		      exp_limit = MAX_EXP + 3;
Packit 6c4009
		    }
Packit 6c4009
		  else
Packit 6c4009
		    {
Packit 6c4009
		      assert (lead_zero
Packit 6c4009
			      <= (uintmax_t) (INTMAX_MAX - MAX_EXP - 3) / 4);
Packit 6c4009
		      exp_limit = (MAX_EXP
Packit 6c4009
				   + 4 * (intmax_t) lead_zero
Packit 6c4009
				   + 3);
Packit 6c4009
		    }
Packit 6c4009
		}
Packit 6c4009
	    }
Packit 6c4009
	  else
Packit 6c4009
	    {
Packit 6c4009
	      if (exp_negative)
Packit 6c4009
		{
Packit 6c4009
		  assert (int_no
Packit 6c4009
			  <= (uintmax_t) (INTMAX_MAX + MIN_10_EXP - MANT_DIG));
Packit 6c4009
		  exp_limit = -MIN_10_EXP + MANT_DIG + (intmax_t) int_no;
Packit 6c4009
		}
Packit 6c4009
	      else
Packit 6c4009
		{
Packit 6c4009
		  if (int_no)
Packit 6c4009
		    {
Packit 6c4009
		      assert (lead_zero == 0
Packit 6c4009
			      && int_no <= (uintmax_t) INTMAX_MAX);
Packit 6c4009
		      exp_limit = MAX_10_EXP - (intmax_t) int_no + 1;
Packit 6c4009
		    }
Packit 6c4009
		  else if (lead_zero == (size_t) -1)
Packit 6c4009
		    {
Packit 6c4009
		      /* The number is zero and this limit is
Packit 6c4009
			 arbitrary.  */
Packit 6c4009
		      exp_limit = MAX_10_EXP + 1;
Packit 6c4009
		    }
Packit 6c4009
		  else
Packit 6c4009
		    {
Packit 6c4009
		      assert (lead_zero
Packit 6c4009
			      <= (uintmax_t) (INTMAX_MAX - MAX_10_EXP - 1));
Packit 6c4009
		      exp_limit = MAX_10_EXP + (intmax_t) lead_zero + 1;
Packit 6c4009
		    }
Packit 6c4009
		}
Packit 6c4009
	    }
Packit 6c4009
Packit 6c4009
	  if (exp_limit < 0)
Packit 6c4009
	    exp_limit = 0;
Packit 6c4009
Packit 6c4009
	  do
Packit 6c4009
	    {
Packit 6c4009
	      if (__builtin_expect ((exponent > exp_limit / 10
Packit 6c4009
				     || (exponent == exp_limit / 10
Packit 6c4009
					 && c - L_('0') > exp_limit % 10)), 0))
Packit 6c4009
		/* The exponent is too large/small to represent a valid
Packit 6c4009
		   number.  */
Packit 6c4009
		{
Packit 6c4009
		  FLOAT result;
Packit 6c4009
Packit 6c4009
		  /* We have to take care for special situation: a joker
Packit 6c4009
		     might have written "0.0e100000" which is in fact
Packit 6c4009
		     zero.  */
Packit 6c4009
		  if (lead_zero == (size_t) -1)
Packit 6c4009
		    result = negative ? -0.0 : 0.0;
Packit 6c4009
		  else
Packit 6c4009
		    {
Packit 6c4009
		      /* Overflow or underflow.  */
Packit 6c4009
		      result = (exp_negative
Packit 6c4009
				? underflow_value (negative)
Packit 6c4009
				: overflow_value (negative));
Packit 6c4009
		    }
Packit 6c4009
Packit 6c4009
		  /* Accept all following digits as part of the exponent.  */
Packit 6c4009
		  do
Packit 6c4009
		    ++cp;
Packit 6c4009
		  while (*cp >= L_('0') && *cp <= L_('9'));
Packit 6c4009
Packit 6c4009
		  RETURN (result, cp);
Packit 6c4009
		  /* NOTREACHED */
Packit 6c4009
		}
Packit 6c4009
Packit 6c4009
	      exponent *= 10;
Packit 6c4009
	      exponent += c - L_('0');
Packit 6c4009
Packit 6c4009
	      c = *++cp;
Packit 6c4009
	    }
Packit 6c4009
	  while (c >= L_('0') && c <= L_('9'));
Packit 6c4009
Packit 6c4009
	  if (exp_negative)
Packit 6c4009
	    exponent = -exponent;
Packit 6c4009
	}
Packit 6c4009
      else
Packit 6c4009
	cp = expp;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* We don't want to have to work with trailing zeroes after the radix.  */
Packit 6c4009
  if (dig_no > int_no)
Packit 6c4009
    {
Packit 6c4009
      while (expp[-1] == L_('0'))
Packit 6c4009
	{
Packit 6c4009
	  --expp;
Packit 6c4009
	  --dig_no;
Packit 6c4009
	}
Packit 6c4009
      assert (dig_no >= int_no);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  if (dig_no == int_no && dig_no > 0 && exponent < 0)
Packit 6c4009
    do
Packit 6c4009
      {
Packit 6c4009
	while (! (base == 16 ? ISXDIGIT (expp[-1]) : ISDIGIT (expp[-1])))
Packit 6c4009
	  --expp;
Packit 6c4009
Packit 6c4009
	if (expp[-1] != L_('0'))
Packit 6c4009
	  break;
Packit 6c4009
Packit 6c4009
	--expp;
Packit 6c4009
	--dig_no;
Packit 6c4009
	--int_no;
Packit 6c4009
	exponent += base == 16 ? 4 : 1;
Packit 6c4009
      }
Packit 6c4009
    while (dig_no > 0 && exponent < 0);
Packit 6c4009
Packit 6c4009
 number_parsed:
Packit 6c4009
Packit 6c4009
  /* The whole string is parsed.  Store the address of the next character.  */
Packit 6c4009
  if (endptr)
Packit 6c4009
    *endptr = (STRING_TYPE *) cp;
Packit 6c4009
Packit 6c4009
  if (dig_no == 0)
Packit 6c4009
    return negative ? -0.0 : 0.0;
Packit 6c4009
Packit 6c4009
  if (lead_zero)
Packit 6c4009
    {
Packit 6c4009
      /* Find the decimal point */
Packit 6c4009
#ifdef USE_WIDE_CHAR
Packit 6c4009
      while (*startp != decimal)
Packit 6c4009
	++startp;
Packit 6c4009
#else
Packit 6c4009
      while (1)
Packit 6c4009
	{
Packit 6c4009
	  if (*startp == decimal[0])
Packit 6c4009
	    {
Packit 6c4009
	      for (cnt = 1; decimal[cnt] != '\0'; ++cnt)
Packit 6c4009
		if (decimal[cnt] != startp[cnt])
Packit 6c4009
		  break;
Packit 6c4009
	      if (decimal[cnt] == '\0')
Packit 6c4009
		break;
Packit 6c4009
	    }
Packit 6c4009
	  ++startp;
Packit 6c4009
	}
Packit 6c4009
#endif
Packit 6c4009
      startp += lead_zero + decimal_len;
Packit 6c4009
      assert (lead_zero <= (base == 16
Packit 6c4009
			    ? (uintmax_t) INTMAX_MAX / 4
Packit 6c4009
			    : (uintmax_t) INTMAX_MAX));
Packit 6c4009
      assert (lead_zero <= (base == 16
Packit 6c4009
			    ? ((uintmax_t) exponent
Packit 6c4009
			       - (uintmax_t) INTMAX_MIN) / 4
Packit 6c4009
			    : ((uintmax_t) exponent - (uintmax_t) INTMAX_MIN)));
Packit 6c4009
      exponent -= base == 16 ? 4 * (intmax_t) lead_zero : (intmax_t) lead_zero;
Packit 6c4009
      dig_no -= lead_zero;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* If the BASE is 16 we can use a simpler algorithm.  */
Packit 6c4009
  if (base == 16)
Packit 6c4009
    {
Packit 6c4009
      static const int nbits[16] = { 0, 1, 2, 2, 3, 3, 3, 3,
Packit 6c4009
				     4, 4, 4, 4, 4, 4, 4, 4 };
Packit 6c4009
      int idx = (MANT_DIG - 1) / BITS_PER_MP_LIMB;
Packit 6c4009
      int pos = (MANT_DIG - 1) % BITS_PER_MP_LIMB;
Packit 6c4009
      mp_limb_t val;
Packit 6c4009
Packit 6c4009
      while (!ISXDIGIT (*startp))
Packit 6c4009
	++startp;
Packit 6c4009
      while (*startp == L_('0'))
Packit 6c4009
	++startp;
Packit 6c4009
      if (ISDIGIT (*startp))
Packit 6c4009
	val = *startp++ - L_('0');
Packit 6c4009
      else
Packit 6c4009
	val = 10 + TOLOWER (*startp++) - L_('a');
Packit 6c4009
      bits = nbits[val];
Packit 6c4009
      /* We cannot have a leading zero.  */
Packit 6c4009
      assert (bits != 0);
Packit 6c4009
Packit 6c4009
      if (pos + 1 >= 4 || pos + 1 >= bits)
Packit 6c4009
	{
Packit 6c4009
	  /* We don't have to care for wrapping.  This is the normal
Packit 6c4009
	     case so we add the first clause in the `if' expression as
Packit 6c4009
	     an optimization.  It is a compile-time constant and so does
Packit 6c4009
	     not cost anything.  */
Packit 6c4009
	  retval[idx] = val << (pos - bits + 1);
Packit 6c4009
	  pos -= bits;
Packit 6c4009
	}
Packit 6c4009
      else
Packit 6c4009
	{
Packit 6c4009
	  retval[idx--] = val >> (bits - pos - 1);
Packit 6c4009
	  retval[idx] = val << (BITS_PER_MP_LIMB - (bits - pos - 1));
Packit 6c4009
	  pos = BITS_PER_MP_LIMB - 1 - (bits - pos - 1);
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
      /* Adjust the exponent for the bits we are shifting in.  */
Packit 6c4009
      assert (int_no <= (uintmax_t) (exponent < 0
Packit 6c4009
				     ? (INTMAX_MAX - bits + 1) / 4
Packit 6c4009
				     : (INTMAX_MAX - exponent - bits + 1) / 4));
Packit 6c4009
      exponent += bits - 1 + ((intmax_t) int_no - 1) * 4;
Packit 6c4009
Packit 6c4009
      while (--dig_no > 0 && idx >= 0)
Packit 6c4009
	{
Packit 6c4009
	  if (!ISXDIGIT (*startp))
Packit 6c4009
	    startp += decimal_len;
Packit 6c4009
	  if (ISDIGIT (*startp))
Packit 6c4009
	    val = *startp++ - L_('0');
Packit 6c4009
	  else
Packit 6c4009
	    val = 10 + TOLOWER (*startp++) - L_('a');
Packit 6c4009
Packit 6c4009
	  if (pos + 1 >= 4)
Packit 6c4009
	    {
Packit 6c4009
	      retval[idx] |= val << (pos - 4 + 1);
Packit 6c4009
	      pos -= 4;
Packit 6c4009
	    }
Packit 6c4009
	  else
Packit 6c4009
	    {
Packit 6c4009
	      retval[idx--] |= val >> (4 - pos - 1);
Packit 6c4009
	      val <<= BITS_PER_MP_LIMB - (4 - pos - 1);
Packit 6c4009
	      if (idx < 0)
Packit 6c4009
		{
Packit 6c4009
		  int rest_nonzero = 0;
Packit 6c4009
		  while (--dig_no > 0)
Packit 6c4009
		    {
Packit 6c4009
		      if (*startp != L_('0'))
Packit 6c4009
			{
Packit 6c4009
			  rest_nonzero = 1;
Packit 6c4009
			  break;
Packit 6c4009
			}
Packit 6c4009
		      startp++;
Packit 6c4009
		    }
Packit 6c4009
		  return round_and_return (retval, exponent, negative, val,
Packit 6c4009
					   BITS_PER_MP_LIMB - 1, rest_nonzero);
Packit 6c4009
		}
Packit 6c4009
Packit 6c4009
	      retval[idx] = val;
Packit 6c4009
	      pos = BITS_PER_MP_LIMB - 1 - (4 - pos - 1);
Packit 6c4009
	    }
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
      /* We ran out of digits.  */
Packit 6c4009
      MPN_ZERO (retval, idx);
Packit 6c4009
Packit 6c4009
      return round_and_return (retval, exponent, negative, 0, 0, 0);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Now we have the number of digits in total and the integer digits as well
Packit 6c4009
     as the exponent and its sign.  We can decide whether the read digits are
Packit 6c4009
     really integer digits or belong to the fractional part; i.e. we normalize
Packit 6c4009
     123e-2 to 1.23.  */
Packit 6c4009
  {
Packit 6c4009
    intmax_t incr = (exponent < 0
Packit 6c4009
		     ? MAX (-(intmax_t) int_no, exponent)
Packit 6c4009
		     : MIN ((intmax_t) dig_no - (intmax_t) int_no, exponent));
Packit 6c4009
    int_no += incr;
Packit 6c4009
    exponent -= incr;
Packit 6c4009
  }
Packit 6c4009
Packit 6c4009
  if (__glibc_unlikely (exponent > MAX_10_EXP + 1 - (intmax_t) int_no))
Packit 6c4009
    return overflow_value (negative);
Packit 6c4009
Packit 6c4009
  /* 10^(MIN_10_EXP-1) is not normal.  Thus, 10^(MIN_10_EXP-1) /
Packit 6c4009
     2^MANT_DIG is below half the least subnormal, so anything with a
Packit 6c4009
     base-10 exponent less than the base-10 exponent (which is
Packit 6c4009
     MIN_10_EXP - 1 - ceil(MANT_DIG*log10(2))) of that value
Packit 6c4009
     underflows.  DIG is floor((MANT_DIG-1)log10(2)), so an exponent
Packit 6c4009
     below MIN_10_EXP - (DIG + 3) underflows.  But EXPONENT is
Packit 6c4009
     actually an exponent multiplied only by a fractional part, not an
Packit 6c4009
     integer part, so an exponent below MIN_10_EXP - (DIG + 2)
Packit 6c4009
     underflows.  */
Packit 6c4009
  if (__glibc_unlikely (exponent < MIN_10_EXP - (DIG + 2)))
Packit 6c4009
    return underflow_value (negative);
Packit 6c4009
Packit 6c4009
  if (int_no > 0)
Packit 6c4009
    {
Packit 6c4009
      /* Read the integer part as a multi-precision number to NUM.  */
Packit 6c4009
      startp = str_to_mpn (startp, int_no, num, &numsize, &exponent
Packit 6c4009
#ifndef USE_WIDE_CHAR
Packit 6c4009
			   , decimal, decimal_len, thousands
Packit 6c4009
#endif
Packit 6c4009
			   );
Packit 6c4009
Packit 6c4009
      if (exponent > 0)
Packit 6c4009
	{
Packit 6c4009
	  /* We now multiply the gained number by the given power of ten.  */
Packit 6c4009
	  mp_limb_t *psrc = num;
Packit 6c4009
	  mp_limb_t *pdest = den;
Packit 6c4009
	  int expbit = 1;
Packit 6c4009
	  const struct mp_power *ttab = &_fpioconst_pow10[0];
Packit 6c4009
Packit 6c4009
	  do
Packit 6c4009
	    {
Packit 6c4009
	      if ((exponent & expbit) != 0)
Packit 6c4009
		{
Packit 6c4009
		  size_t size = ttab->arraysize - _FPIO_CONST_OFFSET;
Packit 6c4009
		  mp_limb_t cy;
Packit 6c4009
		  exponent ^= expbit;
Packit 6c4009
Packit 6c4009
		  /* FIXME: not the whole multiplication has to be
Packit 6c4009
		     done.  If we have the needed number of bits we
Packit 6c4009
		     only need the information whether more non-zero
Packit 6c4009
		     bits follow.  */
Packit 6c4009
		  if (numsize >= ttab->arraysize - _FPIO_CONST_OFFSET)
Packit 6c4009
		    cy = __mpn_mul (pdest, psrc, numsize,
Packit 6c4009
				    &__tens[ttab->arrayoff
Packit 6c4009
					   + _FPIO_CONST_OFFSET],
Packit 6c4009
				    size);
Packit 6c4009
		  else
Packit 6c4009
		    cy = __mpn_mul (pdest, &__tens[ttab->arrayoff
Packit 6c4009
						  + _FPIO_CONST_OFFSET],
Packit 6c4009
				    size, psrc, numsize);
Packit 6c4009
		  numsize += size;
Packit 6c4009
		  if (cy == 0)
Packit 6c4009
		    --numsize;
Packit 6c4009
		  (void) SWAP (psrc, pdest);
Packit 6c4009
		}
Packit 6c4009
	      expbit <<= 1;
Packit 6c4009
	      ++ttab;
Packit 6c4009
	    }
Packit 6c4009
	  while (exponent != 0);
Packit 6c4009
Packit 6c4009
	  if (psrc == den)
Packit 6c4009
	    memcpy (num, den, numsize * sizeof (mp_limb_t));
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
      /* Determine how many bits of the result we already have.  */
Packit 6c4009
      count_leading_zeros (bits, num[numsize - 1]);
Packit 6c4009
      bits = numsize * BITS_PER_MP_LIMB - bits;
Packit 6c4009
Packit 6c4009
      /* Now we know the exponent of the number in base two.
Packit 6c4009
	 Check it against the maximum possible exponent.  */
Packit 6c4009
      if (__glibc_unlikely (bits > MAX_EXP))
Packit 6c4009
	return overflow_value (negative);
Packit 6c4009
Packit 6c4009
      /* We have already the first BITS bits of the result.  Together with
Packit 6c4009
	 the information whether more non-zero bits follow this is enough
Packit 6c4009
	 to determine the result.  */
Packit 6c4009
      if (bits > MANT_DIG)
Packit 6c4009
	{
Packit 6c4009
	  int i;
Packit 6c4009
	  const mp_size_t least_idx = (bits - MANT_DIG) / BITS_PER_MP_LIMB;
Packit 6c4009
	  const mp_size_t least_bit = (bits - MANT_DIG) % BITS_PER_MP_LIMB;
Packit 6c4009
	  const mp_size_t round_idx = least_bit == 0 ? least_idx - 1
Packit 6c4009
						     : least_idx;
Packit 6c4009
	  const mp_size_t round_bit = least_bit == 0 ? BITS_PER_MP_LIMB - 1
Packit 6c4009
						     : least_bit - 1;
Packit 6c4009
Packit 6c4009
	  if (least_bit == 0)
Packit 6c4009
	    memcpy (retval, &num[least_idx],
Packit 6c4009
		    RETURN_LIMB_SIZE * sizeof (mp_limb_t));
Packit 6c4009
	  else
Packit 6c4009
	    {
Packit 6c4009
	      for (i = least_idx; i < numsize - 1; ++i)
Packit 6c4009
		retval[i - least_idx] = (num[i] >> least_bit)
Packit 6c4009
					| (num[i + 1]
Packit 6c4009
					   << (BITS_PER_MP_LIMB - least_bit));
Packit 6c4009
	      if (i - least_idx < RETURN_LIMB_SIZE)
Packit 6c4009
		retval[RETURN_LIMB_SIZE - 1] = num[i] >> least_bit;
Packit 6c4009
	    }
Packit 6c4009
Packit 6c4009
	  /* Check whether any limb beside the ones in RETVAL are non-zero.  */
Packit 6c4009
	  for (i = 0; num[i] == 0; ++i)
Packit 6c4009
	    ;
Packit 6c4009
Packit 6c4009
	  return round_and_return (retval, bits - 1, negative,
Packit 6c4009
				   num[round_idx], round_bit,
Packit 6c4009
				   int_no < dig_no || i < round_idx);
Packit 6c4009
	  /* NOTREACHED */
Packit 6c4009
	}
Packit 6c4009
      else if (dig_no == int_no)
Packit 6c4009
	{
Packit 6c4009
	  const mp_size_t target_bit = (MANT_DIG - 1) % BITS_PER_MP_LIMB;
Packit 6c4009
	  const mp_size_t is_bit = (bits - 1) % BITS_PER_MP_LIMB;
Packit 6c4009
Packit 6c4009
	  if (target_bit == is_bit)
Packit 6c4009
	    {
Packit 6c4009
	      memcpy (&retval[RETURN_LIMB_SIZE - numsize], num,
Packit 6c4009
		      numsize * sizeof (mp_limb_t));
Packit 6c4009
	      /* FIXME: the following loop can be avoided if we assume a
Packit 6c4009
		 maximal MANT_DIG value.  */
Packit 6c4009
	      MPN_ZERO (retval, RETURN_LIMB_SIZE - numsize);
Packit 6c4009
	    }
Packit 6c4009
	  else if (target_bit > is_bit)
Packit 6c4009
	    {
Packit 6c4009
	      (void) __mpn_lshift (&retval[RETURN_LIMB_SIZE - numsize],
Packit 6c4009
				   num, numsize, target_bit - is_bit);
Packit 6c4009
	      /* FIXME: the following loop can be avoided if we assume a
Packit 6c4009
		 maximal MANT_DIG value.  */
Packit 6c4009
	      MPN_ZERO (retval, RETURN_LIMB_SIZE - numsize);
Packit 6c4009
	    }
Packit 6c4009
	  else
Packit 6c4009
	    {
Packit 6c4009
	      mp_limb_t cy;
Packit 6c4009
	      assert (numsize < RETURN_LIMB_SIZE);
Packit 6c4009
Packit 6c4009
	      cy = __mpn_rshift (&retval[RETURN_LIMB_SIZE - numsize],
Packit 6c4009
				 num, numsize, is_bit - target_bit);
Packit 6c4009
	      retval[RETURN_LIMB_SIZE - numsize - 1] = cy;
Packit 6c4009
	      /* FIXME: the following loop can be avoided if we assume a
Packit 6c4009
		 maximal MANT_DIG value.  */
Packit 6c4009
	      MPN_ZERO (retval, RETURN_LIMB_SIZE - numsize - 1);
Packit 6c4009
	    }
Packit 6c4009
Packit 6c4009
	  return round_and_return (retval, bits - 1, negative, 0, 0, 0);
Packit 6c4009
	  /* NOTREACHED */
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
      /* Store the bits we already have.  */
Packit 6c4009
      memcpy (retval, num, numsize * sizeof (mp_limb_t));
Packit 6c4009
#if RETURN_LIMB_SIZE > 1
Packit 6c4009
      if (numsize < RETURN_LIMB_SIZE)
Packit 6c4009
# if RETURN_LIMB_SIZE == 2
Packit 6c4009
	retval[numsize] = 0;
Packit 6c4009
# else
Packit 6c4009
	MPN_ZERO (retval + numsize, RETURN_LIMB_SIZE - numsize);
Packit 6c4009
# endif
Packit 6c4009
#endif
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* We have to compute at least some of the fractional digits.  */
Packit 6c4009
  {
Packit 6c4009
    /* We construct a fraction and the result of the division gives us
Packit 6c4009
       the needed digits.  The denominator is 1.0 multiplied by the
Packit 6c4009
       exponent of the lowest digit; i.e. 0.123 gives 123 / 1000 and
Packit 6c4009
       123e-6 gives 123 / 1000000.  */
Packit 6c4009
Packit 6c4009
    int expbit;
Packit 6c4009
    int neg_exp;
Packit 6c4009
    int more_bits;
Packit 6c4009
    int need_frac_digits;
Packit 6c4009
    mp_limb_t cy;
Packit 6c4009
    mp_limb_t *psrc = den;
Packit 6c4009
    mp_limb_t *pdest = num;
Packit 6c4009
    const struct mp_power *ttab = &_fpioconst_pow10[0];
Packit 6c4009
Packit 6c4009
    assert (dig_no > int_no
Packit 6c4009
	    && exponent <= 0
Packit 6c4009
	    && exponent >= MIN_10_EXP - (DIG + 2));
Packit 6c4009
Packit 6c4009
    /* We need to compute MANT_DIG - BITS fractional bits that lie
Packit 6c4009
       within the mantissa of the result, the following bit for
Packit 6c4009
       rounding, and to know whether any subsequent bit is 0.
Packit 6c4009
       Computing a bit with value 2^-n means looking at n digits after
Packit 6c4009
       the decimal point.  */
Packit 6c4009
    if (bits > 0)
Packit 6c4009
      {
Packit 6c4009
	/* The bits required are those immediately after the point.  */
Packit 6c4009
	assert (int_no > 0 && exponent == 0);
Packit 6c4009
	need_frac_digits = 1 + MANT_DIG - bits;
Packit 6c4009
      }
Packit 6c4009
    else
Packit 6c4009
      {
Packit 6c4009
	/* The number is in the form .123eEXPONENT.  */
Packit 6c4009
	assert (int_no == 0 && *startp != L_('0'));
Packit 6c4009
	/* The number is at least 10^(EXPONENT-1), and 10^3 <
Packit 6c4009
	   2^10.  */
Packit 6c4009
	int neg_exp_2 = ((1 - exponent) * 10) / 3 + 1;
Packit 6c4009
	/* The number is at least 2^-NEG_EXP_2.  We need up to
Packit 6c4009
	   MANT_DIG bits following that bit.  */
Packit 6c4009
	need_frac_digits = neg_exp_2 + MANT_DIG;
Packit 6c4009
	/* However, we never need bits beyond 1/4 ulp of the smallest
Packit 6c4009
	   representable value.  (That 1/4 ulp bit is only needed to
Packit 6c4009
	   determine tinyness on machines where tinyness is determined
Packit 6c4009
	   after rounding.)  */
Packit 6c4009
	if (need_frac_digits > MANT_DIG - MIN_EXP + 2)
Packit 6c4009
	  need_frac_digits = MANT_DIG - MIN_EXP + 2;
Packit 6c4009
	/* At this point, NEED_FRAC_DIGITS is the total number of
Packit 6c4009
	   digits needed after the point, but some of those may be
Packit 6c4009
	   leading 0s.  */
Packit 6c4009
	need_frac_digits += exponent;
Packit 6c4009
	/* Any cases underflowing enough that none of the fractional
Packit 6c4009
	   digits are needed should have been caught earlier (such
Packit 6c4009
	   cases are on the order of 10^-n or smaller where 2^-n is
Packit 6c4009
	   the least subnormal).  */
Packit 6c4009
	assert (need_frac_digits > 0);
Packit 6c4009
      }
Packit 6c4009
Packit 6c4009
    if (need_frac_digits > (intmax_t) dig_no - (intmax_t) int_no)
Packit 6c4009
      need_frac_digits = (intmax_t) dig_no - (intmax_t) int_no;
Packit 6c4009
Packit 6c4009
    if ((intmax_t) dig_no > (intmax_t) int_no + need_frac_digits)
Packit 6c4009
      {
Packit 6c4009
	dig_no = int_no + need_frac_digits;
Packit 6c4009
	more_bits = 1;
Packit 6c4009
      }
Packit 6c4009
    else
Packit 6c4009
      more_bits = 0;
Packit 6c4009
Packit 6c4009
    neg_exp = (intmax_t) dig_no - (intmax_t) int_no - exponent;
Packit 6c4009
Packit 6c4009
    /* Construct the denominator.  */
Packit 6c4009
    densize = 0;
Packit 6c4009
    expbit = 1;
Packit 6c4009
    do
Packit 6c4009
      {
Packit 6c4009
	if ((neg_exp & expbit) != 0)
Packit 6c4009
	  {
Packit 6c4009
	    mp_limb_t cy;
Packit 6c4009
	    neg_exp ^= expbit;
Packit 6c4009
Packit 6c4009
	    if (densize == 0)
Packit 6c4009
	      {
Packit 6c4009
		densize = ttab->arraysize - _FPIO_CONST_OFFSET;
Packit 6c4009
		memcpy (psrc, &__tens[ttab->arrayoff + _FPIO_CONST_OFFSET],
Packit 6c4009
			densize * sizeof (mp_limb_t));
Packit 6c4009
	      }
Packit 6c4009
	    else
Packit 6c4009
	      {
Packit 6c4009
		cy = __mpn_mul (pdest, &__tens[ttab->arrayoff
Packit 6c4009
					      + _FPIO_CONST_OFFSET],
Packit 6c4009
				ttab->arraysize - _FPIO_CONST_OFFSET,
Packit 6c4009
				psrc, densize);
Packit 6c4009
		densize += ttab->arraysize - _FPIO_CONST_OFFSET;
Packit 6c4009
		if (cy == 0)
Packit 6c4009
		  --densize;
Packit 6c4009
		(void) SWAP (psrc, pdest);
Packit 6c4009
	      }
Packit 6c4009
	  }
Packit 6c4009
	expbit <<= 1;
Packit 6c4009
	++ttab;
Packit 6c4009
      }
Packit 6c4009
    while (neg_exp != 0);
Packit 6c4009
Packit 6c4009
    if (psrc == num)
Packit 6c4009
      memcpy (den, num, densize * sizeof (mp_limb_t));
Packit 6c4009
Packit 6c4009
    /* Read the fractional digits from the string.  */
Packit 6c4009
    (void) str_to_mpn (startp, dig_no - int_no, num, &numsize, &exponent
Packit 6c4009
#ifndef USE_WIDE_CHAR
Packit 6c4009
		       , decimal, decimal_len, thousands
Packit 6c4009
#endif
Packit 6c4009
		       );
Packit 6c4009
Packit 6c4009
    /* We now have to shift both numbers so that the highest bit in the
Packit 6c4009
       denominator is set.  In the same process we copy the numerator to
Packit 6c4009
       a high place in the array so that the division constructs the wanted
Packit 6c4009
       digits.  This is done by a "quasi fix point" number representation.
Packit 6c4009
Packit 6c4009
       num:   ddddddddddd . 0000000000000000000000
Packit 6c4009
	      |--- m ---|
Packit 6c4009
       den:                            ddddddddddd      n >= m
Packit 6c4009
				       |--- n ---|
Packit 6c4009
     */
Packit 6c4009
Packit 6c4009
    count_leading_zeros (cnt, den[densize - 1]);
Packit 6c4009
Packit 6c4009
    if (cnt > 0)
Packit 6c4009
      {
Packit 6c4009
	/* Don't call `mpn_shift' with a count of zero since the specification
Packit 6c4009
	   does not allow this.  */
Packit 6c4009
	(void) __mpn_lshift (den, den, densize, cnt);
Packit 6c4009
	cy = __mpn_lshift (num, num, numsize, cnt);
Packit 6c4009
	if (cy != 0)
Packit 6c4009
	  num[numsize++] = cy;
Packit 6c4009
      }
Packit 6c4009
Packit 6c4009
    /* Now we are ready for the division.  But it is not necessary to
Packit 6c4009
       do a full multi-precision division because we only need a small
Packit 6c4009
       number of bits for the result.  So we do not use __mpn_divmod
Packit 6c4009
       here but instead do the division here by hand and stop whenever
Packit 6c4009
       the needed number of bits is reached.  The code itself comes
Packit 6c4009
       from the GNU MP Library by Torbj\"orn Granlund.  */
Packit 6c4009
Packit 6c4009
    exponent = bits;
Packit 6c4009
Packit 6c4009
    switch (densize)
Packit 6c4009
      {
Packit 6c4009
      case 1:
Packit 6c4009
	{
Packit 6c4009
	  mp_limb_t d, n, quot;
Packit 6c4009
	  int used = 0;
Packit 6c4009
Packit 6c4009
	  n = num[0];
Packit 6c4009
	  d = den[0];
Packit 6c4009
	  assert (numsize == 1 && n < d);
Packit 6c4009
Packit 6c4009
	  do
Packit 6c4009
	    {
Packit 6c4009
	      udiv_qrnnd (quot, n, n, 0, d);
Packit 6c4009
Packit 6c4009
#define got_limb							      \
Packit 6c4009
	      if (bits == 0)						      \
Packit 6c4009
		{							      \
Packit 6c4009
		  int cnt;						      \
Packit 6c4009
		  if (quot == 0)					      \
Packit 6c4009
		    cnt = BITS_PER_MP_LIMB;				      \
Packit 6c4009
		  else							      \
Packit 6c4009
		    count_leading_zeros (cnt, quot);			      \
Packit 6c4009
		  exponent -= cnt;					      \
Packit 6c4009
		  if (BITS_PER_MP_LIMB - cnt > MANT_DIG)		      \
Packit 6c4009
		    {							      \
Packit 6c4009
		      used = MANT_DIG + cnt;				      \
Packit 6c4009
		      retval[0] = quot >> (BITS_PER_MP_LIMB - used);	      \
Packit 6c4009
		      bits = MANT_DIG + 1;				      \
Packit 6c4009
		    }							      \
Packit 6c4009
		  else							      \
Packit 6c4009
		    {							      \
Packit 6c4009
		      /* Note that we only clear the second element.  */      \
Packit 6c4009
		      /* The conditional is determined at compile time.  */   \
Packit 6c4009
		      if (RETURN_LIMB_SIZE > 1)				      \
Packit 6c4009
			retval[1] = 0;					      \
Packit 6c4009
		      retval[0] = quot;					      \
Packit 6c4009
		      bits = -cnt;					      \
Packit 6c4009
		    }							      \
Packit 6c4009
		}							      \
Packit 6c4009
	      else if (bits + BITS_PER_MP_LIMB <= MANT_DIG)		      \
Packit 6c4009
		__mpn_lshift_1 (retval, RETURN_LIMB_SIZE, BITS_PER_MP_LIMB,   \
Packit 6c4009
				quot);					      \
Packit 6c4009
	      else							      \
Packit 6c4009
		{							      \
Packit 6c4009
		  used = MANT_DIG - bits;				      \
Packit 6c4009
		  if (used > 0)						      \
Packit 6c4009
		    __mpn_lshift_1 (retval, RETURN_LIMB_SIZE, used, quot);    \
Packit 6c4009
		}							      \
Packit 6c4009
	      bits += BITS_PER_MP_LIMB
Packit 6c4009
Packit 6c4009
	      got_limb;
Packit 6c4009
	    }
Packit 6c4009
	  while (bits <= MANT_DIG);
Packit 6c4009
Packit 6c4009
	  return round_and_return (retval, exponent - 1, negative,
Packit 6c4009
				   quot, BITS_PER_MP_LIMB - 1 - used,
Packit 6c4009
				   more_bits || n != 0);
Packit 6c4009
	}
Packit 6c4009
      case 2:
Packit 6c4009
	{
Packit 6c4009
	  mp_limb_t d0, d1, n0, n1;
Packit 6c4009
	  mp_limb_t quot = 0;
Packit 6c4009
	  int used = 0;
Packit 6c4009
Packit 6c4009
	  d0 = den[0];
Packit 6c4009
	  d1 = den[1];
Packit 6c4009
Packit 6c4009
	  if (numsize < densize)
Packit 6c4009
	    {
Packit 6c4009
	      if (num[0] >= d1)
Packit 6c4009
		{
Packit 6c4009
		  /* The numerator of the number occupies fewer bits than
Packit 6c4009
		     the denominator but the one limb is bigger than the
Packit 6c4009
		     high limb of the numerator.  */
Packit 6c4009
		  n1 = 0;
Packit 6c4009
		  n0 = num[0];
Packit 6c4009
		}
Packit 6c4009
	      else
Packit 6c4009
		{
Packit 6c4009
		  if (bits <= 0)
Packit 6c4009
		    exponent -= BITS_PER_MP_LIMB;
Packit 6c4009
		  else
Packit 6c4009
		    {
Packit 6c4009
		      if (bits + BITS_PER_MP_LIMB <= MANT_DIG)
Packit 6c4009
			__mpn_lshift_1 (retval, RETURN_LIMB_SIZE,
Packit 6c4009
					BITS_PER_MP_LIMB, 0);
Packit 6c4009
		      else
Packit 6c4009
			{
Packit 6c4009
			  used = MANT_DIG - bits;
Packit 6c4009
			  if (used > 0)
Packit 6c4009
			    __mpn_lshift_1 (retval, RETURN_LIMB_SIZE, used, 0);
Packit 6c4009
			}
Packit 6c4009
		      bits += BITS_PER_MP_LIMB;
Packit 6c4009
		    }
Packit 6c4009
		  n1 = num[0];
Packit 6c4009
		  n0 = 0;
Packit 6c4009
		}
Packit 6c4009
	    }
Packit 6c4009
	  else
Packit 6c4009
	    {
Packit 6c4009
	      n1 = num[1];
Packit 6c4009
	      n0 = num[0];
Packit 6c4009
	    }
Packit 6c4009
Packit 6c4009
	  while (bits <= MANT_DIG)
Packit 6c4009
	    {
Packit 6c4009
	      mp_limb_t r;
Packit 6c4009
Packit 6c4009
	      if (n1 == d1)
Packit 6c4009
		{
Packit 6c4009
		  /* QUOT should be either 111..111 or 111..110.  We need
Packit 6c4009
		     special treatment of this rare case as normal division
Packit 6c4009
		     would give overflow.  */
Packit 6c4009
		  quot = ~(mp_limb_t) 0;
Packit 6c4009
Packit 6c4009
		  r = n0 + d1;
Packit 6c4009
		  if (r < d1)	/* Carry in the addition?  */
Packit 6c4009
		    {
Packit 6c4009
		      add_ssaaaa (n1, n0, r - d0, 0, 0, d0);
Packit 6c4009
		      goto have_quot;
Packit 6c4009
		    }
Packit 6c4009
		  n1 = d0 - (d0 != 0);
Packit 6c4009
		  n0 = -d0;
Packit 6c4009
		}
Packit 6c4009
	      else
Packit 6c4009
		{
Packit 6c4009
		  udiv_qrnnd (quot, r, n1, n0, d1);
Packit 6c4009
		  umul_ppmm (n1, n0, d0, quot);
Packit 6c4009
		}
Packit 6c4009
Packit 6c4009
	    q_test:
Packit 6c4009
	      if (n1 > r || (n1 == r && n0 > 0))
Packit 6c4009
		{
Packit 6c4009
		  /* The estimated QUOT was too large.  */
Packit 6c4009
		  --quot;
Packit 6c4009
Packit 6c4009
		  sub_ddmmss (n1, n0, n1, n0, 0, d0);
Packit 6c4009
		  r += d1;
Packit 6c4009
		  if (r >= d1)	/* If not carry, test QUOT again.  */
Packit 6c4009
		    goto q_test;
Packit 6c4009
		}
Packit 6c4009
	      sub_ddmmss (n1, n0, r, 0, n1, n0);
Packit 6c4009
Packit 6c4009
	    have_quot:
Packit 6c4009
	      got_limb;
Packit 6c4009
	    }
Packit 6c4009
Packit 6c4009
	  return round_and_return (retval, exponent - 1, negative,
Packit 6c4009
				   quot, BITS_PER_MP_LIMB - 1 - used,
Packit 6c4009
				   more_bits || n1 != 0 || n0 != 0);
Packit 6c4009
	}
Packit 6c4009
      default:
Packit 6c4009
	{
Packit 6c4009
	  int i;
Packit 6c4009
	  mp_limb_t cy, dX, d1, n0, n1;
Packit 6c4009
	  mp_limb_t quot = 0;
Packit 6c4009
	  int used = 0;
Packit 6c4009
Packit 6c4009
	  dX = den[densize - 1];
Packit 6c4009
	  d1 = den[densize - 2];
Packit 6c4009
Packit 6c4009
	  /* The division does not work if the upper limb of the two-limb
Packit 6c4009
	     numerator is greater than the denominator.  */
Packit 6c4009
	  if (__mpn_cmp (num, &den[densize - numsize], numsize) > 0)
Packit 6c4009
	    num[numsize++] = 0;
Packit 6c4009
Packit 6c4009
	  if (numsize < densize)
Packit 6c4009
	    {
Packit 6c4009
	      mp_size_t empty = densize - numsize;
Packit 6c4009
	      int i;
Packit 6c4009
Packit 6c4009
	      if (bits <= 0)
Packit 6c4009
		exponent -= empty * BITS_PER_MP_LIMB;
Packit 6c4009
	      else
Packit 6c4009
		{
Packit 6c4009
		  if (bits + empty * BITS_PER_MP_LIMB <= MANT_DIG)
Packit 6c4009
		    {
Packit 6c4009
		      /* We make a difference here because the compiler
Packit 6c4009
			 cannot optimize the `else' case that good and
Packit 6c4009
			 this reflects all currently used FLOAT types
Packit 6c4009
			 and GMP implementations.  */
Packit 6c4009
#if RETURN_LIMB_SIZE <= 2
Packit 6c4009
		      assert (empty == 1);
Packit 6c4009
		      __mpn_lshift_1 (retval, RETURN_LIMB_SIZE,
Packit 6c4009
				      BITS_PER_MP_LIMB, 0);
Packit 6c4009
#else
Packit 6c4009
		      for (i = RETURN_LIMB_SIZE - 1; i >= empty; --i)
Packit 6c4009
			retval[i] = retval[i - empty];
Packit 6c4009
		      while (i >= 0)
Packit 6c4009
			retval[i--] = 0;
Packit 6c4009
#endif
Packit 6c4009
		    }
Packit 6c4009
		  else
Packit 6c4009
		    {
Packit 6c4009
		      used = MANT_DIG - bits;
Packit 6c4009
		      if (used >= BITS_PER_MP_LIMB)
Packit 6c4009
			{
Packit 6c4009
			  int i;
Packit 6c4009
			  (void) __mpn_lshift (&retval[used
Packit 6c4009
						       / BITS_PER_MP_LIMB],
Packit 6c4009
					       retval,
Packit 6c4009
					       (RETURN_LIMB_SIZE
Packit 6c4009
						- used / BITS_PER_MP_LIMB),
Packit 6c4009
					       used % BITS_PER_MP_LIMB);
Packit 6c4009
			  for (i = used / BITS_PER_MP_LIMB - 1; i >= 0; --i)
Packit 6c4009
			    retval[i] = 0;
Packit 6c4009
			}
Packit 6c4009
		      else if (used > 0)
Packit 6c4009
			__mpn_lshift_1 (retval, RETURN_LIMB_SIZE, used, 0);
Packit 6c4009
		    }
Packit 6c4009
		  bits += empty * BITS_PER_MP_LIMB;
Packit 6c4009
		}
Packit 6c4009
	      for (i = numsize; i > 0; --i)
Packit 6c4009
		num[i + empty] = num[i - 1];
Packit 6c4009
	      MPN_ZERO (num, empty + 1);
Packit 6c4009
	    }
Packit 6c4009
	  else
Packit 6c4009
	    {
Packit 6c4009
	      int i;
Packit 6c4009
	      assert (numsize == densize);
Packit 6c4009
	      for (i = numsize; i > 0; --i)
Packit 6c4009
		num[i] = num[i - 1];
Packit 6c4009
	      num[0] = 0;
Packit 6c4009
	    }
Packit 6c4009
Packit 6c4009
	  den[densize] = 0;
Packit 6c4009
	  n0 = num[densize];
Packit 6c4009
Packit 6c4009
	  while (bits <= MANT_DIG)
Packit 6c4009
	    {
Packit 6c4009
	      if (n0 == dX)
Packit 6c4009
		/* This might over-estimate QUOT, but it's probably not
Packit 6c4009
		   worth the extra code here to find out.  */
Packit 6c4009
		quot = ~(mp_limb_t) 0;
Packit 6c4009
	      else
Packit 6c4009
		{
Packit 6c4009
		  mp_limb_t r;
Packit 6c4009
Packit 6c4009
		  udiv_qrnnd (quot, r, n0, num[densize - 1], dX);
Packit 6c4009
		  umul_ppmm (n1, n0, d1, quot);
Packit 6c4009
Packit 6c4009
		  while (n1 > r || (n1 == r && n0 > num[densize - 2]))
Packit 6c4009
		    {
Packit 6c4009
		      --quot;
Packit 6c4009
		      r += dX;
Packit 6c4009
		      if (r < dX) /* I.e. "carry in previous addition?" */
Packit 6c4009
			break;
Packit 6c4009
		      n1 -= n0 < d1;
Packit 6c4009
		      n0 -= d1;
Packit 6c4009
		    }
Packit 6c4009
		}
Packit 6c4009
Packit 6c4009
	      /* Possible optimization: We already have (q * n0) and (1 * n1)
Packit 6c4009
		 after the calculation of QUOT.  Taking advantage of this, we
Packit 6c4009
		 could make this loop make two iterations less.  */
Packit 6c4009
Packit 6c4009
	      cy = __mpn_submul_1 (num, den, densize + 1, quot);
Packit 6c4009
Packit 6c4009
	      if (num[densize] != cy)
Packit 6c4009
		{
Packit 6c4009
		  cy = __mpn_add_n (num, num, den, densize);
Packit 6c4009
		  assert (cy != 0);
Packit 6c4009
		  --quot;
Packit 6c4009
		}
Packit 6c4009
	      n0 = num[densize] = num[densize - 1];
Packit 6c4009
	      for (i = densize - 1; i > 0; --i)
Packit 6c4009
		num[i] = num[i - 1];
Packit 6c4009
	      num[0] = 0;
Packit 6c4009
Packit 6c4009
	      got_limb;
Packit 6c4009
	    }
Packit 6c4009
Packit 6c4009
	  for (i = densize; i >= 0 && num[i] == 0; --i)
Packit 6c4009
	    ;
Packit 6c4009
	  return round_and_return (retval, exponent - 1, negative,
Packit 6c4009
				   quot, BITS_PER_MP_LIMB - 1 - used,
Packit 6c4009
				   more_bits || i >= 0);
Packit 6c4009
	}
Packit 6c4009
      }
Packit 6c4009
  }
Packit 6c4009
Packit 6c4009
  /* NOTREACHED */
Packit 6c4009
}
Packit 6c4009
#if defined _LIBC && !defined USE_WIDE_CHAR
Packit 6c4009
libc_hidden_def (____STRTOF_INTERNAL)
Packit 6c4009
#endif
Packit 6c4009

Packit 6c4009
/* External user entry point.  */
Packit 6c4009
Packit 6c4009
FLOAT
Packit 6c4009
#ifdef weak_function
Packit 6c4009
weak_function
Packit 6c4009
#endif
Packit 6c4009
__STRTOF (const STRING_TYPE *nptr, STRING_TYPE **endptr, locale_t loc)
Packit 6c4009
{
Packit 6c4009
  return ____STRTOF_INTERNAL (nptr, endptr, 0, loc);
Packit 6c4009
}
Packit 6c4009
#if defined _LIBC
Packit 6c4009
libc_hidden_def (__STRTOF)
Packit 6c4009
libc_hidden_ver (__STRTOF, STRTOF)
Packit 6c4009
#endif
Packit 6c4009
weak_alias (__STRTOF, STRTOF)
Packit 6c4009
Packit 6c4009
#ifdef LONG_DOUBLE_COMPAT
Packit 6c4009
# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_1)
Packit 6c4009
#  ifdef USE_WIDE_CHAR
Packit 6c4009
compat_symbol (libc, __wcstod_l, __wcstold_l, GLIBC_2_1);
Packit 6c4009
#  else
Packit 6c4009
compat_symbol (libc, __strtod_l, __strtold_l, GLIBC_2_1);
Packit 6c4009
#  endif
Packit 6c4009
# endif
Packit 6c4009
# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_3)
Packit 6c4009
#  ifdef USE_WIDE_CHAR
Packit 6c4009
compat_symbol (libc, wcstod_l, wcstold_l, GLIBC_2_3);
Packit 6c4009
#  else
Packit 6c4009
compat_symbol (libc, strtod_l, strtold_l, GLIBC_2_3);
Packit 6c4009
#  endif
Packit 6c4009
# endif
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#if BUILD_DOUBLE
Packit 6c4009
# if __HAVE_FLOAT64 && !__HAVE_DISTINCT_FLOAT64
Packit 6c4009
#  undef strtof64_l
Packit 6c4009
#  undef wcstof64_l
Packit 6c4009
#  ifdef USE_WIDE_CHAR
Packit 6c4009
weak_alias (wcstod_l, wcstof64_l)
Packit 6c4009
#  else
Packit 6c4009
weak_alias (strtod_l, strtof64_l)
Packit 6c4009
#  endif
Packit 6c4009
# endif
Packit 6c4009
# if __HAVE_FLOAT32X && !__HAVE_DISTINCT_FLOAT32X
Packit 6c4009
#  undef strtof32x_l
Packit 6c4009
#  undef wcstof32x_l
Packit 6c4009
#  ifdef USE_WIDE_CHAR
Packit 6c4009
weak_alias (wcstod_l, wcstof32x_l)
Packit 6c4009
#  else
Packit 6c4009
weak_alias (strtod_l, strtof32x_l)
Packit 6c4009
#  endif
Packit 6c4009
# endif
Packit 6c4009
#endif