From d107d9126551e61630da020c42a18dd866a6cde0 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Tue, 23 Sep 2014 18:49:16 -0400 Subject: [PATCH] safe_atof() is overkill. --- microjson.asc | 5 +- mjson.c | 208 +------------------------------------------------- 2 files changed, 5 insertions(+), 208 deletions(-) diff --git a/microjson.asc b/microjson.asc index a5a5e20..9409b6d 100644 --- a/microjson.asc +++ b/microjson.asc @@ -391,7 +391,10 @@ in a future release). There are separate entry points for beginning a parse of either JSON object or a JSON array. -JSON "float" quantities are actually stored as doubles. +JSON "float" quantities are actually stored as doubles. Note that +float parsing uses +atof(3)+ and is thus locale-sensitive - this +affects whether perid or comma is used as a decimal point. If in any +doubt, set the C numeric locale explicitly to match your data source. == Advanced Usage == diff --git a/mjson.c b/mjson.c index c3c0979..4ba83f3 100644 --- a/mjson.c +++ b/mjson.c @@ -109,212 +109,6 @@ static void json_trace(int errlevel, const char *fmt, ...) # define json_debug_trace(args) /*@i1@*/do { } while (0) #endif /* DEBUG_ENABLE */ -/* - * Berkeley implementation of strtod(), inlined to avoid locale problems - * with the decimal point and stripped down to an atof()-equivalent. - */ - -/*@-shiftimplementation +charint@*/ -static double safe_atof(const char *string) -/* Takes a decimal ASCII floating-point number, optionally - * preceded by white space. Must have form "-I.FE-X", - * where I is the integer part of the mantissa, F is - * the fractional part of the mantissa, and X is the - * exponent. Either of the signs may be "+", "-", or - * omitted. Either I or F may be omitted, or both. - * The decimal point isn't necessary unless F is - * present. The "E" may actually be an "e". E and X - * may both be omitted (but not just one). - */ -{ - static int maxExponent = 511; /* Largest possible base 10 exponent. Any - * exponent larger than this will already - * produce underflow or overflow, so there's - * no need to worry about additional digits. - */ - static double powersOf10[] = { /* Table giving binary powers of 10. Entry */ - 10., /* is 10^2^i. Used to convert decimal */ - 100., /* exponents into floating-point numbers. */ - 1.0e4, - 1.0e8, - 1.0e16, - 1.0e32, - 1.0e64, - 1.0e128, - 1.0e256 - }; - - bool sign, expSign = false; - double fraction, dblExp, *d; - register const char *p; - register int c; - int exp = 0; /* Exponent read from "EX" field. */ - int fracExp = 0; /* Exponent that derives from the fractional - * part. Under normal circumstatnces, it is - * the negative of the number of digits in F. - * However, if I is very long, the last digits - * of I get dropped (otherwise a long I with a - * large negative exponent could cause an - * unnecessary overflow on I alone). In this - * case, fracExp is incremented one for each - * dropped digit. */ - int mantSize; /* Number of digits in mantissa. */ - int decPt; /* Number of mantissa digits BEFORE decimal - * point. */ - const char *pExp; /* Temporarily holds location of exponent - * in string. */ - - /* - * Strip off leading blanks and check for a sign. - */ - - p = string; - while (isspace((unsigned char) *p)) { - p += 1; - } - if (*p == '-') { - sign = true; - p += 1; - } else { - if (*p == '+') { - p += 1; - } - sign = false; - } - - /* - * Count the number of digits in the mantissa (including the decimal - * point), and also locate the decimal point. - */ - - decPt = -1; - for (mantSize = 0; ; mantSize += 1) - { - c = *p; - if (!isdigit(c)) { - if ((c != '.') || (decPt >= 0)) { - break; - } - decPt = mantSize; - } - p += 1; - } - - /* - * Now suck up the digits in the mantissa. Use two integers to - * collect 9 digits each (this is faster than using floating-point). - * If the mantissa has more than 18 digits, ignore the extras, since - * they can't affect the value anyway. - */ - - pExp = p; - p -= mantSize; - if (decPt < 0) { - decPt = mantSize; - } else { - mantSize -= 1; /* One of the digits was the point. */ - } - if (mantSize > 18) { - fracExp = decPt - 18; - mantSize = 18; - } else { - fracExp = decPt - mantSize; - } - if (mantSize == 0) { - fraction = 0.0; - //p = string; - goto done; - } else { - int frac1, frac2; - frac1 = 0; - for ( ; mantSize > 9; mantSize -= 1) - { - c = *p; - p += 1; - if (c == '.') { - c = *p; - p += 1; - } - frac1 = 10*frac1 + (c - '0'); - } - frac2 = 0; - for (; mantSize > 0; mantSize -= 1) - { - c = *p; - p += 1; - if (c == '.') { - c = *p; - p += 1; - } - frac2 = 10*frac2 + (c - '0'); - } - fraction = (1.0e9 * frac1) + frac2; - } - - /* - * Skim off the exponent. - */ - - p = pExp; - if ((*p == 'E') || (*p == 'e')) { - p += 1; - if (*p == '-') { - expSign = true; - p += 1; - } else { - if (*p == '+') { - p += 1; - } - expSign = false; - } - while (isdigit((unsigned char) *p)) { - exp = exp * 10 + (*p - '0'); - p += 1; - } - } - if (expSign) { - exp = fracExp - exp; - } else { - exp = fracExp + exp; - } - - /* - * Generate a floating-point number that represents the exponent. - * Do this by processing the exponent one bit at a time to combine - * many powers of 2 of 10. Then combine the exponent with the - * fraction. - */ - - if (exp < 0) { - expSign = true; - exp = -exp; - } else { - expSign = false; - } - if (exp > maxExponent) { - exp = maxExponent; - errno = ERANGE; - } - dblExp = 1.0; - for (d = powersOf10; exp != 0; exp >>= 1, d += 1) { - if (exp & 01) { - dblExp *= *d; - } - } - if (expSign) { - fraction /= dblExp; - } else { - fraction *= dblExp; - } - -done: - if (sign) { - return -fraction; - } - return fraction; -} -/*@+shiftimplementation -charint@*/ - #define MONTHSPERYEAR 12 /* months per calendar year */ static time_t mkutctime(register struct tm * t) @@ -718,7 +512,7 @@ static int json_internal_read_object(const char *cp, break; case t_real: { - double tmp = safe_atof(valbuf); + double tmp = atof(valbuf); memcpy(lptr, &tmp, sizeof(double)); } break; -- 2.43.0