Add our mirror of MSys as a submodule
[msysgit.git] / bin / autoscan
blob32b9c9d9f5e76944c435bb0d8a02d686de7b3263
1 #! /bin/perl -w
2 # -*- perl -*-
3 # Generated from autoscan.in; do not edit by hand.
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 # 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)
12 # any later version.
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
22 # 02110-1301, USA.
24 # Written by David MacKenzie <djm@gnu.ai.mit.edu>.
26 eval 'case $# in 0) exec /bin/perl -S "$0";; *) exec /bin/perl -S "$0" "$@";; esac'
27 if 0;
29 BEGIN
31 my $datadir = $ENV{'autom4te_perllibdir'} || '/usr/share/autoconf';
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
37 # has detected.
38 $ENV{'SHELL'} = '/bin/sh' if ($^O eq 'dos');
41 use Autom4te::ChannelDefs;
42 use Autom4te::Configure_ac;
43 use Autom4te::General;
44 use Autom4te::FileUtils;
45 use Autom4te::XFile;
46 use File::Basename;
47 use File::Find;
48 use strict;
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
54 makevar librarie);
56 # For each kind, the default macro.
57 my %generic_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'
66 my %kind_comment =
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.
78 my %used = ();
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.
83 my %macro = ();
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
87 # `alloca (...)'.
88 my %needed_macros =
90 'AC_PREREQ' => [$me],
93 my $configure_scan = 'configure.scan';
94 my $log;
96 # Autoconf and lib files.
97 my $autom4te = $ENV{'AUTOM4TE'} || '/usr/bin/autom4te';
98 my $autoconf = "$autom4te --language=autoconf";
99 my @prepend_include;
100 my @include = ('/usr/share/autoconf');
102 # $help
103 # -----
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
117 Library directories:
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";
123 # $version
124 # --------
125 $version = "autoscan (GNU Autoconf) 2.61
126 Copyright (C) 2006 Free Software Foundation, Inc.
127 This is free software. You may redistribute copies of it under the terms of
128 the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
129 There is NO WARRANTY, to the extent permitted by law.
131 Written by David J. MacKenzie and Akim Demaille.
137 ## ------------------------ ##
138 ## Command line interface. ##
139 ## ------------------------ ##
141 # parse_args ()
142 # -------------
143 # Process any command line arguments.
144 sub parse_args ()
146 getopt ('I|include=s' => \@include,
147 'B|prepend-include=s' => \@prepend_include);
149 die "$me: too many arguments
150 Try `$me --help' for more information.\n"
151 if @ARGV > 1;
153 my $srcdir = $ARGV[0] || ".";
155 verb "srcdir = $srcdir";
156 chdir $srcdir || error "cannot cd to $srcdir: $!";
160 # init_tables ()
161 # --------------
162 # Put values in the tables of what to do with each token.
163 sub init_tables ()
165 # The data file format supports only one line of macros per function.
166 # If more than that is required for a common portability problem,
167 # a new Autoconf macro should probably be written for that case,
168 # instead of duplicating the code in lots of configure.ac files.
169 my $file = find_file ("autoscan/autoscan.list",
170 reverse (@prepend_include), @include);
171 my $table = new Autom4te::XFile $file;
172 my $tables_are_consistent = 1;
174 while ($_ = $table->getline)
176 # Ignore blank lines and comments.
177 next
178 if /^\s*$/ || /^\s*\#/;
180 # '<kind>: <word> <macro invocation>' or...
181 # '<kind>: <word> warn: <message>'.
182 if (/^(\S+):\s+(\S+)\s+(\S.*)$/)
184 my ($kind, $word, $macro) = ($1, $2, $3);
185 error "$file:$.: invalid kind: $_"
186 unless grep { $_ eq $kind } @kinds;
187 push @{$macro{$kind}{$word}}, $macro;
189 else
191 error "$file:$.: invalid definition: $_";
195 if ($debug)
197 foreach my $kind (@kinds)
199 foreach my $word (sort keys %{$macro{$kind}})
201 print "$kind: $word: @{$macro{$kind}{$word}}\n";
209 # used ($KIND, $WORD, [$WHERE])
210 # -----------------------------
211 # $WORD is used as a $KIND.
212 sub used ($$;$)
214 my ($kind, $word, $where) = @_;
215 $where ||= "$File::Find::name:$.";
216 if (
217 # Check for all the libraries. But `-links' is certainly a
218 # `find' argument, and `-le', a `test' argument.
219 ($kind eq 'library' && $word !~ /^(e|inks)$/)
220 # Other than libraries are to be checked only if listed in
221 # the Autoscan library files.
222 || defined $macro{$kind}{$word}
225 push (@{$used{$kind}{$word}}, $where);
231 ## ----------------------- ##
232 ## Scanning source files. ##
233 ## ----------------------- ##
236 # scan_c_file ($FILE-NAME)
237 # ------------------------
238 sub scan_c_file ($)
240 my ($file_name) = @_;
241 push @cfiles, $File::Find::name;
243 # Nonzero if in a multiline comment.
244 my $in_comment = 0;
246 my $file = new Autom4te::XFile "<$file_name";
248 while ($_ = $file->getline)
250 # Strip out comments.
251 if ($in_comment && s,^.*?\*/,,)
253 $in_comment = 0;
255 # The whole line is inside a commment.
256 next if $in_comment;
257 # All on one line.
258 s,/\*.*?\*/,,g;
260 # Starting on this line.
261 if (s,/\*.*$,,)
263 $in_comment = 1;
266 # Preprocessor directives.
267 if (s/^\s*\#\s*//)
269 if (/^include\s*<([^>]*)>/)
271 used ('header', $1);
273 if (s/^(if|ifdef|ifndef|elif)\s+//)
275 foreach my $word (split (/\W+/))
277 used ('identifier', $word)
278 unless $word eq 'defined' || $word !~ /^[a-zA-Z_]/;
281 # Ignore other preprocessor directives.
282 next;
285 # Remove string and character constants.
286 s,\"[^\"]*\",,g;
287 s,\'[^\']*\',,g;
289 # Tokens in the code.
290 # Maybe we should ignore function definitions (in column 0)?
291 while (s/\b([a-zA-Z_]\w*)\s*\(/ /)
293 used ('function', $1);
295 while (s/\b([a-zA-Z_]\w*)\b/ /)
297 used ('identifier', $1);
301 $file->close;
305 # scan_makefile($MAKEFILE-NAME)
306 # -----------------------------
307 sub scan_makefile ($)
309 my ($file_name) = @_;
310 push @makefiles, $File::Find::name;
312 my $file = new Autom4te::XFile "<$file_name";
314 while ($_ = $file->getline)
316 # Strip out comments.
317 s/#.*//;
319 # Variable assignments.
320 while (s/\b([a-zA-Z_]\w*)\s*=/ /)
322 used ('makevar', $1);
324 # Be sure to catch a whole word. For instance `lex$U.$(OBJEXT)'
325 # is a single token. Otherwise we might believe `lex' is needed.
326 foreach my $word (split (/\s+/))
328 # Libraries.
329 if ($word =~ /^-l([a-zA-Z_]\w*)$/)
331 used ('library', $1);
333 # Tokens in the code.
334 # We allow some additional characters, e.g., `+', since
335 # autoscan/programs includes `c++'.
336 if ($word =~ /^[a-zA-Z_][\w+]*$/)
338 used ('program', $word);
343 $file->close;
347 # scan_sh_file($SHELL-SCRIPT-NAME)
348 # --------------------------------
349 sub scan_sh_file ($)
351 my ($file_name) = @_;
352 push @shfiles, $File::Find::name;
354 my $file = new Autom4te::XFile "<$file_name";
356 while ($_ = $file->getline)
358 # Strip out comments and variable references.
359 s/#.*//;
360 s/\${[^\}]*}//g;
361 s/@[^@]*@//g;
363 # Tokens in the code.
364 while (s/\b([a-zA-Z_]\w*)\b/ /)
366 used ('program', $1);
370 $file->close;
374 # scan_file ()
375 # ------------
376 # Called by &find on each file. $_ contains the current file name with
377 # the current directory of the walk through.
378 sub scan_file ()
380 # Wanted only if there is no corresponding FILE.in.
381 return
382 if -f "$_.in";
384 # Save $_ as Find::File requires it to be preserved.
385 local $_ = $_;
387 # Strip a useless leading `./'.
388 $File::Find::name =~ s,^\./,,;
390 if ($_ ne '.' and -d $_ and
391 -f "$_/configure.in" ||
392 -f "$_/configure.ac" ||
393 -f "$_/configure.gnu" ||
394 -f "$_/configure")
396 $File::Find::prune = 1;
397 push @subdirs, $File::Find::name;
399 if (/\.[chlym](\.in)?$/)
401 used 'program', 'cc', $File::Find::name;
402 scan_c_file ($_);
404 elsif (/\.(cc|cpp|cxx|CC|C|hh|hpp|hxx|HH|H|yy|ypp|ll|lpp)(\.in)?$/)
406 used 'program', 'c++', $File::Find::name;
407 scan_c_file ($_);
409 elsif ((/^((?:GNUm|M|m)akefile)(\.in)?$/ && ! -f "$1.am")
410 || /^(?:GNUm|M|m)akefile(\.am)?$/)
412 scan_makefile ($_);
414 elsif (/\.sh(\.in)?$/)
416 scan_sh_file ($_);
421 # scan_files ()
422 # -------------
423 # Read through the files and collect lists of tokens in them
424 # that might create nonportabilities.
425 sub scan_files ()
427 find (\&scan_file, '.');
429 if ($verbose)
431 print "cfiles: @cfiles\n";
432 print "makefiles: @makefiles\n";
433 print "shfiles: @shfiles\n";
435 foreach my $kind (@kinds)
437 print "\n$kind:\n";
438 foreach my $word (sort keys %{$used{$kind}})
440 print "$word: @{$used{$kind}{$word}}\n";
447 ## ----------------------- ##
448 ## Output configure.scan. ##
449 ## ----------------------- ##
452 # output_kind ($FILE, $KIND)
453 # --------------------------
454 sub output_kind ($$)
456 my ($file, $kind) = @_;
457 # Lists of words to be checked with the generic macro.
458 my @have;
460 print $file "\n# $kind_comment{$kind}\n"
461 if exists $kind_comment{$kind};
462 foreach my $word (sort keys %{$used{$kind}})
464 # Output the needed macro invocations in $configure_scan if not
465 # already printed, and remember these macros are needed.
466 foreach my $macro (@{$macro{$kind}{$word}})
468 if ($macro =~ /^warn:\s+(.*)/)
470 my $message = $1;
471 foreach my $location (@{$used{$kind}{$word}})
473 warn "$location: warning: $message\n";
476 elsif (exists $generic_macro{$kind}
477 && $macro eq $generic_macro{$kind})
479 push (@have, $word);
480 push (@{$needed_macros{"$generic_macro{$kind}([$word])"}},
481 @{$used{$kind}{$word}});
483 else
485 if (! $printed{$macro})
487 print $file "$macro\n";
488 $printed{$macro} = 1;
490 push (@{$needed_macros{$macro}},
491 @{$used{$kind}{$word}});
495 print $file "$generic_macro{$kind}([" . join(' ', sort(@have)) . "])\n"
496 if @have;
500 # output_libraries ($FILE)
501 # ------------------------
502 sub output_libraries ($)
504 my ($file) = @_;
506 print $file "\n# Checks for libraries.\n";
507 foreach my $word (sort keys %{$used{'library'}})
509 print $file "# FIXME: Replace `main' with a function in `-l$word':\n";
510 print $file "AC_CHECK_LIB([$word], [main])\n";
515 # output ($CONFIGURE_SCAN)
516 # ------------------------
517 # Print a proto configure.ac.
518 sub output ($)
520 my $configure_scan = shift;
521 my %unique_makefiles;
523 my $file = new Autom4te::XFile ">$configure_scan";
525 print $file
526 ("# -*- Autoconf -*-\n" .
527 "# Process this file with autoconf to produce a configure script.\n" .
528 "\n" .
529 "AC_PREREQ(2.61)\n" .
530 "AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)\n");
531 if (defined $cfiles[0])
533 print $file "AC_CONFIG_SRCDIR([$cfiles[0]])\n";
534 print $file "AC_CONFIG_HEADER([config.h])\n";
537 output_kind ($file, 'program');
538 output_kind ($file, 'makevar');
539 output_libraries ($file);
540 output_kind ($file, 'header');
541 output_kind ($file, 'identifier');
542 output_kind ($file, 'function');
544 print $file "\n";
545 if (@makefiles)
547 # Change DIR/Makefile.in to DIR/Makefile.
548 foreach my $m (@makefiles)
550 $m =~ s/\.(?:in|am)$//;
551 $unique_makefiles{$m}++;
553 print $file ("AC_CONFIG_FILES([",
554 join ("\n ",
555 sort keys %unique_makefiles), "])\n");
557 if (@subdirs)
559 print $file ("AC_CONFIG_SUBDIRS([",
560 join ("\n ",
561 sort @subdirs), "])\n");
563 print $file "AC_OUTPUT\n";
565 $file->close;
570 ## --------------------------------------- ##
571 ## Checking the accuracy of configure.ac. ##
572 ## --------------------------------------- ##
575 # &check_configure_ac ($CONFIGURE_AC)
576 # -----------------------------------
577 # Use autoconf to check if all the suggested macros are included
578 # in CONFIGURE_AC.
579 sub check_configure_ac ($)
581 my ($configure_ac) = @_;
583 # Find what needed macros are invoked in CONFIGURE_AC.
584 # I'd be very happy if someone could explain to me why sort (uniq ...)
585 # doesn't work properly: I need `uniq (sort ...)'. --akim
586 my $trace_option =
587 join (' --trace=', '',
588 uniq (sort (map { s/\(.*//; $_ } keys %needed_macros)));
590 verb "running: $autoconf $trace_option $configure_ac";
591 my $traces =
592 new Autom4te::XFile "$autoconf $trace_option $configure_ac|";
594 while ($_ = $traces->getline)
596 chomp;
597 my ($file, $line, $macro, @args) = split (/:/, $_);
598 if ($macro =~ /^AC_CHECK_(HEADER|FUNC|TYPE|MEMBER)S$/)
600 # To be rigorous, we should distinguish between space and comma
601 # separated macros. But there is no point.
602 foreach my $word (split (/\s|,/, $args[0]))
604 # AC_CHECK_MEMBERS wants `struct' or `union'.
605 if ($macro eq "AC_CHECK_MEMBERS"
606 && $word =~ /^stat.st_/)
608 $word = "struct " . $word;
610 delete $needed_macros{"$macro([$word])"};
613 else
615 delete $needed_macros{$macro};
619 $traces->close;
621 # Report the missing macros.
622 foreach my $macro (sort keys %needed_macros)
624 warn ("$configure_ac: warning: missing $macro wanted by: "
625 . (${$needed_macros{$macro}}[0])
626 . "\n");
627 print $log "$me: warning: missing $macro wanted by: \n";
628 foreach my $need (@{$needed_macros{$macro}})
630 print $log "\t$need\n";
636 ## -------------- ##
637 ## Main program. ##
638 ## -------------- ##
640 parse_args;
641 $log = new Autom4te::XFile ">$me.log";
643 $autoconf .= " --debug" if $debug;
644 $autoconf .= " --verbose" if $verbose;
645 $autoconf .= join (' --include=', '', @include);
646 $autoconf .= join (' --prepend-include=', '', @prepend_include);
648 my $configure_ac = find_configure_ac;
649 init_tables;
650 scan_files;
651 output ('configure.scan');
652 if (-f $configure_ac)
654 check_configure_ac ($configure_ac);
656 # This close is really needed. For some reason, probably best named
657 # a bug, it seems that the dtor of $LOG is not called automatically
658 # at END. It results in a truncated file.
659 $log->close;
660 exit 0;
662 ### Setup "GNU" style for perl-mode and cperl-mode.
663 ## Local Variables:
664 ## perl-indent-level: 2
665 ## perl-continued-statement-offset: 2
666 ## perl-continued-brace-offset: 0
667 ## perl-brace-offset: 0
668 ## perl-brace-imaginary-offset: 0
669 ## perl-label-offset: -2
670 ## cperl-indent-level: 2
671 ## cperl-brace-offset: 0
672 ## cperl-continued-brace-offset: 0
673 ## cperl-label-offset: -2
674 ## cperl-extra-newline-before-brace: t
675 ## cperl-merge-trailing-else: nil
676 ## cperl-continued-statement-offset: 2
677 ## End: