Skip to content

Commit 4a9bd45

Browse files
committed
Fix #15081 (usability: try to report misuse of exclude options)
1 parent 8bb772d commit 4a9bd45

19 files changed

Lines changed: 311 additions & 91 deletions

‎cli/cmdlineparser.cpp‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[])
247247
std::list<FileWithDetails> filesResolved;
248248
// Execute recursiveAddFiles() to each given file parameter
249249
// TODO: verbose log which files were ignored?
250-
const PathMatch matcher(ignored, Path::getCurrentPath());
250+
PathMatch matcher(ignored, Path::getCurrentPath());
251251
for (const std::string &pathname : pathnamesRef) {
252252
const std::string err = FileLister::recursiveAddFiles(filesResolved, Path::toNativeSeparators(pathname), mSettings.library.markupExtensions(), matcher, mSettings.debugignore);
253253
if (!err.empty()) {
@@ -264,6 +264,12 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[])
264264
return false;
265265
}
266266

267+
const auto& unmatched = matcher.unmatched();
268+
if (!unmatched.empty()) {
269+
mLogger.printError("unused ignore/exclude path '" + unmatched.front() + "' to hide warnings in certain files use suppressions instead.");
270+
return false;
271+
}
272+
267273
std::list<FileWithDetails> files;
268274
if (!mSettings.fileFilters.empty()) {
269275
files = filterFiles(mSettings.fileFilters, filesResolved);
@@ -1723,12 +1729,16 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
17231729
mPathNames = project.guiProject.pathNames;
17241730

17251731
if (!project.fileSettings.empty()) {
1726-
project.ignorePaths(mIgnoredPaths, mSettings.debugignore);
1732+
const auto& unmatched = project.ignorePaths(mIgnoredPaths, mSettings.debugignore);
17271733
if (project.fileSettings.empty()) {
17281734
mLogger.printError("no C or C++ source files found.");
17291735
mLogger.printMessage("all paths were ignored"); // TODO: log this differently?
17301736
return Result::Fail;
17311737
}
1738+
if (!unmatched.empty()) {
1739+
mLogger.printError("unused ignore/exclude path '" + unmatched.front() + "' to hide warnings in certain files use suppressions instead.");
1740+
return Result::Fail;
1741+
}
17321742
mFileSettings = project.fileSettings;
17331743
}
17341744

‎cli/filelister.cpp‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
// When compiling Unicode targets WinAPI automatically uses *W Unicode versions
4747
// of called functions. Thus, we explicitly call *A versions of the functions.
4848

49-
static std::string addFiles2(std::list<FileWithDetails>&files, const std::string &path, const std::set<std::string> &extra, bool recursive, const PathMatch& ignored, bool debug = false)
49+
static std::string addFiles2(std::list<FileWithDetails>&files, const std::string &path, const std::set<std::string> &extra, bool recursive, PathMatch& ignored, bool debug = false)
5050
{
5151
const std::string cleanedPath = Path::toNativeSeparators(path);
5252

@@ -163,7 +163,7 @@ static std::string addFiles2(std::list<FileWithDetails>&files, const std::string
163163
return "";
164164
}
165165

166-
std::string FileLister::addFiles(std::list<FileWithDetails> &files, const std::string &path, const std::set<std::string> &extra, bool recursive, const PathMatch& ignored, bool debug)
166+
std::string FileLister::addFiles(std::list<FileWithDetails> &files, const std::string &path, const std::set<std::string> &extra, bool recursive, PathMatch& ignored, bool debug)
167167
{
168168
if (path.empty())
169169
return "no path specified";
@@ -201,7 +201,7 @@ static std::string addFiles2(std::list<FileWithDetails> &files,
201201
const std::string &path,
202202
const std::set<std::string> &extra,
203203
bool recursive,
204-
const PathMatch& ignored,
204+
PathMatch& ignored,
205205
bool debug)
206206
{
207207
if (ignored.match(path))
@@ -280,7 +280,7 @@ static std::string addFiles2(std::list<FileWithDetails> &files,
280280
return "";
281281
}
282282

283-
std::string FileLister::addFiles(std::list<FileWithDetails> &files, const std::string &path, const std::set<std::string> &extra, bool recursive, const PathMatch& ignored, bool debug)
283+
std::string FileLister::addFiles(std::list<FileWithDetails> &files, const std::string &path, const std::set<std::string> &extra, bool recursive, PathMatch& ignored, bool debug)
284284
{
285285
if (path.empty())
286286
return "no path specified";
@@ -304,7 +304,7 @@ std::string FileLister::addFiles(std::list<FileWithDetails> &files, const std::s
304304

305305
#endif
306306

307-
std::string FileLister::recursiveAddFiles(std::list<FileWithDetails> &files, const std::string &path, const std::set<std::string> &extra, const PathMatch& ignored, bool debug)
307+
std::string FileLister::recursiveAddFiles(std::list<FileWithDetails> &files, const std::string &path, const std::set<std::string> &extra, PathMatch& ignored, bool debug)
308308
{
309309
return addFiles(files, path, extra, true, ignored, debug);
310310
}

‎cli/filelister.h‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class FileLister {
4444
* @param debug log if path was ignored
4545
* @return On success, an empty string is returned. On error, a error message is returned.
4646
*/
47-
static std::string recursiveAddFiles(std::list<FileWithDetails> &files, const std::string &path, const std::set<std::string> &extra, const PathMatch& ignored, bool debug = false);
47+
static std::string recursiveAddFiles(std::list<FileWithDetails> &files, const std::string &path, const std::set<std::string> &extra, PathMatch& ignored, bool debug = false);
4848

4949
/**
5050
* @brief (Recursively) add source files to a map.
@@ -59,7 +59,7 @@ class FileLister {
5959
* @param debug log when a path was ignored
6060
* @return On success, an empty string is returned. On error, a error message is returned.
6161
*/
62-
static std::string addFiles(std::list<FileWithDetails> &files, const std::string &path, const std::set<std::string> &extra, bool recursive, const PathMatch& ignored, bool debug = false);
62+
static std::string addFiles(std::list<FileWithDetails> &files, const std::string &path, const std::set<std::string> &extra, bool recursive, PathMatch& ignored, bool debug = false);
6363
};
6464

6565
/// @}

‎gui/filelist.cpp‎

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,14 @@ QStringList FileList::getFileList() const
100100
}
101101
return names;
102102
}
103-
return applyExcludeList();
103+
QStringList unmatched;
104+
return applyExcludeList(unmatched);
105+
}
106+
107+
QStringList FileList::getUnmatchedExcludes() const {
108+
QStringList unmatched;
109+
(void)applyExcludeList(unmatched);
110+
return unmatched;
104111
}
105112

106113
void FileList::addExcludeList(const QStringList &paths)
@@ -117,9 +124,9 @@ static std::vector<std::string> toStdStringList(const QStringList &stringList)
117124
return ret;
118125
}
119126

120-
QStringList FileList::applyExcludeList() const
127+
QStringList FileList::applyExcludeList(QStringList& unmatched) const
121128
{
122-
const PathMatch pathMatch(toStdStringList(mExcludedPaths), QDir::currentPath().toStdString());
129+
PathMatch pathMatch(toStdStringList(mExcludedPaths), QDir::currentPath().toStdString());
123130

124131
QStringList paths;
125132
for (const QFileInfo& item : mFileList) {
@@ -129,5 +136,10 @@ QStringList FileList::applyExcludeList() const
129136
if (!pathMatch.match(canonical.toStdString()))
130137
paths << canonical;
131138
}
139+
140+
for (const std::string& excludePath: pathMatch.unmatched()) {
141+
unmatched << QString::fromStdString(excludePath);
142+
}
143+
132144
return paths;
133145
}

‎gui/filelist.h‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <QString>
2525
#include <QStringList>
2626

27+
class PathMatch;
28+
2729
/**
2830
* @brief A class for listing files and directories to check.
2931
* This class creates a list of files to check. If directory name is given then
@@ -64,6 +66,12 @@ class FileList {
6466
*/
6567
QStringList getFileList() const;
6668

69+
/**
70+
* @brief Return list of unmatched excludes
71+
* @return list of unmatched excludes
72+
*/
73+
QStringList getUnmatchedExcludes() const;
74+
6775
/**
6876
* @brief Add list of paths to exclusion list.
6977
* @param paths Paths to exclude.
@@ -89,9 +97,10 @@ class FileList {
8997
* This method takes the list of paths and applies the exclude lists to
9098
* it. And then returns the list of paths that did not match the
9199
* exclude filters.
100+
* @param unmatched output of unmatched exclude paths
92101
* @return Filtered list of paths.
93102
*/
94-
QStringList applyExcludeList() const;
103+
QStringList applyExcludeList(QStringList& unmatched) const;
95104

96105
private:
97106
QFileInfoList mFileList;

‎gui/mainwindow.cpp‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,7 @@ void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLib, const bo
647647
mUI->mResults->setCheckSettings(checkSettings);
648648
}
649649

650-
void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLib, const bool checkConfig)
650+
void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLib, const bool checkConfig, const bool checkUnusedExcludes)
651651
{
652652
if (files.isEmpty())
653653
return;
@@ -683,6 +683,17 @@ void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLib, c
683683
return;
684684
}
685685

686+
const QStringList& unmatchedExcludePaths = checkUnusedExcludes ? pathList.getUnmatchedExcludes() : QStringList();
687+
if (!unmatchedExcludePaths.isEmpty()) {
688+
QMessageBox msg(QMessageBox::Warning,
689+
"Cppcheck",
690+
tr("Unused exclude paths:\n%1\nto hide warnings in certain files use suppressions instead").arg(unmatchedExcludePaths.join("\n")),
691+
QMessageBox::Ok,
692+
this);
693+
msg.exec();
694+
return;
695+
}
696+
686697
std::list<FileWithDetails> fdetails = enrichFilesForAnalysis(fileNames, checkSettings);
687698

688699
// TODO: lock UI here?
@@ -1981,7 +1992,9 @@ void MainWindow::analyzeProject(const ProjectFile *projectFile, const QStringLis
19811992
if (paths.isEmpty()) {
19821993
paths << mCurrentDirectory;
19831994
}
1984-
doAnalyzeFiles(paths, checkLib, checkConfig);
1995+
// the exclude paths can only be validated when the whole project is analyzed
1996+
const bool checkUnusedExcludes = recheckFiles.isEmpty();
1997+
doAnalyzeFiles(paths, checkLib, checkConfig, checkUnusedExcludes);
19851998
}
19861999

19872000
void MainWindow::newProjectFile()

‎gui/mainwindow.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,8 +317,9 @@ private slots:
317317
* @param files List of files and/or directories to analyze
318318
* @param checkLib Flag to indicate if library should be checked
319319
* @param checkConfig Flag to indicate if the configuration should be checked.
320+
* @param checkUnusedExcludes Flag to indicate if unused exclude paths should be reported.
320321
*/
321-
void doAnalyzeFiles(const QStringList &files, bool checkLib = false, bool checkConfig = false);
322+
void doAnalyzeFiles(const QStringList &files, bool checkLib = false, bool checkConfig = false, bool checkUnusedExcludes = false);
322323

323324
/**
324325
* @brief Get our default cppcheck settings and read project file.

‎gui/test/filelist/testfilelist.cpp‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,4 +184,39 @@ void TestFileList::filterFiles5() const
184184
QVERIFY(!files.contains(base + "/dir1/dir11/foo11.cpp"));
185185
}
186186

187+
void TestFileList::unmatchedExcludes1() const
188+
{
189+
FileList list;
190+
QStringList filters;
191+
filters << "foo1.cpp" << "foo3.cc";
192+
list.addExcludeList(filters);
193+
list.addDirectory(QString(SRCDIR) + "/../data/files");
194+
QVERIFY(list.getUnmatchedExcludes().isEmpty());
195+
}
196+
197+
void TestFileList::unmatchedExcludes2() const
198+
{
199+
FileList list;
200+
QStringList filters;
201+
filters << "foo1.cpp" << "bar.cpp" << "dir3/";
202+
list.addExcludeList(filters);
203+
list.addDirectory(QString(SRCDIR) + "/../data/files", true);
204+
const QStringList unmatched = list.getUnmatchedExcludes();
205+
QCOMPARE(unmatched.size(), 2);
206+
QCOMPARE(unmatched[0], QString("bar.cpp"));
207+
QCOMPARE(unmatched[1], QString("dir3/"));
208+
// unmatched excludes does not affect the file list
209+
QCOMPARE(list.getFileList().size(), 9);
210+
}
211+
212+
void TestFileList::unmatchedExcludes3() const
213+
{
214+
FileList list;
215+
QStringList filters;
216+
filters << "dir1/";
217+
list.addExcludeList(filters);
218+
list.addDirectory(QString(SRCDIR) + "/../data/files", true);
219+
QVERIFY(list.getUnmatchedExcludes().isEmpty());
220+
}
221+
187222
QTEST_MAIN(TestFileList)

‎gui/test/filelist/testfilelist.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,7 @@ private slots:
3333
void filterFiles3() const;
3434
void filterFiles4() const;
3535
void filterFiles5() const;
36+
void unmatchedExcludes1() const;
37+
void unmatchedExcludes2() const;
38+
void unmatchedExcludes3() const;
3639
};

0 commit comments

Comments
 (0)