6577 lines · 191.3 KB · Perl
RawDownload
#!/usr/bin/env perl# SPDX-License-Identifier: GPL-2.0## (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># (c) 2010-2018 Joe Perches <joe@perches.com> use strict;use warnings;use POSIX;use File::Basename;use Cwd 'abs_path';use Term::ANSIColor qw(:constants); my $P = $0;my $D = dirname(abs_path($P)); 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 $showfile = 0;my $file = 0;my $git = 0;my %git_commits = ();my $check = 0;my $check_orig = 0;my $summary = 1;my $mailback = 0;my $summary_file = 0;my $show_types = 0;my $list_types = 0;my $fix = 0;my $fix_inplace = 0;my $root;my %debug;my %camelcase = ();my %use_type = ();my @use = ();my %ignore_type = ();my @ignore = ();my $help = 0;my $configuration_file = ".checkpatch.conf";my $max_line_length = 80;my $ignore_perl_version = 0;my $minimum_perl_version = 5.10.0;my $min_conf_desc_length = 4;my $spelling_file = "$D/spelling.txt";my $codespell = 0;my $codespellfile = "/usr/share/codespell/dictionary.txt";my $conststructsfile = "$D/const_structs.checkpatch";my $typedefsfile = "";my $color = "auto";my $allow_c99_comments = 1; 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  --showfile                 emit diffed file position, not input file position  -g, --git                  treat FILE as a single commit or git revision range                             single git commit with:                               <rev>                               <rev>^                               <rev>~n                             multiple git commits with:                               <rev1>..<rev2>                               <rev1>...<rev2>                               <rev>-<count>                             git merges are ignored  -f, --file                 treat FILE as regular source file  --subjective, --strict     enable more subjective tests  --list-types               list the possible message types  --types TYPE(,TYPE2...)    show only these comma separated message types  --ignore TYPE(,TYPE2...)   ignore various comma separated message types  --show-types               show the specific message type in the output  --max-line-length=n        set the maximum line length, if exceeded, warn  --min-conf-desc-length=n   set the min description length, if shorter, warn  --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  --fix                      EXPERIMENTAL - may create horrible results                             If correctable single-line errors exist, create                             "<inputfile>.EXPERIMENTAL-checkpatch-fixes"                             with potential errors corrected to the preferred                             checkpatch style  --fix-inplace              EXPERIMENTAL - may create horrible results                             Is the same as --fix, but overwrites the input                             file.  It's your fault if there's no backup or git  --ignore-perl-version      override checking of perl version.  expect                             runtime errors.  --codespell                Use the codespell dictionary for spelling/typos                             (default:/usr/share/codespell/dictionary.txt)  --codespellfile            Use this codespell dictionary  --typedefsfile             Read additional types from this file  --color[=WHEN]             Use colors 'always', 'never', or only when output                             is a terminal ('auto'). Default is 'auto'.  -h, --help, --version      display this help and exit When FILE is - read standard input.EOM 	exit($exitcode);} sub uniq {	my %seen;	return grep { !$seen{$_}++ } @_;} sub list_types {	my ($exitcode) = @_; 	my $count = 0; 	local $/ = undef; 	open(my $script, '<', abs_path($P)) or	    die "$P: Can't read '$P' $!\n"; 	my $text = <$script>;	close($script); 	my @types = ();	# Also catch when type or level is passed through a variable	for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {		push (@types, $_);	}	@types = sort(uniq(@types));	print("#\tMessage type\n\n");	foreach my $type (@types) {		print(++$count . "\t" . $type . "\n");	} 	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;} # Perl's Getopt::Long allows options to take optional arguments after a space.# Prevent --color by itself from consuming other argumentsforeach (@ARGV) {	if ($_ eq "--color" || $_ eq "-color") {		$_ = "--color=$color";	}} GetOptions(	'q|quiet+'	=> \$quiet,	'tree!'		=> \$tree,	'signoff!'	=> \$chk_signoff,	'patch!'	=> \$chk_patch,	'emacs!'	=> \$emacs,	'terse!'	=> \$terse,	'showfile!'	=> \$showfile,	'f|file!'	=> \$file,	'g|git!'	=> \$git,	'subjective!'	=> \$check,	'strict!'	=> \$check,	'ignore=s'	=> \@ignore,	'types=s'	=> \@use,	'show-types!'	=> \$show_types,	'list-types!'	=> \$list_types,	'max-line-length=i' => \$max_line_length,	'min-conf-desc-length=i' => \$min_conf_desc_length,	'root=s'	=> \$root,	'summary!'	=> \$summary,	'mailback!'	=> \$mailback,	'summary-file!'	=> \$summary_file,	'fix!'		=> \$fix,	'fix-inplace!'	=> \$fix_inplace,	'ignore-perl-version!' => \$ignore_perl_version,	'debug=s'	=> \%debug,	'test-only=s'	=> \$tst_only,	'codespell!'	=> \$codespell,	'codespellfile=s'	=> \$codespellfile,	'typedefsfile=s'	=> \$typedefsfile,	'color=s'	=> \$color,	'no-color'	=> \$color,	#keep old behaviors of -nocolor	'nocolor'	=> \$color,	#keep old behaviors of -nocolor	'h|help'	=> \$help,	'version'	=> \$help) or help(1); help(0) if ($help); list_types(0) if ($list_types); $fix = 1 if ($fix_inplace);$check_orig = $check; my $exit = 0; if ($^V && $^V lt $minimum_perl_version) {	printf "$P: requires at least perl version %vd\n", $minimum_perl_version;	if (!$ignore_perl_version) {		exit(1);	}} #if no filenames are given, push '-' to read patch from stdinif ($#ARGV < 0) {	push(@ARGV, '-');} if ($color =~ /^[01]$/) {	$color = !$color;} elsif ($color =~ /^always$/i) {	$color = 1;} elsif ($color =~ /^never$/i) {	$color = 0;} elsif ($color =~ /^auto$/i) {	$color = (-t STDOUT);} else {	die "Invalid color mode: $color\n";} sub hash_save_array_words {	my ($hashRef, $arrayRef) = @_; 	my @array = split(/,/, join(',', @$arrayRef));	foreach my $word (@array) {		$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*$/); 		$hashRef->{$word}++;	}} sub hash_show_words {	my ($hashRef, $prefix) = @_; 	if (keys %$hashRef) {		print "\nNOTE: $prefix message types:";		foreach my $word (sort keys %$hashRef) {			print " $word";		}		print "\n";	}} hash_save_array_words(\%ignore_type, \@ignore);hash_save_array_words(\%use_type, \@use); 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|			__private		}x;our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};our $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};our $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};our $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit}; # 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|			__pure|			__noclone|			__deprecated|			__read_mostly|			__kprobes|			$InitAttribute|			____cacheline_aligned|			____cacheline_aligned_in_smp|			____cacheline_internodealigned_in_smp|			__weak		  }x;our $Modifier;our $Inline	= qr{inline|__always_inline|noinline|__inline|__inline__};our $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};our $Lval	= qr{$Ident(?:$Member)*}; our $Int_type	= qr{(?i)llu|ull|ll|lu|ul|l|u};our $Binary	= qr{(?i)0b[01]+$Int_type?};our $Hex	= qr{(?i)0x[0-9a-f]+$Int_type?};our $Int	= qr{[0-9]+$Int_type?};our $Octal	= qr{0[0-7]+$Int_type?};our $String	= qr{"[X\t]*"};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|$Binary|$Octal|$Hex|$Int};our $Assignment	= qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};our $Compare    = qr{<=|>=|==|!=|<|(?<!-)>};our $Arithmetic = qr{\+|-|\*|\/|%};our $Operators	= qr{			<=|>=|==|!=|			=>|->|<<|>>|<|>|!|~|			&&|\|\||,|\^|\+\+|--|&|\||$Arithmetic		  }x; our $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x; our $BasicType;our $NonptrType;our $NonptrTypeMisordered;our $NonptrTypeWithAttr;our $Type;our $TypeMisordered;our $Declare;our $DeclareMisordered; 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 $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};our $typeOtherOSTypedefs = qr{(?x:	u_(?:char|short|int|long) |          # bsd	u(?:nchar|short|int|long)            # sysv)};our $typeKernelTypedefs = qr{(?x:	(?:__)?(?:u|s|be|le)(?:8|16|32|64)|	atomic_t)};our $typeTypedefs = qr{(?x:	$typeC99Typedefs\b|	$typeOtherOSTypedefs\b|	$typeKernelTypedefs\b)}; our $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b}; our $logFunctions = qr{(?x:	printk(?:_ratelimited|_once|_deferred_once|_deferred|)|	(?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|	TP_printk|	WARN(?:_RATELIMIT|_ONCE|)|	panic|	MODULE_[A-Z_]+|	seq_vprintf|seq_printf|seq_puts)}; our $signature_tags = qr{(?xi:	Signed-off-by:|	Acked-by:|	Tested-by:|	Reviewed-by:|	Reported-by:|	Suggested-by:|	To:|	Cc:)}; our @typeListMisordered = (	qr{char\s+(?:un)?signed},	qr{int\s+(?:(?:un)?signed\s+)?short\s},	qr{int\s+short(?:\s+(?:un)?signed)},	qr{short\s+int(?:\s+(?:un)?signed)},	qr{(?:un)?signed\s+int\s+short},	qr{short\s+(?:un)?signed},	qr{long\s+int\s+(?:un)?signed},	qr{int\s+long\s+(?:un)?signed},	qr{long\s+(?:un)?signed\s+int},	qr{int\s+(?:un)?signed\s+long},	qr{int\s+(?:un)?signed},	qr{int\s+long\s+long\s+(?:un)?signed},	qr{long\s+long\s+int\s+(?:un)?signed},	qr{long\s+long\s+(?:un)?signed\s+int},	qr{long\s+long\s+(?:un)?signed},	qr{long\s+(?:un)?signed},); our @typeList = (	qr{void},	qr{(?:(?:un)?signed\s+)?char},	qr{(?:(?:un)?signed\s+)?short\s+int},	qr{(?:(?:un)?signed\s+)?short},

Lines 1–500 of 6577.