Blame bin/autoscan.in

Packit Service 9646c7
#! @PERL@ -w
Packit Service 9646c7
# -*- perl -*-
Packit Service 9646c7
# @configure_input@
Packit Service 9646c7
Packit Service 9646c7
# autoscan - Create configure.scan (a preliminary configure.ac) for a package.
Packit Service 9646c7
# Copyright (C) 1994, 1999-2012 Free Software Foundation, Inc.
Packit Service 9646c7
Packit Service 9646c7
# This program is free software: you can redistribute it and/or modify
Packit Service 9646c7
# it under the terms of the GNU General Public License as published by
Packit Service 9646c7
# the Free Software Foundation, either version 3 of the License, or
Packit Service 9646c7
# (at your option) any later version.
Packit Service 9646c7
Packit Service 9646c7
# This program is distributed in the hope that it will be useful,
Packit Service 9646c7
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 9646c7
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 9646c7
# GNU General Public License for more details.
Packit Service 9646c7
Packit Service 9646c7
# You should have received a copy of the GNU General Public License
Packit Service 9646c7
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit Service 9646c7
Packit Service 9646c7
# Written by David MacKenzie <djm@gnu.ai.mit.edu>.
Packit Service 9646c7
Packit Service 9646c7
eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac'
Packit Service 9646c7
    if 0;
Packit Service 9646c7
Packit Service 9646c7
BEGIN
Packit Service 9646c7
{
Packit Service 9646c7
  my $pkgdatadir = $ENV{'autom4te_perllibdir'} || '@pkgdatadir@';
Packit Service 9646c7
  unshift @INC, $pkgdatadir;
Packit Service 9646c7
Packit Service 9646c7
  # Override SHELL.  On DJGPP SHELL may not be set to a shell
Packit Service 9646c7
  # that can handle redirection and quote arguments correctly,
Packit Service 9646c7
  # e.g.: COMMAND.COM.  For DJGPP always use the shell that configure
Packit Service 9646c7
  # has detected.
Packit Service 9646c7
  $ENV{'SHELL'} = '@SHELL@' if ($^O eq 'dos');
Packit Service 9646c7
}
Packit Service 9646c7
Packit Service 9646c7
use Autom4te::ChannelDefs;
Packit Service 9646c7
use Autom4te::Configure_ac;
Packit Service 9646c7
use Autom4te::General;
Packit Service 9646c7
use Autom4te::FileUtils;
Packit Service 9646c7
use Autom4te::XFile;
Packit Service 9646c7
use File::Basename;
Packit Service 9646c7
use File::Find;
Packit Service 9646c7
use strict;
Packit Service 9646c7
Packit Service 9646c7
use vars qw(@cfiles @makefiles @shfiles @subdirs %printed);
Packit Service 9646c7
Packit Service 9646c7
# The kind of the words we are looking for.
Packit Service 9646c7
my @kinds = qw (function header identifier program
Packit Service 9646c7
		makevar librarie);
Packit Service 9646c7
Packit Service 9646c7
# For each kind, the default macro.
Packit Service 9646c7
my %generic_macro =
Packit Service 9646c7
  (
Packit Service 9646c7
   'function'   => 'AC_CHECK_FUNCS',
Packit Service 9646c7
   'header'     => 'AC_CHECK_HEADERS',
Packit Service 9646c7
   'identifier' => 'AC_CHECK_TYPES',
Packit Service 9646c7
   'program'    => 'AC_CHECK_PROGS',
Packit Service 9646c7
   'library'    => 'AC_CHECK_LIB'
Packit Service 9646c7
  );
Packit Service 9646c7
Packit Service 9646c7
my %kind_comment =
Packit Service 9646c7
  (
Packit Service 9646c7
   'function'   => 'Checks for library functions.',
Packit Service 9646c7
   'header'     => 'Checks for header files.',
Packit Service 9646c7
   'identifier' => 'Checks for typedefs, structures, and compiler characteristics.',
Packit Service 9646c7
   'program'    => 'Checks for programs.',
Packit Service 9646c7
  );
Packit Service 9646c7
Packit Service 9646c7
# $USED{KIND}{ITEM} is the list of locations where the ITEM (of KIND) was used
Packit Service 9646c7
# in the user package.
Packit Service 9646c7
# For instance $USED{function}{alloca} is the list of `file:line' where
Packit Service 9646c7
# `alloca (...)' appears.
Packit Service 9646c7
my %used = ();
Packit Service 9646c7
Packit Service 9646c7
# $MACRO{KIND}{ITEM} is the list of macros to use to test ITEM.
Packit Service 9646c7
# Initialized from lib/autoscan/*.  E.g., $MACRO{function}{alloca} contains
Packit Service 9646c7
# the singleton AC_FUNC_ALLOCA.  Some require several checks.
Packit Service 9646c7
my %macro = ();
Packit Service 9646c7
Packit Service 9646c7
# $NEEDED_MACROS{MACRO} is an array of locations requiring MACRO.
Packit Service 9646c7
# E.g., $NEEDED_MACROS{AC_FUNC_ALLOC} the list of `file:line' containing
Packit Service 9646c7
# `alloca (...)'.
Packit Service 9646c7
my %needed_macros =
Packit Service 9646c7
  (
Packit Service 9646c7
   'AC_PREREQ' => [$me],
Packit Service 9646c7
  );
