check-sources.pl revision 9c3531d72aeaad6c5f01efe6a1c82023e1379e4d
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews#! /usr/bin/perl -ws
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews#
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews# Copyright (C) 2000 Internet Software Consortium.
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews#
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews# Permission to use, copy, modify, and distribute this software for any
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews# purpose with or without fee is hereby granted, provided that the above
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews# copyright notice and this permission notice appear in all copies.
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews#
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews# CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews# SOFTWARE.
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews# $Id: check-sources.pl,v 1.4 2000/06/22 22:00:34 tale Exp $
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews# Rudimentary, primarily for use by the developers.
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews# This just evolved with no serious attempt at making it
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews# bulletproof or foolproof. Or pretty even. Probably would
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews# have done it differently if it were actually designed as opposed
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews# to just growing as a multi-tentacled thing as various messages
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews# were either added or selectively silenced.
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrewsuse strict;
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrewsuse vars qw($help $debug);
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrewssub
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrewssortdir() {
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews if (-d $::a) {
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews if (-d $::b) {
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews return ($::a cmp $::b);
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews } else {
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews return (-1);
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews }
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews } elsif (-d $::b) {
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews return (1);
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews } else {
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews return ($::a cmp $::b);
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews }
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews}
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrewssub
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrewsdo_dir($$) {
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews my($predir, $dir) = @_;
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews my $newdir = $predir ne "" ? "$predir/$dir" : $dir;
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews print "================> $newdir\n";
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews unless (chdir("$dir")) {
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews print "cd $newdir: $1\n";
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews return;
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews }
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews unless (opendir(DIR, ".")) {
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews print "opendir $predir/$dir: $!\n";
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews return;
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews }
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews foreach my $entry (sort sortdir readdir(DIR)) {
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews next if $entry =~ /^\.\.?$/;
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews if (-d $entry) {
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews do_dir($newdir, $entry);
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews next;
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews }
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews next if $entry !~ /\.o$/;
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews do_file($entry);
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews }
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews closedir(DIR);
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews chdir("..") or
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews die "major malfunction: can't chdir to parent dir: $!\n";
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews print "================> $predir\n";
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews}
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrewssub
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrewsdo_file($) {
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews my $objfile = $_[0];
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews my ($file, $savesource, $saveobj);
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews my ($config_h, $cpp_if, $prefix, $elided, $comment, $prefix_extend, $body);
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont unless ($objfile =~ /\.o$/) {
343aeac7176d28c4a1b9d246b1f7311b4cd5da7dFrancis Dupont print "$0: skipping non-object file $objfile\n";
7867d18ce0ffa93055fbda3b9d2be8b168d898fcMark Andrews return;
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews }
($file = $objfile) =~ s%\.o$%.c%;
($savesource = $file) =~ s%$%.save%;
($saveobj = $objfile) =~ s%$%.save%;
if (-f $savesource) {
print "$savesource exists, skipping\n";
return;
}
unless (-f $file) {
print "$file does not exist, skipping\n";
return;
}
rename($file, $savesource);
rename($objfile, $saveobj);
open(SOURCE, "< $savesource");
$_ = join('', <SOURCE>);
close(SOURCE);
$prefix = '';
print "$file begin\n" if $debug;
while (1) {
eval {
# Note that only '#include <...>' is checked, not '#include "..."'.
# 1 23 4 5 6 78
if (m%(\A\Q$prefix\E((.*\n)*?))(\#include\s+(<.*?>)(.*)\n)((.*\n)*)%) {
$elided = $5;
$prefix_extend = $2 . $4;
$comment = $6;
$body = $1 . $7;
} else {
print "$file end\n" if $debug;
$elided = ""; # stop processing this file.
}
};
if ($@ ne "") {
print "$file processing failed: $@\n";
last;
}
last if $elided eq "";
print STDERR "$file checking $elided\n" if $debug;
if (! $config_h) {
$config_h = 1;
if ($elided ne "<config.h>") {
print "$file should include <config.h> before any other\n";
}
}
# Always required.
next if $elided eq "<config.h>";
# Can mark in the header file when a #include should stay even
# though it might not appear that way otherwise.
next if $comment =~ /require|provide|extend|define|contract|explicit/i;
if ($elided eq "<isc/print.h>") {
next if m%snprintf%m;
}
open(SOURCE, "> $file");
print SOURCE "$body";
close(SOURCE);
print "$file elided $elided, compiling\n" if $debug;
if (compile($objfile) == 0) {
if (! defined($cpp_if)) {
$cpp_if = /^#if/m;
print "$file has CPP #if(def), doublecheck elision recommendations.\n"
if $cpp_if;
}
print "$file does not need $elided\n";
} elsif ($elided eq "<string.h>") {
print "$file prefer <isc/string.h> to <string.h>\n";
}
} continue {
$prefix .= $prefix_extend;
}
rename($savesource, $file);
rename($saveobj, $objfile);
}
sub
compile($) {
my $obj = $_[0];
unless ($obj =~ /\.o$/) {
warn "$obj: not a .o object file\n";
return;
}
my $output = $debug ? "/dev/tty" : "/dev/null";
open(COMPILE, "make -e $obj 2>&1 >$output |");
my $stderr_lines = join('', <COMPILE>);
print $stderr_lines if $debug;
close(COMPILE);
unlink($obj);
return ($stderr_lines ne "");
}
sub
main() {
$| = 1;
$0 =~ s%.*/%%;
die "Usage: $0 [-debug]\n" if $help;
unless (-f 'configure' && -f 'Makefile') {
die "$0: run from top of bind9 source tree, after configure has run\n";
}
print "========================\n";
print "building initial objects\n";
print "========================\n";
# XXX bleah
unless (system("make") == 0) {
die "make all failed, couldn't be sure all objects were generated.\n";
}
unless (system("cd bin/tests && make -k all_tests") == 0) {
warn "make all_tests failed, but pressging on anyway\n";
}
print <<EOF;
================================================================
starting header elision
WARNING: Since this script only removes one header at a time,
programs might compile fine without the header because another
header provides the required information. If that header is
also recommend for removal, then removing both of them could
lead to a program that does *not* compile fine. So the only
way to be sure is to take them all out and then recompile to
see if there are any residual warnings/errors.
Similar, this program is quite ignorant when it comes to CPP
#if/#ifdef. It might well be that a header file does not
appear to be necessary because the code that depends on it
is not being compiled. To prevent this program from complaining
about such includes in later runs, put a "Required for ..."
comment on the same line as the #include.
================================================================
EOF
# XXX gcc-specific
# Disable builtin memcmp/memcpy/strcmp/strcpy/etc. When they are
# available, gcc won't warn about the lack of a prototype in a header
# file.
$ENV{'CFLAGS'} = "-fno-builtin";
do_dir("", ".");
}
main();