Skip to content

Commit fcd5cda

Browse files
fuzzelhjbdanmar
authored andcommitted
Check selected files from project (#2378)
1 parent 3db6502 commit fcd5cda

File tree

5 files changed

+61
-4
lines changed

5 files changed

+61
-4
lines changed

cli/cmdlineparser.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,10 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
376376
mSettings->xml = true;
377377
}
378378

379+
// use a file filter
380+
else if (std::strncmp(argv[i], "--file-filter=", 14) == 0)
381+
mSettings->fileFilter = std::string(argv[i] + 14);
382+
379383
// Only print something when there are errors
380384
else if (std::strcmp(argv[i], "-q") == 0 || std::strcmp(argv[i], "--quiet") == 0)
381385
mSettings->quiet = true;
@@ -1035,6 +1039,9 @@ void CmdLineParser::printHelp()
10351039
" --exitcode-suppressions=<file>\n"
10361040
" Used when certain messages should be displayed but\n"
10371041
" should not cause a non-zero exitcode.\n"
1042+
" --file-filter=<str> Analyze only those files matching the given filter str\n"
1043+
" Example: --file-filter=*bar.cpp analyzes only files\n"
1044+
" that end with bar.cpp.\n"
10381045
" --file-list=<file> Specify the files to check in a text file. Add one\n"
10391046
" filename per line. When file is '-,' the file list will\n"
10401047
" be read from standard input.\n"

cli/cppcheckexecutor.cpp

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,23 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
159159
#else
160160
const bool caseSensitive = true;
161161
#endif
162-
if (!pathnames.empty()) {
162+
if (!mSettings->project.fileSettings.empty() && !mSettings->fileFilter.empty()) {
163+
// filter only for the selected filenames from all project files
164+
std::list<ImportProject::FileSettings> newList;
165+
166+
for (const ImportProject::FileSettings &fsetting : settings.project.fileSettings) {
167+
if (Suppressions::matchglob(mSettings->fileFilter, fsetting.filename)) {
168+
newList.push_back(fsetting);
169+
}
170+
}
171+
if (!newList.empty())
172+
settings.project.fileSettings = newList;
173+
else {
174+
std::cout << "cppcheck: error: could not find any files matching the filter." << std::endl;
175+
return false;
176+
}
177+
}
178+
else if (!pathnames.empty()) {
163179
// Execute recursiveAddFiles() to each given file parameter
164180
const PathMatch matcher(ignored, caseSensitive);
165181
for (const std::string &pathname : pathnames)
@@ -172,6 +188,20 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c
172188
std::cout << "cppcheck: Maybe all paths were ignored?" << std::endl;
173189
return false;
174190
}
191+
else if(!mSettings->fileFilter.empty()) {
192+
std::map<std::string, std::size_t> newMap;
193+
for (std::map<std::string, std::size_t>::const_iterator i = mFiles.begin(); i != mFiles.end(); ++i)
194+
if (Suppressions::matchglob(mSettings->fileFilter, i->first)) {
195+
newMap[i->first] = i->second;
196+
}
197+
mFiles = newMap;
198+
if (mFiles.empty()) {
199+
std::cout << "cppcheck: error: could not find any files matching the filter." << std::endl;
200+
return false;
201+
}
202+
203+
}
204+
175205
return true;
176206
}
177207

@@ -890,9 +920,8 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck, int /*argc*/, const cha
890920
}
891921
}
892922
} else {
893-
894923
// filesettings
895-
c = 0;
924+
// check all files of the project
896925
for (const ImportProject::FileSettings &fs : settings.project.fileSettings) {
897926
returnValue += cppcheck.check(fs);
898927
++c;

lib/settings.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ class CPPCHECKLIB Settings : public cppcheck::Platform {
7979
/** @brief --cppcheck-build-dir */
8080
std::string buildDir;
8181

82+
/** @brief --file-filter for analyzing special files */
83+
std::string fileFilter;
84+
8285
/** Is the 'configuration checking' wanted? */
8386
bool checkConfiguration;
8487

man/manual.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,16 @@ We don't know which approach (project file or manual configuration) will give yo
8282

8383
Later chapters will describe this in more detail.
8484

85+
### Check files matching a given file filter
86+
87+
With `--file-filter=<str>` you can set a file filter and only those files matching the filter will be checked.
88+
89+
For example: if you want to check only those files and folders starting from a subfolder src/ that start with "test" you have to type:
90+
91+
cppcheck src/ --file-filter=src/test*
92+
93+
Cppcheck first collects all files in src/ and will apply the filter after that. So the filter must start with the given start folder.
94+
8595
### Excluding a file or folder from checking
8696

8797
To exclude a file or folder, there are two options. The first option is to only provide the paths and files you want to check.

test/cli/test-proj2.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@ def cppcheck_local(args):
2929
os.chdir(cwd)
3030
return (ret, stdout, stderr)
3131

32+
def test_file_filter():
33+
ret, stdout, stderr = cppcheck(['proj2/','--file-filter=proj2/a/*'])
34+
file1 = os.path.join('proj2', 'a', 'a.c')
35+
file2 = os.path.join('proj2', 'b', 'b.c')
36+
assert ret == 0
37+
assert stdout.find('Checking %s ...' % (file1)) >= 0
38+
ret, stdout, stderr = cppcheck(['proj2/','--file-filter=proj2/b*'])
39+
assert ret == 0
40+
assert stdout.find('Checking %s ...' % (file2)) >= 0
3241

3342
def test_local_path():
3443
create_compile_commands()
@@ -150,4 +159,3 @@ def test_gui_project_loads_absolute_vs_solution():
150159
import_project=os.path.join(os.getcwd(), 'proj2', 'proj2.sln').replace('\\', '/'))
151160
ret, stdout, stderr = cppcheck(['--project=test.cppcheck'])
152161
assert stderr == ERR_A + ERR_B
153-

0 commit comments

Comments
 (0)