diff options
Diffstat (limited to 'src/stdlib')
| -rw-r--r-- | src/stdlib/strtod.c | 11 | ||||
| -rw-r--r-- | src/stdlib/strtof.c | 11 | ||||
| -rw-r--r-- | src/stdlib/strtold.c | 103 | 
3 files changed, 31 insertions, 94 deletions
| diff --git a/src/stdlib/strtod.c b/src/stdlib/strtod.c index 388058fe..98b992a1 100644 --- a/src/stdlib/strtod.c +++ b/src/stdlib/strtod.c @@ -1,6 +1,15 @@  #include <stdlib.h> +#include "floatscan.h" +#include "stdio_impl.h"  double strtod(const char *s, char **p)  { -	return strtold(s, p); +	FILE f = { +		.buf = (void *)s, .rpos = (void *)s, +		.rend = (void *)-1, .lock = -1 +	}; +	off_t cnt; +	double y = __floatscan(&f, -1, 1, 1, &cnt); +	if (p) *p = (char *)s + cnt; +	return y;  } diff --git a/src/stdlib/strtof.c b/src/stdlib/strtof.c index 07b32df4..2dc349a9 100644 --- a/src/stdlib/strtof.c +++ b/src/stdlib/strtof.c @@ -1,6 +1,15 @@  #include <stdlib.h> +#include "floatscan.h" +#include "stdio_impl.h"  float strtof(const char *s, char **p)  { -	return strtold(s, p); +	FILE f = { +		.buf = (void *)s, .rpos = (void *)s, +		.rend = (void *)-1, .lock = -1 +	}; +	off_t cnt; +	float y = __floatscan(&f, -1, 0, 1, &cnt); +	if (p) *p = (char *)s + cnt; +	return y;  } diff --git a/src/stdlib/strtold.c b/src/stdlib/strtold.c index ec464c15..40ecc122 100644 --- a/src/stdlib/strtold.c +++ b/src/stdlib/strtold.c @@ -1,96 +1,15 @@  #include <stdlib.h> -#include <errno.h> -#include <ctype.h> +#include "floatscan.h" +#include "stdio_impl.h" -static int valid_exp(const unsigned char *s) +long double strtold(const char *s, char **p)  { -	return isdigit(*s) || ((s[0]=='+'||s[0]=='-') && isdigit(s[1])); -} - -long double strtold(const char *s1, char **p) -{ -	const unsigned char *s = (void *)s1; -	long double x = 0; -	long double frac; -	int sign = 0; -	int nonzero = 0; -	int radix = '.'; -	long e; -	int saved_errno = errno; - -	if (!p) p = (char **)&s1; - -	/* Initial whitespace */ -	for (; isspace(*s); s++); - -	/* Optional sign */ -	if (*s == '-') sign = *s++; -	else if (*s == '+') s++; - -	/* Handle infinities and NaNs. */ -	if ((s[0]|32)=='i' && (s[1]|32)=='n' && (s[2]|32)=='f') { -		*p = (char *)s + 3; -		return sign ? -1.0/0.0 : 1.0/0.0; -	} else if ((s[0]|32)=='n' && (s[1]|32)=='a' && (s[2]|32)=='n') { -		*p = (char *)s + 3; -		return 0.0/0.0; -	} - -	/* Possible hex float */ -	if (s[0]=='0' && (s[1]|32)=='x') { -		/* Mantissa must be non-degenerate */ -		if (!isxdigit(s[2]) && (s[2]!=radix || !isxdigit(s[3]))) { -			/* Decimal float 0, 'x' extraneous */ -			*p = (char *)++s; -			return 0; -		} -		/* We have a real hex float */ -		s += 2; -		for (; isxdigit(*s); s++) { -			x = 16*x + (isdigit(*s)?*s-'0':(*s|32)-'a'+10); -			if (*s!='0') nonzero=1; -		} -		if (*s == radix) { -			frac = 1.0/16.0; -			for (s++; isxdigit(*s); s++) { -				x += frac * (isdigit(*s)?*s-'0':(*s|32)-'a'+10); -				frac *= 1.0/16.0; -				if (*s!='0') nonzero=1; -			} -		} -		if ((*s|32) == 'p' && valid_exp(s+1)) { -			e = strtol((void *)(s+1), (void *)&s, 10); -			for (; e>0; e--) x *= 2.0; -			for (; e<0; e++) x *= 0.5; -		} -		goto finish; -	} - -	/* Mantissa must be non-degenerate */ -	if (!isdigit(s[0]) && (s[0]!=radix || !isdigit(s[1]))) { -		*p = (char *)s1; -		return 0; -	} - -	for (; isdigit(*s); s++) { -		x = 10*x + *s-'0'; -		if (*s!='0') nonzero=1; -	} -	if (*s == radix) { -		frac = 10.0; -		for (s++; isdigit(*s); s++) { -			x += (*s-'0') / frac; -			frac *= 10.0; -			if (*s!='0') nonzero=1; -		} -	} -	if ((*s|32)=='e' && valid_exp(s+1)) { -		e = strtol((void *)++s, (void *)&s, 10); -		for (; e>0; e--) x *= 10.0; -		for (; e<0; e++) x /= 10.0; -	} -finish: -	errno = ((nonzero && !x) || !(1.0/x)) ? ERANGE : saved_errno; -	*p = (char*)s; -	return sign ? -x : x; +	FILE f = { +		.buf = (void *)s, .rpos = (void *)s, +		.rend = (void *)-1, .lock = -1 +	}; +	off_t cnt; +	long double y = __floatscan(&f, -1, 2, 1, &cnt); +	if (p) *p = (char *)s + cnt; +	return y;  } | 
