[PATCH modular] Add hooks to run a static analysis tool.

Trevor Woerner twoerner at gmail.com
Tue Dec 21 20:57:30 PST 2010


From: Trevor Woerner <twoerner at gmail.com>

I've added a new option to have a static analysis tool run over the code
while processing each module/component. I wrote it specifically with
the 'cppcheck' tool in mind but have hopefully made it generic enough
that any tool could be substituted.

The 'cppcheck' tool also comes with a reporting tool called
'cppcheck-htmlreport'. If 'cppcheck' is being used, the script will also
look for this reporting tool to generate nice html-based reports.

On the command-line specify the '--staticcheck' option to enable running
a static checker over the code. This option has one required argument:
a location into which to base the directory tree containing the reports.

If the environment variable 'STATICCHECK' is defined, it is assumed to
point to the static analysis tool to use, otherwise the script assumes
and looks for the 'cppcheck' utility.

If you want to pass different options to the static checker other than
the defaults you can define them in the environment variable
'STATICCHECK_OPTIONS', but I think the defaults are sufficient.

This option works well with the '-o' and '--modfile' options.

E.g.

util/modular/build.sh $PREFIX --staticcheck $HOME/reports

Signed-off-by: Trevor Woerner <twoerner at gmail.com>
---
I saw the item the other day on lwn.net announcing a new project to add static
analysis checks on the Debian project and thought it would be nice to provide
a similar functionality to the X.Org codebase. Simply download, configure,
and install the 'cppcheck' tool and its daughter tool 'cppcheck-htmlreport',
use the --staticcheck option, provide a base directory for the reports
and see what comes out!

Hopefully these hooks have been written generically enough that you can
substitute whatever other static analysis tools with which you're familiar
(in case you don't like 'cppcheck' or want to try something else).

 build.sh |   86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 86 insertions(+), 0 deletions(-)

diff --git a/build.sh b/build.sh
index 8568083..2dacf96 100755
--- a/build.sh
+++ b/build.sh
@@ -1,5 +1,7 @@
 #!/bin/sh
 
+DEFAULT_STATICCHECK_OPTIONS="-v --enable=unusedFunction --force --xml"
+
 envoptions() {
 cat << EOF
 Environment variables specific to build.sh:
@@ -13,6 +15,10 @@ Environment variables specific to build.sh:
               Used to build the font path, search libraries and packages
   FONTPATH    Path to fonts directories [\$PREFIX/\$LIBDIR/X11/fonts/misc/, ...]
               Picked-up by the xserver as a value for --with-default-font-path
+  STATICCHECK Specify static analysis tool to use if not the default [cppcheck]
+  STATICCHECK_OPTIONS
+              User-supplied options to static analysis tool to override the defaults
+              [$DEFAULT_STATICCHECK_OPTIONS]
 
 Environment variables defined by the GNU Build System:
   DESTDIR     Path to the staging area where installed objects are relocated
@@ -263,6 +269,43 @@ clone() {
     return 0
 }
 
+# perform static anaysis of code
+# arguments:
+#   $1 - module
+#   $2 - component (optional)
+# returns:
+#   n/a
+staticcheck_analysis() {
+    # preconds
+    if [ X"$1" = X ]; then
+	echo "staticcheck_analysis() required argument \$1 missing"
+	return
+    fi
+
+    # skip modules which obviously don't have source code (proto & doc)
+    case X"$1" in
+	X"proto" | X"doc")
+	    return
+	    ;;
+    esac
+
+    if [ X"$STATICCHECK" != X ]; then
+	report_dir=$STATICCHECK_PREFIX/$1/$2
+	mkdir -p $report_dir
+	echo "performing static analysis using '$STATICCHECK' with options '${STATICCHECK_OPTIONS="$DEFAULT_STATICCHECK_OPTIONS"}' on '$1/$2' and placing report in '$report_dir/report.xml'"
+	which tee > /dev/null 2>&1
+	if [ $? -eq 0 ]; then
+	    $STATICCHECK ${STATICCHECK_OPTIONS="$DEFAULT_STATICCHECK_OPTIONS"} $1/$2 2>&1 | tee $report_dir/report.xml
+	else
+	    $STATICCHECK ${STATICCHECK_OPTIONS="$DEFAULT_STATICCHECK_OPTIONS"} $1/$2 > $report_dir/report.xml 2>&1
+	fi
+	if [ $? -eq 0 ] && [ X"$STATICCHECK_REPORT" != X ]; then
+	    echo "generating static check report using 'cppcheck-htmlreport'"
+	    cppcheck-htmlreport --file=$report_dir/report.xml --report-dir=$report_dir
+	fi
+    fi
+}
+
 # perform processing of each module/component
 # arguments:
 #   $1 - module
@@ -308,6 +351,10 @@ process() {
         echo "$1/$2" >> $BUILT_MODULES_FILE
     fi
 
+    if [ X"$STATICCHECK" != X ]; then
+	staticcheck_analysis $1 $2
+    fi
+
     old_pwd=`pwd`
     cd $SRCDIR
     if [ $? -ne 0 ]; then
@@ -960,6 +1007,9 @@ usage() {
     echo "  --check     Run make check in addition \"all install\""
     echo "  --clone     Clone non-existing repositories (uses \$GITROOT if set)"
     echo "  --cmd <cmd> Execute arbitrary git, gmake, or make command <cmd>"
+    echo "  --staticcheck <report-prefix>"
+    echo "              Perform static analysis on source, place results based"
+    echo "              at <report-prefix>"
     echo "  --modfile <file> Only process the module/components specified in <file>"
     echo ""
     echo "Usage: $basename -L"
@@ -1095,6 +1145,42 @@ do
 		;;
 	esac
 	;;
+    --staticcheck)
+	required_arg $1 $2
+	shift
+	STATICCHECK_PREFIX=$1
+
+	# look for static analysis tool
+	if [ X"$STATICCHECK" = X ]; then
+	    which cppcheck > /dev/null 2>&1
+	    if [ $? -eq 0 ]; then
+		STATICCHECK=`which cppcheck`
+	    fi
+	fi
+
+	# make sure the tool is found and executable
+	if [ X"$STATICCHECK" = X ]; then
+	    echo "No static analysis tool found"
+	    shift
+	    continue
+	fi
+	if [ ! -x $STATICCHECK ]; then
+	    echo "The static analysis tool '$STATICCHECK' doesn't appear to be executable"
+	    unset STATICCHECK
+	    shift
+	    continue
+	fi
+
+	# look for static analysis reporting tool 'cppcheck-htmlreport'
+	# if using cppcheck as the static analysis tool
+	echo $STATICCHECK | grep cppcheck > /dev/null 2>&1
+	if [ $? -eq 0 ]; then
+	    which cppcheck-htmlreport > /dev/null 2>&1
+	    if [ $? -eq 0 ]; then
+		STATICCHECK_REPORT=1
+	    fi
+	fi
+	;;
     --modfile)
 	required_arg $1 $2
 	shift
-- 
1.7.3.4.577.gf29db



More information about the xorg-devel mailing list