6972 lines · 205.6 KB · Perl
RawDownload
					$newcomp = ">=";				} elsif ($comp eq ">") {					$newcomp = "<";				} elsif ($comp eq ">=") {					$newcomp = "<=";				}				$fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;			}		} # Return of what appears to be an errno should normally be negative		if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {			my $name = $1;			if ($name ne 'EOF' && $name ne 'ERROR') {				WARN("USE_NEGATIVE_ERRNO",				     "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);			}		} # Need a space before open parenthesis after if, while etc		if ($line =~ /\b(if|while|for|switch)\(/) {			if (ERROR("SPACING",				  "space required before the open parenthesis '('\n" . $herecurr) &&			    $fix) {				$fixed[$fixlinenr] =~				    s/\b(if|while|for|switch)\(/$1 \(/;			}		} # 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;			##print "stat<$stat> stat_next<$stat_next>\n"; 			if ($stat_next =~ /^\s*while\b/) {				# If the statement carries leading newlines,				# then count those as offsets.				my ($whitespace) =					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);				my $offset =					statement_rawlines($whitespace) - 1; 				$suppress_whiletrailers{$line_nr_next +								$offset} = 1;			}		}		if (!defined $suppress_whiletrailers{$linenr} &&		    defined($stat) && defined($cond) &&		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {			my ($s, $c) = ($stat, $cond); 			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {				if (ERROR("ASSIGN_IN_IF",					  "do not use assignment in if condition\n" . $herecurr) &&				    $fix && $perl_version_ok) {					if ($rawline =~ /^\+(\s+)if\s*\(\s*(\!)?\s*\(\s*(($Lval)\s*=\s*$LvalOrFunc)\s*\)\s*(?:($Compare)\s*($FuncArg))?\s*\)\s*(\{)?\s*$/) {						my $space = $1;						my $not = $2;						my $statement = $3;						my $assigned = $4;						my $test = $8;						my $against = $9;						my $brace = $15;						fix_delete_line($fixlinenr, $rawline);						fix_insert_line($fixlinenr, "$space$statement;");						my $newline = "${space}if (";						$newline .= '!' if defined($not);						$newline .= '(' if (defined $not && defined($test) && defined($against));						$newline .= "$assigned";						$newline .= " $test $against" if (defined($test) && defined($against));						$newline .= ')' if (defined $not && defined($test) && defined($against));						$newline .= ')';						$newline .= " {" if (defined($brace));						fix_insert_line($fixlinenr + 1, $newline);					}				}			} 			# Find out what is on the end of the line after the			# conditional.			substr($s, 0, length($c), '');			$s =~ s/\n.*//g;			$s =~ s/$;//g;	# Remove any comments			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&			    $c !~ /}\s*while\s*/)			{				# Find out how long the conditional actually is.				my @newlines = ($c =~ /\n/gs);				my $cond_lines = 1 + $#newlines;				my $stat_real = ''; 				$stat_real = raw_line($linenr, $cond_lines)							. "\n" if ($cond_lines);				if (defined($stat_real) && $cond_lines > 1) {					$stat_real = "[...]\n$stat_real";				} 				ERROR("TRAILING_STATEMENTS",				      "trailing statements should be on next line\n" . $herecurr . $stat_real);			}		} # Check for bitwise tests written as boolean		if ($line =~ /			(?:				(?:\[|\(|\&\&|\|\|)				\s*0[xX][0-9]+\s*				(?:\&\&|\|\|)			|				(?:\&\&|\|\|)				\s*0[xX][0-9]+\s*				(?:\&\&|\|\||\)|\])			)/x)		{			WARN("HEXADECIMAL_BOOLEAN_TEST",			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);		} # if and else should not have general statements after it		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {			my $s = $1;			$s =~ s/$;//g;	# Remove any comments			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {				ERROR("TRAILING_STATEMENTS",				      "trailing statements should be on next line\n" . $herecurr);			}		}# if should not continue a brace		if ($line =~ /}\s*if\b/) {			ERROR("TRAILING_STATEMENTS",			      "trailing statements should be on next line (or did you mean 'else if'?)\n" .				$herecurr);		}# case and default should not have general statements after them		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&		    $line !~ /\G(?:			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|			\s*return\s+		    )/xg)		{			ERROR("TRAILING_STATEMENTS",			      "trailing statements should be on next line\n" . $herecurr);		} 		# Check for }<nl>else {, these must be at the same		# indent level to be relevant to each other.		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&		    $previndent == $indent) {			if (ERROR("ELSE_AFTER_BRACE",				  "else should follow close brace '}'\n" . $hereprev) &&			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {				fix_delete_line($fixlinenr - 1, $prevrawline);				fix_delete_line($fixlinenr, $rawline);				my $fixedline = $prevrawline;				$fixedline =~ s/}\s*$//;				if ($fixedline !~ /^\+\s*$/) {					fix_insert_line($fixlinenr, $fixedline);				}				$fixedline = $rawline;				$fixedline =~ s/^(.\s*)else/$1} else/;				fix_insert_line($fixlinenr, $fixedline);			}		} 		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&		    $previndent == $indent) {			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 			# Find out what is on the end of the line after the			# conditional.			substr($s, 0, length($c), '');			$s =~ s/\n.*//g; 			if ($s =~ /^\s*;/) {				if (ERROR("WHILE_AFTER_BRACE",					  "while should follow close brace '}'\n" . $hereprev) &&				    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {					fix_delete_line($fixlinenr - 1, $prevrawline);					fix_delete_line($fixlinenr, $rawline);					my $fixedline = $prevrawline;					my $trailing = $rawline;					$trailing =~ s/^\+//;					$trailing = trim($trailing);					$fixedline =~ s/}\s*$/} $trailing/;					fix_insert_line($fixlinenr, $fixedline);				}			}		} #Specific variable tests		while ($line =~ m{($Constant|$Lval)}g) {			my $var = $1; #CamelCase			if ($var !~ /^$Constant$/ &&			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&#Ignore Page<foo> variants			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&#Ignore SI style variants like nS, mV and dB#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)			    $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&#Ignore some three character SI units explicitly, like MiB and KHz			    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {				while ($var =~ m{($Ident)}g) {					my $word = $1;					next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);					if ($check) {						seed_camelcase_includes();						if (!$file && !$camelcase_file_seeded) {							seed_camelcase_file($realfile);							$camelcase_file_seeded = 1;						}					}					if (!defined $camelcase{$word}) {						$camelcase{$word} = 1;						CHK("CAMELCASE",						    "Avoid CamelCase: <$word>\n" . $herecurr);					}				}			}		} #no spaces allowed after \ in define		if ($line =~ /\#\s*define.*\\\s+$/) {			if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",				 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&			    $fix) {				$fixed[$fixlinenr] =~ s/\s+$//;			}		} # warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes# itself <asm/foo.h> (uses RAW line)		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {			my $file = "$1.h";			my $checkfile = "include/linux/$file";			if (-f "$root/$checkfile" &&			    $realfile ne $checkfile &&			    $1 !~ /$allowed_asm_includes/)			{				my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;				if ($asminclude > 0) {					if ($realfile =~ m{^arch/}) {						CHK("ARCH_INCLUDE_LINUX",						    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);					} else {						WARN("INCLUDE_LINUX",						     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);					}				}			}		} # multi-statement macros should be enclosed in a do while loop, grab the# first statement and ensure its the whole macro if its not enclosed# in a known good container		if ($realfile !~ m@/vmlinux.lds.h$@ &&		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {			my $ln = $linenr;			my $cnt = $realcnt;			my ($off, $dstat, $dcond, $rest);			my $ctx = '';			my $has_flow_statement = 0;			my $has_arg_concat = 0;			($dstat, $dcond, $ln, $cnt, $off) =				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"; 			$has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);			$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/); 			$dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;			my $define_args = $1;			my $define_stmt = $dstat;			my @def_args = (); 			if (defined $define_args && $define_args ne "") {				$define_args = substr($define_args, 1, length($define_args) - 2);				$define_args =~ s/\s*//g;				$define_args =~ s/\\\+?//g;				@def_args = split(",", $define_args);			} 			$dstat =~ s/$;//g;			$dstat =~ s/\\\n.//g;			$dstat =~ s/^\s*//s;			$dstat =~ s/\s*$//s; 			# Flatten any parentheses and braces			while ($dstat =~ s/\([^\(\)]*\)/1/ ||			       $dstat =~ s/\{[^\{\}]*\}/1/ ||			       $dstat =~ s/.\[[^\[\]]*\]/1/)			{			} 			# Flatten any obvious string concatenation.			while ($dstat =~ s/($String)\s*$Ident/$1/ ||			       $dstat =~ s/$Ident\s*($String)/$1/)			{			} 			# Make asm volatile uses seem like a generic function			$dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g; 			my $exceptions = qr{				$Declare|				module_param_named|				MODULE_PARM_DESC|				DECLARE_PER_CPU|				DEFINE_PER_CPU|				__typeof__\(|				union|				struct|				\.$Ident\s*=\s*|				^\"|\"$|				^\[			}x;			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 			$ctx =~ s/\n*$//;			my $stmt_cnt = statement_rawlines($ctx);			my $herectx = get_stat_here($linenr, $stmt_cnt, $here); 			if ($dstat ne '' &&			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz			    $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ &&			# character constants			    $dstat !~ /$exceptions/ &&			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #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*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)			{				if ($dstat =~ /^\s*if\b/) {					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",					      "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");				} elsif ($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 parentheses\n" . "$herectx");				} 			} 			# Make $define_stmt single line, comment-free, etc			my @stmt_array = split('\n', $define_stmt);			my $first = 1;			$define_stmt = "";			foreach my $l (@stmt_array) {				$l =~ s/\\$//;				if ($first) {					$define_stmt = $l;					$first = 0;				} elsif ($l =~ /^[\+ ]/) {					$define_stmt .= substr($l, 1);				}			}			$define_stmt =~ s/$;//g;			$define_stmt =~ s/\s+/ /g;			$define_stmt = trim($define_stmt); # check if any macro arguments are reused (ignore '...' and 'type')			foreach my $arg (@def_args) {			        next if ($arg =~ /\.\.\./);			        next if ($arg =~ /^type$/i);				my $tmp_stmt = $define_stmt;				$tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;				$tmp_stmt =~ s/\#+\s*$arg\b//g;				$tmp_stmt =~ s/\b$arg\s*\#\#//g;				my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;				if ($use_cnt > 1) {					CHK("MACRO_ARG_REUSE",					    "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");				    }# check if any macro arguments may have other precedence issues				if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&				    ((defined($1) && $1 ne ',') ||				     (defined($2) && $2 ne ','))) {					CHK("MACRO_ARG_PRECEDENCE",					    "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");				}			} # check for macros with flow control, but without ## concatenation# ## concatenation is commonly a macro that defines a function so ignore those			if ($has_flow_statement && !$has_arg_concat) {				my $cnt = statement_rawlines($ctx);				my $herectx = get_stat_here($linenr, $cnt, $here); 				WARN("MACRO_WITH_FLOW_CONTROL",				     "Macros with flow control statements should be avoided\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 ($perl_version_ok &&		    $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;			$dstat =~ s/$;/ /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 = get_stat_here($linenr, $cnt, $here); 				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");				}			} elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {				$ctx =~ s/\n*$//;				my $cnt = statement_rawlines($ctx);				my $herectx = get_stat_here($linenr, $cnt, $here); 				WARN("TRAILING_SEMICOLON",				     "macros should not use a trailing semicolon\n" . "$herectx");			}		} # check for redundant bracing round if etc		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {			my ($level, $endln, @chunks) =				ctx_statement_full($linenr, $realcnt, 1);			#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 = ();				my $allow = 0;				my $seen = 0;				my $herectx = $here . "\n";				my $ln = $linenr - 1;				for my $chunk (@chunks) {					my ($cond, $block) = @{$chunk}; 					# If the condition carries leading newlines, then count those as offsets.					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.					$suppress_ifbraces{$ln + $offset} = 1; 					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";					$ln += statement_rawlines($block) - 1; 					substr($block, 0, length($cond), ''); 					$seen++ if ($block =~ /^\s*{/); 					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";					if (statement_lines($cond) > 1) {						#print "APW: ALLOWED: cond<$cond>\n";						$allowed[$allow] = 1;

Lines 5001–5500 of 6972. Previous lines