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|-fortran|-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|-fortran|-ada|-intl|-fixinc 23 # Only show warnings from the specified gcc 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 (at] 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. 39 longLineFilter() 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. 51 subdirectoryFilter() 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|fortran|ada|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. 71 stageNfilter() 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. 87 warningFilter() 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 97 keywordFilter() { 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 122 srcdirFilter() 123 { 124 sed ' 125 s%^[^ ]*/\(gcc/\)%\1%; 126 s%^[^ ]*/\(include/\)%\1%; 127 s%^[^ ]*/\(texinfo/\)%\1%; 128 s%^[^ ]*/\(fastjar/\)%\1%; 129 s%^[^ ]*/\(zlib/\)%\1%; 130 s%^[^ ]*/\(fixincludes/\)%\1%; 131 s%^[^ ]*/\(sim/\)%\1%; 132 s%^[^ ]*/\(newlib/\)%\1%; 133 s%^[^ ]*/\(mpfr/\)%\1%; 134 s%^[^ ]*/\(lib[a-z23+-]*/\)%\1%;' 135 } 136 137 # Start the main section. 138 139 usage="usage: `basename $0` [-llf] [-s stage] [-nosub|-ch|-cp|-f|-fortran|-ada|-intl|-fixinc] [-pass|-wpass] [file(s)]" 140 stageN=3 141 tmpfile=${TMPDIR:-/tmp}/tmp-warn.$$ 142 143 # Remove $tmpfile on exit and various signals. 144 trap "rm -f $tmpfile" 0 145 trap "rm -f $tmpfile ; exit 1" 1 2 3 5 9 13 15 146 147 # Find a good awk. 148 if test -z "$AWK" ; then 149 for AWK in gawk nawk awk ; do 150 if type $AWK 2>&1 | grep 'not found' > /dev/null 2>&1 ; then 151 : 152 else 153 break 154 fi 155 done 156 fi 157 158 # Parse command line arguments. 159 while test -n "$1" ; do 160 case "$1" in 161 -llf) llf=1 ; shift ;; 162 -s) if test -z "$2"; then echo $usage 1>&2; exit 1; fi 163 stageN="$2"; shift 2 ;; 164 -s*) stageN="`expr $1 : '-s\(.*\)'`" ; shift ;; 165 -nosub|-ch|-cp|-f|-fortran|-ada|-intl|-fixinc) filter="`expr $1 : '-\(.*\)'`" ; shift ;; 166 -pass) pass=1 ; shift ;; 167 -wpass) pass=w ; shift ;; 168 -*) echo $usage 1>&2 ; exit 1 ;; 169 *) break ;; 170 esac 171 done 172 173 # Check for a valid value of $stageN. 174 case "$stageN" in 175 [0-9]) ;; 176 *) echo "Stage <$stageN> must be in the range [0..9]." 1>&2 ; exit 1 ;; 177 esac 178 179 for file in "$@" ; do 180 181 stageNfilter < $file | subdirectoryFilter > $tmpfile 182 183 # (Just) show me the warnings. 184 if test "$pass" != '' ; then 185 if test "$pass" = w ; then 186 warningFilter < $tmpfile 187 else 188 cat $tmpfile 189 fi 190 continue 191 fi 192 193 if test -z "$filter" ; then 194 echo "Counting all warnings," 195 else 196 if test "$filter" = nosub ; then 197 echo "Counting non-subdirectory warnings," 198 else 199 echo "Counting warnings in the gcc/$filter subdirectory," 200 fi 201 fi 202 count=`warningFilter < $tmpfile | wc -l` 203 echo there are $count warnings in stage$stageN of this bootstrap. 204 205 echo 206 echo Number of warnings per file: 207 warningFilter < $tmpfile | srcdirFilter | $AWK -F: '{print$1}' | sort | \ 208 uniq -c | sort -nr 209 210 echo 211 echo Number of warning types: 212 warningFilter < $tmpfile | keywordFilter | sort | uniq -c | sort -nr 213 214 done 215