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)
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
20 # Written by David MacKenzie <djm@gnu.ai.mit.edu>.
27 use vars qw($autoconf $datadir $initfile $me $name $verbose
28 @cfiles @makefiles @shfiles
29 %functions_macros %headers_macros %identifiers_macros
30 %programs_macros %makevars_macros %needed_macros
31 %c_keywords %programs %headers %identifiers %makevars
32 %libraries %functions %printed);
34 ($me = $0) =~ s,.*/,,;
37 # Reference these variables to pacify perl -w.
38 %identifiers_macros = ();
39 %makevars_macros = ();
40 %programs_macros = ();
43 my @kinds = qw (functions headers identifiers programs makevars);
45 # For each kind, the default macro.
48 'functions' => 'AC_CHECK_FUNCS',
49 'headers' => 'AC_CHECK_HEADERS',
50 'identifiers' => 'AC_CHECK_TYPES',
51 'programs' => 'AC_CHECK_PROGS'
55 my $configure_scan = 'configure.scan';
58 # Exit nonzero whenever closing STDOUT fails.
62 # This is required if the code might send any output to stdout
63 # E.g., even --version or --help. So it's best to do it unconditionally.
65 or (warn "$me: closing standard output: $!\n"), _exit (1);
70 # Find the lib files and autoconf.
73 $datadir = $ENV{"AC_MACRODIR"} || "@datadir@";
74 (my $dir = $0) =~ s,[^/]*$,,;
76 # We test "$dir/autoconf" in case we are in the build tree, in which case
77 # the names are not transformed yet.
78 foreach my $file ($ENV{"AUTOCONF"} || '',
79 "$dir/@autoconf-name@",
81 "@bindir@/@autoconf-name@")
93 # &find_configure_ac ()
94 # ---------------------
95 sub find_configure_ac ()
97 if (-f 'configure.ac')
99 if (-f 'configure.in')
101 warn "warning: `configure.ac' and `configure.in' both present.\n";
102 warn "warning: proceeding with `configure.ac'.\n";
104 return 'configure.ac';
106 elsif (-f 'configure.in')
108 return 'configure.in';
116 # Display usage (--help).
119 print "Usage: $0 [OPTION] ... [SRCDIR]
121 Examine source files in the directory tree rooted at SRCDIR, or the
122 current directory if none is given. Search the source files for
123 common portability problems and create a file `$configure_scan' which
124 is a preliminary `configure.ac' for that package.
126 -h, --help print this help, then exit
127 -V, --version print version number, then exit
128 -v, --verbose verbosely report processing
131 -A, --autoconf-dir=ACDIR Autoconf's files location (rarely needed)
132 -l, --localdir=DIR location of `aclocal.m4' and `acconfig.h'
134 Report bugs to <bug-autoconf\@gnu.org>.\n";
141 # Display version (--version).
144 print "autoscan (@PACKAGE_NAME@) @VERSION@
145 Written by David J. MacKenzie.
147 Copyright 1994, 1999, 2000, 2001 Free Software Foundation, Inc.
148 This is free software; see the source for copying conditions. There is NO
149 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
156 # Process any command line arguments.
160 Getopt::Long::config ("bundling");
161 Getopt::Long::GetOptions ("A|autoconf-dir|m|macrodir=s" => \$datadir,
162 "h|help" => \&print_usage,
163 "V|version" => \&print_version,
164 "v|verbose" => \$verbose)
167 die "$me: too many arguments
168 Try `$me --help' for more information.\n"
174 print "srcdir=$srcdir\n" if $verbose;
175 chdir $srcdir || die "$me: cannot cd to $srcdir: $!\n";
181 # Put values in the tables of what to do with each token.
184 # Initialize a table of C keywords (to ignore).
185 # Taken from K&R 1st edition p. 180.
186 # ANSI C, GNU C, and C++ keywords can introduce portability problems,
187 # so don't ignore them.
188 foreach my $word (qw (int char float double struct union long short
189 unsigned auto extern register typedef static
190 goto return sizeof break continue if else for
191 do while switch case default))
193 $c_keywords{$word} = 0;
196 # The data file format supports only one line of macros per function.
197 # If more than that is required for a common portability problem,
198 # a new Autoconf macro should probably be written for that case,
199 # instead of duplicating the code in lots of configure.ac files.
201 foreach my $kind (@kinds)
203 my $file = "$datadir/ac$kind";
205 die "$me: cannot open $file: $!\n";
208 # Ignore blank lines and comments.
210 if /^\s*$/ || /^\s*\#/;
211 unless (/^(\S+)\s+(\S.*)$/ || /^(\S+)\s*$/)
213 die "$me: cannot parse definition in $file:\n$_\n";
216 my $macro = $2 || $generic_macro{$kind};
217 eval "\$$kind" . "_macros{\$word} = \$macro";
226 # Collect names of various kinds of files in the package.
227 # Called by &find on each file.
230 # Strip a useless leading `./'.
233 if (/^.*\.[chlymC]$/ || /^.*\.cc$/)
235 push (@cfiles, $name);
237 elsif (/^[Mm]akefile$/ || /^GNUmakefile$/)
239 # Wanted only if there is no corresponding Makefile.in.
240 # Using Find, $_ contains the current filename with the current
241 # directory of the walk through.
242 push (@makefiles, $name)
245 elsif (/^[Mm]akefile\.in$/)
247 push (@makefiles, $name);
251 push (@shfiles, $name);
258 # Read through the files and collect lists of tokens in them
259 # that might create nonportabilities.
263 if (defined $cfiles[0])
265 $initfile = $cfiles[0]; # Pick one at random.
268 foreach $file (@cfiles)
270 push (@{$programs{"cc"}}, $file);
274 foreach $file (@makefiles)
276 scan_makefile ($file);
279 foreach $file (@shfiles)
281 scan_sh_file ($file);
286 print "cfiles:", join(" ", @cfiles), "\n";
287 print "makefiles:", join(" ", @makefiles), "\n";
288 print "shfiles:", join(" ", @shfiles), "\n";
290 foreach my $class (qw (functions identifiers headers
291 makevars libraries programs))
294 my $h = eval "\\\%$class";
295 foreach my $word (sort keys %$h)
297 print "$word: @{$h->{$word}}\n";
309 my ($in_comment) = 0; # Nonzero if in a multiline comment.
311 open(CFILE, "<$file") || die "$me: cannot open $file: $!\n";
314 # Strip out comments, approximately.
315 # Ending on this line.
316 if ($in_comment && m,\*/,)
323 # Starting on this line.
328 # Continuing on this line.
331 # Preprocessor directives.
332 if (/^\s*\#\s*include\s*<([^>]*)>/)
334 push (@{$headers{$1}}, "$file:$.");
336 # Ignore other preprocessor directives.
339 # Remove string and character constants.
343 # Tokens in the code.
344 # Maybe we should ignore function definitions (in column 0)?
345 while (s/\b([a-zA-Z_]\w*)\s*\(/ /)
347 push (@{$functions{$1}}, "$file:$.")
348 if !defined $c_keywords{$1};
350 while (s/\b([a-zA-Z_]\w*)\b/ /)
352 push (@{$identifiers{$1}}, "$file:$.")
353 if !defined $c_keywords{$1};
360 # scan_makefile(MAKEFILE)
361 # -----------------------
362 sub scan_makefile ($)
366 open(MFILE, "<$file") || die "$me: cannot open $file: $!\n";
369 # Strip out comments and variable references.
375 # Variable assignments.
376 while (s/\b([a-zA-Z_]\w*)\s*=/ /)
378 push (@{$makevars{$1}}, "$file:$.");
381 while (s/\B-l([a-zA-Z_]\w*)\b/ /)
383 push (@{$libraries{$1}}, "$file:$.");
385 # Tokens in the code.
386 while (s/\b([a-zA-Z_]\w*)\b/ /)
388 push (@{$programs{$1}}, "$file:$.");
395 # scan_sh_file(SHELL-SCRIPT)
396 # --------------------------
401 open(MFILE, "<$file") || die "$me: cannot open $file: $!\n";
404 # Strip out comments and variable references.
409 # Tokens in the code.
410 while (s/\b([a-zA-Z_]\w*)\b/ /)
412 push (@{$programs{$1}}, "$file:$.");
419 # print_unique ($MACRO, @WHERE)
420 # -----------------------------
421 # $MACRO is wanted from $WHERE, hence (i) print $MACRO in $configure_scan
422 # if it exists and hasn't been printed already, (ii), remember it's needed.
423 sub print_unique ($@)
425 my ($macro, @where) = @_;
427 if (defined $macro && !defined $printed{$macro})
429 print CONF "$macro\n";
430 $printed{$macro} = 1;
432 push (@{$needed_macros{$macro}}, @where);
439 sub output_programs ()
441 print CONF "\n# Checks for programs.\n";
442 foreach my $word (sort keys %programs)
444 print_unique ($programs_macros{$word}, @{$programs{$word}});
446 foreach my $word (sort keys %makevars)
448 print_unique ($makevars_macros{$word}, @{$makevars{$word}});
453 # output_libraries ()
454 # -------------------
455 sub output_libraries ()
457 print CONF "\n# Checks for libraries.\n";
458 foreach my $word (sort keys %libraries)
460 print CONF "# FIXME: Replace `main' with a function in `-l$word':\n";
461 print CONF "AC_CHECK_LIB([$word], [main])\n";
468 sub output_headers ()
472 print CONF "\n# Checks for header files.\n";
473 foreach my $word (sort keys %headers)
475 if (defined $headers_macros{$word})
477 if ($headers_macros{$word} eq 'AC_CHECK_HEADERS')
479 push (@have_headers, $word);
480 push (@{$needed_macros{"AC_CHECK_HEADERS([$word])"}},
485 print_unique ($headers_macros{$word}, @{$headers{$word}});
489 print CONF "AC_CHECK_HEADERS([" . join(' ', sort(@have_headers)) . "])\n"
494 # output_identifiers ()
495 # ---------------------
496 sub output_identifiers ()
500 print CONF "\n# Checks for typedefs, structures, and compiler characteristics.\n";
501 foreach my $word (sort keys %identifiers)
503 if (defined $identifiers_macros{$word})
505 if ($identifiers_macros{$word} eq 'AC_CHECK_TYPES')
507 push (@have_types, $word);
508 push (@{$needed_macros{"AC_CHECK_TYPES([$word])"}},
509 @{$identifiers{$word}});
513 print_unique ($identifiers_macros{$word},
514 @{$identifiers{$word}});
518 print CONF "AC_CHECK_TYPES([" . join(', ', sort(@have_types)) . "])\n"
523 # output_functions ()
524 # -------------------
525 sub output_functions ()
529 print CONF "\n# Checks for library functions.\n";
530 foreach my $word (sort keys %functions)
532 if (defined $functions_macros{$word})
534 if ($functions_macros{$word} eq 'AC_CHECK_FUNCS')
536 push (@have_funcs, $word);
537 push (@{$needed_macros{"AC_CHECK_FUNCS([$word])"}},
538 @{$functions{$word}});
542 print_unique ($functions_macros{$word},
543 @{$functions{$word}});
547 print CONF "AC_CHECK_FUNCS([" . join(' ', sort(@have_funcs)) . "])\n"
552 # output (CONFIGURE_SCAN)
553 # -----------------------
554 # Print a proto configure.ac.
557 my $configure_scan = shift;
558 my %unique_makefiles;
560 open (CONF, ">$configure_scan") ||
561 die "$me: cannot create $configure_scan: $!\n";
563 print CONF "# Process this file with autoconf to produce a configure script.\n";
564 print CONF "AC_INIT\n";
565 if (defined $initfile)
567 print CONF "AC_CONFIG_SRCDIR([$initfile])\n";
569 if (defined $cfiles[0])
571 print CONF "AC_CONFIG_HEADER([config.h])\n";
580 # Change DIR/Makefile.in to DIR/Makefile.
581 foreach my $m (@makefiles)
584 $unique_makefiles{$m}++;
586 print CONF "\nAC_CONFIG_FILES([",
587 join ("\n ", keys(%unique_makefiles)), "])\n";
588 print CONF "AC_OUTPUT\n";
591 die "$me: closing $configure_scan: $!\n";
595 # check_configure_ac (CONFIGURE_AC)
596 # ---------------------------------
597 # Use autoconf to check if all the suggested macros are included
599 sub check_configure_ac ($)
601 my ($configure_ac) = $@;
602 my ($trace_option) = '';
604 foreach my $macro (sort keys %needed_macros)
607 $trace_option .= " -t $macro";
610 open (TRACES, "$autoconf -A $datadir $trace_option $configure_ac|") ||
611 die "$me: cannot create read traces: $!\n";
616 my ($file, $line, $macro, @args) = split (/:/, $_);
617 if ($macro =~ /^AC_CHECK_(HEADER|FUNC|TYPE|MEMBER)S$/)
619 # To be rigorous, we should distinguish between space and comma
620 # separated macros. But there is no point.
621 foreach my $word (split (/\s|,/, $args[0]))
623 # AC_CHECK_MEMBERS wants `struct' or `union'.
624 if ($macro eq "AC_CHECK_MEMBERS"
625 && $word =~ /^stat.st_/)
627 $word = "struct " . $word;
629 delete ($needed_macros{"$macro([$word])"});
634 delete ($needed_macros{$macro});
639 die "$me: cannot close traces: $!\n";
641 foreach my $macro (sort keys %needed_macros)
643 warn "$me: warning: missing $macro wanted by: \n";
644 foreach my $need (@{$needed_macros{$macro}})
656 # Find the lib files and autoconf.
658 my $configure_ac = find_configure_ac;
663 output ('configure.scan');
666 check_configure_ac ($configure_ac);