From 41dfa21869cc3c3f848dfcfb4507eac6a543e8cf Mon Sep 17 00:00:00 2001 From: Grigoris Pavlakis <grigpavl@ece.auth.gr> Date: Fri, 22 Mar 2019 18:40:16 +0200 Subject: [PATCH] Commit for saving the current state in order to hunt down a last-minute bug Finalize pipeline scripts, waiting for review Fix pipeline passing on GitLab CI when it should fail --- ci/cppcheck-misra.sh | 16 ++++++---- ci/summarizer.py | 71 +++++++++++++++++++++++++++----------------- 2 files changed, 54 insertions(+), 33 deletions(-) diff --git a/ci/cppcheck-misra.sh b/ci/cppcheck-misra.sh index 2df95340..96e0c9cd 100755 --- a/ci/cppcheck-misra.sh +++ b/ci/cppcheck-misra.sh @@ -7,23 +7,29 @@ # $ ci/cppcheck-misra.sh # -echo -e "\u001b[34;1mRunning cppcheck with MISRA C(2012) rule compliance tests...\u001b[0m" - +echo -e "\u001b[34;1mGetting prerequisites...\u001b[0m" # grab the MISRA addon and the cppcheck addon interface from github -curl https://raw.githubusercontent.com/danmar/cppcheck/f4b5b156d720c712f6ce99f6e01d8c1b3f800d52/addons/misra.py > misra.py -curl https://raw.githubusercontent.com/danmar/cppcheck/f4b5b156d720c712f6ce99f6e01d8c1b3f800d52/addons/cppcheckdata.py > cppcheckdata.py +curl https://raw.githubusercontent.com/danmar/cppcheck/f4b5b156d720c712f6ce99f6e01d8c1b3f800d52/addons/misra.py > ci/misra.py +curl https://raw.githubusercontent.com/danmar/cppcheck/f4b5b156d720c712f6ce99f6e01d8c1b3f800d52/addons/cppcheckdata.py > ci/cppcheckdata.py # 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 # 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 misra.py $file >> ci/report.msr 2>&1 + python ci/misra.py $file >> ci/report.msr 2>&1 done # pre-process the generated report to remove all useless strings +echo -e "\u001b[34;1mPre-processing report...\u001b[0m" sed -i -r 's/(.*Script.*)|(.*Checking.*)|(.*MISRA.*)//gm; /(^$)/d; s/(\s\(.*\)\s)//gm; s/(\]|\[)//gm; s/(misra-c2012-)//gm' ci/report.msr + +# 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 diff --git a/ci/summarizer.py b/ci/summarizer.py index 68e62dc5..17c2ffdc 100755 --- a/ci/summarizer.py +++ b/ci/summarizer.py @@ -1,51 +1,66 @@ -#!/bin/env python3 +#!/bin/env python from sys import argv +from sys import exit from collections import Counter -script, reportfile = argv +''' +Naive parser and pretty printer for the MISRA reports by cppcheck +''' +script, reportfile = argv def analyze(): - errorsMap = {} + ''' + 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) - linesSeen = set() + cppcheckNumOfErrors = len(fileLines) # number of errors in the original report (most of these are duplicates) + linesSeen = set() # contains the unique lines from the file - for line in fileLines: # remove duplicate lines - if line not in linesSeen: - linesSeen.add(line) + 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) - for line in linesSeen: - lineContents = line.split(':') - fileName = lineContents[0] - error = (lineContents[1], lineContents[2].strip('\n')) - - if fileName not in errorsMap.keys(): - errorsMap[fileName] = list() - errorsMap[fileName].append(error) - else: - errorsMap[fileName].append(error) + 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 + + 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 - return errorsMap + return errorsMap # return the completed error dictionary + 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("\033[1m=================================================\033[0m\n") - -if __name__ == "__main__": +def run(): errors = analyze() - if len(errors) == 0: - print("\033[1m\033[92mStatic analysis for MISRA compliance complete. No errors found.") - exit(0) - else: + if isinstance(errors, dict): prettyprint(errors) - exit(1) - + exit(127) + elif isinstance(errors, int) and errors == 0: + exit(0) + + +if __name__ == "__main__": + run() -- GitLab