2018-09-28 05:38:15 +08:00
|
|
|
#include <assert.h>
|
|
|
|
#include <cstring>
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <inttypes.h>
|
2018-09-28 08:26:27 +08:00
|
|
|
#include <math.h>
|
2018-09-28 05:38:15 +08:00
|
|
|
|
|
|
|
#ifndef JSON_TEST_NUMBERS
|
|
|
|
#define JSON_TEST_NUMBERS
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "jsonparser/common_defs.h"
|
|
|
|
|
2018-09-28 08:26:27 +08:00
|
|
|
int parse_error;
|
|
|
|
char *fullpath;
|
|
|
|
enum{PARSE_WARNING, PARSE_ERROR};
|
2018-09-28 05:38:15 +08:00
|
|
|
|
|
|
|
inline void foundInvalidNumber(const u8 * buf) {
|
2018-09-28 08:26:27 +08:00
|
|
|
char * endptr;
|
|
|
|
double expected = strtod((char *)buf, &endptr);
|
|
|
|
if(endptr != (char *)buf) {
|
|
|
|
printf("Warning: foundInvalidNumber %.32s whereas strtod parses it to %f, ", buf, expected);
|
|
|
|
printf(" while parsing %s \n", fullpath);
|
|
|
|
parse_error |= PARSE_WARNING;
|
|
|
|
}
|
2018-09-28 05:38:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
inline void foundInteger(int64_t result, const u8 * buf) {
|
2018-09-28 08:26:27 +08:00
|
|
|
char * endptr;
|
|
|
|
long long expected = strtoll((char *)buf, & endptr, 10);
|
|
|
|
if((endptr == (char *)buf) || (expected != result)) {
|
|
|
|
printf("Error: parsed %" PRId64 " out of %.32s, ", result, buf);
|
|
|
|
printf(" while parsing %s \n", fullpath);
|
|
|
|
parse_error |= PARSE_ERROR;
|
|
|
|
}
|
2018-09-28 05:38:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
inline void foundFloat(double result, const u8 * buf) {
|
2018-09-28 08:26:27 +08:00
|
|
|
char * endptr;
|
|
|
|
double expected = strtod((char *)buf, &endptr);
|
|
|
|
if(endptr == (char *)buf) {
|
|
|
|
printf("parsed %f from %.32s whereas strtod refuses to parse a float, ", result, buf);
|
|
|
|
printf(" while parsing %s \n", fullpath);
|
|
|
|
parse_error |= PARSE_ERROR;
|
|
|
|
}
|
|
|
|
// we want to get some reasonable relative accuracy
|
|
|
|
if(fabs(expected - result)/fmax(fabs(expected),fabs(result)) > 0.000000000000001) {
|
|
|
|
printf("parsed %f from %.32s whereas strtod gives %f,", result, buf, expected);
|
|
|
|
printf(" while parsing %s \n", fullpath);
|
|
|
|
parse_error |= PARSE_ERROR;
|
|
|
|
}
|
2018-09-28 05:38:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "jsonparser/jsonparser.h"
|
|
|
|
#include "src/stage34_unified.cpp"
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Does the file filename ends with the given extension.
|
|
|
|
*/
|
|
|
|
static bool hasExtension(const char *filename, const char *extension) {
|
|
|
|
const char *ext = strrchr(filename, '.');
|
|
|
|
return (ext && !strcmp(ext, extension));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool startsWith(const char *pre, const char *str) {
|
|
|
|
size_t lenpre = strlen(pre), lenstr = strlen(str);
|
|
|
|
return lenstr < lenpre ? false : strncmp(pre, str, lenpre) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool validate(const char *dirname) {
|
2018-09-28 08:26:27 +08:00
|
|
|
parse_error = 0;
|
2018-09-28 05:38:15 +08:00
|
|
|
// init_state_machine(); // no longer necessary
|
|
|
|
const char *extension = ".json";
|
|
|
|
size_t dirlen = strlen(dirname);
|
|
|
|
struct dirent **entry_list;
|
|
|
|
int c = scandir(dirname, &entry_list, 0, alphasort);
|
|
|
|
if (c < 0) {
|
|
|
|
printf("error accessing %s \n", dirname);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (c == 0) {
|
|
|
|
printf("nothing in dir %s \n", dirname);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
bool needsep = (strlen(dirname) > 1) && (dirname[strlen(dirname) - 1] != '/');
|
|
|
|
for (int i = 0; i < c; i++) {
|
|
|
|
const char *name = entry_list[i]->d_name;
|
|
|
|
if (hasExtension(name, extension)) {
|
|
|
|
size_t filelen = strlen(name);
|
2018-09-28 08:26:27 +08:00
|
|
|
fullpath = (char *)malloc(dirlen + filelen + 1 + 1);
|
2018-09-28 05:38:15 +08:00
|
|
|
strcpy(fullpath, dirname);
|
|
|
|
if (needsep) {
|
|
|
|
fullpath[dirlen] = '/';
|
|
|
|
strcpy(fullpath + dirlen + 1, name);
|
|
|
|
} else {
|
|
|
|
strcpy(fullpath + dirlen, name);
|
|
|
|
}
|
|
|
|
std::pair<u8 *, size_t> p = get_corpus(fullpath);
|
|
|
|
// terrible hack but just to get it working
|
|
|
|
ParsedJson *pj_ptr = allocate_ParsedJson(p.second);
|
|
|
|
if(pj_ptr == NULL) {
|
|
|
|
std::cerr<< "can't allocate memory"<<std::endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
ParsedJson &pj(*pj_ptr);
|
2018-09-28 08:26:27 +08:00
|
|
|
//bool isok =
|
|
|
|
json_parse(p.first, p.second, pj);
|
|
|
|
//printf("File %s %s.\n", name,
|
|
|
|
// isok ? " is valid JSON " : " is not valid JSON");
|
2018-09-28 05:38:15 +08:00
|
|
|
free(p.first);
|
|
|
|
free(fullpath);
|
|
|
|
deallocate_ParsedJson(pj_ptr);
|
|
|
|
}
|
|
|
|
}
|
2018-09-28 08:26:27 +08:00
|
|
|
if((parse_error & PARSE_ERROR) != 0) {
|
|
|
|
printf("NUMBER PARSING FAILS?\n");
|
|
|
|
}
|
2018-09-28 05:38:15 +08:00
|
|
|
for (int i = 0; i < c; ++i)
|
|
|
|
free(entry_list[i]);
|
|
|
|
free(entry_list);
|
2018-09-28 08:26:27 +08:00
|
|
|
return ((parse_error & PARSE_ERROR) == 0);
|
2018-09-28 05:38:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) {
|
|
|
|
if (argc != 2) {
|
|
|
|
std::cerr << "Usage: " << argv[0] << " <directorywithjsonfiles>"
|
|
|
|
<< std::endl;
|
|
|
|
std::cout
|
2018-09-28 08:26:27 +08:00
|
|
|
<< "We are going to assume you mean to use the 'jsonchecker' and 'jsonexamples' directories."
|
2018-09-28 05:38:15 +08:00
|
|
|
<< std::endl;
|
2018-09-28 08:26:27 +08:00
|
|
|
return validate("jsonchecker/") && validate("jsonexamples/") ? EXIT_SUCCESS : EXIT_FAILURE;
|
2018-09-28 05:38:15 +08:00
|
|
|
}
|
|
|
|
return validate(argv[1]) ? EXIT_SUCCESS : EXIT_FAILURE;
|
|
|
|
}
|