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