headers_check.pl 2.61 KB
Newer Older
1
#!/usr/bin/perl -w
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#
# headers_check.pl execute a number of trivial consistency checks
#
# Usage: headers_check.pl dir [files...]
# dir:   dir to look for included files
# arch:  architecture
# files: list of files to check
#
# The script reads the supplied files line by line and:
#
# 1) for each include statement it checks if the
#    included file actually exists.
#    Only include files located in asm* and linux* are checked.
#    The rest are assumed to be system include files.
#
17 18
# 2) It is checked that prototypes does not use "extern"
#
19
# 3) Check for leaked CONFIG_ symbols
20 21 22 23 24 25 26 27 28 29 30

use strict;

my ($dir, $arch, @files) = @ARGV;

my $ret = 0;
my $line;
my $lineno = 0;
my $filename;

foreach my $file (@files) {
31
	local *FH;
32
	$filename = $file;
33
	open(FH, "<$filename") or die "$filename: $!\n";
34
	$lineno = 0;
35
	while ($line = <FH>) {
36
		$lineno++;
37 38 39 40
		&check_include();
		&check_asm_types();
		&check_sizetypes();
		&check_prototypes();
41
		# Dropped for now. Too much noise &check_config();
42
	}
43
	close FH;
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
}
exit $ret;

sub check_include
{
	if ($line =~ m/^\s*#\s*include\s+<((asm|linux).*)>/) {
		my $inc = $1;
		my $found;
		$found = stat($dir . "/" . $inc);
		if (!$found) {
			$inc =~ s#asm/#asm-$arch/#;
			$found = stat($dir . "/" . $inc);
		}
		if (!$found) {
			printf STDERR "$filename:$lineno: included file '$inc' is not exported\n";
			$ret = 1;
		}
	}
}
63 64 65 66 67 68 69

sub check_prototypes
{
	if ($line =~ m/^\s*extern\b/) {
		printf STDERR "$filename:$lineno: extern's make no sense in userspace\n";
	}
}
70 71 72 73 74 75 76 77

sub check_config
{
	if ($line =~ m/[^a-zA-Z0-9_]+CONFIG_([a-zA-Z0-9]+)[^a-zA-Z0-9]/) {
		printf STDERR "$filename:$lineno: leaks CONFIG_$1 to userspace where it is not valid\n";
	}
}

78 79 80
my $linux_asm_types;
sub check_asm_types()
{
81 82 83
	if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) {
		return;
	}
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
	if ($lineno == 1) {
		$linux_asm_types = 0;
	} elsif ($linux_asm_types >= 1) {
		return;
	}
	if ($line =~ m/^\s*#\s*include\s+<asm\/types.h>/) {
		$linux_asm_types = 1;
		printf STDERR "$filename:$lineno: " .
		"include of <linux/types.h> is preferred over <asm/types.h>\n"
		# Warn until headers are all fixed
		#$ret = 1;
	}
}

my $linux_types;
sub check_sizetypes
{
101 102 103
	if ($filename =~ /types.h|int-l64.h|int-ll64.h/o) {
		return;
	}
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
	if ($lineno == 1) {
		$linux_types = 0;
	} elsif ($linux_types >= 1) {
		return;
	}
	if ($line =~ m/^\s*#\s*include\s+<linux\/types.h>/) {
		$linux_types = 1;
		return;
	}
	if ($line =~ m/__[us](8|16|32|64)\b/) {
		printf STDERR "$filename:$lineno: " .
		              "found __[us]{8,16,32,64} type " .
		              "without #include <linux/types.h>\n";
		$linux_types = 2;
		# Warn until headers are all fixed
		#$ret = 1;
	}
}