3 # autoscan - Create configure.scan (a preliminary configure.ac) for a package.
4 # Copyright (C) 1994, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2, or (at your option)
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21 # Written by David MacKenzie <djm@gnu.ai.mit.edu>.
23 eval 'case $# in 0) exec /bin/perl -S "$0";; *) exec /bin/perl -S "$0" "$@";; esac'
28 my $perllibdir = $ENV{'autom4te_perllibdir'} || "/usr/share/autoconf";
29 unshift @INC, "$perllibdir";
32 use Autom4te
::General
;
38 use vars
qw(@cfiles @makefiles @shfiles %printed);
40 # The kind of the words we are looking for.
41 my @kinds = qw (function header identifier program
44 # For each kind, the default macro.
47 'function' => 'AC_CHECK_FUNCS',
48 'header' => 'AC_CHECK_HEADERS',
49 'identifier' => 'AC_CHECK_TYPES',
50 'program' => 'AC_CHECK_PROGS',
51 'library' => 'AC_CHECK_LIB'
56 'function' => 'Checks for library functions.',
57 'header' => 'Checks for header files.',
58 'identifier' => 'Checks for typedefs, structures, and compiler characteristics.',
59 'program' => 'Checks for programs.',
62 # $USED{KIND}{ITEM} is the list of locations where the ITEM (of KIND) was used
63 # in the user package.
64 # For instance $USED{function}{alloca} is the list of `file:line' where
65 # `alloca (...)' appears.
68 # $MACRO{KIND}{ITEM} is the list of macros to use to test ITEM.
69 # Initialized from lib/autoscan/*. E.g., $MACRO{function}{alloca} contains
70 # the singleton AC_FUNC_ALLOCA. Some require several checks.
73 # $NEEDED_MACROS{MACRO} is an array of locations requiring MACRO.
74 # E.g., $NEEDED_MACROS{AC_FUNC_ALLOC} the list of `file:line' containing
81 my $configure_scan = 'configure.scan';
82 my $log = new Autom4te::XFile ">$me.log";
84 # Autoconf and lib files.
85 my $autom4te = $ENV{'AUTOM4TE'} || '/usr/bin/autom4te';
86 my $autoconf = "$autom4te --language=autoconf";
88 my @include = ('/usr/share/autoconf');
92 $help = "Usage: $0 [OPTION] ... [SRCDIR]
94 Examine source files in the directory tree rooted at SRCDIR, or the
95 current directory if none is given. Search the source files for
96 common portability problems, check for incompleteness of
97 `configure.ac', and create a file `$configure_scan' which is a
98 preliminary `configure.ac' for that package.
100 -h, --help print this help, then exit
101 -V, --version print version number, then exit
102 -v, --verbose verbosely report processing
103 -d, --debug don't remove temporary files
106 -B, --prepend-include=DIR prepend directory DIR to search path
107 -I, --include=DIR append directory DIR to search path
109 Report bugs to <bug-autoconf\@gnu.org>.\n";
113 $version = "autoscan (GNU Autoconf) 2.56
114 Written by David J. MacKenzie and Akim Demaille.
116 Copyright 2002 Free Software Foundation, Inc.
117 This is free software; see the source for copying conditions. There is NO
118 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
123 ## ------------------------ ##
124 ## Command line interface. ##
125 ## ------------------------ ##
129 # Process any command line arguments.
132 getopt ('I|include=s' => \@include,
133 'B|prepend-include=s' => \@prepend_include);
135 die "$me: too many arguments
136 Try `$me --help' for more information.\n"
139 my $srcdir = $ARGV[0] || ".";
141 verbose "srcdir = $srcdir";
142 chdir $srcdir || error "cannot cd to $srcdir: $!";
148 # Put values in the tables of what to do with each token.
151 # The data file format supports only one line of macros per function.
152 # If more than that is required for a common portability problem,
153 # a new Autoconf macro should probably be written for that case,
154 # instead of duplicating the code in lots of configure.ac files.
155 my $file = find_file ("autoscan/autoscan.list",
156 reverse (@prepend_include), @include);
157 my $table = new Autom4te::XFile $file;
158 my $tables_are_consistent = 1;
160 while ($_ = $table->getline)
162 # Ignore blank lines and comments.
164 if /^\s*$/ || /^\s*\#/;
166 # '<kind>: <word> <macro invocation>' or...
167 # '<kind>: <word> warn: <message>'.
168 if (/^(\S+):\s+(\S+)\s+(\S.*)$/)
170 my ($kind, $word, $macro) = ($1, $2, $3);
171 error "$file:$.: invalid kind: $_"
172 unless grep { $_ eq $kind } @kinds;
173 push @{$macro{$kind}{$word}}, $macro;
177 error "$file:$.: invalid definition: $_";
183 foreach my $kind (@kinds)
185 foreach my $word (sort keys %{$macro{$kind}})
187 print "$kind: $word: @{$macro{$kind}{$word}}\n";
195 # used ($KIND, $WORD, [$WHERE])
196 # -----------------------------
197 # $WORD is used as a $KIND.
200 my ($kind, $word, $where) = @_;
201 $where ||= "$File::Find::name:$.";
203 # Check for all the libraries. But `-links' is certainly a
204 # `find' argument, and `-le', a `test' argument.
205 ($kind eq 'library' && $word !~ /^(e|inks)$/)
206 # Other than libraries are to be checked only if listed in
207 # the Autoscan library files.
208 || defined $macro{$kind}{$word}
211 push (@{$used{$kind}{$word}}, $where);
217 ## ----------------------- ##
218 ## Scanning source files. ##
219 ## ----------------------- ##
222 # scan_c_file ($FILENAME)
223 # -----------------------
227 push @cfiles, $File::Find::name;
229 # Nonzero if in a multiline comment.
232 my $file = new Autom4te::XFile "<$filename";
234 while ($_ = $file->getline)
236 # Strip out comments.
237 if ($in_comment && s,^.*?\*/,,)
241 # The whole line is inside a commment.
246 # Starting on this line.
252 # Preprocessor directives.
255 if (/^include\s*<([^>]*)>/)
259 if (s/^(if|ifdef|ifndef|elif)\s+//)
261 foreach my $word (split (/\W+/))
263 used ('identifier', $word)
264 unless $word eq 'defined' || $word !~ /^[a-zA-Z_]/;
267 # Ignore other preprocessor directives.
271 # Remove string and character constants.
275 # Tokens in the code.
276 # Maybe we should ignore function definitions (in column 0)?
277 while (s/\b([a-zA-Z_]\w*)\s*\(/ /)
279 used ('function', $1);
281 while (s/\b([a-zA-Z_]\w*)\b/ /)
283 used ('identifier', $1);
291 # scan_makefile($MAKEFILE-NAME)
292 # -----------------------------
293 sub scan_makefile ($)
296 push @makefiles, $File::Find::name;
298 my $file = new Autom4te::XFile "<$filename";
300 while ($_ = $file->getline)
302 # Strip out comments.
305 # Variable assignments.
306 while (s/\b([a-zA-Z_]\w*)\s*=/ /)
308 used ('makevar', $1);
310 # Be sure to catch a whole word. For instance `lex$U.$(OBJEXT)'
311 # is a single token. Otherwise we might believe `lex' is needed.
312 foreach my $word (split (/\s+/))
315 if ($word =~ /^-l([a-zA-Z_]\w*)$/)
317 used ('library', $1);
319 # Tokens in the code.
320 # We allow some additional characters, e.g., `+', since
321 # autoscan/programs includes `c++'.
322 if ($word =~ /^[a-zA-Z_][\w+]*$/)
324 used ('program', $word);
333 # scan_sh_file($SHELL-SCRIPT-NAME)
334 # --------------------------------
338 push @shfiles, $File::Find::name;
340 my $file = new Autom4te::XFile "<$filename";
342 while ($_ = $file->getline)
344 # Strip out comments and variable references.
349 # Tokens in the code.
350 while (s/\b([a-zA-Z_]\w*)\b/ /)
352 used ('program', $1);
362 # Called by &find on each file. $_ contains the current filename with
363 # the current directory of the walk through.
366 # Wanted only if there is no corresponding FILE.in.
370 # Save $_ as Find::File requires it to be preserved.
373 # Strip a useless leading `./'.
374 $File::Find::name =~ s,^\./,,;
376 if (/\.[chlym](\.in)?$/)
378 used 'program', 'cc', $File::Find::name;
381 elsif (/\.(cc|cpp|cxx|CC|C|hh|hpp|hxx|HH|H|yy|ypp|ll|lpp)(\.in)?$/)
383 used 'program', 'c++', $File::Find::name;
386 elsif ((/^((?:GNUm|M|m)akefile)(\.in)?$/ && ! -f "$1.am")
387 || /^(?:GNUm|M|m)akefile(\.am)?$/)
391 elsif (/\.sh(\.in)?$/)
400 # Read through the files and collect lists of tokens in them
401 # that might create nonportabilities.
404 find (\&scan_file, '.');
408 print "cfiles: @cfiles\n";
409 print "makefiles: @makefiles\n";
410 print "shfiles: @shfiles\n";
412 foreach my $kind (@kinds)
415 foreach my $word (sort keys %{$used{$kind}})
417 print "$word: @{$used{$kind}{$word}}\n";
424 ## ----------------------- ##
425 ## Output configure.scan. ##
426 ## ----------------------- ##
429 # output_kind ($FILE, $KIND)
430 # --------------------------
433 my ($file, $kind) = @_;
434 # Lists of words to be checked with the generic macro.
437 print $file "\n# $kind_comment{$kind}\n"
438 if exists $kind_comment{$kind};
439 foreach my $word (sort keys %{$used{$kind}})
441 # Output the needed macro invocations in $configure_scan if not
442 # already printed, and remember these macros are needed.
443 foreach my $macro (@{$macro{$kind}{$word}})
445 if ($macro =~ /^warn:\s+(.*)/)
448 foreach my $location (@{$used{$kind}{$word}})
450 warn "$location: warning: $message\n";
453 elsif (exists $generic_macro{$kind}
454 && $macro eq $generic_macro{$kind})
457 push (@{$needed_macros{"$generic_macro{$kind}([$word])"}},
458 @{$used{$kind}{$word}});
462 if (! $printed{$macro})
464 print $file "$macro\n";
465 $printed{$macro} = 1;
467 push (@{$needed_macros{$macro}},
468 @{$used{$kind}{$word}});
472 print $file "$generic_macro{$kind}([" . join(' ', sort(@have)) . "])\n"
477 # output_libraries ($FILE)
478 # ------------------------
479 sub output_libraries ($)
483 print $file "\n# Checks for libraries.\n";
484 foreach my $word (sort keys %{$used{'library'}})
486 print $file "# FIXME: Replace `main' with a function in `-l$word':\n";
487 print $file "AC_CHECK_LIB([$word], [main])\n";
492 # output ($CONFIGURE_SCAN)
493 # ------------------------
494 # Print a proto configure.ac.
497 my $configure_scan = shift;
498 my %unique_makefiles;
500 my $file = new Autom4te::XFile ">$configure_scan";
503 ("# -*- Autoconf -*-\n" .
504 "# Process this file with autoconf to produce a configure script.\n" .
506 "AC_PREREQ(2.56)\n" .
507 "AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)\n");
508 if (defined $cfiles[0])
510 print $file "AC_CONFIG_SRCDIR([$cfiles[0]])\n";
511 print $file "AC_CONFIG_HEADER([config.h])\n";
514 output_kind ($file, 'program');
515 output_kind ($file, 'makevar');
516 output_libraries ($file);
517 output_kind ($file, 'header');
518 output_kind ($file, 'identifier');
519 output_kind ($file, 'function');
523 # Change DIR/Makefile.in to DIR/Makefile.
524 foreach my $m (@makefiles)
526 $m =~ s/\.(?:in|am)$//;
527 $unique_makefiles{$m}++;
529 print $file ("\nAC_CONFIG_FILES([",
531 sort keys %unique_makefiles), "])\n");
533 print $file "AC_OUTPUT\n";
540 ## --------------------------------------- ##
541 ## Checking the accuracy of configure.ac. ##
542 ## --------------------------------------- ##
545 # &check_configure_ac ($CONFIGURE_AC)
546 # -----------------------------------
547 # Use autoconf to check if all the suggested macros are included
549 sub check_configure_ac ($)
551 my ($configure_ac) = @_;
553 # Find what needed macros are invoked in CONFIGURE_AC.
554 # I'd be very happy if someone could explain to me why sort (uniq ...)
555 # doesn't work properly: I need `uniq (sort ...)'. --akim
557 join (' --trace=', '',
558 uniq (sort (map { s/\(.*//; $_ } keys %needed_macros)));
560 verbose "running: $autoconf $trace_option $configure_ac";
562 new Autom4te::XFile "$autoconf $trace_option $configure_ac|";
564 while ($_ = $traces->getline)
567 my ($file, $line, $macro, @args) = split (/:/, $_);
568 if ($macro =~ /^AC_CHECK_(HEADER|FUNC|TYPE|MEMBER)S$/)
570 # To be rigorous, we should distinguish between space and comma
571 # separated macros. But there is no point.
572 foreach my $word (split (/\s|,/, $args[0]))
574 # AC_CHECK_MEMBERS wants `struct' or `union'.
575 if ($macro eq "AC_CHECK_MEMBERS"
576 && $word =~ /^stat.st_/)
578 $word = "struct " . $word;
580 delete $needed_macros{"$macro([$word])"};
585 delete $needed_macros{$macro};
591 # Report the missing macros.
592 foreach my $macro (sort keys %needed_macros)
594 warn ("$configure_ac: warning: missing $macro wanted by: "
595 . (${$needed_macros{$macro}}[0])
597 print $log "$me: warning: missing $macro wanted by: \n";
598 foreach my $need (@{$needed_macros{$macro}})
600 print $log "\t$need\n";
611 $autoconf .= " --debug" if $debug;
612 $autoconf .= " --verbose" if $verbose;
613 $autoconf .= join (' --include=', '', @include);
614 $autoconf .= join (' --prepend-include=', '', @prepend_include);
616 my $configure_ac = find_configure_ac;
619 output ('configure.scan');
622 check_configure_ac ($configure_ac);
624 # This close is really needed. For some reason, probably best named
625 # a bug, it seems that the dtor of $LOG is not called automatically
626 # at END. It results in a truncated file.
630 ### Setup "GNU" style for perl-mode and cperl-mode.
632 ## perl-indent-level: 2
633 ## perl-continued-statement-offset: 2
634 ## perl-continued-brace-offset: 0
635 ## perl-brace-offset: 0
636 ## perl-brace-imaginary-offset: 0
637 ## perl-label-offset: -2
638 ## cperl-indent-level: 2
639 ## cperl-brace-offset: 0
640 ## cperl-continued-brace-offset: 0
641 ## cperl-label-offset: -2
642 ## cperl-extra-newline-before-brace: t
643 ## cperl-merge-trailing-else: nil
644 ## cperl-continued-statement-offset: 2