#! /usr/bin/perl use POSIX; use Fcntl; use File::Temp; use Getopt::Long; if ($0 =~ /autoconf$/) { $mode = 'autoconf'; } elsif ($0 =~ /autoheader$/) { $mode = 'autoheader'; } elsif ($0 =~ /autoreconf$/) { $mode = 'autoreconf'; } else { die "autoconf-wrapper: unrecognized mode '$0'\n"; } OPTION: for ($i = 0; $i <= $#ARGV; $i++) { $_ = $arg = $ARGV[$i]; # --install was added to autoreconf around version 2.50 if ($mode eq 'autoreconf' && $arg eq '--install') { ac250 (); } # Most options don't tell us anything or need any special handling. elsif (/--v.+/ || $arg eq '-V' || $arg eq '--verbose' || $arg eq '-v' || /^--h.+/ || $arg eq '-h' || $arg eq '--debug' || $arg eq '-d' || /^--output=/ || /^-o.+/ || $arg eq '--force' || $arg eq '-f' || $arg eq '--install' || $arg eq '-i' || $arg eq '--symlink' || $arg eq '-s' || /^--m4dir=/ || /^-M.+/ || $arg eq '--cygnus' || $arg eq '--foreign' || $arg eq '--gnits' || $arg eq '--gnu' || $arg eq '--include-deps' || $arg eq '-i' ) { # Nothing to do } # We need to know the macro dir in order to properly search for aclocal.m4. # Only a fsckwit would use --macrodir to find aclocal.m4, but I'm trying # to be bug-for-bug compatible here. elsif ($arg eq '--macrodir' || $arg eq '-m') { $macrodir = $ARGV[$i++]; } elsif (/^--macrodir=(.*)$/ || /^-m(.+)$/) { $macrodir = $1; } # Ditto for the local dir. elsif ($arg eq '--localdir' || $arg eq '-l') { $localdir = $ARGV[$i++]; } elsif (/^--localdir=(.*)$/ || /^-l(.+)$/) { $localdir = $1; } # Some options require that we skip the next argument too. elsif ($arg eq '--output' || $arg eq '-o' ) { $i++; } # Some options are new in autoconf 2.50, so we know what version to use. elsif (/^--trace/ || /^-t/ || /^--autoconf-dir/ || /^-A/ || $arg eq '--initialization' || $arg eq '-i' || $arg eq '--m4dir' || $arg eq '-M' || /^--warnings=/ || /^-W.+/ || $arg eq '-W' || /^--include=/ || /^-I.+/ || $arg eq '-I' || /^--prepend-include=/ || /^-B.+/ || $arg eq '-B' ) { ac250 (); } # -- causes us to stop option processing. elsif ($arg eq '--') { for ($i++; $i <= $#ARGV; $i++) { nonoption_arg ($arg); } last OPTION; } # Check for an option we don't understand. elsif (/^-.+/) { print "autoconf-wrapper: unrecognized option $arg\n"; } # Otherwise, it's a nonoption argument. else { nonoption_arg ($arg); } } # If no input file was passed on the command line, # find the default. if (!defined ($infile)) { if (-e 'configure.ac') { $infile = 'configure.ac'; } elsif (-e 'configure.in') { $infile = 'configure.in'; } elsif ($mode eq 'autoreconf') { # A cop-out, but autoreconf is pretty uncommon in practice. ac213 (); } } if (defined ($infile)) { # Assume an input file ending in .ac is 2.50, # because that extension was introduced after 2.13. if ($infile =~ /\.ac$/) { ac250 (); } # If the input file is stdin, copy it to a temporary file. if ($infile eq '-') { ($fh) = File::Temp::tmpfile (); fcntl ($fh, F_SETFD, fcntl ($fh, F_GETFD, 0) & ~FD_CLOEXEC); while () { print $fh $_; } seek ($fh, SEEK_SET, 0); } else { $fh = 'INFILE'; open ($fh, "<$infile") || die "autoconf-wrapper: $infile: $!\n"; } # Read the input file and check for AC_PREREQ calls. check_fh (); if ($infile ne '-') { close ($fh); } # Check aclocal.m4, too. check_file ('aclocal.m4'); # Check include files, recursively, too. while (@included_files) { my ($filename) = pop (@included_files); check_file ($filename); } } # Default to 2.13. ac213 (); # Check the specified file for AC_PREREQ and include directives. # Searches the m4 include path to find the file. sub check_file { my ($basename) = @_; my ($filename); if (-e $basename) { $filename = $basename; } else { foreach $dir ($macrodir, $localdir, split (/:/, $ENV{'M4PATH'})) { my ($try) = "$dir/basename"; if (-e $try) { $filename = $try; last; } } } if (defined ($filename)) { $fh = 'INFILE'; open ($fh, "<$filename") || die ("autoconf-wrapper: $filename: $!\n"); check_fh (); close ($fh); } } # Checks $fh for a line containing a v2.50+ AC_PREREQ call # and adds any not-yet-processed included files to @included_files. sub check_fh { while (<$fh>) { if (/AC_PREREQ\s*\(\s*\[?\s*2\.(\d+).*\)/) { $prematch = $`; if (!($prematch =~ /(\bdnl\b)|#/)) { if ($1 > 13) { ac250 (); } } } elsif (/\bs?include\((.*)\)/) { push (@included_files, $1) unless $checked_files{$1}; $checked_files{$1} = 1; } } } # Handle nonoption argument. sub nonoption_arg { my ($arg) = @_; die "autoconf-wrapper: invalid number of arguments\n" if defined ($infile) || $mode eq 'autoreconf'; $infile = $arg; } sub ac213 { run_autoconf ("/usr/bin/${mode}2.13"); } sub ac250 { run_autoconf ("/usr/bin/${mode}2.59"); } sub run_autoconf { my ($binary) = @_; # If we read input from stdin, rewind the temporary file # and make the temporary stream available as a new stdin. if ($infile eq '-') { seek ($fh, SEEK_SET, 0); dup2 (fileno ($fh), 0); } #print STDERR "autoconf-wrapper: executing $binary\n"; exec { $binary } $binary, @ARGV; die "couldn't exec $binary: $!"; }