22#include < cstring>
33#include < dirent.h>
44#include < inttypes.h>
5+ #include < math.h>
56#include < stdbool.h>
67#include < stdio.h>
78#include < stdlib.h>
8- #include < inttypes.h>
9- #include < math.h>
109
1110#ifndef JSON_TEST_NUMBERS
1211#define JSON_TEST_NUMBERS
1615
1716int parse_error;
1817char *fullpath;
19- enum { PARSE_WARNING, PARSE_ERROR};
18+ enum { PARSE_WARNING, PARSE_ERROR };
2019
2120size_t float_count;
2221size_t int_count;
2322size_t invalid_count;
2423
25- inline void foundInvalidNumber (const u8 * buf) {
24+ // strings that start with these should not be parsed as numbers
25+ const char *really_bad[] = {" 013}" , " 0x14" , " 0e]" , " 0e+]" , " 0e+-1]" };
26+
27+ bool startsWith (const char *pre , const char *str) {
28+ size_t lenpre = strlen (pre ), lenstr = strlen (str);
29+ return lenstr < lenpre ? false : strncmp (pre , str, lenpre) == 0 ;
30+ }
31+ bool is_in_bad_list (char *buf) {
32+ for (size_t i = 0 ; i < sizeof (really_bad) / sizeof (really_bad[0 ]); i++)
33+ if (startsWith (really_bad[i], buf))
34+ return true ;
35+ return false ;
36+ }
37+
38+ inline void foundInvalidNumber (const u8 *buf) {
2639 invalid_count++;
27- char * endptr;
40+ char *endptr;
2841 double expected = strtod ((char *)buf, &endptr);
29- if (endptr != (char *)buf) {
30- printf (" Warning: foundInvalidNumber %.32s whereas strtod parses it to %f, " , buf, expected);
31- printf (" while parsing %s \n " , fullpath);
32- parse_error |= PARSE_WARNING;
42+ if (endptr != (char *)buf) {
43+ if (!is_in_bad_list ((char *)buf)) {
44+ printf (
45+ " Warning: foundInvalidNumber %.32s whereas strtod parses it to %f, " ,
46+ buf, expected);
47+ printf (" while parsing %s \n " , fullpath);
48+ parse_error |= PARSE_WARNING;
49+ }
3350 }
3451}
3552
36- inline void foundInteger (int64_t result, const u8 * buf) {
53+ inline void foundInteger (int64_t result, const u8 *buf) {
3754 int_count++;
38- char * endptr;
39- long long expected = strtoll ((char *)buf, & endptr, 10 );
40- if ((endptr == (char *)buf) || (expected != result)) {
55+ char *endptr;
56+ long long expected = strtoll ((char *)buf, &endptr, 10 );
57+ if ((endptr == (char *)buf) || (expected != result)) {
4158 printf (" Error: parsed %" PRId64 " out of %.32s, " , result, buf);
4259 printf (" while parsing %s \n " , fullpath);
4360 parse_error |= PARSE_ERROR;
4461 }
4562}
4663
47- inline void foundFloat (double result, const u8 * buf) {
48- char * endptr;
64+ inline void foundFloat (double result, const u8 *buf) {
65+ char *endptr;
4966 float_count++;
5067 double expected = strtod ((char *)buf, &endptr);
51- if (endptr == (char *)buf) {
52- printf (" parsed %f from %.32s whereas strtod refuses to parse a float, " , result, buf);
68+ if (endptr == (char *)buf) {
69+ printf (" parsed %f from %.32s whereas strtod refuses to parse a float, " ,
70+ result, buf);
5371 printf (" while parsing %s \n " , fullpath);
5472 parse_error |= PARSE_ERROR;
5573 }
5674 // we want to get some reasonable relative accuracy
57- if (fabs (expected - result)/fmin (fabs (expected),fabs (result)) > 0.000000000000001 ) {
75+ if (fabs (expected - result) / fmin (fabs (expected), fabs (result)) >
76+ 0.000000000000001 ) {
5877 printf (" parsed %.32f from \n " , result);
5978 printf (" %.32s whereas strtod gives\n " , buf);
60- printf (" %.32f," , expected);
79+ printf (" %.32f," , expected);
6180 printf (" while parsing %s \n " , fullpath);
6281 parse_error |= PARSE_ERROR;
6382 }
6483}
6584
66-
67-
6885#include " jsonparser/jsonparser.h"
6986#include " src/stage34_unified.cpp"
7087
@@ -76,13 +93,10 @@ static bool hasExtension(const char *filename, const char *extension) {
7693 return (ext && !strcmp (ext, extension));
7794}
7895
79- bool startsWith (const char *pre , const char *str) {
80- size_t lenpre = strlen (pre ), lenstr = strlen (str);
81- return lenstr < lenpre ? false : strncmp (pre , str, lenpre) == 0 ;
82- }
83-
8496bool validate (const char *dirname) {
8597 parse_error = 0 ;
98+ size_t total_count = 0 ;
99+
86100 // init_state_machine(); // no longer necessary
87101 const char *extension = " .json" ;
88102 size_t dirlen = strlen (dirname);
@@ -112,28 +126,32 @@ bool validate(const char *dirname) {
112126 std::pair<u8 *, size_t > p = get_corpus (fullpath);
113127 // terrible hack but just to get it working
114128 ParsedJson *pj_ptr = allocate_ParsedJson (p.second );
115- if (pj_ptr == NULL ) {
116- std::cerr<< " can't allocate memory" << std::endl;
129+ if (pj_ptr == NULL ) {
130+ std::cerr << " can't allocate memory" << std::endl;
117131 return false ;
118132 }
119133 float_count = 0 ;
120134 int_count = 0 ;
121135 invalid_count = 0 ;
136+ total_count += float_count + int_count + invalid_count;
122137 ParsedJson &pj (*pj_ptr);
123- bool isok =
124- json_parse (p.first , p.second , pj);
125- if (int_count+float_count+invalid_count > 0 ) {
126- printf (" File %40s %s --- integers: %10zu floats: %10zu invalid: %10zu total numbers: %10zu \n " , name,
127- isok ? " is valid " :
128- " is not valid " ,int_count, float_count, invalid_count, int_count+float_count+invalid_count);
138+ bool isok = json_parse (p.first , p.second , pj);
139+ if (int_count + float_count + invalid_count > 0 ) {
140+ printf (" File %40s %s --- integers: %10zu floats: %10zu invalid: %10zu "
141+ " total numbers: %10zu \n " ,
142+ name, isok ? " is valid " : " is not valid " , int_count,
143+ float_count, invalid_count,
144+ int_count + float_count + invalid_count);
129145 }
130146 free (p.first );
131147 free (fullpath);
132148 deallocate_ParsedJson (pj_ptr);
133149 }
134150 }
135- if ((parse_error & PARSE_ERROR) != 0 ) {
151+ if ((parse_error & PARSE_ERROR) != 0 ) {
136152 printf (" NUMBER PARSING FAILS?\n " );
153+ } else {
154+ printf (" All ok.\n " );
137155 }
138156 for (int i = 0 ; i < c; ++i)
139157 free (entry_list[i]);
@@ -145,10 +163,11 @@ int main(int argc, char *argv[]) {
145163 if (argc != 2 ) {
146164 std::cerr << " Usage: " << argv[0 ] << " <directorywithjsonfiles>"
147165 << std::endl;
148- std::cout
149- << " We are going to assume you mean to use the 'jsonchecker' and 'jsonexamples' directories."
150- << std::endl;
151- return validate (" jsonchecker/" ) && validate (" jsonexamples/" ) ? EXIT_SUCCESS : EXIT_FAILURE;
166+ std::cout << " We are going to assume you mean to use the 'jsonchecker' and "
167+ " 'jsonexamples' directories."
168+ << std::endl;
169+ return validate (" jsonchecker/" ) && validate (" jsonexamples/" ) ? EXIT_SUCCESS
170+ : EXIT_FAILURE;
152171 }
153172 return validate (argv[1 ]) ? EXIT_SUCCESS : EXIT_FAILURE;
154173}
0 commit comments