Packit Service 9646c7
Packit Service 9646c7
my $configure_scan = 'configure.scan';
Packit Service 9646c7
my $log;
Packit Service 9646c7
Packit Service 9646c7
# Autoconf and lib files.
Packit Service 9646c7
my $autom4te = $ENV{'AUTOM4TE'} || '@bindir@/@autom4te-name@';
Packit Service 9646c7
my $autoconf = "$autom4te --language=autoconf";
Packit Service 9646c7
my @prepend_include;
Packit Service 9646c7
my @include = ('@pkgdatadir@');
Packit Service 9646c7
Packit Service 9646c7
# $help
Packit Service 9646c7
# -----
Packit Service 9646c7
$help = "Usage: $0 [OPTION]... [SRCDIR]
Packit Service 9646c7
Packit Service 9646c7
Examine source files in the directory tree rooted at SRCDIR, or the
Packit Service 9646c7
current directory if none is given.  Search the source files for
Packit Service 9646c7
common portability problems, check for incompleteness of
Packit Service 9646c7
`configure.ac', and create a file `$configure_scan' which is a
Packit Service 9646c7
preliminary `configure.ac' for that package.
Packit Service 9646c7
Packit Service 9646c7
  -h, --help          print this help, then exit
Packit Service 9646c7
  -V, --version       print version number, then exit
Packit Service 9646c7
  -v, --verbose       verbosely report processing
Packit Service 9646c7
  -d, --debug         don't remove temporary files
Packit Service 9646c7
Packit Service 9646c7
Library directories:
Packit Service 9646c7
  -B, --prepend-include=DIR  prepend directory DIR to search path
Packit Service 9646c7
  -I, --include=DIR          append directory DIR to search path
Packit Service 9646c7
Packit Service 9646c7
Report bugs to <bug-autoconf\@gnu.org>.
Packit Service 9646c7
GNU Autoconf home page: <http://www.gnu.org/software/autoconf/>.
Packit Service 9646c7
General help using GNU software: <http://www.gnu.org/gethelp/>.
Packit Service 9646c7
";
Packit Service 9646c7
Packit Service 9646c7
# $version
Packit Service 9646c7
# --------
Packit Service 9646c7
$version = "autoscan (@PACKAGE_NAME@) @VERSION@
Packit Service 9646c7
Copyright (C) @RELEASE_YEAR@ Free Software Foundation, Inc.
Packit Service 9646c7
License GPLv3+/Autoconf: GNU GPL version 3 or later
Packit Service 9646c7
<http://gnu.org/licenses/gpl.html>, <http://gnu.org/licenses/exceptions.html>
Packit Service 9646c7
This is free software: you are free to change and redistribute it.
Packit Service 9646c7
There is NO WARRANTY, to the extent permitted by law.
Packit Service 9646c7
Packit Service 9646c7
Written by David J. MacKenzie and Akim Demaille.
Packit Service 9646c7
";
Packit Service 9646c7
Packit Service 9646c7
Packit Service 9646c7
Packit Service 9646c7
Packit Service 9646c7
## ------------------------ ##
Packit Service 9646c7
## Command line interface.  ##
Packit Service 9646c7
## ------------------------ ##
Packit Service 9646c7
Packit Service 9646c7
# parse_args ()
Packit Service 9646c7
# -------------
Packit Service 9646c7
# Process any command line arguments.
Packit Service 9646c7
sub parse_args ()
Packit Service 9646c7
{
Packit Service 9646c7
  getopt ('I|include=s' => \@include,
Packit Service 9646c7
	  'B|prepend-include=s' => \@prepend_include);
Packit Service 9646c7
Packit Service 9646c7
  die "$me: too many arguments
Packit Service 9646c7
Try `$me --help' for more information.\n"
Packit Service 9646c7
    if @ARGV > 1;
Packit Service 9646c7
Packit Service 9646c7
  my $srcdir = $ARGV[0] || ".";
Packit Service 9646c7
Packit Service 9646c7
  verb "srcdir = $srcdir";
Packit Service 9646c7
  chdir $srcdir || error "cannot cd to $srcdir: $!";
