133965Sjdp/* Implementation of strtod for systems with atof. 2104834Sobrien Copyright (C) 1991, 1995, 2002 Free Software Foundation, Inc. 333965Sjdp 433965SjdpThis file is part of the libiberty library. This library is free 533965Sjdpsoftware; you can redistribute it and/or modify it under the 633965Sjdpterms of the GNU General Public License as published by the 733965SjdpFree Software Foundation; either version 2, or (at your option) 833965Sjdpany later version. 933965Sjdp 1033965SjdpThis library is distributed in the hope that it will be useful, 1133965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 1233965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1333965SjdpGNU General Public License for more details. 1433965Sjdp 1533965SjdpYou should have received a copy of the GNU General Public License 1633965Sjdpalong with GNU CC; see the file COPYING. If not, write to 17218822Sdimthe Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. 1833965Sjdp 1933965SjdpAs a special exception, if you link this library with files 2033965Sjdpcompiled with a GNU compiler to produce an executable, this does not cause 2133965Sjdpthe resulting executable to be covered by the GNU General Public License. 2233965SjdpThis exception does not however invalidate any other reasons why 2333965Sjdpthe executable file might be covered by the GNU General Public License. */ 2433965Sjdp 2589857Sobrien/* 2689857Sobrien 2789857Sobrien@deftypefn Supplemental double strtod (const char *@var{string}, char **@var{endptr}) 2889857Sobrien 2989857SobrienThis ISO C function converts the initial portion of @var{string} to a 3089857Sobrien@code{double}. If @var{endptr} is not @code{NULL}, a pointer to the 3189857Sobriencharacter after the last character used in the conversion is stored in 3289857Sobrienthe location referenced by @var{endptr}. If no conversion is 3389857Sobrienperformed, zero is returned and the value of @var{string} is stored in 3489857Sobrienthe location referenced by @var{endptr}. 3589857Sobrien 3689857Sobrien@end deftypefn 3789857Sobrien 3889857Sobrien*/ 3989857Sobrien 4077298Sobrien#include "ansidecl.h" 4177298Sobrien#include "safe-ctype.h" 4233965Sjdp 43218822Sdimextern double atof (const char *); 4433965Sjdp 4533965Sjdp/* Disclaimer: this is currently just used by CHILL in GDB and therefore 4633965Sjdp has not been tested well. It may have been tested for nothing except 4733965Sjdp that it compiles. */ 4833965Sjdp 4933965Sjdpdouble 50218822Sdimstrtod (char *str, char **ptr) 5133965Sjdp{ 5233965Sjdp char *p; 5333965Sjdp 5433965Sjdp if (ptr == (char **)0) 5533965Sjdp return atof (str); 5633965Sjdp 5733965Sjdp p = str; 5833965Sjdp 5977298Sobrien while (ISSPACE (*p)) 6033965Sjdp ++p; 6133965Sjdp 6233965Sjdp if (*p == '+' || *p == '-') 6333965Sjdp ++p; 6433965Sjdp 6533965Sjdp /* INF or INFINITY. */ 6633965Sjdp if ((p[0] == 'i' || p[0] == 'I') 6733965Sjdp && (p[1] == 'n' || p[1] == 'N') 6833965Sjdp && (p[2] == 'f' || p[2] == 'F')) 6933965Sjdp { 7033965Sjdp if ((p[3] == 'i' || p[3] == 'I') 7133965Sjdp && (p[4] == 'n' || p[4] == 'N') 7233965Sjdp && (p[5] == 'i' || p[5] == 'I') 7333965Sjdp && (p[6] == 't' || p[6] == 'T') 7433965Sjdp && (p[7] == 'y' || p[7] == 'Y')) 7533965Sjdp { 76104834Sobrien *ptr = p + 8; 7733965Sjdp return atof (str); 7833965Sjdp } 7933965Sjdp else 8033965Sjdp { 8133965Sjdp *ptr = p + 3; 8233965Sjdp return atof (str); 8333965Sjdp } 8433965Sjdp } 8533965Sjdp 8633965Sjdp /* NAN or NAN(foo). */ 8733965Sjdp if ((p[0] == 'n' || p[0] == 'N') 8833965Sjdp && (p[1] == 'a' || p[1] == 'A') 8933965Sjdp && (p[2] == 'n' || p[2] == 'N')) 9033965Sjdp { 9133965Sjdp p += 3; 9233965Sjdp if (*p == '(') 9333965Sjdp { 9433965Sjdp ++p; 9533965Sjdp while (*p != '\0' && *p != ')') 9633965Sjdp ++p; 9733965Sjdp if (*p == ')') 9833965Sjdp ++p; 9933965Sjdp } 10033965Sjdp *ptr = p; 10133965Sjdp return atof (str); 10233965Sjdp } 10333965Sjdp 10433965Sjdp /* digits, with 0 or 1 periods in it. */ 10577298Sobrien if (ISDIGIT (*p) || *p == '.') 10633965Sjdp { 10733965Sjdp int got_dot = 0; 10877298Sobrien while (ISDIGIT (*p) || (!got_dot && *p == '.')) 10933965Sjdp { 11033965Sjdp if (*p == '.') 11133965Sjdp got_dot = 1; 11233965Sjdp ++p; 11333965Sjdp } 11433965Sjdp 11533965Sjdp /* Exponent. */ 11633965Sjdp if (*p == 'e' || *p == 'E') 11733965Sjdp { 11833965Sjdp int i; 11933965Sjdp i = 1; 12033965Sjdp if (p[i] == '+' || p[i] == '-') 12133965Sjdp ++i; 12277298Sobrien if (ISDIGIT (p[i])) 12333965Sjdp { 12477298Sobrien while (ISDIGIT (p[i])) 12533965Sjdp ++i; 12633965Sjdp *ptr = p + i; 12733965Sjdp return atof (str); 12833965Sjdp } 12933965Sjdp } 13033965Sjdp *ptr = p; 13133965Sjdp return atof (str); 13233965Sjdp } 13333965Sjdp /* Didn't find any digits. Doesn't look like a number. */ 13433965Sjdp *ptr = str; 13533965Sjdp return 0.0; 13633965Sjdp} 137