diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index ff4a37b629c..608e1844716 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -315,6 +315,9 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a { mSettings.exename = Path::getCurrentExecutablePath(argv[0]); + bool xmlOptionProvided = false; + bool outputFormatOptionProvided = false; + // default to --check-level=normal from CLI for now mSettings.setCheckLevel(Settings::CheckLevel::normal); @@ -1001,6 +1004,10 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a mSettings.outputFile = Path::simplifyPath(argv[i] + 14); else if (std::strncmp(argv[i], "--output-format=", 16) == 0) { + if (xmlOptionProvided) { + outputFormatOptionMixingError(); + return Result::Fail; + } const std::string format = argv[i] + 16; // plist can not be handled here because it requires additional data if (format == "text") @@ -1009,11 +1016,18 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a mSettings.outputFormat = Settings::OutputFormat::sarif; else if (format == "xml") mSettings.outputFormat = Settings::OutputFormat::xml; - else { - mLogger.printError("argument to '--output-format=' must be 'text', 'sarif' or 'xml'."); + else if (format == "xmlv2") { + mSettings.outputFormat = Settings::OutputFormat::xml; + mSettings.xml_version = 2; + } else if (format == "xmlv3") { + mSettings.outputFormat = Settings::OutputFormat::xml; + mSettings.xml_version = 3; + } else { + mLogger.printError("argument to '--output-format=' must be 'text', 'sarif', 'xml' (deprecated), 'xmlv2' or 'xmlv3'."); return Result::Fail; } mSettings.plistOutput = ""; + outputFormatOptionProvided = true; } @@ -1486,11 +1500,20 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a // Write results in results.xml else if (std::strcmp(argv[i], "--xml") == 0) { + if (outputFormatOptionProvided) { + outputFormatOptionMixingError(); + return Result::Fail; + } mSettings.outputFormat = Settings::OutputFormat::xml; + xmlOptionProvided = true; } // Define the XML file version (and enable XML output) else if (std::strncmp(argv[i], "--xml-version=", 14) == 0) { + if (outputFormatOptionProvided) { + outputFormatOptionMixingError(); + return Result::Fail; + } int tmp; if (!parseNumberArg(argv[i], 14, tmp)) return Result::Fail; @@ -1503,6 +1526,7 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a mSettings.xml_version = tmp; // Enable also XML if version is set mSettings.outputFormat = Settings::OutputFormat::xml; + xmlOptionProvided = true; } else { @@ -1814,7 +1838,9 @@ void CmdLineParser::printHelp() const " Specify the output format. The available formats are:\n" " * text\n" " * sarif\n" - " * xml\n" + " * xml (deprecated)\n" + " * xmlv2\n" + " * xmlv3\n" " --platform=, --platform=\n" " Specifies platform specific types and sizes. The\n" " available builtin platforms are:\n" @@ -2149,3 +2175,8 @@ std::list CmdLineParser::filterFiles(const std::vectoroutputFormat); } + void outputFormatXmlv2() { + REDIRECT; + const char * const argv[] = {"cppcheck", "--output-format=xmlv2", "file.cpp"}; + ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv)); + ASSERT_EQUALS_ENUM(Settings::OutputFormat::xml, settings->outputFormat); + ASSERT_EQUALS(2, settings->xml_version); + } + + void outputFormatXmlv3() { + REDIRECT; + const char * const argv[] = {"cppcheck", "--output-format=xmlv3", "file.cpp"}; + ASSERT_EQUALS_ENUM(CmdLineParser::Result::Success, parseFromArgs(argv)); + ASSERT_EQUALS_ENUM(Settings::OutputFormat::xml, settings->outputFormat); + ASSERT_EQUALS(3, settings->xml_version); + } + void outputFormatOther() { REDIRECT; const char * const argv[] = {"cppcheck", "--output-format=plist", "file.cpp"}; ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); - ASSERT_EQUALS("cppcheck: error: argument to '--output-format=' must be 'text', 'sarif' or 'xml'.\n", logger->str()); + ASSERT_EQUALS("cppcheck: error: argument to '--output-format=' must be 'text', 'sarif', 'xml' (deprecated), 'xmlv2' or 'xmlv3'.\n", logger->str()); } void outputFormatImplicitPlist() { @@ -1411,6 +1432,27 @@ class TestCmdlineParser : public TestFixture { ASSERT_EQUALS("", settings->plistOutput); } + void outputFormatMixed1() { + REDIRECT; + const char * const argv[] = {"cppcheck", "--xml", "--output-format=xml", "file.cpp"}; + ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); + ASSERT_EQUALS("cppcheck: error: '--output-format' and '--xml...' may not be used in conjunction.\n", logger->str()); + } + + void outputFormatMixed2() { + REDIRECT; + const char * const argv[] = {"cppcheck", "--output-format=xml", "--xml", "file.cpp"}; + ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); + ASSERT_EQUALS("cppcheck: error: '--output-format' and '--xml...' may not be used in conjunction.\n", logger->str()); + } + + void outputFormatMixed3() { + REDIRECT; + const char * const argv[] = {"cppcheck", "--xml-version=2", "--output-format=xml", "file.cpp"}; + ASSERT_EQUALS_ENUM(CmdLineParser::Result::Fail, parseFromArgs(argv)); + ASSERT_EQUALS("cppcheck: error: '--output-format' and '--xml...' may not be used in conjunction.\n", logger->str()); + } + void premiumOptions1() { REDIRECT; asPremium();