Packit Service 9646c7
}
Packit Service 9646c7
Packit Service 9646c7
Packit Service 9646c7
# init_tables ()
Packit Service 9646c7
# --------------
Packit Service 9646c7
# Put values in the tables of what to do with each token.
Packit Service 9646c7
sub init_tables ()
Packit Service 9646c7
{
Packit Service 9646c7
  # The data file format supports only one line of macros per function.
Packit Service 9646c7
  # If more than that is required for a common portability problem,
Packit Service 9646c7
  # a new Autoconf macro should probably be written for that case,
Packit Service 9646c7
  # instead of duplicating the code in lots of configure.ac files.
Packit Service 9646c7
  my $file = find_file ("autoscan/autoscan.list",
Packit Service 9646c7
			reverse (@prepend_include), @include);
Packit Service 9646c7
  my $table = new Autom4te::XFile "< " . open_quote ($file);
Packit Service 9646c7
  my $tables_are_consistent = 1;
Packit Service 9646c7
Packit Service 9646c7
  while ($_ = $table->getline)
Packit Service 9646c7
    {
Packit Service 9646c7
      # Ignore blank lines and comments.
Packit Service 9646c7
      next
Packit Service 9646c7
	if /^\s*$/ || /^\s*\#/;
Packit Service 9646c7
Packit Service 9646c7
      # '<kind>: <word> <macro invocation>' or...
Packit Service 9646c7
      # '<kind>: <word> warn: <message>'.
Packit Service 9646c7
      if (/^(\S+):\s+(\S+)\s+(\S.*)$/)
Packit Service 9646c7
	{
Packit Service 9646c7
	  my ($kind, $word, $macro) = ($1, $2, $3);
Packit Service 9646c7
	  error "$file:$.: invalid kind: $_"
Packit Service 9646c7
	    unless grep { $_ eq $kind } @kinds;
Packit Service 9646c7
	  push @{$macro{$kind}{$word}}, $macro;
Packit Service 9646c7
	}
Packit Service 9646c7
      else
Packit Service 9646c7
	{
Packit Service 9646c7
	  error "$file:$.: invalid definition: $_";
Packit Service 9646c7
	}
Packit Service 9646c7
    }
Packit Service 9646c7
Packit Service 9646c7
  if ($debug)
Packit Service 9646c7
    {
Packit Service 9646c7
      foreach my $kind (@kinds)
Packit Service 9646c7
	{
Packit Service 9646c7
	  foreach my $word (sort keys %{$macro{$kind}})
Packit Service 9646c7
	    {
Packit Service 9646c7
	      print "$kind: $word: @{$macro{$kind}{$word}}\n";
Packit Service 9646c7
	    }
Packit Service 9646c7
	}
Packit Service 9646c7
Packit Service 9646c7
    }
Packit Service 9646c7
}
Packit Service 9646c7
Packit Service 9646c7
Packit Service 9646c7
# used ($KIND, $WORD, [$WHERE])
Packit Service 9646c7
# -----------------------------
Packit Service 9646c7
# $WORD is used as a $KIND.
Packit Service 9646c7
sub used ($$;$)
Packit Service 9646c7
{
Packit Service 9646c7
  my ($kind, $word, $where) = @_;
Packit Service 9646c7
  $where ||= "$File::Find::name:$.";
Packit Service 9646c7
  if (
Packit Service 9646c7
      # Check for all the libraries.  But `-links' is certainly a
Packit Service 9646c7
      # `find' argument, and `-le', a `test' argument.
Packit Service 9646c7
      ($kind eq 'library' && $word !~ /^(e|inks)$/)
Packit Service 9646c7
      # Other than libraries are to be checked only if listed in
Packit Service 9646c7
      # the Autoscan library files.
Packit Service 9646c7
      || defined $macro{$kind}{$word}
Packit Service 9646c7
     )
Packit Service 9646c7
    {
Packit Service 9646c7
      push (@{$used{$kind}{$word}}, $where);
Packit Service 9646c7
    }
Packit Service 9646c7
}
Packit Service 9646c7
Packit Service 9646c7
Packit Service 9646c7
Packit Service 9646c7
## ----------------------- ##
Packit Service 9646c7
## Scanning source files.  ##
Packit Service 9646c7
## ----------------------- ##
Packit Service 9646c7
Packit Service 9646c7
Packit Service 9646c7
# scan_c_file ($FILE-NAME)
Packit Service 9646c7
# ------------------------
Packit Service 9646c7
sub scan_c_file ($)
Packit Service 9646c7
{
Packit Service 9646c7
  my ($file_name) = @_;
Packit Service 9646c7
  push @cfiles, $File::Find::name;
Packit Service 9646c7
Packit Service 9646c7
  # Nonzero if in a multiline comment.
Packit Service 9646c7
  my $in_comment = 0;
Packit Service 9646c7
Packit Service 9646c7
  my $file = new Autom4te::XFile "< " . open_quote ($file_name);
Packit Service 9646c7
Packit Service 9646c7
  while ($_ = $file->getline)
Packit Service 9646c7
    {
Packit Service 9646c7
      # Strip out comments.
Packit Service 9646c7
      if ($in_comment && s,^.*?\*/,,)
Packit Service 9646c7
	{
Packit Service 9646c7
	  $in_comment = 0;
Packit Service 9646c7
	}
Packit Service 9646c7
      # The whole line is inside a comment.
Packit Service 9646c7
      next if $in_comment;
Packit Service 9646c7
      # All on one line.
Packit Service 9646c7
      s,/\*.*?\*/,,g;
Packit Service 9646c7
Packit Service 9646c7
      # Starting on this line.
Packit Service 9646c7
      if (s,/\*.*$,,)
Packit Service 9646c7
	{
Packit Service 9646c7
	  $in_comment = 1;
Packit Service 9646c7
	}
Packit Service 9646c7
Packit Service 9646c7
      # Preprocessor directives.
Packit Service 9646c7
      if (s/^\s*\#\s*//)
Packit Service 9646c7
	{
Packit Service 9646c7
	  if (/^include\s*<([^>]*)>/)
Packit Service 9646c7
	    {
Packit Service 9646c7
	      used ('header', $1);
Packit Service 9646c7
	    }
Packit Service 9646c7
	  if (s/^(if|ifdef|ifndef|elif)\s+//)
Packit Service 9646c7
	    {
Packit Service 9646c7
	      foreach my $word (split (/\W+/))
Packit Service 9646c7
		{
Packit Service 9646c7
		  used ('identifier', $word)
Packit Service 9646c7
		    unless $word eq 'defined' || $word !~ /^[a-zA-Z_]/;
Packit Service 9646c7
		}
Packit Service 9646c7
	    }
Packit Service 9646c7
	  # Ignore other preprocessor directives.
Packit Service 9646c7
	  next;
Packit Service 9646c7
	}
Packit Service 9646c7
Packit Service 9646c7
      # Remove string and character constants.
Packit Service 9646c7
      s,\"[^\"]*\",,g;
Packit Service 9646c7
      s,\'[^\']*\',,g;
Packit Service 9646c7
Packit Service 9646c7
      # Tokens in the code.
Packit Service 9646c7
      # Maybe we should ignore function definitions (in column 0)?
Packit Service 9646c7
      while (s/\b([a-zA-Z_]\w*)\s*\(/ /)
Packit Service 9646c7
	{
Packit Service 9646c7
	  used ('function', $1);
Packit Service 9646c7
	}
Packit Service 9646c7
      while (s/\b([a-zA-Z_]\w*)\b/ /)
Packit Service 9646c7
	{
Packit Service 9646c7
	  used ('identifier', $1);
Packit Service 9646c7
	}
Packit Service 9646c7
    }
Packit Service 9646c7
Packit Service 9646c7
  $file->close;
Packit Service 9646c7
}
Packit Service 9646c7
Packit Service 9646c7
Packit Service 9646c7
# scan_makefile($MAKEFILE-NAME)
Packit Service 9646c7
# -----------------------------
Packit Service 9646c7
sub scan_makefile ($)
Packit Service 9646c7
{
Packit Service 9646c7
  my ($file_name) = @_;
Packit Service 9646c7
  push @makefiles, $File::Find::name;
Packit Service 9646c7
Packit Service 9646c7
  my $file = new Autom4te::XFile "< " . open_quote ($file_name);
Packit Service 9646c7
Packit Service 9646c7
  while ($_ = $file->getline)
Packit Service 9646c7
    {
Packit Service 9646c7
      # Strip out comments.
Packit Service 9646c7
      s/#.*//;
Packit Service 9646c7
Packit Service 9646c7
      # Variable assignments.
Packit Service 9646c7
      while (s/\b([a-zA-Z_]\w*)\s*=/ /)
Packit Service 9646c7
	{
Packit Service 9646c7
	  used ('makevar', $1);
Packit Service 9646c7
	}
Packit Service 9646c7
      # Be sure to catch a whole word.  For instance `lex$U.$(OBJEXT)'
Packit Service 9646c7
      # is a single token.  Otherwise we might believe `lex' is needed.
Packit Service 9646c7
      foreach my $word (split (/\s+/))
Packit Service 9646c7
	{
Packit Service 9646c7
	  # Libraries.
Packit Service 9646c7
	  if ($word =~ /^-l([a-zA-Z_]\w*)$/)
Packit Service 9646c7
	    {
Packit Service 9646c7
	      used ('library', $1);
Packit Service 9646c7
	    }
Packit Service 9646c7
	  # Tokens in the code.
Packit Service 9646c7
	  # We allow some additional characters, e.g., `+', since
Packit Service 9646c7
	  # autoscan/programs includes `c++'.
Packit Service 9646c7
	  if ($word =~ /^[a-zA-Z_][\w+]*$/)
Packit Service 9646c7
	    {
Packit Service 9646c7
	      used ('program', $word);
Packit Service 9646c7
	    }
Packit Service 9646c7
	}
Packit Service 9646c7
    }
Packit Service 9646c7
Packit Service 9646c7
  $file->close;
Packit Service 9646c7
}
Packit Service 9646c7
Packit Service 9646c7
Packit Service 9646c7
# scan_sh_file($SHELL-SCRIPT-NAME)
Packit Service 9646c7
# --------------------------------
Packit Service 9646c7
sub scan_sh_file ($)
Packit Service 9646c7
{
Packit Service 9646c7
  my ($file_name) = @_;
Packit Service 9646c7
  push @shfiles, $File::Find::name;
Packit Service 9646c7
Packit Service 9646c7
  my $file = new Autom4te::XFile "< " . open_quote ($file_name);
Packit Service 9646c7
Packit Service 9646c7
  while ($_ = $file->getline)
Packit Service 9646c7
    {
Packit Service 9646c7
      # Strip out comments and variable references.
Packit Service 9646c7
      s/#.*//;
Packit Service f9ae99
      s/\$\{[^\}]*}//g;
Packit Service 9646c7
      s/@[^@]*@//g;
Packit Service 9646c7
Packit Service 9646c7
      # Tokens in the code.
Packit Service 9646c7
      while (s/\b([a-zA-Z_]\w*)\b/ /)
Packit Service 9646c7
	{
Packit Service 9646c7
	  used ('program', $1);
Packit Service 9646c7
	}
Packit Service 9646c7
    }
Packit Service 9646c7
Packit Service 9646c7
  $file->close;
Packit Service 9646c7
}
Packit Service 9646c7
Packit Service 9646c7
Packit Service 9646c7
# scan_file ()
Packit Service 9646c7
# ------------
Packit Service 9646c7
# Called by &find on each file.  $_ contains the current file name with
Packit Service 9646c7
# the current directory of the walk through.
Packit Service 9646c7
sub scan_file ()
Packit Service 9646c7
{
Packit Service 9646c7
  # Wanted only if there is no corresponding FILE.in.
Packit Service 9646c7
  return
Packit Service 9646c7
    if -f "$_.in";
Packit Service 9646c7
Packit Service 9646c7
  # Save $_ as Find::File requires it to be preserved.
Packit Service 9646c7
  local $_ = $_;
Packit Service 9646c7
Packit Service 9646c7
  # Strip a useless leading `./'.
Packit Service 9646c7
  $File::Find::name =~ s,^\./,,;
Packit Service 9646c7
Packit Service 9646c7
  if ($_ ne '.' and -d $_ and
Packit Service 9646c7
      -f "$_/configure.in"  ||
Packit Service 9646c7
      -f "$_/configure.ac"  ||
Packit Service 9646c7
      -f "$_/configure.gnu" ||
Packit Service 9646c7
      -f "$_/configure")
Packit Service 9646c7
    {
Packit Service 9646c7
      $File::Find::prune = 1;
Packit Service 9646c7
      push @subdirs, $File::Find::name;
Packit Service 9646c7
    }
Packit Service 9646c7
  if (/\.[chlym](\.in)?$/)
Packit Service 9646c7
    {
Packit Service 9646c7
      used 'program', 'cc', $File::Find::name;
Packit Service 9646c7
      scan_c_file ($_);
Packit Service 9646c7
    }
Packit Service 9646c7
  elsif (/\.(cc|cpp|cxx|CC|C|hh|hpp|hxx|HH|H|yy|ypp|ll|lpp)(\.in)?$/)
Packit Service 9646c7
    {
Packit Service 9646c7
      used 'program', 'c++', $File::Find::name;
Packit Service 9646c7
      scan_c_file ($_);
Packit Service 9646c7
    }
Packit Service 9646c7
  elsif ((/^((?:GNUm|M|m)akefile)(\.in)?$/ && ! -f "$1.am")
Packit Service 9646c7
	 || /^(?:GNUm|M|m)akefile(\.am)?$/)
Packit Service 9646c7
    {
Packit Service 9646c7
      scan_makefile ($_);
Packit Service 9646c7
    }
Packit Service 9646c7
  elsif (/\.sh(\.in)?$/)
Packit Service 9646c7
    {
Packit Service 9646c7
      scan_sh_file ($_);
Packit Service 9646c7
    }
Packit Service 9646c7
}
Packit Service 9646c7
Packit Service 9646c7
Packit Service 9646c7
# scan_files ()
Packit Service 9646c7
# -------------
Packit Service 9646c7
# Read through the files and collect lists of tokens in them
Packit Service 9646c7
# that might create nonportabilities.
Packit Service 9646c7
sub scan_files ()
Packit Service 9646c7
{
Packit Service 9646c7
  find (\&scan_file, '.');
Packit Service 9646c7
Packit Service 9646c7
  if ($verbose)
Packit Service 9646c7
    {
Packit Service 9646c7
      print "cfiles: @cfiles\n";
Packit Service 9646c7
      print "makefiles: @makefiles\n";
Packit Service 9646c7
      print "shfiles: @shfiles\n";
Packit Service 9646c7
Packit Service 9646c7
      foreach my $kind (@kinds)
Packit Service 9646c7
	{
Packit Service 9646c7
	  print "\n$kind:\n";
Packit Service 9646c7
	  foreach my $word (sort keys %{$used{$kind}})
Packit Service 9646c7
	    {
Packit Service 9646c7
	      print "$word: @{$used{$kind}{$word}}\n";
Packit Service 9646c7
	    }
Packit Service 9646c7
	}
Packit Service 9646c7
    }
Packit Service 9646c7
}
Packit Service 9646c7
Packit Service 9646c7
Packit Service 9646c7
## ----------------------- ##
Packit Service 9646c7
## Output configure.scan.  ##
Packit Service 9646c7
## ----------------------- ##
Packit Service 9646c7
Packit Service 9646c7
Packit Service 9646c7
# output_kind ($FILE, $KIND)
Packit Service 9646c7
# --------------------------
Packit Service 9646c7
sub output_kind ($$)
Packit Service 9646c7
{
Packit Service 9646c7
  my ($file, $kind) = @_;
Packit Service 9646c7
  # Lists of words to be checked with the generic macro.
Packit Service 9646c7
  my @have;
Packit Service 9646c7
Packit Service 9646c7
  print $file "\n# $kind_comment{$kind}\n"
Packit Service 9646c7
    if exists $kind_comment{$kind};
Packit Service 9646c7
  foreach my $word (sort keys %{$used{$kind}})
Packit Service 9646c7
    {
Packit Service 9646c7
      # Output the needed macro invocations in $configure_scan if not
Packit Service 9646c7
      # already printed, and remember these macros are needed.
Packit Service 9646c7
      foreach my $macro (@{$macro{$kind}{$word}})
Packit Service 9646c7
	{
Packit Service 9646c7
	  if ($macro =~ /^warn:\s+(.*)/)
Packit Service 9646c7
	    {
Packit Service 9646c7
	      my $message = $1;
Packit Service 9646c7
	      foreach my $location (@{$used{$kind}{$word}})
Packit Service 9646c7
		{
Packit Service 9646c7
		  warn "$location: warning: $message\n";
Packit Service 9646c7
		}
Packit Service 9646c7
	    }
Packit Service 9646c7
	  elsif (exists $generic_macro{$kind}
Packit Service 9646c7
	      && $macro eq $generic_macro{$kind})
Packit Service 9646c7
	    {
Packit Service 9646c7
	      push (@have, $word);
Packit Service 9646c7
	      push (@{$needed_macros{"$generic_macro{$kind}([$word])"}},
Packit Service 9646c7
		    @{$used{$kind}{$word}});
Packit Service 9646c7
	    }
Packit Service 9646c7
	  else
Packit Service 9646c7
	    {
Packit Service 9646c7
	      if (! $printed{$macro})
Packit Service 9646c7
		{
Packit Service 9646c7
		  print $file "$macro\n";
Packit Service 9646c7
		  $printed{$macro} = 1;
Packit Service 9646c7
		}
Packit Service 9646c7
	      push (@{$needed_macros{$macro}},
Packit Service 9646c7
		    @{$used{$kind}{$word}});
Packit Service 9646c7
	    }
Packit Service 9646c7
	}
Packit Service 9646c7
    }
Packit Service 9646c7
  print $file "$generic_macro{$kind}([" . join(' ', sort(@have)) . "])\n"
Packit Service 9646c7
    if @have;
Packit Service 9646c7
}
Packit Service 9646c7
Packit Service 9646c7
Packit Service 9646c7
# output_libraries ($FILE)
Packit Service 9646c7
# ------------------------
Packit Service 9646c7
sub output_libraries ($)
Packit Service 9646c7
{
Packit Service 9646c7
  my ($file) = @_;
Packit Service 9646c7
Packit Service 9646c7
  print $file "\n# Checks for libraries.\n";
Packit Service 9646c7
  foreach my $word (sort keys %{$used{'library'}})
Packit Service 9646c7
    {
Packit Service 9646c7
      print $file "# FIXME: Replace `main' with a function in `-l$word':\n";
Packit Service 9646c7
      print $file "AC_CHECK_LIB([$word], [main])\n";
Packit Service 9646c7
    }
Packit Service 9646c7
}
Packit Service 9646c7
Packit Service 9646c7
Packit Service 9646c7
# output ($CONFIGURE_SCAN)
Packit Service 9646c7
# ------------------------
Packit Service 9646c7
# Print a proto configure.ac.
Packit Service 9646c7
sub output ($)
Packit Service 9646c7
{
Packit Service 9646c7
  my $configure_scan = shift;
Packit Service 9646c7
  my %unique_makefiles;
Packit Service 9646c7
Packit Service 9646c7
  my $file = new Autom4te::XFile "> " . open_quote ($configure_scan);
Packit Service 9646c7
Packit Service 9646c7
  print $file
Packit Service 9646c7
    ("#                                               -*- Autoconf -*-\n" .
Packit Service 9646c7
     "# Process this file with autoconf to produce a configure script.\n" .
Packit Service 9646c7
     "\n" .
Packit Service 9646c7
     "AC_PREREQ([@VERSION@])\n" .
Packit Service 9646c7
     "AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])\n");
Packit Service 9646c7
  if (defined $cfiles[0])
Packit Service 9646c7
    {
Packit Service 9646c7
      print $file "AC_CONFIG_SRCDIR([$cfiles[0]])\n";
Packit Service 9646c7
      print $file "AC_CONFIG_HEADERS([config.h])\n";
Packit Service 9646c7
    }
Packit Service 9646c7
Packit Service 9646c7
  output_kind ($file, 'program');
Packit Service 9646c7
  output_kind ($file, 'makevar');
Packit Service 9646c7
  output_libraries ($file);
Packit Service 9646c7
  output_kind ($file, 'header');
Packit Service 9646c7
  output_kind ($file, 'identifier');
Packit Service 9646c7
  output_kind ($file, 'function');
Packit Service 9646c7
Packit Service 9646c7
  print $file "\n";
Packit Service 9646c7
  if (@makefiles)
Packit Service 9646c7
    {
Packit Service 9646c7
      # Change DIR/Makefile.in to DIR/Makefile.
Packit Service 9646c7
      foreach my $m (@makefiles)
Packit Service 9646c7
	{
Packit Service 9646c7
	  $m =~ s/\.(?:in|am)$//;
Packit Service 9646c7
	  $unique_makefiles{$m}++;
Packit Service 9646c7
	}
Packit Service 9646c7
      print $file ("AC_CONFIG_FILES([",
Packit Service 9646c7
		   join ("\n                 ",
Packit Service 9646c7
			 sort keys %unique_makefiles), "])\n");
Packit Service 9646c7
    }
Packit Service 9646c7
  if (@subdirs)
Packit Service 9646c7
    {
Packit Service 9646c7
      print $file ("AC_CONFIG_SUBDIRS([",
Packit Service 9646c7
		   join ("\n                   ",
Packit Service 9646c7
			 sort @subdirs), "])\n");
Packit Service 9646c7
    }
Packit Service 9646c7
  print $file "AC_OUTPUT\n";
Packit Service 9646c7
Packit Service 9646c7
  $file->close;
Packit Service 9646c7
}
Packit Service 9646c7
Packit Service 9646c7
Packit Service 9646c7
Packit Service 9646c7
## --------------------------------------- ##
Packit Service 9646c7
## Checking the accuracy of configure.ac.  ##
Packit Service 9646c7
## --------------------------------------- ##
Packit Service 9646c7
Packit Service 9646c7
Packit Service 9646c7
# &check_configure_ac ($CONFIGURE_AC)
Packit Service 9646c7
# -----------------------------------
Packit Service 9646c7
# Use autoconf to check if all the suggested macros are included
Packit Service 9646c7
# in CONFIGURE_AC.
Packit Service 9646c7
sub check_configure_ac ($)
Packit Service 9646c7
{
Packit Service 9646c7
  my ($configure_ac) = @_;
Packit Service 9646c7
Packit Service 9646c7
  # Find what needed macros are invoked in CONFIGURE_AC.
Packit Service 9646c7
  # I'd be very happy if someone could explain to me why sort (uniq ...)
Packit Service 9646c7
  # doesn't work properly: I need `uniq (sort ...)'.  --akim
Packit Service 9646c7
  my $trace_option =
Packit Service 9646c7
    join (' --trace=', '',
Packit Service 9646c7
	  uniq (sort (map { s/\(.*//; $_ } keys %needed_macros)));
Packit Service 9646c7
Packit Service 9646c7
  verb "running: $autoconf $trace_option $configure_ac";
Packit Service 9646c7
  my $traces =
Packit Service 9646c7
    new Autom4te::XFile "$autoconf $trace_option $configure_ac |";
Packit Service 9646c7
Packit Service 9646c7
  while ($_ = $traces->getline)
Packit Service 9646c7
    {
Packit Service 9646c7
      chomp;
Packit Service 9646c7
      my ($file, $line, $macro, @args) = split (/:/, $_);
Packit Service 9646c7
      if ($macro =~ /^AC_CHECK_(HEADER|FUNC|TYPE|MEMBER)S$/)
Packit Service 9646c7
	{
Packit Service 9646c7
	  # To be rigorous, we should distinguish between space and comma
Packit Service 9646c7
	  # separated macros.  But there is no point.
Packit Service 9646c7
	  foreach my $word (split (/\s|,/, $args[0]))
Packit Service 9646c7
	    {
Packit Service 9646c7
	      # AC_CHECK_MEMBERS wants `struct' or `union'.
Packit Service 9646c7
	      if ($macro eq "AC_CHECK_MEMBERS"
Packit Service 9646c7
		  && $word =~ /^stat.st_/)
Packit Service 9646c7
		{
Packit Service 9646c7
		  $word = "struct " . $word;
Packit Service 9646c7
		}
Packit Service 9646c7
	      delete $needed_macros{"$macro([$word])"};
Packit Service 9646c7
	    }
Packit Service 9646c7
	}
Packit Service 9646c7
      else
Packit Service 9646c7
	{
Packit Service 9646c7
	  delete $needed_macros{$macro};
Packit Service 9646c7
	}
Packit Service 9646c7
    }
Packit Service 9646c7
Packit Service 9646c7
  $traces->close;
Packit Service 9646c7
Packit Service 9646c7
  # Report the missing macros.
Packit Service 9646c7
  foreach my $macro (sort keys %needed_macros)
Packit Service 9646c7
    {
Packit Service 9646c7
      warn ("$configure_ac: warning: missing $macro wanted by: "
Packit Service 9646c7
	    . (${$needed_macros{$macro}}[0])
Packit Service 9646c7
	    . "\n");
Packit Service 9646c7
      print $log "$me: warning: missing $macro wanted by: \n";
Packit Service 9646c7
      foreach my $need (@{$needed_macros{$macro}})
Packit Service 9646c7
	{
Packit Service 9646c7
	  print $log "\t$need\n";
Packit Service 9646c7
	}
Packit Service 9646c7
    }
Packit Service 9646c7
}
Packit Service 9646c7
Packit Service 9646c7
Packit Service 9646c7
## -------------- ##
Packit Service 9646c7
## Main program.  ##
Packit Service 9646c7
## -------------- ##
Packit Service 9646c7
Packit Service 9646c7
parse_args;
Packit Service 9646c7
$log = new Autom4te::XFile "> " . open_quote ("$me.log");
Packit Service 9646c7
Packit Service 9646c7
$autoconf .= " --debug" if $debug;
Packit Service 9646c7
$autoconf .= " --verbose" if $verbose;
Packit Service 9646c7
$autoconf .= join (' --include=', '', map { shell_quote ($_) } @include);
Packit Service 9646c7
$autoconf .= join (' --prepend-include=', '', map { shell_quote ($_) } @prepend_include);
Packit Service 9646c7
Packit Service 9646c7
my $configure_ac = find_configure_ac;
Packit Service 9646c7
init_tables;
Packit Service 9646c7
scan_files;
Packit Service 9646c7
output ('configure.scan');
Packit Service 9646c7
if (-f $configure_ac)
Packit Service 9646c7
  {
Packit Service 9646c7
    check_configure_ac ($configure_ac);
Packit Service 9646c7
  }
Packit Service 9646c7
# This close is really needed.  For some reason, probably best named
Packit Service 9646c7
# a bug, it seems that the dtor of $LOG is not called automatically
Packit Service 9646c7
# at END.  It results in a truncated file.
Packit Service 9646c7
$log->close;
Packit Service 9646c7
exit 0;
Packit Service 9646c7
Packit Service 9646c7
### Setup "GNU" style for perl-mode and cperl-mode.
Packit Service 9646c7
## Local Variables:
Packit Service 9646c7
## perl-indent-level: 2
Packit Service 9646c7
## perl-continued-statement-offset: 2
Packit Service 9646c7
## perl-continued-brace-offset: 0
Packit Service 9646c7
## perl-brace-offset: 0
Packit Service 9646c7
## perl-brace-imaginary-offset: 0
Packit Service 9646c7
## perl-label-offset: -2
Packit Service 9646c7
## cperl-indent-level: 2
Packit Service 9646c7
## cperl-brace-offset: 0
Packit Service 9646c7
## cperl-continued-brace-offset: 0
Packit Service 9646c7
## cperl-label-offset: -2
Packit Service 9646c7
## cperl-extra-newline-before-brace: t
Packit Service 9646c7
## cperl-merge-trailing-else: nil
Packit Service 9646c7
## cperl-continued-statement-offset: 2
Packit Service 9646c7
## End: