Skip to content

Commit 930f52c

Browse files
authored
Fix #12427 (premium misra C rule texts) (#5969)
1 parent 7c790ca commit 930f52c

10 files changed

Lines changed: 70 additions & 11 deletions

File tree

addons/misra.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4280,14 +4280,6 @@ def reportError(self, location, num1, num2):
42804280
errorId = 'c2012-' + str(num1) + '.' + str(num2)
42814281
misra_severity = 'Undefined'
42824282
cppcheck_severity = 'style'
4283-
if self.path_premium_addon and ruleNum not in self.ruleTexts:
4284-
for line in cppcheckdata.cmd_output([self.path_premium_addon, '--cli', '--get-rule-text=' + errorId]).split('\n'):
4285-
if len(line) > 1 and not line.startswith('{'):
4286-
errmsg = line.strip()
4287-
rule = Rule(num1, num2)
4288-
rule.text = errmsg
4289-
self.ruleTexts[rule.num] = rule
4290-
break
42914283
if ruleNum in self.ruleTexts:
42924284
errmsg = self.ruleTexts[ruleNum].text
42934285
if self.ruleTexts[ruleNum].misra_severity:

cli/cppcheckexecutor.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ int CppCheckExecutor::check(int argc, const char* const argv[])
191191
mFiles = parser.getFiles();
192192
mFileSettings = parser.getFileSettings();
193193

194+
settings.setMisraRuleTexts(executeCommand);
195+
194196
mStdLogger = new StdLogger(settings);
195197

196198
CppCheck cppCheck(*mStdLogger, true, executeCommand);

gui/checkthread.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
#endif
5858

5959
// NOLINTNEXTLINE(performance-unnecessary-value-param) - used as callback so we need to preserve the signature
60-
static int executeCommand(std::string exe, std::vector<std::string> args, std::string redirect, std::string &output) // cppcheck-suppress passedByValueCallback
60+
int CheckThread::executeCommand(std::string exe, std::vector<std::string> args, std::string redirect, std::string &output) // cppcheck-suppress passedByValue
6161
{
6262
output.clear();
6363

gui/checkthread.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ class CheckThread : public QThread {
9292
*/
9393
static QString clangTidyCmd();
9494

95+
static int executeCommand(std::string exe, std::vector<std::string> args, std::string redirect, std::string &output);
96+
9597
signals:
9698

9799
/**

gui/mainwindow.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "applicationlist.h"
2323
#include "aboutdialog.h"
2424
#include "analyzerinfo.h"
25+
#include "checkthread.h"
2526
#include "common.h"
2627
#include "cppcheck.h"
2728
#include "errortypes.h"
@@ -1090,6 +1091,7 @@ QPair<bool,Settings> MainWindow::getCppcheckSettings()
10901091
if (!premiumArgs.contains("misra") && mProjectFile->getAddons().contains("misra"))
10911092
premiumArgs += " --misra-c-2012";
10921093
result.premiumArgs = premiumArgs.mid(1).toStdString();
1094+
result.setMisraRuleTexts(CheckThread::executeCommand);
10931095
}
10941096
}
10951097

lib/cppcheck.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,8 +1473,7 @@ void CppCheck::executeAddons(const std::vector<std::string>& files, const std::s
14731473
errmsg.id = obj["addon"].get<std::string>() + "-" + obj["errorId"].get<std::string>();
14741474
if (misraC2023 && startsWith(errmsg.id, "misra-c2012-"))
14751475
errmsg.id = "misra-c2023-" + errmsg.id.substr(12);
1476-
const std::string text = obj["message"].get<std::string>();
1477-
errmsg.setmsg(text);
1476+
errmsg.setmsg(mSettings.getMisraRuleText(errmsg.id, obj["message"].get<std::string>()));
14781477
const std::string severity = obj["severity"].get<std::string>();
14791478
errmsg.severity = severityFromString(severity);
14801479
if (errmsg.severity == Severity::none || errmsg.severity == Severity::internal) {

lib/cppcheck.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ class CPPCHECKLIB CppCheck : ErrorLogger {
152152

153153
bool isPremiumCodingStandardId(const std::string& id) const;
154154

155+
std::string getAddonMessage(const std::string& id, const std::string& text) const;
156+
155157
private:
156158
#ifdef HAVE_RULES
157159
/** Are there "simple" rules */

lib/settings.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "vfvalue.h"
2323

2424
#include <fstream>
25+
#include <sstream>
2526

2627
#include "json.h"
2728

@@ -545,3 +546,46 @@ bool Settings::isPremiumEnabled(const char id[]) const
545546
return true;
546547
return false;
547548
}
549+
550+
void Settings::setMisraRuleTexts(const ExecuteCmdFn& executeCommand)
551+
{
552+
if (premiumArgs.find("--misra-c-20") != std::string::npos) {
553+
const auto it = std::find_if(addonInfos.cbegin(), addonInfos.cend(), [](const AddonInfo& a) {
554+
return a.name == "premiumaddon.json";
555+
});
556+
if (it != addonInfos.cend()) {
557+
std::string arg;
558+
if (premiumArgs.find("--misra-c-2023") != std::string::npos)
559+
arg = "--misra-c-2023-rule-texts";
560+
else
561+
arg = "--misra-c-2012-rule-texts";
562+
std::string output;
563+
executeCommand(it->executable, {arg}, "2>&1", output);
564+
setMisraRuleTexts(output);
565+
}
566+
}
567+
}
568+
569+
void Settings::setMisraRuleTexts(const std::string& data)
570+
{
571+
mMisraRuleTexts.clear();
572+
std::istringstream istr(data);
573+
std::string line;
574+
while (std::getline(istr, line)) {
575+
std::string::size_type pos = line.find(' ');
576+
if (pos == std::string::npos)
577+
continue;
578+
std::string id = line.substr(0, pos);
579+
std::string text = line.substr(pos + 1);
580+
if (id.empty() || text.empty())
581+
continue;
582+
mMisraRuleTexts[id] = text;
583+
}
584+
}
585+
586+
std::string Settings::getMisraRuleText(const std::string& id, const std::string& text) const {
587+
if (id.compare(0, 9, "misra-c20") != 0)
588+
return text;
589+
const auto it = mMisraRuleTexts.find(id.substr(id.rfind('-') + 1));
590+
return it != mMisraRuleTexts.end() ? it->second : text;
591+
}

lib/settings.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ class CPPCHECKLIB WARN_UNUSED Settings {
261261
/** @brief Extra arguments for Cppcheck Premium addon */
262262
std::string premiumArgs;
263263

264+
/** Is checker id enabled by premiumArgs */
264265
bool isPremiumEnabled(const char id[]) const;
265266

266267
/** @brief Using -E for debugging purposes */
@@ -452,9 +453,15 @@ class CPPCHECKLIB WARN_UNUSED Settings {
452453
};
453454
CheckLevel checkLevel = CheckLevel::normal;
454455

456+
using ExecuteCmdFn = std::function<int (std::string,std::vector<std::string>,std::string,std::string&)>;
457+
void setMisraRuleTexts(const ExecuteCmdFn& executeCommand);
458+
void setMisraRuleTexts(const std::string& data);
459+
std::string getMisraRuleText(const std::string& id, const std::string& text) const;
460+
455461
private:
456462
static std::string parseEnabled(const std::string &str, std::tuple<SimpleEnableGroup<Severity>, SimpleEnableGroup<Checks>> &groups);
457463
std::string applyEnabled(const std::string &str, bool enable);
464+
std::map<std::string, std::string> mMisraRuleTexts;
458465
};
459466

460467
/// @}

test/testsettings.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class TestSettings : public TestFixture {
3232
TEST_CASE(loadCppcheckCfg);
3333
TEST_CASE(loadCppcheckCfgSafety);
3434
TEST_CASE(getNameAndVersion);
35+
TEST_CASE(ruleTexts);
3536
}
3637

3738
void simpleEnableGroup() const {
@@ -254,6 +255,14 @@ class TestSettings : public TestFixture {
254255
ASSERT_EQUALS("12.3.4s", nameVersion.second);
255256
}
256257
}
258+
259+
void ruleTexts() const
260+
{
261+
Settings s;
262+
s.setMisraRuleTexts("1.1 text 1\n1.2 text 2\n");
263+
ASSERT_EQUALS("text 1", s.getMisraRuleText("misra-c2012-1.1", "---"));
264+
ASSERT_EQUALS("text 2", s.getMisraRuleText("misra-c2012-1.2", "---"));
265+
}
257266
};
258267

259268
REGISTER_TEST(TestSettings)

0 commit comments

Comments
 (0)