#!/bin/bash # ----------------------------------------------------------------------------- # Check source-tree for anomalies # # Copyright (C) 2005-2007 by Ivo van Poorten # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # Thanks to Melchior Franz of the FlightGear project for the original idea # of a source-tree checker and Torinthiel for the feedback along the way. # $Id$ # ----------------------------------------------------------------------------- # All yes/no flags. Spaces around flagnames are important! testflags=" spaces extensions crlf tabs trailws rcsid oll charset stupid gnu \ res depr " allflags="$testflags showcont color head svn " # ----------------------------------------------------------------------------- # Avoid locale problems export LC_ALL=C # ----------------------------------------------------------------------------- # Helper functions set_all_tests() { for i in $testflags ; do eval _$i=$1 done } printoption() { test -n "$3" && def=$3 || eval def=\$_$1 echo " -(no)$1 $2 [default: $def]" } printhead() { test "$_head" = "yes" && echo -e "$COLB$1$COLE" } all_filenames() { test "$_files" != "" && echo "$_files" && return if [ "$_svn" = "no" ]; then find . -type f \ | grep -v "\.\#\|\~$\|\.depend\|\/\.svn\/\|config.mak\|^\./config\.h" \ | grep -v "^\./version\.h\|\.o$\|\.a$\|config.log\|^\./help_mp.h" else for p in . libavcodec libavutil libavformat libpostproc ; do svn info -R $p 2>/dev/null | sed -n \ '/Path:/bb; :a; d; b; :b; s/Path: /.\//; h; :c; n; /Node Kind:/bd; bc; :d; /directory/ba; g; p;' done fi } # ----------------------------------------------------------------------------- # Default settings set_all_tests no _spaces=yes _extensions=yes _crlf=yes _showcont=no _color=yes _head=yes _svn=yes _files= # Parse command line for i in "$@"; do case "$i" in -help|--help|-h|-\?) echo -e "\n$0 [options] [files]\n" echo -e "options:\n" printoption "spaces " "test for spaces in filenames" printoption "extensions" "test for uppercase extensions" printoption "crlf " "test for MSDOS line endings" printoption "tabs " "test for tab characters" printoption "trailws " "test for trailing whitespace" printoption "rcsid " "test for missing RCS Id's" printoption "oll " "test for overly long lines" printoption "charset " "test for wrong charset" printoption "stupid " "test for stupid code" printoption "gnu " "test for GNUisms" printoption "res " "test for reserved identifiers" printoption "depr " "test for deprecated function calls" echo printoption "all " "enable all tests" "no" echo " (-noall can be specified as -none)" echo printoption "showcont " "show offending content of file(s)" echo printoption "color " "colored output" printoption "head " "print heading for each test" printoption "svn " \ "use svn info to determine which files to check" echo -e "\nIf no files are specified, the whole tree is traversed." echo -e "If there are, -(no)svn has no effect.\n" exit ;; -all) set_all_tests yes ;; -noall) set_all_tests no ;; -none) set_all_tests no ;; -*) var=`echo X$i | sed 's/^X-//'` val=yes case "$var" in no*) var=`echo "$var" | cut -c 3-` val=no ;; esac case "$allflags" in *\ $var\ *) eval _$var=$val ;; *) echo "unknown option: $i" >&2 exit 0 ;; esac ;; *) _files="$_files $i" ;; esac done # ----------------------------------------------------------------------------- # Set heading color if [ "$_color" = "yes" ]; then COLB="\e[36m" COLE="\e[m" else COLB="" COLE="" fi # Test presence of svn info if [ "$_svn" = "yes" -a ! -d .svn ] ; then echo "No svn info available. Please use -nosvn." >&2 exit 1 fi # Generate filelist once so -svn isn't _that_ much slower than -nosvn anymore filelist=`all_filenames` case "$_stupid$_res$_depr$_gnu" in *yes*) # generate 'shortlist' to avoid false positives in xpm files, docs, etc, # when one only needs to check .c and .h files chfilelist=`echo $filelist | tr ' ' '\n' | grep "[\.][ch]$"` ;; esac if [ "$_showcont" = "yes" ]; then _diffopts="-u" _grepopts="-n -I" else _diffopts="-q" _grepopts="-l -I" fi TAB=`echo " " | tr ' ' '\011'` # ----------------------------------------------------------------------------- # DO CHECKS # ----------------------------------------------------------------------------- if [ "$_spaces" = "yes" ]; then printhead "checking for spaces in filenames ..." find . | grep " " fi # ----------------------------------------------------------------------------- if [ "$_extensions" = "yes" ]; then printhead "checking for uppercase extensions ..." echo $filelist | grep "\.[[:upper:]]\+$" | grep -v "\.S$" fi # ----------------------------------------------------------------------------- if [ "$_crlf" = "yes" ]; then printhead "checking for MSDOS line endings ..." CR=`echo " " | tr ' ' '\015'` grep $_grepopts "$CR" $filelist fi # ----------------------------------------------------------------------------- if [ "$_tabs" = "yes" ]; then printhead "checking for TAB characters ..." grep $_grepopts "$TAB" $filelist fi # ----------------------------------------------------------------------------- if [ "$_trailws" = "yes" ]; then printhead "checking for trailing whitespace ..." grep $_grepopts "[[:space:]]\+$" $filelist fi # ----------------------------------------------------------------------------- if [ "$_rcsid" = "yes" ]; then printhead "checking for missing RCS \$Id\$ or \$Revision\$ tags ..." grep -L -I "\$\(Id\|Revision\)[[:print:]]\+\$" $filelist fi # ----------------------------------------------------------------------------- if [ "$_oll" = "yes" ]; then printhead "checking for overly long lines (over 79 characters) ..." grep $_grepopts "^[[:print:]]\{80,\}$" $filelist fi # ----------------------------------------------------------------------------- if [ "$_gnu" = "yes" -a -n "$chfilelist" ]; then printhead "checking for GNUisms ..." grep $_grepopts "case.*\.\.\..*:" $chfilelist fi # ----------------------------------------------------------------------------- if [ "$_res" = "yes" -a -n "$chfilelist" ]; then printhead "checking for reserved identifiers ..." grep $_grepopts "#[ $TAB]*define[ $TAB]\+_[[:upper:]].*" $chfilelist grep $_grepopts "#[ $TAB]*define[ $TAB]\+__.*" $chfilelist fi # ----------------------------------------------------------------------------- if [ "$_charset" = "yes" ]; then printhead "checking bad charsets ..." for I in $filelist ; do case "$I" in ./help/help_mp-*.h) ;; ./DOCS/*) ;; *.c|*.h) iconv -c -f ascii -t ascii "$I" | diff $_diffopts "$I" - ;; esac done fi # ----------------------------------------------------------------------------- if [ "$_stupid" = "yes" -a -n "$chfilelist" ]; then printhead "checking for stupid code ..." for i in calloc malloc realloc memalign av_malloc av_mallocz faad_malloc \ lzo_malloc safe_malloc mpeg2_malloc _ogg_malloc; do printhead "--> casting of void* $i()" grep $_grepopts "([ $TAB]*[a-zA-Z_]\+[ $TAB]*\*.*)[ $TAB]*$i" \ $chfilelist done for i in "" signed unsigned; do printhead "--> usage of sizeof($i char)" grep $_grepopts "sizeof[ $TAB]*([ $TAB]*$i[ $TAB]*char[ $TAB]*)" \ $chfilelist done for i in int8_t uint8_t; do printhead "--> usage of sizeof($i)" grep $_grepopts "sizeof[ $TAB]*([ $TAB]*$i[ $TAB]*)" $chfilelist done printhead "--> usage of &&1" grep $_grepopts "&&[ $TAB]*1" $chfilelist printhead "--> usage of ||0" grep $_grepopts "||[ $TAB]*0" $chfilelist # added a-fA-F_ to eliminate some false positives printhead "--> usage of *0" grep $_grepopts "[a-zA-Z0-9)]\+[ $TAB]*\*[ $TAB]*0[^.0-9xa-fA-F_]" \ $chfilelist printhead "--> usage of *1" grep $_grepopts "[a-zA-Z0-9)]\+[ $TAB]*\*[ $TAB]*1[^.0-9ea-fA-F_]" \ $chfilelist printhead "--> usage of +0" grep $_grepopts "[a-zA-Z0-9)]\+[ $TAB]*+[ $TAB]*0[^.0-9xa-fA-F_]" \ $chfilelist printhead "--> usage of -0" grep $_grepopts "[a-zA-Z0-9)]\+[ $TAB]*-[ $TAB]*0[^.0-9xa-fA-F_]" \ $chfilelist fi # ----------------------------------------------------------------------------- if [ "$_depr" = "yes" -a -n "$chfilelist" ]; then printhead "checking for deprecated and obsolete function calls ..." for i in bcmp bcopy bzero getcwd getipnodebyname inet_ntoa inet_addr \ atoq ecvt fcvt ecvt_r fcvt_r qecvt_r qfcvt_r finite ftime gcvt herror \ hstrerror getpass getpw getutent getutid getutline pututline setutent \ endutent utmpname gsignal ssignal gsignal_r ssignal_r infnan memalign \ valloc re_comp re_exec drem dremf dreml rexec svc_getreq sigset \ sighold sigrelse sigignore sigvec sigmask sigblock sigsetmask \ siggetmask ualarm ulimit usleep statfs fstatfs ustat get_kernel_syms \ query_module sbrk tempnam tmpnam mktemp mkstemp do printhead "--> $i()" grep $_grepopts "[^a-zA-Z0-9]$i[ $TAB]*(" $chfilelist done fi