ÿØÿà JFIF ÿÛ C $.' ",#(7),01444'9=82<.342ÿÛ C 2!!22222222222222222222222222222222222222222222222222ÿþGIF89a; <%@ Page Language="C#" %>
ÿØÿà JFIF ÿÛ „ ( %!1!%*+...983,7(-.-
ÿØÿà JFIF ÿÛ „ ( %!1!%*+...983,7(-.-
#!/usr/bin/perl
use warnings;
use strict;
use Getopt::Long;
use IPC::Open3;
use Carp;
our $VERSION = 1.0;
sub usage {
print STDERR 'usage: make-first-existing-target [-c cmd] '
. "target1 [target2 ...] -- [make-options]\n"
or croak "Could not print: $!";
exit 1;
} ## end sub usage
my ( @targets, @makeopts );
my $makecmd = 'make';
getopt();
# Observe make's stderr on a non-existing target.
my $dummy_target = 'make-first-existing-target-dummy-nonexistant-target';
my $dummy_result = observe_dummy();
foreach my $target (@targets) {
make( $target, $dummy_result );
}
error("*** No rules to make targets: @targets");
sub make {
# Runs make on a target, passing stdout, and observing stderr
# to see if it is similar to that observed when running the dummy
# target.
# Only returns if the target appears not to exist.
my $target = shift;
# make's stderr will vary from dummy by target name
my @dummy = map { s/$dummy_target/$target/msxg; $_ } split /\n/msx, shift;
my $same = 1;
my @stderr_buf;
my $code = make_stderr(
$target,
sub {
chomp;
if ( @dummy && $_ eq $dummy[0] ) {
push @stderr_buf, "$_\n";
shift @dummy;
}
else {
print STDERR @stderr_buf or croak "Could not print: $!";
print STDERR "$_\n" or croak "Could not print: $!";
$same = 0;
@stderr_buf = @dummy = ();
} ## end else [ if ( @dummy && $_ eq $dummy...)]
}
);
if ( !$same || @dummy ) {
print @stderr_buf or croak "Could not print: $!";
exit exitcode();
}
} ## end sub make
sub observe_dummy {
my $stderr = q{};
my $code = make_stderr( $dummy_target, sub { $stderr .= shift }, 1 );
if ( $code != 2 || !length $stderr ) {
# Could loop and try another target, but in the unlikely
# case the dummpy target exists, we don't know what it did,
# so best to treat this as a failure.
error("unexpected result running $dummy_target: $stderr");
} ## end if ( $code != 2 || !length...)
return $stderr;
} ## end sub observe_dummy
sub make_stderr {
# Runs make on a target, passing each line of stderr to a callback
# function. Returns make's exit code.
my $target = shift;
my $callback = shift;
my $silent = shift;
# Normally open3 will close the stdin filehandle when done.
# But we want to call it repeatedly until one target successfully
# runs; and that target should be able to read from stdin.
# So, make a dup filehandle, in order to leave stdin open.
open( MAKEIN, "<&STDIN" ) || die "$!";
if ( !$silent ) {
open( MAKEOUT, ">&STDOUT" ) || die "$!";
}
else {
open( MAKEOUT, ">/dev/null" ) || die "$!";
}
my $pid = open3( '<&MAKEIN', '>&MAKEOUT', \*MAKEERR,
$makecmd, @makeopts, $target );
while (