(root)/
gawk-5.2.2/
missing_d/
strtod.c
       1  /*
       2   * gawk wrapper for strtod
       3   */
       4  /*
       5   * Stupid version of System V strtod(3) library routine.
       6   * Does no overflow/underflow checking.
       7   *
       8   * A real number is defined to be
       9   *	optional leading white space
      10   *	optional sign
      11   *	string of digits with optional decimal point
      12   *	optional 'e' or 'E'
      13   *		followed by optional sign or space
      14   *		followed by an integer
      15   *
      16   * if ptr is not NULL a pointer to the character terminating the
      17   * scan is returned in *ptr.  If no number formed, *ptr is set to str
      18   * and 0 is returned.
      19   *
      20   * For speed, we don't do the conversion ourselves.  Instead, we find
      21   * the end of the number and then call atof() to do the dirty work.
      22   * This bought us a 10% speedup on a sample program at uunet.uu.net.
      23   *
      24   * Fall 2000: Changed to enforce C89 semantics, so that 0x... returns 0.
      25   * C99 has hexadecimal floating point numbers.
      26   *
      27   * Summer 2001. Try to make it smarter, so that a string like "0000"
      28   * doesn't look like we failed. Sigh.
      29   *
      30   * Xmass 2002. Fix a bug in ptr determination, eg. for "0e0".
      31   *
      32   * Spring 2004. Update for I18N. Oh joy.
      33   */
      34  
      35  #if 0
      36  #include <ctype.h>
      37  #endif
      38  
      39  extern double atof();
      40  
      41  double
      42  gawk_strtod(s, ptr)
      43  const char *s;
      44  const char **ptr;
      45  {
      46  	const char *start = s;		/* save original start of string */
      47  	const char *begin = NULL;	/* where the number really begins */
      48  	int dig = 0;
      49  	int dig0 = 0;
      50  
      51  	/* optional white space */
      52  	while (isspace(*s))
      53  		s++;
      54  
      55  	begin = s;
      56  
      57  	/* optional sign */
      58  	if (*s == '+' || *s == '-')
      59  		s++;
      60  
      61  	/* string of digits with optional decimal point */
      62  	while (*s == '0') {
      63  		s++;
      64  		dig0++;
      65  	}
      66  	while (isdigit(*s)) {
      67  		s++;
      68  		dig++;
      69  	}
      70  
      71  	if (
      72  #if defined(HAVE_LOCALE_H)
      73  	loc.decimal_point != NULL && do_posix
      74  			? *s == loc.decimal_point[0]
      75  			: *s == '.'
      76  #else
      77  	*s == '.'
      78  #endif
      79  	) {
      80  		s++;
      81  		while (*s == '0') {
      82  			s++;
      83  			dig0++;
      84  		}
      85  		while (isdigit(*s)) {
      86  			s++;
      87  			dig++;
      88  		}
      89  	}
      90  
      91  	dig0 += dig;	/* any digit has appeared */
      92  
      93  	/*
      94   	 *	optional 'e' or 'E'
      95  	 *		if a digit (or at least zero) was seen
      96  	 *		followed by optional sign
      97  	 *		followed by an integer
      98  	 */
      99  	if (dig0
     100  	    && (*s == 'e' || *s == 'E')
     101  	    && (isdigit(s[1])
     102  	      || ((s[1] == '-' || s[1] == '+') && isdigit(s[2])))) {
     103  		s++;
     104  		if (*s == '+' || *s == '-')
     105  			s++;
     106  		while (isdigit(*s))
     107  			s++;
     108  	}
     109  
     110  	/* In case we haven't found a number, set ptr to start. */
     111  	if (ptr)
     112  		*ptr = (dig0 ? s : start);
     113  
     114  	/* Go for it. */
     115  	return (dig ? atof(begin) : 0.0);
     116  }
     117  
     118  #ifdef TEST
     119  int
     120  main(argc, argv)
     121  int argc;
     122  char **argv;
     123  {
     124  	double d;
     125  	char *p;
     126  
     127  	for (argc--, argv++; argc; argc--, argv++) {
     128  		d = strtod (*argv, & p);
     129  		printf ("%lf [%s]\n", d, p);
     130  	}
     131  
     132  	return 0;
     133  }
     134  #endif