Skip to content

Commit 2b44fb5

Browse files
whoopsmithdanmar
authored andcommitted
Loosen restrictions on MISRA rules text structure (cppcheck-opensource#2157)
Version 1.88 changed the parsing of the MISRA rules file adding a severity setting. This caused a regression in rule parsing. In particular the following format used to parse cleanly and produce rule output that would show the severity as part of the rule text. Rule 1.2 Advisory Rule text goes here. Rule 1.3 Required More rule text goes here. As of 1.88 a file structured like above would parse as having no rules. The problem is the use of blank lines as a rule delimiter. The modified rule parser wants to see a rules formatted like below: Rule 3.1 Required R3.1 text. Rule 4.1 Required R4.1 text. or: Rule 1.1 Add this rule and parse to next, skipping empty lines. Rule 1.2 Rule text. Any rule text that did not fall into one of the above formats would result in incomplete rule text parsing. Change the parsing of the rule text file so that blank lines are ignored instead of treating them as a delimiter between rules. Instead use the start of the next rule as a delimiter for the end of the previous rule. This allows both of the newer formats but also supports the behavior of pre-1.88 versions. Change units tests that were specifically forbidding the use of blank lines to ones that allow blank lines.
1 parent 9753e18 commit 2b44fb5

3 files changed

Lines changed: 33 additions & 12 deletions

File tree

addons/misra.py

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2205,7 +2205,7 @@ def loadRuleTexts(self, filename):
22052205
expect_more = False
22062206

22072207
Rule_pattern = re.compile(r'^Rule ([0-9]+).([0-9]+)')
2208-
Choice_pattern = re.compile(r'.*[ ]*(Advisory|Required|Mandatory)$')
2208+
severity_pattern = re.compile(r'.*[ ]*(Advisory|Required|Mandatory)$')
22092209
xA_Z_pattern = re.compile(r'^[#A-Z].*')
22102210
a_z_pattern = re.compile(r'^[a-z].*')
22112211
# Try to detect the file encoding
@@ -2231,30 +2231,53 @@ def loadRuleTexts(self, filename):
22312231
file_stream = open(filename, 'rt')
22322232

22332233
rule = None
2234+
have_severity = False
2235+
severity_loc = 0
2236+
22342237
for line in file_stream:
2238+
22352239
line = line.replace('\r', '').replace('\n', '')
2240+
22362241
if not appendixA:
22372242
if line.find('Appendix A') >= 0 and line.find('Summary of guidelines') >= 10:
22382243
appendixA = True
22392244
continue
22402245
if line.find('Appendix B') >= 0:
22412246
break
22422247
if len(line) == 0:
2243-
expect_more = False
2244-
rule = None
22452248
continue
22462249

22472250
# Parse rule declaration.
22482251
res = Rule_pattern.match(line)
2252+
22492253
if res:
2254+
have_severity = False
2255+
expect_more = False
2256+
severity_loc = 0
22502257
num1 = int(res.group(1))
22512258
num2 = int(res.group(2))
22522259
rule = Rule(num1, num2)
2253-
res = Choice_pattern.match(line)
2260+
2261+
if not have_severity and rule is not None:
2262+
res = severity_pattern.match(line)
2263+
22542264
if res:
22552265
rule.misra_severity = res.group(1)
2256-
expect_more = False
2257-
continue
2266+
have_severity = True
2267+
else:
2268+
severity_loc += 1;
2269+
2270+
# Only look for severity on the Rule line
2271+
# or the next non-blank line after
2272+
# If it's not in either of those locations then
2273+
# assume a severity was not provided.
2274+
2275+
if severity_loc < 2:
2276+
continue
2277+
else:
2278+
rule.misra_severity = ''
2279+
have_severity = True
2280+
22582281
if rule is None:
22592282
continue
22602283

@@ -2263,7 +2286,7 @@ def loadRuleTexts(self, filename):
22632286
if a_z_pattern.match(line):
22642287
self.ruleTexts[rule.num].text += ' ' + line
22652288
continue
2266-
rule = None
2289+
22672290
expect_more = False
22682291
continue
22692292

@@ -2272,8 +2295,6 @@ def loadRuleTexts(self, filename):
22722295
rule.text = line
22732296
self.ruleTexts[rule.num] = rule
22742297
expect_more = True
2275-
else:
2276-
rule = None
22772298

22782299
def verifyRuleTexts(self):
22792300
"""Prints rule numbers without rule text."""

addons/test/misra/misra_rules_multiple_lines.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Rule 1.5
1818
Should
1919
starts from lowercase letter.
2020
Rule 1.6
21-
Should
21+
Can
2222

23-
not contain empty lines.
23+
contain empty lines.
2424

addons/test/test-misra.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def test_loadRuleTexts_mutiple_lines(checker):
4949
assert(checker.ruleTexts[103].text == "Multiple lines text.")
5050
assert(checker.ruleTexts[104].text == "Should")
5151
assert(checker.ruleTexts[105].text == "Should")
52-
assert(checker.ruleTexts[106].text == "Should")
52+
assert(checker.ruleTexts[106].text == "Can contain empty lines.")
5353

5454

5555
def test_verifyRuleTexts(checker, capsys):

0 commit comments

Comments
 (0)