Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 56 additions & 57 deletions cli/cmdlineparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,62 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[])
// TODO: error out on all missing given files/paths
CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const argv[])
{
if (argc <= 1) {
printHelp();
return Result::Exit;
}

// check for exclusive options
for (int i = 1; i < argc; i++) {
// documentation..
if (std::strcmp(argv[i], "--doc") == 0) {
std::ostringstream doc;
// Get documentation..
for (const Check * it : Check::instances()) {
const std::string& name(it->name());
const std::string info(it->classInfo());
if (!name.empty() && !info.empty())
doc << "## " << name << " ##\n"
<< info << "\n";
}

mLogger.printRaw(doc.str());
return Result::Exit;
}

// print all possible error messages..
if (std::strcmp(argv[i], "--errorlist") == 0) {
mSettings.loadCppcheckCfg();
{
XMLErrorMessagesLogger xmlLogger;
std::cout << ErrorMessage::getXMLHeader(mSettings.cppcheckCfgProductName);
CppCheck::getErrorMessages(xmlLogger);
std::cout << ErrorMessage::getXMLFooter() << std::endl;
}
return Result::Exit;
}

// Print help
if (std::strcmp(argv[i], "-h") == 0 || std::strcmp(argv[i], "--help") == 0) {
printHelp();
return Result::Exit;
}

if (std::strcmp(argv[i], "--version") == 0) {
mSettings.loadCppcheckCfg();
if (!mSettings.cppcheckCfgProductName.empty()) {
mLogger.printRaw(mSettings.cppcheckCfgProductName);
} else {
const char * const extraVersion = CppCheck::extraVersion();
if (*extraVersion != '\0')
mLogger.printRaw(std::string("Cppcheck ") + CppCheck::version() + " ("+ extraVersion + ')');
else
mLogger.printRaw(std::string("Cppcheck ") + CppCheck::version());
}
return Result::Exit;
}
}

bool def = false;
bool maxconfigs = false;

Expand Down Expand Up @@ -466,23 +522,6 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
}
}

// documentation..
else if (std::strcmp(argv[i], "--doc") == 0) {
// TODO: make an exclusive option
std::ostringstream doc;
// Get documentation..
for (const Check * it : Check::instances()) {
const std::string& name(it->name());
const std::string info(it->classInfo());
if (!name.empty() && !info.empty())
doc << "## " << name << " ##\n"
<< info << "\n";
}

mLogger.printRaw(doc.str());
return Result::Exit;
}

// dump cppcheck data
else if (std::strcmp(argv[i], "--dump") == 0)
mSettings.dump = true;
Expand All @@ -506,19 +545,6 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
}
}

// print all possible error messages..
else if (std::strcmp(argv[i], "--errorlist") == 0) {
// TODO: make this an exclusive option
mSettings.loadCppcheckCfg();
{
XMLErrorMessagesLogger xmlLogger;
std::cout << ErrorMessage::getXMLHeader(mSettings.cppcheckCfgProductName);
CppCheck::getErrorMessages(xmlLogger);
std::cout << ErrorMessage::getXMLFooter() << std::endl;
}
return Result::Exit;
}

