(root)/
coreutils-9.4/
lib/
cl-strtod.c
       1  /* Convert string to double in the current locale, falling back on the C locale.
       2  
       3     Copyright 2019-2023 Free Software Foundation, Inc.
       4  
       5     This program is free software: you can redistribute it and/or modify
       6     it under the terms of the GNU General Public License as published by
       7     the Free Software Foundation; either version 3 of the License, or
       8     (at your option) any later version.
       9  
      10     This program is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13     GNU General Public License for more details.
      14  
      15     You should have received a copy of the GNU General Public License
      16     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      17  
      18  /* Written by Paul Eggert.  */
      19  
      20  #include <config.h>
      21  
      22  #include "cl-strtod.h"
      23  
      24  #include <c-strtod.h>
      25  
      26  #include <errno.h>
      27  #include <stdlib.h>
      28  
      29  #if LONG
      30  # define CL_STRTOD cl_strtold
      31  # define DOUBLE long double
      32  # define C_STRTOD c_strtold
      33  # define STRTOD strtold
      34  #else
      35  # define CL_STRTOD cl_strtod
      36  # define DOUBLE double
      37  # define C_STRTOD c_strtod
      38  # define STRTOD strtod
      39  #endif
      40  
      41  /* This function acts like strtod or strtold, except that it falls
      42     back on the C locale if the initial prefix is not parsable in
      43     the current locale.  If the prefix is parsable in both locales,
      44     it uses the longer parse, breaking ties in favor of the current locale.
      45  
      46     Parse the initial prefix of NPTR as a floating-point number in the
      47     current locale or in the C locale (preferring the locale that
      48     yields the longer parse, or the current locale if there is a tie).
      49     If ENDPTR is non-null, set *ENDPTR to the first unused byte, or to
      50     NPTR if the prefix cannot be parsed.
      51  
      52     If successful, return a number without changing errno.
      53     If the prefix cannot be parsed, return 0 and possibly set errno to EINVAL.
      54     If the number overflows, return an extreme value and set errno to ERANGE.
      55     If the number underflows, return a value close to 0 and set errno to ERANGE.
      56     If there is some other error, return 0 and set errno.  */
      57  
      58  DOUBLE
      59  CL_STRTOD (char const *nptr, char **restrict endptr)
      60  {
      61    char *end;
      62    DOUBLE d = STRTOD (nptr, &end);
      63    if (*end)
      64      {
      65        int strtod_errno = errno;
      66        char *c_end;
      67        DOUBLE c = C_STRTOD (nptr, &c_end);
      68        if (end < c_end)
      69          d = c, end = c_end;
      70        else
      71          errno = strtod_errno;
      72      }
      73    if (endptr)
      74      *endptr = end;
      75    return d;
      76  }