0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 DIR="$(dirname $(readlink -f $0))/.."
0011 SPATCH="`which ${SPATCH:=spatch}`"
0012
0013 if [ ! -x "$SPATCH" ]; then
0014 echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/'
0015 exit 1
0016 fi
0017
0018 SPATCH_VERSION=$($SPATCH --version | head -1 | awk '{print $3}')
0019
0020 USE_JOBS="no"
0021 $SPATCH --help | grep "\-\-jobs" > /dev/null && USE_JOBS="yes"
0022
0023
0024
0025
0026 if [ -n "$V" -a "$V" != "0" ]; then
0027 VERBOSE="$V"
0028 else
0029 VERBOSE=0
0030 fi
0031
0032 FLAGS="--very-quiet"
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 echo $SPFLAGS | egrep -e "--profile|--show-trying" 2>&1 > /dev/null
0051 if [ $? -eq 0 ]; then
0052 FLAGS="--quiet"
0053 fi
0054
0055
0056
0057 COCCIINCLUDE=${LINUXINCLUDE//-I/-I }
0058 COCCIINCLUDE=${COCCIINCLUDE// -include/ --include}
0059
0060 if [ "$C" = "1" -o "$C" = "2" ]; then
0061 ONLINE=1
0062
0063 if [[ $
0064 echo ''
0065 echo 'Specifying both the variable "C" and rule "coccicheck" in the make
0066 command results in a shift count error.'
0067 echo ''
0068 echo 'Try specifying "scripts/coccicheck" as a value for the CHECK variable instead.'
0069 echo ''
0070 echo 'Example: make C=2 CHECK=scripts/coccicheck drivers/net/ethernet/ethoc.o'
0071 echo ''
0072 exit 1
0073 fi
0074
0075
0076 shift $(( $
0077 OPTIONS="$COCCIINCLUDE $1"
0078
0079
0080 NPROC=1
0081 else
0082 ONLINE=0
0083 if [ "$KBUILD_EXTMOD" = "" ] ; then
0084 OPTIONS="--dir $srctree $COCCIINCLUDE"
0085 else
0086 OPTIONS="--dir $KBUILD_EXTMOD $COCCIINCLUDE"
0087 fi
0088
0089
0090 THREADS_PER_CORE=$(LANG=C lscpu | grep "Thread(s) per core: " | tr -cd "[:digit:]")
0091 if [ -z "$J" ]; then
0092 NPROC=$(getconf _NPROCESSORS_ONLN)
0093 if [ $THREADS_PER_CORE -gt 1 -a $NPROC -gt 4 ] ; then
0094 NPROC=$((NPROC/2))
0095 fi
0096 else
0097 NPROC="$J"
0098 fi
0099 fi
0100
0101 if [ "$KBUILD_EXTMOD" != "" ] ; then
0102 OPTIONS="--patch $srctree $OPTIONS"
0103 fi
0104
0105
0106 if [ "$USE_JOBS" = "no" ]; then
0107 trap kill_running SIGTERM SIGINT
0108 declare -a SPATCH_PID
0109 elif [ "$NPROC" != "1" ]; then
0110
0111
0112 OPTIONS="$OPTIONS --jobs $NPROC --chunksize 1"
0113 fi
0114
0115 if [ "$MODE" = "" ] ; then
0116 if [ "$ONLINE" = "0" ] ; then
0117 echo 'You have not explicitly specified the mode to use. Using default "report" mode.'
0118 echo 'Available modes are the following: patch, report, context, org, chain'
0119 echo 'You can specify the mode with "make coccicheck MODE=<mode>"'
0120 echo 'Note however that some modes are not implemented by some semantic patches.'
0121 fi
0122 MODE="report"
0123 fi
0124
0125 if [ "$MODE" = "chain" ] ; then
0126 if [ "$ONLINE" = "0" ] ; then
0127 echo 'You have selected the "chain" mode.'
0128 echo 'All available modes will be tried (in that order): patch, report, context, org'
0129 fi
0130 elif [ "$MODE" = "report" -o "$MODE" = "org" ] ; then
0131 FLAGS="--no-show-diff $FLAGS"
0132 fi
0133
0134 if [ "$ONLINE" = "0" ] ; then
0135 echo ''
0136 echo 'Please check for false positives in the output before submitting a patch.'
0137 echo 'When using "patch" mode, carefully review the patch before submitting it.'
0138 echo ''
0139 fi
0140
0141 run_cmd_parmap() {
0142 if [ $VERBOSE -ne 0 ] ; then
0143 echo "Running ($NPROC in parallel): $@"
0144 fi
0145 if [ "$DEBUG_FILE" != "/dev/null" -a "$DEBUG_FILE" != "" ]; then
0146 echo $@>>$DEBUG_FILE
0147 $@ 2>>$DEBUG_FILE
0148 else
0149 echo $@
0150 $@ 2>&1
0151 fi
0152
0153 err=$?
0154 if [[ $err -ne 0 ]]; then
0155 echo "coccicheck failed"
0156 exit $err
0157 fi
0158 }
0159
0160 run_cmd_old() {
0161 local i
0162 if [ $VERBOSE -ne 0 ] ; then
0163 echo "Running ($NPROC in parallel): $@"
0164 fi
0165 for i in $(seq 0 $(( NPROC - 1)) ); do
0166 eval "$@ --max $NPROC --index $i &"
0167 SPATCH_PID[$i]=$!
0168 if [ $VERBOSE -eq 2 ] ; then
0169 echo "${SPATCH_PID[$i]} running"
0170 fi
0171 done
0172 wait
0173 }
0174
0175 run_cmd() {
0176 if [ "$USE_JOBS" = "yes" ]; then
0177 run_cmd_parmap $@
0178 else
0179 run_cmd_old $@
0180 fi
0181 }
0182
0183 kill_running() {
0184 for i in $(seq 0 $(( NPROC - 1 )) ); do
0185 if [ $VERBOSE -eq 2 ] ; then
0186 echo "Killing ${SPATCH_PID[$i]}"
0187 fi
0188 kill ${SPATCH_PID[$i]} 2>/dev/null
0189 done
0190 }
0191
0192
0193 OPTIONS="$OPTIONS $SPFLAGS"
0194
0195 coccinelle () {
0196 COCCI="$1"
0197
0198 OPT=`grep "Options:" $COCCI | cut -d':' -f2`
0199 REQ=`grep "Requires:" $COCCI | cut -d':' -f2 | sed "s| ||"`
0200 if [ -n "$REQ" ] && ! { echo "$REQ"; echo "$SPATCH_VERSION"; } | sort -CV ; then
0201 echo "Skipping coccinelle SmPL patch: $COCCI"
0202 echo "You have coccinelle: $SPATCH_VERSION"
0203 echo "This SmPL patch requires: $REQ"
0204 return
0205 fi
0206
0207
0208
0209
0210
0211 if [ $VERBOSE -ne 0 -a $ONLINE -eq 0 ] ; then
0212
0213 FILE=${COCCI
0214
0215 echo "Processing `basename $COCCI`"
0216 echo "with option(s) \"$OPT\""
0217 echo ''
0218 echo 'Message example to submit a patch:'
0219
0220 sed -ne 's|^///||p' $COCCI
0221
0222 if [ "$MODE" = "patch" ] ; then
0223 echo ' The semantic patch that makes this change is available'
0224 elif [ "$MODE" = "report" ] ; then
0225 echo ' The semantic patch that makes this report is available'
0226 elif [ "$MODE" = "context" ] ; then
0227 echo ' The semantic patch that spots this code is available'
0228 elif [ "$MODE" = "org" ] ; then
0229 echo ' The semantic patch that makes this Org report is available'
0230 else
0231 echo ' The semantic patch that makes this output is available'
0232 fi
0233 echo " in $FILE."
0234 echo ''
0235 echo ' More information about semantic patching is available at'
0236 echo ' http://coccinelle.lip6.fr/'
0237 echo ''
0238
0239 if [ "`sed -ne 's|^//#||p' $COCCI`" ] ; then
0240 echo 'Semantic patch information:'
0241 sed -ne 's|^//#||p' $COCCI
0242 echo ''
0243 fi
0244 fi
0245
0246 if [ "$MODE" = "chain" ] ; then
0247 run_cmd $SPATCH -D patch \
0248 $FLAGS --cocci-file $COCCI $OPT $OPTIONS || \
0249 run_cmd $SPATCH -D report \
0250 $FLAGS --cocci-file $COCCI $OPT $OPTIONS --no-show-diff || \
0251 run_cmd $SPATCH -D context \
0252 $FLAGS --cocci-file $COCCI $OPT $OPTIONS || \
0253 run_cmd $SPATCH -D org \
0254 $FLAGS --cocci-file $COCCI $OPT $OPTIONS --no-show-diff || exit 1
0255 elif [ "$MODE" = "rep+ctxt" ] ; then
0256 run_cmd $SPATCH -D report \
0257 $FLAGS --cocci-file $COCCI $OPT $OPTIONS --no-show-diff && \
0258 run_cmd $SPATCH -D context \
0259 $FLAGS --cocci-file $COCCI $OPT $OPTIONS || exit 1
0260 else
0261 run_cmd $SPATCH -D $MODE $FLAGS --cocci-file $COCCI $OPT $OPTIONS || exit 1
0262 fi
0263
0264 }
0265
0266 if [ "$DEBUG_FILE" != "/dev/null" -a "$DEBUG_FILE" != "" ]; then
0267 if [ -f $DEBUG_FILE ]; then
0268 echo "Debug file $DEBUG_FILE exists, bailing"
0269 exit
0270 fi
0271 else
0272 DEBUG_FILE="/dev/null"
0273 fi
0274
0275 if [ "$COCCI" = "" ] ; then
0276 for f in `find $srctree/scripts/coccinelle/ -name '*.cocci' -type f | sort`; do
0277 coccinelle $f
0278 done
0279 else
0280 coccinelle $COCCI
0281 fi