Skip to content

Commit

Permalink
fixed #12221 - de-duplicate input source files (regression) (#5740)
Browse files Browse the repository at this point in the history
  • Loading branch information
firewave committed Dec 8, 2023
1 parent 1af83ad commit 7452e68
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 0 deletions.
17 changes: 17 additions & 0 deletions cli/cmdlineparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[])
assert(!(!pathnamesRef.empty() && !fileSettingsRef.empty()));

if (!fileSettingsRef.empty()) {
// TODO: handle ignored?

// TODO: de-duplicate

std::list<FileSettings> fileSettings;
if (!mSettings.fileFilters.empty()) {
// filter only for the selected filenames from all project files
Expand Down Expand Up @@ -244,6 +248,19 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[])
}
}

// de-duplicate files
{
auto it = filesResolved.begin();
while (it != filesResolved.end()) {
const std::string& name = it->first;
// TODO: log if duplicated files were dropped
filesResolved.erase(std::remove_if(std::next(it), filesResolved.end(), [&](const std::pair<std::string, std::size_t>& entry) {
return entry.first == name;
}), filesResolved.end());
++it;
}
}

std::list<std::pair<std::string, std::size_t>> files;
if (!mSettings.fileFilters.empty()) {
std::copy_if(filesResolved.cbegin(), filesResolved.cend(), std::inserter(files, files.end()), [&](const decltype(filesResolved)::value_type& entry) {
Expand Down
72 changes: 72 additions & 0 deletions test/cli/test-more-projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,3 +432,75 @@ def test_project_file_order(tmpdir):
'4/4 files checked 0% done'
]
assert stderr == ''


def test_project_file_duplicate(tmpdir):
test_file_a = os.path.join(tmpdir, 'a.c')
with open(test_file_a, 'wt'):
pass

project_file = os.path.join(tmpdir, 'test.cppcheck')
with open(project_file, 'wt') as f:
f.write(
"""<?xml version="1.0" encoding="UTF-8"?>
<project>
<paths>
<dir name="{}"/>
<dir name="{}"/>
<dir name="{}"/>
</paths>
</project>""".format(test_file_a, test_file_a, tmpdir))

args = ['--project={}'.format(project_file)]

exitcode, stdout, stderr = cppcheck(args)
assert exitcode == 0
lines = stdout.splitlines()
assert lines == [
'Checking {} ...'.format(test_file_a)
]
assert stderr == ''


def test_project_file_duplicate_2(tmpdir):
test_file_a = os.path.join(tmpdir, 'a.c')
with open(test_file_a, 'wt'):
pass
test_file_b = os.path.join(tmpdir, 'b.c')
with open(test_file_b, 'wt'):
pass
test_file_c = os.path.join(tmpdir, 'c.c')
with open(test_file_c, 'wt'):
pass

project_file = os.path.join(tmpdir, 'test.cppcheck')
with open(project_file, 'wt') as f:
f.write(
"""<?xml version="1.0" encoding="UTF-8"?>
<project>
<paths>
<dir name="{}"/>
<dir name="{}"/>
<dir name="{}"/>
<dir name="{}"/>
<dir name="{}"/>
<dir name="{}"/>
<dir name="{}"/>
<dir name="{}"/>
</paths>
</project>""".format(test_file_c, test_file_a, test_file_b, tmpdir, test_file_b, test_file_c, test_file_a, tmpdir))

args = ['--project={}'.format(project_file)]

exitcode, stdout, stderr = cppcheck(args)
assert exitcode == 0
lines = stdout.splitlines()
assert lines == [
'Checking {} ...'.format(test_file_c),
'1/3 files checked 0% done',
'Checking {} ...'.format(test_file_a),
'2/3 files checked 0% done',
'Checking {} ...'.format(test_file_b),
'3/3 files checked 0% done'
]
assert stderr == ''
43 changes: 43 additions & 0 deletions test/cli/test-other.py
Original file line number Diff line number Diff line change
Expand Up @@ -782,3 +782,46 @@ def test_valueflow_debug(tmpdir):
0 always 0
'''.format(test_file_cpp, test_file_h_2, test_file_h, test_file_cpp, test_file_h_2, test_file_h, test_file_cpp)
assert stderr == ''


def test_file_duplicate(tmpdir):
test_file_a = os.path.join(tmpdir, 'a.c')
with open(test_file_a, 'wt'):
pass

args = [test_file_a, test_file_a, str(tmpdir)]

exitcode, stdout, stderr = cppcheck(args)
assert exitcode == 0
lines = stdout.splitlines()
assert lines == [
'Checking {} ...'.format(test_file_a)
]
assert stderr == ''


def test_file_duplicate_2(tmpdir):
test_file_a = os.path.join(tmpdir, 'a.c')
with open(test_file_a, 'wt'):
pass
test_file_b = os.path.join(tmpdir, 'b.c')
with open(test_file_b, 'wt'):
pass
test_file_c = os.path.join(tmpdir, 'c.c')
with open(test_file_c, 'wt'):
pass

args = [test_file_c, test_file_a, test_file_b, str(tmpdir), test_file_b, test_file_c, test_file_a, str(tmpdir)]

exitcode, stdout, stderr = cppcheck(args)
assert exitcode == 0
lines = stdout.splitlines()
assert lines == [
'Checking {} ...'.format(test_file_c),
'1/3 files checked 0% done',
'Checking {} ...'.format(test_file_a),
'2/3 files checked 0% done',
'Checking {} ...'.format(test_file_b),
'3/3 files checked 0% done'
]
assert stderr == ''

0 comments on commit 7452e68

Please sign in to comment.