Skip to content

Commit e5bf7f2

Browse files
committed
Fix #13751 (Allow that --file-filter is used on looked up files)
1 parent ebc80c0 commit e5bf7f2

5 files changed

Lines changed: 54 additions & 9 deletions

File tree

cli/cmdlineparser.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -308,9 +308,7 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[])
308308

309309
std::list<FileWithDetails> files;
310310
if (!mSettings.fileFilters.empty()) {
311-
std::copy_if(filesResolved.cbegin(), filesResolved.cend(), std::inserter(files, files.end()), [&](const FileWithDetails& entry) {
312-
return matchglobs(mSettings.fileFilters, entry.path());
313-
});
311+
files = filterFiles(mSettings.fileFilters, filesResolved);
314312
if (files.empty()) {
315313
mLogger.printError("could not find any files matching the filter.");
316314
return false;
@@ -2177,3 +2175,16 @@ bool CmdLineParser::loadCppcheckCfg()
21772175
return true;
21782176
}
21792177

2178+
std::list<FileWithDetails> CmdLineParser::filterFiles(const std::vector<std::string>& fileFilters,
2179+
const std::list<FileWithDetails>& filesResolved) {
2180+
std::list<FileWithDetails> files;
2181+
#ifdef _WIN32
2182+
constexpr bool caseInsensitive = true;
2183+
#else
2184+
constexpr bool caseInsensitive = false;
2185+
#endif
2186+
std::copy_if(filesResolved.cbegin(), filesResolved.cend(), std::inserter(files, files.end()), [&](const FileWithDetails& entry) {
2187+
return matchglobs(fileFilters, entry.path(), caseInsensitive) || matchglobs(fileFilters, entry.spath(), caseInsensitive);
2188+
});
2189+
return files;
2190+
}

cli/cmdlineparser.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,16 @@ class CmdLineParser {
6868
*/
6969
bool fillSettingsFromArgs(int argc, const char* const argv[]);
7070

71+
/**
72+
* @brief Filter files
73+
*
74+
* @param fileFilters file filters
75+
* @param filesResolved all the files in project
76+
* @return the files in filesResolved that match filters
77+
*/
78+
static std::list<FileWithDetails> filterFiles(const std::vector<std::string>& fileFilters,
79+
const std::list<FileWithDetails>& filesResolved);
80+
7181
/**
7282
* Parse given command line.
7383
* @return true if command line was ok, false if there was an error.

lib/utils.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ bool isValidGlobPattern(const std::string& pattern)
5151
return true;
5252
}
5353

54-
bool matchglob(const std::string& pattern, const std::string& name)
54+
bool matchglob(const std::string& pattern, const std::string& name, bool caseInsensitive)
5555
{
5656
const char* p = pattern.c_str();
5757
const char* n = name.c_str();
@@ -83,6 +83,8 @@ bool matchglob(const std::string& pattern, const std::string& name)
8383
// Non-wildcard characters match literally
8484
if (*n == *p) {
8585
n++;
86+
} else if (caseInsensitive && tolower(*n) == tolower(*p)) {
87+
n++;
8688
} else if (*n == '\\' && *p == '/') {
8789
n++;
8890
} else if (*n == '/' && *p == '\\') {
@@ -115,9 +117,9 @@ bool matchglob(const std::string& pattern, const std::string& name)
115117
}
116118
}
117119

118-
bool matchglobs(const std::vector<std::string> &patterns, const std::string &name) {
119-
return std::any_of(begin(patterns), end(patterns), [&name](const std::string &pattern) {
120-
return matchglob(pattern, name);
120+
bool matchglobs(const std::vector<std::string> &patterns, const std::string &name, bool caseInsensitive) {
121+
return std::any_of(begin(patterns), end(patterns), [&name, caseInsensitive](const std::string &pattern) {
122+
return matchglob(pattern, name, caseInsensitive);
121123
});
122124
}
123125

lib/utils.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,9 @@ CPPCHECKLIB int caseInsensitiveStringCompare(const std::string& lhs, const std::
202202

203203
CPPCHECKLIB bool isValidGlobPattern(const std::string& pattern);
204204

205-
CPPCHECKLIB bool matchglob(const std::string& pattern, const std::string& name);
205+
CPPCHECKLIB bool matchglob(const std::string& pattern, const std::string& name, bool caseInsensitive = false);
206206

207-
CPPCHECKLIB bool matchglobs(const std::vector<std::string> &patterns, const std::string &name);
207+
CPPCHECKLIB bool matchglobs(const std::vector<std::string> &patterns, const std::string &name, bool caseInsensitive = false);
208208

209209
CPPCHECKLIB void strTolower(std::string& str);
210210

test/testcmdlineparser.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,8 @@ class TestCmdlineParser : public TestFixture {
204204
TEST_CASE(exitcodeSuppressionsOld);
205205
TEST_CASE(exitcodeSuppressions);
206206
TEST_CASE(exitcodeSuppressionsNoFile);
207+
TEST_CASE(fileFilterFileWithDetailsSimplifiedPath);
208+
TEST_CASE(fileFilterFileWithDetailsCase);
207209
TEST_CASE(fileFilterStdin);
208210
TEST_CASE(fileList);
209211
TEST_CASE(fileListNoFile);
@@ -1181,6 +1183,26 @@ class TestCmdlineParser : public TestFixture {
11811183
ASSERT_EQUALS("cppcheck: error: unrecognized command line option: \"--exitcode-suppressions\".\n", logger->str());
11821184
}
11831185

1186+
void fileFilterFileWithDetailsSimplifiedPath() {
1187+
// match against simplified path
1188+
const std::vector<std::string> fileFilters{"m1.c"};
1189+
const std::list<FileWithDetails> filesResolved{ FileWithDetails("./m1.c", Standards::Language::C, 123) };
1190+
std::list<FileWithDetails> files = CmdLineParser::filterFiles(fileFilters, filesResolved);
1191+
ASSERT_EQUALS(1U, files.size());
1192+
}
1193+
1194+
void fileFilterFileWithDetailsCase() {
1195+
// in windows, paths are case insensitive
1196+
const std::vector<std::string> fileFilters{"m1.c"};
1197+
const std::list<FileWithDetails> filesResolved{ FileWithDetails("M1.C", Standards::Language::C, 123) };
1198+
std::list<FileWithDetails> files = CmdLineParser::filterFiles(fileFilters, filesResolved);
1199+
#ifdef _WIN32
1200+
ASSERT_EQUALS(1U, files.size());
1201+
#else
1202+
ASSERT_EQUALS(0U, files.size());
1203+
#endif
1204+
}
1205+
11841206
void fileFilterStdin() {
11851207
REDIRECT;
11861208
RedirectInput input("file1.c\nfile2.cpp\n");

0 commit comments

Comments
 (0)