home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD1.bin / gnu / bin / autoscan < prev    next >
Text File  |  1994-12-22  |  10KB  |  395 lines

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