5 # autoscan - Create configure.scan (a preliminary configure.ac) for a package.
6 # Copyright (C) 1994, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
7 # 2007, 2008 Free Software Foundation, Inc.
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 2, or (at your option)
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with this program; if not, write to the Free Software
21 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 # Written by David MacKenzie <djm@gnu.ai.mit.edu>.
26 eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac'
31 my $datadir = $ENV{'autom4te_perllibdir'} || '@datadir@';
32 unshift @INC, $datadir;
34 # Override SHELL. On DJGPP SHELL may not be set to a shell
35 # that can handle redirection and quote arguments correctly,
36 # e.g.: COMMAND.COM. For DJGPP always use the shell that configure
38 $ENV{'SHELL'} = '@SHELL@' if ($^O eq 'dos');
41 use Autom4te::ChannelDefs;
42 use Autom4te::Configure_ac;
43 use Autom4te::General;
44 use Autom4te::FileUtils;
50 use vars qw(@cfiles @makefiles @shfiles @subdirs %printed);
52 # The kind of the words we are looking for.
53 my @kinds = qw (function header identifier program
56 # For each kind, the default macro.
59 'function' => 'AC_CHECK_FUNCS',
60 'header' => 'AC_CHECK_HEADERS',
61 'identifier' => 'AC_CHECK_TYPES',
62 'program' => 'AC_CHECK_PROGS',
63 'library' => 'AC_CHECK_LIB'
68 'function' => 'Checks for library functions.',
69 'header' => 'Checks for header files.',
70 'identifier' => 'Checks for typedefs, structures, and compiler characteristics.',
71 'program' => 'Checks for programs.',
74 # $USED{KIND}{ITEM} is the list of locations where the ITEM (of KIND) was used
75 # in the user package.
76 # For instance $USED{function}{alloca} is the list of `file:line' where
77 # `alloca (...)' appears.
80 # $MACRO{KIND}{ITEM} is the list of macros to use to test ITEM.
81 # Initialized from lib/autoscan/*. E.g., $MACRO{function}{alloca} contains
82 # the singleton AC_FUNC_ALLOCA. Some require several checks.
85 # $NEEDED_MACROS{MACRO} is an array of locations requiring MACRO.
86 # E.g., $NEEDED_MACROS{AC_FUNC_ALLOC} the list of `file:line' containing
93 my $configure_scan = 'configure.scan';
96 # Autoconf and lib files.
97 my $autom4te = $ENV{'AUTOM4TE'} || '@bindir@/@autom4te-name@';
98 my $autoconf = "$autom4te --language=autoconf";
100 my @include = ('@datadir@');
104 $help = "Usage: $0 [OPTION]... [SRCDIR]
106 Examine source files in the directory tree rooted at SRCDIR, or the
107 current directory if none is given. Search the source files for
108 common portability problems, check for incompleteness of
109 `configure.ac', and create a file `$configure_scan' which is a
110 preliminary `configure.ac' for that package.
112 -h, --help print this help, then exit
113 -V, --version print version number, then exit
114 -v, --verbose verbosely report processing
115 -d, --debug don't remove temporary files
118 -B, --prepend-include=DIR prepend directory DIR to search path
119 -I, --include=DIR append directory DIR to search path
121 Report bugs to <bug-autoconf\@gnu.org>.\n";
125 $version = "autoscan (@PACKAGE_NAME@) @VERSION@
126 Copyright (C) @RELEASE_YEAR@ Free Software Foundation, Inc.
127 License GPLv2+: GNU GPL version 2 or later
128 <http://gnu.org/licenses/old-licenses/gpl-2.0.html>
129 This is free software: you are free to change and redistribute it.
130 There is NO WARRANTY, to the extent permitted by law.
132 Written by David J. MacKenzie and Akim Demaille.
138 ## ------------------------ ##
139 ## Command line interface. ##
140 ## ------------------------ ##
144 # Process any command line arguments.
147 getopt ('I|include=s' => \@include,
148 'B|prepend-include=s' => \@prepend_include);
150 die "$me: too many arguments
151 Try `$me --help' for more information.\n"
154 my $srcdir = $ARGV[0] || ".";
156 verb "srcdir = $srcdir";
157 chdir $srcdir || error "cannot cd to $srcdir: $!";
163 # Put values in the tables of what to do with each token.
166 # The data file format supports only one line of macros per function.
167 # If more than that is required for a common portability problem,
168 # a new Autoconf macro should probably be written for that case,
169 # instead of duplicating the code in lots of configure.ac files.
170 my $file = find_file ("autoscan/autoscan.list",
171 reverse (@prepend_include), @include);
172 my $table = new Autom4te::XFile "< " . open_quote ($file);
173 my $tables_are_consistent = 1;
175 while ($_ = $table->getline)
177 # Ignore blank lines and comments.
179 if /^\s*$/ || /^\s*\#/;
181 # '<kind>: <word> <macro invocation>' or...
182 # '<kind>: <word> warn: <message>'.
183 if (/^(\S+):\s+(\S+)\s+(\S.*)$/)
185 my ($kind, $word, $macro) = ($1, $2, $3);
186 error "$file:$.: invalid kind: $_"
187 unless grep { $_ eq $kind } @kinds;
188 push @{$macro{$kind}{$word}}, $macro;
192 error "$file:$.: invalid definition: $_";
198 foreach my $kind (@kinds)
200 foreach my $word (sort keys %{$macro{$kind}})
202 print "$kind: $word: @{$macro{$kind}{$word}}\n";
210 # used ($KIND, $WORD, [$WHERE])
211 # -----------------------------
212 # $WORD is used as a $KIND.
215 my ($kind, $word, $where) = @_;
216 $where ||= "$File::Find::name:$.";
218 # Check for all the libraries. But `-links' is certainly a
219 # `find' argument, and `-le', a `test' argument.
220 ($kind eq 'library' && $word !~ /^(e|inks)$/)
221 # Other than libraries are to be checked only if listed in
222 # the Autoscan library files.
223 || defined $macro{$kind}{$word}
226 push (@{$used{$kind}{$word}}, $where);
232 ## ----------------------- ##
233 ## Scanning source files. ##
234 ## ----------------------- ##
237 # scan_c_file ($FILE-NAME)
238 # ------------------------
241 my ($file_name) = @_;
242 push @cfiles, $File::Find::name;
244 # Nonzero if in a multiline comment.
247 my $file = new Autom4te::XFile "< " . open_quote ($file_name);
249 while ($_ = $file->getline)
251 # Strip out comments.
252 if ($in_comment && s,^.*?\*/,,)
256 # The whole line is inside a commment.
261 # Starting on this line.
267 # Preprocessor directives.
270 if (/^include\s*<([^>]*)>/)
274 if (s/^(if|ifdef|ifndef|elif)\s+//)
276 foreach my $word (split (/\W+/))
278 used ('identifier', $word)
279 unless $word eq 'defined' || $word !~ /^[a-zA-Z_]/;
282 # Ignore other preprocessor directives.
286 # Remove string and character constants.
290 # Tokens in the code.
291 # Maybe we should ignore function definitions (in column 0)?
292 while (s/\b([a-zA-Z_]\w*)\s*\(/ /)
294 used ('function', $1);
296 while (s/\b([a-zA-Z_]\w*)\b/ /)
298 used ('identifier', $1);
306 # scan_makefile($MAKEFILE-NAME)
307 # -----------------------------
308 sub scan_makefile ($)
310 my ($file_name) = @_;
311 push @makefiles, $File::Find::name;
313 my $file = new Autom4te::XFile "< " . open_quote ($file_name);
315 while ($_ = $file->getline)
317 # Strip out comments.
320 # Variable assignments.
321 while (s/\b([a-zA-Z_]\w*)\s*=/ /)
323 used ('makevar', $1);
325 # Be sure to catch a whole word. For instance `lex$U.$(OBJEXT)'
326 # is a single token. Otherwise we might believe `lex' is needed.
327 foreach my $word (split (/\s+/))
330 if ($word =~ /^-l([a-zA-Z_]\w*)$/)
332 used ('library', $1);
334 # Tokens in the code.
335 # We allow some additional characters, e.g., `+', since
336 # autoscan/programs includes `c++'.
337 if ($word =~ /^[a-zA-Z_][\w+]*$/)
339 used ('program', $word);
348 # scan_sh_file($SHELL-SCRIPT-NAME)
349 # --------------------------------
352 my ($file_name) = @_;
353 push @shfiles, $File::Find::name;
355 my $file = new Autom4te::XFile "< " . open_quote ($file_name);
357 while ($_ = $file->getline)
359 # Strip out comments and variable references.
364 # Tokens in the code.
365 while (s/\b([a-zA-Z_]\w*)\b/ /)
367 used ('program', $1);
377 # Called by &find on each file. $_ contains the current file name with
378 # the current directory of the walk through.
381 # Wanted only if there is no corresponding FILE.in.
385 # Save $_ as Find::File requires it to be preserved.
388 # Strip a useless leading `./'.
389 $File::Find::name =~ s,^\./,,;
391 if ($_ ne '.' and -d $_ and
392 -f "$_/configure.in" ||
393 -f "$_/configure.ac" ||
394 -f "$_/configure.gnu" ||
397 $File::Find::prune = 1;
398 push @subdirs, $File::Find::name;
400 if (/\.[chlym](\.in)?$/)
402 used 'program', 'cc', $File::Find::name;
405 elsif (/\.(cc|cpp|cxx|CC|C|hh|hpp|hxx|HH|H|yy|ypp|ll|lpp)(\.in)?$/)
407 used 'program', 'c++', $File::Find::name;
410 elsif ((/^((?:GNUm|M|m)akefile)(\.in)?$/ && ! -f "$1.am")
411 || /^(?:GNUm|M|m)akefile(\.am)?$/)
415 elsif (/\.sh(\.in)?$/)
424 # Read through the files and collect lists of tokens in them
425 # that might create nonportabilities.
428 find (\&scan_file, '.');
432 print "cfiles: @cfiles\n";
433 print "makefiles: @makefiles\n";
434 print "shfiles: @shfiles\n";
436 foreach my $kind (@kinds)
439 foreach my $word (sort keys %{$used{$kind}})
441 print "$word: @{$used{$kind}{$word}}\n";
448 ## ----------------------- ##
449 ## Output configure.scan. ##
450 ## ----------------------- ##
453 # output_kind ($FILE, $KIND)
454 # --------------------------
457 my ($file, $kind) = @_;
458 # Lists of words to be checked with the generic macro.
461 print $file "\n# $kind_comment{$kind}\n"
462 if exists $kind_comment{$kind};
463 foreach my $word (sort keys %{$used{$kind}})
465 # Output the needed macro invocations in $configure_scan if not
466 # already printed, and remember these macros are needed.
467 foreach my $macro (@{$macro{$kind}{$word}})
469 if ($macro =~ /^warn:\s+(.*)/)
472 foreach my $location (@{$used{$kind}{$word}})
474 warn "$location: warning: $message\n";
477 elsif (exists $generic_macro{$kind}
478 && $macro eq $generic_macro{$kind})
481 push (@{$needed_macros{"$generic_macro{$kind}([$word])"}},
482 @{$used{$kind}{$word}});
486 if (! $printed{$macro})
488 print $file "$macro\n";
489 $printed{$macro} = 1;
491 push (@{$needed_macros{$macro}},
492 @{$used{$kind}{$word}});
496 print $file "$generic_macro{$kind}([" . join(' ', sort(@have)) . "])\n"
501 # output_libraries ($FILE)
502 # ------------------------
503 sub output_libraries ($)
507 print $file "\n# Checks for libraries.\n";
508 foreach my $word (sort keys %{$used{'library'}})
510 print $file "# FIXME: Replace `main' with a function in `-l$word':\n";
511 print $file "AC_CHECK_LIB([$word], [main])\n";
516 # output ($CONFIGURE_SCAN)
517 # ------------------------
518 # Print a proto configure.ac.
521 my $configure_scan = shift;
522 my %unique_makefiles;
524 my $file = new Autom4te::XFile "> " . open_quote ($configure_scan);
527 ("# -*- Autoconf -*-\n" .
528 "# Process this file with autoconf to produce a configure script.\n" .
530 "AC_PREREQ([@VERSION@])\n" .
531 "AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])\n");
532 if (defined $cfiles[0])
534 print $file "AC_CONFIG_SRCDIR([$cfiles[0]])\n";
535 print $file "AC_CONFIG_HEADERS([config.h])\n";
538 output_kind ($file, 'program');
539 output_kind ($file, 'makevar');
540 output_libraries ($file);
541 output_kind ($file, 'header');
542 output_kind ($file, 'identifier');
543 output_kind ($file, 'function');
548 # Change DIR/Makefile.in to DIR/Makefile.
549 foreach my $m (@makefiles)
551 $m =~ s/\.(?:in|am)$//;
552 $unique_makefiles{$m}++;
554 print $file ("AC_CONFIG_FILES([",
556 sort keys %unique_makefiles), "])\n");
560 print $file ("AC_CONFIG_SUBDIRS([",
562 sort @subdirs), "])\n");
564 print $file "AC_OUTPUT\n";
571 ## --------------------------------------- ##
572 ## Checking the accuracy of configure.ac. ##
573 ## --------------------------------------- ##
576 # &check_configure_ac ($CONFIGURE_AC)
577 # -----------------------------------
578 # Use autoconf to check if all the suggested macros are included
580 sub check_configure_ac ($)
582 my ($configure_ac) = @_;
584 # Find what needed macros are invoked in CONFIGURE_AC.
585 # I'd be very happy if someone could explain to me why sort (uniq ...)
586 # doesn't work properly: I need `uniq (sort ...)'. --akim
588 join (' --trace=', '',
589 uniq (sort (map { s/\(.*//; $_ } keys %needed_macros)));
591 verb "running: $autoconf $trace_option $configure_ac";
593 new Autom4te::XFile "$autoconf $trace_option $configure_ac |";
595 while ($_ = $traces->getline)
598 my ($file, $line, $macro, @args) = split (/:/, $_);
599 if ($macro =~ /^AC_CHECK_(HEADER|FUNC|TYPE|MEMBER)S$/)
601 # To be rigorous, we should distinguish between space and comma
602 # separated macros. But there is no point.
603 foreach my $word (split (/\s|,/, $args[0]))
605 # AC_CHECK_MEMBERS wants `struct' or `union'.
606 if ($macro eq "AC_CHECK_MEMBERS"
607 && $word =~ /^stat.st_/)
609 $word = "struct " . $word;
611 delete $needed_macros{"$macro([$word])"};
616 delete $needed_macros{$macro};
622 # Report the missing macros.
623 foreach my $macro (sort keys %needed_macros)
625 warn ("$configure_ac: warning: missing $macro wanted by: "
626 . (${$needed_macros{$macro}}[0])
628 print $log "$me: warning: missing $macro wanted by: \n";
629 foreach my $need (@{$needed_macros{$macro}})
631 print $log "\t$need\n";
642 $log = new Autom4te::XFile "> " . open_quote ("$me.log");
644 $autoconf .= " --debug" if $debug;
645 $autoconf .= " --verbose" if $verbose;
646 $autoconf .= join (' --include=', '', map { shell_quote ($_) } @include);
647 $autoconf .= join (' --prepend-include=', '', map { shell_quote ($_) } @prepend_include);
649 my $configure_ac = find_configure_ac;
652 output ('configure.scan');
653 if (-f $configure_ac)
655 check_configure_ac ($configure_ac);
657 # This close is really needed. For some reason, probably best named
658 # a bug, it seems that the dtor of $LOG is not called automatically
659 # at END. It results in a truncated file.
663 ### Setup "GNU" style for perl-mode and cperl-mode.
665 ## perl-indent-level: 2
666 ## perl-continued-statement-offset: 2
667 ## perl-continued-brace-offset: 0
668 ## perl-brace-offset: 0
669 ## perl-brace-imaginary-offset: 0
670 ## perl-label-offset: -2
671 ## cperl-indent-level: 2
672 ## cperl-brace-offset: 0
673 ## cperl-continued-brace-offset: 0
674 ## cperl-label-offset: -2
675 ## cperl-extra-newline-before-brace: t
676 ## cperl-merge-trailing-else: nil
677 ## cperl-continued-statement-offset: 2