CmdLineParser: made some options exclusive (#5704)

This commit is contained in:
Oliver Stöneberg 2023-12-01 14:19:47 +01:00 committed by GitHub
parent 7e8ea5bcf9
commit 237bed8a91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 103 additions and 58 deletions

View File

@ -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;
@ -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;
@ -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))
@ -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;
@ -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;
@ -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;

View File

@ -119,9 +119,12 @@ private:
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);
@ -255,6 +258,7 @@ private:
TEST_CASE(xmlverunknown);
TEST_CASE(xmlverinvalid);
TEST_CASE(doc);
TEST_CASE(docExclusive);
TEST_CASE(showtimeFile);
TEST_CASE(showtimeFileTotal);
TEST_CASE(showtimeTop5);
@ -264,6 +268,7 @@ private:
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);
@ -373,6 +378,14 @@ private:
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"};
@ -381,6 +394,14 @@ private:
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"};
@ -402,7 +423,15 @@ private:
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;
@ -1577,6 +1606,14 @@ private:
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"};
@ -1659,6 +1696,15 @@ private:
// 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"};