🔧 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
This commit is contained in:
Fargier Sylvain
2022-02-09 10:47:19 +01:00
parent 904eebde03
commit f18b0b649e
8 changed files with 69 additions and 16 deletions

1
.github/reqs.sh vendored
View File

@@ -187,6 +187,7 @@ function _c4_gather_compilers()
g++-7 ) _c4_addgcc 7 ;; g++-7 ) _c4_addgcc 7 ;;
g++-6 ) _c4_addgcc 6 ;; g++-6 ) _c4_addgcc 6 ;;
g++-5 ) _c4_addgcc 5 ;; 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 #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++-12 ) _c4_addclang 12 ;;
clang++-11 ) _c4_addclang 11 ;; clang++-11 ) _c4_addclang 11 ;;

View File

@@ -42,6 +42,8 @@ jobs:
- {std: 20, cxx: g++-10 , bt: Release, os: ubuntu-18.04, bitlinks: shared64 static32} - {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: 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++-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}}"} 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: steps:
- {name: checkout, uses: actions/checkout@v2, with: {submodules: recursive}} - {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: 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: Debug , vg: ON, os: ubuntu-18.04}
- {std: 20, cxx: g++-10, bt: Release, 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}}"} 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: steps:
- {name: checkout, uses: actions/checkout@v2, with: {submodules: recursive}} - {name: checkout, uses: actions/checkout@v2, with: {submodules: recursive}}

View File

@@ -4,6 +4,8 @@ project(ryml
DESCRIPTION "Rapid YAML parsing and emitting" DESCRIPTION "Rapid YAML parsing and emitting"
HOMEPAGE_URL "https://github.com/biojppm/rapidyaml" HOMEPAGE_URL "https://github.com/biojppm/rapidyaml"
LANGUAGES CXX) LANGUAGES CXX)
include(./compat.cmake)
c4_project(VERSION 0.3.0 STANDALONE c4_project(VERSION 0.3.0 STANDALONE
AUTHOR "Joao Paulo Magalhaes <dev@jpmag.me>") AUTHOR "Joao Paulo Magalhaes <dev@jpmag.me>")

11
compat.cmake Normal file
View File

@@ -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()

View File

