diff options
author | aquanight <aquanight@e03df62e-2008-0410-955e-edbf42e46eb7> | 2008-02-09 01:55:31 +0000 |
---|---|---|
committer | aquanight <aquanight@e03df62e-2008-0410-955e-edbf42e46eb7> | 2008-02-09 01:55:31 +0000 |
commit | 6650ab5cb5a7836569c553b4f756332be5f86beb (patch) | |
tree | f123959b09059658b76e016a4d1a7a14ca8b3864 /run-cc.pl | |
parent | 18154f4d229cf8ebdcec0dac671ad6e2e0049fee (diff) |
Add a perl script which will abort compiles for warning messages that don't have a switch to convert to errors (like the one about non-PODs through ...)
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@8855 e03df62e-2008-0410-955e-edbf42e46eb7
Diffstat (limited to 'run-cc.pl')
-rwxr-xr-x | run-cc.pl | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/run-cc.pl b/run-cc.pl new file mode 100755 index 000000000..29af15393 --- /dev/null +++ b/run-cc.pl @@ -0,0 +1,100 @@ +#!/usr/bin/perl + +### THIS IS DESIGNED TO BE RUN BY MAKE! DO NOT RUN FROM THE SHELL (because it MIGHT sigterm the shell)! ### + +use strict; +use warnings FATAL => qw(all); + +use POSIX (); + +# Runs the compiler, passing it the given arguments. +# Filters select output from the compiler's standard error channel and +# can take different actions as a result. + +# NOTE: this is *NOT* a hash (sadly: a hash would stringize all the regexes and thus render them useless, plus you can't index a hash based on regexes anyway) +# even though we use the => in it. + +# The subs are passed the message, and anything the regex captured. + +my @msgfilters = ( + [ qr/^(.*) warning: cannot pass objects of non-POD type `(.*)' through `\.\.\.'; call will abort at runtime/ => sub { + my ($msg, $where, $type) = @_; + my $errstr = "$where error: cannot pass objects of non-POD type `$type' through `...'\n"; + if ($type =~ m/::string/) { + $errstr .= "$where (Did you forget to call c_str()?)\n"; + } + die $errstr; + } ], +); + +my $pid; + +my ($r_stderr, $w_stderr); + +my $cc = shift(@ARGV); + +if (!defined($cc) || $cc eq "") { + die "Compiler not specified!\n"; +} + +pipe($r_stderr, $w_stderr) or die "pipe stderr: $!\n"; + +$pid = fork; + +die "Cannot fork to start gcc! $!\n" unless defined($pid); + +if ($pid) { + my $fail = 0; + # Parent - Close child-side pipes. + close $w_stderr; + # Close STDIN to ensure no conflicts with child. + close STDIN; + # Now read each line of stderr +LINE: while (defined(my $line = <$r_stderr>)) { + chomp $line; + for my $filter (@msgfilters) { + my @caps; + if (@caps = ($line =~ $filter->[0])) { + $@ = ""; + eval { + $filter->[1]->($line, @caps); + }; + if ($@) { + $fail = 1; + print STDERR $@; + } + next LINE; + } + } + print STDERR "$line\n"; + } + waitpid $pid, 0; + close $r_stderr; + my $exit = $?; + # Simulate the same exit, so make gets the right termination info. + if (POSIX::WIFSIGNALED($exit)) { + # Make won't get the right termination info (it gets ours, not the compiler's), so we must tell the user what really happened ourselves! + print STDERR "$cc killed by signal " . POSIX::WTERMSIGN($exit) . "\n"; + kill "TERM", getppid(); # Needed for bsd make. + kill "TERM", $$; + } + else { + if (POSIX::WEXITSTATUS($exit) == 0) { + if ($fail) { + kill "TERM", getppid(); # Needed for bsd make. + kill "TERM", $$; + } + exit 0; + } else { + exit POSIX::WEXITSTATUS($exit); + } + } +} else { + # Child - Close parent-side pipes. + close $r_stderr; + # Divert stderr + open STDERR, ">&", $w_stderr or die "Cannot divert STDERR: $!\n"; + # Run the compiler! + exec { $cc } $cc, @ARGV; + die "exec $cc: $!\n"; +} |