Skip to content

Commit f3e4824

Browse files
authored
Fix #14116 (cmdline: Improve IDE integration with --file-filter=+ option) (#7799)
1 parent a674741 commit f3e4824

File tree

3 files changed

+47
-9
lines changed

3 files changed

+47
-9
lines changed

cli/cmdlineparser.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
382382
bool def = false;
383383
bool maxconfigs = false;
384384
bool debug = false;
385+
bool inputAsFilter = false; // set by: --file-filter=+
385386

386387
ImportProject::Type projectType = ImportProject::Type::NONE;
387388
ImportProject project;
@@ -768,6 +769,8 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
768769
mLogger.printError("Failed: --file-filter=-");
769770
return Result::Fail;
770771
}
772+
} else if (std::strcmp(filter, "+") == 0) {
773+
inputAsFilter = true;
771774
} else {
772775
mSettings.fileFilters.emplace_back(filter);
773776
}
@@ -1582,6 +1585,11 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
15821585
//mLogger.printMessage("whole program analysis requires --cppcheck-build-dir to be active with -j.");
15831586
}
15841587

1588+
if (inputAsFilter) {
1589+
mSettings.fileFilters.insert(mSettings.fileFilters.end(), mPathNames.cbegin(), mPathNames.cend());
1590+
mPathNames.clear();
1591+
}
1592+
15851593
if (!mPathNames.empty() && projectType != ImportProject::Type::NONE) {
15861594
mLogger.printError("--project cannot be used in conjunction with source files.");
15871595
return Result::Fail;
@@ -1777,10 +1785,12 @@ void CmdLineParser::printHelp() const
17771785
" --exitcode-suppressions=<file>\n"
17781786
" Used when certain messages should be displayed but\n"
17791787
" should not cause a non-zero exitcode.\n"
1780-
" --file-filter=<str> Analyze only those files matching the given filter str\n"
1781-
" Can be used multiple times\n"
1788+
" --file-filter=<str> Analyze only those files matching the given filter str.\n"
1789+
" Can be used multiple times. When str is '-', the file\n"
1790+
" filter will be read from standard input. When str is '+',\n"
1791+
" given files on CLI will be treated as file filters.\n"
17821792
" Example: --file-filter=*bar.cpp analyzes only files\n"
1783-
" that end with bar.cpp.\n"
1793+
" that end with bar.cpp.\n"
17841794
" --file-list=<file> Specify the files to check in a text file. Add one\n"
17851795
" filename per line. When file is '-,' the file list will\n"
17861796
" be read from standard input.\n"

test/cli/more-projects_test.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,13 @@ def test_clang_tidy(tmpdir):
295295
assert stderr == ''
296296

297297

298-
def test_project_file_filter(tmpdir):
298+
@pytest.mark.parametrize("file_filter", [
299+
['--file-filter=test.cpp'],
300+
['--file-filter=*.cpp'],
301+
['--file-filter=+', 'test.cpp'],
302+
['--file-filter=+', '*.cpp'],
303+
])
304+
def test_project_file_filter(tmpdir, file_filter):
299305
test_file = os.path.join(tmpdir, 'test.cpp')
300306
with open(test_file, 'wt') as f:
301307
pass
@@ -310,15 +316,19 @@ def test_project_file_filter(tmpdir):
310316
</paths>
311317
</project>""".format(test_file))
312318

313-
args = ['--file-filter=*.cpp', '--project={}'.format(project_file)]
319+
args = file_filter + ['--project={}'.format(project_file)]
314320
out_lines = [
315321
'Checking {} ...'.format(test_file)
316322
]
317323

318324
assert_cppcheck(args, ec_exp=0, err_exp=[], out_exp=out_lines)
319325

320326

321-
def test_project_file_filter_2(tmpdir):
327+
@pytest.mark.parametrize("file_filter", [
328+
['--file-filter=*.cpp'],
329+
['--file-filter=+', '*.cpp'],
330+
])
331+
def test_project_file_filter_cpp(tmpdir, file_filter):
322332
test_file_1 = os.path.join(tmpdir, 'test.cpp')
323333
with open(test_file_1, 'wt') as f:
324334
pass
@@ -337,15 +347,19 @@ def test_project_file_filter_2(tmpdir):
337347
</paths>
338348
</project>""".format(test_file_1, test_file_2))
339349

340-
args = ['--file-filter=*.cpp', '--project={}'.format(project_file)]
350+
args = file_filter + ['--project={}'.format(project_file)]
341351
out_lines = [
342352
'Checking {} ...'.format(test_file_1)
343353
]
344354

345355
assert_cppcheck(args, ec_exp=0, err_exp=[], out_exp=out_lines)
346356

347357

348-
def test_project_file_filter_3(tmpdir):
358+
@pytest.mark.parametrize("file_filter", [
359+
['--file-filter=*.c'],
360+
['--file-filter=+', '*.c'],
361+
])
362+
def test_project_file_filter_c(tmpdir, file_filter):
349363
test_file_1 = os.path.join(tmpdir, 'test.cpp')
350364
with open(test_file_1, 'wt') as f:
351365
pass
@@ -364,7 +378,7 @@ def test_project_file_filter_3(tmpdir):
364378
</paths>
365379
</project>""".format(test_file_1, test_file_2))
366380

367-
args = ['--file-filter=*.c', '--project={}'.format(project_file)]
381+
args = file_filter + ['--project={}'.format(project_file)]
368382
out_lines = [
369383
'Checking {} ...'.format(test_file_2)
370384
]

test/testcmdlineparser.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ class TestCmdlineParser : public TestFixture {
208208
TEST_CASE(fileFilterFileWithDetailsSimplifiedPath);
209209
TEST_CASE(fileFilterFileWithDetailsCase);
210210
TEST_CASE(fileFilterStdin);
211+
TEST_CASE(fileFilterPlus);
211212
TEST_CASE(fileFilterNoMatch);
212213
TEST_CASE(fileList);
213214
TEST_CASE(fileListNoFile);
@@ -1233,6 +1234,19 @@ class TestCmdlineParser : public TestFixture {
12331234
ASSERT_EQUALS("file2.cpp", settings->fileFilters[1]);
12341235
}
12351236

1237+
void fileFilterPlus() {
1238+
REDIRECT;
1239+
ScopedFile file("project.cppcheck",
1240+
"<project>\n"
1241+
"<paths>\n"
1242+
"<dir name=\"src\"/>\n"
1243+
"</paths>\n"
1244+
"</project>");
1245+
const char * const argv[] = {"cppcheck", "--project=project.cppcheck", "--file-filter=+", "src/file.cpp"};
1246+
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv));
1247+
ASSERT_EQUALS("src/file.cpp", settings->fileFilters.front());
1248+
}
1249+
12361250
void fileFilterNoMatch() {
12371251
REDIRECT;
12381252
RedirectInput input("notexist1.c\nnotexist2.cpp\n");

0 commit comments

Comments
 (0)