misra.py: Add --verify-rule-texts option. (#1909)
* misra.py: Add verify-rule-texts option. * Capture stdout output in travis.
This commit is contained in:
parent
a5185c7005
commit
02cc9ffcd8
|
@ -481,7 +481,27 @@ class Define:
|
|||
self.expansionList = res.group(2)
|
||||
|
||||
|
||||
def getAddonRules():
|
||||
"""Returns dict of MISRA rules handled by this addon."""
|
||||
addon_rules = []
|
||||
compiled = re.compile(r'.*def[ ]+misra_([0-9]+)_([0-9]+)[(].*')
|
||||
for line in open(__file__):
|
||||
res = compiled.match(line)
|
||||
if res is None:
|
||||
continue
|
||||
addon_rules.append(res.group(1) + '.' + res.group(2))
|
||||
return addon_rules
|
||||
|
||||
|
||||
def getCppcheckRules():
|
||||
"""Returns list of rules handled by cppcheck."""
|
||||
return ['1.3', '2.1', '2.2', '2.4', '2.6', '8.3', '12.2', '13.2', '13.6',
|
||||
'14.3', '17.5', '18.1', '18.2', '18.3', '18.6', '20.6',
|
||||
'22.1', '22.2', '22.4', '22.6']
|
||||
|
||||
|
||||
def generateTable():
|
||||
# print table
|
||||
numberOfRules = {}
|
||||
numberOfRules[1] = 3
|
||||
numberOfRules[2] = 7
|
||||
|
@ -506,23 +526,11 @@ def generateTable():
|
|||
numberOfRules[21] = 12
|
||||
numberOfRules[22] = 6
|
||||
|
||||
# what rules are handled by this addon?
|
||||
addon = []
|
||||
compiled = re.compile(r'.*def[ ]+misra_([0-9]+)_([0-9]+)[(].*')
|
||||
for line in open(__file__):
|
||||
res = compiled.match(line)
|
||||
if res is None:
|
||||
continue
|
||||
addon.append(res.group(1) + '.' + res.group(2))
|
||||
|
||||
# rules handled by cppcheck
|
||||
cppcheck = ['1.3', '2.1', '2.2', '2.4', '2.6', '8.3', '12.2', '13.2', '13.6', '14.3', '17.5',
|
||||
'18.1', '18.2', '18.3', '18.6', '20.6', '22.1', '22.2', '22.4', '22.6']
|
||||
|
||||
# rules that can be checked with compilers
|
||||
# Rules that can be checked with compilers:
|
||||
# compiler = ['1.1', '1.2']
|
||||
|
||||
# print table
|
||||
addon = getAddonRules()
|
||||
cppcheck = getCppcheckRules()
|
||||
for i1 in range(1, 23):
|
||||
for i2 in range(1, numberOfRules[i1] + 1):
|
||||
num = str(i1) + '.' + str(i2)
|
||||
|
@ -2148,6 +2156,22 @@ class MisraChecker:
|
|||
else:
|
||||
rule = None
|
||||
|
||||
def verifyRuleTexts(self):
|
||||
"""Prints rule numbers without rule text."""
|
||||
rule_texts_rules = []
|
||||
for rule_num in self.ruleTexts:
|
||||
rule = self.ruleTexts[rule_num]
|
||||
rule_texts_rules.append(str(rule.num1) + '.' + str(rule.num2))
|
||||
|
||||
all_rules = list(getAddonRules() + getCppcheckRules())
|
||||
|
||||
missing_rules = list(set(all_rules) - set(rule_texts_rules))
|
||||
if len(missing_rules) == 0:
|
||||
print("Rule texts are correct.")
|
||||
else:
|
||||
print("Missing rule texts: " + ', '.join(missing_rules))
|
||||
|
||||
|
||||
def printStatus(self, *args, **kwargs):
|
||||
if not self.settings.quiet:
|
||||
print(*args, **kwargs)
|
||||
|
@ -2309,6 +2333,7 @@ def get_args():
|
|||
"""Generates list of command-line arguments acceptable by misra.py script."""
|
||||
parser = cppcheckdata.ArgumentParser()
|
||||
parser.add_argument("--rule-texts", type=str, help=RULE_TEXTS_HELP)
|
||||
parser.add_argument("--verify-rule-texts", help="Verify that all supported rules texts are present in given file and exit.", action="store_true")
|
||||
parser.add_argument("--suppress-rules", type=str, help=SUPPRESS_RULES_HELP)
|
||||
parser.add_argument("--quiet", help="Only print something when there is an error", action="store_true")
|
||||
parser.add_argument("--no-summary", help="Hide summary of violations", action="store_true")
|
||||
|
@ -2336,6 +2361,13 @@ def main():
|
|||
print('Fatal error: file is not found: ' + filename)
|
||||
sys.exit(1)
|
||||
checker.loadRuleTexts(filename)
|
||||
if args.verify_rule_texts:
|
||||
checker.verifyRuleTexts()
|
||||
sys.exit(0)
|
||||
|
||||
if args.verify_rule_texts and not args.rule_texts:
|
||||
print("Error: Please specify rule texts file with --rule-texts=<file>")
|
||||
sys.exit(1)
|
||||
|
||||
if args.suppress_rules:
|
||||
checker.setSuppressionList(args.suppress_rules)
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
Appendix A Summary of guidelines
|
||||
Rule 3.1 Required
|
||||
R3.1 text.
|
||||
Rule 4.1 Required
|
||||
R4.1 text.
|
||||
Rule 10.4 Required
|
||||
R10.4 text.
|
||||
Rule 11.5 Advisory
|
||||
R11.5 text.
|
||||
Rule 15.5 Advisory
|
||||
R15.5 text.
|
||||
Rule 15.6 Required
|
||||
R15.6 text.
|
||||
Rule 17.7 Required
|
||||
R17.7 text.
|
||||
Rule 20.1 Advisory
|
||||
R20.1 text.
|
||||
Rule 21.3 Required
|
||||
R21.3 text.
|
||||
|
|
@ -1,5 +1,24 @@
|
|||
# python -m pytest addons/test/test-misra.py
|
||||
import pytest
|
||||
import sys
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
except ImportError:
|
||||
from io import StringIO
|
||||
|
||||
|
||||
class Capturing(object):
|
||||
|
||||
def __enter__(self):
|
||||
self._stdout = sys.stdout
|
||||
sys.stdout = self._stringio = StringIO()
|
||||
self.captured = []
|
||||
return self
|
||||
|
||||
def __exit__(self, *args):
|
||||
self.captured.extend(self._stringio.getvalue().splitlines())
|
||||
del self._stringio # free up some memory
|
||||
sys.stdout = self._stdout
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -32,3 +51,11 @@ def test_loadRuleTexts_mutiple_lines(checker):
|
|||
assert(checker.ruleTexts[105].text == "Should")
|
||||
assert(checker.ruleTexts[106].text == "Should")
|
||||
|
||||
|
||||
def test_verifyRuleTexts(checker):
|
||||
checker.loadRuleTexts("./addons/test/assets/misra_rules_dummy.txt")
|
||||
with Capturing() as output:
|
||||
checker.verifyRuleTexts()
|
||||
captured = ''.join(output.captured)
|
||||
assert("21.3" not in captured)
|
||||
assert("1.3" in captured)
|
||||
|
|
Loading…
Reference in New Issue