Skip to content

Commit f790e2a

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

17 files changed

Lines changed: 259 additions & 55 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: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,17 @@ void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLib, c
683683
return;
684684
}
685685

686+
const QStringList& unmatchedExcludePaths = pathList.getUnmatchedExcludes();
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?

‎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
};

‎lib/importproject.cpp‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ void ImportProject::parseArgs(FileSettings &fs, const std::vector<std::string> &
191191
fsSetDefines(fs, std::move(defs));
192192
}
193193

194-
void ImportProject::ignorePaths(const std::vector<std::string> &ipaths, bool debug)
194+
std::vector<std::string> ImportProject::ignorePaths(const std::vector<std::string> &ipaths, bool debug)
195195
{
196196
PathMatch matcher(ipaths, Path::getCurrentPath());
197197
for (auto it = fileSettings.cbegin(); it != fileSettings.cend();) {
@@ -203,6 +203,7 @@ void ImportProject::ignorePaths(const std::vector<std::string> &ipaths, bool deb
203203
else
204204
++it;
205205
}
206+
return matcher.unmatched();
206207
}
207208

208209
void ImportProject::ignoreOtherConfigs(const std::string &cfg)

‎lib/importproject.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ class CPPCHECKLIB WARN_UNUSED ImportProject {
102102
std::string platform;
103103
} guiProject;
104104

105-
void ignorePaths(const std::vector<std::string> &ipaths, bool debug = false);
105+
std::vector<std::string> ignorePaths(const std::vector<std::string> &ipaths, bool debug = false);
106106
void ignoreOtherConfigs(const std::string &cfg);
107107

108108
Type import(const std::string &filename, Settings *settings=nullptr, Suppressions *supprs=nullptr);

0 commit comments

Comments
 (0)