resetting manifest requested domain to floor
[platform/upstream/autoconf213.git] / autoscan.pl
1 #! @PERL@
2 # autoscan - Create configure.scan (a preliminary configure.in) for a package.
3 # Copyright (C) 1994 Free Software Foundation, Inc.
4
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.
9
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.
14
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.
19
20 # Written by David MacKenzie <djm@gnu.ai.mit.edu>.
21
22 require "find.pl";
23
24 $datadir = $ENV{"AC_MACRODIR"} || "@datadir@";
25 $verbose = 0;
26 # Reference these variables to pacify perl -w.
27 undef %identifiers_macros;
28 undef %makevars_macros;
29 undef %programs_macros;
30
31 &parse_args;
32 &init_tables;
33 &find('.');
34 &scan_files;
35 &output;
36
37 exit 0;
38
39 # Process any command line arguments.
40 sub parse_args
41 {
42     local ($usage) =
43         "Usage: autoscan [--macrodir=dir] [--help] [--verbose] [--version] [srcdir]\n"; 
44
45     foreach $_ (@ARGV) {
46         if (/^--m[a-z]*=(.*)/) {
47             $datadir = $1;
48         } elsif (/^--h/) {
49             print "$usage";
50             exit 0;
51         } elsif (/^--verb/) {
52             $verbose = 1;
53         } elsif (/^--vers/) {
54             &version;
55         } elsif (/^[^-]/) {
56             die "$usage" if defined($srcdir);
57             # Top level directory of the package being autoscanned.
58             $srcdir = $_;
59         } else {
60             die "$usage";
61         }
62     }
63
64     $srcdir="." if !defined($srcdir);
65
66     print "srcdir=$srcdir\n" if $verbose;
67     chdir $srcdir || die "$0: cannot cd to $srcdir: $!\n";
68
69     open(CONF, ">configure.scan") ||
70         die "$0: cannot create configure.scan: $!\n";
71 }
72
73 # Print the version number and exit.
74 sub version
75 {
76     open(ACG, "<$datadir/acgeneral.m4") ||
77         die "$0: cannot open $datadir/acgeneral.m4: $!\n";
78     while (<ACG>) {
79         if (/define.AC_ACVERSION.\s*([0-9.]+)/) {
80             print "Autoconf version $1\n";
81             exit 0;
82         }
83     }
84     die "Autoconf version unknown\n";
85 }
86
87 # Put values in the tables of what to do with each token.
88 sub init_tables
89 {
90     local($kind, $word, $macro);
91
92     # Initialize a table of C keywords (to ignore).
93     # Taken from K&R 1st edition p. 180.
94     # ANSI C, GNU C, and C++ keywords can introduce portability problems,
95     # so don't ignore them.
96     foreach $word ('int', 'char', 'float', 'double', 'struct', 'union',
97                    'long', 'short', 'unsigned', 'auto', 'extern', 'register',
98                    'typedef', 'static', 'goto', 'return', 'sizeof', 'break',
99                    'continue', 'if', 'else', 'for', 'do', 'while', 'switch',
100                    'case', 'default') {
101         $c_keywords{$word} = 0;
102     }
103
104     # The data file format supports only one line of macros per function.
105     # If more than that is required for a common portability problem,
106     # a new Autoconf macro should probably be written for that case,
107     # instead of duplicating the code in lots of configure.in files.
108
109     foreach $kind ('functions', 'headers', 'identifiers', 'programs',
110                    'makevars') {
111         open(TABLE, "<$datadir/ac$kind") ||
112             die "$0: cannot open $datadir/ac$kind: $!\n";
113         while (<TABLE>) {
114             next if /^\s*$/ || /^\s*#/; # Ignore blank lines and comments.
115             ($word, $macro) = split;
116             eval "\$$kind" . "_macros{\$word} = \$macro";
117         }
118         close(TABLE);
119     }
120 }
121
122 # Collect names of various kinds of files in the package.
123 # Called by &find on each file.
124 sub wanted
125 {
126   # Wanted only if there is no corresponding FILE.in.
127   return
128     if -f "$_.in";
129
130   # Strip a useless leading `./'.
131   $name =~ s,^\./,,;
132
133   if (/^.*\.[chlymC](\.in)?$/)
134     {
135       push (@cfiles, $name);
136       $programs{cc}++;
137     }
138   elsif (/^.*\.(cc|cpp|cxx|CC|C|hh|hpp|hxx|HH|H|yy|ypp|ll|lpp)(\.in)?$/)
139     {
140       push (@cfiles, $name);
141       $programs{CC}++;
142     }
143   elsif (/^[Mm]akefile(\.in)?$/ || /^GNUmakefile$/)
144     {
145       # Wanted only if there is no corresponding Makefile.in.
146       # Using Find, $_ contains the current filename with the current
147       # directory of the walk through.
148       push (@makefiles, $name);
149     }
150   elsif (/^.*\.sh(\.in)?$/)
151     {
152       push (@shfiles, $name);
153     }
154 }
155
156 # Read through the files and collect lists of tokens in them
157 # that might create nonportabilities.
158 sub scan_files
159 {
160     $initfile = $cfiles[0];             # Pick one at random.
161
162     if ($verbose) {
163         print "cfiles:", join(" ", @cfiles), "\n";
164         print "makefiles:", join(" ", @makefiles), "\n";
165         print "shfiles:", join(" ", @shfiles), "\n";
166     }
167
168     foreach $file (@cfiles) {
169         &scan_c_file($file);
170     }
171
172     foreach $file (@makefiles) {
173         &scan_makefile($file);
174     }
175
176     foreach $file (@shfiles) {
177         &scan_sh_file($file);
178     }
179 }
180
181 sub scan_c_file
182 {
183     local($file) = @_;
184     local($in_comment) = 0;     # Nonzero if in a multiline comment.
185
186     open(CFILE, "<$file") || die "$0: cannot open $file: $!\n";
187     while (<CFILE>) {
188         # Strip out comments, approximately.
189         # Ending on this line.
190         if ($in_comment && m,\*/,) {
191             s,.*\*/,,;
192             $in_comment = 0;
193         }
194         # All on one line.
195         s,/\*.*\*/,,g;
196         # Starting on this line.
197         if (m,/\*,) {
198             $in_comment = 1;
199         }
200         # Continuing on this line.
201         next if $in_comment;
202
203         # Preprocessor directives.
204         if (/^\s*#\s*include\s*<([^>]*)>/) {
205             $headers{$1}++;
206         }
207         # Ignore other preprocessor directives.
208         next if /^\s*#/;
209
210         # Remove string and character constants.
211         s,\"[^\"]*\",,g;
212         s,\'[^\']*\',,g;
213
214         # Tokens in the code.
215         # Maybe we should ignore function definitions (in column 0)?
216         while (s/\W([a-zA-Z_]\w*)\s*\(/ /) {
217             $functions{$1}++ if !defined($c_keywords{$1});
218         }
219         while (s/\W([a-zA-Z_]\w*)\W/ /) {
220             $identifiers{$1}++ if !defined($c_keywords{$1});
221         }
222     }
223     close(CFILE);
224
225     if ($verbose) {
226         local($word);
227
228         print "\n$file functions:\n";
229         foreach $word (sort keys %functions) {
230             print "$word $functions{$word}\n";
231         }
232
233         print "\n$file identifiers:\n";
234         foreach $word (sort keys %identifiers) {
235             print "$word $identifiers{$word}\n";
236         }
237
238         print "\n$file headers:\n";
239         foreach $word (sort keys %headers) {
240             print "$word $headers{$word}\n";
241         }
242     }
243 }
244
245 sub scan_makefile
246 {
247     local($file) = @_;
248
249     open(MFILE, "<$file") || die "$0: cannot open $file: $!\n";
250     while (<MFILE>) {
251         # Strip out comments and variable references.
252         s/#.*//;
253         s/\$\([^\)]*\)//g;
254         s/\${[^\}]*}//g;
255         s/@[^@]*@//g;
256
257         # Variable assignments.
258         while (s/\W([a-zA-Z_]\w*)\s*=/ /) {
259             $makevars{$1}++;
260         }
261         # Libraries.
262         while (s/\W-l([a-zA-Z_]\w*)\W/ /) {
263             $libraries{$1}++;
264         }
265         # Tokens in the code.
266         while (s/\W([a-zA-Z_][\w\+\.-]*)\W/ /) {
267             $programs{$1}++;
268         }
269     }
270     close(MFILE);
271
272     if ($verbose) {
273         local($word);
274
275         print "\n$file makevars:\n";
276         foreach $word (sort keys %makevars) {
277             print "$word $makevars{$word}\n";
278         }
279
280         print "\n$file libraries:\n";
281         foreach $word (sort keys %libraries) {
282             print "$word $libraries{$word}\n";
283         }
284
285         print "\n$file programs:\n";
286         foreach $word (sort keys %programs) {
287             print "$word $programs{$word}\n";
288         }
289     }
290 }
291
292 sub scan_sh_file
293 {
294     local($file) = @_;
295
296     open(MFILE, "<$file") || die "$0: cannot open $file: $!\n";
297     while (<MFILE>) {
298         # Strip out comments and variable references.
299         s/#.*//;
300         s/\${[^\}]*}//g;
301         s/@[^@]*@//g;
302
303         # Tokens in the code.
304         while (s/\W([a-zA-Z_]\w*)\W/ /) {
305             $programs{$1}++;
306         }
307     }
308     close(MFILE);
309
310     if ($verbose) {
311         local($word);
312
313         print "\n$file programs:\n";
314         foreach $word (sort keys %programs) {
315             print "$word $programs{$word}\n";
316         }
317     }
318 }
319
320 # Print a configure.in.
321 sub output
322 {
323     local (%unique_makefiles);
324
325     print CONF "dnl Process this file with autoconf to produce a configure script.\n";
326     print CONF "AC_INIT($initfile)\n";
327
328     &output_programs;
329     &output_headers;
330     &output_identifiers;
331     &output_functions;
332
333     # Change DIR/Makefile.in to DIR/Makefile.
334     foreach $_ (@makefiles) {
335         s/\.in$//;
336         $unique_makefiles{$_}++;
337     }
338     print CONF "\nAC_OUTPUT(", join(" ", keys(%unique_makefiles)), ")\n";
339
340     close CONF;
341 }
342
343 # Print Autoconf macro $1 if it's not undef and hasn't been printed already.
344 sub print_unique
345 {
346     local($macro) = @_;
347
348     if (defined($macro) && !defined($printed{$macro})) {
349         print CONF "$macro\n";
350         $printed{$macro} = 1;
351     }
352 }
353
354 sub output_programs
355 {
356     local ($word);
357
358     print CONF "\ndnl Checks for programs.\n";
359     foreach $word (sort keys %programs) {
360         &print_unique($programs_macros{$word});
361     }
362     foreach $word (sort keys %makevars) {
363         &print_unique($makevars_macros{$word});
364     }
365     print CONF "\ndnl Checks for libraries.\n";
366     foreach $word (sort keys %libraries) {
367         print CONF "dnl Replace `\main\' with a function in -l$word:\n";
368         print CONF "AC_CHECK_LIB($word, main)\n";
369     }
370 }
371
372 sub output_headers
373 {
374     local ($word);
375
376     print CONF "\ndnl Checks for header files.\n";
377     foreach $word (sort keys %headers) {
378         if (defined($headers_macros{$word}) &&
379             $headers_macros{$word} eq 'AC_CHECK_HEADERS') {
380             push(@have_headers, $word);
381         } else {        
382             &print_unique($headers_macros{$word});
383         }
384     }
385     print CONF "AC_CHECK_HEADERS(" . join(' ', sort(@have_headers)) . ")\n"
386         if defined(@have_headers);
387 }
388
389 sub output_identifiers
390 {
391     local ($word);
392
393     print CONF "\ndnl Checks for typedefs, structures, and compiler characteristics.\n";
394     foreach $word (sort keys %identifiers) {
395         &print_unique($identifiers_macros{$word});
396     }
397 }
398
399 sub output_functions
400 {
401     local ($word);
402
403     print CONF "\ndnl Checks for library functions.\n";
404     foreach $word (sort keys %functions) {
405         if (defined($functions_macros{$word}) &&
406             $functions_macros{$word} eq 'AC_CHECK_FUNCS') {
407             push(@have_funcs, $word);
408         } else {        
409             &print_unique($functions_macros{$word});
410         }
411     }
412     print CONF "AC_CHECK_FUNCS(" . join(' ', sort(@have_funcs)) . ")\n"
413         if defined(@have_funcs);
414 }