3708 lines · 100.7 KB · Perl
RawDownload
#!/usr/bin/perl -w# (c) 2001, Dave Jones. (the file handling bit)# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)# (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)# (c) 2008-2010 Andy Whitcroft <apw@canonical.com># Licensed under the terms of the GNU GPL License version 2 use strict; my $P = $0;$P =~ s@.*/@@g; my $V = '0.32'; use Getopt::Long qw(:config no_auto_abbrev); my $quiet = 0;my $tree = 1;my $chk_signoff = 1;my $chk_patch = 1;my $tst_only;my $emacs = 0;my $terse = 0;my $file = 0;my $check = 0;my $summary = 1;my $mailback = 0;my $summary_file = 0;my $show_types = 0;my $root;my %debug;my %ignore_type = ();my @ignore = ();my $help = 0;my $configuration_file = ".checkpatch.conf";my $max_line_length = 80; sub help {	my ($exitcode) = @_; 	print << "EOM";Usage: $P [OPTION]... [FILE]...Version: $V Options:  -q, --quiet                quiet  --no-tree                  run without a kernel tree  --no-signoff               do not check for 'Signed-off-by' line  --patch                    treat FILE as patchfile (default)  --emacs                    emacs compile window format  --terse                    one line per report  -f, --file                 treat FILE as regular source file  --subjective, --strict     enable more subjective tests  --ignore TYPE(,TYPE2...)   ignore various comma separated message types  --max-line-length=n        set the maximum line length, if exceeded, warn  --show-types               show the message "types" in the output  --root=PATH                PATH to the kernel tree root  --no-summary               suppress the per-file summary  --mailback                 only produce a report in case of warnings/errors  --summary-file             include the filename in summary  --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of                             'values', 'possible', 'type', and 'attr' (default                             is all off)  --test-only=WORD           report only warnings/errors containing WORD                             literally  -h, --help, --version      display this help and exit When FILE is - read standard input.EOM 	exit($exitcode);} my $conf = which_conf($configuration_file);if (-f $conf) {	my @conf_args;	open(my $conffile, '<', "$conf")	    or warn "$P: Can't find a readable $configuration_file file $!\n"; 	while (<$conffile>) {		my $line = $_; 		$line =~ s/\s*\n?$//g;		$line =~ s/^\s*//g;		$line =~ s/\s+/ /g; 		next if ($line =~ m/^\s*#/);		next if ($line =~ m/^\s*$/); 		my @words = split(" ", $line);		foreach my $word (@words) {			last if ($word =~ m/^#/);			push (@conf_args, $word);		}	}	close($conffile);	unshift(@ARGV, @conf_args) if @conf_args;} GetOptions(	'q|quiet+'	=> \$quiet,	'tree!'		=> \$tree,	'signoff!'	=> \$chk_signoff,	'patch!'	=> \$chk_patch,	'emacs!'	=> \$emacs,	'terse!'	=> \$terse,	'f|file!'	=> \$file,	'subjective!'	=> \$check,	'strict!'	=> \$check,	'ignore=s'	=> \@ignore,	'show-types!'	=> \$show_types,	'max-line-length=i' => \$max_line_length,	'root=s'	=> \$root,	'summary!'	=> \$summary,	'mailback!'	=> \$mailback,	'summary-file!'	=> \$summary_file, 	'debug=s'	=> \%debug,	'test-only=s'	=> \$tst_only,	'h|help'	=> \$help,	'version'	=> \$help) or help(1); help(0) if ($help); my $exit = 0; if ($#ARGV < 0) {	print "$P: no input files\n";	exit(1);} @ignore = split(/,/, join(',',@ignore));foreach my $word (@ignore) {	$word =~ s/\s*\n?$//g;	$word =~ s/^\s*//g;	$word =~ s/\s+/ /g;	$word =~ tr/[a-z]/[A-Z]/; 	next if ($word =~ m/^\s*#/);	next if ($word =~ m/^\s*$/); 	$ignore_type{$word}++;} my $dbg_values = 0;my $dbg_possible = 0;my $dbg_type = 0;my $dbg_attr = 0;for my $key (keys %debug) {	## no critic	eval "\${dbg_$key} = '$debug{$key}';";	die "$@" if ($@);} my $rpt_cleaners = 0; if ($terse) {	$emacs = 1;	$quiet++;} if ($tree) {	if (defined $root) {		if (!top_of_kernel_tree($root)) {			die "$P: $root: --root does not point at a valid tree\n";		}	} else {		if (top_of_kernel_tree('.')) {			$root = '.';		} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&						top_of_kernel_tree($1)) {			$root = $1;		}	} 	if (!defined $root) {		print "Must be run from the top-level dir. of a kernel tree\n";		exit(2);	}} my $emitted_corrupt = 0; our $Ident	= qr{			[A-Za-z_][A-Za-z\d_]*			(?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*		}x;our $Storage	= qr{extern|static|asmlinkage};our $Sparse	= qr{			__user|			__kernel|			__force|			__iomem|			__must_check|			__init_refok|			__kprobes|			__ref|			__rcu		}x; # Notes to $Attribute:# We need \b after 'init' otherwise 'initconst' will cause a false positive in a checkour $Attribute	= qr{			const|			__percpu|			__nocast|			__safe|			__bitwise__|			__packed__|			__packed2__|			__naked|			__maybe_unused|			__always_unused|			__noreturn|			__used|			__cold|			__noclone|			__deprecated|			__read_mostly|			__kprobes|			__(?:mem|cpu|dev|)(?:initdata|initconst|init\b)|			____cacheline_aligned|			____cacheline_aligned_in_smp|			____cacheline_internodealigned_in_smp|			__weak		  }x;our $Modifier;our $Inline	= qr{inline|__always_inline|noinline};our $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};our $Lval	= qr{$Ident(?:$Member)*}; our $Float_hex	= qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};our $Float_dec	= qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};our $Float_int	= qr{(?i)[0-9]+e-?[0-9]+[fl]?};our $Float	= qr{$Float_hex|$Float_dec|$Float_int};our $Constant	= qr{$Float|(?i)(?:0x[0-9a-f]+|[0-9]+)[ul]*};our $Assignment	= qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};our $Compare    = qr{<=|>=|==|!=|<|>};our $Operators	= qr{			<=|>=|==|!=|			=>|->|<<|>>|<|>|!|~|			&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%		  }x; our $NonptrType;our $Type;our $Declare; our $NON_ASCII_UTF8	= qr{	[\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte	|  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs	| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte	|  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates	|  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3	| [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15	|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16}x; our $UTF8	= qr{	[\x09\x0A\x0D\x20-\x7E]              # ASCII	| $NON_ASCII_UTF8}x; our $typeTypedefs = qr{(?x:	(?:__)?(?:u|s|be|le)(?:8|16|32|64)|	atomic_t)}; our $logFunctions = qr{(?x:	printk(?:_ratelimited|_once|)|	[a-z0-9]+_(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|	WARN(?:_RATELIMIT|_ONCE|)|	panic|	MODULE_[A-Z_]+)}; our $signature_tags = qr{(?xi:	Signed-off-by:|	Acked-by:|	Tested-by:|	Reviewed-by:|	Reported-by:|	To:|	Cc:)}; our @typeList = (	qr{void},	qr{(?:unsigned\s+)?char},	qr{(?:unsigned\s+)?short},	qr{(?:unsigned\s+)?int},	qr{(?:unsigned\s+)?long},	qr{(?:unsigned\s+)?long\s+int},	qr{(?:unsigned\s+)?long\s+long},	qr{(?:unsigned\s+)?long\s+long\s+int},	qr{unsigned},	qr{float},	qr{double},	qr{bool},	qr{struct\s+$Ident},	qr{union\s+$Ident},	qr{enum\s+$Ident},	qr{${Ident}_t},	qr{${Ident}_handler},	qr{${Ident}_handler_fn},);our @modifierList = (	qr{fastcall},); our $allowed_asm_includes = qr{(?x:	irq|	memory)};# memory.h: ARM has a custom one sub build_types {	my $mods = "(?x:  \n" . join("|\n  ", @modifierList) . "\n)";	my $all = "(?x:  \n" . join("|\n  ", @typeList) . "\n)";	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};	$NonptrType	= qr{			(?:$Modifier\s+|const\s+)*			(?:				(?:typeof|__typeof__)\s*\([^\)]*\)|				(?:$typeTypedefs\b)|				(?:${all}\b)			)			(?:\s+$Modifier|\s+const)*		  }x;	$Type	= qr{			$NonptrType			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*|\[\])+|(?:\s*\[\s*\])+)?			(?:\s+$Inline|\s+$Modifier)*		  }x;	$Declare	= qr{(?:$Storage\s+)?$Type};}build_types();  our $Typecast	= qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; # Using $balanced_parens, $LvalOrFunc, or $FuncArg# requires at least perl version v5.10.0# Any use must be runtime checked with $^V our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;our $LvalOrFunc	= qr{($Lval)\s*($balanced_parens{0,1})\s*};our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant)}; sub deparenthesize {	my ($string) = @_;	return "" if (!defined($string));	$string =~ s@^\s*\(\s*@@g;	$string =~ s@\s*\)\s*$@@g;	$string =~ s@\s+@ @g;	return $string;} $chk_signoff = 0 if ($file); my @rawlines = ();my @lines = ();my $vname;for my $filename (@ARGV) {	my $FILE;	if ($file) {		open($FILE, '-|', "diff -u /dev/null $filename") ||			die "$P: $filename: diff failed - $!\n";	} elsif ($filename eq '-') {		open($FILE, '<&STDIN');	} else {		open($FILE, '<', "$filename") ||			die "$P: $filename: open failed - $!\n";	}	if ($filename eq '-') {		$vname = 'Your patch';	} else {		$vname = $filename;	}	while (<$FILE>) {		chomp;		push(@rawlines, $_);	}	close($FILE);	if (!process($filename)) {		$exit = 1;	}	@rawlines = ();	@lines = ();} exit($exit); sub top_of_kernel_tree {	my ($root) = @_; 	my @tree_check = (		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",		"README", "Documentation", "arch", "include", "drivers",		"fs", "init", "ipc", "kernel", "lib", "scripts",	); 	foreach my $check (@tree_check) {		if (! -e $root . '/' . $check) {			return 0;		}	}	return 1;} sub parse_email {	my ($formatted_email) = @_; 	my $name = "";	my $address = "";	my $comment = ""; 	if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {		$name = $1;		$address = $2;		$comment = $3 if defined $3;	} elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {		$address = $1;		$comment = $2 if defined $2;	} elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {		$address = $1;		$comment = $2 if defined $2;		$formatted_email =~ s/$address.*$//;		$name = $formatted_email;		$name =~ s/^\s+|\s+$//g;		$name =~ s/^\"|\"$//g;		# If there's a name left after stripping spaces and		# leading quotes, and the address doesn't have both		# leading and trailing angle brackets, the address		# is invalid. ie:		#   "joe smith joe@smith.com" bad		#   "joe smith <joe@smith.com" bad		if ($name ne "" && $address !~ /^<[^>]+>$/) {			$name = "";			$address = "";			$comment = "";		}	} 	$name =~ s/^\s+|\s+$//g;	$name =~ s/^\"|\"$//g;	$address =~ s/^\s+|\s+$//g;	$address =~ s/^\<|\>$//g; 	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes		$name = "\"$name\"";	} 	return ($name, $address, $comment);} sub format_email {	my ($name, $address) = @_; 	my $formatted_email; 	$name =~ s/^\s+|\s+$//g;	$name =~ s/^\"|\"$//g;	$address =~ s/^\s+|\s+$//g; 	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes		$name = "\"$name\"";	} 	if ("$name" eq "") {		$formatted_email = "$address";	} else {		$formatted_email = "$name <$address>";	} 	return $formatted_email;} sub which_conf {	my ($conf) = @_; 	foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {		if (-e "$path/$conf") {			return "$path/$conf";		}	} 	return "";} sub expand_tabs {	my ($str) = @_; 	my $res = '';	my $n = 0;	for my $c (split(//, $str)) {		if ($c eq "\t") {

Lines 1–500 of 3708.