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