Blame missing_d/strtod.c

Packit 575503
/*
Packit 575503
 * gawk wrapper for strtod
Packit 575503
 */
Packit 575503
/*
Packit 575503
 * Stupid version of System V strtod(3) library routine.
Packit 575503
 * Does no overflow/underflow checking.
Packit 575503
 *
Packit 575503
 * A real number is defined to be
Packit 575503
 *	optional leading white space
Packit 575503
 *	optional sign
Packit 575503
 *	string of digits with optional decimal point
Packit 575503
 *	optional 'e' or 'E'
Packit 575503
 *		followed by optional sign or space
Packit 575503
 *		followed by an integer
Packit 575503
 *
Packit 575503
 * if ptr is not NULL a pointer to the character terminating the
Packit 575503
 * scan is returned in *ptr.  If no number formed, *ptr is set to str
Packit 575503
 * and 0 is returned.
Packit 575503
 *
Packit 575503
 * For speed, we don't do the conversion ourselves.  Instead, we find
Packit 575503
 * the end of the number and then call atof() to do the dirty work.
Packit 575503
 * This bought us a 10% speedup on a sample program at uunet.uu.net.
Packit 575503
 *
Packit 575503
 * Fall 2000: Changed to enforce C89 semantics, so that 0x... returns 0.
Packit 575503
 * C99 has hexadecimal floating point numbers.
Packit 575503
 *
Packit 575503
 * Summer 2001. Try to make it smarter, so that a string like "0000"
Packit 575503
 * doesn't look like we failed. Sigh.
Packit 575503
 *
Packit 575503
 * Xmass 2002. Fix a bug in ptr determination, eg. for "0e0".
Packit 575503
 *
Packit 575503
 * Spring 2004. Update for I18N. Oh joy.
Packit 575503
 */
Packit 575503
Packit 575503
#if 0
Packit 575503
#include <ctype.h>
Packit 575503
#endif
Packit 575503
Packit 575503
extern double atof();
Packit 575503
Packit 575503
double
Packit 575503
gawk_strtod(s, ptr)
Packit 575503
const char *s;
Packit 575503
const char **ptr;
Packit 575503
{
Packit 575503
	const char *start = s;		/* save original start of string */
Packit 575503
	const char *begin = NULL;	/* where the number really begins */
Packit 575503
	int dig = 0;
Packit 575503
	int dig0 = 0;
Packit 575503
Packit 575503
	/* optional white space */
Packit 575503
	while (isspace(*s))
Packit 575503
		s++;
Packit 575503
Packit 575503
	begin = s;
Packit 575503
Packit 575503
	/* optional sign */
Packit 575503
	if (*s == '+' || *s == '-')
Packit 575503
		s++;
Packit 575503
Packit 575503
	/* string of digits with optional decimal point */
Packit 575503
	while (*s == '0') {
Packit 575503
		s++;
Packit 575503
		dig0++;
Packit 575503
	}
Packit 575503
	while (isdigit(*s)) {
Packit 575503
		s++;
Packit 575503
		dig++;
Packit 575503
	}
Packit 575503
Packit 575503
	if (
Packit 575503
#if defined(HAVE_LOCALE_H)
Packit 575503
	loc.decimal_point != NULL && do_posix
Packit 575503
			? *s == loc.decimal_point[0]
Packit 575503
			: *s == '.'
Packit 575503
#else
Packit 575503
	*s == '.'
Packit 575503
#endif
Packit 575503
	) {
Packit 575503
		s++;
Packit 575503
		while (*s == '0') {
Packit 575503
			s++;
Packit 575503
			dig0++;
Packit 575503
		}
Packit 575503
		while (isdigit(*s)) {
Packit 575503
			s++;
Packit 575503
			dig++;
Packit 575503
		}
Packit 575503
	}
Packit 575503
Packit 575503
	dig0 += dig;	/* any digit has appeared */
Packit 575503
Packit 575503
	/*
Packit 575503
 	 *	optional 'e' or 'E'
Packit 575503
	 *		if a digit (or at least zero) was seen
Packit 575503
	 *		followed by optional sign
Packit 575503
	 *		followed by an integer
Packit 575503
	 */
Packit 575503
	if (dig0
Packit 575503
	    && (*s == 'e' || *s == 'E')
Packit 575503
	    && (isdigit(s[1])
Packit 575503
	      || ((s[1] == '-' || s[1] == '+') && isdigit(s[2])))) {
Packit 575503
		s++;
Packit 575503
		if (*s == '+' || *s == '-')
Packit 575503
			s++;
Packit 575503
		while (isdigit(*s))
Packit 575503
			s++;
Packit 575503
	}
Packit 575503
Packit 575503
	/* In case we haven't found a number, set ptr to start. */
Packit 575503
	if (ptr)
Packit 575503
		*ptr = (dig0 ? s : start);
Packit 575503
Packit 575503
	/* Go for it. */
Packit 575503
	return (dig ? atof(begin) : 0.0);
Packit 575503
}
Packit 575503
Packit 575503
#ifdef TEST
Packit 575503
int
Packit 575503
main(argc, argv)
Packit 575503
int argc;
Packit 575503
char **argv;
Packit 575503
{
Packit 575503
	double d;
Packit 575503
	char *p;
Packit 575503
Packit 575503
	for (argc--, argv++; argc; argc--, argv++) {
Packit 575503
		d = strtod (*argv, & p);
Packit 575503
		printf ("%lf [%s]\n", d, p);
Packit 575503
	}
Packit 575503
Packit 575503
	return 0;
Packit 575503
}
Packit 575503
#endif