* aclocal.in (write_aclocal): Set ``binmode'' after file has been
[platform/upstream/automake.git] / aclocal.in
1 #!@PERL@
2 # -*- perl -*-
3 # @configure_input@
4
5 # aclocal - create aclocal.m4 by scanning configure.in
6 # Copyright 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
7
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2, or (at your option)
11 # any later version.
12
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
17
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21 # 02111-1307, USA.
22
23 # Written by Tom Tromey <tromey@cygnus.com>.
24
25 eval 'exec @PERL@ -S $0 ${1+"$@"}'
26     if 0;
27
28 # aclocal - scan configure.in and generate aclocal.m4.
29
30 # Some constants.
31 $VERSION = "@VERSION@";
32 $PACKAGE = "@PACKAGE@";
33 $prefix = "@prefix@";
34 # Note that this isn't pkgdatadir, but a separate directory.
35 $acdir = "@datadir@/aclocal";
36
37 # Some globals.
38
39 # Exit status.
40 $exit_status = 0;
41
42 # Text to output.
43 $output = '';
44
45 # Output file name.
46 $output_file = 'aclocal.m4';
47
48 # Which macros have been seen.
49 %macro_seen = ();
50
51 # Which files have been seen.
52 %file_seen = ();
53
54 # Map macro names to file names.
55 %map = ();
56
57 # Map file names to file contents.
58 %file_contents = ();
59
60 # How much to say.
61 $verbosity = 0;
62
63 # Map from obsolete macros to hints for new macros.
64 # If you change this, change the corresponding list in automake.in.
65 # FIXME: should just put this into a single file.
66 %obsolete_macros =
67     (
68      'AC_FEATURE_CTYPE', "use \`AC_HEADER_STDC'",
69      'AC_FEATURE_ERRNO', "add \`strerror' to \`AC_REPLACE_FUNCS(...)'",
70      'AC_FEATURE_EXIT', '',
71      'AC_SYSTEM_HEADER', '',
72
73      # Note that we do not handle this one, because it is still run
74      # from AM_CONFIG_HEADER.  So we deal with it specially in
75      # scan_configure.
76      # 'AC_CONFIG_HEADER', "use \`AM_CONFIG_HEADER'",
77
78      'fp_C_PROTOTYPES', "use \`AM_C_PROTOTYPES'",
79      'fp_PROG_CC_STDC', "use \`AM_PROG_CC_STDC'",
80      'fp_PROG_INSTALL', "use \`AC_PROG_INSTALL'",
81      'fp_WITH_DMALLOC', "use \`AM_WITH_DMALLOC'",
82      'fp_WITH_REGEX', "use \`AM_WITH_REGEX'",
83      'gm_PROG_LIBTOOL', "use \`AM_PROG_LIBTOOL'",
84      'jm_MAINTAINER_MODE', "use \`AM_MAINTAINER_MODE'",
85      'md_TYPE_PTRDIFF_T', "use \`AM_TYPE_PTRDIFF_T'",
86      'ud_PATH_LISPDIR', "use \`AM_PATH_LISPDIR'",
87      'ud_GNU_GETTEXT', "use \`AM_GNU_GETTEXT'",
88
89      # Now part of autoconf proper, under a different name.
90      'AM_FUNC_FNMATCH', "use \`AC_FUNC_FNMATCH'",
91      'fp_FUNC_FNMATCH', "use \`AC_FUNC_FNMATCH'",
92      'AM_SANITY_CHECK_CC', "automatically done by \`AC_PROG_CC'",
93      'AM_PROG_INSTALL', "use \`AC_PROG_INSTALL'",
94      'AM_EXEEXT', "use \`AC_EXEEXT'",
95      'AM_CYGWIN32', "use \`AC_CYGWIN'",
96      'AM_MINGW32', "use \`AC_MINGW32'",
97      'AM_FUNC_MKTIME', "use \`AC_FUNC_MKTIME'",
98
99 # These aren't quite obsolete.
100 #      'md_PATH_PROG',
101      );
102
103 # Regexp to match the above macros.
104 $obsolete_rx = '(' . join ('|', keys %obsolete_macros) . ')';
105
106 # Matches a macro definition.
107 $ac_defun_rx = "AC_DEFUN\\(\\[?([^],)\n]+)\\]?";
108
109 # Matches an AC_REQUIRE line.
110 $ac_require_rx = "AC_REQUIRE\\(\\[?([^])]*)\\]?\\)";
111
112 \f
113
114 local (@dirlist) = &parse_arguments (@ARGV);
115 &scan_m4_files (@dirlist);
116 &scan_configure;
117 if (! $exit_status)
118 {
119     &write_aclocal;
120 }
121 &check_acinclude;
122
123 exit $exit_status;
124
125 ################################################################
126
127 # Print usage and exit.
128 sub usage
129 {
130     local ($status) = @_;
131
132     print "Usage: aclocal [OPTIONS] ...\n\n";
133     print "Generate aclocal.m4 by scanning configure.in\n
134   --acdir=DIR           directory holding config files
135   --help                print this help, then exit
136   -I DIR                add directory to search list for .m4 files
137   --output=FILE         put output in FILE (default aclocal.m4)
138   --print-ac-dir        print name of directory holding m4 files
139   --verbose             don't be silent
140   --version             print version number, then exit
141
142 Report bugs to <bug-automake\@gnu.org>.\n";
143
144     exit $status;
145 }
146
147 # Parse command line.
148 sub parse_arguments
149 {
150     local (@arglist) = @_;
151     local (@dirlist);
152     local ($print_and_exit) = 0;
153
154     while (@arglist)
155     {
156         if ($arglist[0] =~ /^--acdir=(.+)$/)
157         {
158             $acdir = $1;
159         }
160         elsif ($arglist[0] =~/^--output=(.+)$/)
161         {
162             $output_file = $1;
163         }
164         elsif ($arglist[0] eq '-I')
165         {
166             shift (@arglist);
167             push (@dirlist, $arglist[0]);
168         }
169         elsif ($arglist[0] eq '--print-ac-dir')
170         {
171             $print_and_exit = 1;
172         }
173         elsif ($arglist[0] eq '--verbose')
174         {
175             ++$verbosity;
176         }
177         elsif ($arglist[0] eq '--version')
178         {
179             print "aclocal (GNU $PACKAGE) $VERSION\n\n";
180             print "Copyright 2000 Free Software Foundation, Inc.\n";
181             print "This is free software; see the source for copying conditions.  There is NO\n";
182             print "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n";
183             print "Written by Tom Tromey <tromey\@cygnus.com>\n";
184             exit 0;
185         }
186         elsif ($arglist[0] eq '--help')
187         {
188             &usage (0);
189         }
190         else
191         {
192             die "aclocal: unrecognized option -- \`$arglist[0]'\nTry \`aclocal --help' for more information.\n";
193         }
194
195         shift (@arglist);
196     }
197
198     if ($print_and_exit)
199     {
200         print $acdir, "\n";
201         exit 0;
202     }
203
204     # Search our install directory last.
205     push (@dirlist, $acdir);
206
207     return @dirlist;
208 }
209
210 ################################################################
211
212 sub scan_configure
213 {
214     open (CONFIGURE, "configure.in")
215         || die "aclocal: couldn't open \`configure.in': $!\n";
216
217     # Make sure we include acinclude.m4 if it exists.
218     if (-f 'acinclude.m4')
219     {
220         &add_file ('acinclude.m4');
221     }
222
223     while (<CONFIGURE>)
224     {
225         # Remove comments from current line.
226         s/\bdnl\b.*$//;
227         s/\#.*$//;
228
229         if (/$obsolete_rx/o)
230         {
231             local ($hint) = '';
232             if ($obsolete_macros{$1} ne '')
233             {
234                 $hint = '; ' . $obsolete_macros{$1};
235             }
236             warn "aclocal: configure.in: $.: \`$1' is obsolete$hint\n";
237             $exit_status = 1;
238             next;
239         }
240
241         # Search for things we know about.  The "search" sub is
242         # constructed dynamically by scan_m4_files.
243         if (! &search && /(^|\s+)(AM_[A-Z_]+)/)
244         {
245             # Macro not found, but AM_ prefix found.
246             warn "aclocal: configure.in: $.: macro \`$2' not found in library\n";
247             $exit_status = 1;
248         }
249     }
250
251     close (CONFIGURE);
252 }
253
254 ################################################################
255
256 # Check macros in acinclude.m4.  If one is not used, warn.
257 sub check_acinclude
258 {
259     local ($key);
260
261     foreach $key (keys %map)
262     {
263         next unless $map{$key} eq 'acinclude.m4';
264         if (! $macro_seen{$key})
265         {
266             # FIXME: should print line number of acinclude.m4.
267             warn "aclocal: macro \`$key' defined in acinclude.m4 but never used\n";
268         }
269     }
270 }
271
272 ################################################################
273
274 # Scan all the installed m4 files and construct a map.
275 sub scan_m4_files
276 {
277     local (@dirlist) = @_;
278
279     # First, scan acinclude.m4 if it exists.
280     if (-f 'acinclude.m4')
281     {
282         $file_contents{'acinclude.m4'} = &scan_file ('acinclude.m4');
283     }
284
285     local ($m4dir);
286     foreach $m4dir (@dirlist)
287     {
288         opendir (DIR, $m4dir)
289             || die "aclocal: couldn't open directory \`$m4dir': $!\n";
290         local ($file, $fullfile, $expr);
291         foreach $file (sort grep (! /^\./, readdir (DIR)))
292         {
293             # Only examine .m4 files.
294             next unless $file =~ /\.m4$/;
295
296             # Skip some files when running out of srcdir.
297             next if $file eq 'aclocal.m4';
298
299             $fullfile = $m4dir . '/' . $file;
300             $file_contents{$fullfile} = &scan_file ($fullfile);
301         }
302         closedir (DIR);
303     }
304
305     # Construct a new function that does the searching.  We use a
306     # function (instead of just evalling $search in the loop) so that
307     # "die" is correctly and easily propagated if run.
308     local ($search, $expr, $key) = '';
309     foreach $key (reverse sort keys %map)
310     {
311         # EXPR is a regexp matching the name of the macro.
312         ($expr = $key) =~ s/(\W)/\\$1/g;
313         $search .= ("if (/" . $expr . "/) { & add_macro (" . $key
314                     . "); return 1; }\n");
315     }
316     $search .= "return 0;\n";
317     eval 'sub search { ' . $search . '};';
318     die "internal error: $@\n search is $search " if $@;
319 }
320
321 ################################################################
322
323 # Add a macro to the output.
324 sub add_macro
325 {
326     local ($macro) = @_;
327
328     # We want to ignore AC_ macros.  However, if an AC_ macro is
329     # defined in (eg) acinclude.m4, then we want to make sure we mark
330     # it as seen.
331     return if $macro =~ /^AC_/ && ! defined $map{$macro};
332
333     if (! defined $map{$macro})
334     {
335         warn "aclocal: macro \`$macro' required but not defined\n";
336         $exit_status = 1;
337         return;
338     }
339
340     print STDERR "saw macro $macro\n" if $verbosity;
341     $macro_seen{$macro} = 1;
342     &add_file ($map{$macro});
343 }
344
345 # Add a file to output.
346 sub add_file
347 {
348     local ($file) = @_;
349
350     # Only add a file once.
351     return if ($file_seen{$file});
352     $file_seen{$file} = 1;
353
354     $output .= $file_contents{$file} . "\n";
355     local ($a, @rlist);
356     foreach (split ("\n", $file_contents{$file}))
357     {
358         # This is a hack for Perl 4.
359         $a = $_;
360         if ($a =~ /$ac_require_rx/g)
361         {
362             push (@rlist, $1);
363         }
364
365         # Remove comments from current line.
366         s/\bdnl\b.*$//;
367         s/\#.*$//;
368
369         # The search function is constructed dynamically by scan_m4_files.
370         if (! &search && /(^|\s+)(AM_[A-Z_]+)/)
371         {
372             # Macro not found, but AM_ prefix found.
373             warn "aclocal: configure.in: $.: macro \`$2' not found in library\n";
374             $exit_status = 1;
375         }
376     }
377
378     local ($macro);
379     foreach $macro (@rlist)
380     {
381         &add_macro ($macro);
382     }
383 }
384
385 # Scan a single M4 file.  Return contents.
386 sub scan_file
387 {
388     local ($file) = @_;
389
390     open (FILE, $file)
391         || die "aclocal: couldn't open \`$file': $!\n";
392     local ($contents) = '';
393     while (<FILE>)
394     {
395         # Ignore `##' lines.
396         next if /^##/;
397
398         $contents .= $_;
399
400         if (/$ac_defun_rx/)
401         {
402             if (! defined $map{$1})
403             {
404                 $map{$1} = $file;
405             }
406             elsif ($map{$1} eq $file)
407             {
408                 # You basically never want a macro in the same .m4
409                 # file twice.
410                 warn "aclocal: $file: $.: duplicated macro \`$1'\n";
411                 $exit_status = 1;
412             }
413             print STDERR "Found macro $1 in $file: $.\n" if $verbosity;
414         }
415     }
416     close (FILE);
417
418     return $contents;
419 }
420
421 ################################################################
422
423 # Write output.
424 sub write_aclocal
425 {
426     return if ! length ($output);
427
428     print STDERR "Writing $output_file\n" if $verbosity;
429
430     open (ACLOCAL, "> " . $output_file)
431         || die "aclocal: couldn't open \`$output_file' for writing: $!\n";
432
433     # In case we're running under MSWindows, don't write with CRLF.
434     # (This circumvents a bug in at least Cygwin bash where the shell
435     # parsing fails on lines ending with the continuation character '\'
436     # and CRLF.)
437     binmode ACLOCAL;
438
439     print ACLOCAL "# $output_file generated automatically by aclocal $VERSION\n";
440     print ACLOCAL "\
441 # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000
442 # Free Software Foundation, Inc.
443 # This file is free software; the Free Software Foundation
444 # gives unlimited permission to copy and/or distribute it,
445 # with or without modifications, as long as this notice is preserved.
446
447 # This program is distributed in the hope that it will be useful,
448 # but WITHOUT ANY WARRANTY, to the extent permitted by law; without
449 # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
450 # PARTICULAR PURPOSE.
451
452 ";
453     print ACLOCAL $output;
454     close (ACLOCAL);
455 }