testrunner: use structs with designated initialization to pass options (#4975)
I need to add parameters to some `check()` functions in the tests and things are already pretty messy with having to specify all the default values - readability aside. I found this on https://stackoverflow.com/a/49572324/532627 - apparently the CC BY-SA license by StackOverflow allows the usage within GPL.
This commit is contained in:
parent
4aae670b45
commit
5d201c4e87
|
@ -35,6 +35,10 @@ if (BUILD_TESTS)
|
|||
target_compile_definitions(testrunner PRIVATE CPPCHECKLIB_IMPORT SIMPLECPP_IMPORT)
|
||||
target_link_libraries(testrunner cppcheck-core)
|
||||
endif()
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
# $ is used in dinit() dessignated initialization helper
|
||||
target_compile_options_safe(testrunner -Wno-dollar-in-identifier-extension)
|
||||
endif()
|
||||
|
||||
if (NOT CMAKE_DISABLE_PRECOMPILE_HEADERS)
|
||||
target_precompile_headers(testrunner PRIVATE precompiled.h)
|
||||
|
|
|
@ -92,4 +92,31 @@ public:
|
|||
static std::string getcode(Preprocessor &preprocessor, const std::string &filedata, const std::string &cfg, const std::string &filename, Suppressions *inlineSuppression = nullptr);
|
||||
};
|
||||
|
||||
/* designated initialization helper
|
||||
Usage:
|
||||
struct S
|
||||
{
|
||||
int i;
|
||||
};
|
||||
|
||||
const auto s = dinit(S,
|
||||
$.i = 1
|
||||
);
|
||||
*/
|
||||
#define dinit(T, ...) \
|
||||
([&] { T ${}; __VA_ARGS__; return $; }())
|
||||
|
||||
#if (defined(__GNUC__) && (__GNUC__ >= 5)) || defined(__clang__)
|
||||
// work around Clang compilation error
|
||||
// error: default member initializer for 'y' needed within definition of enclosing class 'X' outside of member functions
|
||||
// work around GCC compilation error
|
||||
// error: default member initializer for ‘x::y::z’ required before the end of its enclosing class
|
||||
// see https://stackoverflow.com/questions/53408962
|
||||
#define DINIT_NOEXCEPT noexcept
|
||||
#else
|
||||
// work around GCC 4.8 compilation error
|
||||
// error: function 'x()' defaulted on its first declaration with an exception-specification that differs from the implicit declaration 'x()'
|
||||
#define DINIT_NOEXCEPT
|
||||
#endif
|
||||
|
||||
#endif // helpersH
|
||||
|
|
|
@ -46,16 +46,24 @@ private:
|
|||
return "process";
|
||||
}
|
||||
|
||||
struct CheckOptions
|
||||
{
|
||||
CheckOptions() DINIT_NOEXCEPT = default;
|
||||
SHOWTIME_MODES showtime = SHOWTIME_MODES::SHOWTIME_NONE;
|
||||
const char* plistOutput = nullptr;
|
||||
std::vector<std::string> filesList;
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute check using n jobs for y files which are have
|
||||
* identical data, given within data.
|
||||
*/
|
||||
void check(unsigned int jobs, int files, int result, const std::string &data, SHOWTIME_MODES showtime = SHOWTIME_MODES::SHOWTIME_NONE, const char* const plistOutput = nullptr, const std::vector<std::string>& filesList = {}) {
|
||||
void check(unsigned int jobs, int files, int result, const std::string &data, const CheckOptions &opt = {}) {
|
||||
errout.str("");
|
||||
output.str("");
|
||||
|
||||
std::map<std::string, std::size_t> filemap;
|
||||
if (filesList.empty()) {
|
||||
if (opt.filesList.empty()) {
|
||||
for (int i = 1; i <= files; ++i) {
|
||||
std::ostringstream oss;
|
||||
oss << fprefix() << "_" << i << ".cpp";
|
||||
|
@ -63,16 +71,16 @@ private:
|
|||
}
|
||||
}
|
||||
else {
|
||||
for (const auto& f : filesList)
|
||||
for (const auto& f : opt.filesList)
|
||||
{
|
||||
filemap[f] = data.size();
|
||||
}
|
||||
}
|
||||
|
||||
settings.jobs = jobs;
|
||||
settings.showtime = showtime;
|
||||
if (plistOutput)
|
||||
settings.plistOutput = plistOutput;
|
||||
settings.showtime = opt.showtime;
|
||||
if (opt.plistOutput)
|
||||
settings.plistOutput = opt.plistOutput;
|
||||
// TODO: test with settings.project.fileSettings;
|
||||
ProcessExecutor executor(filemap, settings, *this);
|
||||
std::vector<std::unique_ptr<ScopedFile>> scopedfiles;
|
||||
|
@ -127,7 +135,7 @@ private:
|
|||
"{\n"
|
||||
" char *a = malloc(10);\n"
|
||||
" return 0;\n"
|
||||
"}", SHOWTIME_MODES::SHOWTIME_SUMMARY);
|
||||
"}", dinit(CheckOptions, $.showtime = SHOWTIME_MODES::SHOWTIME_SUMMARY));
|
||||
}
|
||||
|
||||
void many_threads_plist() {
|
||||
|
@ -139,7 +147,7 @@ private:
|
|||
"{\n"
|
||||
" char *a = malloc(10);\n"
|
||||
" return 0;\n"
|
||||
"}", SHOWTIME_MODES::SHOWTIME_NONE, plistOutput);
|
||||
"}", dinit(CheckOptions, $.plistOutput = plistOutput));
|
||||
}
|
||||
|
||||
void no_errors_more_files() {
|
||||
|
@ -184,7 +192,6 @@ private:
|
|||
"}");
|
||||
}
|
||||
|
||||
|
||||
void markup() {
|
||||
const Settings settingsOld = settings;
|
||||
settings.library.mMarkupExtensions.emplace(".cp1");
|
||||
|
@ -201,7 +208,7 @@ private:
|
|||
" char *a = malloc(10);\n"
|
||||
" return 0;\n"
|
||||
"}",
|
||||
SHOWTIME_MODES::SHOWTIME_NONE, nullptr, files);
|
||||
dinit(CheckOptions, $.filesList = files));
|
||||
// TODO: order of "Checking" and "checked" is affected by thread
|
||||
/*TODO_ASSERT_EQUALS("Checking " + fprefix() + "_2.cpp ...\n"
|
||||
"1/4 files checked 25% done\n"
|
||||
|
|
|
@ -61,13 +61,21 @@ private:
|
|||
return std::to_string(i);
|
||||
}
|
||||
|
||||
void check(int files, int result, const std::string &data, SHOWTIME_MODES showtime = SHOWTIME_MODES::SHOWTIME_NONE, const char* const plistOutput = nullptr, const std::vector<std::string>& filesList = {}) {
|
||||
struct CheckOptions
|
||||
{
|
||||
CheckOptions() DINIT_NOEXCEPT = default;
|
||||
SHOWTIME_MODES showtime = SHOWTIME_MODES::SHOWTIME_NONE;
|
||||
const char* plistOutput = nullptr;
|
||||
std::vector<std::string> filesList;
|
||||
};
|
||||
|
||||
void check(int files, int result, const std::string &data, const CheckOptions &opt = {}) {
|
||||
errout.str("");
|
||||
output.str("");
|
||||
settings.project.fileSettings.clear();
|
||||
|
||||
std::map<std::string, std::size_t> filemap;
|
||||
if (filesList.empty()) {
|
||||
if (opt.filesList.empty()) {
|
||||
for (int i = 1; i <= files; ++i) {
|
||||
const std::string s = fprefix() + "_" + zpad3(i) + ".cpp";
|
||||
filemap[s] = data.size();
|
||||
|
@ -79,7 +87,7 @@ private:
|
|||
}
|
||||
}
|
||||
else {
|
||||
for (const auto& f : filesList)
|
||||
for (const auto& f : opt.filesList)
|
||||
{
|
||||
filemap[f] = data.size();
|
||||
if (useFS) {
|
||||
|
@ -90,9 +98,9 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
settings.showtime = showtime;
|
||||
if (plistOutput)
|
||||
settings.plistOutput = plistOutput;
|
||||
settings.showtime = opt.showtime;
|
||||
if (opt.plistOutput)
|
||||
settings.plistOutput = opt.plistOutput;
|
||||
// NOLINTNEXTLINE(performance-unnecessary-value-param)
|
||||
CppCheck cppcheck(*this, true, [](std::string,std::vector<std::string>,std::string,std::string&){
|
||||
return false;
|
||||
|
@ -152,7 +160,7 @@ private:
|
|||
"{\n"
|
||||
" char *a = malloc(10);\n"
|
||||
" return 0;\n"
|
||||
"}", SHOWTIME_MODES::SHOWTIME_SUMMARY);
|
||||
"}", dinit(CheckOptions, $.showtime = SHOWTIME_MODES::SHOWTIME_SUMMARY));
|
||||
}
|
||||
|
||||
void many_files_plist() {
|
||||
|
@ -164,7 +172,7 @@ private:
|
|||
"{\n"
|
||||
" char *a = malloc(10);\n"
|
||||
" return 0;\n"
|
||||
"}", SHOWTIME_MODES::SHOWTIME_NONE, plistOutput);
|
||||
"}", dinit(CheckOptions, $.plistOutput = plistOutput));
|
||||
}
|
||||
|
||||
void no_errors_more_files() {
|
||||
|
@ -225,7 +233,7 @@ private:
|
|||
" char *a = malloc(10);\n"
|
||||
" return 0;\n"
|
||||
"}",
|
||||
SHOWTIME_MODES::SHOWTIME_NONE, nullptr, files);
|
||||
dinit(CheckOptions, $.filesList = files));
|
||||
// TODO: filter out the "files checked" messages
|
||||
ASSERT_EQUALS("Checking " + fprefix() + "_2.cpp ...\n"
|
||||
"1/4 files checked 25% done\n"
|
||||
|
|
|
@ -46,16 +46,24 @@ private:
|
|||
return "thread";
|
||||
}
|
||||
|
||||
struct CheckOptions
|
||||
{
|
||||
CheckOptions() DINIT_NOEXCEPT = default;
|
||||
SHOWTIME_MODES showtime = SHOWTIME_MODES::SHOWTIME_NONE;
|
||||
const char* plistOutput = nullptr;
|
||||
std::vector<std::string> filesList;
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute check using n jobs for y files which are have
|
||||
* identical data, given within data.
|
||||
*/
|
||||
void check(unsigned int jobs, int files, int result, const std::string &data, SHOWTIME_MODES showtime = SHOWTIME_MODES::SHOWTIME_NONE, const char* const plistOutput = nullptr, const std::vector<std::string>& filesList = {}) {
|
||||
void check(unsigned int jobs, int files, int result, const std::string &data, const CheckOptions &opt = {}) {
|
||||
errout.str("");
|
||||
output.str("");
|
||||
|
||||
std::map<std::string, std::size_t> filemap;
|
||||
if (filesList.empty()) {
|
||||
if (opt.filesList.empty()) {
|
||||
for (int i = 1; i <= files; ++i) {
|
||||
std::ostringstream oss;
|
||||
oss << fprefix() << "_" << i << ".cpp";
|
||||
|
@ -63,7 +71,7 @@ private:
|
|||
}
|
||||
}
|
||||
else {
|
||||
for (const auto& f : filesList)
|
||||
for (const auto& f : opt.filesList)
|
||||
{
|
||||
filemap[f] = data.size();
|
||||
}
|
||||
|
@ -71,9 +79,9 @@ private:
|
|||
|
||||
Settings settings1 = settings;
|
||||
settings1.jobs = jobs;
|
||||
settings1.showtime = showtime;
|
||||
if (plistOutput)
|
||||
settings1.plistOutput = plistOutput;
|
||||
settings1.showtime = opt.showtime;
|
||||
if (opt.plistOutput)
|
||||
settings1.plistOutput = opt.plistOutput;
|
||||
// TODO: test with settings.project.fileSettings;
|
||||
ThreadExecutor executor(filemap, settings1, *this);
|
||||
std::vector<std::unique_ptr<ScopedFile>> scopedfiles;
|
||||
|
@ -126,7 +134,7 @@ private:
|
|||
"{\n"
|
||||
" char *a = malloc(10);\n"
|
||||
" return 0;\n"
|
||||
"}", SHOWTIME_MODES::SHOWTIME_SUMMARY);
|
||||
"}", dinit(CheckOptions, $.showtime = SHOWTIME_MODES::SHOWTIME_SUMMARY));
|
||||
}
|
||||
|
||||
void many_threads_plist() {
|
||||
|
@ -138,7 +146,7 @@ private:
|
|||
"{\n"
|
||||
" char *a = malloc(10);\n"
|
||||
" return 0;\n"
|
||||
"}", SHOWTIME_MODES::SHOWTIME_NONE, plistOutput);
|
||||
"}", dinit(CheckOptions, $.plistOutput = plistOutput));
|
||||
}
|
||||
|
||||
void no_errors_more_files() {
|
||||
|
@ -199,7 +207,7 @@ private:
|
|||
" char *a = malloc(10);\n"
|
||||
" return 0;\n"
|
||||
"}",
|
||||
SHOWTIME_MODES::SHOWTIME_NONE, nullptr, files);
|
||||
dinit(CheckOptions, $.filesList = files));
|
||||
// TODO: order of "Checking" and "checked" is affected by thread
|
||||
/*TODO_ASSERT_EQUALS("Checking " + fprefix() + "_2.cpp ...\n"
|
||||
"1/4 files checked 25% done\n"
|
||||
|
|
Loading…
Reference in New Issue