webmcp
changeset 428:52ebde158c92
Fixed minor glitch regarding floating point numbers (e.g. 0.009) in JSON encoder; Distinguish between integers and floats in JSON encoder if Lua version >= 5.3
author | jbe |
---|---|
date | Thu Jan 14 17:40:49 2016 +0100 (2016-01-14) |
parents | f0303fca9218 |
children | 387a303918a6 |
files | libraries/json/json.c |
line diff
1.1 --- a/libraries/json/json.c Thu Jan 14 17:13:48 2016 +0100 1.2 +++ b/libraries/json/json.c Thu Jan 14 17:40:49 2016 +0100 1.3 @@ -1037,7 +1037,11 @@ 1.4 int pretty; // pretty printing on? (i.e. printing with indentation) 1.5 luaL_Buffer buf; // Lua buffer containing result string 1.6 lua_Number num; // number to encode 1.7 - char numstr[21]; // encoded number (sign, zero, point, 17 significant digits, and terminating NULL byte) 1.8 + char numstr[80]; // encoded number 1.9 + // (21 chars needed for sign, zero, point, 17 significant digits, and NULL byte) 1.10 + // (21 chars needed for sign, 19 digits INT64, and NULL byte) 1.11 + // (80 chars needed for sign, 78 digits INT256, and NULL byte) 1.12 + // (NOTE: we don't know the size of intmax_t and thus use 80) 1.13 const char *str; // string to encode 1.14 size_t strlen; // length of string to encode 1.15 size_t strpos ; // position in string or position of current key 1.16 @@ -1101,6 +1105,14 @@ 1.17 break; 1.18 // value to encode is of type number: 1.19 case LUA_TNUMBER: 1.20 +#if LUA_VERSION_NUM >= 503 1.21 + // handle integers: 1.22 + if (lua_isinteger(L, json_export_value_idx)) { 1.23 + sprintf(numstr, "%ji", (intmax_t)lua_tointeger(L, json_export_value_idx)); 1.24 + luaL_addstring(&buf, numstr); 1.25 + break; 1.26 + } 1.27 +#endif 1.28 // convert value to double precision number: 1.29 num = lua_tonumber(L, json_export_value_idx); 1.30 // throw error if number is not-a-number: 1.31 @@ -1108,10 +1120,21 @@ 1.32 // throw error if number is positive or negative infinity: 1.33 if (isinf(num)) return luaL_error(L, "JSON export not possible for infinite numbers"); 1.34 // determine necessary precision to represent double precision floating point number: 1.35 - sprintf(numstr, "%.16g", num); 1.36 + sprintf(numstr, "%.15g", num); // NOTE: e.g. 0.009 should not be 0.008999999999999999 1.37 + if (strtod(numstr, NULL) != num) sprintf(numstr, "%.16g", num); 1.38 if (strtod(numstr, NULL) != num) sprintf(numstr, "%.17g", num); 1.39 // add string encoding of the number to the output buffer: 1.40 luaL_addstring(&buf, numstr); 1.41 +#if LUA_VERSION_NUM >= 503 1.42 + // enforce trailing ".0" for floats unless exponential notation was chosen: 1.43 + { 1.44 + char *p; 1.45 + if (numstr[0] == '-' || numstr[0] == '+') p = numstr+1; 1.46 + else p = numstr; 1.47 + for (; *p; p++) if (*p < '0' || *p > '9') break; 1.48 + if (!*p) luaL_addstring(&buf, ".0"); 1.49 + } 1.50 +#endif 1.51 break; 1.52 // value to encode is of type boolean: 1.53 case LUA_TBOOLEAN: