mirror of
https://github.com/tristanpenman/valijson.git
synced 2024-12-12 18:20:27 +01:00
Update embedded version of json11 so that tests can be built using clang 4+
This commit is contained in:
parent
29c566dea4
commit
665741110c
@ -47,11 +47,11 @@ target_include_directories(jsoncpp SYSTEM PRIVATE thirdparty/jsoncpp-0.9.4/inclu
|
|||||||
set_target_properties(jsoncpp PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/thirdparty/jsoncpp-0.9.4)
|
set_target_properties(jsoncpp PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/thirdparty/jsoncpp-0.9.4)
|
||||||
|
|
||||||
add_library(json11
|
add_library(json11
|
||||||
thirdparty/json11-2016-01-26/json11.cpp
|
thirdparty/json11-ec4e452/json11.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(json11 SYSTEM PRIVATE thirdparty/json11-2016-01-26)
|
target_include_directories(json11 SYSTEM PRIVATE thirdparty/json11-ec4e452)
|
||||||
set_target_properties(json11 PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/thirdparty/json11-2016-01-26)
|
set_target_properties(json11 PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/thirdparty/json11-ec4e452)
|
||||||
|
|
||||||
# Build local gtest
|
# Build local gtest
|
||||||
set(gtest_force_shared_crt ON)
|
set(gtest_force_shared_crt ON)
|
||||||
@ -61,7 +61,7 @@ add_subdirectory(thirdparty/gtest-1.7.0)
|
|||||||
include_directories(include)
|
include_directories(include)
|
||||||
include_directories(SYSTEM
|
include_directories(SYSTEM
|
||||||
thirdparty/gtest-1.7.0/include
|
thirdparty/gtest-1.7.0/include
|
||||||
thirdparty/json11-2016-01-26
|
thirdparty/json11-ec4e452
|
||||||
thirdparty/jsoncpp-0.9.4/include
|
thirdparty/jsoncpp-0.9.4/include
|
||||||
thirdparty/rapidjson-1.0.2/include
|
thirdparty/rapidjson-1.0.2/include
|
||||||
thirdparty/picojson-1.3.0
|
thirdparty/picojson-1.3.0
|
||||||
|
1
thirdparty/json11-2016-01-26/.gitignore
vendored
1
thirdparty/json11-2016-01-26/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
test
|
|
21
thirdparty/json11-2016-01-26/CMakeLists.txt
vendored
21
thirdparty/json11-2016-01-26/CMakeLists.txt
vendored
@ -1,21 +0,0 @@
|
|||||||
project(json11)
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 2.8)
|
|
||||||
|
|
||||||
enable_testing()
|
|
||||||
|
|
||||||
add_definitions(
|
|
||||||
-std=c++11
|
|
||||||
-fno-rtti
|
|
||||||
-fno-exceptions
|
|
||||||
-Wall
|
|
||||||
-Wextra
|
|
||||||
-Werror)
|
|
||||||
|
|
||||||
set(json11_SRCS json11.cpp)
|
|
||||||
|
|
||||||
add_library(json11 STATIC ${json11_SRCS})
|
|
||||||
|
|
||||||
add_test(json11_test json11_test)
|
|
||||||
|
|
||||||
add_executable(json11_test ${json11_SRCS} test.cpp)
|
|
7
thirdparty/json11-2016-01-26/Makefile
vendored
7
thirdparty/json11-2016-01-26/Makefile
vendored
@ -1,7 +0,0 @@
|
|||||||
test: json11.cpp json11.hpp test.cpp
|
|
||||||
$(CXX) -O -std=c++11 json11.cpp test.cpp -o test -fno-rtti -fno-exceptions
|
|
||||||
|
|
||||||
clean:
|
|
||||||
if [ -e test ]; then rm test; fi
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
205
thirdparty/json11-2016-01-26/test.cpp
vendored
205
thirdparty/json11-2016-01-26/test.cpp
vendored
@ -1,205 +0,0 @@
|
|||||||
#include <string>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstring>
|
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include "json11.hpp"
|
|
||||||
#include <cassert>
|
|
||||||
#include <list>
|
|
||||||
#include <set>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
using namespace json11;
|
|
||||||
using std::string;
|
|
||||||
|
|
||||||
// Check that Json has the properties we want.
|
|
||||||
#include <type_traits>
|
|
||||||
#define CHECK_TRAIT(x) static_assert(std::x::value, #x)
|
|
||||||
CHECK_TRAIT(is_nothrow_constructible<Json>);
|
|
||||||
CHECK_TRAIT(is_nothrow_default_constructible<Json>);
|
|
||||||
CHECK_TRAIT(is_copy_constructible<Json>);
|
|
||||||
CHECK_TRAIT(is_nothrow_move_constructible<Json>);
|
|
||||||
CHECK_TRAIT(is_copy_assignable<Json>);
|
|
||||||
CHECK_TRAIT(is_nothrow_move_assignable<Json>);
|
|
||||||
CHECK_TRAIT(is_nothrow_destructible<Json>);
|
|
||||||
|
|
||||||
void parse_from_stdin() {
|
|
||||||
string buf;
|
|
||||||
string line;
|
|
||||||
while (std::getline(std::cin, line)) {
|
|
||||||
buf += line + "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
string err;
|
|
||||||
auto json = Json::parse(buf, err);
|
|
||||||
if (!err.empty()) {
|
|
||||||
printf("Failed: %s\n", err.c_str());
|
|
||||||
} else {
|
|
||||||
printf("Result: %s\n", json.dump().c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
if (argc == 2 && argv[1] == string("--stdin")) {
|
|
||||||
parse_from_stdin();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const string simple_test =
|
|
||||||
R"({"k1":"v1", "k2":42, "k3":["a",123,true,false,null]})";
|
|
||||||
|
|
||||||
string err;
|
|
||||||
auto json = Json::parse(simple_test, err);
|
|
||||||
|
|
||||||
std::cout << "k1: " << json["k1"].string_value() << "\n";
|
|
||||||
std::cout << "k3: " << json["k3"].dump() << "\n";
|
|
||||||
|
|
||||||
for (auto &k : json["k3"].array_items()) {
|
|
||||||
std::cout << " - " << k.dump() << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
const string comment_test = R"({
|
|
||||||
// comment /* with nested comment */
|
|
||||||
"a": 1,
|
|
||||||
// comment
|
|
||||||
// continued
|
|
||||||
"b": "text",
|
|
||||||
/* multi
|
|
||||||
line
|
|
||||||
comment */
|
|
||||||
// and single-line comment
|
|
||||||
"c": [1, 2, 3]
|
|
||||||
})";
|
|
||||||
|
|
||||||
string err_comment;
|
|
||||||
auto json_comment = Json::parse(
|
|
||||||
comment_test, err_comment, JsonParse::COMMENTS);
|
|
||||||
if (!err_comment.empty()) {
|
|
||||||
printf("Failed: %s\n", err_comment.c_str());
|
|
||||||
} else {
|
|
||||||
printf("Result: %s\n", json_comment.dump().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
string failing_comment_test = R"({
|
|
||||||
/* bad comment
|
|
||||||
"a": 1,
|
|
||||||
})";
|
|
||||||
|
|
||||||
string err_failing_comment;
|
|
||||||
auto json_failing_comment = Json::parse(
|
|
||||||
failing_comment_test, err_failing_comment, JsonParse::COMMENTS);
|
|
||||||
if (!err_failing_comment.empty()) {
|
|
||||||
printf("Failed: %s\n", err_failing_comment.c_str());
|
|
||||||
} else {
|
|
||||||
printf("Result: %s\n", json_failing_comment.dump().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
failing_comment_test = R"({
|
|
||||||
/ / bad comment })";
|
|
||||||
|
|
||||||
json_failing_comment = Json::parse(
|
|
||||||
failing_comment_test, err_failing_comment, JsonParse::COMMENTS);
|
|
||||||
if (!err_failing_comment.empty()) {
|
|
||||||
printf("Failed: %s\n", err_failing_comment.c_str());
|
|
||||||
} else {
|
|
||||||
printf("Result: %s\n", json_failing_comment.dump().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
failing_comment_test = R"({// bad comment })";
|
|
||||||
|
|
||||||
json_failing_comment = Json::parse(
|
|
||||||
failing_comment_test, err_failing_comment, JsonParse::COMMENTS);
|
|
||||||
if (!err_failing_comment.empty()) {
|
|
||||||
printf("Failed: %s\n", err_failing_comment.c_str());
|
|
||||||
} else {
|
|
||||||
printf("Result: %s\n", json_failing_comment.dump().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
failing_comment_test = R"({
|
|
||||||
"a": 1
|
|
||||||
}/)";
|
|
||||||
|
|
||||||
json_failing_comment = Json::parse(
|
|
||||||
failing_comment_test, err_failing_comment, JsonParse::COMMENTS);
|
|
||||||
if (!err_failing_comment.empty()) {
|
|
||||||
printf("Failed: %s\n", err_failing_comment.c_str());
|
|
||||||
} else {
|
|
||||||
printf("Result: %s\n", json_failing_comment.dump().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
failing_comment_test = R"({/* bad
|
|
||||||
comment *})";
|
|
||||||
|
|
||||||
json_failing_comment = Json::parse(
|
|
||||||
failing_comment_test, err_failing_comment, JsonParse::COMMENTS);
|
|
||||||
if (!err_failing_comment.empty()) {
|
|
||||||
printf("Failed: %s\n", err_failing_comment.c_str());
|
|
||||||
} else {
|
|
||||||
printf("Result: %s\n", json_failing_comment.dump().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<int> l1 { 1, 2, 3 };
|
|
||||||
std::vector<int> l2 { 1, 2, 3 };
|
|
||||||
std::set<int> l3 { 1, 2, 3 };
|
|
||||||
assert(Json(l1) == Json(l2));
|
|
||||||
assert(Json(l2) == Json(l3));
|
|
||||||
|
|
||||||
std::map<string, string> m1 { { "k1", "v1" }, { "k2", "v2" } };
|
|
||||||
std::unordered_map<string, string> m2 { { "k1", "v1" }, { "k2", "v2" } };
|
|
||||||
assert(Json(m1) == Json(m2));
|
|
||||||
|
|
||||||
// Json literals
|
|
||||||
Json obj = Json::object({
|
|
||||||
{ "k1", "v1" },
|
|
||||||
{ "k2", 42.0 },
|
|
||||||
{ "k3", Json::array({ "a", 123.0, true, false, nullptr }) },
|
|
||||||
});
|
|
||||||
|
|
||||||
std::cout << "obj: " << obj.dump() << "\n";
|
|
||||||
|
|
||||||
assert(Json("a").number_value() == 0);
|
|
||||||
assert(Json("a").string_value() == "a");
|
|
||||||
assert(Json().number_value() == 0);
|
|
||||||
|
|
||||||
assert(obj == json);
|
|
||||||
assert(Json(42) == Json(42.0));
|
|
||||||
assert(Json(42) != Json(42.1));
|
|
||||||
|
|
||||||
const string unicode_escape_test =
|
|
||||||
R"([ "blah\ud83d\udca9blah\ud83dblah\udca9blah\u0000blah\u1234" ])";
|
|
||||||
|
|
||||||
const char utf8[] = "blah" "\xf0\x9f\x92\xa9" "blah" "\xed\xa0\xbd" "blah"
|
|
||||||
"\xed\xb2\xa9" "blah" "\0" "blah" "\xe1\x88\xb4";
|
|
||||||
|
|
||||||
Json uni = Json::parse(unicode_escape_test, err);
|
|
||||||
assert(uni[0].string_value().size() == (sizeof utf8) - 1);
|
|
||||||
assert(std::memcmp(uni[0].string_value().data(), utf8, sizeof utf8) == 0);
|
|
||||||
|
|
||||||
// Demonstrates the behavior change in Xcode 7 / Clang 3.7 described
|
|
||||||
// here: https://llvm.org/bugs/show_bug.cgi?id=23812
|
|
||||||
Json nested_array = Json::array { Json::array { 1, 2, 3 } };
|
|
||||||
assert(nested_array.is_array());
|
|
||||||
assert(nested_array.array_items().size() == 1);
|
|
||||||
assert(nested_array.array_items()[0].is_array());
|
|
||||||
assert(nested_array.array_items()[0].array_items().size() == 3);
|
|
||||||
|
|
||||||
Json my_json = Json::object {
|
|
||||||
{ "key1", "value1" },
|
|
||||||
{ "key2", false },
|
|
||||||
{ "key3", Json::array { 1, 2, 3 } },
|
|
||||||
};
|
|
||||||
std::string json_str = my_json.dump();
|
|
||||||
printf("%s\n", json_str.c_str());
|
|
||||||
|
|
||||||
class Point {
|
|
||||||
public:
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
Point (int x, int y) : x(x), y(y) {}
|
|
||||||
Json to_json() const { return Json::array { x, y }; }
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<Point> points = { { 1, 2 }, { 10, 20 }, { 100, 200 } };
|
|
||||||
std::string points_json = Json(points).dump();
|
|
||||||
printf("%s\n", points_json.c_str());
|
|
||||||
}
|
|
12
thirdparty/json11-ec4e452/.gitignore
vendored
Executable file
12
thirdparty/json11-ec4e452/.gitignore
vendored
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
# generated files
|
||||||
|
test
|
||||||
|
libjson11.a
|
||||||
|
json11.pc
|
||||||
|
|
||||||
|
# Cmake
|
||||||
|
CMakeCache.txt
|
||||||
|
CTestTestfile.cmake
|
||||||
|
CMakeFiles
|
||||||
|
CMakeScripts
|
||||||
|
cmake_install.cmake
|
||||||
|
install_manifest.txt
|
57
thirdparty/json11-ec4e452/CMakeLists.txt
vendored
Executable file
57
thirdparty/json11-ec4e452/CMakeLists.txt
vendored
Executable file
@ -0,0 +1,57 @@
|
|||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
if (CMAKE_VERSION VERSION_LESS "3")
|
||||||
|
project(json11 CXX)
|
||||||
|
else()
|
||||||
|
cmake_policy(SET CMP0048 NEW)
|
||||||
|
project(json11 VERSION 1.0.0 LANGUAGES CXX)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
enable_testing()
|
||||||
|
|
||||||
|
option(JSON11_BUILD_TESTS "Build unit tests" OFF)
|
||||||
|
option(JSON11_ENABLE_DR1467_CANARY "Enable canary test for DR 1467" OFF)
|
||||||
|
|
||||||
|
if(CMAKE_VERSION VERSION_LESS "3")
|
||||||
|
add_definitions(-std=c++11)
|
||||||
|
else()
|
||||||
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||||
|
set(CMAKE_INSTALL_PREFIX /usr)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_library(json11 json11.cpp)
|
||||||
|
target_include_directories(json11 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
target_compile_options(json11
|
||||||
|
PRIVATE -fPIC -fno-rtti -fno-exceptions -Wall)
|
||||||
|
|
||||||
|
# Set warning flags, which may vary per platform
|
||||||
|
include(CheckCXXCompilerFlag)
|
||||||
|
set(_possible_warnings_flags /W4 /WX -Wextra -Werror)
|
||||||
|
foreach(_warning_flag in ${_possible_warnings_flags})
|
||||||
|
CHECK_CXX_COMPILER_FLAG(_warning_flag _flag_supported)
|
||||||
|
if(${_flag_supported})
|
||||||
|
target_compile_options(json11 PRIVATE ${_warning_flag})
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
configure_file("json11.pc.in" "json11.pc" @ONLY)
|
||||||
|
|
||||||
|
if (JSON11_BUILD_TESTS)
|
||||||
|
|
||||||
|
# enable test for DR1467, described here: https://llvm.org/bugs/show_bug.cgi?id=23812
|
||||||
|
if(JSON11_ENABLE_DR1467_CANARY)
|
||||||
|
add_definitions(-D JSON11_ENABLE_DR1467_CANARY=1)
|
||||||
|
else()
|
||||||
|
add_definitions(-D JSON11_ENABLE_DR1467_CANARY=0)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_executable(json11_test test.cpp)
|
||||||
|
target_link_libraries(json11_test json11)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
install(TARGETS json11 DESTINATION lib/${CMAKE_LIBRARY_ARCHITECTURE})
|
||||||
|
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/json11.hpp" DESTINATION include/${CMAKE_LIBRARY_ARCHITECTURE})
|
||||||
|
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/json11.pc" DESTINATION lib/${CMAKE_LIBRARY_ARCHITECTURE}/pkgconfig)
|
0
thirdparty/json11-2016-01-26/LICENSE.txt → thirdparty/json11-ec4e452/LICENSE.txt
vendored
Normal file → Executable file
0
thirdparty/json11-2016-01-26/LICENSE.txt → thirdparty/json11-ec4e452/LICENSE.txt
vendored
Normal file → Executable file
15
thirdparty/json11-ec4e452/Makefile
vendored
Executable file
15
thirdparty/json11-ec4e452/Makefile
vendored
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
# Environment variable to enable or disable code which demonstrates the behavior change
|
||||||
|
# in Xcode 7 / Clang 3.7, introduced by DR1467 and described here:
|
||||||
|
# https://llvm.org/bugs/show_bug.cgi?id=23812
|
||||||
|
# Defaults to on in order to act as a warning to anyone who's unaware of the issue.
|
||||||
|
ifneq ($(JSON11_ENABLE_DR1467_CANARY),)
|
||||||
|
CANARY_ARGS = -DJSON11_ENABLE_DR1467_CANARY=$(JSON11_ENABLE_DR1467_CANARY)
|
||||||
|
endif
|
||||||
|
|
||||||
|
test: json11.cpp json11.hpp test.cpp
|
||||||
|
$(CXX) $(CANARY_ARGS) -O -std=c++11 json11.cpp test.cpp -o test -fno-rtti -fno-exceptions
|
||||||
|
|
||||||
|
clean:
|
||||||
|
if [ -e test ]; then rm test; fi
|
||||||
|
|
||||||
|
.PHONY: clean
|
0
thirdparty/json11-2016-01-26/README.md → thirdparty/json11-ec4e452/README.md
vendored
Normal file → Executable file
0
thirdparty/json11-2016-01-26/README.md → thirdparty/json11-ec4e452/README.md
vendored
Normal file → Executable file
59
thirdparty/json11-2016-01-26/json11.cpp → thirdparty/json11-ec4e452/json11.cpp
vendored
Normal file → Executable file
59
thirdparty/json11-2016-01-26/json11.cpp → thirdparty/json11-ec4e452/json11.cpp
vendored
Normal file → Executable file
@ -37,11 +37,20 @@ using std::make_shared;
|
|||||||
using std::initializer_list;
|
using std::initializer_list;
|
||||||
using std::move;
|
using std::move;
|
||||||
|
|
||||||
|
/* Helper for representing null - just a do-nothing struct, plus comparison
|
||||||
|
* operators so the helpers in JsonValue work. We can't use nullptr_t because
|
||||||
|
* it may not be orderable.
|
||||||
|
*/
|
||||||
|
struct NullStruct {
|
||||||
|
bool operator==(NullStruct) const { return true; }
|
||||||
|
bool operator<(NullStruct) const { return false; }
|
||||||
|
};
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * *
|
||||||
* Serialization
|
* Serialization
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void dump(std::nullptr_t, string &out) {
|
static void dump(NullStruct, string &out) {
|
||||||
out += "null";
|
out += "null";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,9 +217,9 @@ public:
|
|||||||
explicit JsonObject(Json::object &&value) : Value(move(value)) {}
|
explicit JsonObject(Json::object &&value) : Value(move(value)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class JsonNull final : public Value<Json::NUL, std::nullptr_t> {
|
class JsonNull final : public Value<Json::NUL, NullStruct> {
|
||||||
public:
|
public:
|
||||||
JsonNull() : Value(nullptr) {}
|
JsonNull() : Value({}) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * *
|
||||||
@ -291,6 +300,8 @@ const Json & JsonArray::operator[] (size_t i) const {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
bool Json::operator== (const Json &other) const {
|
bool Json::operator== (const Json &other) const {
|
||||||
|
if (m_ptr == other.m_ptr)
|
||||||
|
return true;
|
||||||
if (m_ptr->type() != other.m_ptr->type())
|
if (m_ptr->type() != other.m_ptr->type())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -298,6 +309,8 @@ bool Json::operator== (const Json &other) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Json::operator< (const Json &other) const {
|
bool Json::operator< (const Json &other) const {
|
||||||
|
if (m_ptr == other.m_ptr)
|
||||||
|
return false;
|
||||||
if (m_ptr->type() != other.m_ptr->type())
|
if (m_ptr->type() != other.m_ptr->type())
|
||||||
return m_ptr->type() < other.m_ptr->type();
|
return m_ptr->type() < other.m_ptr->type();
|
||||||
|
|
||||||
@ -326,11 +339,12 @@ static inline bool in_range(long x, long lower, long upper) {
|
|||||||
return (x >= lower && x <= upper);
|
return (x >= lower && x <= upper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
/* JsonParser
|
/* JsonParser
|
||||||
*
|
*
|
||||||
* Object that tracks all state of an in-progress parse.
|
* Object that tracks all state of an in-progress parse.
|
||||||
*/
|
*/
|
||||||
struct JsonParser {
|
struct JsonParser final {
|
||||||
|
|
||||||
/* State
|
/* State
|
||||||
*/
|
*/
|
||||||
@ -374,38 +388,31 @@ struct JsonParser {
|
|||||||
if (str[i] == '/') {
|
if (str[i] == '/') {
|
||||||
i++;
|
i++;
|
||||||
if (i == str.size())
|
if (i == str.size())
|
||||||
return fail("unexpected end of input inside comment", 0);
|
return fail("unexpected end of input after start of comment", false);
|
||||||
if (str[i] == '/') { // inline comment
|
if (str[i] == '/') { // inline comment
|
||||||
i++;
|
i++;
|
||||||
if (i == str.size())
|
// advance until next line, or end of input
|
||||||
return fail("unexpected end of input inside inline comment", 0);
|
while (i < str.size() && str[i] != '\n') {
|
||||||
// advance until next line
|
|
||||||
while (str[i] != '\n') {
|
|
||||||
i++;
|
i++;
|
||||||
if (i == str.size())
|
|
||||||
return fail("unexpected end of input inside inline comment", 0);
|
|
||||||
}
|
}
|
||||||
comment_found = true;
|
comment_found = true;
|
||||||
}
|
}
|
||||||
else if (str[i] == '*') { // multiline comment
|
else if (str[i] == '*') { // multiline comment
|
||||||
i++;
|
i++;
|
||||||
if (i > str.size()-2)
|
if (i > str.size()-2)
|
||||||
return fail("unexpected end of input inside multi-line comment", 0);
|
return fail("unexpected end of input inside multi-line comment", false);
|
||||||
// advance until closing tokens
|
// advance until closing tokens
|
||||||
while (!(str[i] == '*' && str[i+1] == '/')) {
|
while (!(str[i] == '*' && str[i+1] == '/')) {
|
||||||
i++;
|
i++;
|
||||||
if (i > str.size()-2)
|
if (i > str.size()-2)
|
||||||
return fail(
|
return fail(
|
||||||
"unexpected end of input inside multi-line comment", 0);
|
"unexpected end of input inside multi-line comment", false);
|
||||||
}
|
}
|
||||||
i += 2;
|
i += 2;
|
||||||
if (i == str.size())
|
|
||||||
return fail(
|
|
||||||
"unexpected end of input inside multi-line comment", 0);
|
|
||||||
comment_found = true;
|
comment_found = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return fail("malformed comment", 0);
|
return fail("malformed comment", false);
|
||||||
}
|
}
|
||||||
return comment_found;
|
return comment_found;
|
||||||
}
|
}
|
||||||
@ -420,6 +427,7 @@ struct JsonParser {
|
|||||||
bool comment_found = false;
|
bool comment_found = false;
|
||||||
do {
|
do {
|
||||||
comment_found = consume_comment();
|
comment_found = consume_comment();
|
||||||
|
if (failed) return;
|
||||||
consume_whitespace();
|
consume_whitespace();
|
||||||
}
|
}
|
||||||
while(comment_found);
|
while(comment_found);
|
||||||
@ -433,8 +441,9 @@ struct JsonParser {
|
|||||||
*/
|
*/
|
||||||
char get_next_token() {
|
char get_next_token() {
|
||||||
consume_garbage();
|
consume_garbage();
|
||||||
|
if (failed) return (char)0;
|
||||||
if (i == str.size())
|
if (i == str.size())
|
||||||
return fail("unexpected end of input", 0);
|
return fail("unexpected end of input", (char)0);
|
||||||
|
|
||||||
return str[i++];
|
return str[i++];
|
||||||
}
|
}
|
||||||
@ -508,7 +517,7 @@ struct JsonParser {
|
|||||||
if (esc.length() < 4) {
|
if (esc.length() < 4) {
|
||||||
return fail("bad \\u escape: " + esc, "");
|
return fail("bad \\u escape: " + esc, "");
|
||||||
}
|
}
|
||||||
for (int j = 0; j < 4; j++) {
|
for (size_t j = 0; j < 4; j++) {
|
||||||
if (!in_range(esc[j], 'a', 'f') && !in_range(esc[j], 'A', 'F')
|
if (!in_range(esc[j], 'a', 'f') && !in_range(esc[j], 'A', 'F')
|
||||||
&& !in_range(esc[j], '0', '9'))
|
&& !in_range(esc[j], '0', '9'))
|
||||||
return fail("bad \\u escape: " + esc, "");
|
return fail("bad \\u escape: " + esc, "");
|
||||||
@ -718,6 +727,7 @@ struct JsonParser {
|
|||||||
return fail("expected value, got " + esc(ch));
|
return fail("expected value, got " + esc(ch));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
}//namespace {
|
||||||
|
|
||||||
Json Json::parse(const string &in, string &err, JsonParse strategy) {
|
Json Json::parse(const string &in, string &err, JsonParse strategy) {
|
||||||
JsonParser parser { in, 0, err, false, strategy };
|
JsonParser parser { in, 0, err, false, strategy };
|
||||||
@ -725,6 +735,8 @@ Json Json::parse(const string &in, string &err, JsonParse strategy) {
|
|||||||
|
|
||||||
// Check for any trailing garbage
|
// Check for any trailing garbage
|
||||||
parser.consume_garbage();
|
parser.consume_garbage();
|
||||||
|
if (parser.failed)
|
||||||
|
return Json();
|
||||||
if (parser.i != in.size())
|
if (parser.i != in.size())
|
||||||
return parser.fail("unexpected trailing " + esc(in[parser.i]));
|
return parser.fail("unexpected trailing " + esc(in[parser.i]));
|
||||||
|
|
||||||
@ -733,15 +745,22 @@ Json Json::parse(const string &in, string &err, JsonParse strategy) {
|
|||||||
|
|
||||||
// Documented in json11.hpp
|
// Documented in json11.hpp
|
||||||
vector<Json> Json::parse_multi(const string &in,
|
vector<Json> Json::parse_multi(const string &in,
|
||||||
|
std::string::size_type &parser_stop_pos,
|
||||||
string &err,
|
string &err,
|
||||||
JsonParse strategy) {
|
JsonParse strategy) {
|
||||||
JsonParser parser { in, 0, err, false, strategy };
|
JsonParser parser { in, 0, err, false, strategy };
|
||||||
|
parser_stop_pos = 0;
|
||||||
vector<Json> json_vec;
|
vector<Json> json_vec;
|
||||||
while (parser.i != in.size() && !parser.failed) {
|
while (parser.i != in.size() && !parser.failed) {
|
||||||
json_vec.push_back(parser.parse_json(0));
|
json_vec.push_back(parser.parse_json(0));
|
||||||
|
if (parser.failed)
|
||||||
|
break;
|
||||||
|
|
||||||
// Check for another object
|
// Check for another object
|
||||||
parser.consume_garbage();
|
parser.consume_garbage();
|
||||||
|
if (parser.failed)
|
||||||
|
break;
|
||||||
|
parser_stop_pos = parser.i;
|
||||||
}
|
}
|
||||||
return json_vec;
|
return json_vec;
|
||||||
}
|
}
|
27
thirdparty/json11-2016-01-26/json11.hpp → thirdparty/json11-ec4e452/json11.hpp
vendored
Normal file → Executable file
27
thirdparty/json11-2016-01-26/json11.hpp → thirdparty/json11-ec4e452/json11.hpp
vendored
Normal file → Executable file
@ -56,6 +56,18 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#if _MSC_VER <= 1800 // VS 2013
|
||||||
|
#ifndef noexcept
|
||||||
|
#define noexcept throw()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef snprintf
|
||||||
|
#define snprintf _snprintf_s
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace json11 {
|
namespace json11 {
|
||||||
|
|
||||||
enum JsonParse {
|
enum JsonParse {
|
||||||
@ -95,14 +107,14 @@ public:
|
|||||||
|
|
||||||
// Implicit constructor: map-like objects (std::map, std::unordered_map, etc)
|
// Implicit constructor: map-like objects (std::map, std::unordered_map, etc)
|
||||||
template <class M, typename std::enable_if<
|
template <class M, typename std::enable_if<
|
||||||
std::is_constructible<std::string, typename M::key_type>::value
|
std::is_constructible<std::string, decltype(std::declval<M>().begin()->first)>::value
|
||||||
&& std::is_constructible<Json, typename M::mapped_type>::value,
|
&& std::is_constructible<Json, decltype(std::declval<M>().begin()->second)>::value,
|
||||||
int>::type = 0>
|
int>::type = 0>
|
||||||
Json(const M & m) : Json(object(m.begin(), m.end())) {}
|
Json(const M & m) : Json(object(m.begin(), m.end())) {}
|
||||||
|
|
||||||
// Implicit constructor: vector-like objects (std::list, std::vector, std::set, etc)
|
// Implicit constructor: vector-like objects (std::list, std::vector, std::set, etc)
|
||||||
template <class V, typename std::enable_if<
|
template <class V, typename std::enable_if<
|
||||||
std::is_constructible<Json, typename V::value_type>::value,
|
std::is_constructible<Json, decltype(*std::declval<V>().begin())>::value,
|
||||||
int>::type = 0>
|
int>::type = 0>
|
||||||
Json(const V & v) : Json(array(v.begin(), v.end())) {}
|
Json(const V & v) : Json(array(v.begin(), v.end())) {}
|
||||||
|
|
||||||
@ -165,9 +177,18 @@ public:
|
|||||||
// Parse multiple objects, concatenated or separated by whitespace
|
// Parse multiple objects, concatenated or separated by whitespace
|
||||||
static std::vector<Json> parse_multi(
|
static std::vector<Json> parse_multi(
|
||||||
const std::string & in,
|
const std::string & in,
|
||||||
|
std::string::size_type & parser_stop_pos,
|
||||||
std::string & err,
|
std::string & err,
|
||||||
JsonParse strategy = JsonParse::STANDARD);
|
JsonParse strategy = JsonParse::STANDARD);
|
||||||
|
|
||||||
|
static inline std::vector<Json> parse_multi(
|
||||||
|
const std::string & in,
|
||||||
|
std::string & err,
|
||||||
|
JsonParse strategy = JsonParse::STANDARD) {
|
||||||
|
std::string::size_type parser_stop_pos;
|
||||||
|
return parse_multi(in, parser_stop_pos, err, strategy);
|
||||||
|
}
|
||||||
|
|
||||||
bool operator== (const Json &rhs) const;
|
bool operator== (const Json &rhs) const;
|
||||||
bool operator< (const Json &rhs) const;
|
bool operator< (const Json &rhs) const;
|
||||||
bool operator!= (const Json &rhs) const { return !(*this == rhs); }
|
bool operator!= (const Json &rhs) const { return !(*this == rhs); }
|
9
thirdparty/json11-ec4e452/json11.pc.in
vendored
Executable file
9
thirdparty/json11-ec4e452/json11.pc.in
vendored
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
prefix=@CMAKE_INSTALL_PREFIX@
|
||||||
|
libdir=${prefix}/lib/@CMAKE_LIBRARY_ARCHITECTURE@
|
||||||
|
includedir=${prefix}/include/@CMAKE_LIBRARY_ARCHITECTURE@
|
||||||
|
|
||||||
|
Name: @PROJECT_NAME@
|
||||||
|
Description: json11 is a tiny JSON library for C++11, providing JSON parsing and serialization.
|
||||||
|
Version: @PROJECT_VERSION@
|
||||||
|
Libs: -L${libdir} -ljson11
|
||||||
|
Cflags: -I${includedir}
|
281
thirdparty/json11-ec4e452/test.cpp
vendored
Executable file
281
thirdparty/json11-ec4e452/test.cpp
vendored
Executable file
@ -0,0 +1,281 @@
|
|||||||
|
/*
|
||||||
|
* Define JSON11_TEST_CUSTOM_CONFIG to 1 if you want to build this tester into
|
||||||
|
* your own unit-test framework rather than a stand-alone program. By setting
|
||||||
|
* The values of the variables included below, you can insert your own custom
|
||||||
|
* code into this file as it builds, in order to make it into a test case for
|
||||||
|
* your favorite framework.
|
||||||
|
*/
|
||||||
|
#if !JSON11_TEST_CUSTOM_CONFIG
|
||||||
|
#define JSON11_TEST_CPP_PREFIX_CODE
|
||||||
|
#define JSON11_TEST_CPP_SUFFIX_CODE
|
||||||
|
#define JSON11_TEST_STANDALONE_MAIN 1
|
||||||
|
#define JSON11_TEST_CASE(name) static void name()
|
||||||
|
#define JSON11_TEST_ASSERT(b) assert(b)
|
||||||
|
#ifdef NDEBUG
|
||||||
|
#undef NDEBUG//at now assert will work even in Release build
|
||||||
|
#endif
|
||||||
|
#endif // JSON11_TEST_CUSTOM_CONFIG
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable or disable code which demonstrates the behavior change in Xcode 7 / Clang 3.7,
|
||||||
|
* introduced by DR1467 and described here: https://github.com/dropbox/json11/issues/86
|
||||||
|
* Defaults to off since it doesn't appear the standards committee is likely to act
|
||||||
|
* on this, so it needs to be considered normal behavior.
|
||||||
|
*/
|
||||||
|
#ifndef JSON11_ENABLE_DR1467_CANARY
|
||||||
|
#define JSON11_ENABLE_DR1467_CANARY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Beginning of standard source file, which makes use of the customizations above.
|
||||||
|
*/
|
||||||
|
#include <cassert>
|
||||||
|
#include <string>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include "json11.hpp"
|
||||||
|
#include <list>
|
||||||
|
#include <set>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
// Insert user-defined prefix code (includes, function declarations, etc)
|
||||||
|
// to set up a custom test suite
|
||||||
|
JSON11_TEST_CPP_PREFIX_CODE
|
||||||
|
|
||||||
|
using namespace json11;
|
||||||
|
using std::string;
|
||||||
|
|
||||||
|
// Check that Json has the properties we want.
|
||||||
|
#define CHECK_TRAIT(x) static_assert(std::x::value, #x)
|
||||||
|
CHECK_TRAIT(is_nothrow_constructible<Json>);
|
||||||
|
CHECK_TRAIT(is_nothrow_default_constructible<Json>);
|
||||||
|
CHECK_TRAIT(is_copy_constructible<Json>);
|
||||||
|
CHECK_TRAIT(is_nothrow_move_constructible<Json>);
|
||||||
|
CHECK_TRAIT(is_copy_assignable<Json>);
|
||||||
|
CHECK_TRAIT(is_nothrow_move_assignable<Json>);
|
||||||
|
CHECK_TRAIT(is_nothrow_destructible<Json>);
|
||||||
|
|
||||||
|
JSON11_TEST_CASE(json11_test) {
|
||||||
|
const string simple_test =
|
||||||
|
R"({"k1":"v1", "k2":42, "k3":["a",123,true,false,null]})";
|
||||||
|
|
||||||
|
string err;
|
||||||
|
const auto json = Json::parse(simple_test, err);
|
||||||
|
|
||||||
|
std::cout << "k1: " << json["k1"].string_value() << "\n";
|
||||||
|
std::cout << "k3: " << json["k3"].dump() << "\n";
|
||||||
|
|
||||||
|
for (auto &k : json["k3"].array_items()) {
|
||||||
|
std::cout << " - " << k.dump() << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
string comment_test = R"({
|
||||||
|
// comment /* with nested comment */
|
||||||
|
"a": 1,
|
||||||
|
// comment
|
||||||
|
// continued
|
||||||
|
"b": "text",
|
||||||
|
/* multi
|
||||||
|
line
|
||||||
|
comment
|
||||||
|
// line-comment-inside-multiline-comment
|
||||||
|
*/
|
||||||
|
// and single-line comment
|
||||||
|
// and single-line comment /* multiline inside single line */
|
||||||
|
"c": [1, 2, 3]
|
||||||
|
// and single-line comment at end of object
|
||||||
|
})";
|
||||||
|
|
||||||
|
string err_comment;
|
||||||
|
auto json_comment = Json::parse(
|
||||||
|
comment_test, err_comment, JsonParse::COMMENTS);
|
||||||
|
JSON11_TEST_ASSERT(!json_comment.is_null());
|
||||||
|
JSON11_TEST_ASSERT(err_comment.empty());
|
||||||
|
|
||||||
|
comment_test = "{\"a\": 1}//trailing line comment";
|
||||||
|
json_comment = Json::parse(
|
||||||
|
comment_test, err_comment, JsonParse::COMMENTS);
|
||||||
|
JSON11_TEST_ASSERT(!json_comment.is_null());
|
||||||
|
JSON11_TEST_ASSERT(err_comment.empty());
|
||||||
|
|
||||||
|
comment_test = "{\"a\": 1}/*trailing multi-line comment*/";
|
||||||
|
json_comment = Json::parse(
|
||||||
|
comment_test, err_comment, JsonParse::COMMENTS);
|
||||||
|
JSON11_TEST_ASSERT(!json_comment.is_null());
|
||||||
|
JSON11_TEST_ASSERT(err_comment.empty());
|
||||||
|
|
||||||
|
string failing_comment_test = "{\n/* unterminated comment\n\"a\": 1,\n}";
|
||||||
|
string err_failing_comment;
|
||||||
|
auto json_failing_comment = Json::parse(
|
||||||
|
failing_comment_test, err_failing_comment, JsonParse::COMMENTS);
|
||||||
|
JSON11_TEST_ASSERT(json_failing_comment.is_null());
|
||||||
|
JSON11_TEST_ASSERT(!err_failing_comment.empty());
|
||||||
|
|
||||||
|
failing_comment_test = "{\n/* unterminated trailing comment }";
|
||||||
|
json_failing_comment = Json::parse(
|
||||||
|
failing_comment_test, err_failing_comment, JsonParse::COMMENTS);
|
||||||
|
JSON11_TEST_ASSERT(json_failing_comment.is_null());
|
||||||
|
JSON11_TEST_ASSERT(!err_failing_comment.empty());
|
||||||
|
|
||||||
|
failing_comment_test = "{\n/ / bad comment }";
|
||||||
|
json_failing_comment = Json::parse(
|
||||||
|
failing_comment_test, err_failing_comment, JsonParse::COMMENTS);
|
||||||
|
JSON11_TEST_ASSERT(json_failing_comment.is_null());
|
||||||
|
JSON11_TEST_ASSERT(!err_failing_comment.empty());
|
||||||
|
|
||||||
|
failing_comment_test = "{// bad comment }";
|
||||||
|
json_failing_comment = Json::parse(
|
||||||
|
failing_comment_test, err_failing_comment, JsonParse::COMMENTS);
|
||||||
|
JSON11_TEST_ASSERT(json_failing_comment.is_null());
|
||||||
|
JSON11_TEST_ASSERT(!err_failing_comment.empty());
|
||||||
|
|
||||||
|
failing_comment_test = "{\n\"a\": 1\n}/";
|
||||||
|
json_failing_comment = Json::parse(
|
||||||
|
failing_comment_test, err_failing_comment, JsonParse::COMMENTS);
|
||||||
|
JSON11_TEST_ASSERT(json_failing_comment.is_null());
|
||||||
|
JSON11_TEST_ASSERT(!err_failing_comment.empty());
|
||||||
|
|
||||||
|
failing_comment_test = "{/* bad\ncomment *}";
|
||||||
|
json_failing_comment = Json::parse(
|
||||||
|
failing_comment_test, err_failing_comment, JsonParse::COMMENTS);
|
||||||
|
JSON11_TEST_ASSERT(json_failing_comment.is_null());
|
||||||
|
JSON11_TEST_ASSERT(!err_failing_comment.empty());
|
||||||
|
|
||||||
|
std::list<int> l1 { 1, 2, 3 };
|
||||||
|
std::vector<int> l2 { 1, 2, 3 };
|
||||||
|
std::set<int> l3 { 1, 2, 3 };
|
||||||
|
JSON11_TEST_ASSERT(Json(l1) == Json(l2));
|
||||||
|
JSON11_TEST_ASSERT(Json(l2) == Json(l3));
|
||||||
|
|
||||||
|
std::map<string, string> m1 { { "k1", "v1" }, { "k2", "v2" } };
|
||||||
|
std::unordered_map<string, string> m2 { { "k1", "v1" }, { "k2", "v2" } };
|
||||||
|
JSON11_TEST_ASSERT(Json(m1) == Json(m2));
|
||||||
|
|
||||||
|
// Json literals
|
||||||
|
const Json obj = Json::object({
|
||||||
|
{ "k1", "v1" },
|
||||||
|
{ "k2", 42.0 },
|
||||||
|
{ "k3", Json::array({ "a", 123.0, true, false, nullptr }) },
|
||||||
|
});
|
||||||
|
|
||||||
|
std::cout << "obj: " << obj.dump() << "\n";
|
||||||
|
JSON11_TEST_ASSERT(obj.dump() == "{\"k1\": \"v1\", \"k2\": 42, \"k3\": [\"a\", 123, true, false, null]}");
|
||||||
|
|
||||||
|
JSON11_TEST_ASSERT(Json("a").number_value() == 0);
|
||||||
|
JSON11_TEST_ASSERT(Json("a").string_value() == "a");
|
||||||
|
JSON11_TEST_ASSERT(Json().number_value() == 0);
|
||||||
|
|
||||||
|
JSON11_TEST_ASSERT(obj == json);
|
||||||
|
JSON11_TEST_ASSERT(Json(42) == Json(42.0));
|
||||||
|
JSON11_TEST_ASSERT(Json(42) != Json(42.1));
|
||||||
|
|
||||||
|
const string unicode_escape_test =
|
||||||
|
R"([ "blah\ud83d\udca9blah\ud83dblah\udca9blah\u0000blah\u1234" ])";
|
||||||
|
|
||||||
|
const char utf8[] = "blah" "\xf0\x9f\x92\xa9" "blah" "\xed\xa0\xbd" "blah"
|
||||||
|
"\xed\xb2\xa9" "blah" "\0" "blah" "\xe1\x88\xb4";
|
||||||
|
|
||||||
|
Json uni = Json::parse(unicode_escape_test, err);
|
||||||
|
JSON11_TEST_ASSERT(uni[0].string_value().size() == (sizeof utf8) - 1);
|
||||||
|
JSON11_TEST_ASSERT(std::memcmp(uni[0].string_value().data(), utf8, sizeof utf8) == 0);
|
||||||
|
|
||||||
|
// Demonstrates the behavior change in Xcode 7 / Clang 3.7, introduced by DR1467
|
||||||
|
// and described here: https://llvm.org/bugs/show_bug.cgi?id=23812
|
||||||
|
if (JSON11_ENABLE_DR1467_CANARY) {
|
||||||
|
Json nested_array = Json::array { Json::array { 1, 2, 3 } };
|
||||||
|
JSON11_TEST_ASSERT(nested_array.is_array());
|
||||||
|
JSON11_TEST_ASSERT(nested_array.array_items().size() == 1);
|
||||||
|
JSON11_TEST_ASSERT(nested_array.array_items()[0].is_array());
|
||||||
|
JSON11_TEST_ASSERT(nested_array.array_items()[0].array_items().size() == 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const std::string good_json = R"( {"k1" : "v1"})";
|
||||||
|
const std::string bad_json1 = good_json + " {";
|
||||||
|
const std::string bad_json2 = good_json + R"({"k2":"v2", "k3":[)";
|
||||||
|
struct TestMultiParse {
|
||||||
|
std::string input;
|
||||||
|
std::string::size_type expect_parser_stop_pos;
|
||||||
|
size_t expect_not_empty_elms_count;
|
||||||
|
Json expect_parse_res;
|
||||||
|
} tests[] = {
|
||||||
|
{" {", 0, 0, {}},
|
||||||
|
{good_json, good_json.size(), 1, Json(std::map<string, string>{ { "k1", "v1" } })},
|
||||||
|
{bad_json1, good_json.size() + 1, 1, Json(std::map<string, string>{ { "k1", "v1" } })},
|
||||||
|
{bad_json2, good_json.size(), 1, Json(std::map<string, string>{ { "k1", "v1" } })},
|
||||||
|
{"{}", 2, 1, Json::object{}},
|
||||||
|
};
|
||||||
|
for (const auto &tst : tests) {
|
||||||
|
std::string::size_type parser_stop_pos;
|
||||||
|
std::string err;
|
||||||
|
auto res = Json::parse_multi(tst.input, parser_stop_pos, err);
|
||||||
|
JSON11_TEST_ASSERT(parser_stop_pos == tst.expect_parser_stop_pos);
|
||||||
|
JSON11_TEST_ASSERT(
|
||||||
|
(size_t)std::count_if(res.begin(), res.end(),
|
||||||
|
[](const Json& j) { return !j.is_null(); })
|
||||||
|
== tst.expect_not_empty_elms_count);
|
||||||
|
if (!res.empty()) {
|
||||||
|
JSON11_TEST_ASSERT(tst.expect_parse_res == res[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Json my_json = Json::object {
|
||||||
|
{ "key1", "value1" },
|
||||||
|
{ "key2", false },
|
||||||
|
{ "key3", Json::array { 1, 2, 3 } },
|
||||||
|
};
|
||||||
|
std::string json_obj_str = my_json.dump();
|
||||||
|
std::cout << "json_obj_str: " << json_obj_str << "\n";
|
||||||
|
JSON11_TEST_ASSERT(json_obj_str == "{\"key1\": \"value1\", \"key2\": false, \"key3\": [1, 2, 3]}");
|
||||||
|
|
||||||
|
class Point {
|
||||||
|
public:
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
Point (int x, int y) : x(x), y(y) {}
|
||||||
|
Json to_json() const { return Json::array { x, y }; }
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<Point> points = { { 1, 2 }, { 10, 20 }, { 100, 200 } };
|
||||||
|
std::string points_json = Json(points).dump();
|
||||||
|
std::cout << "points_json: " << points_json << "\n";
|
||||||
|
JSON11_TEST_ASSERT(points_json == "[[1, 2], [10, 20], [100, 200]]");
|
||||||
|
}
|
||||||
|
|
||||||
|
#if JSON11_TEST_STANDALONE_MAIN
|
||||||
|
|
||||||
|
static void parse_from_stdin() {
|
||||||
|
string buf;
|
||||||
|
string line;
|
||||||
|
while (std::getline(std::cin, line)) {
|
||||||
|
buf += line + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
string err;
|
||||||
|
auto json = Json::parse(buf, err);
|
||||||
|
if (!err.empty()) {
|
||||||
|
printf("Failed: %s\n", err.c_str());
|
||||||
|
} else {
|
||||||
|
printf("Result: %s\n", json.dump().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
if (argc == 2 && argv[1] == string("--stdin")) {
|
||||||
|
parse_from_stdin();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
json11_test();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // JSON11_TEST_STANDALONE_MAIN
|
||||||
|
|
||||||
|
// Insert user-defined suffix code (function definitions, etc)
|
||||||
|
// to set up a custom test suite
|
||||||
|
JSON11_TEST_CPP_SUFFIX_CODE
|
Loading…
Reference in New Issue
Block a user