From 690529637a0167dd8101347d7ec64faba36b2be0 Mon Sep 17 00:00:00 2001 From: adbancroft <13982343+adbancroft@users.noreply.github.com> Date: Sun, 24 Jan 2021 16:56:37 -0600 Subject: [PATCH] refactor: parameterize the MISRA checking script (#507) * refactor: parameterize the MISRA checking script The script contained hardcoded paths, which made it difficult to use as part of the development workflow. * ci!: use script relative path to pick source folder * ci!: default output folder within source tree * refactor: have cppcheck run the misra script * refactor: use "rm -f" - remove existence check * refactor: encapsulate into functions * ci!: merge git MISRA logic into check_misra.sh * ci!: count true errors, not style violations * ci: use common MISRA check script Co-authored-by: adbancroft --- .gitignore | 1 + azure-pipelines.yml | 4 +- misra/check_misra.sh | 87 +++++++++++++++++++++++++++++-------- misra/check_misra_github.sh | 38 ---------------- misra/misra.json | 1 + 5 files changed, 74 insertions(+), 57 deletions(-) delete mode 100755 misra/check_misra_github.sh create mode 100644 misra/misra.json diff --git a/.gitignore b/.gitignore index 1769ffe9..d53df6f7 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ speeduino/board_samd21* reference/doxygen speeduino.ino.cpp test/output_export.cpp +misra/.results diff --git a/azure-pipelines.yml b/azure-pipelines.yml index f0a283e7..d560c5d3 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -25,8 +25,8 @@ steps: displayName: 'Making cppcheck' - bash: | cd noisymime - chmod +x speeduino/misra/check_misra_github.sh - speeduino/misra/check_misra_github.sh + chmod +x speeduino/misra/check_misra.sh + speeduino/misra/check_misra.sh -c "cppcheck_github" #This task is always an error if there are MISRA violations continueOnError: true displayName: 'Running Scan' diff --git a/misra/check_misra.sh b/misra/check_misra.sh index c04c54cb..ef9ca1e0 100755 --- a/misra/check_misra.sh +++ b/misra/check_misra.sh @@ -1,25 +1,78 @@ -if [ -f ./results.txt ]; then - rm results.txt -fi +#!/bin/bash -for i in speeduino/speeduino/*.ino; do - #cppcheck --xml --include=${i%.*}.h --include=speeduino/speeduino/globals.h $i > /dev/null - #cppcheck --force --dump --suppress=syntaxError:speeduino/speeduino/src/PID_v1/PID_v1.h --include=${i%.*}.h --include=speeduino/speeduino/globals.h -DCORE_AVR=1 -USTM32F4 $i > /dev/null - cppcheck --dump --suppress=syntaxError:speeduino/speeduino/src/PID_v1/PID_v1.h --include=${i%.*}.h -DCORE_AVR=1 -D__AVR_ATmega2560__ $i > /dev/null -done -mv speeduino/speeduino/*.dump ./ -rm ./utils.*.dump +script_folder="$(dirname $(readlink -f $0))" -python cppcheck/addons/misra.py --rule-texts=speeduino/misra/misra_2012_text.txt *.dump 2> results.txt -rm *.dump +# Initialize variables with defaults +source_folder="$script_folder/../speeduino" # -s, --source +file_exts="ino" # -e, --exts +out_folder="$script_folder/.results" # -o, --out +cppcheck_path="" # -c, --cppcheck -cat results.txt -# wc -l results.txt +function parse_command_line() { + while [ $# -gt 0 ] ; do + case "$1" in + -s | --source) source_folder="$2" ;; + -e | --exts) file_exts="$2" ;; + -o | --out) out_folder="$2" ;; + -c | --cppcheck) cppcheck_path="$2" ;; + -*) + echo "Unknown option: " $1 + exit 1 + ;; + esac + shift + done +} -errors=`wc -l < results.txt | tr -d ' '` -echo $errors MISRA violations +function run_cppcheck() { + shopt -s nullglob nocaseglob + for i in "$source_folder"/*.{"$file_exts",}; do + "$cppcheck_bin" \ + --inline-suppr \ + --language=c++ \ + --addon="$script_folder/misra.json" \ + --suppressions-list="$script_folder/suppressions.txt" \ + -DCORE_AVR=1 \ + -D__AVR_ATmega2560__ \ + $i 2>> "$cpp_result_file" + done + shopt -u nullglob nocaseglob +} -if [ $errors -gt 0 ]; then +function process_cpp_results() { + local intermediate_file="$out_folder/tmp.txt" + + # It's grouped into chunks of 3 lines: fold those into one line + sed '$!N;$!N;s/\n/~/g' < "$cpp_result_file" |\ + # Remove duplicate lines + sort | uniq > "$intermediate_file" + # Count error lines + local __error_count=`grep ": error:" < "$intermediate_file" | wc -l` + # Unfold the line groups for readability + tr '~' '\n' < "$intermediate_file" > "$result_file" + rm -f "$intermediate_file" + + echo "$__error_count" +} + +parse_command_line "$@" + +cppcheck_bin="${cppcheck_path}/cppcheck" +cppcheck_misra="${cppcheck_path}/addons/misra.py" +cpp_result_file="$out_folder/cpp_results.txt" +result_file="$out_folder/results.txt" + +mkdir -p "$out_folder" +rm -f "$cpp_result_file" +rm -f "$result_file" + +run_cppcheck +error_count="$(process_cpp_results)" + +cat "$result_file" +echo $error_count MISRA violations + +if [ $error_count -gt 0 ]; then exit 1 else exit 0 diff --git a/misra/check_misra_github.sh b/misra/check_misra_github.sh deleted file mode 100755 index 7e74a8e6..00000000 --- a/misra/check_misra_github.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -cppcheck_path=cppcheck_github/ -cppcheck_bin="${cppcheck_path}cppcheck" -cppcheck_misra="${cppcheck_path}addons/misra.py" - -#Uncomment below to use the Brew installation of cppcheck on Mac -#cppcheck_path_brew=/usr/local/Cellar/cppcheck/2.1/share/cppcheck/ -#cppcheck_misra="${cppcheck_path_brew}addons/misra.py" -#cppcheck_bin=/usr/local/Cellar/cppcheck/2.1/bin/cppcheck - - - -if [ -f ./results.txt ]; then - rm results.txt -fi - -for i in speeduino/speeduino/*.ino; do - $cppcheck_bin --dump --max-configs=1 --inline-suppr --suppressions-list=speeduino/misra/suppressions.txt --language=c++ --include=${i%.*}.h -DCORE_AVR=1 -D__AVR_ATmega2560__=1 $i > /dev/null -done - -mv speeduino/speeduino/*.dump ./ -rm ./utils.*.dump - -python $cppcheck_misra --rule-texts=speeduino/misra/misra_2012_text.txt *.dump 2> results.txt -#rm *.dump - -sort results.txt | uniq -# wc -l results.txt - -errors=`sort results.txt | uniq | wc -l` -echo $errors MISRA violations - -if [ $errors -gt 0 ]; then - exit 1 -else - exit 0 -fi diff --git a/misra/misra.json b/misra/misra.json new file mode 100644 index 00000000..3905a3cc --- /dev/null +++ b/misra/misra.json @@ -0,0 +1 @@ +{"script": "misra.py","args": ["--rule-texts=./misra_2012_text.txt"]} \ No newline at end of file