11debfc3dSmrg#!/bin/sh 21debfc3dSmrg# 31debfc3dSmrg# This script parses the output of a gcc bootstrap when using warning 41debfc3dSmrg# flags and determines various statistics. 51debfc3dSmrg# 61debfc3dSmrg# usage: warn_summary [-llf] [-s stage] [-nosub|-ch|-cp|-f|-fortran|-ada|-intl|-fixinc] 71debfc3dSmrg# [-pass|-wpass] [file(s)] 81debfc3dSmrg# 91debfc3dSmrg# -llf 101debfc3dSmrg# Filter out long lines from the bootstrap output before any other 111debfc3dSmrg# action. This is useful for systems with broken awks/greps which choke 121debfc3dSmrg# on long lines. It is not done by default as it sometimes slows things 131debfc3dSmrg# down. 141debfc3dSmrg# 151debfc3dSmrg# -s number 161debfc3dSmrg# Take warnings from stage "Number". Stage 0 means show warnings from 171debfc3dSmrg# before and after the gcc bootstrap directory. E.g. libraries, etc. 181debfc3dSmrg# This presupposes using "gcc -W*" for the stage1 compiler. 191debfc3dSmrg# 201debfc3dSmrg# -nosub 211debfc3dSmrg# Only show warnings from the gcc top level directory. 221debfc3dSmrg# -ch|-cp|-f|-fortran|-ada|-intl|-fixinc 231debfc3dSmrg# Only show warnings from the specified gcc subdirectory. 241debfc3dSmrg# These override each other so only the last one passed takes effect. 251debfc3dSmrg# 261debfc3dSmrg# -pass 271debfc3dSmrg# Pass through the bootstrap output after filtering stage and subdir 281debfc3dSmrg# (useful for manual inspection.) This is all lines, not just warnings. 291debfc3dSmrg# -wpass 301debfc3dSmrg# Pass through only warnings from the bootstrap output after filtering 311debfc3dSmrg# stage and subdir. 321debfc3dSmrg# 331debfc3dSmrg# By Kaveh Ghazi (ghazi@caip.rutgers.edu) 12/13/97. 341debfc3dSmrg 351debfc3dSmrg 361debfc3dSmrg# Some awks choke on long lines, sed seems to do a better job. 371debfc3dSmrg# Truncate lines > 255 characters. RE '.\{255,\}' doesn't seem to work. :-( 381debfc3dSmrg# Only do this if -llf was specified, because it can really slow things down. 391debfc3dSmrglongLineFilter() 401debfc3dSmrg{ 411debfc3dSmrg if test -z "$llf" ; then 421debfc3dSmrg cat 431debfc3dSmrg else 441debfc3dSmrg sed 's/^\(...............................................................................................................................................................................................................................................................\).*/\1/' 451debfc3dSmrg fi 461debfc3dSmrg} 471debfc3dSmrg 481debfc3dSmrg# This function does one of three things. It either passes through 491debfc3dSmrg# all warning data, or passes through gcc toplevel warnings, or passes 501debfc3dSmrg# through a particular subdirectory set of warnings. 511debfc3dSmrgsubdirectoryFilter() 521debfc3dSmrg{ 531debfc3dSmrg longLineFilter | ( 541debfc3dSmrg if test -z "$filter" ; then 551debfc3dSmrg # Pass through all lines. 561debfc3dSmrg cat 571debfc3dSmrg else 581debfc3dSmrg if test "$filter" = nosub ; then 591debfc3dSmrg # Omit all subdirectories. 601debfc3dSmrg egrep -v '/gcc/(ch|cp|f|fortran|ada|intl|fixinc)/' 611debfc3dSmrg else 621debfc3dSmrg # Pass through only subdir $filter. 631debfc3dSmrg grep "/gcc/$filter/" 641debfc3dSmrg fi 651debfc3dSmrg fi ) 661debfc3dSmrg} 671debfc3dSmrg 681debfc3dSmrg# This function displays all lines from stageN of the bootstrap. If 691debfc3dSmrg# stage==0, then show lines prior to stage1 and lines from after the last 701debfc3dSmrg# stage. I.e. utilities, libraries, etc. 711debfc3dSmrgstageNfilter() 721debfc3dSmrg{ 731debfc3dSmrg if test "$stageN" -lt 1 ; then 741debfc3dSmrg # stage "0" means check everything *but* gcc. 751debfc3dSmrg $AWK "BEGIN{t=1} ; /^Bootstrapping the compiler/{t=0} ; /^Building runtime libraries/{t=1} ; {if(t==1)print}" 761debfc3dSmrg else 771debfc3dSmrg if test "$stageN" -eq 1 ; then 781debfc3dSmrg $AWK "/^Bootstrapping the compiler|^Building the C and C\+\+ compiler/{t=1} ; /stage$stageN/{t=0} ; {if(t==1)print}" 791debfc3dSmrg else 801debfc3dSmrg stageNminus1=`expr $stageN - 1` 811debfc3dSmrg $AWK "/stage${stageNminus1}\//{t=1} ; /stage$stageN/{t=0} ; {if(t==1)print}" 821debfc3dSmrg fi 831debfc3dSmrg fi 841debfc3dSmrg} 851debfc3dSmrg 861debfc3dSmrg# This function displays lines containing warnings. 871debfc3dSmrgwarningFilter() 881debfc3dSmrg{ 891debfc3dSmrg grep ' warning: ' 901debfc3dSmrg} 911debfc3dSmrg 921debfc3dSmrg# This function replaces `xxx' with `???', where xxx is usually some 931debfc3dSmrg# variable or function name. This allows similar warnings to be 941debfc3dSmrg# counted together when summarizing. However it avoids replacing 951debfc3dSmrg# certain C keywords which are known appear in various messages. 961debfc3dSmrg 971debfc3dSmrgkeywordFilter() { 981debfc3dSmrg sed 's/.*warning: //; 991debfc3dSmrg s/`\(int\)'"'"'/"\1"/g; 1001debfc3dSmrg s/`\(long\)'"'"'/"\1"/g; 1011debfc3dSmrg s/`\(char\)'"'"'/"\1"/g; 1021debfc3dSmrg s/`\(inline\)'"'"'/"\1"/g; 1031debfc3dSmrg s/`\(else\)'"'"'/"\1"/g; 1041debfc3dSmrg s/`\(return\)'"'"'/"\1"/g; 1051debfc3dSmrg s/`\(static\)'"'"'/"\1"/g; 1061debfc3dSmrg s/`\(extern\)'"'"'/"\1"/g; 1071debfc3dSmrg s/`\(const\)'"'"'/"\1"/g; 1081debfc3dSmrg s/`\(noreturn\)'"'"'/"\1"/g; 1091debfc3dSmrg s/`\(longjmp\)'"'"' or `\(vfork\)'"'"'/"\1" or "\2"/g; 1101debfc3dSmrg s/'"[\`'][^']*'/"'"???"/g; 1111debfc3dSmrg s/.*format, .* arg (arg [0-9][0-9]*)/??? format, ??? arg (arg ???)/; 1121debfc3dSmrg s/\([( ]\)arg [0-9][0-9]*\([) ]\)/\1arg ???\2/; 1131debfc3dSmrg s/"\([^"]*\)"/`\1'"'"'/g' 1141debfc3dSmrg} 1151debfc3dSmrg 1161debfc3dSmrg# This function strips out relative pathnames for source files printed 1171debfc3dSmrg# by the warningFilter function. This is done so that as the snapshot 1181debfc3dSmrg# directory name changes every week, the output of this program can be 1191debfc3dSmrg# compared to previous runs without spurious diffs caused by source 1201debfc3dSmrg# directory name changes. 1211debfc3dSmrg 1221debfc3dSmrgsrcdirFilter() 1231debfc3dSmrg{ 1241debfc3dSmrg sed ' 1251debfc3dSmrgs%^[^ ]*/\(gcc/\)%\1%; 1261debfc3dSmrgs%^[^ ]*/\(include/\)%\1%; 1271debfc3dSmrgs%^[^ ]*/\(texinfo/\)%\1%; 1281debfc3dSmrgs%^[^ ]*/\(fastjar/\)%\1%; 1291debfc3dSmrgs%^[^ ]*/\(zlib/\)%\1%; 1301debfc3dSmrgs%^[^ ]*/\(fixincludes/\)%\1%; 1311debfc3dSmrgs%^[^ ]*/\(sim/\)%\1%; 1321debfc3dSmrgs%^[^ ]*/\(newlib/\)%\1%; 1331debfc3dSmrgs%^[^ ]*/\(mpfr/\)%\1%; 1341debfc3dSmrgs%^[^ ]*/\(lib[a-z23+-]*/\)%\1%;' 1351debfc3dSmrg} 1361debfc3dSmrg 1371debfc3dSmrg# Start the main section. 1381debfc3dSmrg 1391debfc3dSmrgusage="usage: `basename $0` [-llf] [-s stage] [-nosub|-ch|-cp|-f|-fortran|-ada|-intl|-fixinc] [-pass|-wpass] [file(s)]" 1401debfc3dSmrgstageN=3 141*a2dc1f3fSmrgtmpfile=${TMPDIR:-/tmp}/tmp-warn.$$ 1421debfc3dSmrg 1431debfc3dSmrg# Remove $tmpfile on exit and various signals. 1441debfc3dSmrgtrap "rm -f $tmpfile" 0 1451debfc3dSmrgtrap "rm -f $tmpfile ; exit 1" 1 2 3 5 9 13 15 1461debfc3dSmrg 1471debfc3dSmrg# Find a good awk. 1481debfc3dSmrgif test -z "$AWK" ; then 1491debfc3dSmrg for AWK in gawk nawk awk ; do 1501debfc3dSmrg if type $AWK 2>&1 | grep 'not found' > /dev/null 2>&1 ; then 1511debfc3dSmrg : 1521debfc3dSmrg else 1531debfc3dSmrg break 1541debfc3dSmrg fi 1551debfc3dSmrg done 1561debfc3dSmrgfi 1571debfc3dSmrg 1581debfc3dSmrg# Parse command line arguments. 1591debfc3dSmrgwhile test -n "$1" ; do 1601debfc3dSmrg case "$1" in 1611debfc3dSmrg -llf) llf=1 ; shift ;; 1621debfc3dSmrg -s) if test -z "$2"; then echo $usage 1>&2; exit 1; fi 1631debfc3dSmrg stageN="$2"; shift 2 ;; 1641debfc3dSmrg -s*) stageN="`expr $1 : '-s\(.*\)'`" ; shift ;; 1651debfc3dSmrg -nosub|-ch|-cp|-f|-fortran|-ada|-intl|-fixinc) filter="`expr $1 : '-\(.*\)'`" ; shift ;; 1661debfc3dSmrg -pass) pass=1 ; shift ;; 1671debfc3dSmrg -wpass) pass=w ; shift ;; 1681debfc3dSmrg -*) echo $usage 1>&2 ; exit 1 ;; 1691debfc3dSmrg *) break ;; 1701debfc3dSmrg esac 1711debfc3dSmrgdone 1721debfc3dSmrg 1731debfc3dSmrg# Check for a valid value of $stageN. 1741debfc3dSmrgcase "$stageN" in 1751debfc3dSmrg [0-9]) ;; 1761debfc3dSmrg *) echo "Stage <$stageN> must be in the range [0..9]." 1>&2 ; exit 1 ;; 1771debfc3dSmrgesac 1781debfc3dSmrg 1791debfc3dSmrgfor file in "$@" ; do 1801debfc3dSmrg 1811debfc3dSmrg stageNfilter < $file | subdirectoryFilter > $tmpfile 1821debfc3dSmrg 1831debfc3dSmrg # (Just) show me the warnings. 1841debfc3dSmrg if test "$pass" != '' ; then 1851debfc3dSmrg if test "$pass" = w ; then 1861debfc3dSmrg warningFilter < $tmpfile 1871debfc3dSmrg else 1881debfc3dSmrg cat $tmpfile 1891debfc3dSmrg fi 1901debfc3dSmrg continue 1911debfc3dSmrg fi 1921debfc3dSmrg 1931debfc3dSmrg if test -z "$filter" ; then 1941debfc3dSmrg echo "Counting all warnings," 1951debfc3dSmrg else 1961debfc3dSmrg if test "$filter" = nosub ; then 1971debfc3dSmrg echo "Counting non-subdirectory warnings," 1981debfc3dSmrg else 1991debfc3dSmrg echo "Counting warnings in the gcc/$filter subdirectory," 2001debfc3dSmrg fi 2011debfc3dSmrg fi 2021debfc3dSmrg count=`warningFilter < $tmpfile | wc -l` 2031debfc3dSmrg echo there are $count warnings in stage$stageN of this bootstrap. 2041debfc3dSmrg 2051debfc3dSmrg echo 2061debfc3dSmrg echo Number of warnings per file: 2071debfc3dSmrg warningFilter < $tmpfile | srcdirFilter | $AWK -F: '{print$1}' | sort | \ 2081debfc3dSmrg uniq -c | sort -nr 2091debfc3dSmrg 2101debfc3dSmrg echo 2111debfc3dSmrg echo Number of warning types: 2121debfc3dSmrg warningFilter < $tmpfile | keywordFilter | sort | uniq -c | sort -nr 2131debfc3dSmrg 2141debfc3dSmrgdone 215