(AC_SYS_LARGEFILE_TEST_INCLUDES): Don't reject
[autoconf.git] / autoscan.in
blob137e882916297eedfeef09a15a13ae3e854a2459
1 #! @PERL@ -w
2 # autoscan - Create configure.scan (a preliminary configure.ac) for a package.
3 # Copyright 1994, 1999, 2000, 2001 Free Software Foundation, Inc.
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2, or (at your option)
8 # any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18 # 02111-1307, USA.
20 # Written by David MacKenzie <djm@gnu.ai.mit.edu>.
22 require "find.pl";
23 use Getopt::Long;
24 use strict;
26 use vars qw($autoconf $datadir $initfile $me $name $verbose
27             @cfiles @makefiles @shfiles
28             %functions_macros %headers_macros %identifiers_macros
29             %programs_macros %makevars_macros %needed_macros
30             %c_keywords %programs %headers %identifiers %makevars
31             %libraries %functions %printed);
33 ($me = $0) =~ s,.*/,,;
34 $verbose = 0;
36 # Reference these variables to pacify perl -w.
37 %identifiers_macros = ();
38 %makevars_macros = ();
39 %programs_macros = ();
40 %needed_macros = ();
42 my @kinds = qw (functions headers identifiers programs makevars);
44 # For each kind, the default macro.
45 my %generic_macro =
46   (
47    'functions'   => 'AC_CHECK_FUNCS',
48    'headers'     => 'AC_CHECK_HEADERS',
49    'identifiers' => 'AC_CHECK_TYPES',
50    'programs'    => 'AC_CHECK_PROGS'
51   );
54 my $configure_scan = 'configure.scan';
56 # find_autoconf
57 # -------------
58 # Find the lib files and autoconf.
59 sub find_autoconf
61   my $dir;
62   my $file;
63   $datadir = $ENV{"AC_MACRODIR"} || "@datadir@";
64   ($dir = $0) =~ s,[^/]*$,,;
65   $autoconf = '';
66   # We test "$dir/autoconf" in case we are in the build tree, in which case
67   # the names are not transformed yet.
68   foreach $file ($ENV{"AUTOCONF"} || '',
69                  "$dir/@autoconf-name@",
70                  "$dir/autoconf",
71                  "@bindir@/@autoconf-name@")
72     {
73       if (-f $file)
74         {
75           $autoconf = $file;
76           last;
77         }
78     }
82 # print_usage ()
83 # --------------
84 # Display usage (--help).
85 sub print_usage ()
87   print "Usage: $0 [OPTION] ... [SRCDIR]
89 Examine source files in the directory tree rooted at SRCDIR, or the
90 current directory if none is given.  Search the source files for
91 common portability problems and create a file `$configure_scan' which
92 is a preliminary `configure.ac' for that package.
94   -h, --help            print this help, then exit
95   -V, --version         print version number, then exit
96   -v, --verbose         verbosely report processing
98 Library directories:
99   -A, --autoconf-dir=ACDIR  Autoconf's files location (rarely needed)
100   -l, --localdir=DIR        location of `aclocal.m4' and `acconfig.h'
102 Report bugs to <bug-autoconf\@gnu.org>.\n";
103   exit 0;
107 # print_version ()
108 # ----------------
109 # Display version (--version).
110 sub print_version
112   print "autoscan (@PACKAGE_NAME@) @VERSION@
113 Written by David J. MacKenzie.
115 Copyright 1994, 1999, 2000, 2001 Free Software Foundation, Inc.
116 This is free software; see the source for copying conditions.  There is NO
117 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
118   exit 0;
122 # parse_args ()
123 # -------------
124 # Process any command line arguments.
125 sub parse_args ()
127   my $srcdir;
128   Getopt::Long::config ("bundling");
129   Getopt::Long::GetOptions ("A|autoconf-dir|m|macrodir=s" => \$datadir,
130                             "h|help" => \&print_usage,
131                             "V|version" => \&print_version,
132                             "v|verbose" => \$verbose)
133     or exit 1;
135   die "$me: too many arguments
136 Try `$me --help' for more information.\n"
137     if (@ARGV > 1);
138   ($srcdir) = @ARGV;
139   $srcdir = "."
140     if !defined $srcdir;
142   print "srcdir=$srcdir\n" if $verbose;
143   chdir $srcdir || die "$me: cannot cd to $srcdir: $!\n";
147 # init_tables ()
148 # --------------
149 # Put values in the tables of what to do with each token.
150 sub init_tables ()
152   my ($kind, $word, $macro);
154   # Initialize a table of C keywords (to ignore).
155   # Taken from K&R 1st edition p. 180.
156   # ANSI C, GNU C, and C++ keywords can introduce portability problems,
157   # so don't ignore them.
158   foreach $word ('int', 'char', 'float', 'double', 'struct', 'union',
159                  'long', 'short', 'unsigned', 'auto', 'extern', 'register',
160                  'typedef', 'static', 'goto', 'return', 'sizeof', 'break',
161                  'continue', 'if', 'else', 'for', 'do', 'while', 'switch',
162                  'case', 'default')
163     {
164       $c_keywords{$word} = 0;
165     }
167   # The data file format supports only one line of macros per function.
168   # If more than that is required for a common portability problem,
169   # a new Autoconf macro should probably be written for that case,
170   # instead of duplicating the code in lots of configure.ac files.
172   foreach $kind (@kinds)
173     {
174       open(TABLE, "<$datadir/ac$kind") ||
175         die "$me: cannot open $datadir/ac$kind: $!\n";
176       while (<TABLE>)
177         {
178           # Ignore blank lines and comments.
179           next
180             if /^\s*$/ || /^\s*\#/;
181           unless (/^(\S+)\s+(\S.*)$/ || /^(\S+)\s*$/)
182             {
183               die "$me: cannot parse definition in $datadir/ac$kind:\n$_\n";
184             }
185           $word = $1;
186           $macro = $2 || $generic_macro{$kind};
187           eval "\$$kind" . "_macros{\$word} = \$macro";
188         }
189       close(TABLE);
190     }
194 # wanted ()
195 # ---------
196 # Collect names of various kinds of files in the package.
197 # Called by &find on each file.
198 sub wanted ()
200   # Strip a useless leading `./'.
201   $name =~ s,^\./,,;
203   if (/^.*\.[chlymC]$/ || /^.*\.cc$/)
204     {
205       push (@cfiles, $name);
206     }
207   elsif (/^[Mm]akefile$/ || /^GNUmakefile$/)
208     {
209       # Wanted only if there is no corresponding Makefile.in.
210       # Using Find, $_ contains the current filename with the current
211       # directory of the walk through.
212       push (@makefiles, $name)
213         if ! -f "$_.in";
214     }
215   elsif (/^[Mm]akefile\.in$/)
216     {
217       push (@makefiles, $name);
218     }
219   elsif (/^.*\.sh$/)
220     {
221       push (@shfiles, $name);
222     }
226 # scan_files ()
227 # -------------
228 # Read through the files and collect lists of tokens in them
229 # that might create nonportabilities.
230 sub scan_files ()
232   my $file;
233   if (defined $cfiles[0])
234     {
235       $initfile = $cfiles[0];           # Pick one at random.
236     }
238   foreach $file (@cfiles)
239     {
240       push (@{$programs{"cc"}}, $file);
241       scan_c_file ($file);
242     }
244   foreach $file (@makefiles)
245     {
246       scan_makefile ($file);
247     }
249   foreach $file (@shfiles)
250     {
251       scan_sh_file ($file);
252     }
254   if ($verbose)
255     {
256       print "cfiles:", join(" ", @cfiles), "\n";
257       print "makefiles:", join(" ", @makefiles), "\n";
258       print "shfiles:", join(" ", @shfiles), "\n";
260       foreach my $class (qw (functions identifiers headers
261                        makevars libraries programs))
262         {
263           print "\n$class:\n";
264           my $h = eval "\\\%$class";
265           foreach my $word (sort keys %$h)
266             {
267               print "$word: @{$h->{$word}}\n";
268             }
269         }
270     }
274 # scan_c_file(FILE)
275 # -----------------
276 sub scan_c_file ($)
278   my ($file) = @_;
279   my ($in_comment) = 0; # Nonzero if in a multiline comment.
281   open(CFILE, "<$file") || die "$me: cannot open $file: $!\n";
282   while (<CFILE>)
283     {
284       # Strip out comments, approximately.
285       # Ending on this line.
286       if ($in_comment && m,\*/,)
287         {
288           s,.*\*/,,;
289           $in_comment = 0;
290         }
291       # All on one line.
292       s,/\*.*\*/,,g;
293       # Starting on this line.
294       if (m,/\*,)
295         {
296           $in_comment = 1;
297         }
298       # Continuing on this line.
299       next if $in_comment;
301       # Preprocessor directives.
302       if (/^\s*\#\s*include\s*<([^>]*)>/)
303         {
304           push (@{$headers{$1}}, "$file:$.");
305         }
306       # Ignore other preprocessor directives.
307       next if /^\s*\#/;
309       # Remove string and character constants.
310       s,\"[^\"]*\",,g;
311       s,\'[^\']*\',,g;
313       # Tokens in the code.
314       # Maybe we should ignore function definitions (in column 0)?
315       while (s/\b([a-zA-Z_]\w*)\s*\(/ /)
316         {
317           push (@{$functions{$1}}, "$file:$.")
318             if !defined $c_keywords{$1};
319         }
320       while (s/\b([a-zA-Z_]\w*)\b/ /)
321         {
322           push (@{$identifiers{$1}}, "$file:$.")
323             if !defined $c_keywords{$1};
324         }
325     }
326   close(CFILE);
330 # scan_makefile(MAKEFILE)
331 # -----------------------
332 sub scan_makefile ($)
334   my ($file) = @_;
336   open(MFILE, "<$file") || die "$me: cannot open $file: $!\n";
337   while (<MFILE>)
338     {
339       # Strip out comments and variable references.
340       s/#.*//;
341       s/\$\([^\)]*\)//g;
342       s/\${[^\}]*}//g;
343       s/@[^@]*@//g;
345       # Variable assignments.
346       while (s/\b([a-zA-Z_]\w*)\s*=/ /)
347         {
348           push (@{$makevars{$1}}, "$file:$.");
349         }
350       # Libraries.
351       while (s/\B-l([a-zA-Z_]\w*)\b/ /)
352         {
353           push (@{$libraries{$1}}, "$file:$.");
354         }
355       # Tokens in the code.
356       while (s/\b([a-zA-Z_]\w*)\b/ /)
357         {
358           push (@{$programs{$1}}, "$file:$.");
359         }
360     }
361   close(MFILE);
365 # scan_sh_file(SHELL-SCRIPT)
366 # --------------------------
367 sub scan_sh_file ($)
369   my ($file) = @_;
371   open(MFILE, "<$file") || die "$me: cannot open $file: $!\n";
372   while (<MFILE>)
373     {
374       # Strip out comments and variable references.
375       s/#.*//;
376       s/\${[^\}]*}//g;
377       s/@[^@]*@//g;
379       # Tokens in the code.
380       while (s/\b([a-zA-Z_]\w*)\b/ /)
381         {
382           push (@{$programs{$1}}, "$file:$.");
383         }
384     }
385   close(MFILE);
389 # print_unique ($MACRO, @WHERE)
390 # -----------------------------
391 # $MACRO is wanted from $WHERE, hence (i) print $MACRO in $configure_scan
392 # if it exists and hasn't been printed already, (ii), remember it's needed.
393 sub print_unique ($@)
395   my ($macro, @where) = @_;
397   if (defined $macro && !defined $printed{$macro})
398     {
399       print CONF "$macro\n";
400       $printed{$macro} = 1;
402       push (@{$needed_macros{$macro}}, @where);
403     }
407 # output_programs ()
408 # ------------------
409 sub output_programs ()
411   my $word;
413   print CONF "\n# Checks for programs.\n";
414   foreach $word (sort keys %programs)
415     {
416       print_unique ($programs_macros{$word}, @{$programs{$word}});
417     }
418   foreach $word (sort keys %makevars)
419     {
420       print_unique ($makevars_macros{$word}, @{$makevars{$word}});
421     }
425 # output_libraries ()
426 # -------------------
427 sub output_libraries ()
429   my ($word);
431   print CONF "\n# Checks for libraries.\n";
432   foreach $word (sort keys %libraries)
433     {
434       print CONF "# FIXME: Replace `main' with a function in `-l$word':\n";
435       print CONF "AC_CHECK_LIB([$word], [main])\n";
436     }
440 # output_headers ()
441 # -----------------
442 sub output_headers ()
444   my $word;
445   my @have_headers;
447   print CONF "\n# Checks for header files.\n";
448   foreach $word (sort keys %headers)
449     {
450       if (defined $headers_macros{$word})
451         {
452           if ($headers_macros{$word} eq 'AC_CHECK_HEADERS')
453             {
454               push (@have_headers, $word);
455               push (@{$needed_macros{"AC_CHECK_HEADERS([$word])"}},
456                     @{$headers{$word}});
457             }
458           else
459             {
460               print_unique ($headers_macros{$word}, @{$headers{$word}});
461             }
462         }
463     }
464   print CONF "AC_CHECK_HEADERS([" . join(' ', sort(@have_headers)) . "])\n"
465     if @have_headers;
469 # output_identifiers ()
470 # ---------------------
471 sub output_identifiers ()
473   my $word;
474   my @have_types;
476   print CONF "\n# Checks for typedefs, structures, and compiler characteristics.\n";
477   foreach $word (sort keys %identifiers)
478     {
479       if (defined $identifiers_macros{$word})
480         {
481           if ($identifiers_macros{$word} eq 'AC_CHECK_TYPES')
482             {
483               push (@have_types, $word);
484               push (@{$needed_macros{"AC_CHECK_TYPES([$word])"}},
485                     @{$identifiers{$word}});
486             }
487           else
488             {
489               print_unique ($identifiers_macros{$word},
490                             @{$identifiers{$word}});
491             }
492         }
493     }
494   print CONF "AC_CHECK_TYPES([" . join(', ', sort(@have_types)) . "])\n"
495     if @have_types;
499 # output_functions ()
500 # -------------------
501 sub output_functions ()
503   my $word;
504   my @have_funcs;
506   print CONF "\n# Checks for library functions.\n";
507   foreach $word (sort keys %functions)
508     {
509       if (defined $functions_macros{$word})
510         {
511           if ($functions_macros{$word} eq 'AC_CHECK_FUNCS')
512             {
513               push (@have_funcs, $word);
514               push (@{$needed_macros{"AC_CHECK_FUNCS([$word])"}},
515                     @{$functions{$word}});
516             }
517           else
518             {
519               print_unique ($functions_macros{$word},
520                             @{$functions{$word}});
521             }
522         }
523     }
524   print CONF "AC_CHECK_FUNCS([" . join(' ', sort(@have_funcs)) . "])\n"
525     if @have_funcs;
529 # output (CONFIGURE_SCAN)
530 # -----------------------
531 # Print a proto configure.ac.
532 sub output ($)
534   my $configure_scan = shift;
535   my %unique_makefiles;
537   open (CONF, ">$configure_scan") ||
538     die "$me: cannot create $configure_scan: $!\n";
540   print CONF "# Process this file with autoconf to produce a configure script.\n";
541   print CONF "AC_INIT\n";
542   if (defined $initfile)
543     {
544       print CONF "AC_CONFIG_SRCDIR([$initfile])\n";
545     }
546   if (defined $cfiles[0])
547     {
548       print CONF "AC_CONFIG_HEADER([config.h])\n";
549     }
551   output_programs;
552   output_libraries;
553   output_headers;
554   output_identifiers;
555   output_functions;
557   # Change DIR/Makefile.in to DIR/Makefile.
558   foreach $_ (@makefiles)
559     {
560       s/\.in$//;
561       $unique_makefiles{$_}++;
562     }
563   print CONF "\nAC_CONFIG_FILES([",
564        join ("\n                 ", keys(%unique_makefiles)), "])\n";
565   print CONF "AC_OUTPUT\n";
567   close CONF ||
568     die "$me: closing $configure_scan: $!\n";
572 # check_configure_ac (CONFIGURE_AC)
573 # ---------------------------------
574 # Use autoconf to check if all the suggested macros are included
575 # in CONFIGURE_AC.
576 sub check_configure_ac ($)
578   my ($configure_ac) = $@;
579   my ($trace_option) = '';
580   my ($word);
581   my ($macro);
583   foreach $macro (sort keys %needed_macros)
584     {
585       $macro =~ s/\(.*//;
586       $trace_option .= " -t $macro";
587     }
589   open (TRACES, "$autoconf -A $datadir $trace_option $configure_ac|") ||
590     die "$me: cannot create read traces: $!\n";
592   while (<TRACES>)
593     {
594       chomp;
595       my ($file, $line, $macro, @args) = split (/:/, $_);
596       if ($macro =~ /^AC_CHECK_(HEADER|FUNC|TYPE|MEMBER)S$/)
597         {
598           # To be rigorous, we should distinguish between space and comma
599           # separated macros.  But there is no point.
600           foreach $word (split (/\s|,/, $args[0]))
601             {
602               # AC_CHECK_MEMBERS wants `struct' or `union'.
603               if ($macro eq "AC_CHECK_MEMBERS"
604                   && $word =~ /^stat.st_/)
605                 {
606                   $word = "struct " . $word;
607                 }
608               delete ($needed_macros{"$macro([$word])"});
609             }
610         }
611       else
612         {
613           delete ($needed_macros{$macro});
614         }
615     }
617   close (TRACES) ||
618     die "$me: cannot close traces: $!\n";
620   foreach $macro (sort keys %needed_macros)
621     {
622       warn "warning: missing $macro wanted by: @{$needed_macros{$macro}}\n";
623     }
627 ## -------------- ##
628 ## Main program.  ##
629 ## -------------- ##
631 # Find the lib files and autoconf.
632 find_autoconf;
634 parse_args;
635 init_tables;
636 find ('.');
637 scan_files;
638 output ('configure.scan');
640 if (-f 'configure.ac')
641   {
642     if (-f 'configure.in')
643       {
644         warn "warning: `configure.ac' and `configure.in' both present.\n";
645         warn "warning: proceeding with `configure.ac'.\n";
646       }
647     check_configure_ac ('configure.ac');
648   }
649 elsif (-f 'configure.in')
650   {
651     check_configure_ac ('configure.in');
652   }
654 exit 0;