2
0
mirror of git://git.sv.gnu.org/autoconf synced 2025-03-25 14:50:24 +08:00

* autoscan.in: Use IO::File.

Adjust all the routines to use it.
($log): New file (autoscan.log).
(output): Dump detailed logs into $log, and a shortened version to
stderr.
(&scan_makefile): Refine the regexp catching tokens in the code.
* doc/autoconf.texi (autoscan Invocation): Document `autoscan.log'
and the `configure.ac' checking feature.
This commit is contained in:
Akim Demaille 2001-07-14 14:19:19 +00:00
parent 7a8b65b3f8
commit beaa477c90
6 changed files with 217 additions and 140 deletions

@ -1,3 +1,14 @@
2001-07-14 Akim Demaille <akim@epita.fr>
* autoscan.in: Use IO::File.
Adjust all the routines to use it.
($log): New file (autoscan.log).
(output): Dump detailed logs into $log, and a shortened version to
stderr.
(&scan_makefile): Refine the regexp catching tokens in the code.
* doc/autoconf.texi (autoscan Invocation): Document `autoscan.log'
and the `configure.ac' checking feature.
2001-07-12 Akim Demaille <akim@epita.fr> 2001-07-12 Akim Demaille <akim@epita.fr>
For some AWK, such as on HPUX 11, `xfoo' does not match `foo|^bar'. For some AWK, such as on HPUX 11, `xfoo' does not match `foo|^bar'.

1
NEWS

@ -8,6 +8,7 @@
other hard-to-quote constructs. other hard-to-quote constructs.
- m4_pattern_forbid, m4_pattern_allow - m4_pattern_forbid, m4_pattern_allow
- Tips for upgrading from 2.13. - Tips for upgrading from 2.13.
- Using autoscan to maintain a configure.ac.
** Default includes ** Default includes
- Now include stdint.h. - Now include stdint.h.

@ -24,6 +24,7 @@ use 5.005;
use File::Basename; use File::Basename;
use File::Find; use File::Find;
use Getopt::Long; use Getopt::Long;
use IO::File;
use strict; use strict;
use vars qw(@cfiles @makefiles @shfiles %c_keywords %printed); use vars qw(@cfiles @makefiles @shfiles %c_keywords %printed);
@ -62,6 +63,8 @@ my %kind_comment =
); );
my $configure_scan = 'configure.scan'; my $configure_scan = 'configure.scan';
my $log = new IO::File ">$me.log"
or die "$me: cannot open $me.log: $!\n";
# Autoconf and lib files. # Autoconf and lib files.
my $autoconf; my $autoconf;
@ -92,8 +95,9 @@ sub print_usage ()
Examine source files in the directory tree rooted at SRCDIR, or the Examine source files in the directory tree rooted at SRCDIR, or the
current directory if none is given. Search the source files for current directory if none is given. Search the source files for
common portability problems and create a file `$configure_scan' which common portability problems, check for incompleteness of
is a preliminary `configure.ac' for that package. `configure.ac', and create a file `$configure_scan' which is a
preliminary `configure.ac' for that package.
-h, --help print this help, then exit -h, --help print this help, then exit
-V, --version print version number, then exit -V, --version print version number, then exit
@ -217,9 +221,9 @@ sub init_tables ()
foreach my $kind (@kinds) foreach my $kind (@kinds)
{ {
my $file = "$datadir/ac$kind"; my $file = "$datadir/ac$kind";
open TABLE, $file or my $table = new IO::File $file
die "$me: cannot open $file: $!\n"; or die "$me: cannot open $file: $!\n";
while (<TABLE>) while ($_ = $table->getline)
{ {
# Ignore blank lines and comments. # Ignore blank lines and comments.
next next
@ -244,7 +248,8 @@ sub init_tables ()
push @{$macro{$kind}{$word}}, $macro; push @{$macro{$kind}{$word}}, $macro;
} }
} }
close(TABLE); $table->close
or die "$me: cannot close $file: $!\n";
} }
die "$me: some tables are inconsistent\n" die "$me: some tables are inconsistent\n"
@ -258,19 +263,21 @@ sub init_tables ()
## ----------------------- ## ## ----------------------- ##
# scan_c_file(FILE) # scan_c_file(FILENAME)
# ----------------- # ---------------------
sub scan_c_file ($) sub scan_c_file ($)
{ {
my ($file) = @_; my ($filename) = @_;
push (@cfiles, $File::Find::name); push (@cfiles, $File::Find::name);
# Nonzero if in a multiline comment. # Nonzero if in a multiline comment.
my $in_comment = 0; my $in_comment = 0;
open(CFILE, "<$file") || die "$me: cannot open $file: $!\n"; my $file = new IO::File "<$filename"
while (<CFILE>) or die "$me: cannot open $filename: $!\n";
while ($_ = $file->getline)
{ {
# Strip out comments, approximately. # Strip out comments, approximately.
# Ending on this line. # Ending on this line.
@ -314,19 +321,23 @@ sub scan_c_file ($)
if !defined $c_keywords{$1}; if !defined $c_keywords{$1};
} }
} }
close(CFILE);
$file->close
or die "$me: cannot close $filename: $!\n";
} }
# scan_makefile(MAKEFILE) # scan_makefile(MAKEFILE-NAME)
# ----------------------- # ----------------------------
sub scan_makefile ($) sub scan_makefile ($)
{ {
my ($file) = @_; my ($filename) = @_;
push (@makefiles, $File::Find::name); push (@makefiles, $File::Find::name);
open(MFILE, "<$file") || die "$me: cannot open $file: $!\n"; my $file = new IO::File "<$filename"
while (<MFILE>) or die "$me: cannot open $filename: $!\n";
while ($_ = $file->getline)
{ {
# Strip out comments and variable references. # Strip out comments and variable references.
s/#.*//; s/#.*//;
@ -345,27 +356,32 @@ sub scan_makefile ($)
push (@{$used{'libraries'}{$1}}, "$File::Find::name:$."); push (@{$used{'libraries'}{$1}}, "$File::Find::name:$.");
} }
# Tokens in the code. # Tokens in the code.
while (s/\b([a-zA-Z_][\w\+\.-]+)/ /) while (s/(?<![-\w.])([a-zA-Z_][\w+.-]+)/ /)
{ {
push (@{$used{'programs'}{$1}}, "$File::Find::name:$."); push (@{$used{'programs'}{$1}}, "$File::Find::name:$.");
} }
} }
close(MFILE);
$file->close
or die "$me: cannot close $filename: $!\n";
} }
# scan_sh_file(SHELL-SCRIPT) # scan_sh_file(SHELL-SCRIPT-NAME)
# -------------------------- # -------------------------------
sub scan_sh_file ($) sub scan_sh_file ($)
{ {
my ($file) = @_; my ($filename) = @_;
push (@shfiles, $File::Find::name); push (@shfiles, $File::Find::name);
open(MFILE, "<$file") || die "$me: cannot open $file: $!\n"; my $file = new IO::File "<$filename"
while (<MFILE>) or die "$me: cannot open $filename: $!\n";
while ($_ = $file->getline)
{ {
# Strip out comments and variable references. # Strip out comments and variable references.
s/#.*//; s/#.*//;
s/#.*//;
s/\${[^\}]*}//g; s/\${[^\}]*}//g;
s/@[^@]*@//g; s/@[^@]*@//g;
@ -375,7 +391,9 @@ sub scan_sh_file ($)
push (@{$used{'programs'}{$1}}, "$File::Find::name:$."); push (@{$used{'programs'}{$1}}, "$File::Find::name:$.");
} }
} }
close(MFILE);
$file->close
or die "$me: cannot close $filename: $!\n";
} }
@ -449,15 +467,15 @@ sub scan_files ()
## ----------------------- ## ## ----------------------- ##
# output_kind ($KIND) # output_kind ($FILE, $KIND)
# ------------------- # --------------------------
sub output_kind ($) sub output_kind ($$)
{ {
my ($kind) = @_; my ($file, $kind) = @_;
# Lists of words to be checked with the generic macro. # Lists of words to be checked with the generic macro.
my @have; my @have;
print CONF "\n# $kind_comment{$kind}\n" print $file "\n# $kind_comment{$kind}\n"
if exists $kind_comment{$kind}; if exists $kind_comment{$kind};
foreach my $word (sort keys %{$used{$kind}}) foreach my $word (sort keys %{$used{$kind}})
{ {
@ -481,7 +499,7 @@ sub output_kind ($)
{ {
if (! $printed{$macro}) if (! $printed{$macro})
{ {
print CONF "$macro\n"; print $file "$macro\n";
$printed{$macro} = 1; $printed{$macro} = 1;
} }
push (@{$needed_macros{$macro}}, push (@{$needed_macros{$macro}},
@ -489,20 +507,22 @@ sub output_kind ($)
} }
} }
} }
print CONF "$generic_macro{$kind}([" . join(' ', sort(@have)) . "])\n" print $file "$generic_macro{$kind}([" . join(' ', sort(@have)) . "])\n"
if @have; if @have;
} }
# output_libraries () # output_libraries ($FILE)
# ------------------- # ------------------------
sub output_libraries () sub output_libraries ($)
{ {
print CONF "\n# Checks for libraries.\n"; my ($file) = @_;
print $file "\n# Checks for libraries.\n";
foreach my $word (sort keys %{$used{'libraries'}}) foreach my $word (sort keys %{$used{'libraries'}})
{ {
print CONF "# FIXME: Replace `main' with a function in `-l$word':\n"; print $file "# FIXME: Replace `main' with a function in `-l$word':\n";
print CONF "AC_CHECK_LIB([$word], [main])\n"; print $file "AC_CHECK_LIB([$word], [main])\n";
} }
} }
@ -515,23 +535,23 @@ sub output ($)
my $configure_scan = shift; my $configure_scan = shift;
my %unique_makefiles; my %unique_makefiles;
open (CONF, ">$configure_scan") || my $file = new IO::File ">$configure_scan"
die "$me: cannot create $configure_scan: $!\n"; or die "$me: cannot create $configure_scan: $!\n";
print CONF "# Process this file with autoconf to produce a configure script.\n"; print $file "# Process this file with autoconf to produce a configure script.\n";
print CONF "AC_INIT\n"; print $file "AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)\n";
if (defined $cfiles[0]) if (defined $cfiles[0])
{ {
print CONF "AC_CONFIG_SRCDIR([$cfiles[0]])\n"; print $file "AC_CONFIG_SRCDIR([$cfiles[0]])\n";
print CONF "AC_CONFIG_HEADER([config.h])\n"; print $file "AC_CONFIG_HEADER([config.h])\n";
} }
output_kind ('programs'); output_kind ($file, 'programs');
output_kind ('makevars'); output_kind ($file, 'makevars');
output_libraries; output_libraries ($file);
output_kind ('headers'); output_kind ($file, 'headers');
output_kind ('identifiers'); output_kind ($file, 'identifiers');
output_kind ('functions'); output_kind ($file, 'functions');
# Change DIR/Makefile.in to DIR/Makefile. # Change DIR/Makefile.in to DIR/Makefile.
foreach my $m (@makefiles) foreach my $m (@makefiles)
@ -539,12 +559,12 @@ sub output ($)
$m =~ s/\.in$//; $m =~ s/\.in$//;
$unique_makefiles{$m}++; $unique_makefiles{$m}++;
} }
print CONF "\nAC_CONFIG_FILES([", print $file "\nAC_CONFIG_FILES([",
join ("\n ", sort keys %unique_makefiles), "])\n"; join ("\n ", sort keys %unique_makefiles), "])\n";
print CONF "AC_OUTPUT\n"; print $file "AC_OUTPUT\n";
close CONF || $file->close
die "$me: closing $configure_scan: $!\n"; or die "$me: cannot close $configure_scan: $!\n";
} }
@ -560,19 +580,21 @@ sub output ($)
# in CONFIGURE_AC. # in CONFIGURE_AC.
sub check_configure_ac ($) sub check_configure_ac ($)
{ {
my ($configure_ac) = $@; my ($configure_ac) = @_;
my ($trace_option) = ''; my ($trace_option) = '';
# Find what needed macros are invoked in CONFIGURE_AC.
foreach my $macro (sort keys %needed_macros) foreach my $macro (sort keys %needed_macros)
{ {
$macro =~ s/\(.*//; $macro =~ s/\(.*//;
$trace_option .= " -t $macro"; $trace_option .= " -t $macro";
} }
open (TRACES, "$autoconf -A $datadir $trace_option $configure_ac|") || my $traces =
die "$me: cannot create read traces: $!\n"; new IO::File "$autoconf -A $datadir $trace_option $configure_ac|"
or die "$me: cannot create read traces: $!\n";
while (<TRACES>) while ($_ = $traces->getline)
{ {
chomp; chomp;
my ($file, $line, $macro, @args) = split (/:/, $_); my ($file, $line, $macro, @args) = split (/:/, $_);
@ -597,15 +619,19 @@ sub check_configure_ac ($)
} }
} }
close (TRACES) || $traces->close
die "$me: cannot close traces: $!\n"; or die "$me: cannot close: $!\n";
# Report the missing macros.
foreach my $macro (sort keys %needed_macros) foreach my $macro (sort keys %needed_macros)
{ {
warn "$me: warning: missing $macro wanted by: \n"; warn ("$configure_ac: warning: missing $macro wanted by: "
. (${$needed_macros{$macro}}[0])
. "\n");
print $log "$me: warning: missing $macro wanted by: \n";
foreach my $need (@{$needed_macros{$macro}}) foreach my $need (@{$needed_macros{$macro}})
{ {
warn "\t$need\n"; print $log "\t$need\n";
} }
} }
} }
@ -627,4 +653,7 @@ if ($configure_ac)
check_configure_ac ($configure_ac); check_configure_ac ($configure_ac);
} }
$log->close
or die "$me: cannot close $me.log: $!\n";
exit 0; exit 0;

@ -24,6 +24,7 @@ use 5.005;
use File::Basename; use File::Basename;
use File::Find; use File::Find;
use Getopt::Long; use Getopt::Long;
use IO::File;
use strict; use strict;
use vars qw(@cfiles @makefiles @shfiles %c_keywords %printed); use vars qw(@cfiles @makefiles @shfiles %c_keywords %printed);
@ -62,6 +63,8 @@ my %kind_comment =
); );
my $configure_scan = 'configure.scan'; my $configure_scan = 'configure.scan';
my $log = new IO::File ">$me.log"
or die "$me: cannot open $me.log: $!\n";
# Autoconf and lib files. # Autoconf and lib files.
my $autoconf; my $autoconf;
@ -92,8 +95,9 @@ sub print_usage ()
Examine source files in the directory tree rooted at SRCDIR, or the Examine source files in the directory tree rooted at SRCDIR, or the
current directory if none is given. Search the source files for current directory if none is given. Search the source files for
common portability problems and create a file `$configure_scan' which common portability problems, check for incompleteness of
is a preliminary `configure.ac' for that package. `configure.ac', and create a file `$configure_scan' which is a
preliminary `configure.ac' for that package.
-h, --help print this help, then exit -h, --help print this help, then exit
-V, --version print version number, then exit -V, --version print version number, then exit
@ -217,9 +221,9 @@ sub init_tables ()
foreach my $kind (@kinds) foreach my $kind (@kinds)
{ {
my $file = "$datadir/ac$kind"; my $file = "$datadir/ac$kind";
open TABLE, $file or my $table = new IO::File $file
die "$me: cannot open $file: $!\n"; or die "$me: cannot open $file: $!\n";
while (<TABLE>) while ($_ = $table->getline)
{ {
# Ignore blank lines and comments. # Ignore blank lines and comments.
next next
@ -244,7 +248,8 @@ sub init_tables ()
push @{$macro{$kind}{$word}}, $macro; push @{$macro{$kind}{$word}}, $macro;
} }
} }
close(TABLE); $table->close
or die "$me: cannot close $file: $!\n";
} }
die "$me: some tables are inconsistent\n" die "$me: some tables are inconsistent\n"
@ -258,19 +263,21 @@ sub init_tables ()
## ----------------------- ## ## ----------------------- ##
# scan_c_file(FILE) # scan_c_file(FILENAME)
# ----------------- # ---------------------
sub scan_c_file ($) sub scan_c_file ($)
{ {
my ($file) = @_; my ($filename) = @_;
push (@cfiles, $File::Find::name); push (@cfiles, $File::Find::name);
# Nonzero if in a multiline comment. # Nonzero if in a multiline comment.
my $in_comment = 0; my $in_comment = 0;
open(CFILE, "<$file") || die "$me: cannot open $file: $!\n"; my $file = new IO::File "<$filename"
while (<CFILE>) or die "$me: cannot open $filename: $!\n";
while ($_ = $file->getline)
{ {
# Strip out comments, approximately. # Strip out comments, approximately.
# Ending on this line. # Ending on this line.
@ -314,19 +321,23 @@ sub scan_c_file ($)
if !defined $c_keywords{$1}; if !defined $c_keywords{$1};
} }
} }
close(CFILE);
$file->close
or die "$me: cannot close $filename: $!\n";
} }
# scan_makefile(MAKEFILE) # scan_makefile(MAKEFILE-NAME)
# ----------------------- # ----------------------------
sub scan_makefile ($) sub scan_makefile ($)
{ {
my ($file) = @_; my ($filename) = @_;
push (@makefiles, $File::Find::name); push (@makefiles, $File::Find::name);
open(MFILE, "<$file") || die "$me: cannot open $file: $!\n"; my $file = new IO::File "<$filename"
while (<MFILE>) or die "$me: cannot open $filename: $!\n";
while ($_ = $file->getline)
{ {
# Strip out comments and variable references. # Strip out comments and variable references.
s/#.*//; s/#.*//;
@ -345,27 +356,32 @@ sub scan_makefile ($)
push (@{$used{'libraries'}{$1}}, "$File::Find::name:$."); push (@{$used{'libraries'}{$1}}, "$File::Find::name:$.");
} }
# Tokens in the code. # Tokens in the code.
while (s/\b([a-zA-Z_][\w\+\.-]+)/ /) while (s/(?<![-\w.])([a-zA-Z_][\w+.-]+)/ /)
{ {
push (@{$used{'programs'}{$1}}, "$File::Find::name:$."); push (@{$used{'programs'}{$1}}, "$File::Find::name:$.");
} }
} }
close(MFILE);
$file->close
or die "$me: cannot close $filename: $!\n";
} }
# scan_sh_file(SHELL-SCRIPT) # scan_sh_file(SHELL-SCRIPT-NAME)
# -------------------------- # -------------------------------
sub scan_sh_file ($) sub scan_sh_file ($)
{ {
my ($file) = @_; my ($filename) = @_;
push (@shfiles, $File::Find::name); push (@shfiles, $File::Find::name);
open(MFILE, "<$file") || die "$me: cannot open $file: $!\n"; my $file = new IO::File "<$filename"
while (<MFILE>) or die "$me: cannot open $filename: $!\n";
while ($_ = $file->getline)
{ {
# Strip out comments and variable references. # Strip out comments and variable references.
s/#.*//; s/#.*//;
s/#.*//;
s/\${[^\}]*}//g; s/\${[^\}]*}//g;
s/@[^@]*@//g; s/@[^@]*@//g;
@ -375,7 +391,9 @@ sub scan_sh_file ($)
push (@{$used{'programs'}{$1}}, "$File::Find::name:$."); push (@{$used{'programs'}{$1}}, "$File::Find::name:$.");
} }
} }
close(MFILE);
$file->close
or die "$me: cannot close $filename: $!\n";
} }
@ -449,15 +467,15 @@ sub scan_files ()
## ----------------------- ## ## ----------------------- ##
# output_kind ($KIND) # output_kind ($FILE, $KIND)
# ------------------- # --------------------------
sub output_kind ($) sub output_kind ($$)
{ {
my ($kind) = @_; my ($file, $kind) = @_;
# Lists of words to be checked with the generic macro. # Lists of words to be checked with the generic macro.
my @have; my @have;
print CONF "\n# $kind_comment{$kind}\n" print $file "\n# $kind_comment{$kind}\n"
if exists $kind_comment{$kind}; if exists $kind_comment{$kind};
foreach my $word (sort keys %{$used{$kind}}) foreach my $word (sort keys %{$used{$kind}})
{ {
@ -481,7 +499,7 @@ sub output_kind ($)
{ {
if (! $printed{$macro}) if (! $printed{$macro})
{ {
print CONF "$macro\n"; print $file "$macro\n";
$printed{$macro} = 1; $printed{$macro} = 1;
} }
push (@{$needed_macros{$macro}}, push (@{$needed_macros{$macro}},
@ -489,20 +507,22 @@ sub output_kind ($)
} }
} }
} }
print CONF "$generic_macro{$kind}([" . join(' ', sort(@have)) . "])\n" print $file "$generic_macro{$kind}([" . join(' ', sort(@have)) . "])\n"
if @have; if @have;
} }
# output_libraries () # output_libraries ($FILE)
# ------------------- # ------------------------
sub output_libraries () sub output_libraries ($)
{ {
print CONF "\n# Checks for libraries.\n"; my ($file) = @_;
print $file "\n# Checks for libraries.\n";
foreach my $word (sort keys %{$used{'libraries'}}) foreach my $word (sort keys %{$used{'libraries'}})
{ {
print CONF "# FIXME: Replace `main' with a function in `-l$word':\n"; print $file "# FIXME: Replace `main' with a function in `-l$word':\n";
print CONF "AC_CHECK_LIB([$word], [main])\n"; print $file "AC_CHECK_LIB([$word], [main])\n";
} }
} }
@ -515,23 +535,23 @@ sub output ($)
my $configure_scan = shift; my $configure_scan = shift;
my %unique_makefiles; my %unique_makefiles;
open (CONF, ">$configure_scan") || my $file = new IO::File ">$configure_scan"
die "$me: cannot create $configure_scan: $!\n"; or die "$me: cannot create $configure_scan: $!\n";
print CONF "# Process this file with autoconf to produce a configure script.\n"; print $file "# Process this file with autoconf to produce a configure script.\n";
print CONF "AC_INIT\n"; print $file "AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)\n";
if (defined $cfiles[0]) if (defined $cfiles[0])
{ {
print CONF "AC_CONFIG_SRCDIR([$cfiles[0]])\n"; print $file "AC_CONFIG_SRCDIR([$cfiles[0]])\n";
print CONF "AC_CONFIG_HEADER([config.h])\n"; print $file "AC_CONFIG_HEADER([config.h])\n";
} }
output_kind ('programs'); output_kind ($file, 'programs');
output_kind ('makevars'); output_kind ($file, 'makevars');
output_libraries; output_libraries ($file);
output_kind ('headers'); output_kind ($file, 'headers');
output_kind ('identifiers'); output_kind ($file, 'identifiers');
output_kind ('functions'); output_kind ($file, 'functions');
# Change DIR/Makefile.in to DIR/Makefile. # Change DIR/Makefile.in to DIR/Makefile.
foreach my $m (@makefiles) foreach my $m (@makefiles)
@ -539,12 +559,12 @@ sub output ($)
$m =~ s/\.in$//; $m =~ s/\.in$//;
$unique_makefiles{$m}++; $unique_makefiles{$m}++;
} }
print CONF "\nAC_CONFIG_FILES([", print $file "\nAC_CONFIG_FILES([",
join ("\n ", sort keys %unique_makefiles), "])\n"; join ("\n ", sort keys %unique_makefiles), "])\n";
print CONF "AC_OUTPUT\n"; print $file "AC_OUTPUT\n";
close CONF || $file->close
die "$me: closing $configure_scan: $!\n"; or die "$me: cannot close $configure_scan: $!\n";
} }
@ -560,19 +580,21 @@ sub output ($)
# in CONFIGURE_AC. # in CONFIGURE_AC.
sub check_configure_ac ($) sub check_configure_ac ($)
{ {
my ($configure_ac) = $@; my ($configure_ac) = @_;
my ($trace_option) = ''; my ($trace_option) = '';
# Find what needed macros are invoked in CONFIGURE_AC.
foreach my $macro (sort keys %needed_macros) foreach my $macro (sort keys %needed_macros)
{ {
$macro =~ s/\(.*//; $macro =~ s/\(.*//;
$trace_option .= " -t $macro"; $trace_option .= " -t $macro";
} }
open (TRACES, "$autoconf -A $datadir $trace_option $configure_ac|") || my $traces =
die "$me: cannot create read traces: $!\n"; new IO::File "$autoconf -A $datadir $trace_option $configure_ac|"
or die "$me: cannot create read traces: $!\n";
while (<TRACES>) while ($_ = $traces->getline)
{ {
chomp; chomp;
my ($file, $line, $macro, @args) = split (/:/, $_); my ($file, $line, $macro, @args) = split (/:/, $_);
@ -597,15 +619,19 @@ sub check_configure_ac ($)
} }
} }
close (TRACES) || $traces->close
die "$me: cannot close traces: $!\n"; or die "$me: cannot close: $!\n";
# Report the missing macros.
foreach my $macro (sort keys %needed_macros) foreach my $macro (sort keys %needed_macros)
{ {
warn "$me: warning: missing $macro wanted by: \n"; warn ("$configure_ac: warning: missing $macro wanted by: "
. (${$needed_macros{$macro}}[0])
. "\n");
print $log "$me: warning: missing $macro wanted by: \n";
foreach my $need (@{$needed_macros{$macro}}) foreach my $need (@{$needed_macros{$macro}})
{ {
warn "\t$need\n"; print $log "\t$need\n";
} }
} }
} }
@ -627,4 +653,7 @@ if ($configure_ac)
check_configure_ac ($configure_ac); check_configure_ac ($configure_ac);
} }
$log->close
or die "$me: cannot close $me.log: $!\n";
exit 0; exit 0;

