coccicheck 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #!/bin/bash
  2. #
  3. # This script requires at least spatch
  4. # version 1.0.0-rc11.
  5. #
  6. SPATCH="`which ${SPATCH:=spatch}`"
  7. trap kill_running SIGTERM SIGINT
  8. declare -a SPATCH_PID
  9. # The verbosity may be set by the environmental parameter V=
  10. # as for example with 'make V=1 coccicheck'
  11. if [ -n "$V" -a "$V" != "0" ]; then
  12. VERBOSE="$V"
  13. else
  14. VERBOSE=0
  15. fi
  16. if [ -z "$J" ]; then
  17. NPROC=$(getconf _NPROCESSORS_ONLN)
  18. else
  19. NPROC="$J"
  20. fi
  21. FLAGS="$SPFLAGS --very-quiet"
  22. # spatch only allows include directories with the syntax "-I include"
  23. # while gcc also allows "-Iinclude" and "-include include"
  24. COCCIINCLUDE=${LINUXINCLUDE//-I/-I }
  25. COCCIINCLUDE=${COCCIINCLUDE//-include/-I}
  26. if [ "$C" = "1" -o "$C" = "2" ]; then
  27. ONLINE=1
  28. # Take only the last argument, which is the C file to test
  29. shift $(( $# - 1 ))
  30. OPTIONS="$COCCIINCLUDE $1"
  31. else
  32. ONLINE=0
  33. if [ "$KBUILD_EXTMOD" = "" ] ; then
  34. OPTIONS="--dir $srctree $COCCIINCLUDE"
  35. else
  36. OPTIONS="--dir $KBUILD_EXTMOD $COCCIINCLUDE"
  37. fi
  38. fi
  39. if [ "$KBUILD_EXTMOD" != "" ] ; then
  40. OPTIONS="--patch $srctree $OPTIONS"
  41. fi
  42. if [ ! -x "$SPATCH" ]; then
  43. echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/'
  44. exit 1
  45. fi
  46. if [ "$MODE" = "" ] ; then
  47. if [ "$ONLINE" = "0" ] ; then
  48. echo 'You have not explicitly specified the mode to use. Using default "report" mode.'
  49. echo 'Available modes are the following: patch, report, context, org'
  50. echo 'You can specify the mode with "make coccicheck MODE=<mode>"'
  51. echo 'Note however that some modes are not implemented by some semantic patches.'
  52. fi
  53. MODE="report"
  54. fi
  55. if [ "$MODE" = "chain" ] ; then
  56. if [ "$ONLINE" = "0" ] ; then
  57. echo 'You have selected the "chain" mode.'
  58. echo 'All available modes will be tried (in that order): patch, report, context, org'
  59. fi
  60. elif [ "$MODE" = "report" -o "$MODE" = "org" ] ; then
  61. FLAGS="$FLAGS --no-show-diff"
  62. fi
  63. if [ "$ONLINE" = "0" ] ; then
  64. echo ''
  65. echo 'Please check for false positives in the output before submitting a patch.'
  66. echo 'When using "patch" mode, carefully review the patch before submitting it.'
  67. echo ''
  68. fi
  69. run_cmd() {
  70. local i
  71. if [ $VERBOSE -ne 0 ] ; then
  72. echo "Running ($NPROC in parallel): $@"
  73. fi
  74. for i in $(seq 0 $(( NPROC - 1)) ); do
  75. eval "$@ --max $NPROC --index $i &"
  76. SPATCH_PID[$i]=$!
  77. if [ $VERBOSE -eq 2 ] ; then
  78. echo "${SPATCH_PID[$i]} running"
  79. fi
  80. done
  81. wait
  82. }
  83. kill_running() {
  84. for i in $(seq $(( NPROC - 1 )) ); do
  85. if [ $VERBOSE -eq 2 ] ; then
  86. echo "Killing ${SPATCH_PID[$i]}"
  87. fi
  88. kill ${SPATCH_PID[$i]} 2>/dev/null
  89. done
  90. }
  91. coccinelle () {
  92. COCCI="$1"
  93. OPT=`grep "Option" $COCCI | cut -d':' -f2`
  94. # The option '--parse-cocci' can be used to syntactically check the SmPL files.
  95. #
  96. # $SPATCH -D $MODE $FLAGS -parse_cocci $COCCI $OPT > /dev/null
  97. if [ $VERBOSE -ne 0 -a $ONLINE -eq 0 ] ; then
  98. FILE=`echo $COCCI | sed "s|$srctree/||"`
  99. echo "Processing `basename $COCCI`"
  100. echo "with option(s) \"$OPT\""
  101. echo ''
  102. echo 'Message example to submit a patch:'
  103. sed -ne 's|^///||p' $COCCI
  104. if [ "$MODE" = "patch" ] ; then
  105. echo ' The semantic patch that makes this change is available'
  106. elif [ "$MODE" = "report" ] ; then
  107. echo ' The semantic patch that makes this report is available'
  108. elif [ "$MODE" = "context" ] ; then
  109. echo ' The semantic patch that spots this code is available'
  110. elif [ "$MODE" = "org" ] ; then
  111. echo ' The semantic patch that makes this Org report is available'
  112. else
  113. echo ' The semantic patch that makes this output is available'
  114. fi
  115. echo " in $FILE."
  116. echo ''
  117. echo ' More information about semantic patching is available at'
  118. echo ' http://coccinelle.lip6.fr/'
  119. echo ''
  120. if [ "`sed -ne 's|^//#||p' $COCCI`" ] ; then
  121. echo 'Semantic patch information:'
  122. sed -ne 's|^//#||p' $COCCI
  123. echo ''
  124. fi
  125. fi
  126. if [ "$MODE" = "chain" ] ; then
  127. run_cmd $SPATCH -D patch \
  128. $FLAGS --cocci-file $COCCI $OPT $OPTIONS || \
  129. run_cmd $SPATCH -D report \
  130. $FLAGS --cocci-file $COCCI $OPT $OPTIONS --no-show-diff || \
  131. run_cmd $SPATCH -D context \
  132. $FLAGS --cocci-file $COCCI $OPT $OPTIONS || \
  133. run_cmd $SPATCH -D org \
  134. $FLAGS --cocci-file $COCCI $OPT $OPTIONS --no-show-diff || exit 1
  135. elif [ "$MODE" = "rep+ctxt" ] ; then
  136. run_cmd $SPATCH -D report \
  137. $FLAGS --cocci-file $COCCI $OPT $OPTIONS --no-show-diff && \
  138. run_cmd $SPATCH -D context \
  139. $FLAGS --cocci-file $COCCI $OPT $OPTIONS || exit 1
  140. else
  141. run_cmd $SPATCH -D $MODE $FLAGS --cocci-file $COCCI $OPT $OPTIONS || exit 1
  142. fi
  143. }
  144. if [ "$COCCI" = "" ] ; then
  145. for f in `find $srctree/scripts/coccinelle/ -name '*.cocci' -type f | sort`; do
  146. coccinelle $f
  147. done
  148. else
  149. coccinelle $COCCI
  150. fi