summaryrefslogtreecommitdiff
path: root/json.c
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2011-08-27 08:45:33 -0400
committerEric S. Raymond <esr@thyrsus.com>2011-08-27 08:45:33 -0400
commit35135b1f379a103e2bc236577358db060f6cf90d (patch)
tree48a13cbfeaed09b2dc0c5d621fd5269f3f491143 /json.c
parent774853128108460f83e98b76f981459d6b583410 (diff)
downloadgpsd-35135b1f379a103e2bc236577358db060f6cf90d.tar.gz
Avoid locale problems in the NMEA driver, too.
Diffstat (limited to 'json.c')
-rw-r--r--json.c210
1 files changed, 2 insertions, 208 deletions
diff --git a/json.c b/json.c
index 8c8e7cca..becbfe1f 100644
--- a/json.c
+++ b/json.c
@@ -63,14 +63,13 @@ PERMISSIONS
#include <stdlib.h>
#include <stdbool.h>
#include <stdarg.h>
-#include <errno.h>
#include <ctype.h>
#include "gpsd_config.h" /* for strlcpy() prototype */
#ifdef SOCKET_EXPORT_ENABLE
#include "json.h"
-#include "gps.h" /* only for timestamp_t prototype */
+#include "gps.h" /* for safe_atof() & timestamp_t prototype */
#ifdef CLIENTDEBUG_ENABLE
static int debuglevel = 0;
@@ -148,211 +147,6 @@ static /*@null@*/ char *json_target_address(const struct json_attr_t *cursor,
return targetaddr;
}
-
-/*
- * Berkeley implementation of strtod(), inlined to avoid locale problems
- * with the decimal point an stripped dowb to an atof()-equivalent.
- */
-
-static double c_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
- };
-
- int 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(*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(*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;
-}
-
/*@-immediatetrans -dependenttrans +usereleased +compdef@*/
static int json_internal_read_object(const char *cp,
@@ -650,7 +444,7 @@ static int json_internal_read_object(const char *cp,
*((double *)lptr) = iso8601_to_unix(valbuf);
break;
case t_real:
- *((double *)lptr) = c_atof(valbuf);
+ *((double *)lptr) = safe_atof(valbuf);
break;
case t_string:
if (parent != NULL