Skip to content
Snippets Groups Projects
Commit 94a3ef0b authored by Grigoris Pavlakis's avatar Grigoris Pavlakis Committed by kongr45gpen
Browse files

Add rule suppression functionality; just pass , do a general refactor to...

Add rule suppression functionality; just pass , do a general refactor to comply with PEP8 and get rid of most of the ugly code
parent 8ccd44eb
No related branches found
No related tags found
No related merge requests found
...@@ -26,4 +26,4 @@ sed -i -r 's/(.*Script.*)|(.*Checking.*)|(.*MISRA.*)//gm; /(^$)/d; s/(\s\(.*\)\s ...@@ -26,4 +26,4 @@ sed -i -r 's/(.*Script.*)|(.*Checking.*)|(.*MISRA.*)//gm; /(^$)/d; s/(\s\(.*\)\s
# run the summarizer for a nice, clean summary of errors # run the summarizer for a nice, clean summary of errors
echo -e "\u001b[34;1mSummarizing results...\u001b[0m" echo -e "\u001b[34;1mSummarizing results...\u001b[0m"
python3.6 ci/summarizer.py ci/report.msr ci/summarizer.py --report ci/report.msr --suppress 5.2 5.3 12.1 15.5 # these are random, will be replaced
#!/bin/env python3.6 #!/bin/env python3.6
from sys import argv from argparse import ArgumentParser
from collections import Counter
""" """
Naive parser and pretty printer for the MISRA reports by cppcheck Naive parser and pretty printer for the MISRA reports by cppcheck
""" """
class Summarizer(object): class Summarizer(object):
def __init__(self, report_name): def __init__(self, report_name, suppression_list):
with open(report_name, 'r') as f: with open(report_name, 'r') as f:
self.file_lines = f.readlines() self.file_lines = f.readlines() # read the report file
f.close() f.close()
self.red = "\033[91m" self.red = "\033[91m" # terminal colors
self.yellow = "\033[93m" self.yellow = "\033[93m"
self.green = "\033[92m" self.green = "\033[92m"
self.bold = "\033[1m" self.bold = "\033[1m"
self.end = "\033[0m" self.end = "\033[0m"
self.violations_map = {} # dictionary containing filenames, rule violations and line where the violation
# occurred
self.suppression_list = suppression_list # list of rule numbers to be suppressed
def analyze(self): def analyze(self):
""" """
A really dumb parser for the pre-processed report generated by cppcheck A really dumb parser for the pre-processed report generated by cppcheck
""" """
errors_map = {} # dictionary containing filenames, rule violations and line where the violation occurred lines_seen = set() # contains the unique lines from the file
lines_seen = set() # contains the unique lines from the file
if len(self.file_lines) == 0:
print(bold + green + "Static analysis for MISRA compliance complete. No errors found." + end)
return 0
for line in self.file_lines: # remove duplicate lines for line in self.file_lines: # remove duplicate lines
if line not in lines_seen: if line not in lines_seen:
lines_seen.add(line) lines_seen.add(line)
line_contents = line.split(':') line_contents = line.split(':')
file_name = line_contents[0] # first part is the filename (index 0) file_name = line_contents[0] # first part is the filename (index 0)
error = (line_contents[1], line_contents[2].strip('\n')) # index 1 is the line number, index 2 is the number of violated rule violation = (line_contents[1], line_contents[2].strip(
'\n')) # index 1 is the line number, index 2 is the number of violated rule (both are strings)
if file_name not in errors_map.keys(): if file_name not in self.violations_map.keys():
errors_map[file_name] = list() # create a new list for the new filename and append the tuple in it self.violations_map[
errors_map[file_name].append(error) file_name] = list() # create a new list for the new filename and append the tuple w/ line &
# rule no.
self.violations_map[file_name].append(violation)
else: else:
errors_map[file_name].append(error) # do not append if it already exists self.violations_map[file_name].append(violation) # do not append if it already exists
return errors_map # return the completed error dictionary for e in self.suppression_list:
for file_name in self.violations_map.keys():
self.violations_map[file_name] = [x for x in self.violations_map[file_name] if x[1] != str(e)]
# replace the list of infractions with a new one, containing everything except the suppressed rules
self.violations_map = {k: v for (k, v) in self.violations_map.items() if len(v) != 0}
# "delete" all keys whose lists are empty
def pretty_print(self, errors): def pretty_print_violations(self):
""" """
Pretty-prints the contents of the error dictionary with colors and stuff Just a pretty printing function, no fancy logic here.
""" """
print(self.bold + self.red + "=========================================================\n" + self.end)
print(self.bold + self.red + "=================================================\n" + self.end) print(self.bold + self.red + " Static analysis results: Infraction summary \n" + self.end)
print(self.bold + self.red + " Static analysis results: Error Summary \n" + self.end) for file_name in self.violations_map:
for file_name in errors:
print("") print("")
for error in sorted(errors[file_name], key=lambda x: int(x[0])): for violation in sorted(self.violations_map[file_name], key=lambda x: int(x[0])):
name_string = f"{self.bold}{self.red}File {self.yellow}{file_name}{self.red}" name_string = f"{self.bold}{self.red}File {self.yellow}{file_name}{self.red}"
rule_violated_string = f"violates rule {self.yellow}#{error[1]}{self.red} of the MISRA C 2012 standard" rule_violated_string = f"violates rule {self.yellow}#{violation[1]}{self.red} " \
line_number_string = f"at line {self.yellow}{error[0]}{self.end}" f"of the MISRA C 2012 standard"
line_number_string = f"at line {self.yellow}{violation[0]}{self.end}"
print(f"{name_string.ljust(75)} {rule_violated_string} {line_number_string}") print(f"{name_string.ljust(75)} {rule_violated_string} {line_number_string}")
print("") print("")
print("") print("")
print(self.bold + self.red +"=================================================" + self.end) print(self.bold + self.red + "=================================================" + self.end)
def suppression_info(self):
"""
Pretty-prints the suppressed rule numbers.
:return:
"""
if (len(self.suppression_list) != 0):
print(self.bold + self.yellow + "WARNING: Suppressed infractions of rules: ", end="")
print(f", ".join(self.suppression_list), end=".")
print("")
print("")
else:
print(self.bold + self.green + "All available rules enforced - no suppressions")
if __name__ == "__main__": if __name__ == "__main__":
s = Summarizer(argv[1]) cli = ArgumentParser()
errors = s.analyze() cli.add_argument("--report", nargs=1, default="./report.msr")
if isinstance(errors, dict): cli.add_argument("--suppress", nargs="*", type=str, default="")
s.pretty_print(errors)
args = cli.parse_args()
s = Summarizer(str(args.report[0]), args.suppress)
s.analyze()
s.suppression_info()
if len(s.violations_map) != 0:
s.pretty_print_violations()
exit(127) exit(127)
elif isinstance(errors, int) and errors == 0: elif len(s.violations_map) == 0:
print(s.bold + s.green + "Static analysis for MISRA compliance complete. No infractions found." + s.end)
exit(0) exit(0)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment