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