| 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. | 
|---|
| 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|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. | 
|---|
| 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%^[^ ]*/\(lib[a-z23+-]*/\)%\1%;' | 
|---|
| 131 | } | 
|---|
| 132 |  | 
|---|
| 133 | # Start the main section. | 
|---|
| 134 |  | 
|---|
| 135 | usage="usage: `basename $0` [-llf] [-s stage] [-nosub|-ch|-cp|-f|-java|-ada|-intl|-fixinc] [-pass|-wpass] [file(s)]" | 
|---|
| 136 | stageN=3 | 
|---|
| 137 | tmpfile=/tmp/tmp-warn.$$ | 
|---|
| 138 |  | 
|---|
| 139 | # Remove $tmpfile on exit and various signals. | 
|---|
| 140 | trap "rm -f $tmpfile" 0 | 
|---|
| 141 | trap "rm -f $tmpfile ; exit 1" 1 2 3 5 9 13 15 | 
|---|
| 142 |  | 
|---|
| 143 | # Find a good awk. | 
|---|
| 144 | if 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 | 
|---|
| 152 | fi | 
|---|
| 153 |  | 
|---|
| 154 | # Parse command line arguments. | 
|---|
| 155 | while 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 | 
|---|
| 167 | done | 
|---|
| 168 |  | 
|---|
| 169 | # Check for a valid value of $stageN. | 
|---|
| 170 | case "$stageN" in | 
|---|
| 171 | [0-9]) ;; | 
|---|
| 172 | *) echo "Stage <$stageN> must be in the range [0..9]." 1>&2 ; exit 1 ;; | 
|---|
| 173 | esac | 
|---|
| 174 |  | 
|---|
| 175 | for 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 |  | 
|---|
| 210 | done | 
|---|