Separate integers and real numbers
This commit is contained in:
parent
39802813f4
commit
b724c2b122
18
src/dump.c
18
src/dump.c
@ -106,12 +106,26 @@ static int do_dump(const json_t *json, uint32_t flags, int depth,
|
||||
case JSON_FALSE:
|
||||
return dump("false", 5, data);
|
||||
|
||||
case JSON_NUMBER:
|
||||
case JSON_INTEGER:
|
||||
{
|
||||
char *buffer;
|
||||
int size, ret;
|
||||
|
||||
size = asprintf(&buffer, "%.17f", json_number_value(json));
|
||||
size = asprintf(&buffer, "%d", json_integer_value(json));
|
||||
if(size == -1)
|
||||
return -1;
|
||||
|
||||
ret = dump(buffer, size, data);
|
||||
free(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
case JSON_REAL:
|
||||
{
|
||||
char *buffer;
|
||||
int size, ret;
|
||||
|
||||
size = asprintf(&buffer, "%.17f", json_real_value(json));
|
||||
if(size == -1)
|
||||
return -1;
|
||||
|
||||
|
@ -10,7 +10,8 @@ typedef enum {
|
||||
JSON_OBJECT,
|
||||
JSON_ARRAY,
|
||||
JSON_STRING,
|
||||
JSON_NUMBER,
|
||||
JSON_INTEGER,
|
||||
JSON_REAL,
|
||||
JSON_TRUE,
|
||||
JSON_FALSE,
|
||||
JSON_NULL
|
||||
@ -25,7 +26,9 @@ typedef struct {
|
||||
#define json_is_object(json) (json && json_typeof(json) == JSON_OBJECT)
|
||||
#define json_is_array(json) (json && json_typeof(json) == JSON_ARRAY)
|
||||
#define json_is_string(json) (json && json_typeof(json) == JSON_STRING)
|
||||
#define json_is_number(json) (json && json_typeof(json) == JSON_NUMBER)
|
||||
#define json_is_integer(json) (json && json_typeof(json) == JSON_INTEGER)
|
||||
#define json_is_real(json) (json && json_typeof(json) == JSON_REAL)
|
||||
#define json_is_number(json) (json_is_integer(json) || json_is_real(json))
|
||||
#define json_is_true(json) (json && json_typeof(json) == JSON_TRUE)
|
||||
#define json_is_false(json) (json && json_typeof(json) == JSON_FALSE)
|
||||
#define json_is_null(json) (json && json_typeof(json) == JSON_NULL)
|
||||
@ -35,7 +38,8 @@ typedef struct {
|
||||
json_t *json_object(void);
|
||||
json_t *json_array(void);
|
||||
json_t *json_string(const char *value);
|
||||
json_t *json_number(double value);
|
||||
json_t *json_integer(int value);
|
||||
json_t *json_real(double value);
|
||||
json_t *json_true(void);
|
||||
json_t *json_false(void);
|
||||
json_t *json_null(void);
|
||||
@ -75,6 +79,8 @@ int json_array_set(json_t *array, unsigned int index, json_t *value);
|
||||
int json_array_append(json_t *array, json_t *value);
|
||||
|
||||
const char *json_string_value(const json_t *json);
|
||||
int json_integer_value(const json_t *json);
|
||||
double json_real_value(const json_t *json);
|
||||
double json_number_value(const json_t *json);
|
||||
|
||||
|
||||
|
36
src/load.c
36
src/load.c
@ -15,10 +15,11 @@
|
||||
#define JSON_TOKEN_INVALID -1
|
||||
#define JSON_TOKEN_EOF 0
|
||||
#define JSON_TOKEN_STRING 256
|
||||
#define JSON_TOKEN_NUMBER 257
|
||||
#define JSON_TOKEN_TRUE 258
|
||||
#define JSON_TOKEN_FALSE 259
|
||||
#define JSON_TOKEN_NULL 260
|
||||
#define JSON_TOKEN_INTEGER 257
|
||||
#define JSON_TOKEN_REAL 258
|
||||
#define JSON_TOKEN_TRUE 259
|
||||
#define JSON_TOKEN_FALSE 260
|
||||
#define JSON_TOKEN_NULL 261
|
||||
|
||||
typedef struct {
|
||||
const char *input;
|
||||
@ -27,7 +28,8 @@ typedef struct {
|
||||
int line, column;
|
||||
union {
|
||||
char *string;
|
||||
double number;
|
||||
int integer;
|
||||
double real;
|
||||
} value;
|
||||
} json_lex;
|
||||
|
||||
@ -176,7 +178,16 @@ static void json_scan_number(json_lex *lex)
|
||||
p++;
|
||||
}
|
||||
|
||||
if(*p == '.') {
|
||||
if(*p != '.') {
|
||||
lex->token = JSON_TOKEN_INTEGER;
|
||||
|
||||
lex->value.integer = strtol(lex->start, &end, 10);
|
||||
assert(end == p);
|
||||
|
||||
lex->input = p;
|
||||
return;
|
||||
}
|
||||
else /* *p == '.' */ {
|
||||
p++;
|
||||
if(!isdigit(*(p++)))
|
||||
goto out;
|
||||
@ -197,9 +208,9 @@ static void json_scan_number(json_lex *lex)
|
||||
p++;
|
||||
}
|
||||
|
||||
lex->token = JSON_TOKEN_NUMBER;
|
||||
lex->token = JSON_TOKEN_REAL;
|
||||
|
||||
lex->value.number = strtod(lex->start, &end);
|
||||
lex->value.real = strtod(lex->start, &end);
|
||||
assert(end == p);
|
||||
|
||||
out:
|
||||
@ -402,8 +413,13 @@ static json_t *json_parse(json_lex *lex, json_error_t *error)
|
||||
break;
|
||||
}
|
||||
|
||||
case JSON_TOKEN_NUMBER: {
|
||||
json = json_number(lex->value.number);
|
||||
case JSON_TOKEN_INTEGER: {
|
||||
json = json_integer(lex->value.integer);
|
||||
break;
|
||||
}
|
||||
|
||||
case JSON_TOKEN_REAL: {
|
||||
json = json_real(lex->value.real);
|
||||
break;
|
||||
}
|
||||
|
||||
|
89
src/value.c
89
src/value.c
@ -29,12 +29,18 @@ typedef struct {
|
||||
typedef struct {
|
||||
json_t json;
|
||||
double value;
|
||||
} json_number_t;
|
||||
} json_real_t;
|
||||
|
||||
typedef struct {
|
||||
json_t json;
|
||||
int value;
|
||||
} json_integer_t;
|
||||
|
||||
#define json_to_object(json_) container_of(json_, json_object_t, json)
|
||||
#define json_to_array(json_) container_of(json_, json_array_t, json)
|
||||
#define json_to_string(json_) container_of(json_, json_string_t, json)
|
||||
#define json_to_number(json_) container_of(json_, json_number_t, json)
|
||||
#define json_to_real(json_) container_of(json_, json_real_t, json)
|
||||
#define json_to_integer(json_) container_of(json_, json_integer_t, json)
|
||||
|
||||
static inline void json_init(json_t *json, json_type type)
|
||||
{
|
||||
@ -274,15 +280,58 @@ static void json_delete_string(json_string_t *string)
|
||||
free(string);
|
||||
}
|
||||
|
||||
json_t *json_number(double value)
|
||||
{
|
||||
json_number_t *number = malloc(sizeof(json_number_t));
|
||||
if(!number)
|
||||
return NULL;
|
||||
json_init(&number->json, JSON_NUMBER);
|
||||
|
||||
number->value = value;
|
||||
return &number->json;
|
||||
/*** integer ***/
|
||||
|
||||
json_t *json_integer(int value)
|
||||
{
|
||||
json_integer_t *integer = malloc(sizeof(json_integer_t));
|
||||
if(!integer)
|
||||
return NULL;
|
||||
json_init(&integer->json, JSON_INTEGER);
|
||||
|
||||
integer->value = value;
|
||||
return &integer->json;
|
||||
}
|
||||
|
||||
int json_integer_value(const json_t *json)
|
||||
{
|
||||
if(!json_is_integer(json))
|
||||
return 0;
|
||||
|
||||
return json_to_integer(json)->value;
|
||||
}
|
||||
|
||||
static void json_delete_integer(json_integer_t *integer)
|
||||
{
|
||||
free(integer);
|
||||
}
|
||||
|
||||
|
||||
/*** real ***/
|
||||
|
||||
json_t *json_real(double value)
|
||||
{
|
||||
json_real_t *real = malloc(sizeof(json_real_t));
|
||||
if(!real)
|
||||
return NULL;
|
||||
json_init(&real->json, JSON_REAL);
|
||||
|
||||
real->value = value;
|
||||
return &real->json;
|
||||
}
|
||||
|
||||
double json_real_value(const json_t *json)
|
||||
{
|
||||
if(!json_is_real(json))
|
||||
return 0;
|
||||
|
||||
return json_to_real(json)->value;
|
||||
}
|
||||
|
||||
static void json_delete_real (json_real_t *real)
|
||||
{
|
||||
free(real);
|
||||
}
|
||||
|
||||
|
||||
@ -290,15 +339,12 @@ json_t *json_number(double value)
|
||||
|
||||
double json_number_value(const json_t *json)
|
||||
{
|
||||
if(!json_is_number(json))
|
||||
if(json_is_integer(json))
|
||||
return json_integer_value(json);
|
||||
else if(json_is_real(json))
|
||||
return json_real_value(json);
|
||||
else
|
||||
return 0.0;
|
||||
|
||||
return json_to_number(json)->value;
|
||||
}
|
||||
|
||||
static void json_delete_number(json_number_t *number)
|
||||
{
|
||||
free(number);
|
||||
}
|
||||
|
||||
|
||||
@ -347,8 +393,11 @@ void json_delete(json_t *json)
|
||||
else if(json_is_string(json))
|
||||
json_delete_string(json_to_string(json));
|
||||
|
||||
else if(json_is_number(json))
|
||||
json_delete_number(json_to_number(json));
|
||||
else if(json_is_integer(json))
|
||||
json_delete_integer(json_to_integer(json));
|
||||
|
||||
else if(json_is_real(json))
|
||||
json_delete_real(json_to_real(json));
|
||||
|
||||
/* json_delete is not called for true, false or null */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user