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(); |
---|