Skip to content

Commit

Permalink
Fix #12601 (cli: Add --file-filter=- option that reads from stdin) (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
danmar authored Apr 9, 2024
1 parent e45744d commit fe45744
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 10 deletions.
13 changes: 11 additions & 2 deletions cli/cmdlineparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -667,8 +667,17 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
}

// use a file filter
else if (std::strncmp(argv[i], "--file-filter=", 14) == 0)
mSettings.fileFilters.emplace_back(argv[i] + 14);
else if (std::strncmp(argv[i], "--file-filter=", 14) == 0) {
const char *filter = argv[i] + 14;
if (std::strcmp(filter, "-") == 0) {
if (!addFilesToList(filter, mSettings.fileFilters)) {
mLogger.printError("Failed: --file-filter=-");
return Result::Fail;
}
} else {
mSettings.fileFilters.emplace_back(filter);
}
}

// file list specified
else if (std::strncmp(argv[i], "--file-list=", 12) == 0) {
Expand Down
15 changes: 15 additions & 0 deletions test/redirect.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,19 @@ class SuppressOutput {

#define SUPPRESS SuppressOutput supprout


class RedirectInput {
public:
explicit RedirectInput(const std::string &input) : _in(input) {
_oldCin = std::cin.rdbuf(); // back up cin's streambuf
std::cin.rdbuf(_in.rdbuf()); // assign streambuf to cin
}
~RedirectInput() noexcept {
std::cin.rdbuf(_oldCin); // restore cin's original streambuf
}
private:
std::istringstream _in;
std::streambuf* _oldCin;
};

#endif
32 changes: 24 additions & 8 deletions test/testcmdlineparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,10 @@ class TestCmdlineParser : public TestFixture {
TEST_CASE(exitcodeSuppressionsOld);
TEST_CASE(exitcodeSuppressions);
TEST_CASE(exitcodeSuppressionsNoFile);
TEST_CASE(fileFilterStdin);
TEST_CASE(fileList);
TEST_CASE(fileListNoFile);
// TEST_CASE(fileListStdin); // Disabled since hangs the test run
TEST_CASE(fileListStdin);
TEST_CASE(fileListInvalid);
TEST_CASE(inlineSuppr);
TEST_CASE(jobs);
Expand Down Expand Up @@ -1083,6 +1084,17 @@ class TestCmdlineParser : public TestFixture {
ASSERT_EQUALS("cppcheck: error: unrecognized command line option: \"--exitcode-suppressions\".\n", logger->str());
}

void fileFilterStdin() {
REDIRECT;
RedirectInput input("file1.c\nfile2.cpp\n");
const char * const argv[] = {"cppcheck", "--file-filter=-"};
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parser->parseFromArgs(2, argv));
ASSERT_EQUALS("cppcheck: error: no C or C++ source files found.\n", logger->str());
ASSERT_EQUALS(2U, settings->fileFilters.size());
ASSERT_EQUALS("file1.c", settings->fileFilters[0]);
ASSERT_EQUALS("file2.cpp", settings->fileFilters[1]);
}

void fileList() {
REDIRECT;
ScopedFile file("files.txt",
Expand All @@ -1104,13 +1116,17 @@ class TestCmdlineParser : public TestFixture {
ASSERT_EQUALS("cppcheck: error: couldn't open the file: \"files.txt\".\n", logger->str());
}

/* void fileListStdin() {
// TODO: Give it some stdin to read from, fails because the list of
// files in stdin (_pathnames) is empty
REDIRECT;
const char * const argv[] = {"cppcheck", "--file-list=-", "file.cpp"};
TODO_ASSERT_EQUALS(true, false, parser->parseFromArgs(3, argv));
} */
void fileListStdin() {
REDIRECT;
RedirectInput input("file1.c\nfile2.cpp\n");
const char * const argv[] = {"cppcheck", "--file-list=-", "file.cpp"};
ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parser->parseFromArgs(3, argv));
ASSERT_EQUALS(3, parser->getPathNames().size());
auto it = parser->getPathNames().cbegin();
ASSERT_EQUALS("file1.c", *it++);
ASSERT_EQUALS("file2.cpp", *it++);
ASSERT_EQUALS("file.cpp", *it);
}

void fileListInvalid() {
REDIRECT;
Expand Down

0 comments on commit fe45744

Please sign in to comment.