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

Clean up MISRA scripts according to review comments

Change variable and function names to be more pythonic

Replace the ugly ANSI escapes with more readable, reusable strings

Pad the resulting strings for readability

Close the file after reading its lines

Delete a redundant loop in the parser code, credits to @dimst23

Fix comments to foolow Python conventions

Comment fixing vol. 2

Encapsulate the 2 functions into a class

Fix various blunders with the class encapsulation
parent 4f9945c9
No related branches found
No related tags found
No related merge requests found
......@@ -14,17 +14,11 @@ curl https://raw.githubusercontent.com/danmar/cppcheck/f4b5b156d720c712f6ce99f6e
# generate dump files (XML representations of AST etc.) for all headers, source files etc.
echo -e "\u001b[34;1mGenerating dump files...\u001b[0m"
for file in $(find inc/ src/ -type f \( -iname "*.cpp" -or -iname "*.hpp" \))
do
cppcheck --dump $file
done
find inc/ src/ -type f \( -iname "*.cpp" -or -iname "*.hpp" \) | xargs cppcheck --dump
# run the MISRA checks against the dumps and send the results to a file
echo -e "\u001b[34;1mRunning MISRA C(2012) rule compliance tests...\u001b[0m"
for file in $(find inc/ src/ -type f -name "*.dump")
do
python ci/misra.py $file >> ci/report.msr 2>&1
done
find inc/ src/ -type f -name "*.dump" | xargs python3 ci/misra.py >> ci/report.msr 2>&1
# pre-process the generated report to remove all useless strings
echo -e "\u001b[34;1mPre-processing report...\u001b[0m"
......@@ -32,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
echo -e "\u001b[34;1mSummarizing results...\u001b[0m"
python ci/summarizer.py ci/report.msr
python3 ci/summarizer.py ci/report.msr
#!/bin/env python
#!/bin/env python3
from sys import argv
from sys import exit
from collections import Counter
'''
"""
Naive parser and pretty printer for the MISRA reports by cppcheck
'''
"""
script, reportfile = argv
def analyze():
'''
A really dumb parser for the pre-processed report generated by cppcheck
'''
errorsMap = {} # keys: filenames, values: list of tuples containing rule violated and line
file = open(reportfile, 'r')
fileLines = file.readlines()
cppcheckNumOfErrors = len(fileLines) # number of errors in the original report (most of these are duplicates)
linesSeen = set() # contains the unique lines from the file
red = "\033[91m"
yellow = "\033[93m"
green = "\033[92m"
bold = "\033[1m"
end = "\033[0m"
class Summarizer(object):
def __init__(self, report_name):
with open(report_name, 'r') as f:
self.file_lines = f.readlines()
f.close()
def analyze(self):
"""
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
if len(fileLines) == 0:
print("\033[1m\033[92mStatic analysis for MISRA compliance complete. No errors found.")
return 0
else:
for line in fileLines: # remove duplicate lines
if line not in linesSeen:
linesSeen.add(line)
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
else:
for line in self.file_lines: # remove duplicate lines
if line not in lines_seen:
lines_seen.add(line)
for line in linesSeen: # after cleaning up the duplicates, split the line into parts
lineContents = line.split(':')
fileName = lineContents[0] # first part is the filename (index 0)
error = (lineContents[1], lineContents[2].strip('\n')) # index 1: line number, index 2: number of violated rule
line_contents = line.split(':')
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
if fileName not in errorsMap.keys():
errorsMap[fileName] = list() # create a new list for the new filename and append the tuple in it
errorsMap[fileName].append(error)
else:
errorsMap[fileName].append(error) # do not append if it already exists
if file_name not in errors_map.keys():
errors_map[file_name] = list() # create a new list for the new filename and append the tuple in it
errors_map[file_name].append(error)
else:
errors_map[file_name].append(error) # do not append if it already exists
return errorsMap # return the completed error dictionary
return errors_map # return the completed error dictionary
def pretty_print(self, errors):
"""
Pretty-prints the contents of the error dictionary with colors and stuff
"""
print(bold + red + "=================================================\n" + end)
print(bold + red + " Static analysis results: Error Summary \n" + end)
for key in errors:
for error in errors[key]:
name_string = f"{bold}{red}File {yellow}{key}{red}"
rule_violated_string = f"violates rule {yellow}#{error[1]}{red} of the MISRA C 2012 standard"
line_number_string = f"at line {yellow}{error[0]}{end}"
def prettyprint(errors):
'''
Prettyprints the contents of the error dictionary with colors and stuff
'''
print("\033[1m\033[91m=================================================\n")
print("\033[1m Static analysis results: Error Summary \n")
for key in errors:
for error in errors[key]:
print("\033[1mFile \033[93m{0}\033[91m violates rule \033[93m#{1}\033[91m of the MISRA C 2012 standard at line \033[93m{2}\033[91m".format(key, error[1], error[0]))
print ""
print ""
print("\033[1m=================================================\033[0m\n")
print(f"{name_string.ljust(75)} {rule_violated_string} {line_number_string}")
print("")
print("")
print(bold + red +"=================================================" + end)
def run():
errors = analyze()
if __name__ == "__main__":
s = Summarizer(argv[1])
errors = s.analyze()
if isinstance(errors, dict):
prettyprint(errors)
s.pretty_print(errors)
exit(127)
elif isinstance(errors, int) and errors == 0:
exit(0)
if __name__ == "__main__":
run()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment