diff options
Diffstat (limited to 'tools/checkpatch.pl')
| -rwxr-xr-x | tools/checkpatch.pl | 749 | 
1 files changed, 557 insertions, 192 deletions
| diff --git a/tools/checkpatch.pl b/tools/checkpatch.pl index c7475f9e3..9f2390187 100755 --- a/tools/checkpatch.pl +++ b/tools/checkpatch.pl @@ -33,6 +33,7 @@ my %ignore_type = ();  my @ignore = ();  my $help = 0;  my $configuration_file = ".checkpatch.conf"; +my $max_line_length = 80;  sub help {  	my ($exitcode) = @_; @@ -51,6 +52,7 @@ Options:    -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 @@ -107,6 +109,7 @@ GetOptions(  	'strict!'	=> \$check,  	'ignore=s'	=> \@ignore,  	'show-types!'	=> \$show_types, +	'max-line-length=i' => \$max_line_length,  	'root=s'	=> \$root,  	'summary!'	=> \$summary,  	'mailback!'	=> \$mailback, @@ -227,8 +230,12 @@ our $Inline	= qr{inline|__always_inline|noinline};  our $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};  our $Lval	= qr{$Ident(?:$Member)*}; -our $Constant	= qr{(?:[0-9]+|0x[0-9a-fA-F]+)[UL]*}; -our $Assignment	= qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)}; +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{  			<=|>=|==|!=| @@ -240,9 +247,8 @@ our $NonptrType;  our $Type;  our $Declare; -our $UTF8	= qr { -	[\x09\x0A\x0D\x20-\x7E]              # ASCII -	| [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte +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 @@ -251,6 +257,11 @@ our $UTF8	= qr {  	|  \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 @@ -261,6 +272,7 @@ our $logFunctions = qr{(?x:  	[a-z0-9]+_(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|  	WARN(?:_RATELIMIT|_ONCE|)|  	panic| +	debug|  	MODULE_[A-Z_]+  )}; @@ -311,7 +323,7 @@ sub build_types {  	$NonptrType	= qr{  			(?:$Modifier\s+|const\s+)*  			(?: -				(?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\)| +				(?:typeof|__typeof__)\s*\([^\)]*\)|  				(?:$typeTypedefs\b)|  				(?:${all}\b)  			) @@ -319,17 +331,23 @@ sub build_types {  		  }x;  	$Type	= qr{  			$NonptrType -			(?:[\s\*]+\s*const|[\s\*]+|(?:\s*\[\s*\])+)? +			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*|\[\])+|(?:\s*\[\s*\])+)?  			(?:\s+$Inline|\s+$Modifier)*  		  }x;  	$Declare	= qr{(?:$Storage\s+)?$Type};  }  build_types(); -our $match_balanced_parentheses = qr/(\((?:[^\(\)]+|(-1))*\))/;  our $Typecast	= qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; -our $LvalOrFunc	= qr{($Lval)\s*($match_balanced_parentheses{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) = @_; @@ -342,27 +360,6 @@ sub deparenthesize {  $chk_signoff = 0 if ($file); -my @dep_includes = (); -my @dep_functions = (); -my $removal = "Documentation/feature-removal-schedule.txt"; -if ($tree && -f "$root/$removal") { -	open(my $REMOVE, '<', "$root/$removal") || -				die "$P: $removal: open failed - $!\n"; -	while (<$REMOVE>) { -		if (/^Check:\s+(.*\S)/) { -			for my $entry (split(/[, ]+/, $1)) { -				if ($entry =~ m@include/(.*)@) { -					push(@dep_includes, $1); - -				} elsif ($entry !~ m@/@) { -					push(@dep_functions, $entry); -				} -			} -		} -	} -	close($REMOVE); -} -  my @rawlines = ();  my @lines = ();  my $vname; @@ -411,7 +408,7 @@ sub top_of_kernel_tree {  		}  	}  	return 1; -    } +}  sub parse_email {  	my ($formatted_email) = @_; @@ -672,6 +669,10 @@ sub ctx_statement_block {  			if ($off >= $len) {  				last;  			} +			if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { +				$level++; +				$type = '#'; +			}  		}  		$p = $c;  		$c = substr($blk, $off, 1); @@ -734,6 +735,13 @@ sub ctx_statement_block {  				last;  			}  		} +		# Preprocessor commands end at the newline unless escaped. +		if ($type eq '#' && $c eq "\n" && $p ne "\\") { +			$level--; +			$type = ''; +			$off++; +			last; +		}  		$off++;  	}  	# We are truly at the end, so shuffle to the next line. @@ -1016,7 +1024,7 @@ sub annotate_values {  		} elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {  			print "CAST($1)\n" if ($dbg_values > 1);  			push(@av_paren_type, $type); -			$type = 'C'; +			$type = 'c';  		} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {  			print "DECLARE($1)\n" if ($dbg_values > 1); @@ -1208,7 +1216,9 @@ sub possible {  			case|  			else|  			asm|__asm__| -			do +			do| +			\#| +			\#\#|  		)(?:\s|$)|  		^(?:typedef|struct|enum)\b  	    )}x; @@ -1312,6 +1322,36 @@ sub check_absolute_file {  	}  } +sub pos_last_openparen { +	my ($line) = @_; + +	my $pos = 0; + +	my $opens = $line =~ tr/\(/\(/; +	my $closes = $line =~ tr/\)/\)/; + +	my $last_openparen = 0; + +	if (($opens == 0) || ($closes >= $opens)) { +		return -1; +	} + +	my $len = length($line); + +	for ($pos = 0; $pos < $len; $pos++) { +		my $string = substr($line, $pos); +		if ($string =~ /^($FuncArg|$balanced_parens)/) { +			$pos += length($1) - 1; +		} elsif (substr($line, $pos, 1) eq '(') { +			$last_openparen = $pos; +		} elsif (index($string, '(') == -1) { +			last; +		} +	} + +	return $last_openparen + 1; +} +  sub process {  	my $filename = shift; @@ -1330,6 +1370,11 @@ sub process {  	my $signoff = 0;  	my $is_patch = 0; +	my $in_header_lines = 1; +	my $in_commit_log = 0;		#Scanning lines before patch + +	my $non_utf8_charset = 0; +  	our @report = ();  	our $cnt_lines = 0;  	our $cnt_error = 0; @@ -1352,6 +1397,9 @@ sub process {  	my %suppress_ifbraces;  	my %suppress_whiletrailers;  	my %suppress_export; +	my $suppress_statement = 0; + +	my %camelcase = ();  	# Pre-scan the patch sanitizing the lines.  	# Pre-scan the patch looking for any __setup documentation. @@ -1461,6 +1509,7 @@ sub process {  			%suppress_ifbraces = ();  			%suppress_whiletrailers = ();  			%suppress_export = (); +			$suppress_statement = 0;  			next;  # track the line number as we move through the hunk, note that @@ -1497,10 +1546,11 @@ sub process {  		if ($line =~ /^diff --git.*?(\S+)$/) {  			$realfile = $1;  			$realfile =~ s@^([^/]*)/@@; - +			$in_commit_log = 0;  		} elsif ($line =~ /^\+\+\+\s+(\S+)/) {  			$realfile = $1;  			$realfile =~ s@^([^/]*)/@@; +			$in_commit_log = 0;  			$p1_prefix = $1;  			if (!$file && $tree && $p1_prefix ne '' && @@ -1536,16 +1586,22 @@ sub process {  # Check the patch for a signoff:  		if ($line =~ /^\s*signed-off-by:/i) {  			$signoff++; +			$in_commit_log = 0;  		}  # Check signature styles -		if ($line =~ /^(\s*)($signature_tags)(\s*)(.*)/) { +		if (!$in_header_lines && +		    $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {  			my $space_before = $1;  			my $sign_off = $2;  			my $space_after = $3;  			my $email = $4;  			my $ucfirst_sign_off = ucfirst(lc($sign_off)); +			if ($sign_off !~ /$signature_tags/) { +				WARN("BAD_SIGN_OFF", +				     "Non-standard signature: $sign_off\n" . $herecurr); +			}  			if (defined $space_before && $space_before ne "") {  				WARN("BAD_SIGN_OFF",  				     "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr); @@ -1613,6 +1669,28 @@ sub process {  			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);  		} +# Check if it's the start of a commit log +# (not a header line and we haven't seen the patch filename) +		if ($in_header_lines && $realfile =~ /^$/ && +		    $rawline !~ /^(commit\b|from\b|[\w-]+:).+$/i) { +			$in_header_lines = 0; +			$in_commit_log = 1; +		} + +# Check if there is UTF-8 in a commit log when a mail header has explicitly +# declined it, i.e defined some charset where it is missing. +		if ($in_header_lines && +		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && +		    $1 !~ /utf-8/i) { +			$non_utf8_charset = 1; +		} + +		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && +		    $rawline =~ /$NON_ASCII_UTF8/) { +			WARN("UTF8_BEFORE_PATCH", +			    "8-bit UTF-8 used in possible commit log\n" . $herecurr); +		} +  # ignore non-hunk lines and lines being removed  		next if (!$hunk_line || $line =~ /^-/); @@ -1633,19 +1711,26 @@ sub process {  # Only applies when adding the entry originally, after that we do not have  # sufficient context to determine whether it is indeed long enough.  		if ($realfile =~ /Kconfig/ && -		    $line =~ /\+\s*(?:---)?help(?:---)?$/) { +		    $line =~ /.\s*config\s+/) {  			my $length = 0;  			my $cnt = $realcnt;  			my $ln = $linenr + 1;  			my $f; +			my $is_start = 0;  			my $is_end = 0; -			while ($cnt > 0 && defined $lines[$ln - 1]) { +			for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {  				$f = $lines[$ln - 1];  				$cnt-- if ($lines[$ln - 1] !~ /^-/);  				$is_end = $lines[$ln - 1] =~ /^\+/; -				$ln++;  				next if ($f =~ /^-/); + +				if ($lines[$ln - 1] =~ /.\s*(?:bool|tristate)\s*\"/) { +					$is_start = 1; +				} elsif ($lines[$ln - 1] =~ /.\s*(?:---)?help(?:---)?$/) { +					$length = -1; +				} +  				$f =~ s/^.//;  				$f =~ s/#.*//;  				$f =~ s/^\s+//; @@ -1657,22 +1742,58 @@ sub process {  				$length++;  			}  			WARN("CONFIG_DESCRIPTION", -			     "please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_end && $length < 4); -			#print "is_end<$is_end> length<$length>\n"; +			     "please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_start && $is_end && $length < 4); +			#print "is_start<$is_start> is_end<$is_end> length<$length>\n"; +		} + +# discourage the addition of CONFIG_EXPERIMENTAL in Kconfig. +		if ($realfile =~ /Kconfig/ && +		    $line =~ /.\s*depends on\s+.*\bEXPERIMENTAL\b/) { +			WARN("CONFIG_EXPERIMENTAL", +			     "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n"); +		} + +		if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && +		    ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { +			my $flag = $1; +			my $replacement = { +				'EXTRA_AFLAGS' =>   'asflags-y', +				'EXTRA_CFLAGS' =>   'ccflags-y', +				'EXTRA_CPPFLAGS' => 'cppflags-y', +				'EXTRA_LDFLAGS' =>  'ldflags-y', +			}; + +			WARN("DEPRECATED_VARIABLE", +			     "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});  		}  # check we are in a valid source file if not then ignore this hunk  		next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/); -#80 column limit +#line length limit  		if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&  		    $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&  		    !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:|,|\)\s*;)\s*$/ ||  		    $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) && -		    $length > 80) +		    $length > $max_line_length)  		{  			WARN("LONG_LINE", -			     "line over 80 characters\n" . $herecurr); +			     "line over $max_line_length characters\n" . $herecurr); +		} + +# Check for user-visible strings broken across lines, which breaks the ability +# to grep for the string.  Limited to strings used as parameters (those +# following an open parenthesis), which almost completely eliminates false +# positives, as well as warning only once per parameter rather than once per +# line of the string.  Make an exception when the previous string ends in a +# newline (multiple lines in one string constant) or \n\t (common in inline +# assembly to indent the instruction on the following line). +		if ($line =~ /^\+\s*"/ && +		    $prevline =~ /"\s*$/ && +		    $prevline =~ /\(/ && +		    $prevrawline !~ /\\n(?:\\t)*"\s*$/) { +			WARN("SPLIT_STRING", +			     "quoted string split across lines\n" . $hereprev);  		}  # check for spaces before a quoted newline @@ -1721,6 +1842,58 @@ sub process {  			     "please, no space before tabs\n" . $herevet);  		} +# check for && or || at the start of a line +		if ($rawline =~ /^\+\s*(&&|\|\|)/) { +			CHK("LOGICAL_CONTINUATIONS", +			    "Logical continuations should be on the previous line\n" . $hereprev); +		} + +# check multi-line statement indentation matches previous line +		if ($^V && $^V ge 5.10.0 && +		    $prevline =~ /^\+(\t*)(if \(|$Ident\().*(\&\&|\|\||,)\s*$/) { +			$prevline =~ /^\+(\t*)(.*)$/; +			my $oldindent = $1; +			my $rest = $2; + +			my $pos = pos_last_openparen($rest); +			if ($pos >= 0) { +				$line =~ /^(\+| )([ \t]*)/; +				my $newindent = $2; + +				my $goodtabindent = $oldindent . +					"\t" x ($pos / 8) . +					" "  x ($pos % 8); +				my $goodspaceindent = $oldindent . " "  x $pos; + +				if ($newindent ne $goodtabindent && +				    $newindent ne $goodspaceindent) { +					CHK("PARENTHESIS_ALIGNMENT", +					    "Alignment should match open parenthesis\n" . $hereprev); +				} +			} +		} + +		if ($line =~ /^\+.*\*[ \t]*\)[ \t]+/) { +			CHK("SPACING", +			    "No space is necessary after a cast\n" . $hereprev); +		} + +		if ($realfile =~ m@^(drivers/net/|net/)@ && +		    $rawline =~ /^\+[ \t]*\/\*[ \t]*$/ && +		    $prevrawline =~ /^\+[ \t]*$/) { +			WARN("NETWORKING_BLOCK_COMMENT_STYLE", +			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); +		} + +		if ($realfile =~ m@^(drivers/net/|net/)@ && +		    $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */ +		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/ +		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/ +		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */ +			WARN("NETWORKING_BLOCK_COMMENT_STYLE", +			     "networking block comments put the trailing */ on a separate line\n" . $herecurr); +		} +  # check for spaces at the beginning of a line.  # Exceptions:  #  1) within comments @@ -1735,6 +1908,12 @@ sub process {  # check we are in a valid C source file if not then ignore this hunk  		next if ($realfile !~ /\.(h|c)$/); +# discourage the addition of CONFIG_EXPERIMENTAL in #if(def). +		if ($line =~ /^\+\s*\#\s*if.*\bCONFIG_EXPERIMENTAL\b/) { +			WARN("CONFIG_EXPERIMENTAL", +			     "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n"); +		} +  # check for RCS/CVS revision markers  		if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {  			WARN("CVS_KEYWORD", @@ -1753,15 +1932,33 @@ sub process {  			      "use the SSYNC() macro in asm/blackfin.h\n" . $herevet);  		} +# check for old HOTPLUG __dev<foo> section markings +		if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { +			WARN("HOTPLUG_SECTION", +			     "Using $1 is unnecessary\n" . $herecurr); +		} +  # Check for potential 'bare' types  		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,  		    $realline_next); -		if ($realcnt && $line =~ /.\s*\S/) { +#print "LINE<$line>\n"; +		if ($linenr >= $suppress_statement && +		    $realcnt && $line =~ /.\s*\S/) {  			($stat, $cond, $line_nr_next, $remain_next, $off_next) =  				ctx_statement_block($linenr, $realcnt, 0);  			$stat =~ s/\n./\n /g;  			$cond =~ s/\n./\n /g; +#print "linenr<$linenr> <$stat>\n"; +			# If this statement has no statement boundaries within +			# it there is no point in retrying a statement scan +			# until we hit end of it. +			my $frag = $stat; $frag =~ s/;+\s*$//; +			if ($frag !~ /(?:{|;)/) { +#print "skip<$line_nr_next>\n"; +				$suppress_statement = $line_nr_next; +			} +  			# Find the real next line.  			$realline_next = $line_nr_next;  			if (defined $realline_next && @@ -1850,6 +2047,12 @@ sub process {  			my $pre_ctx = "$1$2";  			my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); + +			if ($line =~ /^\+\t{6,}/) { +				WARN("DEEP_INDENTATION", +				     "Too many leading tabs - consider code refactoring\n" . $herecurr); +			} +  			my $ctx_cnt = $realcnt - $#ctx - 1;  			my $ctx = join("\n", @ctx); @@ -1887,6 +2090,9 @@ sub process {  # Check relative indent for conditionals and blocks.  		if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { +			($stat, $cond, $line_nr_next, $remain_next, $off_next) = +				ctx_statement_block($linenr, $realcnt, 0) +					if (!defined $stat);  			my ($s, $c) = ($stat, $cond);  			substr($s, 0, length($c), ''); @@ -2027,8 +2233,11 @@ sub process {  			my $path = $1;  			if ($path =~ m{//}) {  				ERROR("MALFORMED_INCLUDE", -				      "malformed #include filename\n" . -					$herecurr); +				      "malformed #include filename\n" . $herecurr); +			} +			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { +				ERROR("UAPI_INCLUDE", +				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);  			}  		} @@ -2054,7 +2263,7 @@ sub process {  			#   XXX(foo);  			#   EXPORT_SYMBOL(something_foo);  			my $name = $1; -			if ($stat =~ /^.([A-Z_]+)\s*\(\s*($Ident)/ && +			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&  			    $name =~ /^${Ident}_$2/) {  #print "FOO C name<$name>\n";  				$suppress_export{$realline_next} = 1; @@ -2132,8 +2341,9 @@ sub process {  # * goes on variable not on type  		# (char*[ const]) -		if ($line =~ m{\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\)}) { -			my ($from, $to) = ($1, $1); +		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { +			#print "AA<$1>\n"; +			my ($from, $to) = ($2, $2);  			# Should start with a space.  			$to =~ s/^(\S)/ $1/; @@ -2148,8 +2358,10 @@ sub process {  				ERROR("POINTER_LOCATION",  				      "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr);  			} -		} elsif ($line =~ m{\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident)}) { -			my ($from, $to, $ident) = ($1, $1, $2); +		} +		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { +			#print "BB<$1>\n"; +			my ($from, $to, $ident) = ($2, $2, $3);  			# Should start with a space.  			$to =~ s/^(\S)/ $1/; @@ -2210,6 +2422,30 @@ sub process {  			}  		} +		if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { +			my $orig = $1; +			my $level = lc($orig); +			$level = "warn" if ($level eq "warning"); +			my $level2 = $level; +			$level2 = "dbg" if ($level eq "debug"); +			WARN("PREFER_PR_LEVEL", +			     "Prefer netdev_$level2(netdev, ... then dev_$level2(dev, ... then pr_$level(...  to printk(KERN_$orig ...\n" . $herecurr); +		} + +		if ($line =~ /\bpr_warning\s*\(/) { +			WARN("PREFER_PR_LEVEL", +			     "Prefer pr_warn(... to pr_warning(...\n" . $herecurr); +		} + +		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { +			my $orig = $1; +			my $level = lc($orig); +			$level = "warn" if ($level eq "warning"); +			$level = "dbg" if ($level eq "debug"); +			WARN("PREFER_DEV_LEVEL", +			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); +		} +  # function brace can't be on same line, except for #defines of do while,  # or if closed on same line  		if (($line=~/$Type\s*$Ident\(.*\).*\s{/) and @@ -2239,7 +2475,7 @@ sub process {  			my ($where, $prefix) = ($-[1], $1);  			if ($prefix !~ /$Type\s+$/ &&  			    ($where != 0 || $prefix !~ /^.\s+$/) && -			    $prefix !~ /{\s+$/) { +			    $prefix !~ /[{,]\s+$/) {  				ERROR("BRACKET_SPACE",  				      "space prohibited before open square bracket '['\n" . $herecurr);  			} @@ -2276,6 +2512,13 @@ sub process {  				     "space prohibited between function name and open parenthesis '('\n" . $herecurr);  			}  		} + +# check for whitespace before a non-naked semicolon +		if ($line =~ /^\+.*\S\s+;/) { +			CHK("SPACING", +			    "space prohibited before semicolon\n" . $herecurr); +		} +  # Check operator spacing.  		if (!($line=~/\#\s*include/)) {  			my $ops = qr{ @@ -2532,7 +2775,7 @@ sub process {  			# Flatten any parentheses  			$value =~ s/\(/ \(/g;  			$value =~ s/\)/\) /g; -			while ($value =~ s/\[[^\{\}]*\]/1/ || +			while ($value =~ s/\[[^\[\]]*\]/1/ ||  			       $value !~ /(?:$Ident|-?$Constant)\s*  					     $Compare\s*  					     (?:$Ident|-?$Constant)/x && @@ -2557,28 +2800,6 @@ sub process {  			}  		} -# typecasts on min/max could be min_t/max_t -		if ($line =~ /^\+(?:.*?)\b(min|max)\s*\($Typecast{0,1}($LvalOrFunc)\s*,\s*$Typecast{0,1}($LvalOrFunc)\s*\)/) { -			if (defined $2 || defined $8) { -				my $call = $1; -				my $cast1 = deparenthesize($2); -				my $arg1 = $3; -				my $cast2 = deparenthesize($8); -				my $arg2 = $9; -				my $cast; - -				if ($cast1 ne "" && $cast2 ne "") { -					$cast = "$cast1 or $cast2"; -				} elsif ($cast1 ne "") { -					$cast = $cast1; -				} else { -					$cast = $cast2; -				} -				WARN("MINMAX", -				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . $herecurr); -			} -		} -  # Need a space before open parenthesis after if, while etc  		if ($line=~/\b(if|while|for|switch)\(/) {  			ERROR("SPACING", "space required before the open parenthesis '('\n" . $herecurr); @@ -2587,6 +2808,9 @@ sub process {  # Check for illegal assignment in if conditional -- and check for trailing  # statements after the conditional.  		if ($line =~ /do\s*(?!{)/) { +			($stat, $cond, $line_nr_next, $remain_next, $off_next) = +				ctx_statement_block($linenr, $realcnt, 0) +					if (!defined $stat);  			my ($stat_next) = ctx_statement_block($line_nr_next,  						$remain_next, $off_next);  			$stat_next =~ s/\n./\n /g; @@ -2702,12 +2926,18 @@ sub process {  			}  		} -#studly caps, commented out until figure out how to distinguish between use of existing and adding new -#		if (($line=~/[\w_][a-z\d]+[A-Z]/) and !($line=~/print/)) { -#		    print "No studly caps, use _\n"; -#		    print "$herecurr"; -#		    $clean = 0; -#		} +#CamelCase +		while ($line =~ m{($Constant|$Lval)}g) { +			my $var = $1; +			if ($var !~ /$Constant/ && +			    $var =~ /[A-Z]\w*[a-z]|[a-z]\w*[A-Z]/ && +			    $var !~ /"^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && +			    !defined $camelcase{$var}) { +				$camelcase{$var} = 1; +				WARN("CAMELCASE", +				     "Avoid CamelCase: <$var>\n" . $herecurr); +			} +		}  #no spaces allowed after \ in define  		if ($line=~/\#\s*define.*\\\s$/) { @@ -2742,47 +2972,13 @@ sub process {  			my $cnt = $realcnt;  			my ($off, $dstat, $dcond, $rest);  			my $ctx = ''; - -			my $args = defined($1); - -			# Find the end of the macro and limit our statement -			# search to that. -			while ($cnt > 0 && defined $lines[$ln - 1] && -				$lines[$ln - 1] =~ /^(?:-|..*\\$)/) -			{ -				$ctx .= $rawlines[$ln - 1] . "\n"; -				$cnt-- if ($lines[$ln - 1] !~ /^-/); -				$ln++; -			} -			$ctx .= $rawlines[$ln - 1]; -  			($dstat, $dcond, $ln, $cnt, $off) = -				ctx_statement_block($linenr, $ln - $linenr + 1, 0); +				ctx_statement_block($linenr, $realcnt, 0); +			$ctx = $dstat;  			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";  			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; -			# Extract the remainder of the define (if any) and -			# rip off surrounding spaces, and trailing \'s. -			$rest = ''; -			while ($off != 0 || ($cnt > 0 && $rest =~ /\\\s*$/)) { -				#print "ADDING cnt<$cnt> $off <" . substr($lines[$ln - 1], $off) . "> rest<$rest>\n"; -				if ($off != 0 || $lines[$ln - 1] !~ /^-/) { -					$rest .= substr($lines[$ln - 1], $off) . "\n"; -					$cnt--; -				} -				$ln++; -				$off = 0; -			} -			$rest =~ s/\\\n.//g; -			$rest =~ s/^\s*//s; -			$rest =~ s/\s*$//s; - -			# Clean up the original statement. -			if ($args) { -				substr($dstat, 0, length($dcond), ''); -			} else { -				$dstat =~ s/^.\s*\#\s*define\s+$Ident\s*//; -			} +			$dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//;  			$dstat =~ s/$;//g;  			$dstat =~ s/\\\n.//g;  			$dstat =~ s/^\s*//s; @@ -2791,14 +2987,20 @@ sub process {  			# Flatten any parentheses and braces  			while ($dstat =~ s/\([^\(\)]*\)/1/ ||  			       $dstat =~ s/\{[^\{\}]*\}/1/ || -			       $dstat =~ s/\[[^\{\}]*\]/1/) +			       $dstat =~ s/\[[^\[\]]*\]/1/) +			{ +			} + +			# Flatten any obvious string concatentation. +			while ($dstat =~ s/("X*")\s*$Ident/$1/ || +			       $dstat =~ s/$Ident\s*("X*")/$1/)  			{  			}  			my $exceptions = qr{  				$Declare|  				module_param_named| -				MODULE_PARAM_DESC| +				MODULE_PARM_DESC|  				DECLARE_PER_CPU|  				DEFINE_PER_CPU|  				__typeof__\(| @@ -2808,23 +3010,84 @@ sub process {  				^\"|\"$  			}x;  			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; -			if ($rest ne '' && $rest ne ',') { -				if ($rest !~ /while\s*\(/ && -				    $dstat !~ /$exceptions/) -				{ -					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", -					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$here\n$ctx\n"); +			if ($dstat ne '' && +			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(), +			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo(); +			    $dstat !~ /^[!~-]?(?:$Ident|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo +			    $dstat !~ /^'X'$/ &&					# character constants +			    $dstat !~ /$exceptions/ && +			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo = +			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...) +			    $dstat !~ /^for\s*$Constant$/ &&				# for (...) +			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar() +			    $dstat !~ /^do\s*{/ &&					# do {... +			    $dstat !~ /^\({/)						# ({... +			{ +				$ctx =~ s/\n*$//; +				my $herectx = $here . "\n"; +				my $cnt = statement_rawlines($ctx); + +				for (my $n = 0; $n < $cnt; $n++) { +					$herectx .= raw_line($linenr, $n) . "\n";  				} -			} elsif ($ctx !~ /;/) { -				if ($dstat ne '' && -				    $dstat !~ /^(?:$Ident|-?$Constant)$/ && -				    $dstat !~ /$exceptions/ && -				    $dstat !~ /^\.$Ident\s*=/ && -				    $dstat =~ /$Operators/) -				{ +				if ($dstat =~ /;/) { +					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", +					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); +				} else {  					ERROR("COMPLEX_MACRO", -					      "Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n"); +					      "Macros with complex values should be enclosed in parenthesis\n" . "$herectx"); +				} +			} + +# check for line continuations outside of #defines, preprocessor #, and asm + +		} else { +			if ($prevline !~ /^..*\\$/ && +			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor +			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm +			    $line =~ /^\+.*\\$/) { +				WARN("LINE_CONTINUATIONS", +				     "Avoid unnecessary line continuations\n" . $herecurr); +			} +		} + +# do {} while (0) macro tests: +# single-statement macros do not need to be enclosed in do while (0) loop, +# macro should not end with a semicolon +		if ($^V && $^V ge 5.10.0 && +		    $realfile !~ m@/vmlinux.lds.h$@ && +		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { +			my $ln = $linenr; +			my $cnt = $realcnt; +			my ($off, $dstat, $dcond, $rest); +			my $ctx = ''; +			($dstat, $dcond, $ln, $cnt, $off) = +				ctx_statement_block($linenr, $realcnt, 0); +			$ctx = $dstat; + +			$dstat =~ s/\\\n.//g; + +			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { +				my $stmts = $2; +				my $semis = $3; + +				$ctx =~ s/\n*$//; +				my $cnt = statement_rawlines($ctx); +				my $herectx = $here . "\n"; + +				for (my $n = 0; $n < $cnt; $n++) { +					$herectx .= raw_line($linenr, $n) . "\n"; +				} + +				if (($stmts =~ tr/;/;/) == 1 && +				    $stmts !~ /^\s*(if|while|for|switch)\b/) { +					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", +					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); +				} +				if (defined $semis && $semis ne "") { +					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", +					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");  				}  			}  		} @@ -2846,7 +3109,8 @@ sub process {  			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";  			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";  			if ($#chunks > 0 && $level == 0) { -				my $allowed = 0; +				my @allowed = (); +				my $allow = 0;  				my $seen = 0;  				my $herectx = $here . "\n";  				my $ln = $linenr - 1; @@ -2857,6 +3121,7 @@ sub process {  					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);  					my $offset = statement_rawlines($whitespace) - 1; +					$allowed[$allow] = 0;  					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";  					# We have looked at and allowed this specific line. @@ -2869,23 +3134,34 @@ sub process {  					$seen++ if ($block =~ /^\s*{/); -					#print "cond<$cond> block<$block> allowed<$allowed>\n"; +					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";  					if (statement_lines($cond) > 1) {  						#print "APW: ALLOWED: cond<$cond>\n"; -						$allowed = 1; +						$allowed[$allow] = 1;  					}  					if ($block =~/\b(?:if|for|while)\b/) {  						#print "APW: ALLOWED: block<$block>\n"; -						$allowed = 1; +						$allowed[$allow] = 1;  					}  					if (statement_block_size($block) > 1) {  						#print "APW: ALLOWED: lines block<$block>\n"; -						$allowed = 1; +						$allowed[$allow] = 1;  					} +					$allow++;  				} -				if ($seen && !$allowed) { -					WARN("BRACES", -					     "braces {} are not necessary for any arm of this statement\n" . $herectx); +				if ($seen) { +					my $sum_allowed = 0; +					foreach (@allowed) { +						$sum_allowed += $_; +					} +					if ($sum_allowed == 0) { +						WARN("BRACES", +						     "braces {} are not necessary for any arm of this statement\n" . $herectx); +					} elsif ($sum_allowed != $allow && +						 $seen != $allow) { +						CHK("BRACES", +						    "braces {} should be used on all arms of this statement\n" . $herectx); +					}  				}  			}  		} @@ -2932,11 +3208,11 @@ sub process {  				}  			}  			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { -				my $herectx = $here . "\n";; +				my $herectx = $here . "\n";  				my $cnt = statement_rawlines($block);  				for (my $n = 0; $n < $cnt; $n++) { -					$herectx .= raw_line($linenr, $n) . "\n";; +					$herectx .= raw_line($linenr, $n) . "\n";  				}  				WARN("BRACES", @@ -2944,20 +3220,14 @@ sub process {  			}  		} -# don't include deprecated include files (uses RAW line) -		for my $inc (@dep_includes) { -			if ($rawline =~ m@^.\s*\#\s*include\s*\<$inc>@) { -				ERROR("DEPRECATED_INCLUDE", -				      "Don't use <$inc>: see Documentation/feature-removal-schedule.txt\n" . $herecurr); -			} +# check for unnecessary blank lines around braces +		if (($line =~ /^..*}\s*$/ && $prevline =~ /^.\s*$/)) { +			CHK("BRACES", +			    "Blank lines aren't necessary before a close brace '}'\n" . $hereprev);  		} - -# don't use deprecated functions -		for my $func (@dep_functions) { -			if ($line =~ /\b$func\b/) { -				ERROR("DEPRECATED_FUNCTION", -				      "Don't use $func(): see Documentation/feature-removal-schedule.txt\n" . $herecurr); -			} +		if (($line =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { +			CHK("BRACES", +			    "Blank lines aren't necessary after an open brace '{'\n" . $hereprev);  		}  # no volatiles please @@ -2974,27 +3244,19 @@ sub process {  				$herecurr);  		} -# check for needless kfree() checks -		if ($prevline =~ /\bif\s*\(([^\)]*)\)/) { -			my $expr = $1; -			if ($line =~ /\bkfree\(\Q$expr\E\);/) { -				WARN("NEEDLESS_KFREE", -				     "kfree(NULL) is safe this check is probably not required\n" . $hereprev); -			} -		} -# check for needless usb_free_urb() checks -		if ($prevline =~ /\bif\s*\(([^\)]*)\)/) { -			my $expr = $1; -			if ($line =~ /\busb_free_urb\(\Q$expr\E\);/) { -				WARN("NEEDLESS_USB_FREE_URB", -				     "usb_free_urb(NULL) is safe this check is probably not required\n" . $hereprev); +# check for needless "if (<foo>) fn(<foo>)" uses +		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { +			my $expr = '\s*\(\s*' . quotemeta($1) . '\s*\)\s*;'; +			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?)$expr/) { +				WARN('NEEDLESS_IF', +				     "$1(NULL) is safe this check is probably not required\n" . $hereprev);  			}  		}  # prefer usleep_range over udelay -		if ($line =~ /\budelay\s*\(\s*(\w+)\s*\)/) { +		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {  			# ignore udelay's < 10, however -			if (! (($1 =~ /(\d+)/) && ($1 < 10)) ) { +			if (! ($1 < 10) ) {  				CHK("USLEEP_RANGE",  				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $line);  			} @@ -3075,18 +3337,100 @@ sub process {  			     "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);  		} +# Check for __attribute__ format(printf, prefer __printf +		if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { +			WARN("PREFER_PRINTF", +			     "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr); +		} + +# Check for __attribute__ format(scanf, prefer __scanf +		if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { +			WARN("PREFER_SCANF", +			     "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr); +		} +  # check for sizeof(&)  		if ($line =~ /\bsizeof\s*\(\s*\&/) {  			WARN("SIZEOF_ADDRESS",  			     "sizeof(& should be avoided\n" . $herecurr);  		} +# check for sizeof without parenthesis +		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { +			WARN("SIZEOF_PARENTHESIS", +			     "sizeof $1 should be sizeof($1)\n" . $herecurr); +		} +  # check for line continuations in quoted strings with odd counts of "  		if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) {  			WARN("LINE_CONTINUATIONS",  			     "Avoid line continuations in quoted strings\n" . $herecurr);  		} +# check for struct spinlock declarations +		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { +			WARN("USE_SPINLOCK_T", +			     "struct spinlock should be spinlock_t\n" . $herecurr); +		} + +# Check for misused memsets +		if ($^V && $^V ge 5.10.0 && +		    defined $stat && +		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/s) { + +			my $ms_addr = $2; +			my $ms_val = $7; +			my $ms_size = $12; + +			if ($ms_size =~ /^(0x|)0$/i) { +				ERROR("MEMSET", +				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); +			} elsif ($ms_size =~ /^(0x|)1$/i) { +				WARN("MEMSET", +				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); +			} +		} + +# typecasts on min/max could be min_t/max_t +		if ($^V && $^V ge 5.10.0 && +		    defined $stat && +		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { +			if (defined $2 || defined $7) { +				my $call = $1; +				my $cast1 = deparenthesize($2); +				my $arg1 = $3; +				my $cast2 = deparenthesize($7); +				my $arg2 = $8; +				my $cast; + +				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { +					$cast = "$cast1 or $cast2"; +				} elsif ($cast1 ne "") { +					$cast = $cast1; +				} else { +					$cast = $cast2; +				} +				WARN("MINMAX", +				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); +			} +		} + +# check usleep_range arguments +		if ($^V && $^V ge 5.10.0 && +		    defined $stat && +		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { +			my $min = $1; +			my $max = $7; +			if ($min eq $max) { +				WARN("USLEEP_RANGE", +				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); +			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && +				 $min > $max) { +				WARN("USLEEP_RANGE", +				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); +			} +		} +  # check for new externs in .c files.  		if ($realfile =~ /\.c$/ && defined $stat &&  		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) @@ -3133,16 +3477,30 @@ sub process {  			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);  		} +# check for alloc argument mismatch +		if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { +			WARN("ALLOC_ARRAY_ARGS", +			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); +		} +  # check for multiple semicolons  		if ($line =~ /;\s*;\s*$/) { -		    WARN("ONE_SEMICOLON", -			 "Statements terminations use 1 semicolon\n" . $herecurr); +			WARN("ONE_SEMICOLON", +			     "Statements terminations use 1 semicolon\n" . $herecurr);  		} -# check for whitespace before semicolon - not allowed at end-of-line -		if ($line =~ /\s+;$/) { -		    WARN("SPACEBEFORE_SEMICOLON", -			 "Whitespace before semicolon\n" . $herecurr); +# check for switch/default statements without a break; +		if ($^V && $^V ge 5.10.0 && +		    defined $stat && +		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { +			my $ctx = ''; +			my $herectx = $here . "\n"; +			my $cnt = statement_rawlines($stat); +			for (my $n = 0; $n < $cnt; $n++) { +				$herectx .= raw_line($linenr, $n) . "\n"; +			} +			WARN("DEFAULT_NO_BREAK", +			     "switch default: should use break\n" . $herectx);  		}  # check for gcc specific __FUNCTION__ @@ -3151,22 +3509,30 @@ sub process {  			     "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr);  		} +# check for use of yield() +		if ($line =~ /\byield\s*\(\s*\)/) { +			WARN("YIELD", +			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr); +		} +  # check for semaphores initialized locked  		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {  			WARN("CONSIDER_COMPLETION",  			     "consider using a completion\n" . $herecurr); -  		} -# recommend kstrto* over simple_strto* -		if ($line =~ /\bsimple_(strto.*?)\s*\(/) { + +# recommend kstrto* over simple_strto* and strict_strto* +		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {  			WARN("CONSIDER_KSTRTO", -			     "consider using kstrto* in preference to simple_$1\n" . $herecurr); +			     "$1 is obsolete, use k$3 instead\n" . $herecurr);  		} +  # check for __initcall(), use device_initcall() explicitly please  		if ($line =~ /^.\s*__initcall\s*\(/) {  			WARN("USE_DEVICE_INITCALL",  			     "please use device_initcall() instead of __initcall()\n" . $herecurr);  		} +  # check for various ops structs, ensure they are const.  		my $struct_ops = qr{acpi_dock_ops|  				address_space_operations| @@ -3264,12 +3630,6 @@ sub process {  			WARN("EXPORTED_WORLD_WRITABLE",  			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);  		} - -		# Check for memset with swapped arguments -		if ($line =~ /memset.*\,(\ |)(0x|)0(\ |0|)\);/) { -			ERROR("MEMSET", -			      "memset size is 3rd argument, not the second.\n" . $herecurr); -		}  	}  	# If we have no input at all, then there is nothing to report on @@ -3309,6 +3669,12 @@ sub process {  	}  	if ($quiet == 0) { + +		if ($^V lt 5.10.0) { +			print("NOTE: perl $^V is not modern enough to detect all possible issues.\n"); +			print("An upgrade to at least perl v5.10.0 is suggested.\n\n"); +		} +  		# If there were whitespace errors which cleanpatch can fix  		# then suggest that.  		if ($rpt_cleaners) { @@ -3318,13 +3684,12 @@ sub process {  		}  	} -	if (keys %ignore_type) { +	if ($quiet == 0 && keys %ignore_type) {  	    print "NOTE: Ignored message types:";  	    foreach my $ignore (sort keys %ignore_type) {  		print " $ignore";  	    } -	    print "\n"; -	    print "\n" if ($quiet == 0); +	    print "\n\n";  	}  	if ($clean == 1 && $quiet == 0) { |