Skip to content

Commit 7452e68

Browse files
authored
fixed #12221 - de-duplicate input source files (regression) (#5740)
1 parent 1af83ad commit 7452e68

3 files changed

Lines changed: 132 additions & 0 deletions

File tree

cli/cmdlineparser.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,10 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[])
198198
assert(!(!pathnamesRef.empty() && !fileSettingsRef.empty()));
199199

200200
if (!fileSettingsRef.empty()) {
201+
// TODO: handle ignored?
202+
203+
// TODO: de-duplicate
204+
201205
std::list<FileSettings> fileSettings;
202206
if (!mSettings.fileFilters.empty()) {
203207
// filter only for the selected filenames from all project files
@@ -244,6 +248,19 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[])
244248
}
245249
}
246250

251+
// de-duplicate files
252+
{
253+
auto it = filesResolved.begin();
254+
while (it != filesResolved.end()) {
255+
const std::string& name = it->first;
256+
// TODO: log if duplicated files were dropped
257+
filesResolved.erase(std::remove_if(std::next(it), filesResolved.end(), [&](const std::pair<std::string, std::size_t>& entry) {
258+
return entry.first == name;
259+
}), filesResolved.end());
260+
++it;
261+
}
262+
}
263+
247264
std::list<std::pair<std::string, std::size_t>> files;
248265
if (!mSettings.fileFilters.empty()) {
249266
std::copy_if(filesResolved.cbegin(), filesResolved.cend(), std::inserter(files, files.end()), [&](const decltype(filesResolved)::value_type& entry) {

test/cli/test-more-projects.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,3 +432,75 @@ def test_project_file_order(tmpdir):
432432
'4/4 files checked 0% done'
433433
]
434434
assert stderr == ''
435+
436+
437+
def test_project_file_duplicate(tmpdir):
438+
test_file_a = os.path.join(tmpdir, 'a.c')
439+
with open(test_file_a, 'wt'):
440+
pass
441+
442+
project_file = os.path.join(tmpdir, 'test.cppcheck')
443+
with open(project_file, 'wt') as f:
444+
f.write(
445+
"""<?xml version="1.0" encoding="UTF-8"?>
446+
<project>
447+
<paths>
448+
<dir name="{}"/>
449+
<dir name="{}"/>
450+
<dir name="{}"/>
451+
</paths>
452+
</project>""".format(test_file_a, test_file_a, tmpdir))
453+
454+
args = ['--project={}'.format(project_file)]
455+
456+
exitcode, stdout, stderr = cppcheck(args)
457+
assert exitcode == 0
458+
lines = stdout.splitlines()
459+
assert lines == [
460+
'Checking {} ...'.format(test_file_a)
461+
]
462+
assert stderr == ''
463+
464+
465+
def test_project_file_duplicate_2(tmpdir):
466+
test_file_a = os.path.join(tmpdir, 'a.c')
467+
with open(test_file_a, 'wt'):
468+
pass
469+
test_file_b = os.path.join(tmpdir, 'b.c')
470+
with open(test_file_b, 'wt'):
471+
pass
472+
test_file_c = os.path.join(tmpdir, 'c.c')
473+
with open(test_file_c, 'wt'):
474+
pass
475+
476+
project_file = os.path.join(tmpdir, 'test.cppcheck')
477+
with open(project_file, 'wt') as f:
478+
f.write(
479+
"""<?xml version="1.0" encoding="UTF-8"?>
480+
<project>
481+
<paths>
482+
<dir name="{}"/>
483+
<dir name="{}"/>
484+
<dir name="{}"/>
485+
<dir name="{}"/>
486+
<dir name="{}"/>
487+
<dir name="{}"/>
488+
<dir name="{}"/>
489+
<dir name="{}"/>
490+
</paths>
491+
</project>""".format(test_file_c, test_file_a, test_file_b, tmpdir, test_file_b, test_file_c, test_file_a, tmpdir))
492+
493+
args = ['--project={}'.format(project_file)]
494+
495+
exitcode, stdout, stderr = cppcheck(args)
496+
assert exitcode == 0
497+
lines = stdout.splitlines()
498+
assert lines == [
499+
'Checking {} ...'.format(test_file_c),
500+
'1/3 files checked 0% done',
501+
'Checking {} ...'.format(test_file_a),
502+
'2/3 files checked 0% done',
503+
'Checking {} ...'.format(test_file_b),
504+
'3/3 files checked 0% done'
505+
]
506+
assert stderr == ''

test/cli/test-other.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,3 +782,46 @@ def test_valueflow_debug(tmpdir):
782782
0 always 0
783783
'''.format(test_file_cpp, test_file_h_2, test_file_h, test_file_cpp, test_file_h_2, test_file_h, test_file_cpp)
784784
assert stderr == ''
785+
786+
787+
def test_file_duplicate(tmpdir):
788+
test_file_a = os.path.join(tmpdir, 'a.c')
789+
with open(test_file_a, 'wt'):
790+
pass
791+
792+
args = [test_file_a, test_file_a, str(tmpdir)]
793+
794+
exitcode, stdout, stderr = cppcheck(args)
795+
assert exitcode == 0
796+
lines = stdout.splitlines()
797+
assert lines == [
798+
'Checking {} ...'.format(test_file_a)
799+
]
800+
assert stderr == ''
801+
802+
803+
def test_file_duplicate_2(tmpdir):
804+
test_file_a = os.path.join(tmpdir, 'a.c')
805+
with open(test_file_a, 'wt'):
806+
pass
807+
test_file_b = os.path.join(tmpdir, 'b.c')
808+
with open(test_file_b, 'wt'):
809+
pass
810+
test_file_c = os.path.join(tmpdir, 'c.c')
811+
with open(test_file_c, 'wt'):
812+
pass
813+
814+
args = [test_file_c, test_file_a, test_file_b, str(tmpdir), test_file_b, test_file_c, test_file_a, str(tmpdir)]
815+
816+
exitcode, stdout, stderr = cppcheck(args)
817+
assert exitcode == 0
818+
lines = stdout.splitlines()
819+
assert lines == [
820+
'Checking {} ...'.format(test_file_c),
821+
'1/3 files checked 0% done',
822+
'Checking {} ...'.format(test_file_a),
823+
'2/3 files checked 0% done',
824+
'Checking {} ...'.format(test_file_b),
825+
'3/3 files checked 0% done'
826+
]
827+
assert stderr == ''

0 commit comments

Comments
 (0)