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