diff options
Diffstat (limited to 'scripts/checkpatch.pl')
| -rwxr-xr-x | scripts/checkpatch.pl | 114 | 
1 files changed, 91 insertions, 23 deletions
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 3a225d078e75..2287a0bca863 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -57,7 +57,7 @@ my $codespell = 0;  my $codespellfile = "/usr/share/codespell/dictionary.txt";  my $conststructsfile = "$D/const_structs.checkpatch";  my $typedefsfile = ""; -my $color = 1; +my $color = "auto";  my $allow_c99_comments = 1;  sub help { @@ -116,7 +116,8 @@ Options:                               (default:/usr/share/codespell/dictionary.txt)    --codespellfile            Use this codespell dictionary    --typedefsfile             Read additional types from this file -  --color                    Use colors when output is STDOUT (default: on) +  --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. @@ -182,6 +183,14 @@ if (-f $conf) {  	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 arguments +foreach (@ARGV) { +	if ($_ eq "--color" || $_ eq "-color") { +		$_ = "--color=$color"; +	} +} +  GetOptions(  	'q|quiet+'	=> \$quiet,  	'tree!'		=> \$tree, @@ -212,7 +221,9 @@ GetOptions(  	'codespell!'	=> \$codespell,  	'codespellfile=s'	=> \$codespellfile,  	'typedefsfile=s'	=> \$typedefsfile, -	'color!'	=> \$color, +	'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); @@ -238,6 +249,18 @@ if ($#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) = @_; @@ -733,7 +756,7 @@ our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};  our $declaration_macros = qr{(?x:  	(?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(| -	(?:$Storage\s+)?LIST_HEAD\s*\(| +	(?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|  	(?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(  )}; @@ -867,6 +890,7 @@ sub git_commit_info {  #		    echo "commit $(cut -c 1-12,41-)"  #		done  	} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) { +		$id = undef;  	} else {  		$id = substr($lines[0], 0, 12);  		$desc = substr($lines[0], 41); @@ -1882,7 +1906,7 @@ sub report {  		return 0;  	}  	my $output = ''; -	if (-t STDOUT && $color) { +	if ($color) {  		if ($level eq 'ERROR') {  			$output .= RED;  		} elsif ($level eq 'WARNING') { @@ -1893,10 +1917,10 @@ sub report {  	}  	$output .= $prefix . $level . ':';  	if ($show_types) { -		$output .= BLUE if (-t STDOUT && $color); +		$output .= BLUE if ($color);  		$output .= "$type:";  	} -	$output .= RESET if (-t STDOUT && $color); +	$output .= RESET if ($color);  	$output .= ' ' . $msg . "\n";  	if ($showfile) { @@ -2606,7 +2630,8 @@ sub process {  			($id, $description) = git_commit_info($orig_commit,  							      $id, $orig_desc); -			if ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens) { +			if (defined($id) && +			   ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) {  				ERROR("GIT_COMMIT_ID",  				      "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);  			} @@ -2776,6 +2801,17 @@ sub process {  			#print "is_start<$is_start> is_end<$is_end> length<$length>\n";  		} +# check for MAINTAINERS entries that don't have the right form +		if ($realfile =~ /^MAINTAINERS$/ && +		    $rawline =~ /^\+[A-Z]:/ && +		    $rawline !~ /^\+[A-Z]:\t\S/) { +			if (WARN("MAINTAINERS_STYLE", +				 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) && +			    $fix) { +				$fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/; +			} +		} +  # discourage the use of boolean for type definition attributes of Kconfig options  		if ($realfile =~ /Kconfig/ &&  		    $line =~ /^\+\s*\bboolean\b/) { @@ -2957,7 +2993,7 @@ sub process {  # check multi-line statement indentation matches previous line  		if ($^V && $^V ge 5.10.0 && -		    $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|$Ident\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { +		    $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {  			$prevline =~ /^\+(\t*)(.*)$/;  			my $oldindent = $1;  			my $rest = $2; @@ -3208,7 +3244,7 @@ sub process {  		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,  		    $realline_next);  #print "LINE<$line>\n"; -		if ($linenr >= $suppress_statement && +		if ($linenr > $suppress_statement &&  		    $realcnt && $sline =~ /.\s*\S/) {  			($stat, $cond, $line_nr_next, $remain_next, $off_next) =  				ctx_statement_block($linenr, $realcnt, 0); @@ -3542,7 +3578,7 @@ sub process {  				$fixedline =~ s/\s*=\s*$/ = {/;  				fix_insert_line($fixlinenr, $fixedline);  				$fixedline = $line; -				$fixedline =~ s/^(.\s*){\s*/$1/; +				$fixedline =~ s/^(.\s*)\{\s*/$1/;  				fix_insert_line($fixlinenr, $fixedline);  			}  		} @@ -3883,7 +3919,7 @@ sub process {  				my $fixedline = rtrim($prevrawline) . " {";  				fix_insert_line($fixlinenr, $fixedline);  				$fixedline = $rawline; -				$fixedline =~ s/^(.\s*){\s*/$1\t/; +				$fixedline =~ s/^(.\s*)\{\s*/$1\t/;  				if ($fixedline !~ /^\+\s*$/) {  					fix_insert_line($fixlinenr, $fixedline);  				} @@ -4372,7 +4408,7 @@ sub process {  			if (ERROR("SPACING",  				  "space required before the open brace '{'\n" . $herecurr) &&  			    $fix) { -				$fixed[$fixlinenr] =~ s/^(\+.*(?:do|\))){/$1 {/; +				$fixed[$fixlinenr] =~ s/^(\+.*(?:do|\)))\{/$1 {/;  			}  		} @@ -4904,17 +4940,17 @@ sub process {  			foreach my $arg (@def_args) {  			        next if ($arg =~ /\.\.\./);  			        next if ($arg =~ /^type$/i); -				my $tmp = $define_stmt; -				$tmp =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; -				$tmp =~ s/\#+\s*$arg\b//g; -				$tmp =~ s/\b$arg\s*\#\#//g; -				my $use_cnt = $tmp =~ s/\b$arg\b//g; +				my $tmp_stmt = $define_stmt; +				$tmp_stmt =~ s/\b(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 =~ s/\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 ($define_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m && +				if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&  				    ((defined($1) && $1 ne ',') ||  				     (defined($2) && $2 ne ','))) {  					CHK("MACRO_ARG_PRECEDENCE", @@ -5311,7 +5347,7 @@ sub process {  			my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);  #			print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); -			if ($c =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|(?:dev_)?alloc_skb)/) { +			if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|kmemdup|(?:dev_)?alloc_skb)/) {  				WARN("OOM_MESSAGE",  				     "Possible unnecessary 'out of memory' message\n" . $hereprev);  			} @@ -5540,10 +5576,18 @@ sub process {  			    "architecture specific defines should be avoided\n" .  $herecurr);  		} +# check that the storage class is not after a type +		if ($line =~ /\b($Type)\s+($Storage)\b/) { +			WARN("STORAGE_CLASS", +			     "storage class '$2' should be located before type '$1'\n" . $herecurr); +		}  # Check that the storage class is at the beginning of a declaration -		if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) { +		if ($line =~ /\b$Storage\b/ && +		    $line !~ /^.\s*$Storage/ && +		    $line =~ /^.\s*(.+?)\$Storage\s/ && +		    $1 !~ /[\,\)]\s*$/) {  			WARN("STORAGE_CLASS", -			     "storage class should be at the beginning of the declaration\n" . $herecurr) +			     "storage class should be at the beginning of the declaration\n" . $herecurr);  		}  # check the location of the inline attribute, that it is between @@ -5886,7 +5930,8 @@ sub process {  			     "externs should be avoided in .c files\n" .  $herecurr);  		} -		if ($realfile =~ /\.[ch]$/ && defined $stat && +# check for function declarations that have arguments without identifier names +		if (defined $stat &&  		    $stat =~ /^.\s*(?:extern\s+)?$Type\s*$Ident\s*\(\s*([^{]+)\s*\)\s*;/s &&  		    $1 ne "void") {  			my $args = trim($1); @@ -5899,6 +5944,29 @@ sub process {  			}  		} +# check for function definitions +		if ($^V && $^V ge 5.10.0 && +		    defined $stat && +		    $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { +			$context_function = $1; + +# check for multiline function definition with misplaced open brace +			my $ok = 0; +			my $cnt = statement_rawlines($stat); +			my $herectx = $here . "\n"; +			for (my $n = 0; $n < $cnt; $n++) { +				my $rl = raw_line($linenr, $n); +				$herectx .=  $rl . "\n"; +				$ok = 1 if ($rl =~ /^[ \+]\{/); +				$ok = 1 if ($rl =~ /\{/ && $n == 0); +				last if $rl =~ /^[ \+].*\{/; +			} +			if (!$ok) { +				ERROR("OPEN_BRACE", +				      "open brace '{' following function definitions go on the next line\n" . $herectx); +			} +		} +  # checks for new __setup's  		if ($rawline =~ /\b__setup\("([^"]*)"/) {  			my $name = $1;  | 
