Skip to content

Commit

Permalink
added PathWithDetails to store input path in and use it in `FileSet…
Browse files Browse the repository at this point in the history
…tings`
  • Loading branch information
firewave committed Apr 16, 2024
1 parent 8cd680b commit fdc6738
Show file tree
Hide file tree
Showing 19 changed files with 133 additions and 49 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ TESTOBJ = test/fixture.o \
test/testerrorlogger.o \
test/testexceptionsafety.o \
test/testfilelister.o \
test/testfilesettings.o \
test/testfunctions.o \
test/testgarbage.o \
test/testimportproject.o \
Expand Down Expand Up @@ -753,6 +754,9 @@ test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/addoninfo.h lib/che
test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/addoninfo.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfilelister.cpp

test/testfilesettings.o: test/testfilesettings.cpp lib/addoninfo.h lib/check.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h test/fixture.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfilesettings.cpp

test/testfunctions.o: test/testfunctions.cpp lib/addoninfo.h lib/check.h lib/checkfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h
$(CXX) ${INCLUDE_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfunctions.cpp

Expand Down
6 changes: 3 additions & 3 deletions cli/cmdlineparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[])
if (!mSettings.fileFilters.empty()) {
// filter only for the selected filenames from all project files
std::copy_if(fileSettingsRef.cbegin(), fileSettingsRef.cend(), std::back_inserter(fileSettings), [&](const FileSettings &fs) {
return matchglobs(mSettings.fileFilters, fs.filename);
return matchglobs(mSettings.fileFilters, fs.filename());
});
if (fileSettings.empty()) {
mLogger.printError("could not find any files matching the filter.");
Expand All @@ -219,11 +219,11 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[])

// sort the markup last
std::copy_if(fileSettings.cbegin(), fileSettings.cend(), std::back_inserter(mFileSettings), [&](const FileSettings &fs) {
return !mSettings.library.markupFile(fs.filename) || !mSettings.library.processMarkupAfterCode(fs.filename);
return !mSettings.library.markupFile(fs.filename()) || !mSettings.library.processMarkupAfterCode(fs.filename());
});

std::copy_if(fileSettings.cbegin(), fileSettings.cend(), std::back_inserter(mFileSettings), [&](const FileSettings &fs) {
return mSettings.library.markupFile(fs.filename) && mSettings.library.processMarkupAfterCode(fs.filename);
return mSettings.library.markupFile(fs.filename()) && mSettings.library.processMarkupAfterCode(fs.filename());
});

if (mFileSettings.empty()) {
Expand Down
2 changes: 1 addition & 1 deletion cli/cppcheckexecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ bool CppCheckExecutor::reportSuppressions(const Settings &settings, const Suppre

for (std::list<FileSettings>::const_iterator i = fileSettings.cbegin(); i != fileSettings.cend(); ++i) {
err |= SuppressionList::reportUnmatchedSuppressions(
suppressions.getUnmatchedLocalSuppressions(i->filename, unusedFunctionCheckEnabled), errorLogger);
suppressions.getUnmatchedLocalSuppressions(i->filename(), unusedFunctionCheckEnabled), errorLogger);
}
}
err |= SuppressionList::reportUnmatchedSuppressions(suppressions.getUnmatchedGlobalSuppressions(unusedFunctionCheckEnabled), errorLogger);
Expand Down
4 changes: 2 additions & 2 deletions cli/processexecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,8 @@ unsigned int ProcessExecutor::check()
close(pipes[1]);
rpipes.push_back(pipes[0]);
if (iFileSettings != mFileSettings.end()) {
childFile[pid] = iFileSettings->filename + ' ' + iFileSettings->cfg;
pipeFile[pipes[0]] = iFileSettings->filename + ' ' + iFileSettings->cfg;
childFile[pid] = iFileSettings->filename() + ' ' + iFileSettings->cfg;
pipeFile[pipes[0]] = iFileSettings->filename() + ' ' + iFileSettings->cfg;
++iFileSettings;
} else {
childFile[pid] = iFile->first;
Expand Down
8 changes: 4 additions & 4 deletions gui/checkthread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,11 @@ void CheckThread::run()
}

FileSettings fileSettings = mResult.getNextFileSettings();
while (!fileSettings.filename.empty() && mState == Running) {
file = QString::fromStdString(fileSettings.filename);
while (!fileSettings.filename().empty() && mState == Running) {
file = QString::fromStdString(fileSettings.filename());
qDebug() << "Checking file" << file;
mCppcheck.check(fileSettings);
runAddonsAndTools(&fileSettings, QString::fromStdString(fileSettings.filename));
runAddonsAndTools(&fileSettings, QString::fromStdString(fileSettings.filename()));
emit fileChecked(file);

if (mState == Running)
Expand Down Expand Up @@ -214,7 +214,7 @@ void CheckThread::runAddonsAndTools(const FileSettings *fileSettings, const QStr

const std::string &buildDir = mCppcheck.settings().buildDir;
if (!buildDir.empty()) {
analyzerInfoFile = QString::fromStdString(AnalyzerInformation::getAnalyzerInfoFile(buildDir, fileSettings->filename, fileSettings->cfg));
analyzerInfoFile = QString::fromStdString(AnalyzerInformation::getAnalyzerInfoFile(buildDir, fileSettings->filename(), fileSettings->cfg));

QStringList args2(args);
args2.insert(0,"-E");
Expand Down
2 changes: 1 addition & 1 deletion gui/compliancereportdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ void ComplianceReportDialog::save()

QDir dir(inf.absoluteDir());
for (const FileSettings& fs: p.fileSettings)
fileList.addFile(dir.relativeFilePath(QString::fromStdString(fs.filename)));
fileList.addFile(dir.relativeFilePath(QString::fromStdString(fs.filename())));
}

QSet<QString> allFiles;
Expand Down
2 changes: 1 addition & 1 deletion gui/threadresult.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ void ThreadResult::setProject(const ImportProject &prj)
// Determine the total size of all of the files to check, so that we can
// show an accurate progress estimate
mMaxProgress = std::accumulate(prj.fileSettings.begin(), prj.fileSettings.end(), quint64{ 0 }, [](quint64 v, const FileSettings& fs) {
return v + QFile(QString::fromStdString(fs.filename)).size();
return v + QFile(QString::fromStdString(fs.filename())).size();
});
}

Expand Down
4 changes: 2 additions & 2 deletions lib/analyzerinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ void AnalyzerInformation::writeFilesTxt(const std::string &buildDir, const std::
}

for (const FileSettings &fs : fileSettings) {
const std::string afile = getFilename(fs.filename);
fout << afile << ".a" << (++fileCount[afile]) << ":" << fs.cfg << ":" << Path::simplifyPath(Path::fromNativeSeparators(fs.filename)) << std::endl;
const std::string afile = getFilename(fs.filename());
fout << afile << ".a" << (++fileCount[afile]) << ":" << fs.cfg << ":" << Path::simplifyPath(Path::fromNativeSeparators(fs.filename())) << std::endl;
}
}

Expand Down
10 changes: 5 additions & 5 deletions lib/cppcheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,12 +593,12 @@ unsigned int CppCheck::check(const FileSettings &fs)
if (mSettings.clang) {
temp.mSettings.includePaths.insert(temp.mSettings.includePaths.end(), fs.systemIncludePaths.cbegin(), fs.systemIncludePaths.cend());
// TODO: propagate back suppressions
const unsigned int returnValue = temp.check(Path::simplifyPath(fs.filename));
const unsigned int returnValue = temp.check(Path::simplifyPath(fs.filename()));
if (mUnusedFunctionsCheck)
mUnusedFunctionsCheck->updateFunctionData(*temp.mUnusedFunctionsCheck);
return returnValue;
}
const unsigned int returnValue = temp.checkFile(Path::simplifyPath(fs.filename), fs.cfg);
const unsigned int returnValue = temp.checkFile(Path::simplifyPath(fs.filename()), fs.cfg);
mSettings.supprs.nomsg.addSuppressions(temp.mSettings.supprs.nomsg.getSuppressions());
if (mUnusedFunctionsCheck)
mUnusedFunctionsCheck->updateFunctionData(*temp.mUnusedFunctionsCheck);
Expand Down Expand Up @@ -1683,7 +1683,7 @@ void CppCheck::analyseClangTidy(const FileSettings &fileSettings)
constexpr char exe[] = "clang-tidy";
#endif

const std::string args = "-quiet -checks=*,-clang-analyzer-*,-llvm* \"" + fileSettings.filename + "\" -- " + allIncludes + allDefines;
const std::string args = "-quiet -checks=*,-clang-analyzer-*,-llvm* \"" + fileSettings.filename() + "\" -- " + allIncludes + allDefines;
std::string output;
if (const int exitcode = mExecuteCommand(exe, split(args), emptyString, output)) {
std::cerr << "Failed to execute '" << exe << "' (exitcode: " << std::to_string(exitcode) << ")" << std::endl;
Expand All @@ -1695,7 +1695,7 @@ void CppCheck::analyseClangTidy(const FileSettings &fileSettings)
std::string line;

if (!mSettings.buildDir.empty()) {
const std::string analyzerInfoFile = AnalyzerInformation::getAnalyzerInfoFile(mSettings.buildDir, fileSettings.filename, emptyString);
const std::string analyzerInfoFile = AnalyzerInformation::getAnalyzerInfoFile(mSettings.buildDir, fileSettings.filename(), emptyString);
std::ofstream fcmd(analyzerInfoFile + ".clang-tidy-cmd");
fcmd << istr.str();
}
Expand Down Expand Up @@ -1847,7 +1847,7 @@ void CppCheck::removeCtuInfoFiles(const std::list<std::pair<std::string, std::si
std::remove(ctuInfoFileName.c_str());
}
for (const auto& fs: fileSettings) {
const std::string &dumpFileName = getDumpFileName(mSettings, fs.filename);
const std::string &dumpFileName = getDumpFileName(mSettings, fs.filename());
const std::string &ctuInfoFileName = getCtuInfoFileName(dumpFileName);
std::remove(ctuInfoFileName.c_str());
}
Expand Down
26 changes: 25 additions & 1 deletion lib/filesettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,35 @@
#include <list>
#include <set>
#include <string>
#include <utility>

class PathWithDetails
{
public:
PathWithDetails() = default;

explicit PathWithDetails(std::string path)
: mPath(std::move(path))
{}

const std::string& path() const
{
return mPath;
}
private:
std::string mPath;
};

/** File settings. Multiple configurations for a file is allowed. */
struct CPPCHECKLIB FileSettings {
FileSettings() = default; // TODO: call PathWithDetails c'tor

std::string cfg;
std::string filename;
PathWithDetails path;
const std::string& filename() const
{
return path.path();
}
std::string defines;
// TODO: handle differently
std::string cppcheckDefines() const {
Expand Down
24 changes: 12 additions & 12 deletions lib/importproject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,17 @@ void ImportProject::ignorePaths(const std::vector<std::string> &ipaths)
for (std::list<FileSettings>::iterator it = fileSettings.begin(); it != fileSettings.end();) {
bool ignore = false;
for (std::string i : ipaths) {
if (it->filename.size() > i.size() && it->filename.compare(0,i.size(),i)==0) {
if (it->filename().size() > i.size() && it->filename().compare(0,i.size(),i)==0) {
ignore = true;
break;
}
if (isValidGlobPattern(i) && matchglob(i, it->filename)) {
if (isValidGlobPattern(i) && matchglob(i, it->filename())) {
ignore = true;
break;
}
if (!Path::isAbsolute(i)) {
i = mPath + i;
if (it->filename.size() > i.size() && it->filename.compare(0,i.size(),i)==0) {
if (it->filename().size() > i.size() && it->filename().compare(0,i.size(),i)==0) {
ignore = true;
break;
}
Expand Down Expand Up @@ -400,7 +400,7 @@ bool ImportProject::importCompileCommands(std::istream &istr)

FileSettings fs;
if (Path::isAbsolute(file))
fs.filename = Path::simplifyPath(file);
fs.path = PathWithDetails{Path::simplifyPath(file)};
#ifdef _WIN32
else if (file[0] == '/' && directory.size() > 2 && std::isalpha(directory[0]) && directory[1] == ':')
// directory: C:\foo\bar
Expand All @@ -409,9 +409,9 @@ bool ImportProject::importCompileCommands(std::istream &istr)
fs.filename = Path::simplifyPath(directory.substr(0,2) + file);
#endif
else
fs.filename = Path::simplifyPath(directory + file);
if (!sourceFileExists(fs.filename)) {
printError("'" + fs.filename + "' from compilation database does not exist");
fs.path = PathWithDetails{Path::simplifyPath(directory + file)};
if (!sourceFileExists(fs.filename())) {
printError("'" + fs.filename() + "' from compilation database does not exist");
return false;
}
fsParseCommand(fs, command); // read settings; -D, -I, -U, -std, -m*, -f*
Expand Down Expand Up @@ -760,7 +760,7 @@ bool ImportProject::importVcxproj(const std::string &filename, std::map<std::str
}

FileSettings fs;
fs.filename = cfilename;
fs.path = PathWithDetails{cfilename};
fs.cfg = p.name;
// TODO: detect actual MSC version
fs.msc = true;
Expand Down Expand Up @@ -1058,7 +1058,7 @@ bool ImportProject::importBcb6Prj(const std::string &projectFilename)
FileSettings fs;
fsSetIncludePaths(fs, projectDir, toStringList(includePath), variables);
fsSetDefines(fs, cppMode ? cppDefines : defines);
fs.filename = Path::simplifyPath(Path::isAbsolute(c) ? c : projectDir + c);
fs.path = PathWithDetails{Path::simplifyPath(Path::isAbsolute(c) ? c : projectDir + c)};
fileSettings.push_back(std::move(fs));
}

Expand Down Expand Up @@ -1294,12 +1294,12 @@ void ImportProject::selectOneVsConfig(Platform::Type platform)
remove = true;
else if ((platform == Platform::Type::Win32A || platform == Platform::Type::Win32W) && fs.platformType == Platform::Type::Win64)
remove = true;
else if (filenames.find(fs.filename) != filenames.end())
else if (filenames.find(fs.filename()) != filenames.end())
remove = true;
if (remove) {
it = fileSettings.erase(it);
} else {
filenames.insert(fs.filename);
filenames.insert(fs.filename());
++it;
}
}
Expand Down Expand Up @@ -1340,7 +1340,7 @@ void ImportProject::setRelativePaths(const std::string &filename)
return;
const std::vector<std::string> basePaths{Path::fromNativeSeparators(Path::getCurrentPath())};
for (auto &fs: fileSettings) {
fs.filename = Path::getRelativePath(fs.filename, basePaths);
fs.path = PathWithDetails{Path::getRelativePath(fs.filename(), basePaths)};
for (auto &includePath: fs.includePaths)
includePath = Path::getRelativePath(includePath, basePaths);
}
Expand Down
2 changes: 1 addition & 1 deletion test/testcppcheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ class TestCppcheck : public TestFixture {
ErrorLogger2 errorLogger;
CppCheck cppcheck(errorLogger, false, {});
FileSettings fs;
fs.filename = file.path();
fs.path = PathWithDetails{file.path()};
ASSERT_EQUALS(1, cppcheck.check(fs));
// TODO: how to properly disable these warnings?
errorLogger.ids.erase(std::remove_if(errorLogger.ids.begin(), errorLogger.ids.end(), [](const std::string& id) {
Expand Down
55 changes: 55 additions & 0 deletions test/testfilesettings.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Cppcheck - A tool for static C/C++ code analysis
* Copyright (C) 2007-2024 Cppcheck team.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "filesettings.h"
#include "fixture.h"

class TestFileSettings : public TestFixture {
public:
TestFileSettings() : TestFixture("TestFileSettings") {}

private:
void run() override {
TEST_CASE(path);
}

void path() const {
{
const PathWithDetails p{"file.cpp"};
ASSERT_EQUALS("file.cpp", p.path());
}
{
const PathWithDetails p{"in/file.cpp"};
ASSERT_EQUALS("in/file.cpp", p.path());
}
{
const PathWithDetails p{"in\\file.cpp"};
ASSERT_EQUALS("in\\file.cpp", p.path());
}
{
const PathWithDetails p{"in/../file.cpp"};
ASSERT_EQUALS("in/../file.cpp", p.path());
}
{
const PathWithDetails p{"in\\..\\file.cpp"};
ASSERT_EQUALS("in\\..\\file.cpp", p.path());
}
}
};

REGISTER_TEST(TestFileSettings)
14 changes: 7 additions & 7 deletions test/testimportproject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ class TestImportProject : public TestFixture {
TestImporter importer;
ASSERT_EQUALS(true, importer.importCompileCommands(istr));
ASSERT_EQUALS(1, importer.fileSettings.size());
ASSERT_EQUALS("C:/bar.c", importer.fileSettings.cbegin()->filename);
ASSERT_EQUALS("C:/bar.c", importer.fileSettings.cbegin()->filename());
#else
constexpr char json[] = R"([{
"directory": "/foo",
Expand All @@ -151,7 +151,7 @@ class TestImportProject : public TestFixture {
TestImporter importer;
ASSERT_EQUALS(true, importer.importCompileCommands(istr));
ASSERT_EQUALS(1, importer.fileSettings.size());
ASSERT_EQUALS("/bar.c", importer.fileSettings.cbegin()->filename);
ASSERT_EQUALS("/bar.c", importer.fileSettings.cbegin()->filename());
#endif
}

Expand All @@ -166,7 +166,7 @@ class TestImportProject : public TestFixture {
TestImporter importer;
ASSERT_EQUALS(true, importer.importCompileCommands(istr));
ASSERT_EQUALS(1, importer.fileSettings.size());
ASSERT_EQUALS("/tmp/src.c", importer.fileSettings.cbegin()->filename);
ASSERT_EQUALS("/tmp/src.c", importer.fileSettings.cbegin()->filename());
}

void importCompileCommands4() const {
Expand Down Expand Up @@ -328,7 +328,7 @@ class TestImportProject : public TestFixture {
TestImporter importer;
ASSERT_EQUALS(true, importer.importCompileCommands(istr));
ASSERT_EQUALS(1, importer.fileSettings.size());
ASSERT_EQUALS("/tmp/src.c", importer.fileSettings.cbegin()->filename);
ASSERT_EQUALS("/tmp/src.c", importer.fileSettings.cbegin()->filename());
}

void importCompileCommandsNoCommandSection() const {
Expand Down Expand Up @@ -372,8 +372,8 @@ class TestImportProject : public TestFixture {

void ignorePaths() const {
FileSettings fs1, fs2;
fs1.filename = "foo/bar";
fs2.filename = "qwe/rty";
fs1.path = PathWithDetails{"foo/bar"};
fs2.path = PathWithDetails{"qwe/rty"};
TestImporter project;
project.fileSettings = {std::move(fs1), std::move(fs2)};

Expand All @@ -382,7 +382,7 @@ class TestImportProject : public TestFixture {

project.ignorePaths({"foo/*"});
ASSERT_EQUALS(1, project.fileSettings.size());
ASSERT_EQUALS("qwe/rty", project.fileSettings.front().filename);
ASSERT_EQUALS("qwe/rty", project.fileSettings.front().filename());

project.ignorePaths({ "*e/r*" });
ASSERT_EQUALS(0, project.fileSettings.size());
Expand Down
Loading

0 comments on commit fdc6738

Please sign in to comment.