diff --git a/README.md b/README.md index e0b70b6d..95e14618 100644 --- a/README.md +++ b/README.md @@ -43,12 +43,24 @@ The `type` field of `json_value` is one of: Compile-Time Options -------------------- +The following options should be specified both when building the library and when using it in your own project, and should be specified on the command line or in your project's settings, not in any source file. + -DJSON_TRACK_SOURCE Stores the source location (line and column number) inside each `json_value`. This is useful for application-level error reporting. + -Djson_int_t=long long + +This is the type of `u.integer`, and defaults to a 64-bit signed integer. + + -Djson_double_t=double + -DJSON_POW=my_pow + -DJSON_POW_HEADER="your_header.h" + +This is the type of `u.dbl` and defaults to `double`, but you may change it to `float` or `long double`. If you are compiling as C++, `std::pow` is used automatically. If you are compiling as C99 or later, the generic `pow` macro from `` is used. If you are compiling as C89 or C94, you need to define `JSON_POW` to an equivalent of C99's `powf` or `powl` for `float` and `long double` respectively, otherwise `pow` will be used which will use `double` only. If you do use a custom `JSON_POW` implementation, you should also define `JSON_POW_HEADER` to the header file that defines or declares the function specified by `JOSN_POW`. + Runtime Options --------------- diff --git a/json.c b/json.c index c44b84e5..3e345c8d 100644 --- a/json.c +++ b/json.c @@ -42,6 +42,24 @@ const struct _json_value json_value_none; #include #include +#ifndef JSON_POW + #ifdef __cplusplus + #include + #define JSON_POW std::pow + #else + #define JSON_POW pow + #ifdef __STDC_VERSION__ + #if __STDC_VERSION__ >= 199901L + #include + #endif + #endif + #endif +#else + #ifdef JSON_POW_HEADER + #include JSON_POW_HEADER + #endif +#endif + typedef unsigned int json_uchar; static unsigned char hex_value (json_char c) @@ -784,7 +802,7 @@ json_value * json_parse_ex (json_settings * settings, } top->type = json_double; - top->u.dbl = (double) top->u.integer; + top->u.dbl = (json_double_t) top->u.integer; num_digits = 0; continue; @@ -799,7 +817,7 @@ json_value * json_parse_ex (json_settings * settings, goto e_failed; } - top->u.dbl += ((double) num_fraction) / (pow (10.0, (double) num_digits)); + top->u.dbl += ((json_double_t) num_fraction) / (json_double_t) (JSON_POW ((json_double_t) 10.0, (json_double_t) num_digits)); } if (b == 'e' || b == 'E') @@ -809,7 +827,7 @@ json_value * json_parse_ex (json_settings * settings, if (top->type == json_integer) { top->type = json_double; - top->u.dbl = (double) top->u.integer; + top->u.dbl = (json_double_t) top->u.integer; } num_digits = 0; @@ -825,7 +843,7 @@ json_value * json_parse_ex (json_settings * settings, goto e_failed; } - top->u.dbl *= pow (10.0, (double) + top->u.dbl *= (json_double_t) JSON_POW ((json_double_t) 10.0, (json_double_t) (flags & flag_num_e_negative ? - num_e : num_e)); } diff --git a/json.h b/json.h index f6549ec4..59d828de 100644 --- a/json.h +++ b/json.h @@ -44,6 +44,10 @@ #endif #endif +#ifndef json_double_t + #define json_double_t double +#endif + #include #ifdef __cplusplus @@ -108,7 +112,7 @@ typedef struct _json_value { int boolean; json_int_t integer; - double dbl; + json_double_t dbl; struct { @@ -236,12 +240,12 @@ typedef struct _json_value return u.boolean != 0; } - inline operator double () const + inline operator json_double_t () const { switch (type) { case json_integer: - return (double) u.integer; + return (json_double_t) u.integer; case json_double: return u.dbl;