]> granicus.if.org Git - json-c/commitdiff
Issue#102 - add support for parsing "NaN".
authorEric Haszlakiewicz <erh+git@nimenees.com>
Sun, 9 Mar 2014 20:41:33 +0000 (16:41 -0400)
committerEric Haszlakiewicz <erh+git@nimenees.com>
Sun, 9 Mar 2014 20:41:33 +0000 (16:41 -0400)
config.h.in
configure.ac
json_tokener.c
math_compat.h
tests/test_parse.c
tests/test_parse.expected

index d612636fa87de8feaaf92b3add161a0d1b342bab..f24bfbc2d07a87ce577498df7b004b32bdfdafd8 100644 (file)
@@ -11,6 +11,9 @@
    */
 #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
    don't. */
 #undef HAVE_DECL__FINITE
index a7d2d7b3e48bfc452f4bcc7196ec68f32a2f8479..96e24661025b567e9e83461bfff50ec3209f4352 100644 (file)
@@ -29,6 +29,7 @@ AC_FUNC_MEMCMP
 AC_FUNC_MALLOC
 AC_FUNC_REALLOC
 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([isinf], [], [], [[#include <math.h>]])
 AC_CHECK_DECLS([_isnan], [], [], [[#include <float.h>]])
index 74fd27ade32ff19cf96a6c71ed742067545872af..0c800d8f85cfb01d43802b9511cef5f632311612 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "config.h"
 
+#include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stddef.h>
 # error You do not have strncasecmp on your system.
 #endif /* HAVE_STRNCASECMP */
 
-static const char* json_null_str = "null";
-static const char* json_true_str = "true";
-static const char* json_false_str = "false";
+static const char json_null_str[] = "null";
+static const int json_null_str_len = sizeof(json_null_str) - 1;
+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:
 const char* json_tokener_errors[] = {
@@ -266,7 +272,7 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
        break;
       case 'N':
       case 'n':
-       state = json_tokener_state_null;
+       state = json_tokener_state_null; // or NaN
        printbuf_reset(tok->pb);
        tok->st_pos = 0;
        goto redo_char;
@@ -324,18 +330,33 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
     case json_tokener_state_null:
       {
        int size;
+       int size_nan;
        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) &&
          strncasecmp(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;
            saved_state = json_tokener_state_finish;
            state = json_tokener_state_eatws;
            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 {
          tok->err = json_tokener_error_parse_null;
          goto out;
@@ -557,13 +578,13 @@ struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
       {
        int size1, size2;
        printbuf_memappend_fast(tok->pb, &c, 1);
-       size1 = json_min(tok->st_pos+1, (int)strlen(json_true_str));
-       size2 = json_min(tok->st_pos+1, (int)strlen(json_false_str));
+       size1 = json_min(tok->st_pos+1, json_true_str_len);
+       size2 = json_min(tok->st_pos+1, json_false_str_len);
        if((!(tok->flags & JSON_TOKENER_STRICT) &&
          strncasecmp(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);
            saved_state = json_tokener_state_finish;
            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) &&
          strncasecmp(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);
            saved_state = json_tokener_state_finish;
            state = json_tokener_state_eatws;
index 4a2721e19e3b23eb286e182b80cae09c8cfd6caa..d94a4dacfd48513cc5a1e7bbd8ecec21d87a12d1 100644 (file)
@@ -17,4 +17,8 @@
 # endif
 #endif
 
+#ifndef HAVE_DECL_NAN
+#error This platform does not have nan()
+#endif
+
 #endif
index 1a59a6bddba84e47c287fe092be6a6b890fc30d2..f0f255026d6d4a1832b17f9f522e7c65a0b3a2c8 100644 (file)
@@ -47,6 +47,10 @@ static void test_basic_parse()
        printf("new_obj.to_string()=%s\n", json_object_to_json_string(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");
        printf("new_obj.to_string()=%s\n", json_object_to_json_string(new_obj));
        json_object_put(new_obj);
index 5ea99d84bde2968f0381d15a5f698c3ee3f7115d..378a82b6dad42fe83d309461ca75c70fdf597f2e 100644 (file)
@@ -3,6 +3,7 @@ new_obj.to_string()="foo"
 new_obj.to_string()="foo"
 new_obj.to_string()="ABC"
 new_obj.to_string()=null
+new_obj.to_string()=NaN
 new_obj.to_string()=true
 new_obj.to_string()=12
 new_obj.to_string()=12.3