]> thyrsus.com Git - microjson.git/commitdiff
safe_atof() is overkill.
authorEric S. Raymond <esr@thyrsus.com>
Tue, 23 Sep 2014 22:49:16 +0000 (18:49 -0400)
committerEric S. Raymond <esr@thyrsus.com>
Tue, 23 Sep 2014 23:52:41 +0000 (19:52 -0400)
microjson.asc
mjson.c

index a5a5e2091d64e9ca2ca1860488b15867651a9998..9409b6dedb4821acf5245df8da32a870af8d1b6c 100644 (file)
@@ -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 c3c097913a759da021d3e135b773d10f412669cf..4ba83f383782f81c6c32b9b29f50baafa7f16967 100644 (file)
--- 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;