mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-08-09 00:56:08 +00:00
The current implementation of continuous run operation using command `./scripts/coccicheck` i.e., without specifying any options, `coccicheck` default runs in `report` mode with all available coccinelle scripts present at `scripts/coccinelle/`. Not all scripts have report mode implemented in them, which leads to failure of coccicheck. With this new implementation we choose whatever available mode is present in coccinelle script and pass it to MODE variable without stopping continuous coverage. And perhaps if there are plans to add `coccicheck` as a sanity checker in future to the Zephyr automated CI, then certainly we want the warnings/errors produced by scripts to be less verbose to the users. Therefore, in this new implementation we prioritise the modes as: 1. report 2. context 3. patch and lastly falling to 4. org Lastly, in order to differentiate between outputs of various coccinelle scripts being run, `x------x` separator has been used to make reports mode readable. Signed-off-by: Himanshu Jha <himanshujha199640@gmail.com>
236 lines
6.0 KiB
Bash
Executable File
236 lines
6.0 KiB
Bash
Executable File
#!/bin/bash
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
#
|
|
# Read doc/application/coccinelle.rst
|
|
#
|
|
|
|
ZEPHYR_BASE=$( builtin cd "$( dirname "$DIR" )" && pwd ${PWD_OPT})
|
|
DIR="$(dirname $(readlink -f $0))/.."
|
|
SPATCH="`which ${SPATCH:=spatch}`"
|
|
|
|
if [ ! -x "$SPATCH" ]; then
|
|
echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/'
|
|
exit 1
|
|
fi
|
|
|
|
VERBOSE=0
|
|
usage="Usage: ./scripts/coccicheck [OPTIONS]... [DIRECTORY|FILE]...
|
|
|
|
OPTIONS:
|
|
-------
|
|
|
|
-m= , --mode= specify the mode use {report, patch, org, context, chain}
|
|
-v= , --verbose= enable verbose output {1}
|
|
-j= , --jobs= number of jobs to use {0 - `nproc`}
|
|
-c= , --cocci= specify cocci script to use
|
|
-d= , --debug= specify file to store debug log
|
|
-h , --help display help and exit
|
|
|
|
Default values if any OPTION is not supplied:
|
|
--------------------------------------------
|
|
|
|
mode = report
|
|
verbose = 0 (disabled)
|
|
jobs = maximum jobs available on the machine
|
|
cocci = all cocci scripts available at scripts/coccinelle/*
|
|
|
|
If no [DIRECTORY|FILE] is supplied, entire codebase is processed.
|
|
|
|
For detailed documentation refer: doc/application/coccinelle.rst"
|
|
|
|
for i in "$@"
|
|
do
|
|
case $i in
|
|
-m=*|--mode=*)
|
|
MODE="${i#*=}"
|
|
shift # past argument=value
|
|
;;
|
|
-v=*|--verbose=*)
|
|
VERBOSE="${i#*=}"
|
|
shift # past argument=value
|
|
;;
|
|
-j=*|--jobs=*)
|
|
J="${i#*=}"
|
|
shift
|
|
;;
|
|
-c=*|--cocci=*)
|
|
COCCI="${i#*=}"
|
|
shift
|
|
;;
|
|
-d=*|--debug=*)
|
|
DEBUG_FILE="${i#*=}"
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
echo "$usage"
|
|
exit 1
|
|
;;
|
|
*)
|
|
FILE="${i#*=}"
|
|
if [ ! -e "$FILE" ]; then
|
|
echo "unknown option: '${i#*=}'"
|
|
echo "$usage"
|
|
exit 2
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
|
|
FLAGS="--very-quiet"
|
|
|
|
if [ "$FILE" = "" ] ; then
|
|
OPTIONS="--dir $ZEPHYR_BASE"
|
|
else
|
|
OPTIONS="--dir $FILE"
|
|
fi
|
|
|
|
if [ -z "$J" ]; then
|
|
NPROC=$(getconf _NPROCESSORS_ONLN)
|
|
else
|
|
NPROC="$J"
|
|
fi
|
|
|
|
if [ "$FILE" != "" ] ; then
|
|
OPTIONS="--patch $ZEPHYR_BASE $OPTIONS"
|
|
fi
|
|
|
|
if [ "$NPROC" != "1" ]; then
|
|
# Using 0 should work as well, refer to _SC_NPROCESSORS_ONLN use on
|
|
# https://github.com/rdicosmo/parmap/blob/master/setcore_stubs.c
|
|
OPTIONS="$OPTIONS --jobs $NPROC --chunksize 1"
|
|
fi
|
|
|
|
if [ "$MODE" = "" ] ; then
|
|
echo 'You have not explicitly specified the mode to use. Using default "report" mode.'
|
|
echo 'Available modes are the following: 'patch', 'report', 'context', 'org''
|
|
echo 'You can specify the mode with "./scripts/coccicheck --mode=<mode>"'
|
|
echo 'Note however that some modes are not implemented by some semantic patches.'
|
|
MODE="report"
|
|
fi
|
|
|
|
if [ "$MODE" = "chain" ] ; then
|
|
echo 'You have selected the "chain" mode.'
|
|
echo 'All available modes will be tried (in that order): patch, report, context, org'
|
|
elif [ "$MODE" = "report" -o "$MODE" = "org" ] ; then
|
|
FLAGS="--no-show-diff $FLAGS"
|
|
fi
|
|
|
|
echo ''
|
|
echo 'Please check for false positives in the output before submitting a patch.'
|
|
echo 'When using "patch" mode, carefully review the patch before submitting it.'
|
|
echo ''
|
|
|
|
run_cmd_parmap() {
|
|
if [ $VERBOSE -ne 0 ] ; then
|
|
echo "Running ($NPROC in parallel): $@"
|
|
fi
|
|
echo $@ >>$DEBUG_FILE
|
|
$@ 2>>$DEBUG_FILE
|
|
err=$?
|
|
if [[ $err -ne 0 ]]; then
|
|
echo "coccicheck failed"
|
|
exit $err
|
|
fi
|
|
}
|
|
|
|
coccinelle () {
|
|
COCCI="$1"
|
|
OPT=`grep "Options:" $COCCI | cut -d':' -f2`
|
|
VIRTUAL=`grep "virtual" $COCCI | cut -d' ' -f2`
|
|
|
|
if [[ $VIRTUAL = "" ]]; then
|
|
echo "No available modes found in \"$COCCI\" script."
|
|
echo "Consider adding vitrual rules to the script."
|
|
exit 1
|
|
elif [[ $VIRTUAL != *"$MODE"* ]]; then
|
|
echo "Invalid mode \"$MODE\" supplied!"
|
|
echo "Available modes for \"`basename $COCCI`\" are: "$VIRTUAL""
|
|
|
|
if [[ $VIRTUAL == *report* ]]; then
|
|
MODE=report
|
|
elif [[ $VIRTUAL == *context* ]]; then
|
|
MODE=context
|
|
elif [[ $VIRTUAL == *patch* ]]; then
|
|
MODE=patch
|
|
else
|
|
MODE=org
|
|
fi
|
|
echo "Using random availble mode: \"$MODE\""
|
|
echo ''
|
|
fi
|
|
|
|
if [ $VERBOSE -ne 0 ] ; then
|
|
|
|
FILE=${COCCI#$ZEPHYR_BASE/}
|
|
|
|
echo "Processing `basename $COCCI`"
|
|
echo "with option(s) \"$OPT\""
|
|
echo ''
|
|
echo 'Message example to submit a patch:'
|
|
|
|
sed -ne 's|^///||p' $COCCI
|
|
|
|
if [ "$MODE" = "patch" ] ; then
|
|
echo ' The semantic patch that makes this change is available'
|
|
elif [ "$MODE" = "report" ] ; then
|
|
echo ' The semantic patch that makes this report is available'
|
|
elif [ "$MODE" = "context" ] ; then
|
|
echo ' The semantic patch that spots this code is available'
|
|
elif [ "$MODE" = "org" ] ; then
|
|
echo ' The semantic patch that makes this Org report is available'
|
|
else
|
|
echo ' The semantic patch that makes this output is available'
|
|
fi
|
|
echo " in $FILE."
|
|
echo ''
|
|
echo ' More information about semantic patching is available at'
|
|
echo ' http://coccinelle.lip6.fr/'
|
|
echo ''
|
|
|
|
if [ "`sed -ne 's|^//#||p' $COCCI`" ] ; then
|
|
echo 'Semantic patch information:'
|
|
sed -ne 's|^//#||p' $COCCI
|
|
echo ''
|
|
fi
|
|
fi
|
|
|
|
if [ "$MODE" = "chain" ] ; then
|
|
run_cmd_parmap $SPATCH -D patch \
|
|
$FLAGS --cocci-file $COCCI $OPT $OPTIONS || \
|
|
run_cmd_parmap $SPATCH -D report \
|
|
$FLAGS --cocci-file $COCCI $OPT $OPTIONS --no-show-diff || \
|
|
run_cmd_parmap $SPATCH -D context \
|
|
$FLAGS --cocci-file $COCCI $OPT $OPTIONS || \
|
|
run_cmd_parmap $SPATCH -D org \
|
|
$FLAGS --cocci-file $COCCI $OPT $OPTIONS --no-show-diff || exit 1
|
|
elif [ "$MODE" = "rep+ctxt" ] ; then
|
|
run_cmd_parmap $SPATCH -D report \
|
|
$FLAGS --cocci-file $COCCI $OPT $OPTIONS --no-show-diff && \
|
|
run_cmd_parmap $SPATCH -D context \
|
|
$FLAGS --cocci-file $COCCI $OPT $OPTIONS || exit 1
|
|
else
|
|
run_cmd_parmap $SPATCH -D $MODE $FLAGS --cocci-file $COCCI $OPT $OPTIONS || exit 1
|
|
fi
|
|
|
|
MODE=report
|
|
}
|
|
|
|
if [ "$DEBUG_FILE" != "/dev/null" -a "$DEBUG_FILE" != "" ]; then
|
|
if [ -f $DEBUG_FILE ]; then
|
|
echo "Debug file \"$DEBUG_FILE\" exists, bailing ..."
|
|
exit
|
|
fi
|
|
else
|
|
DEBUG_FILE="/dev/null"
|
|
fi
|
|
|
|
if [ "$COCCI" = "" ] ; then
|
|
for f in `find $ZEPHYR_BASE/scripts/coccinelle/ -name '*.cocci' -type f | sort`; do
|
|
coccinelle $f
|
|
echo '-------------------------------------------------------------------------'
|
|
echo ''
|
|
done
|
|
else
|
|
coccinelle $COCCI
|
|
fi
|