@ -985,25 +985,31 @@ checks for system services
@section Using @code{autoscan} to Create @file{configure.ac} @section Using @code{autoscan} to Create @file{configure.ac}
@cindex @code{autoscan} @cindex @code{autoscan}
The @code{autoscan} program can help you create a @file{configure.ac} The @code{autoscan} program can help you create and/or maintain a
file for a software package. @code{autoscan} examines source files in @file{configure.ac} file for a software package. @code{autoscan}
the directory tree rooted at a directory given as a command line examines source files in the directory tree rooted at a directory given
argument, or the current directory if none is given. It searches the as a command line argument, or the current directory if none is given.
source files for common portability problems and creates a file It searches the source files for common portability problems and creates
@file{configure.scan} which is a preliminary @file{configure.ac} for a file @file{configure.scan} which is a preliminary @file{configure.ac}
that package. for that package, and checks a possibly existing @file{configure.ac} for
completeness.
You should manually examine @file{configure.scan} before renaming it to When using @command{autoscan} to create a @file{configure.ac}, you
should manually examine @file{configure.scan} before renaming it to
@file{configure.ac}; it will probably need some adjustments. @file{configure.ac}; it will probably need some adjustments.
Occasionally, @code{autoscan} outputs a macro in the wrong order relative Occasionally, @code{autoscan} outputs a macro in the wrong order
to another macro, so that @code{autoconf} produces a warning; you need relative to another macro, so that @code{autoconf} produces a warning;
to move such macros manually. Also, if you want the package to use a you need to move such macros manually. Also, if you want the package to
configuration header file, you must add a call to use a configuration header file, you must add a call to
@code{AC_CONFIG_HEADERS} (@pxref{Configuration Headers}). You might also @code{AC_CONFIG_HEADERS} (@pxref{Configuration Headers}). You might
have to change or add some @code{#if} directives to your program in also have to change or add some @code{#if} directives to your program in
order to make it work with Autoconf (@pxref{ifnames Invocation}, for order to make it work with Autoconf (@pxref{ifnames Invocation}, for
information about a program that can help with that job). information about a program that can help with that job).
When using @command{autoscan} to maintain a @file{configure.ac}, simply
consider adding its suggestions. The file @file{autoscan.log} will
contain detailed information on why a macro is requested.
@code{autoscan} uses several data files (installed along with Autoconf) @code{autoscan} uses several data files (installed along with Autoconf)
to determine which macros to output when it finds particular symbols in to determine which macros to output when it finds particular symbols in
a package's source files. These data files all have the same format: a package's source files. These data files all have the same format:

@ -8,8 +8,9 @@ autoscan \- Generate a preliminary configure.in
.SH DESCRIPTION .SH DESCRIPTION
Examine source files in the directory tree rooted at SRCDIR, or the Examine source files in the directory tree rooted at SRCDIR, or the
current directory if none is given. Search the source files for current directory if none is given. Search the source files for
common portability problems and create a file `configure.scan' which common portability problems, check for incompleteness of
is a preliminary `configure.ac' for that package. `configure.ac', and create a file `configure.scan' which is a
preliminary `configure.ac' for that package.
.TP .TP
\fB\-h\fR, \fB\-\-help\fR \fB\-h\fR, \fB\-\-help\fR
print this help, then exit print this help, then exit