MISRA check: add XML output (#967)
* MISRA check: add XML output * Improve handling of cppcheck output * Simplify - make cppcheck do more work Now need for the script to gather source files and run them one at a time, or flatten xml etc. * Define the byte type - flushes out violations. * Precaution: apply dos2unix before invoking shell script * Restore force rename of libdivide folder Scans on Windows Git Bash were taking way too long. * Performance: run as many cppcheck jobs as possible Logical CPU count - 1 * Set the build dir Prevents temp files being left in the source tree
This commit is contained in:
parent
b30fde5685
commit
8888e06e7f
|
@ -30,6 +30,7 @@ jobs:
|
|||
cd $GITHUB_WORKSPACE/misra/
|
||||
mkdir .results
|
||||
chmod +x check_misra.sh
|
||||
dos2unix check_misra.sh
|
||||
./check_misra.sh -c /usr/bin -o ./.results -q
|
||||
echo "Scan complete"
|
||||
NumViolations=`cat .results/error_count.txt`
|
||||
|
|
|
@ -4,19 +4,19 @@ script_folder="$(dirname $(readlink -f $0))"
|
|||
|
||||
# Initialize variables with defaults
|
||||
source_folder="$script_folder/../speeduino" # -s, --source
|
||||
file_exts="cpp,ino" # -e, --exts
|
||||
out_folder="$script_folder/.results" # -o, --out
|
||||
cppcheck_path="" # -c, --cppcheck
|
||||
quiet=0 # -q, --quiet
|
||||
output_xml=0 # -x, --xml
|
||||
|
||||
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" ;;
|
||||
-q | --quiet) quiet=1 ;;
|
||||
-x | --xml) output_xml=1 ;;
|
||||
-*)
|
||||
echo "Unknown option: " $1
|
||||
exit 1
|
||||
|
@ -26,67 +26,62 @@ function parse_command_line() {
|
|||
done
|
||||
}
|
||||
|
||||
function run_cppcheck() {
|
||||
# There is no way to tell the misra add on to skip certain headers
|
||||
# libdivide adds many 10+ minutes to each file so rename the folder
|
||||
# before the scan
|
||||
mv "$source_folder"/src/libdivide "$source_folder"/src/_libdivide
|
||||
shopt -s nullglob nocaseglob
|
||||
for ext in ${file_exts//,/ }; do
|
||||
for i in "$source_folder"/*."$ext"; do
|
||||
# All violations from included libraries (*src* folders) are ignored
|
||||
"$cppcheck_bin" \
|
||||
--inline-suppr \
|
||||
--language=c++ \
|
||||
--addon="$script_folder/misra.json" \
|
||||
--suppressions-list="$script_folder/suppressions.txt" \
|
||||
--platform=avr8 \
|
||||
-DCORE_AVR=1 \
|
||||
-D__AVR_ATmega2560__ \
|
||||
--suppress="*:*src*" \
|
||||
--report-progress \
|
||||
$i 2>> "$cpp_result_file"
|
||||
done
|
||||
done
|
||||
shopt -u nullglob nocaseglob
|
||||
# Restore libdivide folder name after scan
|
||||
mv "$source_folder"/src/_libdivide "$source_folder"/src/libdivide
|
||||
}
|
||||
|
||||
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 lines for Mandatory or Required rules
|
||||
local __error_count=`grep -i "Mandatory\|Required" < "$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"
|
||||
|
||||
num_cores=`getconf _NPROCESSORS_ONLN`
|
||||
let num_cores--
|
||||
|
||||
mkdir -p "$out_folder"
|
||||
rm -f "$cpp_result_file"
|
||||
rm -f "$result_file"
|
||||
|
||||
run_cppcheck
|
||||
error_count="$(process_cpp_results)"
|
||||
cppcheck_parameters=( --inline-suppr
|
||||
--language=c++
|
||||
--addon="$script_folder/misra.json"
|
||||
--suppressions-list="$script_folder/suppressions.txt"
|
||||
--platform=avr8
|
||||
--cppcheck-build-dir="$out_folder"
|
||||
-j "$num_cores"
|
||||
-DCORE_AVR=1
|
||||
-D__AVR_ATmega2560__
|
||||
# This is defined in the AVR headers, which aren't included.
|
||||
# cppcheck will not do type checking on unknown types.
|
||||
# It's used a lot and it's unsigned, which can trigger a lot
|
||||
# of type mismatch violations.
|
||||
-Dbyte=uint8_t
|
||||
# All violations from included libraries (*src* folders) are ignored
|
||||
--suppress="*:*src*"
|
||||
# No libdivide - analysis takes too long
|
||||
-UUSE_LIBDIVIDE
|
||||
# Don't parse the /src folder
|
||||
-i "$source_folder/src"
|
||||
"$source_folder/**.ino"
|
||||
"$source_folder/**.cpp")
|
||||
|
||||
cppcheck_out_file="$out_folder/results.txt"
|
||||
if [ $output_xml -eq 1 ]; then
|
||||
cppcheck_out_file="$out_folder/results.xml"
|
||||
cppcheck_parameters+=(--xml)
|
||||
fi
|
||||
|
||||
# There is no way to tell the misra add on to skip certain headers
|
||||
# libdivide adds 10+ minutes to each file so rename the folder
|
||||
# before the scan
|
||||
mv "$source_folder"/src/libdivide "$source_folder"/src/_libdivide
|
||||
|
||||
"$cppcheck_bin" ${cppcheck_parameters[@]} 2> $cppcheck_out_file
|
||||
|
||||
# Restore libdivide folder name after scan
|
||||
mv "$source_folder"/src/_libdivide "$source_folder"/src/libdivide
|
||||
|
||||
# Count lines for Mandatory or Required rules
|
||||
error_count=`grep -i "Mandatory - \|Required - " < "$cppcheck_out_file" | wc -l`
|
||||
|
||||
if [ $quiet -eq 0 ]; then
|
||||
cat "$result_file"
|
||||
cat "$cppcheck_out_file"
|
||||
fi
|
||||
echo $error_count MISRA violations
|
||||
echo $error_count > ".results/error_count.txt"
|
||||
echo $error_count > "$out_folder/error_count.txt"
|
||||
|
||||
exit 0
|
Loading…
Reference in New Issue