Map MISRA violation categories to cppcheck categories (#1775)
This commit is contained in:
parent
480284d428
commit
76bf5ecb06
|
@ -545,6 +545,26 @@ def remove_file_prefix(file_path, prefix):
|
||||||
result = file_path
|
result = file_path
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
class Rule:
|
||||||
|
""" Class to keep rule text and metadata """
|
||||||
|
def __init__(self, num1, num2):
|
||||||
|
self.num1 = num1
|
||||||
|
self.num2 = num2
|
||||||
|
self.text = ''
|
||||||
|
self.severity = 'style'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def num(self):
|
||||||
|
return self.num1 * 100 + self.num2
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cppcheck_severity(self):
|
||||||
|
return self.SEVERITY_MAP[self.severity]
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "%d.%d %s" % (self.num1, self.num2, self.severity)
|
||||||
|
|
||||||
|
SEVERITY_MAP = { 'Required': 'warning', 'Mandatory': 'error', 'Advisory': 'information' }
|
||||||
|
|
||||||
class MisraChecker:
|
class MisraChecker:
|
||||||
|
|
||||||
|
@ -555,7 +575,7 @@ class MisraChecker:
|
||||||
self.verify_actual = list()
|
self.verify_actual = list()
|
||||||
|
|
||||||
# List of formatted violation messages
|
# List of formatted violation messages
|
||||||
self.violations = list()
|
self.violations = dict()
|
||||||
|
|
||||||
# if --rule-texts is specified this dictionary
|
# if --rule-texts is specified this dictionary
|
||||||
# is loaded with descriptions of each rule
|
# is loaded with descriptions of each rule
|
||||||
|
@ -1690,9 +1710,16 @@ class MisraChecker:
|
||||||
return self.verify_actual
|
return self.verify_actual
|
||||||
|
|
||||||
|
|
||||||
def get_violations(self):
|
def get_violations(self, violation_type = None):
|
||||||
"""Return the list of violations for a normal checker run"""
|
"""Return the list of violations for a normal checker run"""
|
||||||
return self.violations
|
if violation_type == None:
|
||||||
|
return self.violations.items()
|
||||||
|
else:
|
||||||
|
return self.violations[violation_type]
|
||||||
|
|
||||||
|
def get_violation_types(self):
|
||||||
|
"""Return the list of violations for a normal checker run"""
|
||||||
|
return self.violations.keys()
|
||||||
|
|
||||||
|
|
||||||
def addSuppressedRule(self, ruleNum,
|
def addSuppressedRule(self, ruleNum,
|
||||||
|
@ -1922,23 +1949,26 @@ class MisraChecker:
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
id = 'misra-c2012-' + str(num1) + '.' + str(num2)
|
id = 'misra-c2012-' + str(num1) + '.' + str(num2)
|
||||||
|
severity = 'style'
|
||||||
if ruleNum in self.ruleTexts:
|
if ruleNum in self.ruleTexts:
|
||||||
errmsg = self.ruleTexts[ruleNum] + ' [' + id + ']'
|
errmsg = self.ruleTexts[ruleNum].text + ' [' + id + ']'
|
||||||
|
severity = self.ruleTexts[ruleNum].cppcheck_severity
|
||||||
elif len(self.ruleTexts) == 0:
|
elif len(self.ruleTexts) == 0:
|
||||||
errmsg = 'misra violation (use --rule-texts=<file> to get proper output) [' + id + ']'
|
errmsg = 'misra violation (use --rule-texts=<file> to get proper output) [' + id + ']'
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
formattedMsg = cppcheckdata.reportError(args.template,
|
formattedMsg = cppcheckdata.reportError(args.template,
|
||||||
callstack=[(location.file, location.linenr)],
|
callstack=[(location.file, location.linenr)],
|
||||||
severity='style',
|
severity=severity,
|
||||||
message = errmsg,
|
message = errmsg,
|
||||||
errorId = id,
|
errorId = id,
|
||||||
suppressions = self.dumpfileSuppressions)
|
suppressions = self.dumpfileSuppressions)
|
||||||
if formattedMsg:
|
if formattedMsg:
|
||||||
sys.stderr.write(formattedMsg)
|
sys.stderr.write(formattedMsg)
|
||||||
sys.stderr.write('\n')
|
sys.stderr.write('\n')
|
||||||
self.violations.append(errmsg)
|
if not severity in self.violations:
|
||||||
|
self.violations[severity] = []
|
||||||
|
self.violations[severity].append(id)
|
||||||
|
|
||||||
def loadRuleTexts(self, filename):
|
def loadRuleTexts(self, filename):
|
||||||
num1 = 0
|
num1 = 0
|
||||||
|
@ -1972,13 +2002,14 @@ class MisraChecker:
|
||||||
# Python 2 does not support the errors parameter
|
# Python 2 does not support the errors parameter
|
||||||
file_stream = open(filename, 'rt')
|
file_stream = open(filename, 'rt')
|
||||||
# Parse the rule texts
|
# Parse the rule texts
|
||||||
|
rule = None
|
||||||
for line in file_stream:
|
for line in file_stream:
|
||||||
line = line.replace('\r', '').replace('\n', '')
|
line = line.replace('\r', '').replace('\n', '')
|
||||||
if len(line) == 0:
|
if len(line) == 0:
|
||||||
if ruleText:
|
if rule:
|
||||||
num1 = 0
|
num1 = 0
|
||||||
num2 = 0
|
num2 = 0
|
||||||
ruleText = False
|
rule = None
|
||||||
continue
|
continue
|
||||||
if not appendixA:
|
if not appendixA:
|
||||||
if line.find('Appendix A') >= 0 and line.find('Summary of guidelines') >= 10:
|
if line.find('Appendix A') >= 0 and line.find('Summary of guidelines') >= 10:
|
||||||
|
@ -1990,22 +2021,19 @@ class MisraChecker:
|
||||||
if res:
|
if res:
|
||||||
num1 = int(res.group(1))
|
num1 = int(res.group(1))
|
||||||
num2 = int(res.group(2))
|
num2 = int(res.group(2))
|
||||||
ruleText = False
|
rule = Rule(num1, num2)
|
||||||
continue
|
continue
|
||||||
if Choice_pattern.match(line):
|
if Choice_pattern.match(line):
|
||||||
ruleText = False
|
if rule:
|
||||||
|
rule.severity = line
|
||||||
elif xA_Z_pattern.match(line):
|
elif xA_Z_pattern.match(line):
|
||||||
if ruleText:
|
if rule:
|
||||||
num2 = num2 + 1
|
rule.text = line
|
||||||
num = num1 * 100 + num2
|
self.ruleTexts[rule.num] = rule
|
||||||
self.ruleTexts[num] = line
|
elif rule and a_z_pattern.match(line):
|
||||||
ruleText = True
|
self.ruleTexts[rule.num].text = self.ruleTexts[rule.num].text + ' ' + line
|
||||||
elif ruleText and a_z_pattern.match(line):
|
|
||||||
num = num1 * 100 + num2
|
|
||||||
self.ruleTexts[num] = self.ruleTexts[num] + ' ' + line
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
||||||
def parseDump(self, dumpfile):
|
def parseDump(self, dumpfile):
|
||||||
|
|
||||||
data = cppcheckdata.parsedump(dumpfile)
|
data = cppcheckdata.parsedump(dumpfile)
|
||||||
|
@ -2224,7 +2252,7 @@ else:
|
||||||
exitCode = 1
|
exitCode = 1
|
||||||
|
|
||||||
if SHOW_SUMMARY:
|
if SHOW_SUMMARY:
|
||||||
print("\nMISRA rule violations found: %d\n" % (number_of_violations))
|
print("\nMISRA rule violations found: %s\n" % ("\t".join([ "%s: %d" % (viol, len(checker.get_violations(viol))) for viol in checker.get_violation_types()])))
|
||||||
|
|
||||||
if args.show_suppressed_rules:
|
if args.show_suppressed_rules:
|
||||||
checker.showSuppressedRules()
|
checker.showSuppressedRules()
|
||||||
|
|
Loading…
Reference in New Issue