Skip to content

Commit 237bed8

Browse files
authored
CmdLineParser: made some options exclusive (#5704)
1 parent 7e8ea5b commit 237bed8

2 files changed

Lines changed: 103 additions & 58 deletions

File tree

cli/cmdlineparser.cpp

Lines changed: 56 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,62 @@ bool CmdLineParser::fillSettingsFromArgs(int argc, const char* const argv[])
282282
// TODO: error out on all missing given files/paths
283283
CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const argv[])
284284
{
285+
if (argc <= 1) {
286+
printHelp();
287+
return Result::Exit;
288+
}
289+
290+
// check for exclusive options
291+
for (int i = 1; i < argc; i++) {
292+
// documentation..
293+
if (std::strcmp(argv[i], "--doc") == 0) {
294+
std::ostringstream doc;
295+
// Get documentation..
296+
for (const Check * it : Check::instances()) {
297+
const std::string& name(it->name());
298+
const std::string info(it->classInfo());
299+
if (!name.empty() && !info.empty())
300+
doc << "## " << name << " ##\n"
301+
<< info << "\n";
302+
}
303+
304+
mLogger.printRaw(doc.str());
305+
return Result::Exit;
306+
}
307+
308+
// print all possible error messages..
309+
if (std::strcmp(argv[i], "--errorlist") == 0) {
310+
mSettings.loadCppcheckCfg();
311+
{
312+
XMLErrorMessagesLogger xmlLogger;
313+
std::cout << ErrorMessage::getXMLHeader(mSettings.cppcheckCfgProductName);
314+
CppCheck::getErrorMessages(xmlLogger);
315+
std::cout << ErrorMessage::getXMLFooter() << std::endl;
316+
}
317+
return Result::Exit;
318+
}
319+
320+
// Print help
321+
if (std::strcmp(argv[i], "-h") == 0 || std::strcmp(argv[i], "--help") == 0) {
322+
printHelp();
323+
return Result::Exit;
324+
}
325+
326+
if (std::strcmp(argv[i], "--version") == 0) {
327+
mSettings.loadCppcheckCfg();
328+
if (!mSettings.cppcheckCfgProductName.empty()) {
329+
mLogger.printRaw(mSettings.cppcheckCfgProductName);
330+
} else {
331+
const char * const extraVersion = CppCheck::extraVersion();
332+
if (*extraVersion != '\0')
333+
mLogger.printRaw(std::string("Cppcheck ") + CppCheck::version() + " ("+ extraVersion + ')');
334+
else
335+
mLogger.printRaw(std::string("Cppcheck ") + CppCheck::version());
336+
}
337+
return Result::Exit;
338+
}
339+
}
340+
285341
bool def = false;
286342
bool maxconfigs = false;
287343

@@ -466,23 +522,6 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
466522
}
467523
}
468524

469-
// documentation..
470-
else if (std::strcmp(argv[i], "--doc") == 0) {
471-
// TODO: make an exclusive option
472-
std::ostringstream doc;
473-
// Get documentation..
474-
for (const Check * it : Check::instances()) {
475-
const std::string& name(it->name());
476-
const std::string info(it->classInfo());
477-
if (!name.empty() && !info.empty())
478-
doc << "## " << name << " ##\n"
479-
<< info << "\n";
480-
}
481-
482-
mLogger.printRaw(doc.str());
483-
return Result::Exit;
484-
}
485-
486525
// dump cppcheck data
487526
else if (std::strcmp(argv[i], "--dump") == 0)
488527
mSettings.dump = true;
@@ -506,19 +545,6 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
506545
}
507546
}
508547

