From: Akim Demaille Date: Sat, 14 Jul 2001 14:19:19 +0000 (+0000) Subject: * autoscan.in: Use IO::File. X-Git-Tag: AUTOCONF-2.50c~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=beaa477c90269c104b26f476482dd27479c8a789;p=thirdparty%2Fautoconf.git * 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. --- diff --git a/ChangeLog b/ChangeLog index 67364e6fa..7ce23b7cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2001-07-14 Akim Demaille + + * 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 For some AWK, such as on HPUX 11, `xfoo' does not match `foo|^bar'. diff --git a/NEWS b/NEWS index 5bbc6199e..45eb158d9 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,7 @@ other hard-to-quote constructs. - m4_pattern_forbid, m4_pattern_allow - Tips for upgrading from 2.13. +- Using autoscan to maintain a configure.ac. ** Default includes - Now include stdint.h. diff --git a/autoscan.in b/autoscan.in index e70528df8..3cbd47bb0 100644 --- a/autoscan.in +++ b/autoscan.in @@ -24,6 +24,7 @@ use 5.005; use File::Basename; use File::Find; use Getopt::Long; +use IO::File; use strict; use vars qw(@cfiles @makefiles @shfiles %c_keywords %printed); @@ -62,6 +63,8 @@ my %kind_comment = ); my $configure_scan = 'configure.scan'; +my $log = new IO::File ">$me.log" + or die "$me: cannot open $me.log: $!\n"; # Autoconf and lib files. my $autoconf; @@ -92,8 +95,9 @@ sub print_usage () Examine source files in the directory tree rooted at SRCDIR, or the current directory if none is given. Search the source files for -common portability problems and create a file `$configure_scan' which -is a preliminary `configure.ac' for that package. +common portability problems, check for incompleteness of +`configure.ac', and create a file `$configure_scan' which is a +preliminary `configure.ac' for that package. -h, --help print this help, then exit -V, --version print version number, then exit @@ -217,9 +221,9 @@ sub init_tables () foreach my $kind (@kinds) { my $file = "$datadir/ac$kind"; - open TABLE, $file or - die "$me: cannot open $file: $!\n"; - while () + my $table = new IO::File $file + or die "$me: cannot open $file: $!\n"; + while ($_ = $table->getline) { # Ignore blank lines and comments. next @@ -244,7 +248,8 @@ sub init_tables () push @{$macro{$kind}{$word}}, $macro; } } - close(TABLE); + $table->close + or die "$me: cannot close $file: $!\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 ($) { - my ($file) = @_; + my ($filename) = @_; push (@cfiles, $File::Find::name); # Nonzero if in a multiline comment. my $in_comment = 0; - open(CFILE, "<$file") || die "$me: cannot open $file: $!\n"; - while () + my $file = new IO::File "<$filename" + or die "$me: cannot open $filename: $!\n"; + + while ($_ = $file->getline) { # Strip out comments, approximately. # Ending on this line. @@ -314,19 +321,23 @@ sub scan_c_file ($) 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 ($) { - my ($file) = @_; + my ($filename) = @_; push (@makefiles, $File::Find::name); - open(MFILE, "<$file") || die "$me: cannot open $file: $!\n"; - while () + my $file = new IO::File "<$filename" + or die "$me: cannot open $filename: $!\n"; + + while ($_ = $file->getline) { # Strip out comments and variable references. s/#.*//; @@ -345,27 +356,32 @@ sub scan_makefile ($) push (@{$used{'libraries'}{$1}}, "$File::Find::name:$."); } # Tokens in the code. - while (s/\b([a-zA-Z_][\w\+\.-]+)/ /) + while (s/(?close + or die "$me: cannot close $filename: $!\n"; } -# scan_sh_file(SHELL-SCRIPT) -# -------------------------- +# scan_sh_file(SHELL-SCRIPT-NAME) +# ------------------------------- sub scan_sh_file ($) { - my ($file) = @_; + my ($filename) = @_; push (@shfiles, $File::Find::name); - open(MFILE, "<$file") || die "$me: cannot open $file: $!\n"; - while () + my $file = new IO::File "<$filename" + or die "$me: cannot open $filename: $!\n"; + + while ($_ = $file->getline) { # Strip out comments and variable references. s/#.*//; + s/#.*//; s/\${[^\}]*}//g; s/@[^@]*@//g; @@ -375,7 +391,9 @@ sub scan_sh_file ($) 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) -# ------------------- -sub output_kind ($) +# output_kind ($FILE, $KIND) +# -------------------------- +sub output_kind ($$) { - my ($kind) = @_; + my ($file, $kind) = @_; # Lists of words to be checked with the generic macro. my @have; - print CONF "\n# $kind_comment{$kind}\n" + print $file "\n# $kind_comment{$kind}\n" if exists $kind_comment{$kind}; foreach my $word (sort keys %{$used{$kind}}) { @@ -481,7 +499,7 @@ sub output_kind ($) { if (! $printed{$macro}) { - print CONF "$macro\n"; + print $file "$macro\n"; $printed{$macro} = 1; } 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; } -# output_libraries () -# ------------------- -sub output_libraries () +# output_libraries ($FILE) +# ------------------------ +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'}}) { - print CONF "# FIXME: Replace `main' with a function in `-l$word':\n"; - print CONF "AC_CHECK_LIB([$word], [main])\n"; + print $file "# FIXME: Replace `main' with a function in `-l$word':\n"; + print $file "AC_CHECK_LIB([$word], [main])\n"; } } @@ -515,23 +535,23 @@ sub output ($) my $configure_scan = shift; my %unique_makefiles; - open (CONF, ">$configure_scan") || - die "$me: cannot create $configure_scan: $!\n"; + my $file = new IO::File ">$configure_scan" + or die "$me: cannot create $configure_scan: $!\n"; - print CONF "# Process this file with autoconf to produce a configure script.\n"; - print CONF "AC_INIT\n"; + print $file "# Process this file with autoconf to produce a configure script.\n"; + print $file "AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)\n"; if (defined $cfiles[0]) { - print CONF "AC_CONFIG_SRCDIR([$cfiles[0]])\n"; - print CONF "AC_CONFIG_HEADER([config.h])\n"; + print $file "AC_CONFIG_SRCDIR([$cfiles[0]])\n"; + print $file "AC_CONFIG_HEADER([config.h])\n"; } - output_kind ('programs'); - output_kind ('makevars'); - output_libraries; - output_kind ('headers'); - output_kind ('identifiers'); - output_kind ('functions'); + output_kind ($file, 'programs'); + output_kind ($file, 'makevars'); + output_libraries ($file); + output_kind ($file, 'headers'); + output_kind ($file, 'identifiers'); + output_kind ($file, 'functions'); # Change DIR/Makefile.in to DIR/Makefile. foreach my $m (@makefiles) @@ -539,12 +559,12 @@ sub output ($) $m =~ s/\.in$//; $unique_makefiles{$m}++; } - print CONF "\nAC_CONFIG_FILES([", + print $file "\nAC_CONFIG_FILES([", join ("\n ", sort keys %unique_makefiles), "])\n"; - print CONF "AC_OUTPUT\n"; + print $file "AC_OUTPUT\n"; - close CONF || - die "$me: closing $configure_scan: $!\n"; + $file->close + or die "$me: cannot close $configure_scan: $!\n"; } @@ -560,19 +580,21 @@ sub output ($) # in CONFIGURE_AC. sub check_configure_ac ($) { - my ($configure_ac) = $@; + my ($configure_ac) = @_; my ($trace_option) = ''; + # Find what needed macros are invoked in CONFIGURE_AC. foreach my $macro (sort keys %needed_macros) { $macro =~ s/\(.*//; $trace_option .= " -t $macro"; } - open (TRACES, "$autoconf -A $datadir $trace_option $configure_ac|") || - die "$me: cannot create read traces: $!\n"; + my $traces = + new IO::File "$autoconf -A $datadir $trace_option $configure_ac|" + or die "$me: cannot create read traces: $!\n"; - while () + while ($_ = $traces->getline) { chomp; my ($file, $line, $macro, @args) = split (/:/, $_); @@ -597,15 +619,19 @@ sub check_configure_ac ($) } } - close (TRACES) || - die "$me: cannot close traces: $!\n"; + $traces->close + or die "$me: cannot close: $!\n"; + # Report the missing 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}}) { - warn "\t$need\n"; + print $log "\t$need\n"; } } } @@ -627,4 +653,7 @@ if ($configure_ac) check_configure_ac ($configure_ac); } +$log->close + or die "$me: cannot close $me.log: $!\n"; + exit 0; diff --git a/bin/autoscan.in b/bin/autoscan.in index e70528df8..3cbd47bb0 100644 --- a/bin/autoscan.in +++ b/bin/autoscan.in @@ -24,6 +24,7 @@ use 5.005; use File::Basename; use File::Find; use Getopt::Long; +use IO::File; use strict; use vars qw(@cfiles @makefiles @shfiles %c_keywords %printed); @@ -62,6 +63,8 @@ my %kind_comment = ); my $configure_scan = 'configure.scan'; +my $log = new IO::File ">$me.log" + or die "$me: cannot open $me.log: $!\n"; # Autoconf and lib files. my $autoconf; @@ -92,8 +95,9 @@ sub print_usage () Examine source files in the directory tree rooted at SRCDIR, or the current directory if none is given. Search the source files for -common portability problems and create a file `$configure_scan' which -is a preliminary `configure.ac' for that package. +common portability problems, check for incompleteness of +`configure.ac', and create a file `$configure_scan' which is a +preliminary `configure.ac' for that package. -h, --help print this help, then exit -V, --version print version number, then exit @@ -217,9 +221,9 @@ sub init_tables () foreach my $kind (@kinds) { my $file = "$datadir/ac$kind"; - open TABLE, $file or - die "$me: cannot open $file: $!\n"; - while (
) + my $table = new IO::File $file + or die "$me: cannot open $file: $!\n"; + while ($_ = $table->getline) { # Ignore blank lines and comments. next @@ -244,7 +248,8 @@ sub init_tables () push @{$macro{$kind}{$word}}, $macro; } } - close(TABLE); + $table->close + or die "$me: cannot close $file: $!\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 ($) { - my ($file) = @_; + my ($filename) = @_; push (@cfiles, $File::Find::name); # Nonzero if in a multiline comment. my $in_comment = 0; - open(CFILE, "<$file") || die "$me: cannot open $file: $!\n"; - while () + my $file = new IO::File "<$filename" + or die "$me: cannot open $filename: $!\n"; + + while ($_ = $file->getline) { # Strip out comments, approximately. # Ending on this line. @@ -314,19 +321,23 @@ sub scan_c_file ($) 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 ($) { - my ($file) = @_; + my ($filename) = @_; push (@makefiles, $File::Find::name); - open(MFILE, "<$file") || die "$me: cannot open $file: $!\n"; - while () + my $file = new IO::File "<$filename" + or die "$me: cannot open $filename: $!\n"; + + while ($_ = $file->getline) { # Strip out comments and variable references. s/#.*//; @@ -345,27 +356,32 @@ sub scan_makefile ($) push (@{$used{'libraries'}{$1}}, "$File::Find::name:$."); } # Tokens in the code. - while (s/\b([a-zA-Z_][\w\+\.-]+)/ /) + while (s/(?close + or die "$me: cannot close $filename: $!\n"; } -# scan_sh_file(SHELL-SCRIPT) -# -------------------------- +# scan_sh_file(SHELL-SCRIPT-NAME) +# ------------------------------- sub scan_sh_file ($) { - my ($file) = @_; + my ($filename) = @_; push (@shfiles, $File::Find::name); - open(MFILE, "<$file") || die "$me: cannot open $file: $!\n"; - while () + my $file = new IO::File "<$filename" + or die "$me: cannot open $filename: $!\n"; + + while ($_ = $file->getline) { # Strip out comments and variable references. s/#.*//; + s/#.*//; s/\${[^\}]*}//g; s/@[^@]*@//g; @@ -375,7 +391,9 @@ sub scan_sh_file ($) 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) -# ------------------- -sub output_kind ($) +# output_kind ($FILE, $KIND) +# -------------------------- +sub output_kind ($$) { - my ($kind) = @_; + my ($file, $kind) = @_; # Lists of words to be checked with the generic macro. my @have; - print CONF "\n# $kind_comment{$kind}\n" + print $file "\n# $kind_comment{$kind}\n" if exists $kind_comment{$kind}; foreach my $word (sort keys %{$used{$kind}}) { @@ -481,7 +499,7 @@ sub output_kind ($) { if (! $printed{$macro}) { - print CONF "$macro\n"; + print $file "$macro\n"; $printed{$macro} = 1; } 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; } -# output_libraries () -# ------------------- -sub output_libraries () +# output_libraries ($FILE) +# ------------------------ +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'}}) { - print CONF "# FIXME: Replace `main' with a function in `-l$word':\n"; - print CONF "AC_CHECK_LIB([$word], [main])\n"; + print $file "# FIXME: Replace `main' with a function in `-l$word':\n"; + print $file "AC_CHECK_LIB([$word], [main])\n"; } } @@ -515,23 +535,23 @@ sub output ($) my $configure_scan = shift; my %unique_makefiles; - open (CONF, ">$configure_scan") || - die "$me: cannot create $configure_scan: $!\n"; + my $file = new IO::File ">$configure_scan" + or die "$me: cannot create $configure_scan: $!\n"; - print CONF "# Process this file with autoconf to produce a configure script.\n"; - print CONF "AC_INIT\n"; + print $file "# Process this file with autoconf to produce a configure script.\n"; + print $file "AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)\n"; if (defined $cfiles[0]) { - print CONF "AC_CONFIG_SRCDIR([$cfiles[0]])\n"; - print CONF "AC_CONFIG_HEADER([config.h])\n"; + print $file "AC_CONFIG_SRCDIR([$cfiles[0]])\n"; + print $file "AC_CONFIG_HEADER([config.h])\n"; } - output_kind ('programs'); - output_kind ('makevars'); - output_libraries; - output_kind ('headers'); - output_kind ('identifiers'); - output_kind ('functions'); + output_kind ($file, 'programs'); + output_kind ($file, 'makevars'); + output_libraries ($file); + output_kind ($file, 'headers'); + output_kind ($file, 'identifiers'); + output_kind ($file, 'functions'); # Change DIR/Makefile.in to DIR/Makefile. foreach my $m (@makefiles) @@ -539,12 +559,12 @@ sub output ($) $m =~ s/\.in$//; $unique_makefiles{$m}++; } - print CONF "\nAC_CONFIG_FILES([", + print $file "\nAC_CONFIG_FILES([", join ("\n ", sort keys %unique_makefiles), "])\n"; - print CONF "AC_OUTPUT\n"; + print $file "AC_OUTPUT\n"; - close CONF || - die "$me: closing $configure_scan: $!\n"; + $file->close + or die "$me: cannot close $configure_scan: $!\n"; } @@ -560,19 +580,21 @@ sub output ($) # in CONFIGURE_AC. sub check_configure_ac ($) { - my ($configure_ac) = $@; + my ($configure_ac) = @_; my ($trace_option) = ''; + # Find what needed macros are invoked in CONFIGURE_AC. foreach my $macro (sort keys %needed_macros) { $macro =~ s/\(.*//; $trace_option .= " -t $macro"; } - open (TRACES, "$autoconf -A $datadir $trace_option $configure_ac|") || - die "$me: cannot create read traces: $!\n"; + my $traces = + new IO::File "$autoconf -A $datadir $trace_option $configure_ac|" + or die "$me: cannot create read traces: $!\n"; - while () + while ($_ = $traces->getline) { chomp; my ($file, $line, $macro, @args) = split (/:/, $_); @@ -597,15 +619,19 @@ sub check_configure_ac ($) } } - close (TRACES) || - die "$me: cannot close traces: $!\n"; + $traces->close + or die "$me: cannot close: $!\n"; + # Report the missing 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}}) { - warn "\t$need\n"; + print $log "\t$need\n"; } } } @@ -627,4 +653,7 @@ if ($configure_ac) check_configure_ac ($configure_ac); } +$log->close + or die "$me: cannot close $me.log: $!\n"; + exit 0; diff --git a/doc/autoconf.texi b/doc/autoconf.texi index da5fa65de..eea3d4525 100644 --- a/doc/autoconf.texi +++ b/doc/autoconf.texi @@ -985,25 +985,31 @@ checks for system services @section Using @code{autoscan} to Create @file{configure.ac} @cindex @code{autoscan} -The @code{autoscan} program can help you create a @file{configure.ac} -file for a software package. @code{autoscan} examines source files in -the directory tree rooted at a directory given as a command line -argument, or the current directory if none is given. It searches the -source files for common portability problems and creates a file -@file{configure.scan} which is a preliminary @file{configure.ac} for -that package. - -You should manually examine @file{configure.scan} before renaming it to +The @code{autoscan} program can help you create and/or maintain a +@file{configure.ac} file for a software package. @code{autoscan} +examines source files in the directory tree rooted at a directory given +as a command line argument, or the current directory if none is given. +It searches the source files for common portability problems and creates +a file @file{configure.scan} which is a preliminary @file{configure.ac} +for that package, and checks a possibly existing @file{configure.ac} for +completeness. + +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. -Occasionally, @code{autoscan} outputs a macro in the wrong order relative -to another macro, so that @code{autoconf} produces a warning; you need -to move such macros manually. Also, if you want the package to use a -configuration header file, you must add a call to -@code{AC_CONFIG_HEADERS} (@pxref{Configuration Headers}). You might also -have to change or add some @code{#if} directives to your program in +Occasionally, @code{autoscan} outputs a macro in the wrong order +relative to another macro, so that @code{autoconf} produces a warning; +you need to move such macros manually. Also, if you want the package to +use a configuration header file, you must add a call to +@code{AC_CONFIG_HEADERS} (@pxref{Configuration Headers}). You might +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 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) 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: diff --git a/man/autoscan.1 b/man/autoscan.1 index c4a1e17c9..680efc374 100644 --- a/man/autoscan.1 +++ b/man/autoscan.1 @@ -8,8 +8,9 @@ autoscan \- Generate a preliminary configure.in .SH DESCRIPTION Examine source files in the directory tree rooted at SRCDIR, or the current directory if none is given. Search the source files for -common portability problems and create a file `configure.scan' which -is a preliminary `configure.ac' for that package. +common portability problems, check for incompleteness of +`configure.ac', and create a file `configure.scan' which is a +preliminary `configure.ac' for that package. .TP \fB\-h\fR, \fB\-\-help\fR print this help, then exit