1#!/bin/sh 2# 3# This script parses the output of a gcc bootstrap when using warning 4# flags and determines various statistics. 5# 6# usage: warn_summary [-llf] [-s stage] [-nosub|-ch|-cp|-f|-java|-ada|-intl|-fixinc] 7# [-pass|-wpass] [file(s)] 8# 9# -llf 10# Filter out long lines from the bootstrap output before any other 11# action. This is useful for systems with broken awks/greps which choke 12# on long lines. It is not done by default as it sometimes slows things 13# down. 14# 15# -s number 16# Take warnings from stage "Number". Stage 0 means show warnings from 17# before and after the gcc bootstrap directory. E.g. libraries, etc. 18# This presupposes using "gcc -W*" for the stage1 compiler. 19# 20# -nosub 21# Only show warnings from the gcc top level directory. 22# -ch|-cp|-f|-java|-ada|-intl|-fixinc 23# Only show warnings from the specified language subdirectory. 24# These override each other so only the last one passed takes effect. 25# 26# -pass 27# Pass through the bootstrap output after filtering stage and subdir 28# (useful for manual inspection.) This is all lines, not just warnings. 29# -wpass 30# Pass through only warnings from the bootstrap output after filtering 31# stage and subdir. 32# 33# By Kaveh Ghazi (ghazi@caip.rutgers.edu) 12/13/97. 34 35 36# Some awks choke on long lines, sed seems to do a better job. 37# Truncate lines > 255 characters. RE '.\{255,\}' doesn't seem to work. :-( 38# Only do this if -llf was specified, because it can really slow things down. 39longLineFilter() 40{ 41 if test -z "$llf" ; then 42 cat 43 else 44 sed 's/^\(...............................................................................................................................................................................................................................................................\).*/\1/' 45 fi 46} 47 48# This function does one of three things. It either passes through 49# all warning data, or passes through gcc toplevel warnings, or passes 50# through a particular subdirectory set of warnings. 51subdirectoryFilter() 52{ 53 longLineFilter | ( 54 if test -z "$filter" ; then 55 # Pass through all lines. 56 cat 57 else 58 if test "$filter" = nosub ; then 59 # Omit all subdirectories. 60 egrep -v '/gcc/(ch|cp|f|java|intl|fixinc)/' 61 else 62 # Pass through only subdir $filter. 63 grep "/gcc/$filter/" 64 fi 65 fi ) 66} 67 68# This function displays all lines from stageN of the bootstrap. If 69# stage==0, then show lines prior to stage1 and lines from after the last 70# stage. I.e. utilities, libraries, etc. 71stageNfilter() 72{ 73 if test "$stageN" -lt 1 ; then 74 # stage "0" means check everything *but* gcc. 75 $AWK "BEGIN{t=1} ; /^Bootstrapping the compiler/{t=0} ; /^Building runtime libraries/{t=1} ; {if(t==1)print}" 76 else 77 if test "$stageN" -eq 1 ; then 78 $AWK "/^Bootstrapping the compiler|^Building the C and C\+\+ compiler/{t=1} ; /stage$stageN/{t=0} ; {if(t==1)print}" 79 else 80 stageNminus1=`expr $stageN - 1` 81 $AWK "/stage${stageNminus1}\//{t=1} ; /stage$stageN/{t=0} ; {if(t==1)print}" 82 fi 83 fi 84} 85 86# This function displays lines containing warnings. 87warningFilter() 88{ 89 grep ' warning: ' 90} 91 92# This function replaces `xxx' with `???', where xxx is usually some 93# variable or function name. This allows similar warnings to be 94# counted together when summarizing. However it avoids replacing 95# certain C keywords which are known appear in various messages. 96 97keywordFilter() { 98 sed 's/.*warning: //; 99 s/`\(int\)'"'"'/"\1"/g; 100 s/`\(long\)'"'"'/"\1"/g; 101 s/`\(char\)'"'"'/"\1"/g; 102 s/`\(inline\)'"'"'/"\1"/g; 103 s/`\(else\)'"'"'/"\1"/g; 104 s/`\(return\)'"'"'/"\1"/g; 105 s/`\(static\)'"'"'/"\1"/g; 106 s/`\(extern\)'"'"'/"\1"/g; 107 s/`\(const\)'"'"'/"\1"/g; 108 s/`\(noreturn\)'"'"'/"\1"/g; 109 s/`\(longjmp\)'"'"' or `\(vfork\)'"'"'/"\1" or "\2"/g; 110 s/`'"[^']*'/"'`???'"'/g;"' 111 s/.*format, .* arg (arg [0-9][0-9]*)/??? format, ??? arg (arg ???)/; 112 s/\([( ]\)arg [0-9][0-9]*\([) ]\)/\1arg ???\2/; 113 s/"\([^"]*\)"/`\1'"'"'/g' 114} 115 116# This function strips out relative pathnames for source files printed 117# by the warningFilter function. This is done so that as the snapshot 118# directory name changes every week, the output of this program can be 119# compared to previous runs without spurious diffs caused by source 120# directory name changes. 121 122srcdirFilter() 123{ 124 sed ' 125s%^[^ ]*/\(gcc/\)%\1%; 126s%^[^ ]*/\(include/\)%\1%; 127s%^[^ ]*/\(texinfo/\)%\1%; 128s%^[^ ]*/\(fastjar/\)%\1%; 129s%^[^ ]*/\(zlib/\)%\1%; 130s%^[^ ]*/\(lib[a-z23+-]*/\)%\1%;' 131} 132 133# Start the main section. 134 135usage="usage: `basename $0` [-llf] [-s stage] [-nosub|-ch|-cp|-f|-java|-ada|-intl|-fixinc] [-pass|-wpass] [file(s)]" 136stageN=3 137tmpfile=/tmp/tmp-warn.$$ 138 139# Remove $tmpfile on exit and various signals. 140trap "rm -f $tmpfile" 0 141trap "rm -f $tmpfile ; exit 1" 1 2 3 5 9 13 15 142 143# Find a good awk. 144if test -z "$AWK" ; then 145 for AWK in gawk nawk awk ; do 146 if type $AWK 2>&1 | grep 'not found' > /dev/null 2>&1 ; then 147 : 148 else 149 break 150 fi 151 done 152fi 153 154# Parse command line arguments. 155while test -n "$1" ; do 156 case "$1" in 157 -llf) llf=1 ; shift ;; 158 -s) if test -z "$2"; then echo $usage 1>&2; exit 1; fi 159 stageN="$2"; shift 2 ;; 160 -s*) stageN="`expr $1 : '-s\(.*\)'`" ; shift ;; 161 -nosub|-ch|-cp|-f|-java|-ada|-intl|-fixinc) filter="`expr $1 : '-\(.*\)'`" ; shift ;; 162 -pass) pass=1 ; shift ;; 163 -wpass) pass=w ; shift ;; 164 -*) echo $usage 1>&2 ; exit 1 ;; 165 *) break ;; 166 esac 167done 168 169# Check for a valid value of $stageN. 170case "$stageN" in 171 [0-9]) ;; 172 *) echo "Stage <$stageN> must be in the range [0..9]." 1>&2 ; exit 1 ;; 173esac 174 175for file in "$@" ; do 176 177 stageNfilter < $file | subdirectoryFilter > $tmpfile 178 179 # (Just) show me the warnings. 180 if test "$pass" != '' ; then 181 if test "$pass" = w ; then 182 warningFilter < $tmpfile 183 else 184 cat $tmpfile 185 fi 186 continue 187 fi 188 189 if test -z "$filter" ; then 190 echo "Counting all warnings," 191 else 192 if test "$filter" = nosub ; then 193 echo "Counting non-subdirectory warnings," 194 else 195 echo "Counting warnings in the gcc/$filter subdirectory," 196 fi 197 fi 198 count=`warningFilter < $tmpfile | wc -l` 199 echo there are $count warnings in stage$stageN of this bootstrap. 200 201 echo 202 echo Number of warnings per file: 203 warningFilter < $tmpfile | srcdirFilter | $AWK -F: '{print$1}' | sort | \ 204 uniq -c | sort -nr 205 206 echo 207 echo Number of warning types: 208 warningFilter < $tmpfile | keywordFilter | sort | uniq -c | sort -nr 209 210done 211