check-includes.pl revision 9c3531d72aeaad6c5f01efe6a1c82023e1379e4d
#
# Copyright (C) 2000 Internet Software Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
# ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
# CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
# SOFTWARE.
# $Id: check-includes.pl,v 1.3 2000/06/22 22:00:32 tale Exp $
# Rudimentary, primarily for use by the developers.
# This just evolved with no serious attempt at making it
# bulletproof or foolproof. Or pretty even. Probably would
# have done it differently if it were actually designed as opposed
# to just growing as a multi-tentacled thing as various messages
# were either added or selectively silenced.
# XXX many warnings should not be made unless the header will be a public file
use strict;
use vars qw($debug);
$0 =~ s%.*/%%;
unless (-f 'configure.in') {
die "$0: run from top of bind9 source tree\n";
}
undef $/;
# Outer loop runs once for each file.
for (<>) {
unless ($file =~ /\.h$/) {
print "$0: skipping non-header file $file\n";
next;
}
die "$0: $file: no such file\n" unless -f $file;
# header file fragments; ignore
# XXX rdatastruct itself is moderately tricky.
# From external sources; ignore.
# Totally wrong platform; ignore.
$tmpfile =~ s/\.h$/.c/;
$file =~ m%(.*/)?(.*)/(.*)\.h%;
my $symbol = uc "\Q$2_$3_H\E";
$symbol =~ s/\\-/_/g;
if (! m%^\#ifndef\ $symbol\n
\#define\ $symbol\ 1\n
(.*\n)+
\#endif\ /\*\ $symbol\ \*/\n
\n*\Z%mx) {
print "$file has non-conforming wrapper for symbol $symbol\n"
unless $file =~ m%confparser_p\.h%;
}
my $nocomment = '^(?!\s+/?\*)';
# check use of macros without having included proper header for them.
}
print "$file has ISC_EVENTCLASS_ without <isc/eventclass.h>\n"
}
if (/$nocomment.*ISC_RESULTCLASS_/m &&
! m%^#include <isc/resultclass\.h>%m) {
print "$file has ISC_RESULTCLASS_ without <isc/resultclass.h>\n"
}
! m%^#include <isc/(types|boolean).h>%m) {
}
if (/$nocomment.*ISC_PLATFORM_/m &&
! m%^#include <isc/platform.h>%m) {
print "$file has ISC_PLATFORM_ without <isc/platform.h>\n"
}
}
}
if (/^$nocomment(?!#define)[a-z].*([a-zA-Z0-9]\([^;]*\);)/m &&
}
#
# First see whether it can be compiled without any additional includes.
# Only bother doing this for files that will be installed as public
#
print "$file does not compile stand-alone\n";
}
}
my $prefix = '';
while (1) {
eval {
# 1 23 4 5 6 78
if (m%(\A\Q$prefix\E((.*\n)*?))(\#include .*(<.*?>)(.*)\n)((.*\n)*)%) {
$elided = $5;
$comment = $6;
} else {
}
};
if ($@ ne "") {
print "$file processing failed: $@\n";
last;
}
last if $elided eq "";
# Can mark in the header file when a #include should stay even
# though it might not appear that way otherwise.
#
# Special exceptions.
# XXXDCL some of these should be perhaps generalized (ie, look for
#
next;
}
my $dir = $1;
# so only the ISC_R_ aspect has to be pointed out.
next;
}
} else {
# There is an {foo}_R_; this is a necessary include.
next;
}
}
if (! /^ISC_LANG_BEGINDECLS$/m) {
} elsif (! /^ISC_LANG_ENDDECLS$/m) {
print "$file has ISC_LANG_BEGINDECLS but no ISC_LANG_ENDDECLS\n";
} elsif (! /^$nocomment(?!#define)[a-z].*([a-zA-Z0-9]\()/m) {
}
next;
}
if ($elided eq "<isc/eventclass.h>") {
if (! /$nocomment.*ISC_EVENTCLASS_/m) {
print "$file has <isc/eventclass.h> without ISC_EVENTCLASS_\n";
}
next;
}
if ($elided eq "<isc/resultclass.h>") {
if (! /$nocomment.*ISC_RESULTCLASS_/m) {
print "$file has <isc/resultclass.h> without ISC_RESULTCLASS_\n";
}
next;
}
if ($elided =~ "<(isc|dns)/types.h>") {
my $dir = $1;
}
# ... otherwise the types.h file is needed for the relevant _t types
# it defines, even if this header file accidentally picks it up by
# including another header that itself included types.h.
# So skip the elision test in any event.
# XXX would be good to test for files that need types.h but don't
# include it.
next;
}
}
if ($elided eq "<isc/platform.h>") {
if (! /^$nocomment.*ISC_PLATFORM_/m) {
print "$file has <isc/platform.h> but no ISC_PLATFORM_\n";
}
next;
}
if (! /^$nocomment.*ISC_MAGIC_VALID/m) {
}
next;
}
open(TMP, "> $tmpfile");
print TMP "$body";
close(TMP);
print "$file elided $elided, compiling\n" if $debug;
print "$file does not need $elided\n";
}
} continue {
$prefix .= $prefix_extend;
}
}
sub
compile() {
#XXX -Iflags are a pain. this needs mending.
system("cc " .
"-c $source -o $objfile $stderr");
return ($?);
}