1# A bunch of shell functions that help finding unnecessary includes. 2# Relies on appropriate versions of etags, grep, tr, awk and maybe bash. 3# 4# To use: 5# $ . util/includes.sh 6# $ checkall 7 8# Tries to list all names defined in the header file $1. 9# Indented names are assumed to be members that don't need to be checked, 10# which will fail for indented declarations with #ifdefs. 11_wrap_etags() 12{ 13 tmp=$1.etags.h 14 # clean up const member functions since they confuse etags 15 sed -e 's/) const\;/)\;/' < $1 > $tmp 16 etags --declarations $tmp -o - 17 rm $tmp 18} 19 20names () 21{ 22 b=$(basename $1 .h); 23 { 24 _wrap_etags $1 \ 25 | grep '\(^[#a-z]\|^ *[0-9A-Z_][0-9A-Z_][0-9A-Z_]\)' \ 26 | grep -v '^'$b'\.h' \ 27 | tr '\177' '\t' | awk '{ print $(NF-1) }' \ 28 # etags misses namespace declarations 29 grep namespace $1 | awk '{ print $NF }' 30 # and some function definitions... 31 grep '^[a-z]' $1 | grep '(' | cut -d'(' -f 1 | awk '{ print $NF }' 32 } | sed -e 's/^\**//;s/[^a-zA-Z0-9]$//' | sort | uniq 33} 34 35# lists possible uses in $2 of names defined in $1 36mightuse () 37{ 38 for n in $(names $1); 39 do 40 if grep -F $n $2; then 41 return 0; 42 fi; 43 done; 44 return 1 45} 46 47# checks whether source file $2 #include's $1 48includes () 49{ 50 grep '#include "'$1'"' $2 51} 52 53# echo arguments if $2 includes $1 put shouldn't 54check () 55{ 56 if includes $1 $2 > /dev/null && ! mightuse $1 $2 > /dev/null; then 57 echo $1 $2; 58 fi 59} 60 61# run check on all source for a given header 62# should really cache the result of "names" 63checkhdr () 64{ 65 for src in *.cc; do 66 check $1 $src 67 done 68} 69 70# Run check on all headers for a given source 71# This is useful when you just want to check a single source file, most 72# likely because that source file has recently been heavily modified. 73checkcc () 74{ 75 for hdr in *.h; do 76 check $hdr $1 77 done 78} 79 80# run check on all pairs 81checkall () 82{ 83 checkafter "" 84} 85 86# Run checkhdr on all pairs alphabetically after a specific header 87# Useful to run directly in the case running checkall is interrupted. 88checkafter () 89{ 90 for hdr in *.h; do 91 if [[ $hdr < $1 || $hdr = AppHdr.h ]]; then 92 continue; 93 fi 94 95 checkhdr $hdr 96 done 97} 98 99# remove #include of $1 from $2 100remove () 101{ 102 b=$(basename $1 .h) 103 re='^#include "'$b'\.h"$' 104 if grep "$re" $2 > /dev/null; then 105 sed -e '/^#include "'$b'\.h"$/d' < $2 > $2.rmincl 106 mv $2.rmincl $2 107 fi 108} 109 110# remove doubtful includes for a list as output by checkall. 111removelst () 112{ 113 while read hdr src; do 114 remove $hdr $src 115 done 116} 117 118# remove special includes 119cleanup () 120{ 121 sed -e '/^quiver.h/d; 122 /^ghost.h kills.cc$/d; 123 /^cmd-name.h macro.cc$/d; 124 /^cmd-keys.h macro.cc$/d; 125 /^mon-spell.h monster.cc$/d; 126 /^AppHdr.h /d; 127 / artefact.cc/d' 128} 129