socsvn commit: r268941 - soc2014/pedrosouza/lua_loader/head/sys/boot/lua/src

pedrosouza at FreeBSD.org pedrosouza at FreeBSD.org
Mon Jun 2 01:00:57 UTC 2014


Author: pedrosouza
Date: Mon Jun  2 01:00:55 2014
New Revision: 268941
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=268941

Log:
  Implemented number parsing for lua

Modified:
  soc2014/pedrosouza/lua_loader/head/sys/boot/lua/src/lstd.c

Modified: soc2014/pedrosouza/lua_loader/head/sys/boot/lua/src/lstd.c
==============================================================================
--- soc2014/pedrosouza/lua_loader/head/sys/boot/lua/src/lstd.c	Mon Jun  2 00:21:42 2014	(r268940)
+++ soc2014/pedrosouza/lua_loader/head/sys/boot/lua/src/lstd.c	Mon Jun  2 01:00:55 2014	(r268941)
@@ -49,6 +49,96 @@
 double
 strtod(const char *string, char **endPtr)
 {
-	printf("strtod not implemented!\n");
-	return 0.;
+	int sign = 0;
+	int exp_sign = 0;
+	int has_num = 0;
+	int has_frac = 0;
+	int has_exp = 0;
+	unsigned long long num = 0;
+	unsigned long long exp = 0;
+
+	double frac = 0;
+	double fm = 0.1;
+	double exp_m = 1;
+	double ret = 0;
+	
+	const char *ptr = string;
+
+	while (isspace(*ptr)) ++ptr;
+	
+	if (*ptr == '-') 
+	{
+		sign = 1;
+		++ptr;
+	} else if (*ptr == '+')
+		++ptr;
+
+	while (isdigit(*ptr))
+	{
+		num *= 10;
+		num += *ptr - '0';
+		++ptr;
+		++has_num;
+	}
+
+	if (*ptr == '.')
+	{
+		++ptr;
+		while (isdigit(*ptr))
+		{
+			frac += (double)(*ptr - '0') * fm;
+			fm *= 0.1;
+			++ptr;
+			++has_frac;
+		}
+	}
+
+	if (has_frac == 0 && has_num == 0)
+	{
+		if (*endPtr)
+			*endPtr = (char*)string;
+		return 0.;
+	}
+
+	ret = (double)num;
+	ret += frac;
+
+	if (*ptr == 'e' || *ptr == 'E')
+	{
+		if (*endPtr)
+			*endPtr = (char*)ptr;
+		++ptr;
+		if (*ptr == '-') 
+		{
+			exp_sign = 1;
+			++ptr;
+		} else if (*ptr == '+')
+			++ptr;
+
+		while (isdigit(*ptr))
+		{
+			exp *= 10;
+			exp += *ptr - '0';
+			++ptr;
+			++has_exp;
+		}
+		if (has_exp == 0)
+			return ret;
+	}
+
+	if (*endPtr)
+		*endPtr = (char*)ptr;
+
+	if (has_exp)
+	{
+		while (exp--)
+			exp_m *= 10;
+		if (exp_sign)
+			exp_m = 1./exp_m;
+
+	}
+	if (sign)
+		ret = -ret;
+
+	return ret * exp_m;
 }


More information about the svn-soc-all mailing list