Initial bulk commit for "Git on MSys"
[msysgit/historical-msysgit.git] / bin / autoscan
blob8a8da7c488ba8ee63951d2f731fcb9f35846e873
1 #! /bin/perl -w
2 # -*- perl -*-
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)
9 # any later version.
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
19 # 02111-1307, USA.
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'
24 if 0;
26 BEGIN
28 my $perllibdir = $ENV{'autom4te_perllibdir'} || "/usr/share/autoconf";
29 unshift @INC, "$perllibdir";
32 use Autom4te::General;
33 use Autom4te::XFile;
34 use File::Basename;
35 use File::Find;
36 use strict;
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
42 makevar librarie);
44 # For each kind, the default macro.
45 my %generic_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'
54 my %kind_comment =
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.
66 my %used = ();
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.
71 my %macro = ();
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
75 # `alloca (...)'.
76 my %needed_macros =
78 'AC_PREREQ' => [$me],
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";
87 my @prepend_include;
88 my @include = ('/usr/share/autoconf');
90 # $help
91 # -----
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
105 Library directories:
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";
111 # $version
112 # --------
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 ## ------------------------ ##
127 # parse_args ()
128 # -------------
129 # Process any command line arguments.
130 sub parse_args ()
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"
137 if @ARGV > 1;
139 my $srcdir = $ARGV[0] || ".";
141 verbose "srcdir = $srcdir";
142 chdir $srcdir || error "cannot cd to $srcdir: $!";
146 # init_tables ()
147 # --------------
148 # Put values in the tables of what to do with each token.
149 sub init_tables ()
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.
163 next
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;
175 else
177 error "$file:$.: invalid definition: $_";
181 if ($debug)
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.
198 sub used ($$;$)
200 my ($kind, $word, $where) = @_;
201 $where ||= "$File::Find::name:$.";
202 if (
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 # -----------------------
224 sub scan_c_file ($)
226 my ($filename) = @_;
227 push @cfiles, $File::Find::name;
229 # Nonzero if in a multiline comment.
230 my $in_comment = 0;
232 my $file = new Autom4te::XFile "<$filename";
234 while ($_ = $file->getline)
236 # Strip out comments.
237 if ($in_comment && s,^.*?\*/,,)
239 $in_comment = 0;
241 # The whole line is inside a commment.
242 next if $in_comment;
243 # All on one line.
244 s,/\*.*?\*/,,g;
246 # Starting on this line.
247 if (s,/\*.*$,,)
249 $in_comment = 1;
252 # Preprocessor directives.
253 if (s/^\s*\#\s*//)
255 if (/^include\s*<([^>]*)>/)
257 used ('header', $1);
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.
268 next;
271 # Remove string and character constants.
272 s,\"[^\"]*\",,g;
273 s,\'[^\']*\',,g;
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);
287 $file->close;
291 # scan_makefile($MAKEFILE-NAME)
292 # -----------------------------
293 sub scan_makefile ($)
295 my ($filename) = @_;
296 push @makefiles, $File::Find::name;
298 my $file = new Autom4te::XFile "<$filename";
300 while ($_ = $file->getline)
302 # Strip out comments.
303 s/#.*//;
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+/))
314 # Libraries.
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);
329 $file->close;
333 # scan_sh_file($SHELL-SCRIPT-NAME)
334 # --------------------------------
335 sub scan_sh_file ($)
337 my ($filename) = @_;
338 push @shfiles, $File::Find::name;
340 my $file = new Autom4te::XFile "<$filename";
342 while ($_ = $file->getline)
344 # Strip out comments and variable references.
345 s/#.*//;
346 s/\${[^\}]*}//g;
347 s/@[^@]*@//g;
349 # Tokens in the code.
350 while (s/\b([a-zA-Z_]\w*)\b/ /)
352 used ('program', $1);
356 $file->close;
360 # scan_file ()
361 # ------------
362 # Called by &find on each file. $_ contains the current filename with
363 # the current directory of the walk through.
364 sub scan_file ()
366 # Wanted only if there is no corresponding FILE.in.
367 return
368 if -f "$_.in";
370 # Save $_ as Find::File requires it to be preserved.
371 local $_ = $_;
373 # Strip a useless leading `./'.
374 $File::Find::name =~ s,^\./,,;
376 if (/\.[chlym](\.in)?$/)
378 used 'program', 'cc', $File::Find::name;
379 scan_c_file ($_);
381 elsif (/\.(cc|cpp|cxx|CC|C|hh|hpp|hxx|HH|H|yy|ypp|ll|lpp)(\.in)?$/)
383 used 'program', 'c++', $File::Find::name;
384 scan_c_file ($_);
386 elsif ((/^((?:GNUm|M|m)akefile)(\.in)?$/ && ! -f "$1.am")
387 || /^(?:GNUm|M|m)akefile(\.am)?$/)
389 scan_makefile ($_);
391 elsif (/\.sh(\.in)?$/)
393 scan_sh_file ($_);
398 # scan_files ()
399 # -------------
400 # Read through the files and collect lists of tokens in them
401 # that might create nonportabilities.
402 sub scan_files ()
404 find (\&scan_file, '.');
406 if ($verbose)
408 print "cfiles: @cfiles\n";
409 print "makefiles: @makefiles\n";
410 print "shfiles: @shfiles\n";
412 foreach my $kind (@kinds)
414 print "\n$kind:\n";
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 # --------------------------
431 sub output_kind ($$)
433 my ($file, $kind) = @_;
434 # Lists of words to be checked with the generic macro.
435 my @have;
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+(.*)/)
447 my $message = $1;
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})
456 push (@have, $word);
457 push (@{$needed_macros{"$generic_macro{$kind}([$word])"}},
458 @{$used{$kind}{$word}});
460 else
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"
473 if @have;
477 # output_libraries ($FILE)
478 # ------------------------
479 sub output_libraries ($)
481 my ($file) = @_;
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.
495 sub output ($)
497 my $configure_scan = shift;
498 my %unique_makefiles;
500 my $file = new Autom4te::XFile ">$configure_scan";
502 print $file
503 ("# -*- Autoconf -*-\n" .
504 "# Process this file with autoconf to produce a configure script.\n" .
505 "\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');
521 if (@makefiles)
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([",
530 join ("\n ",
531 sort keys %unique_makefiles), "])\n");
533 print $file "AC_OUTPUT\n";
535 $file->close;
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
548 # in CONFIGURE_AC.
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
556 my $trace_option =
557 join (' --trace=', '',
558 uniq (sort (map { s/\(.*//; $_ } keys %needed_macros)));
560 verbose "running: $autoconf $trace_option $configure_ac";
561 my $traces =
562 new Autom4te::XFile "$autoconf $trace_option $configure_ac|";
564 while ($_ = $traces->getline)
566 chomp;
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])"};
583 else
585 delete $needed_macros{$macro};
589 $traces->close;
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])
596 . "\n");
597 print $log "$me: warning: missing $macro wanted by: \n";
598 foreach my $need (@{$needed_macros{$macro}})
600 print $log "\t$need\n";
606 ## -------------- ##
607 ## Main program. ##
608 ## -------------- ##
610 parse_args;
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;
617 init_tables;
618 scan_files;
619 output ('configure.scan');
620 if ($configure_ac)
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.
627 $log->close;
628 exit 0;
630 ### Setup "GNU" style for perl-mode and cperl-mode.
631 ## Local Variables:
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
645 ## End: