/* Copyright (C) 1991-1992, 1997, 1999, 2003, 2006, 2008-2020 Free Software
   Foundation, Inc.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */

#if ! defined USE_LONG_DOUBLE
# include <config.h>
#endif

/* Specification.  */
#include <stdlib.h>

#include <ctype.h>      /* isspace() */
#include <errno.h>
#include <float.h>      /* {DBL,LDBL}_{MIN,MAX} */
#include <limits.h>     /* LONG_{MIN,MAX} */
#include <locale.h>     /* localeconv() */
#include <math.h>       /* NAN */
#include <stdbool.h>
#include <stdio.h>      /* sprintf() */
#include <string.h>     /* strdup() */
#if HAVE_NL_LANGINFO
# include <langinfo.h>
#endif

#include "c-ctype.h"

#undef MIN
#undef MAX
#ifdef USE_LONG_DOUBLE
# define STRTOD strtold
# define LDEXP ldexpl
# if defined __hpux && defined __hppa
   /* We cannot call strtold on HP-UX/hppa, because its return type is a struct,
      not a 'long double'.  */
#  define HAVE_UNDERLYING_STRTOD 0
# elif STRTOLD_HAS_UNDERFLOW_BUG
   /* strtold would not set errno=ERANGE upon underflow.  */
#  define HAVE_UNDERLYING_STRTOD 0
# else
#  define HAVE_UNDERLYING_STRTOD HAVE_STRTOLD
# endif
# define DOUBLE long double
# define MIN LDBL_MIN
# define MAX LDBL_MAX
# define L_(literal) literal##L
#else
# define STRTOD strtod
# define LDEXP ldexp
# define HAVE_UNDERLYING_STRTOD 1
# define DOUBLE double
# define MIN DBL_MIN
# define MAX DBL_MAX
# define L_(literal) literal
#endif

#if (defined USE_LONG_DOUBLE ? HAVE_LDEXPM_IN_LIBC : HAVE_LDEXP_IN_LIBC)
# define USE_LDEXP 1
#else
# define USE_LDEXP 0
#endif

/* Return true if C is a space in the current locale, avoiding
   problems with signed char and isspace.  */
static bool
locale_isspace (char c)
{
  unsigned char uc = c;
  return isspace (uc) != 0;
}

/* Determine the decimal-point character according to the current locale.  */
static char
decimal_point_char (void)
{
  const char *point;
  /* Determine it in a multithread-safe way.  We know nl_langinfo is
     multithread-safe on glibc systems and Mac OS X systems, but is not required
     to be multithread-safe by POSIX.  sprintf(), however, is multithread-safe.
     localeconv() is rarely multithread-safe.  */
#if HAVE_NL_LANGINFO && (__GLIBC__ || defined __UCLIBC__ || (defined __APPLE__ && defined __MACH__))
  point = nl_langinfo (RADIXCHAR);
#elif 1
  char pointbuf[5];
  sprintf (pointbuf, "%#.0f", 1.0);
  point = &pointbuf[1];
#else
  point = localeconv () -> decimal_point;
#endif
  /* The decimal point is always a single byte: either '.' or ','.  */
  return (point[0] != '\0' ? point[0] : '.');
}

#if !USE_LDEXP
 #undef LDEXP
 #define LDEXP dummy_ldexp
 /* A dummy definition that will never be invoked.  */
 static DOUBLE LDEXP (DOUBLE x _GL_UNUSED, int exponent _GL_UNUSED)
 {
   abort ();
   return L_(0.0);
 }
#endif

/* Return X * BASE**EXPONENT.  Return an extreme value and set errno
   to ERANGE if underflow or overflow occurs.  */
static DOUBLE
scale_radix_exp (DOUBLE x, int radix, long int exponent)
{
  /* If RADIX == 10, this code is neither precise nor fast; it is
     merely a straightforward and relatively portable approximation.
     If N == 2, this code is precise on a radix-2 implementation,
     albeit perhaps not fast if ldexp is not in libc.  */

  long int e = exponent;

  if (USE_LDEXP && radix == 2)
    return LDEXP (x, e < INT_MIN ? INT_MIN : INT_MAX < e ? INT_MAX : e);
  else
    {
      DOUBLE r = x;

      if (r != 0)
        {
          if (e < 0)
            {
              while (e++ != 0)
                {
                  r /= radix;
                  if (r == 0 && x != 0)
                    {
                      errno = ERANGE;
                      break;
                    }
                }
            }
          else
            {
              while (e-- != 0)
                {
                  if (r < -MAX / radix)
                    {
                      errno = ERANGE;
                      return -HUGE_VAL;
                    }
                  else if (MAX / radix < r)
                    {
                      errno = ERANGE;
                      return HUGE_VAL;
                    }
                  else
                    r *= radix;
                }
            }
        }

      return r;
    }
}

/* Parse a number at NPTR; this is a bit like strtol (NPTR, ENDPTR)
   except there are no leading spaces or signs or "0x", and ENDPTR is
   nonnull.  The number uses a base BASE (either 10 or 16) fraction, a
   radix RADIX (either 10 or 2) exponent, and exponent character
   EXPCHAR.  BASE is RADIX**RADIX_MULTIPLIER.  */
static DOUBLE
parse_number (const char *nptr,
              int base, int radix, int radix_multiplier, char radixchar,
              char expchar,
              char **endptr)
{
  const char *s = nptr;
  const char *digits_start;
  const char *digits_end;
  const char *radixchar_ptr;
  long int exponent;
  DOUBLE num;

  /* First, determine the start and end of the digit sequence.  */
  digits_start = s;
  radixchar_ptr = NULL;
  for (;; ++s)
    {
      if (base == 16 ? c_isxdigit (*s) : c_isdigit (*s))
        ;
      else if (radixchar_ptr == NULL && *s == radixchar)
        {
          /* Record that we have found the decimal point.  */
          radixchar_ptr = s;
        }
      else
        /* Any other character terminates the digit sequence.  */
        break;
    }
  digits_end = s;
  /* Now radixchar_ptr == NULL or
     digits_start <= radixchar_ptr < digits_end.  */

  if (false)
    { /* Unoptimized.  */
      exponent =
        (radixchar_ptr != NULL
         ? - (long int) (digits_end - radixchar_ptr - 1)
         : 0);
    }
  else
    { /* Remove trailing zero digits.  This reduces rounding errors for
         inputs such as 1.0000000000 or 10000000000e-10.  */
      while (digits_end > digits_start)
        {
          if (digits_end - 1 == radixchar_ptr || *(digits_end - 1) == '0')
            digits_end--;
          else
            break;
        }
      exponent =
        (radixchar_ptr != NULL
         ? (digits_end > radixchar_ptr
            ? - (long int) (digits_end - radixchar_ptr - 1)
            : (long int) (radixchar_ptr - digits_end))
         : (long int) (s - digits_end));
    }

  /* Then, convert the digit sequence to a number.  */
  {
    const char *dp;
    num = 0;
    for (dp = digits_start; dp < digits_end; dp++)
      if (dp != radixchar_ptr)
        {
          int digit;

          /* Make sure that multiplication by BASE will not overflow.  */
          if (!(num <= MAX / base))
            {
              /* The value of the digit and all subsequent digits don't matter,
                 since we have already gotten as many digits as can be
                 represented in a 'DOUBLE'.  This doesn't necessarily mean that
                 the result will overflow: The exponent may reduce it to within
                 range.  */
              exponent +=
                (digits_end - dp)
                - (radixchar_ptr >= dp && radixchar_ptr < digits_end ? 1 : 0);
              break;
            }

          /* Eat the next digit.  */
          if (c_isdigit (*dp))
            digit = *dp - '0';
          else if (base == 16 && c_isxdigit (*dp))
            digit = c_tolower (*dp) - ('a' - 10);
          else
            abort ();
          num = num * base + digit;
        }
  }

  exponent = exponent * radix_multiplier;

  /* Finally, parse the exponent.  */
  if (c_tolower (*s) == expchar && ! locale_isspace (s[1]))
    {
      /* Add any given exponent to the implicit one.  */
      int saved_errno = errno;
      char *end;
      long int value = strtol (s + 1, &end, 10);
      errno = saved_errno;

      if (s + 1 != end)
        {
          /* Skip past the exponent, and add in the implicit exponent,
             resulting in an extreme value on overflow.  */
          s = end;
          exponent =
            (exponent < 0
             ? (value < LONG_MIN - exponent ? LONG_MIN : exponent + value)
             : (LONG_MAX - exponent < value ? LONG_MAX : exponent + value));
        }
    }

  *endptr = (char *) s;
  return scale_radix_exp (num, radix, exponent);
}

/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
   ICC 10.0 has a bug when optimizing the expression -zero.
   The expression -MIN * MIN does not work when cross-compiling
   to PowerPC on Mac OS X 10.5.  */
static DOUBLE
minus_zero (void)
{
#if defined __hpux || defined __sgi || defined __ICC
  return -MIN * MIN;
#else
  return -0.0;
#endif
}

/* Convert NPTR to a DOUBLE.  If ENDPTR is not NULL, a pointer to the
   character after the last one used in the number is put in *ENDPTR.  */
DOUBLE
STRTOD (const char *nptr, char **endptr)
#if HAVE_UNDERLYING_STRTOD
# ifdef USE_LONG_DOUBLE
#  undef strtold
# else
#  undef strtod
# endif
#else
# undef STRTOD
# define STRTOD(NPTR,ENDPTR) \
   parse_number (NPTR, 10, 10, 1, radixchar, 'e', ENDPTR)
