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:
|
case JSON_FALSE:
|
||||||
return dump("false", 5, data);
|
return dump("false", 5, data);
|
||||||
|
|
||||||
case JSON_NUMBER:
|
case JSON_INTEGER:
|
||||||
{
|
{
|
||||||
char *buffer;
|
char *buffer;
|
||||||
int size, ret;
|
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)
|
if(size == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -10,7 +10,8 @@ typedef enum {
|
|||||||
JSON_OBJECT,
|
JSON_OBJECT,
|
||||||
JSON_ARRAY,
|
JSON_ARRAY,
|
||||||
JSON_STRING,
|
JSON_STRING,
|
||||||
JSON_NUMBER,
|
JSON_INTEGER,
|
||||||
|
JSON_REAL,
|
||||||
JSON_TRUE,
|
JSON_TRUE,
|
||||||
JSON_FALSE,
|
JSON_FALSE,
|
||||||
JSON_NULL
|
JSON_NULL
|
||||||
@ -25,7 +26,9 @@ typedef struct {
|
|||||||
#define json_is_object(json) (json && json_typeof(json) == JSON_OBJECT)
|
#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_array(json) (json && json_typeof(json) == JSON_ARRAY)
|
||||||
#define json_is_string(json) (json && json_typeof(json) == JSON_STRING)
|
#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_true(json) (json && json_typeof(json) == JSON_TRUE)
|
||||||
#define json_is_false(json) (json && json_typeof(json) == JSON_FALSE)
|
#define json_is_false(json) (json && json_typeof(json) == JSON_FALSE)
|
||||||
#define json_is_null(json) (json && json_typeof(json) == JSON_NULL)
|
#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_object(void);
|
||||||
json_t *json_array(void);
|
json_t *json_array(void);
|
||||||
json_t *json_string(const char *value);
|
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_true(void);
|
||||||
json_t *json_false(void);
|
json_t *json_false(void);
|
||||||
json_t *json_null(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);
|
int json_array_append(json_t *array, json_t *value);
|
||||||
|
|
||||||
const char *json_string_value(const json_t *json);
|
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);
|
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_INVALID -1
|
||||||
#define JSON_TOKEN_EOF 0
|
#define JSON_TOKEN_EOF 0
|
||||||
#define JSON_TOKEN_STRING 256
|
#define JSON_TOKEN_STRING 256
|
||||||
#define JSON_TOKEN_NUMBER 257
|
#define JSON_TOKEN_INTEGER 257
|
||||||
#define JSON_TOKEN_TRUE 258
|
#define JSON_TOKEN_REAL 258
|
||||||
#define JSON_TOKEN_FALSE 259
|
#define JSON_TOKEN_TRUE 259
|
||||||
#define JSON_TOKEN_NULL 260
|
#define JSON_TOKEN_FALSE 260
|
||||||
|
#define JSON_TOKEN_NULL 261
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *input;
|
const char *input;
|
||||||
@ -27,7 +28,8 @@ typedef struct {
|
|||||||
int line, column;
|
int line, column;
|
||||||
union {
|
union {
|
||||||
char *string;
|
char *string;
|
||||||
double number;
|
int integer;
|
||||||
|
double real;
|
||||||
} value;
|
} value;
|
||||||
} json_lex;
|
} json_lex;
|
||||||
|
|
||||||
@ -176,7 +178,16 @@ static void json_scan_number(json_lex *lex)
|
|||||||
p++;
|
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++;
|
p++;
|
||||||
if(!isdigit(*(p++)))
|
if(!isdigit(*(p++)))
|
||||||
goto out;
|
goto out;
|
||||||
@ -197,9 +208,9 @@ static void json_scan_number(json_lex *lex)
|
|||||||
p++;
|
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);
|
assert(end == p);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@ -402,8 +413,13 @@ static json_t *json_parse(json_lex *lex, json_error_t *error)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case JSON_TOKEN_NUMBER: {
|
case JSON_TOKEN_INTEGER: {
|
||||||
json = json_number(lex->value.number);
|
json = json_integer(lex->value.integer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case JSON_TOKEN_REAL: {
|
||||||
|
json = json_real(lex->value.real);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
89
src/value.c
89
src/value.c
@ -29,12 +29,18 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
json_t json;
|
json_t json;
|
||||||
double value;
|
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_object(json_) container_of(json_, json_object_t, json)
|
||||||
#define json_to_array(json_) container_of(json_, json_array_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_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)
|
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);
|
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;
|
/*** integer ***/
|
||||||
return &number->json;
|
|
||||||
|
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)
|
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 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))
|
else if(json_is_string(json))
|
||||||
json_delete_string(json_to_string(json));
|
json_delete_string(json_to_string(json));
|
||||||
|
|
||||||
else if(json_is_number(json))
|
else if(json_is_integer(json))
|
||||||
json_delete_number(json_to_number(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 */
|
/* json_delete is not called for true, false or null */
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user