@@ -128,11 +128,25 @@ int main()
namespace sample { 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 /// 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) #define CHECK(predicate) do { if(!report_check(__FILE__, __LINE__, #predicate, (predicate))) { C4_DEBUG_BREAK(); } } while(0)
#endif
bool report_check(const char *file, int line, const char *predicate, bool result);
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -2492,7 +2506,7 @@ void sample_base64()
tree.rootref().append_child() << ryml::key(ryml::fmt::base64(c.text)) << c.text; tree.rootref().append_child() << ryml::key(ryml::fmt::base64(c.text)) << c.text;
CHECK(tree[c.base64].val() == c.text); CHECK(tree[c.base64].val() == c.text);
} }
C4_CHECK(ryml::emitrs<std::string>(tree) == R"('Love all, trust a few, do wrong to none.': TG92ZSBhbGwsIHRydXN0IGEgZmV3LCBkbyB3cm9uZyB0byBub25lLg== CHECK(ryml::emitrs<std::string>(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== '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 Brevity is the soul of wit.: QnJldml0eSBpcyB0aGUgc291bCBvZiB3aXQu
All that glitters is not gold.: QWxsIHRoYXQgZ2xpdHRlcnMgaXMgbm90IGdvbGQu 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) bool report_check(const char *file, int line, const char *predicate, bool result)
{ {
++num_checks; ++num_checks;
const char *msg = "OK! "; const char *msg = predicate ? "OK! " : "OK!";
if(!result) if(!result)
{ {
++num_failed_checks; ++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; return result;
} }

View File

@@ -41,11 +41,17 @@ namespace yml {
inline void PrintTo(Callbacks const& cb, ::std::ostream* os) inline void PrintTo(Callbacks const& cb, ::std::ostream* os)
{ {
#ifdef __GNUC__
#define RYML_GNUC_EXTENSION __extension__
#else
#define RYML_GNUC_EXTENSION
#endif
*os << '{' *os << '{'
<< "userdata." << (void*)cb.m_user_data << ',' << "userdata." << (void*)cb.m_user_data << ','
<< "allocate." << (void*)cb.m_allocate << ',' << "allocate." << RYML_GNUC_EXTENSION (void*)cb.m_allocate << ','
<< "free." << (void*)cb.m_free << ',' << "free." << RYML_GNUC_EXTENSION (void*)cb.m_free << ','
<< "error." << (void*)cb.m_error << '}'; << "error." << RYML_GNUC_EXTENSION (void*)cb.m_error << '}';
#undef RYML_GNUC_EXTENSION
} }
struct Case; struct Case;
@@ -443,12 +449,11 @@ struct Case
Location expected_location; Location expected_location;
//! create a standard test case: name, source and expected CaseNode structure //! create a standard test case: name, source and expected CaseNode structure
template<size_t N, class... Args> Case(csubstr file, int line, csubstr name_, const char (&src_)[N], Args&& ...args) : filelinebuf(catrs<std::string>(file, ':', line)), fileline(to_csubstr(filelinebuf)), name(name_), src(src_), root(std::forward<Args>(args)...), flags(), expected_location() {} template<class... Args> Case(csubstr file, int line, const char *name_, const char *src_, Args&& ...args) : filelinebuf(catrs<std::string>(file, ':', line)), fileline(to_csubstr(filelinebuf)), name(to_csubstr(name_)), src(to_csubstr(src_)), root(std::forward<Args>(args)...), flags(), expected_location() {}
//! create a test case with explicit flags: name, source flags, and expected CaseNode structure //! create a test case with explicit flags: name, source flags, and expected CaseNode structure
template<size_t N, class... Args> Case(csubstr file, int line, csubstr name_, int f_, const char (&src_)[N], Args&& ...args) : filelinebuf(catrs<std::string>(file, ':', line)), fileline(to_csubstr(filelinebuf)), name(name_), src(src_), root(std::forward<Args>(args)...), flags((TestCaseFlags_e)f_), expected_location() {} template<class... Args> Case(csubstr file, int line, const char *name_, int f_, const char *src_, Args&& ...args) : filelinebuf(catrs<std::string>(file, ':', line)), fileline(to_csubstr(filelinebuf)), name(to_csubstr(name_)), src(to_csubstr(src_)), root(std::forward<Args>(args)...), flags((TestCaseFlags_e)f_), expected_location() {}
//! create a test case with an error on an expected location //! create a test case with an error on an expected location
template<size_t N> Case(csubstr file, int line, csubstr name_, int f_, const char (&src_)[N], LineCol loc) : filelinebuf(catrs<std::string>(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<std::string>(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) {}
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@@ -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 QV = (NodeType_e)(VAL | VALQUO);
constexpr const NodeType_e QKV = (NodeType_e)(VAL | KEYQUO | VALQUO); constexpr const NodeType_e QKV = (NodeType_e)(VAL | KEYQUO | VALQUO);
#ifdef __GNUC__
#if __GNUC__ == 4 && __GNUC_MINOR__ >= 8
struct CaseAdder {
std::vector<Case> *group_cases;
const csubstr file;
const int line;
template<typename... Args>
void operator ()(Args... parameters) const {
group_cases->emplace_back(csubstr(file), line, parameters...);
}
};
/* all arguments are to the constructor of Case */ /* 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(...) \ #define ADD_CASE_TO_GROUP(...) \
group_cases__->emplace_back(csubstr(__FILE__), __LINE__+1, __VA_ARGS__) group_cases__->emplace_back(csubstr(__FILE__), __LINE__+1, __VA_ARGS__)
#endif
#define CASE_GROUP(group_name) \ #define CASE_GROUP(group_name) \
\ \