#endif
/* From here on, STRTOD refers to the underlying implementation.  It needs
   to handle only finite unsigned decimal numbers with non-null ENDPTR.  */
{
  char radixchar;
  bool negative = false;

  /* The number so far.  */
  DOUBLE num;

  const char *s = nptr;
  const char *end;
  char *endbuf;
  int saved_errno = errno;

  radixchar = decimal_point_char ();

  /* Eat whitespace.  */
  while (locale_isspace (*s))
    ++s;

  /* Get the sign.  */
  negative = *s == '-';
  if (*s == '-' || *s == '+')
    ++s;

  num = STRTOD (s, &endbuf);
  end = endbuf;

  if (c_isdigit (s[*s == radixchar]))
    {
      /* If a hex float was converted incorrectly, do it ourselves.
         If the string starts with "0x" but does not contain digits,
         consume the "0" ourselves.  If a hex float is followed by a
         'p' but no exponent, then adjust the end pointer.  */
      if (*s == '0' && c_tolower (s[1]) == 'x')
        {
          if (! c_isxdigit (s[2 + (s[2] == radixchar)]))
            {
              end = s + 1;

              /* strtod() on z/OS returns ERANGE for "0x".  */
              errno = saved_errno;
            }
          else if (end <= s + 2)
            {
              num = parse_number (s + 2, 16, 2, 4, radixchar, 'p', &endbuf);
              end = endbuf;
            }
          else
            {
              const char *p = s + 2;
              while (p < end && c_tolower (*p) != 'p')
                p++;
              if (p < end && ! c_isdigit (p[1 + (p[1] == '-' || p[1] == '+')]))
                {
                  char *dup = strdup (s);
                  errno = saved_errno;
                  if (!dup)
                    {
                      /* Not really our day, is it.  Rounding errors are
                         better than outright failure.  */
                      num =
                        parse_number (s + 2, 16, 2, 4, radixchar, 'p', &endbuf);
                    }
                  else
                    {
                      dup[p - s] = '\0';
                      num = STRTOD (dup, &endbuf);
                      saved_errno = errno;
                      free (dup);
                      errno = saved_errno;
                    }
                  end = p;
                }
            }
        }
      else
        {
          /* If "1e 1" was misparsed as 10.0 instead of 1.0, re-do the
             underlying STRTOD on a copy of the original string
             truncated to avoid the bug.  */
          const char *e = s + 1;
          while (e < end && c_tolower (*e) != 'e')
            e++;
          if (e < end && ! c_isdigit (e[1 + (e[1] == '-' || e[1] == '+')]))
            {
              char *dup = strdup (s);
              errno = saved_errno;
              if (!dup)
                {
                  /* Not really our day, is it.  Rounding errors are
                     better than outright failure.  */
                  num = parse_number (s, 10, 10, 1, radixchar, 'e', &endbuf);
                }
              else
                {
                  dup[e - s] = '\0';
                  num = STRTOD (dup, &endbuf);
                  saved_errno = errno;
                  free (dup);
                  errno = saved_errno;
                }
              end = e;
            }
        }

      s = end;
    }

  /* Check for infinities and NaNs.  */
  else if (c_tolower (*s) == 'i'
           && c_tolower (s[1]) == 'n'
           && c_tolower (s[2]) == 'f')
    {
      s += 3;
      if (c_tolower (*s) == 'i'
          && c_tolower (s[1]) == 'n'
          && c_tolower (s[2]) == 'i'
          && c_tolower (s[3]) == 't'
          && c_tolower (s[4]) == 'y')
        s += 5;
      num = HUGE_VAL;
      errno = saved_errno;
    }
  else if (c_tolower (*s) == 'n'
           && c_tolower (s[1]) == 'a'
           && c_tolower (s[2]) == 'n')
    {
      s += 3;
      if (*s == '(')
        {
          const char *p = s + 1;
          while (c_isalnum (*p))
            p++;
          if (*p == ')')
            s = p + 1;
        }

      /* If the underlying implementation misparsed the NaN, assume
         its result is incorrect, and return a NaN.  Normally it's
         better to use the underlying implementation's result, since a
         nice implementation populates the bits of the NaN according
         to interpreting n-char-sequence as a hexadecimal number.  */
      if (s != end || num == num)
        num = NAN;
      errno = saved_errno;
    }
  else
    {
      /* No conversion could be performed.  */
      errno = EINVAL;
      s = nptr;
    }

  if (endptr != NULL)
    *endptr = (char *) s;
  /* Special case -0.0, since at least ICC miscompiles negation.  We
     can't use copysign(), as that drags in -lm on some platforms.  */
  if (!num && negative)
    return minus_zero ();
  return negative ? -num : num;
}
