12a6b7db3Sskrll /* Implementation of strtod for systems with atof.
2*f22f0ef4Schristos    Copyright (C) 1991-2022 Free Software Foundation, Inc.
32a6b7db3Sskrll 
42a6b7db3Sskrll This file is part of the libiberty library.  This library is free
52a6b7db3Sskrll software; you can redistribute it and/or modify it under the
62a6b7db3Sskrll terms of the GNU General Public License as published by the
72a6b7db3Sskrll Free Software Foundation; either version 2, or (at your option)
82a6b7db3Sskrll any later version.
92a6b7db3Sskrll 
102a6b7db3Sskrll This library is distributed in the hope that it will be useful,
112a6b7db3Sskrll but WITHOUT ANY WARRANTY; without even the implied warranty of
122a6b7db3Sskrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
132a6b7db3Sskrll GNU General Public License for more details.
142a6b7db3Sskrll 
152a6b7db3Sskrll You should have received a copy of the GNU General Public License
162a6b7db3Sskrll along with GNU CC; see the file COPYING.  If not, write to
172a6b7db3Sskrll the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
182a6b7db3Sskrll 
192a6b7db3Sskrll As a special exception, if you link this library with files
202a6b7db3Sskrll compiled with a GNU compiler to produce an executable, this does not cause
212a6b7db3Sskrll the resulting executable to be covered by the GNU General Public License.
222a6b7db3Sskrll This exception does not however invalidate any other reasons why
232a6b7db3Sskrll the executable file might be covered by the GNU General Public License. */
242a6b7db3Sskrll 
252a6b7db3Sskrll /*
262a6b7db3Sskrll 
2705caefcfSchristos @deftypefn Supplemental double strtod (const char *@var{string}, @
2805caefcfSchristos   char **@var{endptr})
292a6b7db3Sskrll 
302a6b7db3Sskrll This ISO C function converts the initial portion of @var{string} to a
312a6b7db3Sskrll @code{double}.  If @var{endptr} is not @code{NULL}, a pointer to the
322a6b7db3Sskrll character after the last character used in the conversion is stored in
332a6b7db3Sskrll the location referenced by @var{endptr}.  If no conversion is
342a6b7db3Sskrll performed, zero is returned and the value of @var{string} is stored in
352a6b7db3Sskrll the location referenced by @var{endptr}.
362a6b7db3Sskrll 
372a6b7db3Sskrll @end deftypefn
382a6b7db3Sskrll 
392a6b7db3Sskrll */
402a6b7db3Sskrll 
412a6b7db3Sskrll #include "ansidecl.h"
422a6b7db3Sskrll #include "safe-ctype.h"
432a6b7db3Sskrll 
442a6b7db3Sskrll extern double atof (const char *);
452a6b7db3Sskrll 
462a6b7db3Sskrll /* Disclaimer: this is currently just used by CHILL in GDB and therefore
472a6b7db3Sskrll    has not been tested well.  It may have been tested for nothing except
482a6b7db3Sskrll    that it compiles.  */
492a6b7db3Sskrll 
502a6b7db3Sskrll double
strtod(char * str,char ** ptr)512a6b7db3Sskrll strtod (char *str, char **ptr)
522a6b7db3Sskrll {
532a6b7db3Sskrll   char *p;
542a6b7db3Sskrll 
552a6b7db3Sskrll   if (ptr == (char **)0)
562a6b7db3Sskrll     return atof (str);
572a6b7db3Sskrll 
582a6b7db3Sskrll   p = str;
592a6b7db3Sskrll 
602a6b7db3Sskrll   while (ISSPACE (*p))
612a6b7db3Sskrll     ++p;
622a6b7db3Sskrll 
632a6b7db3Sskrll   if (*p == '+' || *p == '-')
642a6b7db3Sskrll     ++p;
652a6b7db3Sskrll 
662a6b7db3Sskrll   /* INF or INFINITY.  */
672a6b7db3Sskrll   if ((p[0] == 'i' || p[0] == 'I')
682a6b7db3Sskrll       && (p[1] == 'n' || p[1] == 'N')
692a6b7db3Sskrll       && (p[2] == 'f' || p[2] == 'F'))
702a6b7db3Sskrll     {
712a6b7db3Sskrll       if ((p[3] == 'i' || p[3] == 'I')
722a6b7db3Sskrll 	  && (p[4] == 'n' || p[4] == 'N')
732a6b7db3Sskrll 	  && (p[5] == 'i' || p[5] == 'I')
742a6b7db3Sskrll 	  && (p[6] == 't' || p[6] == 'T')
752a6b7db3Sskrll 	  && (p[7] == 'y' || p[7] == 'Y'))
762a6b7db3Sskrll 	{
772a6b7db3Sskrll 	  *ptr = p + 8;
782a6b7db3Sskrll 	  return atof (str);
792a6b7db3Sskrll 	}
802a6b7db3Sskrll       else
812a6b7db3Sskrll 	{
822a6b7db3Sskrll 	  *ptr = p + 3;
832a6b7db3Sskrll 	  return atof (str);
842a6b7db3Sskrll 	}
852a6b7db3Sskrll     }
862a6b7db3Sskrll 
872a6b7db3Sskrll   /* NAN or NAN(foo).  */
882a6b7db3Sskrll   if ((p[0] == 'n' || p[0] == 'N')
892a6b7db3Sskrll       && (p[1] == 'a' || p[1] == 'A')
902a6b7db3Sskrll       && (p[2] == 'n' || p[2] == 'N'))
912a6b7db3Sskrll     {
922a6b7db3Sskrll       p += 3;
932a6b7db3Sskrll       if (*p == '(')
942a6b7db3Sskrll 	{
952a6b7db3Sskrll 	  ++p;
962a6b7db3Sskrll 	  while (*p != '\0' && *p != ')')
972a6b7db3Sskrll 	    ++p;
982a6b7db3Sskrll 	  if (*p == ')')
992a6b7db3Sskrll 	    ++p;
1002a6b7db3Sskrll 	}
1012a6b7db3Sskrll       *ptr = p;
1022a6b7db3Sskrll       return atof (str);
1032a6b7db3Sskrll     }
1042a6b7db3Sskrll 
1052a6b7db3Sskrll   /* digits, with 0 or 1 periods in it.  */
1062a6b7db3Sskrll   if (ISDIGIT (*p) || *p == '.')
1072a6b7db3Sskrll     {
1082a6b7db3Sskrll       int got_dot = 0;
1092a6b7db3Sskrll       while (ISDIGIT (*p) || (!got_dot && *p == '.'))
1102a6b7db3Sskrll 	{
1112a6b7db3Sskrll 	  if (*p == '.')
1122a6b7db3Sskrll 	    got_dot = 1;
1132a6b7db3Sskrll 	  ++p;
1142a6b7db3Sskrll 	}
1152a6b7db3Sskrll 
1162a6b7db3Sskrll       /* Exponent.  */
1172a6b7db3Sskrll       if (*p == 'e' || *p == 'E')
1182a6b7db3Sskrll 	{
1192a6b7db3Sskrll 	  int i;
1202a6b7db3Sskrll 	  i = 1;
1212a6b7db3Sskrll 	  if (p[i] == '+' || p[i] == '-')
1222a6b7db3Sskrll 	    ++i;
1232a6b7db3Sskrll 	  if (ISDIGIT (p[i]))
1242a6b7db3Sskrll 	    {
1252a6b7db3Sskrll 	      while (ISDIGIT (p[i]))
1262a6b7db3Sskrll 		++i;
1272a6b7db3Sskrll 	      *ptr = p + i;
1282a6b7db3Sskrll 	      return atof (str);
1292a6b7db3Sskrll 	    }
1302a6b7db3Sskrll 	}
1312a6b7db3Sskrll       *ptr = p;
1322a6b7db3Sskrll       return atof (str);
1332a6b7db3Sskrll     }
1342a6b7db3Sskrll   /* Didn't find any digits.  Doesn't look like a number.  */
1352a6b7db3Sskrll   *ptr = str;
1362a6b7db3Sskrll   return 0.0;
1372a6b7db3Sskrll }
138