From 8e2c06cb0e5bcd2c3a57ef155ad66f4d24589aa3 Mon Sep 17 00:00:00 2001 From: John Keiser Date: Sat, 14 Mar 2020 15:23:56 -0700 Subject: [PATCH] Compile with -fno-exceptions --- .drone.yml | 42 +++++ benchmark/benchmarker.h | 24 +-- benchmark/distinctuseridcompetition.cpp | 4 +- benchmark/get_corpus_benchmark.cpp | 6 +- dependencies/jsoncppdist/jsoncpp.cpp | 8 + include/simdjson/common_defs.h | 2 +- include/simdjson/document.h | 5 + include/simdjson/error.h | 19 +- include/simdjson/inline/document.h | 4 + include/simdjson/inline/document_iterator.h | 4 + include/simdjson/jsonioutil.h | 4 + tests/basictests.cpp | 193 +++++++++++++------- tests/integer_tests.cpp | 4 +- tests/parse_many_test.cpp | 13 +- tests/readme_examples.cpp | 122 +++++++------ tools/jsonpointer.cpp | 2 +- 16 files changed, 298 insertions(+), 158 deletions(-) diff --git a/.drone.yml b/.drone.yml index ecca3e795..f5eca687b 100644 --- a/.drone.yml +++ b/.drone.yml @@ -49,6 +49,48 @@ steps: commands: [ make slowtests ] --- kind: pipeline +name: x64-noexceptions-quicktests + +platform: + os: linux + arch: amd64 + +steps: +- name: quicktests + image: gcc:8 + environment: + EXTRA_FLAGS: -fno-exceptions + commands: [ make quicktests ] +--- +kind: pipeline +name: x64-noexceptions-build + +platform: + os: linux + arch: amd64 + +steps: +- name: build + image: gcc:8 + environment: + EXTRA_FLAGS: -fno-exceptions + commands: [ make, make amalgamate ] +--- +kind: pipeline +name: x64-noexceptions-slowtests + +platform: + os: linux + arch: amd64 + +steps: +- name: slowtests + image: gcc:8 + environment: + EXTRA_FLAGS: -fno-exceptions + commands: [ make slowtests ] +--- +kind: pipeline name: arm64-quicktests platform: diff --git a/benchmark/benchmarker.h b/benchmark/benchmarker.h index 49581e777..125d1dd2c 100644 --- a/benchmark/benchmarker.h +++ b/benchmark/benchmarker.h @@ -182,18 +182,6 @@ struct json_stats { } }; -padded_string load_json(const char *filename) { - try { - verbose() << "[verbose] loading " << filename << endl; - padded_string json = padded_string::load(filename); - verbose() << "[verbose] loaded " << filename << " (" << json.size() << " bytes)" << endl; - return json; - } catch (const exception &) { // caught by reference to base - exit_error(string("Could not load the file ") + filename); - exit(EXIT_FAILURE); // This is not strictly necessary but removes the warning - } -} - struct progress_bar { int max_value; int total_ticks; @@ -253,7 +241,7 @@ const char* benchmark_stage_name(BenchmarkStage stage) { struct benchmarker { // JSON text from loading the file. Owns the memory. - const padded_string json; + padded_string json; // JSON filename const char *filename; // Event collector that can be turned on to measure cycles, missed branches, etc. @@ -272,7 +260,15 @@ struct benchmarker { event_aggregate allocate_stage; benchmarker(const char *_filename, event_collector& _collector) - : json(load_json(_filename)), filename(_filename), collector(_collector), stats(NULL) {} + : filename(_filename), collector(_collector), stats(NULL) { + verbose() << "[verbose] loading " << filename << endl; + simdjson::error_code error; + std::tie(this->json, error) = padded_string::load(filename); + if (error) { + exit_error(string("Could not load the file ") + filename); + } + verbose() << "[verbose] loaded " << filename << endl; + } ~benchmarker() { if (stats) { diff --git a/benchmark/distinctuseridcompetition.cpp b/benchmark/distinctuseridcompetition.cpp index d73be0c7c..e274230f0 100644 --- a/benchmark/distinctuseridcompetition.cpp +++ b/benchmark/distinctuseridcompetition.cpp @@ -59,7 +59,7 @@ simdjson_just_dom(simdjson::document &doc) { __attribute__((noinline)) std::vector simdjson_compute_stats(const simdjson::padded_string &p) { std::vector answer; - simdjson::document doc = simdjson::document::parse(p); + auto [doc, error] = simdjson::document::parse(p); simdjson_scan(answer, doc); remove_duplicates(answer); return answer; @@ -319,7 +319,7 @@ int main(int argc, char *argv[]) { volume, !just_data); BEST_TIME("sasjon (just parse) ", sasjon_just_parse(p), false, , repeat, volume, !just_data); - simdjson::document dsimdjson = simdjson::document::parse(p); + auto [dsimdjson, dsimdjson_error] = simdjson::document::parse(p); BEST_TIME("simdjson (just dom) ", simdjson_just_dom(dsimdjson).size(), size, , repeat, volume, !just_data); char *buffer = (char *)malloc(p.size()); diff --git a/benchmark/get_corpus_benchmark.cpp b/benchmark/get_corpus_benchmark.cpp index 26ea2b450..370a7c4bb 100644 --- a/benchmark/get_corpus_benchmark.cpp +++ b/benchmark/get_corpus_benchmark.cpp @@ -8,7 +8,7 @@ never_inline double bench(std::string filename, simdjson::padded_string& p) { std::chrono::time_point start_clock = std::chrono::steady_clock::now(); - simdjson::get_corpus(filename).swap(p); + simdjson::padded_string::load(filename).first.swap(p); std::chrono::time_point end_clock = std::chrono::steady_clock::now(); std::chrono::duration elapsed = end_clock - start_clock; @@ -34,17 +34,21 @@ int main(int argc, char *argv[]) { double minval = 10000; std::cout << "file size: "<< (p.size() / (1024. * 1024 * 1024.)) << " GB" < 1024*1024*1024 ? 5 : 50; +#if __cpp_exceptions try { +#endif for(size_t i = 0; i < times; i++) { double tval = bench(filename, p); if(maxval < tval) maxval = tval; if(minval > tval) minval = tval; meanval += tval; } +#if __cpp_exceptions } catch (const std::exception &) { // caught by reference to base std::cerr << "Could not load the file " << filename << std::endl; return EXIT_FAILURE; } +#endif std::cout << "average speed: " << meanval / times << " GB/s"<< std::endl; std::cout << "min speed : " << minval << " GB/s" << std::endl; std::cout << "max speed : " << maxval << " GB/s" << std::endl; diff --git a/dependencies/jsoncppdist/jsoncpp.cpp b/dependencies/jsoncppdist/jsoncpp.cpp index ffb3ad63b..fa15de2a4 100644 --- a/dependencies/jsoncppdist/jsoncpp.cpp +++ b/dependencies/jsoncppdist/jsoncpp.cpp @@ -2652,10 +2652,18 @@ char const* Exception::what() const JSONCPP_NOEXCEPT { return msg_.c_str(); } RuntimeError::RuntimeError(String const& msg) : Exception(msg) {} LogicError::LogicError(String const& msg) : Exception(msg) {} JSONCPP_NORETURN void throwRuntimeError(String const& msg) { +#if __cpp_exceptions throw RuntimeError(msg); +#else + abort(); +#endif } JSONCPP_NORETURN void throwLogicError(String const& msg) { +#if __cpp_exceptions throw LogicError(msg); +#else + abort(); +#endif } // ////////////////////////////////////////////////////////////////// diff --git a/include/simdjson/common_defs.h b/include/simdjson/common_defs.h index 8ae5fdd27..ddb5e9c49 100644 --- a/include/simdjson/common_defs.h +++ b/include/simdjson/common_defs.h @@ -7,7 +7,7 @@ namespace simdjson { #ifndef SIMDJSON_EXCEPTIONS -#ifdef __cpp_exceptions +#if __cpp_exceptions #define SIMDJSON_EXCEPTIONS 1 #else #define SIMDJSON_EXCEPTIONS 0 diff --git a/include/simdjson/document.h b/include/simdjson/document.h index a85c46af7..38ea61ff8 100644 --- a/include/simdjson/document.h +++ b/include/simdjson/document.h @@ -1642,6 +1642,9 @@ inline std::ostream& operator<<(std::ostream& out, const document::object &value * @throw if there is an error with the underlying output stream. simdjson itself will not throw. */ inline std::ostream& operator<<(std::ostream& out, const document::key_value_pair &value) { return out << minify(value); } + +#if SIMDJSON_EXCEPTIONS + /** * Print JSON to an output stream. * @@ -1703,6 +1706,8 @@ inline std::ostream& operator<<(std::ostream& out, const document::array_result */ inline std::ostream& operator<<(std::ostream& out, const document::object_result &value) noexcept(false) { return out << minify(value); } +#endif + } // namespace simdjson #endif // SIMDJSON_DOCUMENT_H \ No newline at end of file diff --git a/include/simdjson/error.h b/include/simdjson/error.h index 903f89957..9f5b58bec 100644 --- a/include/simdjson/error.h +++ b/include/simdjson/error.h @@ -1,6 +1,7 @@ #ifndef SIMDJSON_ERROR_H #define SIMDJSON_ERROR_H +#include "simdjson/common_defs.h" #include #include @@ -76,6 +77,13 @@ private: */ template struct simdjson_result : public std::pair { + /** + * The error. + */ + error_code error() const { return this->second; } + +#if SIMDJSON_EXCEPTIONS + /** * The value of the function. * @@ -86,11 +94,6 @@ struct simdjson_result : public std::pair { return this->first; }; - /** - * The error. - */ - error_code error() const { return this->second; } - /** * Cast to the value (will throw on error). * @@ -98,6 +101,8 @@ struct simdjson_result : public std::pair { */ operator T() noexcept(false) { return get(); } +#endif // SIMDJSON_EXCEPTIONS + /** * Create a new error result. */ @@ -128,6 +133,8 @@ struct simdjson_move_result : std::pair { */ error_code error() const { return this->second; } +#if SIMDJSON_EXCEPTIONS + /** * The value of the function. * @@ -145,6 +152,8 @@ struct simdjson_move_result : std::pair { */ operator T() noexcept(false) { return move(); } +#endif + /** * Create a new error result. */ diff --git a/include/simdjson/inline/document.h b/include/simdjson/inline/document.h index 055186b42..b5821a533 100644 --- a/include/simdjson/inline/document.h +++ b/include/simdjson/inline/document.h @@ -991,6 +991,8 @@ inline std::ostream& minify::print(std::ostream& out) return out << '"' << internal::escape_json_string(value.key) << "\":" << value.value; } +#if SIMDJSON_EXCEPTIONS + template<> inline std::ostream& minify::print(std::ostream& out) { if (value.error()) { throw simdjson_error(value.error()); } @@ -1017,6 +1019,8 @@ inline std::ostream& minify::print(std::ostream& out) { return out << minify(value.first); } +#endif + } // namespace simdjson #endif // SIMDJSON_INLINE_DOCUMENT_H diff --git a/include/simdjson/inline/document_iterator.h b/include/simdjson/inline/document_iterator.h index c59af5bc9..523dfeffb 100644 --- a/include/simdjson/inline/document_iterator.h +++ b/include/simdjson/inline/document_iterator.h @@ -328,7 +328,9 @@ bool document_iterator::move_to(const char *pointer, uint32_t new_length = 0; for (uint32_t i = 1; i < length; i++) { if (pointer[i] == '%' && pointer[i + 1] == 'x') { +#if __cpp_exceptions try { +#endif int fragment = std::stoi(std::string(&pointer[i + 2], 2), nullptr, 16); if (fragment == '\\' || fragment == '"' || (fragment <= 0x1F)) { @@ -338,10 +340,12 @@ bool document_iterator::move_to(const char *pointer, } new_pointer[new_length] = fragment; i += 3; +#if __cpp_exceptions } catch (std::invalid_argument &) { delete[] new_pointer; return false; // the fragment is invalid } +#endif } else { new_pointer[new_length] = pointer[i]; } diff --git a/include/simdjson/jsonioutil.h b/include/simdjson/jsonioutil.h index 7b855d362..8adfc15ff 100644 --- a/include/simdjson/jsonioutil.h +++ b/include/simdjson/jsonioutil.h @@ -13,10 +13,14 @@ namespace simdjson { +#if SIMDJSON_EXCEPTIONS + inline padded_string get_corpus(const std::string &filename) { return padded_string::load(filename); } +#endif // SIMDJSON_EXCEPTIONS + } // namespace simdjson #endif // SIMDJSON_JSONIOUTIL_H diff --git a/tests/basictests.cpp b/tests/basictests.cpp index 41c7ba940..e82579f82 100644 --- a/tests/basictests.cpp +++ b/tests/basictests.cpp @@ -875,13 +875,13 @@ namespace dom_api { string json(R"({ "a": 1, "b": 2, "c": 3})"); document::parser parser; auto [doc, error] = parser.parse(json); - if (doc["a"].as_uint64_t().first != 1) { cerr << "Expected uint64_t(doc[\"a\"]) to be 1, was " << doc["a"] << endl; return false; } - if (doc["b"].as_uint64_t().first != 2) { cerr << "Expected uint64_t(doc[\"b\"]) to be 2, was " << doc["b"] << endl; return false; } - if (doc["c"].as_uint64_t().first != 3) { cerr << "Expected uint64_t(doc[\"c\"]) to be 3, was " << doc["c"] << endl; return false; } + if (doc["a"].as_uint64_t().first != 1) { cerr << "Expected uint64_t(doc[\"a\"]) to be 1, was " << doc["a"].first << endl; return false; } + if (doc["b"].as_uint64_t().first != 2) { cerr << "Expected uint64_t(doc[\"b\"]) to be 2, was " << doc["b"].first << endl; return false; } + if (doc["c"].as_uint64_t().first != 3) { cerr << "Expected uint64_t(doc[\"c\"]) to be 3, was " << doc["c"].first << endl; return false; } // Check all three again in backwards order, to ensure we can go backwards - if (doc["c"].as_uint64_t().first != 3) { cerr << "Expected uint64_t(doc[\"c\"]) to be 3, was " << doc["c"] << endl; return false; } - if (doc["b"].as_uint64_t().first != 2) { cerr << "Expected uint64_t(doc[\"b\"]) to be 2, was " << doc["b"] << endl; return false; } - if (doc["a"].as_uint64_t().first != 1) { cerr << "Expected uint64_t(doc[\"a\"]) to be 1, was " << doc["a"] << endl; return false; } + if (doc["c"].as_uint64_t().first != 3) { cerr << "Expected uint64_t(doc[\"c\"]) to be 3, was " << doc["c"].first << endl; return false; } + if (doc["b"].as_uint64_t().first != 2) { cerr << "Expected uint64_t(doc[\"b\"]) to be 2, was " << doc["b"].first << endl; return false; } + if (doc["a"].as_uint64_t().first != 1) { cerr << "Expected uint64_t(doc[\"a\"]) to be 1, was " << doc["a"].first << endl; return false; } UNUSED document::element val; tie(val, error) = doc["d"]; @@ -903,13 +903,13 @@ namespace dom_api { if (obj["obj"]["a"].as_uint64_t().first != 1) { cerr << "Expected uint64_t(doc[\"obj\"][\"a\"]) to be 1, was " << doc["obj"]["a"].first << endl; return false; } tie(obj, error) = obj["obj"].as_object(); - if (obj["a"].as_uint64_t().first != 1) { cerr << "Expected uint64_t(obj[\"a\"]) to be 1, was " << obj["a"] << endl; return false; } - if (obj["b"].as_uint64_t().first != 2) { cerr << "Expected uint64_t(obj[\"b\"]) to be 2, was " << obj["a"] << endl; return false; } - if (obj["c"].as_uint64_t().first != 3) { cerr << "Expected uint64_t(obj[\"c\"]) to be 3, was " << obj["a"] << endl; return false; } + if (obj["a"].as_uint64_t().first != 1) { cerr << "Expected uint64_t(obj[\"a\"]) to be 1, was " << obj["a"].first << endl; return false; } + if (obj["b"].as_uint64_t().first != 2) { cerr << "Expected uint64_t(obj[\"b\"]) to be 2, was " << obj["b"].first << endl; return false; } + if (obj["c"].as_uint64_t().first != 3) { cerr << "Expected uint64_t(obj[\"c\"]) to be 3, was " << obj["c"].first << endl; return false; } // Check all three again in backwards order, to ensure we can go backwards - if (obj["c"].as_uint64_t().first != 3) { cerr << "Expected uint64_t(obj[\"c\"]) to be 3, was " << obj["a"] << endl; return false; } - if (obj["b"].as_uint64_t().first != 2) { cerr << "Expected uint64_t(obj[\"b\"]) to be 2, was " << obj["a"] << endl; return false; } - if (obj["a"].as_uint64_t().first != 1) { cerr << "Expected uint64_t(obj[\"a\"]) to be 1, was " << obj["a"] << endl; return false; } + if (obj["c"].as_uint64_t().first != 3) { cerr << "Expected uint64_t(obj[\"c\"]) to be 3, was " << obj["c"].first << endl; return false; } + if (obj["b"].as_uint64_t().first != 2) { cerr << "Expected uint64_t(obj[\"b\"]) to be 2, was " << obj["b"].first << endl; return false; } + if (obj["a"].as_uint64_t().first != 1) { cerr << "Expected uint64_t(obj[\"a\"]) to be 1, was " << obj["a"].first << endl; return false; } UNUSED document::element val; tie(val, error) = doc["d"]; @@ -1183,19 +1183,108 @@ namespace format_tests { } bool print_document_parse() { + std::cout << "Running " << __func__ << std::endl; + auto [doc, error] = document::parse(DOCUMENT); + if (error) { cerr << error << endl; return false; } + ostringstream s; + s << doc; + return assert_minified(s); + } + bool print_minify_document_parse() { + std::cout << "Running " << __func__ << std::endl; + auto [doc, error] = document::parse(DOCUMENT); + if (error) { cerr << error << endl; return false; } + ostringstream s; + s << minify(doc); + return assert_minified(s); + } + + bool print_parser_parse() { + std::cout << "Running " << __func__ << std::endl; + document::parser parser; + auto [doc, error] = parser.parse(DOCUMENT); + if (error) { cerr << error << endl; return false; } + ostringstream s; + s << doc; + return assert_minified(s); + } + bool print_minify_parser_parse() { + std::cout << "Running " << __func__ << std::endl; + document::parser parser; + auto [doc, error] = parser.parse(DOCUMENT); + if (error) { cerr << error << endl; return false; } + ostringstream s; + s << minify(doc); + return assert_minified(s); + } + + bool print_element() { + std::cout << "Running " << __func__ << std::endl; + document::parser parser; + auto [value, error] = parser.parse(DOCUMENT)["foo"]; + ostringstream s; + s << value; + return assert_minified(s, "1"); + } + bool print_minify_element() { + std::cout << "Running " << __func__ << std::endl; + document::parser parser; + auto [value, error] = parser.parse(DOCUMENT)["foo"]; + ostringstream s; + s << minify(value); + return assert_minified(s, "1"); + } + + bool print_array() { + std::cout << "Running " << __func__ << std::endl; + document::parser parser; + auto [value, error] = parser.parse(DOCUMENT)["bar"].as_array(); + ostringstream s; + s << value; + return assert_minified(s, "[1,2,3]"); + } + bool print_minify_array() { + std::cout << "Running " << __func__ << std::endl; + document::parser parser; + auto [value, error] = parser.parse(DOCUMENT)["bar"].as_array(); + ostringstream s; + s << minify(value); + return assert_minified(s, "[1,2,3]"); + } + + bool print_object() { + std::cout << "Running " << __func__ << std::endl; + document::parser parser; + auto [value, error] = parser.parse(DOCUMENT)["baz"].as_object(); + ostringstream s; + s << value; + return assert_minified(s, R"({"a":1,"b":2,"c":3})"); + } + bool print_minify_object() { + std::cout << "Running " << __func__ << std::endl; + document::parser parser; + auto [value, error] = parser.parse(DOCUMENT)["baz"].as_object(); + ostringstream s; + s << minify(value); + return assert_minified(s, R"({"a":1,"b":2,"c":3})"); + } + +#if SIMDJSON_EXCEPTIONS + + bool print_document_parse_exception() { std::cout << "Running " << __func__ << std::endl; ostringstream s; s << document::parse(DOCUMENT); return assert_minified(s); } - bool print_minify_document_parse() { + bool print_minify_document_parse_exception() { std::cout << "Running " << __func__ << std::endl; ostringstream s; s << minify(document::parse(DOCUMENT)); return assert_minified(s); } - bool print_parser_parse() { + bool print_parser_parse_exception() { std::cout << "Running " << __func__ << std::endl; document::parser parser; if (!parser.allocate_capacity(DOCUMENT.length())) { cerr << "Couldn't allocate!" << endl; return false; } @@ -1203,7 +1292,7 @@ namespace format_tests { s << parser.parse(DOCUMENT); return assert_minified(s); } - bool print_minify_parser_parse() { + bool print_minify_parser_parse_exception() { std::cout << "Running " << __func__ << std::endl; document::parser parser; if (!parser.allocate_capacity(DOCUMENT.length())) { cerr << "Couldn't allocate!" << endl; return false; } @@ -1212,48 +1301,14 @@ namespace format_tests { return assert_minified(s); } - bool print_document() { - std::cout << "Running " << __func__ << std::endl; - document doc = document::parse(DOCUMENT); - ostringstream s; - s << doc; - return assert_minified(s); - } - bool print_minify_document() { - std::cout << "Running " << __func__ << std::endl; - document doc = document::parse(DOCUMENT); - ostringstream s; - s << minify(doc); - return assert_minified(s); - } - - bool print_document_ref() { - std::cout << "Running " << __func__ << std::endl; - document::parser parser; - if (!parser.allocate_capacity(DOCUMENT.length())) { cerr << "Couldn't allocate!" << endl; return false; } - const document &doc_ref = parser.parse(DOCUMENT); - ostringstream s; - s << doc_ref; - return assert_minified(s); - } - bool print_minify_document_ref() { - std::cout << "Running " << __func__ << std::endl; - document::parser parser; - if (!parser.allocate_capacity(DOCUMENT.length())) { cerr << "Couldn't allocate!" << endl; return false; } - const document &doc_ref = parser.parse(DOCUMENT); - ostringstream s; - s << minify(doc_ref); - return assert_minified(s); - } - - bool print_element_result() { + bool print_element_result_exception() { std::cout << "Running " << __func__ << std::endl; const document &doc = document::parse(DOCUMENT); ostringstream s; s << doc["foo"]; return assert_minified(s, "1"); } - bool print_minify_element_result() { + bool print_minify_element_result_exception() { std::cout << "Running " << __func__ << std::endl; const document &doc = document::parse(DOCUMENT); ostringstream s; @@ -1261,7 +1316,7 @@ namespace format_tests { return assert_minified(s, "1"); } - bool print_element() { + bool print_element_exception() { std::cout << "Running " << __func__ << std::endl; const document &doc = document::parse(DOCUMENT); document::element value = doc["foo"]; @@ -1269,7 +1324,7 @@ namespace format_tests { s << value; return assert_minified(s, "1"); } - bool print_minify_element() { + bool print_minify_element_exception() { std::cout << "Running " << __func__ << std::endl; const document &doc = document::parse(DOCUMENT); document::element value = doc["foo"]; @@ -1278,14 +1333,14 @@ namespace format_tests { return assert_minified(s, "1"); } - bool print_array_result() { + bool print_array_result_exception() { std::cout << "Running " << __func__ << std::endl; const document &doc = document::parse(DOCUMENT); ostringstream s; s << doc["bar"].as_array(); return assert_minified(s, "[1,2,3]"); } - bool print_minify_array_result() { + bool print_minify_array_result_exception() { std::cout << "Running " << __func__ << std::endl; const document &doc = document::parse(DOCUMENT); ostringstream s; @@ -1293,14 +1348,14 @@ namespace format_tests { return assert_minified(s, "[1,2,3]"); } - bool print_object_result() { + bool print_object_result_exception() { std::cout << "Running " << __func__ << std::endl; const document &doc = document::parse(DOCUMENT); ostringstream s; s << doc["baz"].as_object(); return assert_minified(s, R"({"a":1,"b":2,"c":3})"); } - bool print_minify_object_result() { + bool print_minify_object_result_exception() { std::cout << "Running " << __func__ << std::endl; const document &doc = document::parse(DOCUMENT); ostringstream s; @@ -1308,8 +1363,7 @@ namespace format_tests { return assert_minified(s, R"({"a":1,"b":2,"c":3})"); } -#if SIMDJSON_EXCEPTIONS - bool print_array() { + bool print_array_exception() { std::cout << "Running " << __func__ << std::endl; const document &doc = document::parse(DOCUMENT); document::array value = doc["bar"]; @@ -1317,7 +1371,7 @@ namespace format_tests { s << value; return assert_minified(s, "[1,2,3]"); } - bool print_minify_array() { + bool print_minify_array_exception() { std::cout << "Running " << __func__ << std::endl; const document &doc = document::parse(DOCUMENT); document::array value = doc["bar"]; @@ -1326,7 +1380,7 @@ namespace format_tests { return assert_minified(s, "[1,2,3]"); } - bool print_object() { + bool print_object_exception() { std::cout << "Running " << __func__ << std::endl; const document &doc = document::parse(DOCUMENT); document::object value = doc["baz"]; @@ -1334,7 +1388,7 @@ namespace format_tests { s << value; return assert_minified(s, R"({"a":1,"b":2,"c":3})"); } - bool print_minify_object() { + bool print_minify_object_exception() { std::cout << "Running " << __func__ << std::endl; const document &doc = document::parse(DOCUMENT); document::object value = doc["baz"]; @@ -1347,15 +1401,18 @@ namespace format_tests { bool run_tests() { return print_document_parse() && print_minify_document_parse() && print_parser_parse() && print_minify_parser_parse() && - print_document() && print_minify_document() && - print_document_ref() && print_minify_document_ref() && - print_element_result() && print_minify_element_result() && - print_array_result() && print_minify_array_result() && - print_object_result() && print_minify_object_result() && print_element() && print_minify_element() && -#if SIMDJSON_EXCEPTIONS print_array() && print_minify_array() && print_object() && print_minify_object() && +#if SIMDJSON_EXCEPTIONS + print_document_parse_exception() && print_minify_document_parse_exception() && + print_parser_parse_exception() && print_minify_parser_parse_exception() && + print_element_result_exception() && print_minify_element_result_exception() && + print_array_result_exception() && print_minify_array_result_exception() && + print_object_result_exception() && print_minify_object_result_exception() && + print_element_exception() && print_minify_element_exception() && + print_array_exception() && print_minify_array_exception() && + print_object_exception() && print_minify_object_exception() && #endif true; } diff --git a/tests/integer_tests.cpp b/tests/integer_tests.cpp index e36566d1a..c9193b5c7 100644 --- a/tests/integer_tests.cpp +++ b/tests/integer_tests.cpp @@ -48,8 +48,8 @@ static void parse_and_validate(const std::string src, T expected) { } std::cout << std::boolalpha << "test: " << result << std::endl; if(!result) { - std::cerr << "bug detected" << std::endl; - throw std::runtime_error("bug"); + std::cerr << "bug detected" << std::endl; + exit(EXIT_FAILURE); } } diff --git a/tests/parse_many_test.cpp b/tests/parse_many_test.cpp index 186128aa6..80f239cc7 100644 --- a/tests/parse_many_test.cpp +++ b/tests/parse_many_test.cpp @@ -75,13 +75,14 @@ bool validate(const char *dirname) { /* The actual test*/ - simdjson::padded_string json = simdjson::padded_string::load(fullpath); - simdjson::document::parser parser; + auto [json, error] = simdjson::padded_string::load(fullpath); + if (!error) { + simdjson::document::parser parser; - ++how_many; - simdjson::error_code error = simdjson::SUCCESS; - for (auto result : parser.parse_many(json)) { - error = result.error(); + ++how_many; + for (auto result : parser.parse_many(json)) { + error = result.error(); + } } printf("%s\n", error ? "ok" : "invalid"); /* Check if the file is supposed to pass or not. Print the results */ diff --git a/tests/readme_examples.cpp b/tests/readme_examples.cpp index 1d0ea17f5..2a00fc17f 100644 --- a/tests/readme_examples.cpp +++ b/tests/readme_examples.cpp @@ -12,33 +12,6 @@ void document_parse_error_code() { cout << doc << endl; } -void document_parse_exception() { - cout << __func__ << endl; - - string json("[ 1, 2, 3 ]"); - cout << document::parse(json) << endl; -} - -void document_parse_padded_string() { - cout << __func__ << endl; - - padded_string json(string("[ 1, 2, 3 ]")); - cout << document::parse(json) << endl; -} - -void document_parse_get_corpus() { - cout << __func__ << endl; - - auto json = get_corpus("jsonexamples/small/demo.json"); - cout << document::parse(json) << endl; -} - -void document_load() { - cout << __func__ << endl; - - cout << document::load("jsonexamples/small/demo.json") << endl; -} - void parser_parse_error_code() { cout << __func__ << endl; @@ -54,19 +27,6 @@ void parser_parse_error_code() { } } -void parser_parse_exception() { - cout << __func__ << endl; - - // Allocate a parser big enough for all files - document::parser parser; - - // Read files with the parser, one by one - for (padded_string json : { string("[1, 2, 3]"), string("true"), string("[ true, false ]") }) { - cout << "Parsing " << json.data() << " ..." << endl; - cout << parser.parse(json) << endl; - } -} - void parser_parse_many_error_code() { cout << __func__ << endl; @@ -80,18 +40,6 @@ void parser_parse_many_error_code() { } } -void parser_parse_many_exception() { - cout << __func__ << endl; - - // Read files with the parser - padded_string json = string("[1, 2, 3] true [ true, false ]"); - cout << "Parsing " << json.data() << " ..." << endl; - document::parser parser; - for (const document &doc : parser.parse_many(json)) { - cout << doc << endl; - } -} - void parser_parse_max_capacity() { int argc = 2; padded_string argv[] { string("[1,2,3]"), string("true") }; @@ -118,19 +66,77 @@ void parser_parse_fixed_capacity() { } } +#if SIMDJSON_EXCEPTIONS + +void document_parse_exception() { + cout << __func__ << endl; + + string json("[ 1, 2, 3 ]"); + cout << document::parse(json) << endl; +} + +void document_parse_padded_string() { + cout << __func__ << endl; + + padded_string json(string("[ 1, 2, 3 ]")); + cout << document::parse(json) << endl; +} + +void document_parse_get_corpus() { + cout << __func__ << endl; + + auto json = get_corpus("jsonexamples/small/demo.json"); + cout << document::parse(json) << endl; +} + +void document_load() { + cout << __func__ << endl; + + cout << document::load("jsonexamples/small/demo.json") << endl; +} + +void parser_parse_exception() { + cout << __func__ << endl; + + // Allocate a parser big enough for all files + document::parser parser; + + // Read files with the parser, one by one + for (padded_string json : { string("[1, 2, 3]"), string("true"), string("[ true, false ]") }) { + cout << "Parsing " << json.data() << " ..." << endl; + cout << parser.parse(json) << endl; + } +} + +void parser_parse_many_exception() { + cout << __func__ << endl; + + // Read files with the parser + padded_string json = string("[1, 2, 3] true [ true, false ]"); + cout << "Parsing " << json.data() << " ..." << endl; + document::parser parser; + for (const document &doc : parser.parse_many(json)) { + cout << doc << endl; + } +} + +#endif // SIMDJSON_EXCEPTIONS + int main() { cout << "Running examples." << endl; document_parse_error_code(); + parser_parse_error_code(); + parser_parse_many_error_code(); + parser_parse_max_capacity(); + parser_parse_fixed_capacity(); +#if SIMDJSON_EXCEPTIONS document_parse_exception(); + parser_parse_exception(); + parser_parse_many_exception(); document_parse_padded_string(); document_parse_get_corpus(); document_load(); - parser_parse_error_code(); - parser_parse_exception(); - parser_parse_many_error_code(); - parser_parse_many_exception(); - parser_parse_max_capacity(); - parser_parse_fixed_capacity(); +#endif // SIMDJSON_EXCEPTIONS cout << "Ran to completion!" << endl; return 0; } diff --git a/tools/jsonpointer.cpp b/tools/jsonpointer.cpp index 427cd6694..1d508d0e5 100644 --- a/tools/jsonpointer.cpp +++ b/tools/jsonpointer.cpp @@ -67,7 +67,7 @@ int main(int argc, char *argv[]) { std::cout << "[" << std::endl; for (int idx = 2; idx < argc; idx++) { const char *jsonpath = argv[idx]; - simdjson::ParsedJson::Iterator it(pj); + simdjson::ParsedJson::Iterator it(pj.doc); if (it.move_to(std::string(jsonpath))) { std::cout << "{\"jsonpath\": \"" << jsonpath << "\"," << std::endl; std::cout << "\"value\":";