Add a dynamic rule enable/disable system

This commit is contained in:
Albert Aribaud 2015-10-09 19:57:05 +02:00 committed by Daniel Marjamäki
parent 2eb8492993
commit 231b486e49
3 changed files with 71 additions and 20 deletions

View File

@ -641,43 +641,68 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
else if (std::strncmp(argv[i], "--rule=", 7) == 0) {
Settings::Rule rule;
rule.pattern = 7 + argv[i];
_settings->rules.push_back(rule);
_settings->rules[rule.id] = rule;
}
// Rule file
else if (std::strncmp(argv[i], "--rule-file=", 12) == 0) {
tinyxml2::XMLDocument doc;
if (doc.LoadFile(12+argv[i]) == tinyxml2::XML_NO_ERROR) {
tinyxml2::XMLElement *node = doc.FirstChildElement();
const tinyxml2::XMLElement *node = doc.FirstChildElement();
for (; node && strcmp(node->Value(), "rule") == 0; node = node->NextSiblingElement()) {
Settings::Rule rule;
tinyxml2::XMLElement *tokenlist = node->FirstChildElement("tokenlist");
const tinyxml2::XMLElement *tokenlist = node->FirstChildElement("tokenlist");
if (tokenlist)
rule.tokenlist = tokenlist->GetText();
tinyxml2::XMLElement *pattern = node->FirstChildElement("pattern");
const tinyxml2::XMLElement *pattern = node->FirstChildElement("pattern");
if (pattern) {
rule.pattern = pattern->GetText();
}
tinyxml2::XMLElement *message = node->FirstChildElement("message");
const tinyxml2::XMLElement *message = node->FirstChildElement("message");
if (message) {
tinyxml2::XMLElement *severity = message->FirstChildElement("severity");
const tinyxml2::XMLElement *severity = message->FirstChildElement("severity");
if (severity)
rule.severity = severity->GetText();
tinyxml2::XMLElement *id = message->FirstChildElement("id");
const tinyxml2::XMLElement *id = message->FirstChildElement("id");
if (id)
rule.id = id->GetText();
tinyxml2::XMLElement *summary = message->FirstChildElement("summary");
const tinyxml2::XMLElement *summary = message->FirstChildElement("summary");
if (summary)
rule.summary = summary->GetText() ? summary->GetText() : "";
}
tinyxml2::XMLElement *state = node->FirstChildElement("state");
if (state) {
std::string rule_state = state->GetText();
if (rule_state == "enabled")
rule.enabled = true;
else if (rule_state == "disabled")
rule.enabled = false;
else {
std::string msg("cppcheck: error: unrecognized rule state: \"");
msg += rule_state;
msg += "\". Supported states: disable, enable.";
PrintMessage(msg);
}
}
tinyxml2::XMLElement *disabled = node->FirstChildElement("disable");
if (disabled) {
rule.disable_rules = disabled->GetText();
}
tinyxml2::XMLElement *enabled = node->FirstChildElement("enable");
if (enabled) {
rule.enable_rules = enabled->GetText();
}
if (!rule.pattern.empty())
_settings->rules.push_back(rule);
_settings->rules[rule.id] = rule;
}
}
}

View File

@ -168,8 +168,8 @@ unsigned int CppCheck::processFile(const std::string& filename, std::istream& fi
}
// Run rules on this code
for (std::list<Settings::Rule>::const_iterator it = _settings.rules.begin(); it != _settings.rules.end(); ++it) {
if (it->tokenlist == "define") {
for (std::map<std::string, Settings::Rule>::const_iterator it = _settings.rules.begin(); it != _settings.rules.end(); ++it) {
if (it->second.enabled && it->second.tokenlist == "define") {
Tokenizer tokenizer2(&_settings, this);
std::istringstream istr2(filedata);
tokenizer2.list.createTokens(istr2, filename);
@ -320,8 +320,8 @@ bool CppCheck::checkFile(const std::string &code, const char FileName[], std::se
_tokenizer.setTimerResults(&S_timerResults);
try {
// Execute rules for "raw" code
for (std::list<Settings::Rule>::const_iterator it = _settings.rules.begin(); it != _settings.rules.end(); ++it) {
if (it->tokenlist == "raw") {
for (std::map<std::string, Settings::Rule>::const_iterator it = _settings.rules.begin(); it != _settings.rules.end(); ++it) {
if (it->second.enabled && it->second.tokenlist == "raw") {
Tokenizer tokenizer2(&_settings, this);
std::istringstream istr(code);
tokenizer2.list.createTokens(istr, FileName);
@ -439,8 +439,8 @@ void CppCheck::executeRules(const std::string &tokenlist, const Tokenizer &token
#ifdef HAVE_RULES
// Are there rules to execute?
bool isrule = false;
for (std::list<Settings::Rule>::const_iterator it = _settings.rules.begin(); it != _settings.rules.end(); ++it) {
if (it->tokenlist == tokenlist)
for (std::map<std::string, Settings::Rule>::const_iterator it = _settings.rules.begin(); it != _settings.rules.end(); ++it) {
if (it->second.enabled && it->second.tokenlist == tokenlist)
isrule = true;
}
@ -454,9 +454,9 @@ void CppCheck::executeRules(const std::string &tokenlist, const Tokenizer &token
ostr << " " << tok->str();
const std::string str(ostr.str());
for (std::list<Settings::Rule>::const_iterator it = _settings.rules.begin(); it != _settings.rules.end(); ++it) {
const Settings::Rule &rule = *it;
if (rule.pattern.empty() || rule.id.empty() || rule.severity.empty() || rule.tokenlist != tokenlist)
for (std::map<std::string, Settings::Rule>::const_iterator it = _settings.rules.begin(); it != _settings.rules.end(); ++it) {
const Settings::Rule &rule = it->second;
if (rule.pattern.empty() || rule.id.empty() || rule.severity.empty() || rule.tokenlist != tokenlist || !rule.enabled)
continue;
const char *error = nullptr;
@ -511,6 +511,26 @@ void CppCheck::executeRules(const std::string &tokenlist, const Tokenizer &token
// Report error
reportErr(errmsg);
// Disable rules that must be disabled
std::istringstream disable(rule.disable_rules);
do {
std::string rule_to_disable;
disable >> rule_to_disable;
if (rule_to_disable != "") {
_settings.rules[rule_to_disable].enabled = false;
}
} while (disable);
// Enable rules that must be enabled
std::istringstream enable(rule.enable_rules);
do {
std::string rule_to_enable;
enable >> rule_to_enable;
if (rule_to_enable != "") {
_settings.rules[rule_to_enable].enabled = true;
}
} while (enable);
}
pcre_free(re);

View File

@ -218,7 +218,10 @@ public:
Rule()
: tokenlist("simple") // use simple tokenlist
, id("rule") // default id
, severity("style") { // default severity
, severity("style") // default severity
, disable_rules("") // default disabled rules
, enable_rules("") // default enabled rules
, enabled(true) {
}
std::string tokenlist;
@ -226,12 +229,15 @@ public:
std::string id;
std::string severity;
std::string summary;
std::string disable_rules;
std::string enable_rules;
bool enabled;
};
/**
* @brief Extra rules
*/
std::list<Rule> rules;
std::map<std::string, Rule> rules;
/** Is the 'configuration checking' wanted? */
bool checkConfiguration;