Russ Cox | d8b461d | 2009-10-09 00:39:32 -0700 | [diff] [blame] | 1 | #!/usr/bin/perl |
Ian Lance Taylor | 66b261a | 2008-09-19 14:39:49 -0700 | [diff] [blame] | 2 | # Copyright 2009 The Go Authors. All rights reserved. |
| 3 | # Use of this source code is governed by a BSD-style |
| 4 | # license that can be found in the LICENSE file. |
| 5 | |
Eoghan Sherry | 802360e | 2010-12-07 15:28:21 -0500 | [diff] [blame] | 6 | # This script checks that the compilers emit the errors which we expect. |
| 7 | # Usage: errchk COMPILER [OPTS] SOURCEFILES. This will run the command |
| 8 | # COMPILER [OPTS] SOURCEFILES. The compilation is expected to fail; if |
| 9 | # it succeeds, this script will report an error. The stderr output of |
| 10 | # the compiler will be matched against comments in SOURCEFILES. For each |
| 11 | # line of the source files which should generate an error, there should |
| 12 | # be a comment of the form // ERROR "regexp". If the compiler generates |
| 13 | # an error for a line which has no such comment, this script will report |
| 14 | # an error. Likewise if the compiler does not generate an error for a |
| 15 | # line which has a comment, or if the error message does not match the |
| 16 | # <regexp>. The <regexp> syntax is Perl but its best to stick to egrep. |
Ian Lance Taylor | 66b261a | 2008-09-19 14:39:49 -0700 | [diff] [blame] | 17 | |
Russ Cox | d8b461d | 2009-10-09 00:39:32 -0700 | [diff] [blame] | 18 | use POSIX; |
Ian Lance Taylor | 66b261a | 2008-09-19 14:39:49 -0700 | [diff] [blame] | 19 | |
Russ Cox | d8b461d | 2009-10-09 00:39:32 -0700 | [diff] [blame] | 20 | if(@ARGV < 1) { |
Eoghan Sherry | 802360e | 2010-12-07 15:28:21 -0500 | [diff] [blame] | 21 | print STDERR "Usage: errchk COMPILER [OPTS] SOURCEFILES\n"; |
Russ Cox | d8b461d | 2009-10-09 00:39:32 -0700 | [diff] [blame] | 22 | exit 1; |
Russ Cox | 925454e | 2008-10-17 07:41:18 -0700 | [diff] [blame] | 23 | } |
| 24 | |
Eoghan Sherry | 802360e | 2010-12-07 15:28:21 -0500 | [diff] [blame] | 25 | # Grab SOURCEFILES |
| 26 | foreach(reverse 0 .. @ARGV-1) { |
| 27 | unless($ARGV[$_] =~ /\.go$/) { |
| 28 | @file = @ARGV[$_+1 .. @ARGV-1]; |
| 29 | last; |
| 30 | } |
| 31 | } |
| 32 | |
| 33 | foreach $file (@file) { |
| 34 | open(SRC, $file) || die "BUG: errchk: open $file: $!"; |
| 35 | $src{$file} = [<SRC>]; |
| 36 | close(SRC); |
| 37 | } |
Ian Lance Taylor | 66b261a | 2008-09-19 14:39:49 -0700 | [diff] [blame] | 38 | |
Russ Cox | d8b461d | 2009-10-09 00:39:32 -0700 | [diff] [blame] | 39 | # Run command |
| 40 | $cmd = join(' ', @ARGV); |
Russ Cox | 7b5da35 | 2009-10-09 16:44:40 -0700 | [diff] [blame] | 41 | open(CMD, "exec $cmd </dev/null 2>&1 |") || die "BUG: errchk: run $cmd: $!"; |
Russ Cox | 37c531f | 2010-06-20 12:05:43 -0700 | [diff] [blame] | 42 | |
| 43 | # 6g error messages continue onto additional lines with leading tabs. |
| 44 | # Split the output at the beginning of each line that doesn't begin with a tab. |
| 45 | $out = join('', <CMD>); |
| 46 | @out = split(/^(?!\t)/m, $out); |
| 47 | |
Russ Cox | d8b461d | 2009-10-09 00:39:32 -0700 | [diff] [blame] | 48 | close CMD; |
Ian Lance Taylor | 66b261a | 2008-09-19 14:39:49 -0700 | [diff] [blame] | 49 | |
Russ Cox | d8b461d | 2009-10-09 00:39:32 -0700 | [diff] [blame] | 50 | if($? == 0) { |
| 51 | print STDERR "BUG: errchk: command succeeded unexpectedly\n"; |
| 52 | print STDERR @out; |
| 53 | exit 0; |
| 54 | } |
| 55 | |
| 56 | if(!WIFEXITED($?)) { |
| 57 | print STDERR "BUG: errchk: compiler crashed\n"; |
Russ Cox | 7b5da35 | 2009-10-09 16:44:40 -0700 | [diff] [blame] | 58 | print STDERR @out, "\n"; |
Russ Cox | d8b461d | 2009-10-09 00:39:32 -0700 | [diff] [blame] | 59 | exit 0; |
| 60 | } |
| 61 | |
| 62 | sub bug() { |
| 63 | if(!$bug++) { |
| 64 | print STDERR "BUG: "; |
| 65 | } |
| 66 | } |
| 67 | |
Eoghan Sherry | 802360e | 2010-12-07 15:28:21 -0500 | [diff] [blame] | 68 | sub chk { |
| 69 | my $file = shift; |
| 70 | my $line = 0; |
| 71 | my $regexp; |
| 72 | my @errmsg; |
| 73 | my @match; |
| 74 | foreach my $src (@{$src{$file}}) { |
| 75 | $line++; |
Russ Cox | f4e76d8 | 2011-01-31 18:36:28 -0500 | [diff] [blame] | 76 | next if $src =~ m|////|; # double comment disables ERROR |
Eoghan Sherry | 802360e | 2010-12-07 15:28:21 -0500 | [diff] [blame] | 77 | next unless $src =~ m|// (GC_)?ERROR (.*)|; |
| 78 | $regexp = $2; |
| 79 | if($regexp !~ /^"([^"]*)"/) { |
| 80 | print STDERR "$file:$line: malformed regexp\n"; |
| 81 | next; |
| 82 | } |
| 83 | $regexp = $1; |
Russ Cox | e0a6174 | 2011-06-20 14:06:00 -0400 | [diff] [blame^] | 84 | |
| 85 | # Turn relative line number in message into absolute line number. |
| 86 | if($regexp =~ /LINE(([+-])([0-9]+))?/) { |
| 87 | my $n = $line; |
| 88 | if(defined($1)) { |
| 89 | if($2 eq "+") { |
| 90 | $n += int($3); |
| 91 | } else { |
| 92 | $n -= int($3); |
| 93 | } |
| 94 | } |
| 95 | $regexp = "$`$file:$n$'"; |
| 96 | } |
Russ Cox | d8b461d | 2009-10-09 00:39:32 -0700 | [diff] [blame] | 97 | |
Eoghan Sherry | 802360e | 2010-12-07 15:28:21 -0500 | [diff] [blame] | 98 | @errmsg = grep { /$file:$line[:[]/ } @out; |
| 99 | @out = grep { !/$file:$line[:[]/ } @out; |
| 100 | if(@errmsg == 0) { |
| 101 | bug(); |
| 102 | print STDERR "errchk: $file:$line: missing expected error: '$regexp'\n"; |
| 103 | next; |
| 104 | } |
| 105 | @match = grep { /$regexp/ } @errmsg; |
| 106 | if(@match == 0) { |
| 107 | bug(); |
| 108 | print STDERR "errchk: $file:$line: error message does not match '$regexp'\n"; |
Russ Cox | e0a6174 | 2011-06-20 14:06:00 -0400 | [diff] [blame^] | 109 | foreach my $l (@errmsg) { |
| 110 | print STDERR "> $l"; |
| 111 | } |
Eoghan Sherry | 802360e | 2010-12-07 15:28:21 -0500 | [diff] [blame] | 112 | next; |
| 113 | } |
Russ Cox | d8b461d | 2009-10-09 00:39:32 -0700 | [diff] [blame] | 114 | } |
Eoghan Sherry | 802360e | 2010-12-07 15:28:21 -0500 | [diff] [blame] | 115 | } |
| 116 | |
| 117 | foreach $file (@file) { |
| 118 | chk($file) |
Russ Cox | d8b461d | 2009-10-09 00:39:32 -0700 | [diff] [blame] | 119 | } |
| 120 | |
| 121 | if(@out != 0) { |
| 122 | bug(); |
Eoghan Sherry | 802360e | 2010-12-07 15:28:21 -0500 | [diff] [blame] | 123 | print STDERR "errchk: unmatched error messages:\n"; |
Russ Cox | d8b461d | 2009-10-09 00:39:32 -0700 | [diff] [blame] | 124 | print STDERR "==================================================\n"; |
| 125 | print STDERR @out; |
| 126 | print STDERR "==================================================\n"; |
| 127 | } |
| 128 | |
| 129 | exit 0; |