// --error-exitcode=1
else if (std::strncmp(argv[i], "--error-exitcode=", 17) == 0) {
if (!parseNumberArg(argv[i], 17, mSettings.exitCode))
Expand Down Expand Up @@ -592,13 +618,6 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
else if (std::strcmp(argv[i], "--funsigned-char") == 0)
mSettings.platform.defaultSign = 'u';

// Print help
else if (std::strcmp(argv[i], "-h") == 0 || std::strcmp(argv[i], "--help") == 0) {
// TODO: make this an exclusive option
printHelp();
return Result::Exit;
}

// Ignored paths
else if (std::strncmp(argv[i], "-i", 2) == 0) {
std::string path;
Expand Down Expand Up @@ -1150,21 +1169,6 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
else if (std::strcmp(argv[i], "-v") == 0 || std::strcmp(argv[i], "--verbose") == 0)
mSettings.verbose = true;

else if (std::strcmp(argv[i], "--version") == 0) {
// TODO: make this an exclusive parameter
mSettings.loadCppcheckCfg();
if (!mSettings.cppcheckCfgProductName.empty()) {
mLogger.printRaw(mSettings.cppcheckCfgProductName);
} else {
const char * const extraVersion = CppCheck::extraVersion();
if (*extraVersion != '\0')
mLogger.printRaw(std::string("Cppcheck ") + CppCheck::version() + " ("+ extraVersion + ')');
else
mLogger.printRaw(std::string("Cppcheck ") + CppCheck::version());
}
return Result::Exit;
}

// Write results in results.xml
else if (std::strcmp(argv[i], "--xml") == 0)
mSettings.xml = true;
Expand Down Expand Up @@ -1226,11 +1230,6 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
mLogger.printMessage("unusedFunction check can't be used with '-j' option. Disabling unusedFunction check.");
}

if (argc <= 1) {
printHelp();
return Result::Exit;
}

if (!mPathNames.empty() && project.projectType != ImportProject::Type::NONE) {
mLogger.printError("--project cannot be used in conjunction with source files.");
return Result::Fail;
Expand Down
48 changes: 47 additions & 1 deletion test/testcmdlineparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,12 @@ class TestCmdlineParser : public TestFixture {
void run() override {
TEST_CASE(nooptions);
TEST_CASE(helpshort);
TEST_CASE(helpshortExclusive);
TEST_CASE(helplong);
TEST_CASE(helplongExclusive);
TEST_CASE(version);
TEST_CASE(versionWithCfg);
TEST_CASE(versionExclusive);
TEST_CASE(onefile);
TEST_CASE(onepath);
TEST_CASE(optionwithoutfile);
Expand Down Expand Up @@ -255,6 +258,7 @@ class TestCmdlineParser : public TestFixture {
TEST_CASE(xmlverunknown);
TEST_CASE(xmlverinvalid);
TEST_CASE(doc);
TEST_CASE(docExclusive);
TEST_CASE(showtimeFile);
TEST_CASE(showtimeFileTotal);
TEST_CASE(showtimeTop5);
Expand All @@ -264,6 +268,7 @@ class TestCmdlineParser : public TestFixture {
TEST_CASE(showtimeEmpty);
TEST_CASE(showtimeInvalid);
TEST_CASE(errorlist);
TEST_CASE(errorlistExclusive);
TEST_CASE(ignorepathsnopath);
#if defined(USE_WINDOWS_SEH) || defined(USE_UNIX_SIGNAL_HANDLING)
TEST_CASE(exceptionhandling);
Expand Down Expand Up @@ -373,6 +378,14 @@ class TestCmdlineParser : public TestFixture {
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
}

void helpshortExclusive() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--library=missing", "-h"};
ASSERT_EQUALS(CmdLineParser::Result::Exit, parser->parseFromArgs(3, argv));
ASSERT(startsWith(logger->str(), "Cppcheck - A tool for static C/C++ code analysis"));
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
}

void helplong() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--help"};
Expand All @@ -381,6 +394,14 @@ class TestCmdlineParser : public TestFixture {
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
}

void helplongExclusive() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--library=missing", "--help"};
ASSERT_EQUALS(CmdLineParser::Result::Exit, parser->parseFromArgs(3, argv));
ASSERT(startsWith(logger->str(), "Cppcheck - A tool for static C/C++ code analysis"));
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
}

void version() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--version"};
Expand All @@ -402,7 +423,15 @@ class TestCmdlineParser : public TestFixture {
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
}

// TODO: test extraVersion
// TODO: test --version with extraVersion

void versionExclusive() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--library=missing", "--version"};
ASSERT_EQUALS(CmdLineParser::Result::Exit, parser->parseFromArgs(3, argv));
ASSERT_EQUALS("Cppcheck 2.13 dev\n", logger->str());
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
}

void onefile() {
REDIRECT;
Expand Down Expand Up @@ -1577,6 +1606,14 @@ class TestCmdlineParser : public TestFixture {
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
}

void docExclusive() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--library=missing", "--doc"};
ASSERT_EQUALS(CmdLineParser::Result::Exit, parser->parseFromArgs(3, argv));
ASSERT(startsWith(logger->str(), "## "));
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
}

void showtimeSummary() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--showtime=summary", "file.cpp"};
Expand Down Expand Up @@ -1659,6 +1696,15 @@ class TestCmdlineParser : public TestFixture {

// TODO: test --errorlist with product name

void errorlistExclusive() {
REDIRECT;
const char * const argv[] = {"cppcheck", "--library=missing", "--errorlist"};
ASSERT_EQUALS(CmdLineParser::Result::Exit, parser->parseFromArgs(3, argv));
ASSERT_EQUALS("", logger->str()); // empty since it is logged via ErrorLogger
ASSERT(startsWith(GET_REDIRECT_OUTPUT, "<?xml"));
ASSERT(endsWith(GET_REDIRECT_OUTPUT, "</results>\n"));
}

void ignorepathsnopath() {
REDIRECT;
const char * const argv[] = {"cppcheck", "-i"};
Expand Down