From f18b0b649e465b8e5f2de611b26a6b90fc0e4933 Mon Sep 17 00:00:00 2001 From: Fargier Sylvain Date: Wed, 9 Feb 2022 10:47:19 +0100 Subject: [PATCH] :wrench: gcc-4.8.5 support - fix missing initializer for member [-Werror=missing-field-initializers] - fix ISO C++ forbids casting between pointer-to-function and pointer-to-object [-Werror=pedantic] - add gcc-4.8 tests - ubuntu has less patches than CentOS7 on gcc, some old bugs are not - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55971 - https://sourceware.org/bugzilla/show_bug.cgi?id=25399 - compat.cmake - disable some features with old compilers --- .github/reqs.sh | 1 + .github/workflows/gcc.yml | 4 ++++ CMakeLists.txt | 2 ++ compat.cmake | 11 +++++++++++ ext/c4core | 2 +- samples/quickstart.cpp | 28 +++++++++++++++++++++------- test/test_case.hpp | 19 ++++++++++++------- test/test_group.hpp | 18 +++++++++++++++++- 8 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 compat.cmake diff --git a/.github/reqs.sh b/.github/reqs.sh index 67852f5a..8f2cd797 100644 --- a/.github/reqs.sh +++ b/.github/reqs.sh @@ -187,6 +187,7 @@ function _c4_gather_compilers() g++-7 ) _c4_addgcc 7 ;; g++-6 ) _c4_addgcc 6 ;; g++-5 ) _c4_addgcc 5 ;; + g++-4.8 ) _c4_addgcc 4.8 ;; #g++-4.9 ) _c4_addgcc 4.9 ;; # https://askubuntu.com/questions/1036108/install-gcc-4-9-at-ubuntu-18-04 clang++-12 ) _c4_addclang 12 ;; clang++-11 ) _c4_addclang 11 ;; diff --git a/.github/workflows/gcc.yml b/.github/workflows/gcc.yml index 2399b0c0..0d21bedf 100644 --- a/.github/workflows/gcc.yml +++ b/.github/workflows/gcc.yml @@ -42,6 +42,8 @@ jobs: - {std: 20, cxx: g++-10 , bt: Release, os: ubuntu-18.04, bitlinks: shared64 static32} - {std: 11, cxx: g++-5 , bt: Debug , os: ubuntu-18.04, bitlinks: shared64 static32} - {std: 11, cxx: g++-5 , bt: Release, os: ubuntu-18.04, bitlinks: shared64 static32} + - {std: 11, cxx: g++-4.8 , bt: Debug, os: ubuntu-18.04, bitlinks: shared64 static32} + - {std: 11, cxx: g++-4.8 , bt: Release, os: ubuntu-18.04, bitlinks: shared64 static32} env: {STD: "${{matrix.std}}", CXX_: "${{matrix.cxx}}", BT: "${{matrix.bt}}", BITLINKS: "${{matrix.bitlinks}}", VG: "${{matrix.vg}}", SAN: "${{matrix.san}}", LINT: "${{matrix.lint}}", OS: "${{matrix.os}}"} steps: - {name: checkout, uses: actions/checkout@v2, with: {submodules: recursive}} @@ -137,6 +139,8 @@ jobs: - {std: 17, cxx: g++-10, bt: Release, vg: ON, os: ubuntu-18.04} - {std: 20, cxx: g++-10, bt: Debug , vg: ON, os: ubuntu-18.04} - {std: 20, cxx: g++-10, bt: Release, vg: ON, os: ubuntu-18.04} + - {std: 11, cxx: g++-4.8, bt: Debug, vg: ON, os: ubuntu-18.04} + - {std: 11, cxx: g++-4.8, bt: Release, vg: ON, os: ubuntu-18.04} env: {STD: "${{matrix.std}}", CXX_: "${{matrix.cxx}}", BT: "${{matrix.bt}}", BITLINKS: "${{matrix.bitlinks}}", VG: "${{matrix.vg}}", SAN: "${{matrix.san}}", LINT: "${{matrix.lint}}", OS: "${{matrix.os}}"} steps: - {name: checkout, uses: actions/checkout@v2, with: {submodules: recursive}} diff --git a/CMakeLists.txt b/CMakeLists.txt index 515b0b30..c1e8f114 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,8 @@ project(ryml DESCRIPTION "Rapid YAML parsing and emitting" HOMEPAGE_URL "https://github.com/biojppm/rapidyaml" LANGUAGES CXX) +include(./compat.cmake) + c4_project(VERSION 0.3.0 STANDALONE AUTHOR "Joao Paulo Magalhaes ") diff --git a/compat.cmake b/compat.cmake new file mode 100644 index 00000000..bbdd16c3 --- /dev/null +++ b/compat.cmake @@ -0,0 +1,11 @@ + +# old gcc-4.8 support +if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND + (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 4.8) AND + (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)) + + # c++17 compiler required + set(C4RYML_BUILD_BENCHMARKS OFF CACHE BOOL "" FORCE) + # LLVM required + set(C4RYML_SANITIZE OFF CACHE BOOL "" FORCE) +endif() diff --git a/ext/c4core b/ext/c4core index 255cb552..4edf5602 160000 --- a/ext/c4core +++ b/ext/c4core @@ -1 +1 @@ -Subproject commit 255cb552bf1fdf606645803c65ee2007fb128151 +Subproject commit 4edf5602a56cf6cd76a1664983d8ffc6505fdbf1 diff --git a/samples/quickstart.cpp b/samples/quickstart.cpp index 315553c0..85f6b0bd 100644 --- a/samples/quickstart.cpp +++ b/samples/quickstart.cpp @@ -128,11 +128,25 @@ int main() namespace sample { +bool report_check(const char *file, int line, const char *predicate, bool result); +#ifdef __GNUC__ +#if __GNUC__ == 4 && __GNUC_MINOR__ >= 8 +struct CheckPredicate { + const char *file; + const int line; + + void operator ()(bool predicate) const { + if (!report_check(file, line, nullptr, predicate)) { C4_DEBUG_BREAK(); } + } +}; +#define CHECK CheckPredicate{__FILE__, __LINE__} +#endif +#endif + +#if !defined(CHECK) /// a quick'n'dirty assertion to verify a predicate #define CHECK(predicate) do { if(!report_check(__FILE__, __LINE__, #predicate, (predicate))) { C4_DEBUG_BREAK(); } } while(0) - -bool report_check(const char *file, int line, const char *predicate, bool result); - +#endif //----------------------------------------------------------------------------- @@ -2492,7 +2506,7 @@ void sample_base64() tree.rootref().append_child() << ryml::key(ryml::fmt::base64(c.text)) << c.text; CHECK(tree[c.base64].val() == c.text); } - C4_CHECK(ryml::emitrs(tree) == R"('Love all, trust a few, do wrong to none.': TG92ZSBhbGwsIHRydXN0IGEgZmV3LCBkbyB3cm9uZyB0byBub25lLg== + CHECK(ryml::emitrs(tree) == R"('Love all, trust a few, do wrong to none.': TG92ZSBhbGwsIHRydXN0IGEgZmV3LCBkbyB3cm9uZyB0byBub25lLg== 'The fool doth think he is wise, but the wise man knows himself to be a fool.': VGhlIGZvb2wgZG90aCB0aGluayBoZSBpcyB3aXNlLCBidXQgdGhlIHdpc2UgbWFuIGtub3dzIGhpbXNlbGYgdG8gYmUgYSBmb29sLg== Brevity is the soul of wit.: QnJldml0eSBpcyB0aGUgc291bCBvZiB3aXQu All that glitters is not gold.: QWxsIHRoYXQgZ2xpdHRlcnMgaXMgbm90IGdvbGQu @@ -3963,13 +3977,13 @@ static int num_failed_checks = 0; bool report_check(const char *file, int line, const char *predicate, bool result) { ++num_checks; - const char *msg = "OK! "; + const char *msg = predicate ? "OK! " : "OK!"; if(!result) { ++num_failed_checks; - msg = "ERROR: "; + msg = predicate ? "ERROR: " : "ERROR"; } - std::cout << file << ':' << line << ": " << msg << predicate << std::endl; + std::cout << file << ':' << line << ": " << msg << (predicate ? predicate : "") << std::endl; return result; } diff --git a/test/test_case.hpp b/test/test_case.hpp index 7f3be164..fd38e00b 100644 --- a/test/test_case.hpp +++ b/test/test_case.hpp @@ -41,11 +41,17 @@ namespace yml { inline void PrintTo(Callbacks const& cb, ::std::ostream* os) { +#ifdef __GNUC__ +#define RYML_GNUC_EXTENSION __extension__ +#else +#define RYML_GNUC_EXTENSION +#endif *os << '{' << "userdata." << (void*)cb.m_user_data << ',' - << "allocate." << (void*)cb.m_allocate << ',' - << "free." << (void*)cb.m_free << ',' - << "error." << (void*)cb.m_error << '}'; + << "allocate." << RYML_GNUC_EXTENSION (void*)cb.m_allocate << ',' + << "free." << RYML_GNUC_EXTENSION (void*)cb.m_free << ',' + << "error." << RYML_GNUC_EXTENSION (void*)cb.m_error << '}'; +#undef RYML_GNUC_EXTENSION } struct Case; @@ -443,12 +449,11 @@ struct Case Location expected_location; //! create a standard test case: name, source and expected CaseNode structure - template Case(csubstr file, int line, csubstr name_, const char (&src_)[N], Args&& ...args) : filelinebuf(catrs(file, ':', line)), fileline(to_csubstr(filelinebuf)), name(name_), src(src_), root(std::forward(args)...), flags(), expected_location() {} + template Case(csubstr file, int line, const char *name_, const char *src_, Args&& ...args) : filelinebuf(catrs(file, ':', line)), fileline(to_csubstr(filelinebuf)), name(to_csubstr(name_)), src(to_csubstr(src_)), root(std::forward(args)...), flags(), expected_location() {} //! create a test case with explicit flags: name, source flags, and expected CaseNode structure - template Case(csubstr file, int line, csubstr name_, int f_, const char (&src_)[N], Args&& ...args) : filelinebuf(catrs(file, ':', line)), fileline(to_csubstr(filelinebuf)), name(name_), src(src_), root(std::forward(args)...), flags((TestCaseFlags_e)f_), expected_location() {} + template Case(csubstr file, int line, const char *name_, int f_, const char *src_, Args&& ...args) : filelinebuf(catrs(file, ':', line)), fileline(to_csubstr(filelinebuf)), name(to_csubstr(name_)), src(to_csubstr(src_)), root(std::forward(args)...), flags((TestCaseFlags_e)f_), expected_location() {} //! create a test case with an error on an expected location - template Case(csubstr file, int line, csubstr name_, int f_, const char (&src_)[N], LineCol loc) : filelinebuf(catrs(file, ':', line)), fileline(to_csubstr(filelinebuf)), name(name_), src(src_), root(), flags((TestCaseFlags_e)f_), expected_location(name, loc.line, loc.col) {} - + Case(csubstr file, int line, const char *name_, int f_, const char *src_, LineCol loc) : filelinebuf(catrs(file, ':', line)), fileline(to_csubstr(filelinebuf)), name(to_csubstr(name_)), src(to_csubstr(src_)), root(), flags((TestCaseFlags_e)f_), expected_location(name, loc.line, loc.col) {} }; //----------------------------------------------------------------------------- diff --git a/test/test_group.hpp b/test/test_group.hpp index 54729577..e9cb125b 100644 --- a/test/test_group.hpp +++ b/test/test_group.hpp @@ -75,12 +75,28 @@ constexpr const NodeType_e QK = (NodeType_e)(VAL | KEYQUO); constexpr const NodeType_e QV = (NodeType_e)(VAL | VALQUO); constexpr const NodeType_e QKV = (NodeType_e)(VAL | KEYQUO | VALQUO); +#ifdef __GNUC__ +#if __GNUC__ == 4 && __GNUC_MINOR__ >= 8 +struct CaseAdder { + std::vector *group_cases; + const csubstr file; + const int line; + template + void operator ()(Args... parameters) const { + group_cases->emplace_back(csubstr(file), line, parameters...); + } +}; /* all arguments are to the constructor of Case */ +#define ADD_CASE_TO_GROUP CaseAdder{group_cases__, csubstr(__FILE__), __LINE__+1} +#endif +#endif + +#ifndef ADD_CASE_TO_GROUP #define ADD_CASE_TO_GROUP(...) \ group_cases__->emplace_back(csubstr(__FILE__), __LINE__+1, __VA_ARGS__) - +#endif #define CASE_GROUP(group_name) \ \