Issue#102 - add support for parsing "NaN".
This commit is contained in:
@@ -11,6 +11,9 @@
|
|||||||
*/
|
*/
|
||||||
#undef HAVE_DECL_ISNAN
|
#undef HAVE_DECL_ISNAN
|
||||||
|
|
||||||
|
/* Define to 1 if you have the declaration of `nan', and to 0 if you don't. */
|
||||||
|
#undef HAVE_DECL_NAN
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `_finite', and to 0 if you
|
/* Define to 1 if you have the declaration of `_finite', and to 0 if you
|
||||||
don't. */
|
don't. */
|
||||||
#undef HAVE_DECL__FINITE
|
#undef HAVE_DECL__FINITE
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ AC_FUNC_MEMCMP
|
|||||||
AC_FUNC_MALLOC
|
AC_FUNC_MALLOC
|
||||||
AC_FUNC_REALLOC
|
AC_FUNC_REALLOC
|
||||||
AC_CHECK_FUNCS(strcasecmp strdup strerror snprintf vsnprintf vasprintf open vsyslog strncasecmp setlocale)
|
AC_CHECK_FUNCS(strcasecmp strdup strerror snprintf vsnprintf vasprintf open vsyslog strncasecmp setlocale)
|
||||||
|
AC_CHECK_DECLS([nan], [], [], [[#include <math.h>]])
|
||||||
AC_CHECK_DECLS([isnan], [], [], [[#include <math.h>]])
|
AC_CHECK_DECLS([isnan], [], [], [[#include <math.h>]])
|
||||||
AC_CHECK_DECLS([isinf], [], [], [[#include <math.h>]])
|
AC_CHECK_DECLS([isinf], [], [], [[#include <math.h>]])
|
||||||
AC_CHECK_DECLS([_isnan], [], [], [[#include <float.h>]])
|
AC_CHECK_DECLS([_isnan], [], [], [[#include <float.h>]])
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@@ -49,9 +50,14 @@
|
|||||||
# error You do not have strncasecmp on your system.
|
# error You do not have strncasecmp on your system.
|
||||||
#endif /* HAVE_STRNCASECMP */
|
#endif /* HAVE_STRNCASECMP */
|
||||||
|
|
||||||
static const char* json_null_str = "null";
|
static const char json_null_str[] = "null";
|
||||||
static const char* json_true_str = "true";
|
static const int json_null_str_len = sizeof(json_null_str) - 1;
|
||||||
static const char* json_false_str = "false";
|
static const char json_nan_str[] = "NaN";
|
||||||
|
static const int json_nan_str_len = sizeof(json_nan_str) - 1;
|
||||||
|
static const char json_true_str[] = "true";
|
||||||
|
static const int json_true_str_len = sizeof(json_true_str) - 1;
|
||||||
|
static const char json_false_str[] = "false";
|
||||||
|
static const int json_false_str_len = sizeof(json_false_str) - 1;
|
||||||
|
|
||||||
// XXX after v0.10 this array will become static:
|
// XXX after v0.10 this array will become static:
|
||||||
const char* json_tokener_errors[] = {
|
const char* json_tokener_errors[] = {
|
||||||
@@ -266,7 +272,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
break;
|
break;
|
||||||
case 'N':
|
case 'N':
|
||||||
case 'n':
|
case 'n':
|
||||||
state = json_tokener_state_null;
|
state = json_tokener_state_null; // or NaN
|
||||||
printbuf_reset(tok->pb);
|
printbuf_reset(tok->pb);
|
||||||
tok->st_pos = 0;
|
tok->st_pos = 0;
|
||||||
goto redo_char;
|
goto redo_char;
|
||||||
@@ -324,18 +330,33 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
case json_tokener_state_null:
|
case json_tokener_state_null:
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
|
int size_nan;
|
||||||
printbuf_memappend_fast(tok->pb, &c, 1);
|
printbuf_memappend_fast(tok->pb, &c, 1);
|
||||||
size = json_min(tok->st_pos+1, (int)strlen(json_null_str));
|
size = json_min(tok->st_pos+1, json_null_str_len);
|
||||||
|
size_nan = json_min(tok->st_pos+1, json_nan_str_len);
|
||||||
if((!(tok->flags & JSON_TOKENER_STRICT) &&
|
if((!(tok->flags & JSON_TOKENER_STRICT) &&
|
||||||
strncasecmp(json_null_str, tok->pb->buf, size) == 0)
|
strncasecmp(json_null_str, tok->pb->buf, size) == 0)
|
||||||
|| (strncmp(json_null_str, tok->pb->buf, size) == 0)
|
|| (strncmp(json_null_str, tok->pb->buf, size) == 0)
|
||||||
) {
|
) {
|
||||||
if(tok->st_pos == (int)strlen(json_null_str)) {
|
if (tok->st_pos == json_null_str_len) {
|
||||||
current = NULL;
|
current = NULL;
|
||||||
saved_state = json_tokener_state_finish;
|
saved_state = json_tokener_state_finish;
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
goto redo_char;
|
goto redo_char;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
|
||||||
|
strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
|
||||||
|
(strncmp(json_nan_str, tok->pb->buf, size_nan) == 0)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (tok->st_pos == json_nan_str_len)
|
||||||
|
{
|
||||||
|
current = json_object_new_double(nan(""));
|
||||||
|
saved_state = json_tokener_state_finish;
|
||||||
|
state = json_tokener_state_eatws;
|
||||||
|
goto redo_char;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
tok->err = json_tokener_error_parse_null;
|
tok->err = json_tokener_error_parse_null;
|
||||||
goto out;
|
goto out;
|
||||||
@@ -557,13 +578,13 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
{
|
{
|
||||||
int size1, size2;
|
int size1, size2;
|
||||||
printbuf_memappend_fast(tok->pb, &c, 1);
|
printbuf_memappend_fast(tok->pb, &c, 1);
|
||||||
size1 = json_min(tok->st_pos+1, (int)strlen(json_true_str));
|
size1 = json_min(tok->st_pos+1, json_true_str_len);
|
||||||
size2 = json_min(tok->st_pos+1, (int)strlen(json_false_str));
|
size2 = json_min(tok->st_pos+1, json_false_str_len);
|
||||||
if((!(tok->flags & JSON_TOKENER_STRICT) &&
|
if((!(tok->flags & JSON_TOKENER_STRICT) &&
|
||||||
strncasecmp(json_true_str, tok->pb->buf, size1) == 0)
|
strncasecmp(json_true_str, tok->pb->buf, size1) == 0)
|
||||||
|| (strncmp(json_true_str, tok->pb->buf, size1) == 0)
|
|| (strncmp(json_true_str, tok->pb->buf, size1) == 0)
|
||||||
) {
|
) {
|
||||||
if(tok->st_pos == (int)strlen(json_true_str)) {
|
if(tok->st_pos == json_true_str_len) {
|
||||||
current = json_object_new_boolean(1);
|
current = json_object_new_boolean(1);
|
||||||
saved_state = json_tokener_state_finish;
|
saved_state = json_tokener_state_finish;
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
@@ -572,7 +593,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
|||||||
} else if((!(tok->flags & JSON_TOKENER_STRICT) &&
|
} else if((!(tok->flags & JSON_TOKENER_STRICT) &&
|
||||||
strncasecmp(json_false_str, tok->pb->buf, size2) == 0)
|
strncasecmp(json_false_str, tok->pb->buf, size2) == 0)
|
||||||
|| (strncmp(json_false_str, tok->pb->buf, size2) == 0)) {
|
|| (strncmp(json_false_str, tok->pb->buf, size2) == 0)) {
|
||||||
if(tok->st_pos == (int)strlen(json_false_str)) {
|
if(tok->st_pos == json_false_str_len) {
|
||||||
current = json_object_new_boolean(0);
|
current = json_object_new_boolean(0);
|
||||||
saved_state = json_tokener_state_finish;
|
saved_state = json_tokener_state_finish;
|
||||||
state = json_tokener_state_eatws;
|
state = json_tokener_state_eatws;
|
||||||
|
|||||||
@@ -17,4 +17,8 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_DECL_NAN
|
||||||
|
#error This platform does not have nan()
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -47,6 +47,10 @@ static void test_basic_parse()
|
|||||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||||
json_object_put(new_obj);
|
json_object_put(new_obj);
|
||||||
|
|
||||||
|
new_obj = json_tokener_parse("NaN");
|
||||||
|
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||||
|
json_object_put(new_obj);
|
||||||
|
|
||||||
new_obj = json_tokener_parse("True");
|
new_obj = json_tokener_parse("True");
|
||||||
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
|
||||||
json_object_put(new_obj);
|
json_object_put(new_obj);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ new_obj.to_string()="foo"
|
|||||||
new_obj.to_string()="foo"
|
new_obj.to_string()="foo"
|
||||||
new_obj.to_string()="ABC"
|
new_obj.to_string()="ABC"
|
||||||
new_obj.to_string()=null
|
new_obj.to_string()=null
|
||||||
|
new_obj.to_string()=NaN
|
||||||
new_obj.to_string()=true
|
new_obj.to_string()=true
|
||||||
new_obj.to_string()=12
|
new_obj.to_string()=12
|
||||||
new_obj.to_string()=12.3
|
new_obj.to_string()=12.3
|
||||||
|
|||||||
Reference in New Issue
Block a user