Skip to content

Commit fe45744

Browse files
authored
Fix #12601 (cli: Add --file-filter=- option that reads from stdin) (danmar#6258)
1 parent e45744d commit fe45744

File tree

3 files changed

+50
-10
lines changed

3 files changed

+50
-10
lines changed

cli/cmdlineparser.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -667,8 +667,17 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
667667
}
668668

669669
// use a file filter
670-
else if (std::strncmp(argv[i], "--file-filter=", 14) == 0)
671-
mSettings.fileFilters.emplace_back(argv[i] + 14);
670+
else if (std::strncmp(argv[i], "--file-filter=", 14) == 0) {
671+
const char *filter = argv[i] + 14;
672+
if (std::strcmp(filter, "-") == 0) {
673+
if (!addFilesToList(filter, mSettings.fileFilters)) {
674+
mLogger.printError("Failed: --file-filter=-");
675+
return Result::Fail;
676+
}
677+
} else {
678+
mSettings.fileFilters.emplace_back(filter);
679+
}
680+
}
672681

673682
// file list specified
674683
else if (std::strncmp(argv[i], "--file-list=", 12) == 0) {

test/redirect.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,19 @@ class SuppressOutput {
114114

115115
#define SUPPRESS SuppressOutput supprout
116116

117+
118+
class RedirectInput {
119+
public:
120+
explicit RedirectInput(const std::string &input) : _in(input) {
121+
_oldCin = std::cin.rdbuf(); // back up cin's streambuf
122+
std::cin.rdbuf(_in.rdbuf()); // assign streambuf to cin
123+
}
124+
~RedirectInput() noexcept {
125+
std::cin.rdbuf(_oldCin); // restore cin's original streambuf
126+
}
127+
private:
128+
std::istringstream _in;
129+
std::streambuf* _oldCin;
130+
};
131+
117132
#endif

test/testcmdlineparser.cpp

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,10 @@ class TestCmdlineParser : public TestFixture {
192192
TEST_CASE(exitcodeSuppressionsOld);
193193
TEST_CASE(exitcodeSuppressions);
194194
TEST_CASE(exitcodeSuppressionsNoFile);
195+
TEST_CASE(fileFilterStdin);
195196
TEST_CASE(fileList);
196197
TEST_CASE(fileListNoFile);
197-
// TEST_CASE(fileListStdin); // Disabled since hangs the test run
198+
TEST_CASE(fileListStdin);
198199
TEST_CASE(fileListInvalid);
199200
TEST_CASE(inlineSuppr);
200201
TEST_CASE(jobs);
@@ -1083,6 +1084,17 @@ class TestCmdlineParser : public TestFixture {
10831084
ASSERT_EQUALS("cppcheck: error: unrecognized command line option: \"--exitcode-suppressions\".\n", logger->str());
10841085
}
10851086

1087+
void fileFilterStdin() {
1088+
REDIRECT;
1089+
RedirectInput input("file1.c\nfile2.cpp\n");
1090+
const char * const argv[] = {"cppcheck", "--file-filter=-"};
1091+
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parser->parseFromArgs(2, argv));
1092+
ASSERT_EQUALS("cppcheck: error: no C or C++ source files found.\n", logger->str());
1093+
ASSERT_EQUALS(2U, settings->fileFilters.size());
1094+
ASSERT_EQUALS("file1.c", settings->fileFilters[0]);
1095+
ASSERT_EQUALS("file2.cpp", settings->fileFilters[1]);
1096+
}
1097+
10861098
void fileList() {
10871099
REDIRECT;
10881100
ScopedFile file("files.txt",
@@ -1104,13 +1116,17 @@ class TestCmdlineParser : public TestFixture {
11041116
ASSERT_EQUALS("cppcheck: error: couldn't open the file: \"files.txt\".\n", logger->str());
11051117
}
11061118

1107-
/* void fileListStdin() {
1108-
// TODO: Give it some stdin to read from, fails because the list of
1109-
// files in stdin (_pathnames) is empty
1110-
REDIRECT;
1111-
const char * const argv[] = {"cppcheck", "--file-list=-", "file.cpp"};
1112-
TODO_ASSERT_EQUALS(true, false, parser->parseFromArgs(3, argv));
1113-
} */
1119+
void fileListStdin() {
1120+
REDIRECT;
1121+
RedirectInput input("file1.c\nfile2.cpp\n");
1122+
const char * const argv[] = {"cppcheck", "--file-list=-", "file.cpp"};
1123+
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv));
1124+
ASSERT_EQUALS(3, parser->getPathNames().size());
1125+
auto it = parser->getPathNames().cbegin();
1126+
ASSERT_EQUALS("file1.c", *it++);
1127+
ASSERT_EQUALS("file2.cpp", *it++);
1128+
ASSERT_EQUALS("file.cpp", *it);
1129+
}
11141130

11151131
void fileListInvalid() {
11161132
REDIRECT;

0 commit comments

Comments
 (0)