| 1 | #!/usr/bin/perl |
|---|
| 2 | |
|---|
| 3 | use strict; |
|---|
| 4 | use warnings; |
|---|
| 5 | |
|---|
| 6 | # ID is just a counter through all error occurrences |
|---|
| 7 | |
|---|
| 8 | my %loc = (); # key=ID content=location |
|---|
| 9 | my %num = (); # key=ID content=errornumber |
|---|
| 10 | my %msg = (); # key=ID content=message |
|---|
| 11 | my %type = (); # key=ID content=W|E|? (warning|error|unknown) |
|---|
| 12 | |
|---|
| 13 | my %numUsed = (); # key=num content=times used |
|---|
| 14 | |
|---|
| 15 | my $ID = 0; |
|---|
| 16 | |
|---|
| 17 | sub calc_numUsed() { |
|---|
| 18 | foreach (values %num) { $numUsed{$_}=0; } |
|---|
| 19 | foreach (values %num) { $numUsed{$_}++; } |
|---|
| 20 | } |
|---|
| 21 | |
|---|
| 22 | sub pad_locs() { |
|---|
| 23 | my $maxlen = 0; |
|---|
| 24 | foreach (values %loc) { |
|---|
| 25 | my $len = length($_); |
|---|
| 26 | if ($len>$maxlen) { $maxlen = $len; } |
|---|
| 27 | } |
|---|
| 28 | %loc = map { |
|---|
| 29 | my $padded = $loc{$_}; |
|---|
| 30 | my $len = length($padded); |
|---|
| 31 | while ($len<$maxlen) { |
|---|
| 32 | $padded .= ' '; |
|---|
| 33 | $len++; |
|---|
| 34 | } |
|---|
| 35 | |
|---|
| 36 | $_ => $padded; |
|---|
| 37 | } keys %loc; |
|---|
| 38 | } |
|---|
| 39 | |
|---|
| 40 | sub parse_errors() { |
|---|
| 41 | my $cmd = "grep -En 'throw_error|warning' *.cxx *.h"; |
|---|
| 42 | open(GREP,$cmd.'|') || die "failed to fork '$cmd' (Reason: $!)"; |
|---|
| 43 | LINE: foreach (<GREP>) { |
|---|
| 44 | chomp; |
|---|
| 45 | if (/(throw_errorf?|warningf?)\(\s*([0-9]+)\s*,(.*)/) { |
|---|
| 46 | my ($loc,$what,$num,$msg) = ($`,$1,$2,$3); |
|---|
| 47 | |
|---|
| 48 | my $msgType = '?'; |
|---|
| 49 | if ($what =~ /warning/o) { $msgType = 'W'; } |
|---|
| 50 | if ($what =~ /error/o) { $msgType = 'E'; } |
|---|
| 51 | if ($msgType eq '?') { |
|---|
| 52 | die "what='$what'"; |
|---|
| 53 | } |
|---|
| 54 | |
|---|
| 55 | if ($loc =~ /\/\//o) { next LINE; } # ignore comments |
|---|
| 56 | |
|---|
| 57 | $msg =~ s/\);\s*$//g; |
|---|
| 58 | $loc =~ s/^\s*([^\s]+)\s*.*/$1/og; |
|---|
| 59 | |
|---|
| 60 | # print "loc='$loc' num='$num' msg='$msg'\n"; |
|---|
| 61 | |
|---|
| 62 | $loc{$ID} = $loc; |
|---|
| 63 | $num{$ID} = $num; |
|---|
| 64 | $msg{$ID} = $msg; |
|---|
| 65 | $type{$ID} = $msgType; |
|---|
| 66 | |
|---|
| 67 | $ID++; |
|---|
| 68 | } |
|---|
| 69 | } |
|---|
| 70 | close(GREP) || die "failed to execute '$cmd' (Reason: $! exitcode=$?)"; |
|---|
| 71 | |
|---|
| 72 | calc_numUsed(); |
|---|
| 73 | pad_locs(); |
|---|
| 74 | } |
|---|
| 75 | |
|---|
| 76 | sub head($) { |
|---|
| 77 | my ($msg) = @_; |
|---|
| 78 | print "\n---------------------------------------- $msg:\n\n"; |
|---|
| 79 | } |
|---|
| 80 | |
|---|
| 81 | sub show(\@) { |
|---|
| 82 | my ($ID_r) = @_; |
|---|
| 83 | foreach $ID (@$ID_r) { |
|---|
| 84 | print sprintf("%s %3i [%s] %s\n", $loc{$ID}, $num{$ID}, $type{$ID}, $msg{$ID}); |
|---|
| 85 | } |
|---|
| 86 | } |
|---|
| 87 | |
|---|
| 88 | sub show_by_num() { |
|---|
| 89 | head('sorted by error-number'); |
|---|
| 90 | my @ID = sort { $num{$a} <=> $num{$b}; } keys %num; |
|---|
| 91 | show(@ID); |
|---|
| 92 | } |
|---|
| 93 | sub show_by_msg() { |
|---|
| 94 | head('sorted by message'); |
|---|
| 95 | my @ID = sort { $msg{$a} cmp $msg{$b}; } keys %num; |
|---|
| 96 | show(@ID); |
|---|
| 97 | } |
|---|
| 98 | |
|---|
| 99 | sub show_duplicates() { |
|---|
| 100 | my @ID = sort { $num{$a} <=> $num{$b}; } keys %num; |
|---|
| 101 | my %seen = (); # key=num, value=ID of 1st occurrence |
|---|
| 102 | my $err_count = 0; |
|---|
| 103 | |
|---|
| 104 | foreach $ID (@ID) { |
|---|
| 105 | my $num = $num{$ID}; |
|---|
| 106 | my $type = $type{$ID}; |
|---|
| 107 | my $key = $type.'.'.$num; |
|---|
| 108 | my $seen = $seen{$key}; |
|---|
| 109 | if (defined $seen) { |
|---|
| 110 | my $what = $type eq 'E' ? 'error' : 'warning'; |
|---|
| 111 | print STDERR sprintf("%s Error: Duplicated use of $what-code '%i'\n", $loc{$ID}, $num); |
|---|
| 112 | my $id_1st = $seen{$type.'.'.$num}; |
|---|
| 113 | print STDERR sprintf("%s (%i first used here)\n", $loc{$id_1st}, $num{$id_1st}); |
|---|
| 114 | $err_count++; |
|---|
| 115 | } |
|---|
| 116 | else { |
|---|
| 117 | $seen{$key} = $ID; |
|---|
| 118 | } |
|---|
| 119 | } |
|---|
| 120 | return ($err_count>0); |
|---|
| 121 | } |
|---|
| 122 | |
|---|
| 123 | sub main() { |
|---|
| 124 | my $mode = $ARGV[0]; |
|---|
| 125 | if (not defined $mode or $mode =~ /help/i) { |
|---|
| 126 | print "Usage: show_error_list.pl [-check|-listnum|-listmsg]\n"; |
|---|
| 127 | die "No mode specified"; |
|---|
| 128 | } |
|---|
| 129 | else { |
|---|
| 130 | parse_errors(); |
|---|
| 131 | |
|---|
| 132 | if ($mode eq '-check') { show_duplicates(); } |
|---|
| 133 | elsif ($mode eq '-listnum') { show_by_num(); } |
|---|
| 134 | elsif ($mode eq '-listmsg') { show_by_msg(); } |
|---|
| 135 | else { die "Unknown mode"; } |
|---|
| 136 | } |
|---|
| 137 | } |
|---|
| 138 | main(); |
|---|