xref: /netbsd-src/external/gpl3/binutils.old/dist/libiberty/strtod.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
116dce513Schristos /* Implementation of strtod for systems with atof.
2*e992f068Schristos    Copyright (C) 1991-2022 Free Software Foundation, Inc.
316dce513Schristos 
416dce513Schristos This file is part of the libiberty library.  This library is free
516dce513Schristos software; you can redistribute it and/or modify it under the
616dce513Schristos terms of the GNU General Public License as published by the
716dce513Schristos Free Software Foundation; either version 2, or (at your option)
816dce513Schristos any later version.
916dce513Schristos 
1016dce513Schristos This library is distributed in the hope that it will be useful,
1116dce513Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
1216dce513Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1316dce513Schristos GNU General Public License for more details.
1416dce513Schristos 
1516dce513Schristos You should have received a copy of the GNU General Public License
1616dce513Schristos along with GNU CC; see the file COPYING.  If not, write to
1716dce513Schristos the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
1816dce513Schristos 
1916dce513Schristos As a special exception, if you link this library with files
2016dce513Schristos compiled with a GNU compiler to produce an executable, this does not cause
2116dce513Schristos the resulting executable to be covered by the GNU General Public License.
2216dce513Schristos This exception does not however invalidate any other reasons why
2316dce513Schristos the executable file might be covered by the GNU General Public License. */
2416dce513Schristos 
2516dce513Schristos /*
2616dce513Schristos 
2716dce513Schristos @deftypefn Supplemental double strtod (const char *@var{string}, @
2816dce513Schristos   char **@var{endptr})
2916dce513Schristos 
3016dce513Schristos This ISO C function converts the initial portion of @var{string} to a
3116dce513Schristos @code{double}.  If @var{endptr} is not @code{NULL}, a pointer to the
3216dce513Schristos character after the last character used in the conversion is stored in
3316dce513Schristos the location referenced by @var{endptr}.  If no conversion is
3416dce513Schristos performed, zero is returned and the value of @var{string} is stored in
3516dce513Schristos the location referenced by @var{endptr}.
3616dce513Schristos 
3716dce513Schristos @end deftypefn
3816dce513Schristos 
3916dce513Schristos */
4016dce513Schristos 
4116dce513Schristos #include "ansidecl.h"
4216dce513Schristos #include "safe-ctype.h"
4316dce513Schristos 
4416dce513Schristos extern double atof (const char *);
4516dce513Schristos 
4616dce513Schristos /* Disclaimer: this is currently just used by CHILL in GDB and therefore
4716dce513Schristos    has not been tested well.  It may have been tested for nothing except
4816dce513Schristos    that it compiles.  */
4916dce513Schristos 
5016dce513Schristos double
strtod(char * str,char ** ptr)5116dce513Schristos strtod (char *str, char **ptr)
5216dce513Schristos {
5316dce513Schristos   char *p;
5416dce513Schristos 
5516dce513Schristos   if (ptr == (char **)0)
5616dce513Schristos     return atof (str);
5716dce513Schristos 
5816dce513Schristos   p = str;
5916dce513Schristos 
6016dce513Schristos   while (ISSPACE (*p))
6116dce513Schristos     ++p;
6216dce513Schristos 
6316dce513Schristos   if (*p == '+' || *p == '-')
6416dce513Schristos     ++p;
6516dce513Schristos 
6616dce513Schristos   /* INF or INFINITY.  */
6716dce513Schristos   if ((p[0] == 'i' || p[0] == 'I')
6816dce513Schristos       && (p[1] == 'n' || p[1] == 'N')
6916dce513Schristos       && (p[2] == 'f' || p[2] == 'F'))
7016dce513Schristos     {
7116dce513Schristos       if ((p[3] == 'i' || p[3] == 'I')
7216dce513Schristos 	  && (p[4] == 'n' || p[4] == 'N')
7316dce513Schristos 	  && (p[5] == 'i' || p[5] == 'I')
7416dce513Schristos 	  && (p[6] == 't' || p[6] == 'T')
7516dce513Schristos 	  && (p[7] == 'y' || p[7] == 'Y'))
7616dce513Schristos 	{
7716dce513Schristos 	  *ptr = p + 8;
7816dce513Schristos 	  return atof (str);
7916dce513Schristos 	}
8016dce513Schristos       else
8116dce513Schristos 	{
8216dce513Schristos 	  *ptr = p + 3;
8316dce513Schristos 	  return atof (str);
8416dce513Schristos 	}
8516dce513Schristos     }
8616dce513Schristos 
8716dce513Schristos   /* NAN or NAN(foo).  */
8816dce513Schristos   if ((p[0] == 'n' || p[0] == 'N')
8916dce513Schristos       && (p[1] == 'a' || p[1] == 'A')
9016dce513Schristos       && (p[2] == 'n' || p[2] == 'N'))
9116dce513Schristos     {
9216dce513Schristos       p += 3;
9316dce513Schristos       if (*p == '(')
9416dce513Schristos 	{
9516dce513Schristos 	  ++p;
9616dce513Schristos 	  while (*p != '\0' && *p != ')')
9716dce513Schristos 	    ++p;
9816dce513Schristos 	  if (*p == ')')
9916dce513Schristos 	    ++p;
10016dce513Schristos 	}
10116dce513Schristos       *ptr = p;
10216dce513Schristos       return atof (str);
10316dce513Schristos     }
10416dce513Schristos 
10516dce513Schristos   /* digits, with 0 or 1 periods in it.  */
10616dce513Schristos   if (ISDIGIT (*p) || *p == '.')
10716dce513Schristos     {
10816dce513Schristos       int got_dot = 0;
10916dce513Schristos       while (ISDIGIT (*p) || (!got_dot && *p == '.'))
11016dce513Schristos 	{
11116dce513Schristos 	  if (*p == '.')
11216dce513Schristos 	    got_dot = 1;
11316dce513Schristos 	  ++p;
11416dce513Schristos 	}
11516dce513Schristos 
11616dce513Schristos       /* Exponent.  */
11716dce513Schristos       if (*p == 'e' || *p == 'E')
11816dce513Schristos 	{
11916dce513Schristos 	  int i;
12016dce513Schristos 	  i = 1;
12116dce513Schristos 	  if (p[i] == '+' || p[i] == '-')
12216dce513Schristos 	    ++i;
12316dce513Schristos 	  if (ISDIGIT (p[i]))
12416dce513Schristos 	    {
12516dce513Schristos 	      while (ISDIGIT (p[i]))
12616dce513Schristos 		++i;
12716dce513Schristos 	      *ptr = p + i;
12816dce513Schristos 	      return atof (str);
12916dce513Schristos 	    }
13016dce513Schristos 	}
13116dce513Schristos       *ptr = p;
13216dce513Schristos       return atof (str);
13316dce513Schristos     }
13416dce513Schristos   /* Didn't find any digits.  Doesn't look like a number.  */
13516dce513Schristos   *ptr = str;
13616dce513Schristos   return 0.0;
13716dce513Schristos }
138