1169695Skan/* Implementation of strtod for systems with atof.
2169695Skan   Copyright (C) 1991, 1995, 2002 Free Software Foundation, Inc.
3169695Skan
4169695SkanThis file is part of the libiberty library.  This library is free
5169695Skansoftware; you can redistribute it and/or modify it under the
6169695Skanterms of the GNU General Public License as published by the
7169695SkanFree Software Foundation; either version 2, or (at your option)
8169695Skanany later version.
9169695Skan
10169695SkanThis library is distributed in the hope that it will be useful,
11169695Skanbut WITHOUT ANY WARRANTY; without even the implied warranty of
12169695SkanMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13169695SkanGNU General Public License for more details.
14169695Skan
15169695SkanYou should have received a copy of the GNU General Public License
16169695Skanalong with GNU CC; see the file COPYING.  If not, write to
17169695Skanthe Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
18169695Skan
19169695SkanAs a special exception, if you link this library with files
20169695Skancompiled with a GNU compiler to produce an executable, this does not cause
21169695Skanthe resulting executable to be covered by the GNU General Public License.
22169695SkanThis exception does not however invalidate any other reasons why
23169695Skanthe executable file might be covered by the GNU General Public License. */
24169695Skan
25169695Skan/*
26169695Skan
27169695Skan@deftypefn Supplemental double strtod (const char *@var{string}, char **@var{endptr})
28169695Skan
29169695SkanThis ISO C function converts the initial portion of @var{string} to a
30169695Skan@code{double}.  If @var{endptr} is not @code{NULL}, a pointer to the
31169695Skancharacter after the last character used in the conversion is stored in
32169695Skanthe location referenced by @var{endptr}.  If no conversion is
33169695Skanperformed, zero is returned and the value of @var{string} is stored in
34169695Skanthe location referenced by @var{endptr}.
35169695Skan
36169695Skan@end deftypefn
37169695Skan
38169695Skan*/
39169695Skan
40169695Skan#include "ansidecl.h"
41169695Skan#include "safe-ctype.h"
42169695Skan
43169695Skanextern double atof (const char *);
44169695Skan
45169695Skan/* Disclaimer: this is currently just used by CHILL in GDB and therefore
46169695Skan   has not been tested well.  It may have been tested for nothing except
47169695Skan   that it compiles.  */
48169695Skan
49169695Skandouble
50169695Skanstrtod (char *str, char **ptr)
51169695Skan{
52169695Skan  char *p;
53169695Skan
54169695Skan  if (ptr == (char **)0)
55169695Skan    return atof (str);
56169695Skan
57169695Skan  p = str;
58169695Skan
59169695Skan  while (ISSPACE (*p))
60169695Skan    ++p;
61169695Skan
62169695Skan  if (*p == '+' || *p == '-')
63169695Skan    ++p;
64169695Skan
65169695Skan  /* INF or INFINITY.  */
66169695Skan  if ((p[0] == 'i' || p[0] == 'I')
67169695Skan      && (p[1] == 'n' || p[1] == 'N')
68169695Skan      && (p[2] == 'f' || p[2] == 'F'))
69169695Skan    {
70169695Skan      if ((p[3] == 'i' || p[3] == 'I')
71169695Skan	  && (p[4] == 'n' || p[4] == 'N')
72169695Skan	  && (p[5] == 'i' || p[5] == 'I')
73169695Skan	  && (p[6] == 't' || p[6] == 'T')
74169695Skan	  && (p[7] == 'y' || p[7] == 'Y'))
75169695Skan	{
76169695Skan	  *ptr = p + 8;
77169695Skan	  return atof (str);
78169695Skan	}
79169695Skan      else
80169695Skan	{
81169695Skan	  *ptr = p + 3;
82169695Skan	  return atof (str);
83169695Skan	}
84169695Skan    }
85169695Skan
86169695Skan  /* NAN or NAN(foo).  */
87169695Skan  if ((p[0] == 'n' || p[0] == 'N')
88169695Skan      && (p[1] == 'a' || p[1] == 'A')
89169695Skan      && (p[2] == 'n' || p[2] == 'N'))
90169695Skan    {
91169695Skan      p += 3;
92169695Skan      if (*p == '(')
93169695Skan	{
94169695Skan	  ++p;
95169695Skan	  while (*p != '\0' && *p != ')')
96169695Skan	    ++p;
97169695Skan	  if (*p == ')')
98169695Skan	    ++p;
99169695Skan	}
100169695Skan      *ptr = p;
101169695Skan      return atof (str);
102169695Skan    }
103169695Skan
104169695Skan  /* digits, with 0 or 1 periods in it.  */
105169695Skan  if (ISDIGIT (*p) || *p == '.')
106169695Skan    {
107169695Skan      int got_dot = 0;
108169695Skan      while (ISDIGIT (*p) || (!got_dot && *p == '.'))
109169695Skan	{
110169695Skan	  if (*p == '.')
111169695Skan	    got_dot = 1;
112169695Skan	  ++p;
113169695Skan	}
114169695Skan
115169695Skan      /* Exponent.  */
116169695Skan      if (*p == 'e' || *p == 'E')
117169695Skan	{
118169695Skan	  int i;
119169695Skan	  i = 1;
120169695Skan	  if (p[i] == '+' || p[i] == '-')
121169695Skan	    ++i;
122169695Skan	  if (ISDIGIT (p[i]))
123169695Skan	    {
124169695Skan	      while (ISDIGIT (p[i]))
125169695Skan		++i;
126169695Skan	      *ptr = p + i;
127169695Skan	      return atof (str);
128169695Skan	    }
129169695Skan	}
130169695Skan      *ptr = p;
131169695Skan      return atof (str);
132169695Skan    }
133169695Skan  /* Didn't find any digits.  Doesn't look like a number.  */
134169695Skan  *ptr = str;
135169695Skan  return 0.0;
136169695Skan}
137