Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixup #13216, improved xml-format checkers report #6945

Merged
merged 1 commit into from
Oct 22, 2024
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: 25 additions & 88 deletions lib/checkersreport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ static bool isCppcheckPremium(const Settings& settings) {
return (settings.cppcheckCfgProductName.compare(0, 16, "Cppcheck Premium") == 0);
}

static int getMisraCVersion(const Settings& settings) {
if (settings.premiumArgs.find("misra-c-2012") != std::string::npos)
return 2012;
if (settings.premiumArgs.find("misra-c-2023") != std::string::npos)
return 2023;
if (settings.addons.count("misra"))
return 2012;
return 0;
}

static bool isMisraRuleActive(const std::set<std::string>& activeCheckers, const std::string& rule) {
if (activeCheckers.count("Misra C: " + rule))
return true;
Expand Down Expand Up @@ -229,29 +239,23 @@ std::string CheckersReport::getReport(const std::string& criticalErrors) const
reportSection("Cert C", mSettings, mActiveCheckers, checkers::premiumCheckers, "Cert C: ");
reportSection("Cert C++", mSettings, mActiveCheckers, checkers::premiumCheckers, "Cert C++: ");

int misra = 0;
if (mSettings.premiumArgs.find("misra-c-2012") != std::string::npos)
misra = 2012;
else if (mSettings.premiumArgs.find("misra-c-2023") != std::string::npos)
misra = 2023;
else if (mSettings.addons.count("misra"))
misra = 2012;
const int misraCVersion = getMisraCVersion(mSettings);

if (misra == 0) {
if (misraCVersion == 0) {
fout << std::endl << std::endl;
fout << "Misra C" << std::endl;
fout << "-------" << std::endl;
fout << "Misra is not enabled" << std::endl;
} else {
fout << std::endl << std::endl;
fout << "Misra C " << misra << std::endl;
fout << "Misra C " << misraCVersion << std::endl;
fout << "------------" << std::endl;
for (const checkers::MisraInfo& info: checkers::misraC2012Directives) {
const std::string directive = "Dir " + std::to_string(info.a) + "." + std::to_string(info.b);
const bool active = isMisraRuleActive(mActiveCheckers, directive);
fout << (active ? "Yes " : "No ") << "Misra C " << misra << ": " << directive;
fout << (active ? "Yes " : "No ") << "Misra C " << misraCVersion << ": " << directive;
std::string extra;
if (misra == 2012 && info.amendment >= 1)
if (misraCVersion == 2012 && info.amendment >= 1)
extra = " amendment:" + std::to_string(info.amendment);
if (!extra.empty())
fout << std::string(10 - directive.size(), ' ') << extra;
Expand All @@ -260,9 +264,9 @@ std::string CheckersReport::getReport(const std::string& criticalErrors) const
for (const checkers::MisraInfo& info: checkers::misraC2012Rules) {
const std::string rule = std::to_string(info.a) + "." + std::to_string(info.b);
const bool active = isMisraRuleActive(mActiveCheckers, rule);
fout << (active ? "Yes " : "No ") << "Misra C " << misra << ": " << rule;
fout << (active ? "Yes " : "No ") << "Misra C " << misraCVersion << ": " << rule;
std::string extra;
if (misra == 2012 && info.amendment >= 1)
if (misraCVersion == 2012 && info.amendment >= 1)
extra = " amendment:" + std::to_string(info.amendment);
std::string reqs;
if (info.amendment >= 3)
Expand All @@ -284,84 +288,17 @@ std::string CheckersReport::getReport(const std::string& criticalErrors) const
std::string CheckersReport::getXmlReport(const std::string& criticalErrors) const
{
std::string ret;

if (!criticalErrors.empty()) {
ret += " <critical-errors>" + criticalErrors + "\n </critical-errors>\n";
} else
if (!criticalErrors.empty())
ret += " <critical-errors>" + criticalErrors + "</critical-errors>\n";
else
ret += " <critical-errors/>\n";
ret += " <checkers-report>\n";

const bool cppcheckPremium = isCppcheckPremium(mSettings);

auto reportSection = [&ret, cppcheckPremium]
(const std::string& title,
const Settings& settings,
const std::set<std::string>& activeCheckers,
const std::map<std::string, std::string>& premiumCheckers,
const std::string& substring) {
if (!cppcheckPremium) {
ret += "<" + title + "/>\n";
return;
}
ret += " <" + title + ">\n";
for (const auto& checkReq: premiumCheckers) {
const std::string& checker = checkReq.first;
if (checker.find(substring) == std::string::npos)
continue;
bool active = cppcheckPremium && activeCheckers.count(checker) > 0;
if (substring == "::") {
if (checkReq.second == "warning")
active &= settings.severity.isEnabled(Severity::warning);
else if (checkReq.second == "style")
active &= settings.severity.isEnabled(Severity::style);
else if (checkReq.second == "portability")
active &= settings.severity.isEnabled(Severity::portability);
else if (!checkReq.second.empty())
active = false; // FIXME: handle req
}
ret += " <checker active=\"" + std::string(active ? "Yes" : "No") + "\" id=\"" + checker + "\"";
ret += "/>\n";
}
ret += " </" + title + ">\n";
};

reportSection("premium-checkers", mSettings, mActiveCheckers, checkers::premiumCheckers, "::");
reportSection("autosar", mSettings, mActiveCheckers, checkers::premiumCheckers, "Autosar: ");
reportSection("cert-c", mSettings, mActiveCheckers, checkers::premiumCheckers, "Cert C: ");
reportSection("cert-cpp", mSettings, mActiveCheckers, checkers::premiumCheckers, "Cert C++: ");

int misra = 0;
if (mSettings.premiumArgs.find("misra-c-2012") != std::string::npos)
misra = 2012;
else if (mSettings.premiumArgs.find("misra-c-2023") != std::string::npos)
misra = 2023;
else if (mSettings.addons.count("misra"))
misra = 2012;

if (misra == 0) {
ret += " <misra-c/>\n";
} else {
ret += " <misra-c-" + std::to_string(misra) + ">\n";
for (const checkers::MisraInfo& info: checkers::misraC2012Directives) {
const std::string directive = "Dir " + std::to_string(info.a) + "." + std::to_string(info.b);
const bool active = isMisraRuleActive(mActiveCheckers, directive);
ret += " <checker active=\"";
ret += std::string(active ? "Yes" : "No") + "\" id=\"Misra C " + std::to_string(misra) + ": " + directive + "\"";
ret += "/>\n";
}
for (const checkers::MisraInfo& info: checkers::misraC2012Rules) {
const std::string rule = std::to_string(info.a) + "." + std::to_string(info.b);
const bool active = isMisraRuleActive(mActiveCheckers, rule);
ret += " <checker active=\"";
ret += std::string(active ? "Yes" : "No") + "\" id=\"Misra C " + std::to_string(misra) + ": " + rule + "\"";
ret += "/>\n";
}
ret += " </misra-c-" + std::to_string(misra) + ">\n";
const int misraCVersion = getMisraCVersion(mSettings);
for (std::string checker: mActiveCheckers) {
if (checker.compare(0,8,"Misra C:") == 0)
checker = "Misra C " + std::to_string(misraCVersion) + ":" + checker.substr(8);
ret += " <checker id=\"" + checker + "\"/>\n";
}

reportSection("misra-cpp-2008", mSettings, mActiveCheckers, checkers::premiumCheckers, "Misra C++ 2008: ");
reportSection("misra-cpp-2023", mSettings, mActiveCheckers, checkers::premiumCheckers, "Misra C++ 2023: ");

ret += " </checkers-report>";
return ret;
}
2 changes: 1 addition & 1 deletion lib/errorlogger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ std::string ErrorMessage::getXMLHeader(std::string productName, int xmlVersion)

std::string ErrorMessage::getXMLFooter(int xmlVersion)
{
return xmlVersion == 3? "</results>" : " </errors>\n</results>";
return xmlVersion == 3 ? "</results>" : " </errors>\n</results>";
}

// There is no utf-8 support around but the strings should at least be safe for to tinyxml2.
Expand Down
Loading