Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/CI-unixish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ jobs:
- name: Run CTest
run: |
pushd cmake.output
ctest -j$(nproc)
ctest --output-on-failure -j$(nproc)
build_uchar:

Expand Down
50 changes: 37 additions & 13 deletions cli/singleexecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ unsigned int SingleExecutor::check()

std::size_t processedsize = 0;
unsigned int c = 0;
// TODO: processes either mSettings.project.fileSettings or mFiles - process/thread implementations process both
// TODO: thread/process implementations process fileSettings first
if (mSettings.project.fileSettings.empty()) {
for (std::map<std::string, std::size_t>::const_iterator i = mFiles.cbegin(); i != mFiles.cend(); ++i) {
if (!mSettings.library.markupFile(i->first)
Expand All @@ -59,31 +61,53 @@ unsigned int SingleExecutor::check()
processedsize += i->second;
if (!mSettings.quiet)
reportStatus(c + 1, mFiles.size(), processedsize, totalfilesize);
// TODO: call analyseClangTidy()
c++;
}
}
} else {
// filesettings
// check all files of the project
for (const ImportProject::FileSettings &fs : mSettings.project.fileSettings) {
result += mCppcheck.check(fs);
++c;
if (!mSettings.quiet)
reportStatus(c, mSettings.project.fileSettings.size(), c, mSettings.project.fileSettings.size());
if (mSettings.clangTidy)
mCppcheck.analyseClangTidy(fs);
if (!mSettings.library.markupFile(fs.filename)
|| !mSettings.library.processMarkupAfterCode(fs.filename)) {
result += mCppcheck.check(fs);
++c;
if (!mSettings.quiet)
reportStatus(c, mSettings.project.fileSettings.size(), c, mSettings.project.fileSettings.size());
if (mSettings.clangTidy)
mCppcheck.analyseClangTidy(fs);
}
}
}

