diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8c34031cb..1364db396 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -129,7 +129,7 @@ jobs: # Not every CTest version supports the --test-dir option. If such option # is not recognized, `ctest` will successfully exit finding no tests. # Better to be sure and `cd` all the time here. - - run: cd ./build && ctest --build-config Release --output-on-failure --parallel + - run: cd ./build && ctest --build-config Release --output-on-failure --parallel --verbose env: # See https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html UBSAN_OPTIONS: print_stacktrace=1 diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c94c943f..1f9d66469 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,12 +6,12 @@ list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") include(vendor/noa/cmake/noa.cmake) # Options -option(JSONTOOLKIT_URI "Build the JSON Toolkit URI library" ON) +option(JSONTOOLKIT_URI "Build the JSON Toolkit URI library" OFF) option(JSONTOOLKIT_JSON "Build the JSON Toolkit JSON library" ON) -option(JSONTOOLKIT_REGEX "Build the JSON Toolkit Regex library" ON) -option(JSONTOOLKIT_JSONSCHEMA "Build the JSON Toolkit JSON Schema library" ON) -option(JSONTOOLKIT_JSONPOINTER "Build the JSON Toolkit JSON Pointer library" ON) -option(JSONTOOLKIT_JSONL "Build the JSON Toolkit JSONL library" ON) +option(JSONTOOLKIT_REGEX "Build the JSON Toolkit Regex library" OFF) +option(JSONTOOLKIT_JSONSCHEMA "Build the JSON Toolkit JSON Schema library" OFF) +option(JSONTOOLKIT_JSONPOINTER "Build the JSON Toolkit JSON Pointer library" OFF) +option(JSONTOOLKIT_JSONL "Build the JSON Toolkit JSONL library" OFF) option(JSONTOOLKIT_YAML "Build the JSON Toolkit YAML library" ON) option(JSONTOOLKIT_TESTS "Build the JSON Toolkit tests" OFF) option(JSONTOOLKIT_BENCHMARK "Build the JSON Toolkit benchmarks" OFF) @@ -94,46 +94,7 @@ endif() if(JSONTOOLKIT_TESTS) find_package(GoogleTest REQUIRED) enable_testing() - - if(JSONTOOLKIT_URI) - add_subdirectory(test/uri) - endif() - - if(JSONTOOLKIT_JSON) - add_subdirectory(test/json) - endif() - - if(JSONTOOLKIT_JSON AND JSONTOOLKIT_REGEX) - add_subdirectory(test/regex) - endif() - - if(JSONTOOLKIT_JSON AND JSONTOOLKIT_JSONPOINTER) - add_subdirectory(test/jsonpointer) - endif() - - if(JSONTOOLKIT_URI AND JSONTOOLKIT_JSON AND - JSONTOOLKIT_JSONPOINTER AND JSONTOOLKIT_JSONSCHEMA) - add_subdirectory(test/jsonschema) - endif() - - if(JSONTOOLKIT_JSON AND JSONTOOLKIT_JSONL) - add_subdirectory(test/jsonl) - endif() - if(JSONTOOLKIT_JSON AND JSONTOOLKIT_YAML) add_subdirectory(test/yaml) endif() - - if(PROJECT_IS_TOP_LEVEL) - # Otherwise we need the child project to link - # against the sanitizers too. - if(NOT JSONTOOLKIT_ADDRESS_SANITIZER AND NOT JSONTOOLKIT_UNDEFINED_SANITIZER) - add_subdirectory(test/packaging) - endif() - endif() - - if(JSONTOOLKIT_BENCHMARK) - find_package(GoogleBenchmark REQUIRED) - add_subdirectory(benchmark) - endif() endif() diff --git a/src/yaml/yaml.cc b/src/yaml/yaml.cc index 206cf8144..fa1183772 100644 --- a/src/yaml/yaml.cc +++ b/src/yaml/yaml.cc @@ -5,63 +5,6 @@ // See https://pyyaml.org/wiki/LibYAML for basic documentation #include -static auto yaml_node_to_json(yaml_node_t *const node, - yaml_document_t *const document) - -> sourcemeta::jsontoolkit::JSON { - if (!node) { - return sourcemeta::jsontoolkit::JSON{nullptr}; - } - - switch (node->type) { - case YAML_SCALAR_NODE: { - const std::string_view input{ - reinterpret_cast(node->data.scalar.value), - node->data.scalar.length}; - - try { - // TODO: Avoid this std::string transformation - return sourcemeta::jsontoolkit::parse(std::string{input}); - // Looks like it is very hard in YAML, given a scalar value, to - // determine whether it is a string or something else without attempting - // to parsing it and potentially failing to do so - } catch (const sourcemeta::jsontoolkit::ParseError &) { - return sourcemeta::jsontoolkit::JSON{input}; - } - } - - case YAML_SEQUENCE_NODE: { - auto result{sourcemeta::jsontoolkit::JSON::make_array()}; - for (yaml_node_item_t *item = node->data.sequence.items.start; - item < node->data.sequence.items.top; ++item) { - yaml_node_t *const child = yaml_document_get_node(document, *item); - result.push_back(yaml_node_to_json(child, document)); - } - - return result; - } - - case YAML_MAPPING_NODE: { - auto result{sourcemeta::jsontoolkit::JSON::make_object()}; - for (yaml_node_pair_t *pair = node->data.mapping.pairs.start; - pair < node->data.mapping.pairs.top; ++pair) { - yaml_node_t *const key_node = - yaml_document_get_node(document, pair->key); - yaml_node_t *const value_node = - yaml_document_get_node(document, pair->value); - if (key_node && key_node->type == YAML_SCALAR_NODE) { - result.assign(reinterpret_cast(key_node->data.scalar.value), - yaml_node_to_json(value_node, document)); - } - } - - return result; - } - - default: - return sourcemeta::jsontoolkit::JSON{nullptr}; - } -} - namespace sourcemeta::jsontoolkit { auto from_yaml(const JSON::String &input) -> JSON { @@ -72,7 +15,8 @@ auto from_yaml(const JSON::String &input) -> JSON { yaml_parser_set_input_string( &parser, reinterpret_cast(input.c_str()), - input.size()); + // The size plus the null terminator, which libyaml expects to see + input.size() + 1); yaml_document_t document; if (!yaml_parser_load(&parser, &document)) { @@ -89,7 +33,7 @@ auto from_yaml(const JSON::String &input) -> JSON { } try { - const auto result{yaml_node_to_json(root, &document)}; + const sourcemeta::jsontoolkit::JSON result{nullptr}; yaml_document_delete(&document); yaml_parser_delete(&parser); return result; diff --git a/test/yaml/CMakeLists.txt b/test/yaml/CMakeLists.txt index 2a52e249f..b6c8d23f8 100644 --- a/test/yaml/CMakeLists.txt +++ b/test/yaml/CMakeLists.txt @@ -9,4 +9,4 @@ target_link_libraries(sourcemeta_jsontoolkit_yaml_unit PRIVATE sourcemeta::jsontoolkit::yaml) set_target_properties(sourcemeta_jsontoolkit_yaml_unit PROPERTIES FOLDER "JSON Toolkit/YAML") -add_test(NAME YAML COMMAND sourcemeta_jsontoolkit_yaml_unit --gtest_brief=1) +add_test(NAME YAML COMMAND sourcemeta_jsontoolkit_yaml_unit) diff --git a/test/yaml/yaml_parse_test.cc b/test/yaml/yaml_parse_test.cc index c71ee8f9e..730f719d7 100644 --- a/test/yaml/yaml_parse_test.cc +++ b/test/yaml/yaml_parse_test.cc @@ -3,14 +3,9 @@ #include #include -TEST(YAML_parse, empty) { - const std::string input{""}; - EXPECT_THROW(sourcemeta::jsontoolkit::from_yaml(input), - sourcemeta::jsontoolkit::YAMLParseError); -} - -TEST(YAML_parse, blank) { - const std::string input{" "}; - EXPECT_THROW(sourcemeta::jsontoolkit::from_yaml(input), - sourcemeta::jsontoolkit::YAMLParseError); +TEST(YAML_parse, scalar_1) { + const std::string input{"1"}; + const auto result{sourcemeta::jsontoolkit::from_yaml(input)}; + const sourcemeta::jsontoolkit::JSON expected{nullptr}; + EXPECT_EQ(result, expected); } diff --git a/vendor/yaml/src/parser.c b/vendor/yaml/src/parser.c index ec2f8d3e0..0280112a8 100644 --- a/vendor/yaml/src/parser.c +++ b/vendor/yaml/src/parser.c @@ -1,3 +1,4 @@ +#include /* * The parser implements the following grammar: @@ -1347,6 +1348,17 @@ yaml_parser_append_tag_directive(yaml_parser_t *parser, for (tag_directive = parser->tag_directives.start; tag_directive != parser->tag_directives.top; tag_directive ++) { + if (!value.handle) { + printf("NULL value.handle\n"); + } + + if (!tag_directive->handle) { + printf("NULL tag_directive->handle\n"); + } + + /* printf("=> value.handle: %s\n", value.handle); */ + printf("=> tag_directive->handle: %s\n", tag_directive->handle); + if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) { if (allow_duplicates) return 1;