Mercurial > hg > buildtools
view autopoop @ 1:2375efb3340d
Added a modified version of svn2cl and the XSL stylesheet.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 09 May 2008 14:12:09 +0300 |
parents | d72d5d73b93a |
children | 5665a846d227 |
line wrap: on
line source
#!/usr/bin/perl -w # autopoop v0.57 (C) 2008 Matti 'ccr' Hamalainen # # Tries to generate extra.mk.in from known configure.ac and other # autoconf m4-macros, scanning against Makefiles. Also checks for # missing / unsubstituted symbols, etc. # # Requirements: # - Recent enough GNU Autoconf (and requirements for that) # - Perl 5 # # TODO: # - see fixmes # - document this # - find bugs # - ??? # - profit # use strict; use Cwd qw(getcwd realpath); # List of subdirectories to check for additional Autoconf m4 macros my @m4testdirs = ("m4", "unix"); # Misc. settings my $makefile = "Makefile"; my $extrasys = "extra.mk"; my $buildsys = "buildsys.mk"; my $tmpfile = "autopoop.tmp"; my $autom4te = "autom4te"; # Things that may be set by user my %bsdefines = ( "DESTDIR" => 1, ); # Special substitutions my %confdefines = ( # "VPATH" => "srcdir", # "SET_MAKE" => "", ); ### Function prototypes sub shortpath($); sub scanfile($$$$$$$$); ### Argument handling my $pcwd = getcwd(); my $argc = ($#ARGV + 1); print "Autopoop v0.57 (C) 2008 Matti 'ccr' Hamalainen\n"; die("Usage: autopoop <configurefile> <outfile> [autom4te options]\n". "Example: autopoop configure.ac extra.mk.in\n\n". "NOTICE! Assumes following files are used:\n". "$buildsys\[.in\], $extrasys, $makefile\n\n") unless ($argc >= 2); my $configure = shift; my $outfile = shift; ### Execute Autoconf 'autom4te' ... my @args = (@ARGV); foreach my $dir (@m4testdirs) { if (-d $dir) { push(@args, ("-I", $dir)); } } push(@args, ( "--force", "--no-cache", "--melt", "--language=autoconf", "--trace=AC_SUBST", "-o", $tmpfile, $configure)); print "- Running $autom4te ".join(" ", @args)." ...\n"; system($autom4te, @args) == 0 or die("Failed to execute $autom4te: $?\n"); ### Paf files $buildsys = realpath($buildsys); $extrasys = realpath($extrasys); $outfile = realpath($outfile); ### Process results open(INFILE,"<".$tmpfile) or die("Could not open '$tmpfile'!\n"); while (<INFILE>) { chop; my @entries = split(/:/); my $key = $entries[3]; unless ($key =~ /_(FALSE|TRUE)$/) { $confdefines{$key} = $key; } } close INFILE; unlink($tmpfile); ### Scan Makefiles and depencies my %makesubsts = (); my %confsubsts = (); my %makedefines = (); my %scanned = ($outfile => 1, $extrasys => 1); scanfile(".", $makefile, \%scanned, \%makesubsts, \%confsubsts, \%makedefines, 1, 1); scanfile("", $buildsys, \%scanned, \%makesubsts, \%confsubsts, \%makedefines, 1, 0); ### Scan buildsys.mk.in my %bssubsts = (); scanfile("", $buildsys.".in", \%scanned, \%bssubsts, \%bssubsts, \%bsdefines, 0, 0); my %globdefs = (); foreach my $file (keys %makedefines) { foreach my $s (keys %{$makedefines{$file}}) { $globdefs{$s} = 1; } } ### Compare results print "- Checking for used, but possibly undefined Make variables:\n"; foreach my $file (keys %makesubsts) { foreach my $s (sort { $a cmp $b } keys %{$makesubsts{$file}}) { if (!defined($confdefines{$s}) && !defined($makedefines{$file}{$s}) && !defined($bsdefines{$s})) { my $err = 0; if (!defined($globdefs{$s})) { $err = 1; } elsif ($file ne $buildsys && $file ne $outfile) { $err = 2; } if ($err) { printf " %-20s", "'$s'"; print " in ".shortpath($file).":".$makesubsts{$file}{$s}." ($err)\n"; } } } } print qq|Legend: (1) = Not defined anywhere (or misdetected). (2) = Defined 'somewhere', but unsure if symbol is propagated. |; print "- Checking for used, but possibly undefined substitutions:\n"; foreach my $file (keys %confsubsts) { foreach my $s (keys %{$confsubsts{$file}}) { if (!defined($confdefines{$s})) { printf " %-20s", "'$s'"; print " in ".shortpath($file).":".$confsubsts{$file}{$s}."\n"; } } } print "\n"; ### Output stuff print "- Outputting '$outfile'\n"; open(OUTFILE, ">", $outfile) or die("Could not open '$outfile'!\n"); foreach my $s (keys %confdefines) { if ($confdefines{$s} ne "") { print OUTFILE "$s ?= \@".$confdefines{$s}."\@\n"; } else { print OUTFILE "\@".$s."\@\n"; } } close OUTFILE; print "- Done.\n"; ### ### Functions ### sub shortpath($) { if (index($_[0], $pcwd) == 0) { return substr($_[0], length($pcwd) + 1); } else { return $_[0]; } } sub addhash($$$$$) { # if ($usenames) { $substs->{$filename}{$1} = $line; } else { $substs->{$1} = $line; } if ($_[0]) { $_[1]->{$_[2]}{$_[3]} = $_[4]; } else { $_[1]->{$_[3]} = $_[4]; } } sub scanfile($$$$$$$$) { my $mypath = $_[0]; my $myfile = $_[1]; my $scanned = $_[2]; my $substs = $_[3]; my $confsubsts = $_[4]; my $defines = $_[5]; my $usenames = $_[6]; my $recurse = $_[7]; # Form real path and check if we have already scanned the file my $filename = realpath($mypath."/".$myfile); if (defined($filename)) { if (defined($scanned->{$filename})) { $scanned->{$filename}++; return; } $scanned->{$filename} = 1; } else { $filename = $mypath."/".$myfile; } #print "ASDF: $filename\n"; # Scan file, if found if (open(my $SCANFILE, "<", $filename)) { print "- Scanning ".shortpath($filename)." ...\n"; my $line = 0; while (<$SCANFILE>) { $line++; chop; if (/^#/) { # ignore comment lines } else { while (/[^\$]\$\{([A-Za-z0-9_]+)\}/g) { addhash($usenames, $substs, $filename, $1, $line); } while (/[^\$]\$\(([A-Za-z0-9_]+)\)/g) { addhash($usenames, $substs, $filename, $1, $line); } while (/\@([A-Za-z0-9_]+)\@/g) { addhash($usenames, $confsubsts, $filename, $1, $line); } if (/^ifdef\s+([A-Za-z0-9_]+)/g) { addhash($usenames, $substs, $filename, $1, $line); } elsif (/^([A-Za-z][A-Za-z0-9_]+)\s*[\+]?=/) { addhash($usenames, $defines, $filename, $1, $line); } elsif (/^include (\S+)/) { scanfile($mypath, "$1", $scanned, $substs, $confsubsts, $defines, $usenames, $recurse); } } } close $SCANFILE; } # Recurse into subdirectories if ($recurse) { opendir(DIR, $mypath) || return; my @dirs = grep { /^[^\.]/ && -d "$mypath/$_" } readdir(DIR); closedir(DIR); foreach my $dir (@dirs) { scanfile($mypath."/".$dir, $myfile, $scanned, $substs, $confsubsts, $defines, $usenames, $recurse); } } }