// second loop to parse all markup files which may not work until all
// c/cpp files have been parsed and checked
for (std::map<std::string, std::size_t>::const_iterator i = mFiles.cbegin(); i != mFiles.cend(); ++i) {
if (mSettings.library.markupFile(i->first) && mSettings.library.processMarkupAfterCode(i->first)) {
result += mCppcheck.check(i->first);
processedsize += i->second;
if (!mSettings.quiet)
reportStatus(c + 1, mFiles.size(), processedsize, totalfilesize);
c++;
// TODO: get rid of duplicated code
if (mSettings.project.fileSettings.empty()) {
for (std::map<std::string, std::size_t>::const_iterator i = mFiles.cbegin(); i != mFiles.cend(); ++i) {
if (mSettings.library.markupFile(i->first)
&& mSettings.library.processMarkupAfterCode(i->first)) {
result += mCppcheck.check(i->first);
processedsize += i->second;
if (!mSettings.quiet)
reportStatus(c + 1, mFiles.size(), processedsize, totalfilesize);
// TODO: call analyseClangTidy()
c++;
}
}
}
else {
for (const ImportProject::FileSettings &fs : mSettings.project.fileSettings) {
if (mSettings.library.markupFile(fs.filename)
&& mSettings.library.processMarkupAfterCode(fs.filename)) {
result += mCppcheck.check(fs);
++c;
if (!mSettings.quiet)
reportStatus(c, mSettings.project.fileSettings.size(), c, mSettings.project.fileSettings.size());
if (mSettings.clangTidy)
mCppcheck.analyseClangTidy(fs);
}
}
}
if (mCppcheck.analyseWholeProgram())
Expand Down
2 changes: 1 addition & 1 deletion lib/library.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ namespace tinyxml2 {
class CPPCHECKLIB Library {
// TODO: get rid of this
friend class TestSymbolDatabase; // For testing only
friend class TestSingleExecutor; // For testing only
friend class TestSingleExecutorBase; // For testing only
friend class TestThreadExecutor; // For testing only
friend class TestProcessExecutor; // For testing only

Expand Down
1 change: 1 addition & 0 deletions releasenotes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ release notes for cppcheck-2.11
- `constVariableReference`
- `constVariablePointer`
- More command-line parameters will now check if the given integer argument is actually valid. Several other internal string-to-integer conversions will not be error checked.
- scanning projects (with -j1) will now defer the analysis of markup files until the whole code was processed
Comment thread
danmar marked this conversation as resolved.
16 changes: 13 additions & 3 deletions test/helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "preprocessor.h"

#include <cstdio>
#include <iostream>
#include <fstream>
#include <stdexcept>
#include <utility>
Expand Down Expand Up @@ -60,12 +61,21 @@ ScopedFile::ScopedFile(std::string name, const std::string &content, std::string
}

ScopedFile::~ScopedFile() {
std::remove(mFullPath.c_str());
const int remove_res = std::remove(mFullPath.c_str());
if (remove_res != 0) {
std::cout << "ScopedFile(" << mFullPath + ") - could not delete file (" << remove_res << ")";
}
if (!mPath.empty() && mPath != Path::getCurrentPath()) {
#ifdef _WIN32
RemoveDirectoryA(mPath.c_str());
if (!RemoveDirectoryA(mPath.c_str())) {
std::cout << "ScopedFile(" << mFullPath + ") - could not delete folder (" << GetLastError() << ")";
}
#else
rmdir(mPath.c_str());
const int rmdir_res = rmdir(mPath.c_str());
if (rmdir_res == -1) {
const int err = errno;
std::cout << "ScopedFile(" << mFullPath + ") - could not delete folder (" << err << ")";
}
#endif
}
}
Expand Down
25 changes: 15 additions & 10 deletions test/testprocessexecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ class TestProcessExecutor : public TestFixture {
private:
Settings settings = settingsBuilder().library("std.cfg").build();

static std::string fprefix()
{
return "process";
}

/**
* Execute check using n jobs for y files which are have
* identical data, given within data.
Expand All @@ -53,7 +58,7 @@ class TestProcessExecutor : public TestFixture {
if (filesList.empty()) {
for (int i = 1; i <= files; ++i) {
std::ostringstream oss;
oss << "file_" << i << ".cpp";
oss << fprefix() << "_" << i << ".cpp";
filemap[oss.str()] = data.size();
}
}
Expand Down Expand Up @@ -186,7 +191,7 @@ class TestProcessExecutor : public TestFixture {
settings.library.mProcessAfterCode.emplace(".cp1", true);

const std::vector<std::string> files = {
"file_1.cp1", "file_2.cpp", "file_3.cp1", "file_4.cpp"
fprefix() + "_1.cp1", fprefix() + "_2.cpp", fprefix() + "_3.cp1", fprefix() + "_4.cpp"
};

// the checks are not executed on the markup files => expected result is 2
Expand All @@ -198,21 +203,21 @@ class TestProcessExecutor : public TestFixture {
"}",
SHOWTIME_MODES::SHOWTIME_NONE, nullptr, files);
// TODO: order of "Checking" and "checked" is affected by thread
/*TODO_ASSERT_EQUALS("Checking file_2.cpp ...\n"
/*TODO_ASSERT_EQUALS("Checking " + fprefix() + "_2.cpp ...\n"
"1/4 files checked 25% done\n"
"Checking file_4.cpp ...\n"
"Checking " + fprefix() + "_4.cpp ...\n"
"2/4 files checked 50% done\n"
"Checking file_1.cp1 ...\n"
"Checking " + fprefix() + "_1.cp1 ...\n"
"3/4 files checked 75% done\n"
"Checking file_3.cp1 ...\n"
"Checking " + fprefix() + "_3.cp1 ...\n"
"4/4 files checked 100% done\n",
"Checking file_1.cp1 ...\n"
"Checking " + fprefix() + "_1.cp1 ...\n"
"1/4 files checked 25% done\n"
"Checking file_2.cpp ...\n"
"Checking " + fprefix() + "_2.cpp ...\n"
"2/4 files checked 50% done\n"
"Checking file_3.cp1 ...\n"
"Checking " + fprefix() + "_3.cp1 ...\n"
"3/4 files checked 75% done\n"
"Checking file_4.cpp ...\n"
"Checking " + fprefix() + "_4.cpp ...\n"
"4/4 files checked 100% done\n",
output.str());*/
settings = settingsOld;
Expand Down
61 changes: 48 additions & 13 deletions test/testsingleexecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,20 @@
#include <utility>
#include <vector>

class TestSingleExecutor : public TestFixture {
public:
TestSingleExecutor() : TestFixture("TestSingleExecutor") {}
class TestSingleExecutorBase : public TestFixture {
protected:
TestSingleExecutorBase(const char * const name, bool useFS) : TestFixture(name), useFS(useFS) {}

private:
Settings settings = settingsBuilder().library("std.cfg").build();
bool useFS;

std::string fprefix() const
{
if (useFS)
return "singlefs";
return "single";
}

static std::string zpad3(int i)
{
Expand All @@ -55,18 +63,29 @@ class TestSingleExecutor : public TestFixture {
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 = {}) {
errout.str("");
output.str("");
settings.project.fileSettings.clear();

std::map<std::string, std::size_t> filemap;
if (filesList.empty()) {
for (int i = 1; i <= files; ++i) {
const std::string s = "file_" + zpad3(i) + ".cpp";
const std::string s = fprefix() + "_" + zpad3(i) + ".cpp";
filemap[s] = data.size();
if (useFS) {
ImportProject::FileSettings fs;
fs.filename = s;
settings.project.fileSettings.emplace_back(std::move(fs));
}
}
}
else {
for (const auto& f : filesList)
{
filemap[f] = data.size();
if (useFS) {
ImportProject::FileSettings fs;
fs.filename = f;
settings.project.fileSettings.emplace_back(std::move(fs));
}
}
}

Expand All @@ -78,13 +97,18 @@ class TestSingleExecutor : public TestFixture {
return false;
});
cppcheck.settings() = settings;
// TODO: test with settings.project.fileSettings;
SingleExecutor executor(cppcheck, filemap, settings, *this);

std::vector<std::unique_ptr<ScopedFile>> scopedfiles;
scopedfiles.reserve(filemap.size());
for (std::map<std::string, std::size_t>::const_iterator i = filemap.cbegin(); i != filemap.cend(); ++i)
scopedfiles.emplace_back(new ScopedFile(i->first, data));

// clear files list so only fileSettings are used
if (useFS)
filemap.clear();

// TODO: test with settings.project.fileSettings;
SingleExecutor executor(cppcheck, filemap, settings, *this);
ASSERT_EQUALS(result, executor.check());
}

Expand Down Expand Up @@ -112,7 +136,7 @@ class TestSingleExecutor : public TestFixture {
"}");
std::string expected;
for (int i = 1; i <= 100; ++i) {
expected += "Checking file_" + zpad3(i) + ".cpp ...\n";
expected += "Checking " + fprefix() + "_" + zpad3(i) + ".cpp ...\n";
expected += std::to_string(i) + "/100 files checked " + std::to_string(i) + "% done\n";
}
ASSERT_EQUALS(expected, output.str());
Expand Down Expand Up @@ -190,7 +214,7 @@ class TestSingleExecutor : public TestFixture {
settings.library.mProcessAfterCode.emplace(".cp1", true);

const std::vector<std::string> files = {
"file_1.cp1", "file_2.cpp", "file_3.cp1", "file_4.cpp"
fprefix() + "_1.cp1", fprefix() + "_2.cpp", fprefix() + "_3.cp1", fprefix() + "_4.cpp"
};

// checks are not executed on markup files => expected result is 2
Expand All @@ -202,13 +226,13 @@ class TestSingleExecutor : public TestFixture {
"}",
SHOWTIME_MODES::SHOWTIME_NONE, nullptr, files);
// TODO: filter out the "files checked" messages
ASSERT_EQUALS("Checking file_2.cpp ...\n"
ASSERT_EQUALS("Checking " + fprefix() + "_2.cpp ...\n"
"1/4 files checked 25% done\n"
"Checking file_4.cpp ...\n"
"Checking " + fprefix() + "_4.cpp ...\n"
"2/4 files checked 50% done\n"
"Checking file_1.cp1 ...\n"
"Checking " + fprefix() + "_1.cp1 ...\n"
"3/4 files checked 75% done\n"
"Checking file_3.cp1 ...\n"
"Checking " + fprefix() + "_3.cp1 ...\n"
"4/4 files checked 100% done\n", output.str());
settings = settingsOld;
}
Expand All @@ -217,4 +241,15 @@ class TestSingleExecutor : public TestFixture {
// TODO: test whole program analysis
};

REGISTER_TEST(TestSingleExecutor)
class TestSingleExecutorFiles : public TestSingleExecutorBase {
public:
TestSingleExecutorFiles() : TestSingleExecutorBase("TestSingleExecutorFiles", false) {}
};

class TestSingleExecutorFS : public TestSingleExecutorBase {
public:
TestSingleExecutorFS() : TestSingleExecutorBase("TestSingleExecutorFS", true) {}
};

REGISTER_TEST(TestSingleExecutorFiles)
REGISTER_TEST(TestSingleExecutorFS)
25 changes: 15 additions & 10 deletions test/testthreadexecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ class TestThreadExecutor : public TestFixture {
private:
Settings settings = settingsBuilder().library("std.cfg").build();

static std::string fprefix()
{
return "thread";
}

/**
* Execute check using n jobs for y files which are have
* identical data, given within data.
Expand All @@ -53,7 +58,7 @@ class TestThreadExecutor : public TestFixture {
if (filesList.empty()) {
for (int i = 1; i <= files; ++i) {
std::ostringstream oss;
oss << "file_" << i << ".cpp";
oss << fprefix() << "_" << i << ".cpp";
filemap[oss.str()] = data.size();
}
}
Expand Down Expand Up @@ -184,7 +189,7 @@ class TestThreadExecutor : public TestFixture {
settings.library.mProcessAfterCode.emplace(".cp1", true);

const std::vector<std::string> files = {
"file_1.cp1", "file_2.cpp", "file_3.cp1", "file_4.cpp"
fprefix() + "_1.cp1", fprefix() + "_2.cpp", fprefix() + "_3.cp1", fprefix() + "_4.cpp"
};

// checks are not executed on markup files => expected result is 2
Expand All @@ -196,21 +201,21 @@ class TestThreadExecutor : public TestFixture {
"}",
SHOWTIME_MODES::SHOWTIME_NONE, nullptr, files);
// TODO: order of "Checking" and "checked" is affected by thread
/*TODO_ASSERT_EQUALS("Checking file_2.cpp ...\n"
/*TODO_ASSERT_EQUALS("Checking " + fprefix() + "_2.cpp ...\n"
"1/4 files checked 25% done\n"
"Checking file_4.cpp ...\n"
"Checking " + fprefix() + "_4.cpp ...\n"
"2/4 files checked 50% done\n"
"Checking file_1.cp1 ...\n"
"Checking " + fprefix() + "_1.cp1 ...\n"
"3/4 files checked 75% done\n"
"Checking file_3.cp1 ...\n"
"Checking " + fprefix() + "_3.cp1 ...\n"
"4/4 files checked 100% done\n",
"Checking file_1.cp1 ...\n"
"Checking " + fprefix() + "_1.cp1 ...\n"
"1/4 files checked 25% done\n"
"Checking file_2.cpp ...\n"
"Checking " + fprefix() + "_2.cpp ...\n"
"2/4 files checked 50% done\n"
"Checking file_3.cp1 ...\n"
"Checking " + fprefix() + "_3.cp1 ...\n"
"3/4 files checked 75% done\n"
"Checking file_4.cpp ...\n"
"Checking " + fprefix() + "_4.cpp ...\n"
"4/4 files checked 100% done\n",
output.str());*/
settings = settingsOld;
Expand Down