3566 lines · 95.2 KB · Perl
RawDownload
			if ($err ne '') {				ERROR("SWITCH_CASE_INDENT_LEVEL",				      "switch and case should be at the same indent\n$hereline$err");			}		} # if/while/etc brace do not go on next line, unless defining a do while loop,# or if that brace on the next line is for something else		if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {			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); 			my $ctx_ln = $linenr;			my $ctx_skip = $realcnt; 			while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&					defined $lines[$ctx_ln - 1] &&					$lines[$ctx_ln - 1] =~ /^-/)) {				##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";				$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);				$ctx_ln++;			} 			#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";			#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 			if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {				ERROR("OPEN_BRACE",				      "that open brace { should be on the previous line\n" .					"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");			}			if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&			    $ctx =~ /\)\s*\;\s*$/ &&			    defined $lines[$ctx_ln - 1])			{				my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);				if ($nindent > $indent) {					WARN("TRAILING_SEMICOLON",					     "trailing semicolon indicates no statements, indent implies otherwise\n" .						"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");				}			}		} # 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), ''); 			# Make sure we remove the line prefixes as we have			# none on the first line, and are going to readd them			# where necessary.			$s =~ s/\n./\n/gs; 			# Find out how long the conditional actually is.			my @newlines = ($c =~ /\n/gs);			my $cond_lines = 1 + $#newlines; 			# We want to check the first line inside the block			# starting at the end of the conditional, so remove:			#  1) any blank line termination			#  2) any opening brace { on end of the line			#  3) any do (...) {			my $continuation = 0;			my $check = 0;			$s =~ s/^.*\bdo\b//;			$s =~ s/^\s*{//;			if ($s =~ s/^\s*\\//) {				$continuation = 1;			}			if ($s =~ s/^\s*?\n//) {				$check = 1;				$cond_lines++;			} 			# Also ignore a loop construct at the end of a			# preprocessor statement.			if (($prevline =~ /^.\s*#\s*define\s/ ||			    $prevline =~ /\\\s*$/) && $continuation == 0) {				$check = 0;			} 			my $cond_ptr = -1;			$continuation = 0;			while ($cond_ptr != $cond_lines) {				$cond_ptr = $cond_lines; 				# If we see an #else/#elif then the code				# is not linear.				if ($s =~ /^\s*\#\s*(?:else|elif)/) {					$check = 0;				} 				# Ignore:				#  1) blank lines, they should be at 0,				#  2) preprocessor lines, and				#  3) labels.				if ($continuation ||				    $s =~ /^\s*?\n/ ||				    $s =~ /^\s*#\s*?/ ||				    $s =~ /^\s*$Ident\s*:/) {					$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;					if ($s =~ s/^.*?\n//) {						$cond_lines++;					}				}			} 			my (undef, $sindent) = line_stats("+" . $s);			my $stat_real = raw_line($linenr, $cond_lines); 			# Check if either of these lines are modified, else			# this is not this patch's fault.			if (!defined($stat_real) ||			    $stat !~ /^\+/ && $stat_real !~ /^\+/) {				$check = 0;			}			if (defined($stat_real) && $cond_lines > 1) {				$stat_real = "[...]\n$stat_real";			} 			#print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n"; 			if ($check && (($sindent % 8) != 0 ||			    ($sindent <= $indent && $s ne ''))) {				WARN("SUSPECT_CODE_INDENT",				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");			}		} 		# Track the 'values' across context and added lines.		my $opline = $line; $opline =~ s/^./ /;		my ($curr_values, $curr_vars) =				annotate_values($opline . "\n", $prev_values);		$curr_values = $prev_values . $curr_values;		if ($dbg_values) {			my $outline = $opline; $outline =~ s/\t/ /g;			print "$linenr > .$outline\n";			print "$linenr > $curr_values\n";			print "$linenr >  $curr_vars\n";		}		$prev_values = substr($curr_values, -1); #ignore lines not being added		if ($line=~/^[^\+]/) {next;} # TEST: allow direct testing of the type matcher.		if ($dbg_type) {			if ($line =~ /^.\s*$Declare\s*$/) {				ERROR("TEST_TYPE",				      "TEST: is type\n" . $herecurr);			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {				ERROR("TEST_NOT_TYPE",				      "TEST: is not type ($1 is)\n". $herecurr);			}			next;		}# TEST: allow direct testing of the attribute matcher.		if ($dbg_attr) {			if ($line =~ /^.\s*$Modifier\s*$/) {				ERROR("TEST_ATTR",				      "TEST: is attr\n" . $herecurr);			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {				ERROR("TEST_NOT_ATTR",				      "TEST: is not attr ($1 is)\n". $herecurr);			}			next;		} # check for initialisation to aggregates open brace on the next line		if ($line =~ /^.\s*{/ &&		    $prevline =~ /(?:^|[^=])=\s*$/) {			ERROR("OPEN_BRACE",			      "that open brace { should be on the previous line\n" . $hereprev);		} ## Checks which are anchored on the added line.# # check for malformed paths in #include statements (uses RAW line)		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {			my $path = $1;			if ($path =~ m{//}) {				ERROR("MALFORMED_INCLUDE",				      "malformed #include filename\n" .					$herecurr);			}		} # no C99 // comments		if ($line =~ m{//}) {			ERROR("C99_COMMENTS",			      "do not use C99 // comments\n" . $herecurr);		}		# Remove C99 comments.		$line =~ s@//.*@@;		$opline =~ s@//.*@@; # EXPORT_SYMBOL should immediately follow the thing it is exporting, consider# the whole statement.#print "APW <$lines[$realline_next - 1]>\n";		if (defined $realline_next &&		    exists $lines[$realline_next - 1] &&		    !defined $suppress_export{$realline_next} &&		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||		     $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {			# Handle definitions which produce identifiers with			# a prefix:			#   XXX(foo);			#   EXPORT_SYMBOL(something_foo);			my $name = $1;			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&			    $name =~ /^${Ident}_$2/) {#print "FOO C name<$name>\n";				$suppress_export{$realline_next} = 1; 			} elsif ($stat !~ /(?:				\n.}\s*$|				^.DEFINE_$Ident\(\Q$name\E\)|				^.DECLARE_$Ident\(\Q$name\E\)|				^.LIST_HEAD\(\Q$name\E\)|				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()			    )/x) {#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";				$suppress_export{$realline_next} = 2;			} else {				$suppress_export{$realline_next} = 1;			}		}		if (!defined $suppress_export{$linenr} &&		    $prevline =~ /^.\s*$/ &&		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||		     $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {#print "FOO B <$lines[$linenr - 1]>\n";			$suppress_export{$linenr} = 2;		}		if (defined $suppress_export{$linenr} &&		    $suppress_export{$linenr} == 2) {			WARN("EXPORT_SYMBOL",			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);		} # check for global initialisers.		if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) {			ERROR("GLOBAL_INITIALISERS",			      "do not initialise globals to 0 or NULL\n" .				$herecurr);		}# check for static initialisers.		if ($line =~ /\bstatic\s.*=\s*(0|NULL|false)\s*;/) {			ERROR("INITIALISED_STATIC",			      "do not initialise statics to 0 or NULL\n" .				$herecurr);		} # check for static const char * arrays.		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {			WARN("STATIC_CONST_CHAR_ARRAY",			     "static const char * array should probably be static const char * const\n" .				$herecurr);               } # check for static char foo[] = "bar" declarations.		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {			WARN("STATIC_CONST_CHAR_ARRAY",			     "static char array declaration should probably be static const char\n" .				$herecurr);               } # check for declarations of struct pci_device_id		if ($line =~ /\bstruct\s+pci_device_id\s+\w+\s*\[\s*\]\s*\=\s*\{/) {			WARN("DEFINE_PCI_DEVICE_TABLE",			     "Use DEFINE_PCI_DEVICE_TABLE for struct pci_device_id\n" . $herecurr);		} # check for new typedefs, only function parameters and sparse annotations# make sense.		if ($line =~ /\btypedef\s/ &&		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&		    $line !~ /\b$typeTypedefs\b/ &&		    $line !~ /\b__bitwise(?:__|)\b/) {			WARN("NEW_TYPEDEFS",			     "do not add new typedefs\n" . $herecurr);		} # * goes on variable not on type		# (char*[ const])		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/;			# Should not end with a space.			$to =~ s/\s+$//;			# '*'s should not have spaces between.			while ($to =~ s/\*\s+\*/\*\*/) {			} 			#print "from<$from> to<$to>\n";			if ($from ne $to) {				ERROR("POINTER_LOCATION",				      "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr);			}		}		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/;			# Should not end with a space.			$to =~ s/\s+$//;			# '*'s should not have spaces between.			while ($to =~ s/\*\s+\*/\*\*/) {			}			# Modifiers should have spaces.			$to =~ s/(\b$Modifier$)/$1 /; 			#print "from<$from> to<$to> ident<$ident>\n";			if ($from ne $to && $ident !~ /^$Modifier$/) {				ERROR("POINTER_LOCATION",				      "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr);			}		} # # no BUG() or BUG_ON()# 		if ($line =~ /\b(BUG|BUG_ON)\b/) {# 			print "Try to use WARN_ON & Recovery code rather than BUG() or BUG_ON()\n";# 			print "$herecurr";# 			$clean = 0;# 		} 		if ($line =~ /\bLINUX_VERSION_CODE\b/) {			WARN("LINUX_VERSION_CODE",			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);		} # check for uses of printk_ratelimit		if ($line =~ /\bprintk_ratelimit\s*\(/) {			WARN("PRINTK_RATELIMITED","Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);		} # printk should use KERN_* levels.  Note that follow on printk's on the# same line do not need a level, so we use the current block context# to try and find and validate the current printk.  In summary the current# printk includes all preceding printk's which have no newline on the end.# we assume the first bad printk is the one to report.		if ($line =~ /\bprintk\((?!KERN_)\s*"/) {			my $ok = 0;			for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) {				#print "CHECK<$lines[$ln - 1]\n";				# we have a preceding printk if it ends				# with "\n" ignore it, else it is to blame				if ($lines[$ln - 1] =~ m{\bprintk\(}) {					if ($rawlines[$ln - 1] !~ m{\\n"}) {						$ok = 1;					}					last;				}			}			if ($ok == 0) {				WARN("PRINTK_WITHOUT_KERN_LEVEL",				     "printk() should include KERN_ facility level\n" . $herecurr);			}		} 		if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) {			my $orig = $1;			my $level = lc($orig);			$level = "warn" if ($level eq "warning");			WARN("PREFER_PR_LEVEL",			     "Prefer pr_$level(... to printk(KERN_$1, ...\n" . $herecurr);		} 		if ($line =~ /\bpr_warning\s*\(/) {			WARN("PREFER_PR_LEVEL",			     "Prefer pr_warn(... to pr_warning(...\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		    !($line=~/\#\s*define.*do\s{/) and !($line=~/}/)) {			ERROR("OPEN_BRACE",			      "open brace '{' following function declarations go on the next line\n" . $herecurr);		} # open braces for enum, union and struct go on the same line.		if ($line =~ /^.\s*{/ &&		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {			ERROR("OPEN_BRACE",			      "open brace '{' following $1 go on the same line\n" . $hereprev);		} # missing space after union, struct or enum definition		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?(?:\s+$Ident)?[=\{]/) {		    WARN("SPACING",			 "missing space after $1 definition\n" . $herecurr);		} # check for spacing round square brackets; allowed:#  1. with a type on the left -- int [] a;#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,#  3. inside a curly brace -- = { [0...10] = 5 }		while ($line =~ /(.*?\s)\[/g) {			my ($where, $prefix) = ($-[1], $1);			if ($prefix !~ /$Type\s+$/ &&			    ($where != 0 || $prefix !~ /^.\s+$/) &&			    $prefix !~ /[{,]\s+$/) {				ERROR("BRACKET_SPACE",				      "space prohibited before open square bracket '['\n" . $herecurr);			}		} # check for spaces between functions and their parentheses.		while ($line =~ /($Ident)\s+\(/g) {			my $name = $1;			my $ctx_before = substr($line, 0, $-[1]);			my $ctx = "$ctx_before$name"; 			# Ignore those directives where spaces _are_ permitted.			if ($name =~ /^(?:				if|for|while|switch|return|case|				volatile|__volatile__|				__attribute__|format|__extension__|				asm|__asm__)$/x)			{ 			# cpp #define statements have non-optional spaces, ie			# if there is a space between the name and the open			# parenthesis it is simply not a parameter group.			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 			# cpp #elif statement condition may start with a (			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 			# If this whole things ends with a type its most			# likely a typedef for a function.			} elsif ($ctx =~ /$Type$/) { 			} else {				WARN("SPACING",				     "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{				<<=|>>=|<=|>=|==|!=|				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|				=>|->|<<|>>|<|>|=|!|~|				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|				\?|:			}x;			my @elements = split(/($ops|;)/, $opline);			my $off = 0; 			my $blank = copy_spacing($opline); 			for (my $n = 0; $n < $#elements; $n += 2) {				$off += length($elements[$n]); 				# Pick up the preceding and succeeding characters.				my $ca = substr($opline, 0, $off);				my $cc = '';				if (length($opline) >= ($off + length($elements[$n + 1]))) {					$cc = substr($opline, $off + length($elements[$n + 1]));				}				my $cb = "$ca$;$cc"; 				my $a = '';				$a = 'V' if ($elements[$n] ne '');				$a = 'W' if ($elements[$n] =~ /\s$/);				$a = 'C' if ($elements[$n] =~ /$;$/);				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);

Lines 2001–2500 of 3566. Previous lines