509-
// print all possible error messages..
510-
else if (std::strcmp(argv[i], "--errorlist") == 0) {
511-
// TODO: make this an exclusive option
512-
mSettings.loadCppcheckCfg();
513-
{
514-
XMLErrorMessagesLogger xmlLogger;
515-
std::cout << ErrorMessage::getXMLHeader(mSettings.cppcheckCfgProductName);
516-
CppCheck::getErrorMessages(xmlLogger);
517-
std::cout << ErrorMessage::getXMLFooter() << std::endl;
518-
}
519-
return Result::Exit;
520-
}
521-
522548
// --error-exitcode=1
523549
else if (std::strncmp(argv[i], "--error-exitcode=", 17) == 0) {
524550
if (!parseNumberArg(argv[i], 17, mSettings.exitCode))
@@ -592,13 +618,6 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
592618
else if (std::strcmp(argv[i], "--funsigned-char") == 0)
593619
mSettings.platform.defaultSign = 'u';
594620

595-
// Print help
596-
else if (std::strcmp(argv[i], "-h") == 0 || std::strcmp(argv[i], "--help") == 0) {
597-
// TODO: make this an exclusive option
598-
printHelp();
599-
return Result::Exit;
600-
}
601-
602621
// Ignored paths
603622
else if (std::strncmp(argv[i], "-i", 2) == 0) {
604623
std::string path;
@@ -1150,21 +1169,6 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
11501169
else if (std::strcmp(argv[i], "-v") == 0 || std::strcmp(argv[i], "--verbose") == 0)
11511170
mSettings.verbose = true;
11521171

1153-
else if (std::strcmp(argv[i], "--version") == 0) {
1154-
// TODO: make this an exclusive parameter
1155-
mSettings.loadCppcheckCfg();
1156-
if (!mSettings.cppcheckCfgProductName.empty()) {
1157-
mLogger.printRaw(mSettings.cppcheckCfgProductName);
1158-
} else {
1159-
const char * const extraVersion = CppCheck::extraVersion();
1160-
if (*extraVersion != '\0')
1161-
mLogger.printRaw(std::string("Cppcheck ") + CppCheck::version() + " ("+ extraVersion + ')');
1162-
else
1163-
mLogger.printRaw(std::string("Cppcheck ") + CppCheck::version());
1164-
}
1165-
return Result::Exit;
1166-
}
1167-
11681172
// Write results in results.xml
11691173
else if (std::strcmp(argv[i], "--xml") == 0)
11701174
mSettings.xml = true;
@@ -1226,11 +1230,6 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
12261230
mLogger.printMessage("unusedFunction check can't be used with '-j' option. Disabling unusedFunction check.");
12271231
}
12281232

1229-
if (argc <= 1) {
1230-
printHelp();
1231-
return Result::Exit;
1232-
}
1233-
12341233
if (!mPathNames.empty() && project.projectType != ImportProject::Type::NONE) {
12351234
mLogger.printError("--project cannot be used in conjunction with source files.");
12361235
return Result::Fail;

test/testcmdlineparser.cpp

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,12 @@ class TestCmdlineParser : public TestFixture {
119119
void run() override {
120120
TEST_CASE(nooptions);
121121
TEST_CASE(helpshort);
122+
TEST_CASE(helpshortExclusive);
122123
TEST_CASE(helplong);
124+
TEST_CASE(helplongExclusive);
123125
TEST_CASE(version);
124126
TEST_CASE(versionWithCfg);
127+
TEST_CASE(versionExclusive);
125128
TEST_CASE(onefile);
126129
TEST_CASE(onepath);
127130
TEST_CASE(optionwithoutfile);
@@ -255,6 +258,7 @@ class TestCmdlineParser : public TestFixture {
255258
TEST_CASE(xmlverunknown);
256259
TEST_CASE(xmlverinvalid);
257260
TEST_CASE(doc);
261+
TEST_CASE(docExclusive);
258262
TEST_CASE(showtimeFile);
259263
TEST_CASE(showtimeFileTotal);
260264
TEST_CASE(showtimeTop5);
@@ -264,6 +268,7 @@ class TestCmdlineParser : public TestFixture {
264268
TEST_CASE(showtimeEmpty);
265269
TEST_CASE(showtimeInvalid);
266270
TEST_CASE(errorlist);
271+
TEST_CASE(errorlistExclusive);
267272
TEST_CASE(ignorepathsnopath);
268273
#if defined(USE_WINDOWS_SEH) || defined(USE_UNIX_SIGNAL_HANDLING)
269274
TEST_CASE(exceptionhandling);
@@ -373,6 +378,14 @@ class TestCmdlineParser : public TestFixture {
373378
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
374379
}
375380

381+
void helpshortExclusive() {
382+
REDIRECT;
383+
const char * const argv[] = {"cppcheck", "--library=missing", "-h"};
384+
ASSERT_EQUALS(CmdLineParser::Result::Exit, parser->parseFromArgs(3, argv));
385+
ASSERT(startsWith(logger->str(), "Cppcheck - A tool for static C/C++ code analysis"));
386+
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
387+
}
388+
376389
void helplong() {
377390
REDIRECT;
378391
const char * const argv[] = {"cppcheck", "--help"};
@@ -381,6 +394,14 @@ class TestCmdlineParser : public TestFixture {
381394
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
382395
}
383396

397+
void helplongExclusive() {
398+
REDIRECT;
399+
const char * const argv[] = {"cppcheck", "--library=missing", "--help"};
400+
ASSERT_EQUALS(CmdLineParser::Result::Exit, parser->parseFromArgs(3, argv));
401+
ASSERT(startsWith(logger->str(), "Cppcheck - A tool for static C/C++ code analysis"));
402+
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
403+
}
404+
384405
void version() {
385406
REDIRECT;
386407
const char * const argv[] = {"cppcheck", "--version"};
@@ -402,7 +423,15 @@ class TestCmdlineParser : public TestFixture {
402423
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
403424
}
404425

405-
// TODO: test extraVersion
426+
// TODO: test --version with extraVersion
427+
428+
void versionExclusive() {
429+
REDIRECT;
430+
const char * const argv[] = {"cppcheck", "--library=missing", "--version"};
431+
ASSERT_EQUALS(CmdLineParser::Result::Exit, parser->parseFromArgs(3, argv));
432+
ASSERT_EQUALS("Cppcheck 2.13 dev\n", logger->str());
433+
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
434+
}
406435

407436
void onefile() {
408437
REDIRECT;
@@ -1577,6 +1606,14 @@ class TestCmdlineParser : public TestFixture {
15771606
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
15781607
}
15791608

1609+
void docExclusive() {
1610+
REDIRECT;
1611+
const char * const argv[] = {"cppcheck", "--library=missing", "--doc"};
1612+
ASSERT_EQUALS(CmdLineParser::Result::Exit, parser->parseFromArgs(3, argv));
1613+
ASSERT(startsWith(logger->str(), "## "));
1614+
ASSERT_EQUALS("", GET_REDIRECT_OUTPUT);
1615+
}
1616+
15801617
void showtimeSummary() {
15811618
REDIRECT;
15821619
const char * const argv[] = {"cppcheck", "--showtime=summary", "file.cpp"};
@@ -1659,6 +1696,15 @@ class TestCmdlineParser : public TestFixture {
16591696

16601697
// TODO: test --errorlist with product name
16611698

1699+
void errorlistExclusive() {
1700+
REDIRECT;
1701+
const char * const argv[] = {"cppcheck", "--library=missing", "--errorlist"};
1702+
ASSERT_EQUALS(CmdLineParser::Result::Exit, parser->parseFromArgs(3, argv));
1703+
ASSERT_EQUALS("", logger->str()); // empty since it is logged via ErrorLogger
1704+
ASSERT(startsWith(GET_REDIRECT_OUTPUT, "<?xml"));
1705+
ASSERT(endsWith(GET_REDIRECT_OUTPUT, "</results>\n"));
1706+
}
1707+
16621708
void ignorepathsnopath() {
16631709
REDIRECT;
16641710
const char * const argv[] = {"cppcheck", "-i"};

0 commit comments

Comments
 (0)