diff mbox

[1/1] scripts/checkpatch: Update to latest checkpatch

Message ID 1472577242-2003-1-git-send-email-mike.holmes@linaro.org
State New
Headers show

Commit Message

Mike Holmes Aug. 30, 2016, 5:14 p.m. UTC
The existing checkpatch used by ODP crashes when used on recent patches by Bill,
update to the latest version. The latest version has a new test that we need to disable
that warns about not using kernel types:

PREFER_KERNEL_TYPES
check for c99 types like uint8_t used outside of uapi

Signed-off-by: Mike Holmes <mike.holmes@linaro.org>

---
 .checkpatch.conf      |   1 +
 scripts/checkpatch.pl | 820 ++++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 690 insertions(+), 131 deletions(-)

-- 
2.7.4

Comments

Maxim Uvarov Aug. 30, 2016, 7:17 p.m. UTC | #1
How is this patch was generated? Did you apply upstream patches on top 
of our current checkpatch? Were local changes included to that patch?
We should not forget to pull all local things on top of updates.

Maxim.

On 08/30/16 20:14, Mike Holmes wrote:
> The existing checkpatch used by ODP crashes when used on recent patches by Bill,

> update to the latest version. The latest version has a new test that we need to disable

> that warns about not using kernel types:

>

> PREFER_KERNEL_TYPES

> check for c99 types like uint8_t used outside of uapi

>

> Signed-off-by: Mike Holmes <mike.holmes@linaro.org>

> ---

>   .checkpatch.conf      |   1 +

>   scripts/checkpatch.pl | 820 ++++++++++++++++++++++++++++++++++++++++++--------

>   2 files changed, 690 insertions(+), 131 deletions(-)

>

> diff --git a/.checkpatch.conf b/.checkpatch.conf

> index 1e7d663..81723d6 100644

> --- a/.checkpatch.conf

> +++ b/.checkpatch.conf

> @@ -8,3 +8,4 @@

>   --ignore=BIT_MACRO

>   --codespell

>   --codespellfile=/usr/share/codespell/dictionary.txt

> +--ignore=PREFER_KERNEL_TYPES

> diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl

> index 16316b9..4de3cc4 100755

> --- a/scripts/checkpatch.pl

> +++ b/scripts/checkpatch.pl

> @@ -9,6 +9,7 @@ use strict;

>   use POSIX;

>   use File::Basename;

>   use Cwd 'abs_path';

> +use Term::ANSIColor qw(:constants);

>   

>   my $P = $0;

>   my $D = dirname(abs_path($P));

> @@ -24,13 +25,17 @@ 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;

> @@ -48,7 +53,9 @@ 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/local/share/codespell/dictionary.txt";

> +my $codespellfile = "/usr/share/codespell/dictionary.txt";

> +my $color = 1;

> +my $allow_c99_comments = 1;

>   

>   sub help {

>   	my ($exitcode) = @_;

> @@ -64,13 +71,25 @@ Options:

>     --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

> -  --show-types               show the message "types" in the output

>     --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

> @@ -91,8 +110,9 @@ Options:

>     --ignore-perl-version      override checking of perl version.  expect

>                                runtime errors.

>     --codespell                Use the codespell dictionary for spelling/typos

> -                             (default:/usr/local/share/codespell/dictionary.txt)

> +                             (default:/usr/share/codespell/dictionary.txt)

>     --codespellfile            Use this codespell dictionary

> +  --color                    Use colors when output is STDOUT (default: on)

>     -h, --help, --version      display this help and exit

>   

>   When FILE is - read standard input.

> @@ -101,6 +121,37 @@ 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 = ();

> +	for ($text =~ /\b(?:(?:CHK|WARN|ERROR)\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;

> @@ -134,12 +185,15 @@ GetOptions(

>   	'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,

> @@ -153,12 +207,15 @@ GetOptions(

>   	'test-only=s'	=> \$tst_only,

>   	'codespell!'	=> \$codespell,

>   	'codespellfile=s'	=> \$codespellfile,

> +	'color!'	=> \$color,

>   	'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;

>   

> @@ -171,9 +228,9 @@ if ($^V && $^V lt $minimum_perl_version) {

>   	}

>   }

>   

> +#if no filenames are given, push '-' to read patch from stdin

>   if ($#ARGV < 0) {

> -	print "$P: no input files\n";

> -	exit(1);

> +	push(@ARGV, '-');

>   }

>   

>   sub hash_save_array_words {

> @@ -196,12 +253,12 @@ sub hash_save_array_words {

>   sub hash_show_words {

>   	my ($hashRef, $prefix) = @_;

>   

> -	if ($quiet == 0 && keys %$hashRef) {

> -		print "NOTE: $prefix message types:";

> +	if (keys %$hashRef) {

> +		print "\nNOTE: $prefix message types:";

>   		foreach my $word (sort keys %$hashRef) {

>   			print " $word";

>   		}

> -		print "\n\n";

> +		print "\n";

>   	}

>   }

>   

> @@ -261,7 +318,8 @@ our $Sparse	= qr{

>   			__init_refok|

>   			__kprobes|

>   			__ref|

> -			__rcu

> +			__rcu|

> +			__private

>   		}x;

>   our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};

>   our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};

> @@ -347,15 +405,22 @@ our $UTF8	= qr{

>   	| $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 $typeTypedefs = qr{(?x:

> +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|)|

> @@ -363,11 +428,7 @@ our $logFunctions = qr{(?x:

>   	WARN(?:_RATELIMIT|_ONCE|)|

>   	panic|

>   	MODULE_[A-Z_]+|

> -	seq_vprintf|seq_printf|seq_puts|

> -	ODP_ASSERT|ODP_DBG|ODP_ERR|ODP_ABORT|ODP_LOG|ODP_PRINT|

> -	EXAMPLE_DBG|EXAMPLE_ERR|EXAMPLE_ABORT|

> -	LOG_DBG|LOG_ERR|LOG_ABORT|

> -	printf

> +	seq_vprintf|seq_printf|seq_puts

>   )};

>   

>   our $signature_tags = qr{(?xi:

> @@ -422,6 +483,29 @@ our @typeList = (

>   	qr{${Ident}_handler_fn},

>   	@typeListMisordered,

>   );

> +

> +our $C90_int_types = qr{(?x:

> +	long\s+long\s+int\s+(?:un)?signed|

> +	long\s+long\s+(?:un)?signed\s+int|

> +	long\s+long\s+(?:un)?signed|

> +	(?:(?:un)?signed\s+)?long\s+long\s+int|

> +	(?:(?:un)?signed\s+)?long\s+long|

> +	int\s+long\s+long\s+(?:un)?signed|

> +	int\s+(?:(?:un)?signed\s+)?long\s+long|

> +

> +	long\s+int\s+(?:un)?signed|

> +	long\s+(?:un)?signed\s+int|

> +	long\s+(?:un)?signed|

> +	(?:(?:un)?signed\s+)?long\s+int|

> +	(?:(?:un)?signed\s+)?long|

> +	int\s+long\s+(?:un)?signed|

> +	int\s+(?:(?:un)?signed\s+)?long|

> +

> +	int\s+(?:un)?signed|

> +	(?:(?:un)?signed\s+)?int

> +)};

> +

> +our @typeListFile = ();

>   our @typeListWithAttr = (

>   	@typeList,

>   	qr{struct\s+$InitAttribute\s+$Ident},

> @@ -431,6 +515,7 @@ our @typeListWithAttr = (

>   our @modifierList = (

>   	qr{fastcall},

>   );

> +our @modifierListFile = ();

>   

>   our @mode_permission_funcs = (

>   	["module_param", 3],

> @@ -514,13 +599,12 @@ if ($codespell) {

>   $misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;

>   

>   sub build_types {

> -	my $mods = "(?x:  \n" . join("|\n  ", @modifierList) . "\n)";

> -	my $all = "(?x:  \n" . join("|\n  ", @typeList) . "\n)";

> +	my $mods = "(?x:  \n" . join("|\n  ", (@modifierList, @modifierListFile)) . "\n)";

> +	my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile)) . "\n)";

>   	my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered) . "\n)";

>   	my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr) . "\n)";

>   	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};

>   	$BasicType	= qr{

> -				(?:$typeOtherOSTypedefs\b)|

>   				(?:$typeTypedefs\b)|

>   				(?:${all}\b)

>   		}x;

> @@ -528,7 +612,6 @@ sub build_types {

>   			(?:$Modifier\s+|const\s+)*

>   			(?:

>   				(?:typeof|__typeof__)\s*\([^\)]*\)|

> -				(?:$typeOtherOSTypedefs\b)|

>   				(?:$typeTypedefs\b)|

>   				(?:${all}\b)

>   			)

> @@ -546,7 +629,6 @@ sub build_types {

>   			(?:

>   				(?:typeof|__typeof__)\s*\([^\)]*\)|

>   				(?:$typeTypedefs\b)|

> -				(?:$typeOtherOSTypedefs\b)|

>   				(?:${allWithAttr}\b)

>   			)

>   			(?:\s+$Modifier|\s+const)*

> @@ -577,7 +659,7 @@ our $LvalOrFunc	= qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};

>   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,2}\s*\(|

> +	(?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|

>   	(?:$Storage\s+)?LIST_HEAD\s*\(|

>   	(?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(

>   )};

> @@ -719,10 +801,42 @@ my @fixed_inserted = ();

>   my @fixed_deleted = ();

>   my $fixlinenr = -1;

>   

> +# If input is git commits, extract all commits from the commit expressions.

> +# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.

> +die "$P: No git repository found\n" if ($git && !-e ".git");

> +

> +if ($git) {

> +	my @commits = ();

> +	foreach my $commit_expr (@ARGV) {

> +		my $git_range;

> +		if ($commit_expr =~ m/^(.*)-(\d+)$/) {

> +			$git_range = "-$2 $1";

> +		} elsif ($commit_expr =~ m/\.\./) {

> +			$git_range = "$commit_expr";

> +		} else {

> +			$git_range = "-1 $commit_expr";

> +		}

> +		my $lines = `git log --no-color --no-merges --pretty=format:'%H %s' $git_range`;

> +		foreach my $line (split(/\n/, $lines)) {

> +			$line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;

> +			next if (!defined($1) || !defined($2));

> +			my $sha1 = $1;

> +			my $subject = $2;

> +			unshift(@commits, $sha1);

> +			$git_commits{$sha1} = $subject;

> +		}

> +	}

> +	die "$P: no git commits after extraction!\n" if (@commits == 0);

> +	@ARGV = @commits;

> +}

> +

>   my $vname;

>   for my $filename (@ARGV) {

>   	my $FILE;

> -	if ($file) {

> +	if ($git) {

> +		open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||

> +			die "$P: $filename: git format-patch failed - $!\n";

> +	} elsif ($file) {

>   		open($FILE, '-|', "diff -u /dev/null $filename") ||

>   			die "$P: $filename: diff failed - $!\n";

>   	} elsif ($filename eq '-') {

> @@ -733,6 +847,8 @@ for my $filename (@ARGV) {

>   	}

>   	if ($filename eq '-') {

>   		$vname = 'Your patch';

> +	} elsif ($git) {

> +		$vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';

>   	} else {

>   		$vname = $filename;

>   	}

> @@ -741,6 +857,13 @@ for my $filename (@ARGV) {

>   		push(@rawlines, $_);

>   	}

>   	close($FILE);

> +

> +	if ($#ARGV > 0 && $quiet == 0) {

> +		print '-' x length($vname) . "\n";

> +		print "$vname\n";

> +		print '-' x length($vname) . "\n";

> +	}

> +

>   	if (!process($filename)) {

>   		$exit = 1;

>   	}

> @@ -750,6 +873,29 @@ for my $filename (@ARGV) {

>   	@fixed_inserted = ();

>   	@fixed_deleted = ();

>   	$fixlinenr = -1;

> +	@modifierListFile = ();

> +	@typeListFile = ();

> +	build_types();

> +}

> +

> +if (!$quiet) {

> +	hash_show_words(\%use_type, "Used");

> +	hash_show_words(\%ignore_type, "Ignored");

> +

> +	if ($^V lt 5.10.0) {

> +		print << "EOM"

> +

> +NOTE: perl $^V is not modern enough to detect all possible issues.

> +      An upgrade to at least perl v5.10.0 is suggested.

> +EOM

> +	}

> +	if ($exit) {

> +		print << "EOM"

> +

> +NOTE: If any of the errors are false positives, please report

> +      them to the maintainer, see CHECKPATCH in MAINTAINERS.

> +EOM

> +	}

>   }

>   

>   exit($exit);

> @@ -999,13 +1145,18 @@ sub sanitise_line {

>   		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;

>   	}

>   

> +	if ($allow_c99_comments && $res =~ m@(//.*$)@) {

> +		my $match = $1;

> +		$res =~ s/\Q$match\E/"$;" x length($match)/e;

> +	}

> +

>   	return $res;

>   }

>   

>   sub get_quoted_string {

>   	my ($line, $rawline) = @_;

>   

> -	return "" if ($line !~ m/(\"[X\t]+\")/g);

> +	return "" if ($line !~ m/($String)/g);

>   	return substr($rawline, $-[0], $+[0] - $-[0]);

>   }

>   

> @@ -1614,13 +1765,13 @@ sub possible {

>   			for my $modifier (split(' ', $possible)) {

>   				if ($modifier !~ $notPermitted) {

>   					warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);

> -					push(@modifierList, $modifier);

> +					push(@modifierListFile, $modifier);

>   				}

>   			}

>   

>   		} else {

>   			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);

> -			push(@typeList, $possible);

> +			push(@typeListFile, $possible);

>   		}

>   		build_types();

>   	} else {

> @@ -1645,15 +1796,32 @@ sub report {

>   	    (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {

>   		return 0;

>   	}

> -	my $line;

> +	my $output = '';

> +	if (-t STDOUT && $color) {

> +		if ($level eq 'ERROR') {

> +			$output .= RED;

> +		} elsif ($level eq 'WARNING') {

> +			$output .= YELLOW;

> +		} else {

> +			$output .= GREEN;

> +		}

> +	}

> +	$output .= $prefix . $level . ':';

>   	if ($show_types) {

> -		$line = "$prefix$level:$type: $msg\n";

> -	} else {

> -		$line = "$prefix$level: $msg\n";

> +		$output .= BLUE if (-t STDOUT && $color);

> +		$output .= "$type:";

>   	}

> -	$line = (split('\n', $line))[0] . "\n" if ($terse);

> +	$output .= RESET if (-t STDOUT && $color);

> +	$output .= ' ' . $msg . "\n";

>   

> -	push(our @report, $line);

> +	if ($showfile) {

> +		my @lines = split("\n", $output, -1);

> +		splice(@lines, 1, 1);

> +		$output = join("\n", @lines);

> +	}

> +	$output = (split('\n', $output))[0] . "\n" if ($terse);

> +

> +	push(our @report, $output);

>   

>   	return 1;

>   }

> @@ -1899,11 +2067,13 @@ sub process {

>   	our $clean = 1;

>   	my $signoff = 0;

>   	my $is_patch = 0;

> -

>   	my $in_header_lines = $file ? 0 : 1;

>   	my $in_commit_log = 0;		#Scanning lines before patch

> +	my $has_commit_log = 0;		#Encountered lines before patch

> +       my $commit_log_possible_stack_dump = 0;

>   	my $commit_log_long_line = 0;

> -	my $reported_maintainer_file = 1; # No MAINTAINTERS so silence warning

> +	my $commit_log_has_diff = 0;

> +	my $reported_maintainer_file = 0;

>   	my $non_utf8_charset = 0;

>   

>   	my $last_blank_line = 0;

> @@ -2036,7 +2206,8 @@ sub process {

>   		my $rawline = $rawlines[$linenr - 1];

>   

>   #extract the line range in the file after the patch is applied

> -		if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {

> +		if (!$in_commit_log &&

> +		    $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {

>   			$is_patch = 1;

>   			$first_line = $linenr + 1;

>   			$realline=$1-1;

> @@ -2077,10 +2248,6 @@ sub process {

>   

>   		my $hunk_line = ($realcnt != 0);

>   

> -#make up the handle for any error we report on this line

> -		$prefix = "$filename:$realline: " if ($emacs && $file);

> -		$prefix = "$filename:$linenr: " if ($emacs && !$file);

> -

>   		$here = "#$linenr: " if (!$file);

>   		$here = "#$realline: " if ($file);

>   

> @@ -2110,8 +2277,19 @@ sub process {

>   			$found_file = 1;

>   		}

>   

> +#make up the handle for any error we report on this line

> +		if ($showfile) {

> +			$prefix = "$realfile:$realline: "

> +		} elsif ($emacs) {

> +			if ($file) {

> +				$prefix = "$filename:$realline: ";

> +			} else {

> +				$prefix = "$filename:$linenr: ";

> +			}

> +		}

> +

>   		if ($found_file) {

> -			if ($realfile =~ m@^(drivers/net/|net/)@) {

> +			if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {

>   				$check = 1;

>   			} else {

>   				$check = $check_orig;

> @@ -2127,6 +2305,17 @@ sub process {

>   

>   		$cnt_lines++ if ($realcnt != 0);

>   

> +# Check if the commit log has what seems like a diff which can confuse patch

> +		if ($in_commit_log && !$commit_log_has_diff &&

> +		    (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&

> +		      $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||

> +		     $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||

> +		     $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {

> +			ERROR("DIFF_IN_COMMIT_MSG",

> +			      "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);

> +			$commit_log_has_diff = 1;

> +		}

> +

>   # Check for incorrect file permissions

>   		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {

>   			my $permhere = $here . "FILE: $realfile\n";

> @@ -2238,18 +2427,46 @@ sub process {

>   			      "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr);

>   		}

>   

> +# Check if the commit log is in a possible stack dump

> +		if ($in_commit_log && !$commit_log_possible_stack_dump &&

> +		    ($line =~ /^\s*(?:WARNING:|BUG:)/ ||

> +		     $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||

> +					# timestamp

> +		     $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) {

> +					# stack dump address

> +			$commit_log_possible_stack_dump = 1;

> +		}

> +

>   # Check for line lengths > 75 in commit log, warn once

>   		if ($in_commit_log && !$commit_log_long_line &&

> -		    length($line) > 75) {

> +		    length($line) > 75 &&

> +		    !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||

> +					# file delta changes

> +		      $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||

> +					# filename then :

> +		      $line =~ /^\s*(?:Fixes:|Link:)/i ||

> +					# A Fixes: or Link: line

> +		      $commit_log_possible_stack_dump)) {

>   			WARN("COMMIT_LOG_LONG_LINE",

>   			     "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);

>   			$commit_log_long_line = 1;

>   		}

>   

> +# Reset possible stack dump if a blank line is found

> +		if ($in_commit_log && $commit_log_possible_stack_dump &&

> +		    $line =~ /^\s*$/) {

> +			$commit_log_possible_stack_dump = 0;

> +		}

> +

>   # Check for git id commit length and improperly formed commit descriptions

> -		if ($in_commit_log && $line =~ /\b(c)ommit\s+([0-9a-f]{5,})/i) {

> -			my $init_char = $1;

> -			my $orig_commit = lc($2);

> +		if ($in_commit_log && !$commit_log_possible_stack_dump &&

> +		    $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i &&

> +		    ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||

> +		     ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&

> +		      $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&

> +		      $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {

> +			my $init_char = "c";

> +			my $orig_commit = "";

>   			my $short = 1;

>   			my $long = 0;

>   			my $case = 1;

> @@ -2260,6 +2477,13 @@ sub process {

>   			my $orig_desc = "commit description";

>   			my $description = "";

>   

> +			if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {

> +				$init_char = $1;

> +				$orig_commit = lc($2);

> +			} elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {

> +				$orig_commit = lc($1);

> +			}

> +

>   			$short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);

>   			$long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);

>   			$space = 0 if ($line =~ /\bcommit [0-9a-f]/i);

> @@ -2343,6 +2567,7 @@ sub process {

>   		      $rawline =~ /^(commit\b|from\b|[\w-]+:).*$/i)) {

>   			$in_header_lines = 0;

>   			$in_commit_log = 1;

> +			$has_commit_log = 1;

>   		}

>   

>   # Check if there is UTF-8 in a commit log when a mail header has explicitly

> @@ -2514,16 +2739,60 @@ sub process {

>   # check we are in a valid source file if not then ignore this hunk

>   		next if ($realfile !~ /\.(h|c|s|S|pl|sh|dtsi|dts)$/);

>   

> -#line length limit

> -		if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&

> -		    $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&

> -		    !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?$String\s*(?:|,|\)\s*;)\s*$/ ||

> -		      $line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||

> -		      $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) &&

> -		    $length > $max_line_length)

> -		{

> -			WARN("LONG_LINE",

> -			     "line over $max_line_length characters\n" . $herecurr);

> +# line length limit (with some exclusions)

> +#

> +# There are a few types of lines that may extend beyond $max_line_length:

> +#	logging functions like pr_info that end in a string

> +#	lines with a single string

> +#	#defines that are a single string

> +#

> +# There are 3 different line length message types:

> +# LONG_LINE_COMMENT	a comment starts before but extends beyond $max_linelength

> +# LONG_LINE_STRING	a string starts before but extends beyond $max_line_length

> +# LONG_LINE		all other lines longer than $max_line_length

> +#

> +# if LONG_LINE is ignored, the other 2 types are also ignored

> +#

> +

> +		if ($line =~ /^\+/ && $length > $max_line_length) {

> +			my $msg_type = "LONG_LINE";

> +

> +			# Check the allowed long line types first

> +

> +			# logging functions that end in a string that starts

> +			# before $max_line_length

> +			if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&

> +			    length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {

> +				$msg_type = "";

> +

> +			# lines with only strings (w/ possible termination)

> +			# #defines with only strings

> +			} elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||

> +				 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {

> +				$msg_type = "";

> +

> +			# EFI_GUID is another special case

> +			} elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) {

> +				$msg_type = "";

> +

> +			# Otherwise set the alternate message types

> +

> +			# a comment starts before $max_line_length

> +			} elsif ($line =~ /($;[\s$;]*)$/ &&

> +				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {

> +				$msg_type = "LONG_LINE_COMMENT"

> +

> +			# a quoted string starts before $max_line_length

> +			} elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&

> +				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {

> +				$msg_type = "LONG_LINE_STRING"

> +			}

> +

> +			if ($msg_type ne "" &&

> +			    (show_type("LONG_LINE") || show_type($msg_type))) {

> +				WARN($msg_type,

> +				     "line over $max_line_length characters\n" . $herecurr);

> +			}

>   		}

>   

>   # check for adding lines without a newline.

> @@ -2581,6 +2850,19 @@ sub process {

>   			    "Logical continuations should be on the previous line\n" . $hereprev);

>   		}

>   

> +# check indentation starts on a tab stop

> +		if ($^V && $^V ge 5.10.0 &&

> +		    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$))/) {

> +			my $indent = length($1);

> +			if ($indent % 8) {

> +				if (WARN("TABSTOP",

> +					 "Statements should start on a tabstop\n" . $herecurr) &&

> +				    $fix) {

> +					$fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e;

> +				}

> +			}

> +		}

> +

>   # 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*$/) {

> @@ -2628,6 +2910,8 @@ sub process {

>   			}

>   		}

>   

> +# Block comment styles

> +# Networking with an initial /*

>   		if ($realfile =~ m@^(drivers/net/|net/)@ &&

>   		    $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&

>   		    $rawline =~ /^\+[ \t]*\*/ &&

> @@ -2636,22 +2920,23 @@ sub process {

>   			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);

>   		}

>   

> -		if ($realfile =~ m@^(drivers/net/|net/)@ &&

> -		    $prevrawline =~ /^\+[ \t]*\/\*/ &&		#starting /*

> +# Block comments use * on subsequent lines

> +		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment

> +		    $prevrawline =~ /^\+.*?\/\*/ &&		#starting /*

>   		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */

>   		    $rawline =~ /^\+/ &&			#line is new

>   		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *

> -			WARN("NETWORKING_BLOCK_COMMENT_STYLE",

> -			     "networking block comments start with * on subsequent lines\n" . $hereprev);

> +			WARN("BLOCK_COMMENT_STYLE",

> +			     "Block comments use * on subsequent lines\n" . $hereprev);

>   		}

>   

> -		if ($realfile =~ m@^(drivers/net/|net/)@ &&

> -		    $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */

> +# Block comments use */ on trailing lines

> +		if ($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);

> +			WARN("BLOCK_COMMENT_STYLE",

> +			     "Block comments use a trailing */ on a separate line\n" . $herecurr);

>   		}

>   

>   # check for missing blank lines after struct/union declarations

> @@ -2957,14 +3242,21 @@ sub process {

>   

>   			substr($s, 0, length($c), '');

>   

> +			# remove inline comments

> +			$s =~ s/$;/ /g;

> +			$c =~ s/$;/ /g;

> +

> +			# Find out how long the conditional actually is.

> +			my @newlines = ($c =~ /\n/gs);

> +			my $cond_lines = 1 + $#newlines;

> +

>   			# 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;

> +			while ($s =~ /\n\s+\\\n/) {

> +				$cond_lines += $s =~ s/\n\s+\\\n/\n/g;

> +			}

>   

>   			# We want to check the first line inside the block

>   			# starting at the end of the conditional, so remove:

> @@ -3031,8 +3323,10 @@ sub process {

>   

>   			#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 ''))) {

> +			if ($check && $s ne '' &&

> +			    (($sindent % 8) != 0 ||

> +			     ($sindent < $indent) ||

> +			     ($sindent > $indent + 8))) {

>   				WARN("SUSPECT_CODE_INDENT",

>   				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");

>   			}

> @@ -3054,6 +3348,30 @@ sub process {

>   #ignore lines not being added

>   		next if ($line =~ /^[^\+]/);

>   

> +# check for declarations of signed or unsigned without int

> +		while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {

> +			my $type = $1;

> +			my $var = $2;

> +			$var = "" if (!defined $var);

> +			if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {

> +				my $sign = $1;

> +				my $pointer = $2;

> +

> +				$pointer = "" if (!defined $pointer);

> +

> +				if (WARN("UNSPECIFIED_INT",

> +					 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&

> +				    $fix) {

> +					my $decl = trim($sign) . " int ";

> +					my $comp_pointer = $pointer;

> +					$comp_pointer =~ s/\s//g;

> +					$decl .= $comp_pointer;

> +					$decl = rtrim($decl) if ($var eq "");

> +					$fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;

> +				}

> +			}

> +		}

> +

>   # TEST: allow direct testing of the type matcher.

>   		if ($dbg_type) {

>   			if ($line =~ /^.\s*$Declare\s*$/) {

> @@ -3173,21 +3491,20 @@ sub process {

>   		}

>   

>   # check for global initialisers.

> -		if ($line =~ /^\+(\s*$Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/) {

> +		if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) {

>   			if (ERROR("GLOBAL_INITIALISERS",

> -				  "do not initialise globals to 0 or NULL\n" .

> -				      $herecurr) &&

> +				  "do not initialise globals to $1\n" . $herecurr) &&

>   			    $fix) {

> -				$fixed[$fixlinenr] =~ s/($Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/$1;/;

> +				$fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;

>   			}

>   		}

>   # check for static initialisers.

> -		if ($line =~ /^\+.*\bstatic\s.*=\s*(0|NULL|false)\s*;/) {

> +		if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {

>   			if (ERROR("INITIALISED_STATIC",

> -				  "do not initialise statics to 0 or NULL\n" .

> +				  "do not initialise statics to $1\n" .

>   				      $herecurr) &&

>   			    $fix) {

> -				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*(0|NULL|false)\s*;/$1;/;

> +				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;

>   			}

>   		}

>   

> @@ -3268,7 +3585,6 @@ sub process {

>   		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&

>   		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&

>   		    $line !~ /\b$typeTypedefs\b/ &&

> -		    $line !~ /\b$typeOtherOSTypedefs\b/ &&

>   		    $line !~ /\b__bitwise(?:__|)\b/) {

>   			WARN("NEW_TYPEDEFS",

>   			     "do not add new typedefs\n" . $herecurr);

> @@ -3330,13 +3646,15 @@ sub process {

>   			}

>   		}

>   

> -# # 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;

> -# 		}

> +# avoid BUG() or BUG_ON()

> +		if ($line =~ /\b(?:BUG|BUG_ON)\b/) {

> +			my $msg_type = \&WARN;

> +			$msg_type = \&CHK if ($file);

> +			&{$msg_type}("AVOID_BUG",

> +				     "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);

> +		}

>   

> +# avoid LINUX_VERSION_CODE

>   		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);

> @@ -3923,7 +4241,7 @@ sub process {

>   ## 		}

>   

>   #need space before brace following if, while, etc

> -		if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\){/) ||

> +		if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||

>   		    $line =~ /do\{/) {

>   			if (ERROR("SPACING",

>   				  "space required before the open brace '{'\n" . $herecurr) &&

> @@ -4070,6 +4388,35 @@ sub process {

>   			}

>   		}

>   

> +# comparisons with a constant or upper case identifier on the left

> +#	avoid cases like "foo + BAR < baz"

> +#	only fix matches surrounded by parentheses to avoid incorrect

> +#	conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"

> +		if ($^V && $^V ge 5.10.0 &&

> +		    $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {

> +			my $lead = $1;

> +			my $const = $2;

> +			my $comp = $3;

> +			my $to = $4;

> +			my $newcomp = $comp;

> +			if ($lead !~ /(?:$Operators|\.)\s*$/ &&

> +			    $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&

> +			    WARN("CONSTANT_COMPARISON",

> +				 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&

> +			    $fix) {

> +				if ($comp eq "<") {

> +					$newcomp = ">";

> +				} elsif ($comp eq "<=") {

> +					$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;

> @@ -4256,12 +4603,6 @@ sub process {

>   #Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show)

>   			    $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ &&

>   #Ignore some three character SI units explicitly, like MiB and KHz

> -			    $var !~ /\bCU_/ &&

> -			    $var !~ /\bPRI[diux]32/ &&

> -			    $var !~ /\bPRI[diux]64/ &&

> -			    $var !~ /\bSCN[diux]8/ &&

> -			    $var !~ /\bSCN[diux]32/ &&

> -			    $var !~ /\bSCN[diux]64/ &&

>   			    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {

>   				while ($var =~ m{($Ident)}g) {

>   					my $word = $1;

> @@ -4331,7 +4672,7 @@ sub process {

>   			#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 =~ /\#\#/);

> +			$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);

>   

>   			$dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//;

>   			$dstat =~ s/$;//g;

> @@ -4342,16 +4683,19 @@ 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/)

> +			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|

> @@ -4362,7 +4706,8 @@ sub process {

>   				union|

>   				struct|

>   				\.$Ident\s*=\s*|

> -				^\"|\"$

> +				^\"|\"$|

> +				^\[

>   			}x;

>   			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";

>   			if ($dstat ne '' &&

> @@ -4629,7 +4974,7 @@ sub process {

>   # to grep for the string.  Make exceptions when the previous string ends in a

>   # newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'

>   # (common in inline assembly) or is a octal \123 or hexadecimal \xaf value

> -		if ($line =~ /^\+\s*"[X\t]*"/ &&

> +		if ($line =~ /^\+\s*$String/ &&

>   		    $prevline =~ /"\s*$/ &&

>   		    $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {

>   			if (WARN("SPLIT_STRING",

> @@ -4675,27 +5020,31 @@ sub process {

>   		}

>   

>   # concatenated string without spaces between elements

> -		if ($line =~ /"X+"[A-Z_]+/ || $line =~ /[A-Z_]+"X+"/) {

> +		if ($line =~ /$String[A-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) {

>   			CHK("CONCATENATED_STRING",

>   			    "Concatenated strings should use spaces between elements\n" . $herecurr);

>   		}

>   

>   # uncoalesced string fragments

> -		if ($line =~ /"X*"\s*"/) {

> +		if ($line =~ /$String\s*"/) {

>   			WARN("STRING_FRAGMENTS",

>   			     "Consecutive strings are generally better as a single string\n" . $herecurr);

>   		}

>   

> -# check for %L{u,d,i} in strings

> +# check for %L{u,d,i} and 0x%[udi] in strings

>   		my $string;

>   		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {

>   			$string = substr($rawline, $-[1], $+[1] - $-[1]);

>   			$string =~ s/%%/__/g;

> -			if ($string =~ /(?<!%)%L[udi]/) {

> +			if ($string =~ /(?<!%)%[\*\d\.\$]*L[udi]/) {

>   				WARN("PRINTF_L",

>   				     "\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr);

>   				last;

>   			}

> +			if ($string =~ /0x%[\*\d\.\$\Llzth]*[udi]/) {

> +				ERROR("PRINTF_0xDECIMAL",

> +				      "Prefixing 0x with decimal output is defective\n" . $herecurr);

> +			}

>   		}

>   

>   # check for line continuations in quoted strings with odd counts of "

> @@ -4713,10 +5062,34 @@ sub process {

>   

>   # 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 and this check is probably not required\n" . $hereprev);

> +			my $tested = quotemeta($1);

> +			my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';

> +			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {

> +				my $func = $1;

> +				if (WARN('NEEDLESS_IF',

> +					 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&

> +				    $fix) {

> +					my $do_fix = 1;

> +					my $leading_tabs = "";

> +					my $new_leading_tabs = "";

> +					if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {

> +						$leading_tabs = $1;

> +					} else {

> +						$do_fix = 0;

> +					}

> +					if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {

> +						$new_leading_tabs = $1;

> +						if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {

> +							$do_fix = 0;

> +						}

> +					} else {

> +						$do_fix = 0;

> +					}

> +					if ($do_fix) {

> +						fix_delete_line($fixlinenr - 1, $prevrawline);

> +						$fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;

> +					}

> +				}

>   			}

>   		}

>   

> @@ -4902,12 +5275,69 @@ sub process {

>   			}

>   		}

>   # check for memory barriers without a comment.

> -		if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) {

> +

> +		my $barriers = qr{

> +			mb|

> +			rmb|

> +			wmb|

> +			read_barrier_depends

> +		}x;

> +		my $barrier_stems = qr{

> +			mb__before_atomic|

> +			mb__after_atomic|

> +			store_release|

> +			load_acquire|

> +			store_mb|

> +			(?:$barriers)

> +		}x;

> +		my $all_barriers = qr{

> +			(?:$barriers)|

> +			smp_(?:$barrier_stems)|

> +			virt_(?:$barrier_stems)

> +		}x;

> +

> +		if ($line =~ /\b(?:$all_barriers)\s*\(/) {

>   			if (!ctx_has_comment($first_line, $linenr)) {

>   				WARN("MEMORY_BARRIER",

>   				     "memory barrier without comment\n" . $herecurr);

>   			}

>   		}

> +

> +		my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;

> +

> +		if ($realfile !~ m@^include/asm-generic/@ &&

> +		    $realfile !~ m@/barrier\.h$@ &&

> +		    $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&

> +		    $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {

> +			WARN("MEMORY_BARRIER",

> +			     "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);

> +		}

> +

> +# check for waitqueue_active without a comment.

> +		if ($line =~ /\bwaitqueue_active\s*\(/) {

> +			if (!ctx_has_comment($first_line, $linenr)) {

> +				WARN("WAITQUEUE_ACTIVE",

> +				     "waitqueue_active without comment\n" . $herecurr);

> +			}

> +		}

> +

> +# Check for expedited grace periods that interrupt non-idle non-nohz

> +# online CPUs.  These expedited can therefore degrade real-time response

> +# if used carelessly, and should be avoided where not absolutely

> +# needed.  It is always OK to use synchronize_rcu_expedited() and

> +# synchronize_sched_expedited() at boot time (before real-time applications

> +# start) and in error situations where real-time response is compromised in

> +# any case.  Note that synchronize_srcu_expedited() does -not- interrupt

> +# other CPUs, so don't warn on uses of synchronize_srcu_expedited().

> +# Of course, nothing comes for free, and srcu_read_lock() and

> +# srcu_read_unlock() do contain full memory barriers in payment for

> +# synchronize_srcu_expedited() non-interruption properties.

> +		if ($line =~ /\b(synchronize_rcu_expedited|synchronize_sched_expedited)\(/) {

> +			WARN("EXPEDITED_RCU_GRACE_PERIOD",

> +			     "expedited RCU grace periods should be avoided where they can degrade real-time response\n" . $herecurr);

> +

> +		}

> +

>   # check of hardware specific defines

>   		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {

>   			CHK("ARCH_DEFINES",

> @@ -4983,6 +5413,44 @@ sub process {

>   			      "Using weak declarations can have unintended link defects\n" . $herecurr);

>   		}

>   

> +# check for c99 types like uint8_t used outside of uapi/

> +		if ($realfile !~ m@\binclude/uapi/@ &&

> +		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {

> +			my $type = $1;

> +			if ($type =~ /\b($typeC99Typedefs)\b/) {

> +				$type = $1;

> +				my $kernel_type = 'u';

> +				$kernel_type = 's' if ($type =~ /^_*[si]/);

> +				$type =~ /(\d+)/;

> +				$kernel_type .= $1;

> +				if (CHK("PREFER_KERNEL_TYPES",

> +					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&

> +				    $fix) {

> +					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;

> +				}

> +			}

> +		}

> +

> +# check for cast of C90 native int or longer types constants

> +		if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {

> +			my $cast = $1;

> +			my $const = $2;

> +			if (WARN("TYPECAST_INT_CONSTANT",

> +				 "Unnecessary typecast of c90 int constant\n" . $herecurr) &&

> +			    $fix) {

> +				my $suffix = "";

> +				my $newconst = $const;

> +				$newconst =~ s/${Int_type}$//;

> +				$suffix .= 'U' if ($cast =~ /\bunsigned\b/);

> +				if ($cast =~ /\blong\s+long\b/) {

> +					$suffix .= 'LL';

> +				} elsif ($cast =~ /\blong\b/) {

> +					$suffix .= 'L';

> +				}

> +				$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;

> +			}

> +		}

> +

>   # check for sizeof(&)

>   		if ($line =~ /\bsizeof\s*\(\s*\&/) {

>   			WARN("SIZEOF_ADDRESS",

> @@ -5020,7 +5488,7 @@ sub process {

>   # 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) {

> +		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {

>   

>   			my $ms_addr = $2;

>   			my $ms_val = $7;

> @@ -5035,6 +5503,48 @@ sub process {

>   			}

>   		}

>   

> +# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)

> +		if ($^V && $^V ge 5.10.0 &&

> +		    defined $stat &&

> +		    $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {

> +			if (WARN("PREFER_ETHER_ADDR_COPY",

> +				 "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&

> +			    $fix) {

> +				$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;

> +			}

> +		}

> +

> +# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)

> +		if ($^V && $^V ge 5.10.0 &&

> +		    defined $stat &&

> +		    $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {

> +			WARN("PREFER_ETHER_ADDR_EQUAL",

> +			     "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")

> +		}

> +

> +# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr

> +# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr

> +		if ($^V && $^V ge 5.10.0 &&

> +		    defined $stat &&

> +		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {

> +

> +			my $ms_val = $7;

> +

> +			if ($ms_val =~ /^(?:0x|)0+$/i) {

> +				if (WARN("PREFER_ETH_ZERO_ADDR",

> +					 "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&

> +				    $fix) {

> +					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;

> +				}

> +			} elsif ($ms_val =~ /^(?:0xff|255)$/i) {

> +				if (WARN("PREFER_ETH_BROADCAST_ADDR",

> +					 "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&

> +				    $fix) {

> +					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;

> +				}

> +			}

> +		}

> +

>   # typecasts on min/max could be min_t/max_t

>   		if ($^V && $^V ge 5.10.0 &&

>   		    defined $stat &&

> @@ -5224,8 +5734,9 @@ sub process {

>   			}

>   		}

>   

> -# check for #defines like: 1 << <digit> that could be BIT(digit)

> -		if ($line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {

> +# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi

> +		if ($realfile !~ m@^include/uapi/@ &&

> +		    $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {

>   			my $ull = "";

>   			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);

>   			if (CHK("BIT_MACRO",

> @@ -5235,6 +5746,16 @@ sub process {

>   			}

>   		}

>   

> +# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE

> +		if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {

> +			my $config = $1;

> +			if (WARN("PREFER_IS_ENABLED",

> +				 "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) &&

> +			    $fix) {

> +				$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";

> +			}

> +		}

> +

>   # check for case / default statements not preceded by break/fallthrough/switch

>   		if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {

>   			my $has_break = 0;

> @@ -5425,6 +5946,28 @@ sub process {

>   			}

>   		}

>   

> +# whine about ACCESS_ONCE

> +		if ($^V && $^V ge 5.10.0 &&

> +		    $line =~ /\bACCESS_ONCE\s*$balanced_parens\s*(=(?!=))?\s*($FuncArg)?/) {

> +			my $par = $1;

> +			my $eq = $2;

> +			my $fun = $3;

> +			$par =~ s/^\(\s*(.*)\s*\)$/$1/;

> +			if (defined($eq)) {

> +				if (WARN("PREFER_WRITE_ONCE",

> +					 "Prefer WRITE_ONCE(<FOO>, <BAR>) over ACCESS_ONCE(<FOO>) = <BAR>\n" . $herecurr) &&

> +				    $fix) {

> +					$fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)\s*$eq\s*\Q$fun\E/WRITE_ONCE($par, $fun)/;

> +				}

> +			} else {

> +				if (WARN("PREFER_READ_ONCE",

> +					 "Prefer READ_ONCE(<FOO>) over ACCESS_ONCE(<FOO>)\n" . $herecurr) &&

> +				    $fix) {

> +					$fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)/READ_ONCE($par)/;

> +				}

> +			}

> +		}

> +

>   # check for lockdep_set_novalidate_class

>   		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||

>   		    $line =~ /__lockdep_no_validate__\s*\)/ ) {

> @@ -5472,6 +6015,24 @@ sub process {

>   				}

>   			}

>   		}

> +

> +# validate content of MODULE_LICENSE against list from include/linux/module.h

> +		if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {

> +			my $extracted_string = get_quoted_string($line, $rawline);

> +			my $valid_licenses = qr{

> +						GPL|

> +						GPL\ v2|

> +						GPL\ and\ additional\ rights|

> +						Dual\ BSD/GPL|

> +						Dual\ MIT/GPL|

> +						Dual\ MPL/GPL|

> +						Proprietary

> +					}x;

> +			if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {

> +				WARN("MODULE_LICENSE",

> +				     "unknown module license " . $extracted_string . "\n" . $herecurr);

> +			}

> +		}

>   	}

>   

>   	# If we have no input at all, then there is nothing to report on

> @@ -5492,11 +6053,11 @@ sub process {

>   		exit(0);

>   	}

>   

> -	if (!$is_patch) {

> +	if (!$is_patch && $file !~ /cover-letter\.patch$/) {

>   		ERROR("NOT_UNIFIED_DIFF",

>   		      "Does not appear to be a unified-diff format patch\n");

>   	}

> -	if ($is_patch && $chk_signoff && $signoff == 0) {

> +	if ($is_patch && $has_commit_log && $chk_signoff && $signoff == 0) {

>   		ERROR("MISSING_SIGN_OFF",

>   		      "Missing Signed-off-by: line(s)\n");

>   	}

> @@ -5507,28 +6068,29 @@ sub process {

>   		print "total: $cnt_error errors, $cnt_warn warnings, " .

>   			(($check)? "$cnt_chk checks, " : "") .

>   			"$cnt_lines lines checked\n";

> -		print "\n" if ($quiet == 0);

>   	}

>   

>   	if ($quiet == 0) {

> +		# If there were any defects found and not already fixing them

> +		if (!$clean and !$fix) {

> +			print << "EOM"

>   

> -		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");

> +NOTE: For some of the reported defects, checkpatch may be able to

> +      mechanically convert to the typical style using --fix or --fix-inplace.

> +EOM

>   		}

> -

>   		# If there were whitespace errors which cleanpatch can fix

>   		# then suggest that.

>   		if ($rpt_cleaners) {

> -			print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n";

> -			print "      scripts/cleanfile\n\n";

>   			$rpt_cleaners = 0;

> +			print << "EOM"

> +

> +NOTE: Whitespace errors detected.

> +      You may wish to use scripts/cleanpatch or scripts/cleanfile

> +EOM

>   		}

>   	}

>   

> -	hash_show_words(\%use_type, "Used");

> -	hash_show_words(\%ignore_type, "Ignored");

> -

>   	if ($clean == 0 && $fix &&

>   	    ("@rawlines" ne "@fixed" ||

>   	     $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {

> @@ -5556,6 +6118,7 @@ sub process {

>   

>   		if (!$quiet) {

>   			print << "EOM";

> +

>   Wrote EXPERIMENTAL --fix correction(s) to '$newfile'

>   

>   Do _NOT_ trust the results written to this file.

> @@ -5563,22 +6126,17 @@ Do _NOT_ submit these changes without inspecting them for correctness.

>   

>   This EXPERIMENTAL file is simply a convenience to help rewrite patches.

>   No warranties, expressed or implied...

> -

>   EOM

>   		}

>   	}

>   

> -	if ($clean == 1 && $quiet == 0) {

> -		print "$vname has no obvious style problems and is ready for submission.\n"

> -	}

> -	if ($clean == 0 && $quiet == 0) {

> -		print << "EOM";

> -$vname has style problems, please review.

> -

> -If any of these errors are false positives, please report

> -them to the maintainer, see CHECKPATCH in MAINTAINERS.

> -EOM

> +	if ($quiet == 0) {

> +		print "\n";

> +		if ($clean == 1) {

> +			print "$vname has no obvious style problems and is ready for submission.\n";

> +		} else {

> +			print "$vname has style problems, please review.\n";

> +		}

>   	}

> -

>   	return $clean;

>   }
Bill Fischofer Aug. 30, 2016, 7:23 p.m. UTC | #2
This new checkpatch seems to also generate a new warning that probably
means we need to tweak it more as well:

./scripts/checkpatch.pl
0001-linux-dpdk-configure-harmonize-inline-support-with-l.patch

Gives this:

WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
#128:
deleted file mode 100644

Both this version and the previous one also generate a bunch of weird
warnings that I can't quite figure out:

WARNING: adding a line without newline at end of file
#343: FILE: platform/linux-dpdk/include/odp/api/plat/atomic_inlines.h:1:
+../../../../../linux-generic/include/odp/api/plat/atomic_inlines.h

CHECK: spaces preferred around that '/' (ctx:VxV)
#343: FILE: platform/linux-dpdk/include/odp/api/plat/atomic_inlines.h:1:
+../../../../../linux-generic/include/odp/api/plat/atomic_inlines.h
   ^

CHECK: spaces preferred around that '/' (ctx:VxV)
#343: FILE: platform/linux-dpdk/include/odp/api/plat/atomic_inlines.h:1:
+../../../../../linux-generic/include/odp/api/plat/atomic_inlines.h
      ^

CHECK: spaces preferred around that '/' (ctx:VxV)
#343: FILE: platform/linux-dpdk/include/odp/api/plat/atomic_inlines.h:1:
+../../../../../linux-generic/include/odp/api/plat/atomic_inlines.h
         ^

CHECK: spaces preferred around that '/' (ctx:VxV)
#343: FILE: platform/linux-dpdk/include/odp/api/plat/atomic_inlines.h:1:
+../../../../../linux-generic/include/odp/api/plat/atomic_inlines.h
            ^

CHECK: spaces preferred around that '/' (ctx:VxV)
#343: FILE: platform/linux-dpdk/include/odp/api/plat/atomic_inlines.h:1:
+../../../../../linux-generic/include/odp/api/plat/atomic_inlines.h
               ^

CHECK: spaces preferred around that '-' (ctx:VxV)
#343: FILE: platform/linux-dpdk/include/odp/api/plat/atomic_inlines.h:1:
+../../../../../linux-generic/include/odp/api/plat/atomic_inlines.h
                     ^

These go on and on. Is checkpatch being confused by symbolic links?  These
are is what linux-dpdk uses to refer to linux-generic files in the same
repo.

On Tue, Aug 30, 2016 at 2:17 PM, Maxim Uvarov <maxim.uvarov@linaro.org>
wrote:

> How is this patch was generated? Did you apply upstream patches on top of

> our current checkpatch? Were local changes included to that patch?

> We should not forget to pull all local things on top of updates.

>

> Maxim.

>

> On 08/30/16 20:14, Mike Holmes wrote:

>

>> The existing checkpatch used by ODP crashes when used on recent patches

>> by Bill,

>> update to the latest version. The latest version has a new test that we

>> need to disable

>> that warns about not using kernel types:

>>

>> PREFER_KERNEL_TYPES

>> check for c99 types like uint8_t used outside of uapi

>>

>> Signed-off-by: Mike Holmes <mike.holmes@linaro.org>

>> ---

>>   .checkpatch.conf      |   1 +

>>   scripts/checkpatch.pl | 820 ++++++++++++++++++++++++++++++

>> ++++++++++++--------

>>   2 files changed, 690 insertions(+), 131 deletions(-)

>>

>> diff --git a/.checkpatch.conf b/.checkpatch.conf

>> index 1e7d663..81723d6 100644

>> --- a/.checkpatch.conf

>> +++ b/.checkpatch.conf

>> @@ -8,3 +8,4 @@

>>   --ignore=BIT_MACRO

>>   --codespell

>>   --codespellfile=/usr/share/codespell/dictionary.txt

>> +--ignore=PREFER_KERNEL_TYPES

>> diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl

>> index 16316b9..4de3cc4 100755

>> --- a/scripts/checkpatch.pl

>> +++ b/scripts/checkpatch.pl

>> @@ -9,6 +9,7 @@ use strict;

>>   use POSIX;

>>   use File::Basename;

>>   use Cwd 'abs_path';

>> +use Term::ANSIColor qw(:constants);

>>     my $P = $0;

>>   my $D = dirname(abs_path($P));

>> @@ -24,13 +25,17 @@ 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;

>> @@ -48,7 +53,9 @@ 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/local/share/codespell/dictionary.txt";

>> +my $codespellfile = "/usr/share/codespell/dictionary.txt";

>> +my $color = 1;

>> +my $allow_c99_comments = 1;

>>     sub help {

>>         my ($exitcode) = @_;

>> @@ -64,13 +71,25 @@ Options:

>>     --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

>> -  --show-types               show the message "types" in the output

>>     --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

>> @@ -91,8 +110,9 @@ Options:

>>     --ignore-perl-version      override checking of perl version.  expect

>>                                runtime errors.

>>     --codespell                Use the codespell dictionary for

>> spelling/typos

>> -                             (default:/usr/local/share/cod

>> espell/dictionary.txt)

>> +                             (default:/usr/share/

>> codespell/dictionary.txt)

>>     --codespellfile            Use this codespell dictionary

>> +  --color                    Use colors when output is STDOUT (default:

>> on)

>>     -h, --help, --version      display this help and exit

>>     When FILE is - read standard input.

>> @@ -101,6 +121,37 @@ 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 = ();

>> +       for ($text =~ /\b(?:(?:CHK|WARN|ERROR)\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;

>> @@ -134,12 +185,15 @@ GetOptions(

>>         '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,

>> @@ -153,12 +207,15 @@ GetOptions(

>>         'test-only=s'   => \$tst_only,

>>         'codespell!'    => \$codespell,

>>         'codespellfile=s'       => \$codespellfile,

>> +       'color!'        => \$color,

>>         '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;

>>   @@ -171,9 +228,9 @@ if ($^V && $^V lt $minimum_perl_version) {

>>         }

>>   }

>>   +#if no filenames are given, push '-' to read patch from stdin

>>   if ($#ARGV < 0) {

>> -       print "$P: no input files\n";

>> -       exit(1);

>> +       push(@ARGV, '-');

>>   }

>>     sub hash_save_array_words {

>> @@ -196,12 +253,12 @@ sub hash_save_array_words {

>>   sub hash_show_words {

>>         my ($hashRef, $prefix) = @_;

>>   -     if ($quiet == 0 && keys %$hashRef) {

>> -               print "NOTE: $prefix message types:";

>> +       if (keys %$hashRef) {

>> +               print "\nNOTE: $prefix message types:";

>>                 foreach my $word (sort keys %$hashRef) {

>>                         print " $word";

>>                 }

>> -               print "\n\n";

>> +               print "\n";

>>         }

>>   }

>>   @@ -261,7 +318,8 @@ our $Sparse       = qr{

>>                         __init_refok|

>>                         __kprobes|

>>                         __ref|

>> -                       __rcu

>> +                       __rcu|

>> +                       __private

>>                 }x;

>>   our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};

>>   our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};

>> @@ -347,15 +405,22 @@ our $UTF8 = qr{

>>         | $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 $typeTypedefs = qr{(?x:

>> +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|)|

>> @@ -363,11 +428,7 @@ our $logFunctions = qr{(?x:

>>         WARN(?:_RATELIMIT|_ONCE|)|

>>         panic|

>>         MODULE_[A-Z_]+|

>> -       seq_vprintf|seq_printf|seq_puts|

>> -       ODP_ASSERT|ODP_DBG|ODP_ERR|ODP_ABORT|ODP_LOG|ODP_PRINT|

>> -       EXAMPLE_DBG|EXAMPLE_ERR|EXAMPLE_ABORT|

>> -       LOG_DBG|LOG_ERR|LOG_ABORT|

>> -       printf

>> +       seq_vprintf|seq_printf|seq_puts

>>   )};

>>     our $signature_tags = qr{(?xi:

>> @@ -422,6 +483,29 @@ our @typeList = (

>>         qr{${Ident}_handler_fn},

>>         @typeListMisordered,

>>   );

>> +

>> +our $C90_int_types = qr{(?x:

>> +       long\s+long\s+int\s+(?:un)?signed|

>> +       long\s+long\s+(?:un)?signed\s+int|

>> +       long\s+long\s+(?:un)?signed|

>> +       (?:(?:un)?signed\s+)?long\s+long\s+int|

>> +       (?:(?:un)?signed\s+)?long\s+long|

>> +       int\s+long\s+long\s+(?:un)?signed|

>> +       int\s+(?:(?:un)?signed\s+)?long\s+long|

>> +

>> +       long\s+int\s+(?:un)?signed|

>> +       long\s+(?:un)?signed\s+int|

>> +       long\s+(?:un)?signed|

>> +       (?:(?:un)?signed\s+)?long\s+int|

>> +       (?:(?:un)?signed\s+)?long|

>> +       int\s+long\s+(?:un)?signed|

>> +       int\s+(?:(?:un)?signed\s+)?long|

>> +

>> +       int\s+(?:un)?signed|

>> +       (?:(?:un)?signed\s+)?int

>> +)};

>> +

>> +our @typeListFile = ();

>>   our @typeListWithAttr = (

>>         @typeList,

>>         qr{struct\s+$InitAttribute\s+$Ident},

>> @@ -431,6 +515,7 @@ our @typeListWithAttr = (

>>   our @modifierList = (

>>         qr{fastcall},

>>   );

>> +our @modifierListFile = ();

>>     our @mode_permission_funcs = (

>>         ["module_param", 3],

>> @@ -514,13 +599,12 @@ if ($codespell) {

>>   $misspellings = join("|", sort keys %spelling_fix) if keys

>> %spelling_fix;

>>     sub build_types {

>> -       my $mods = "(?x:  \n" . join("|\n  ", @modifierList) . "\n)";

>> -       my $all = "(?x:  \n" . join("|\n  ", @typeList) . "\n)";

>> +       my $mods = "(?x:  \n" . join("|\n  ", (@modifierList,

>> @modifierListFile)) . "\n)";

>> +       my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile))

>> . "\n)";

>>         my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered)

>> . "\n)";

>>         my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr) .

>> "\n)";

>>         $Modifier       = qr{(?:$Attribute|$Sparse|$mods)};

>>         $BasicType      = qr{

>> -                               (?:$typeOtherOSTypedefs\b)|

>>                                 (?:$typeTypedefs\b)|

>>                                 (?:${all}\b)

>>                 }x;

>> @@ -528,7 +612,6 @@ sub build_types {

>>                         (?:$Modifier\s+|const\s+)*

>>                         (?:

>>                                 (?:typeof|__typeof__)\s*\([^\)]*\)|

>> -                               (?:$typeOtherOSTypedefs\b)|

>>                                 (?:$typeTypedefs\b)|

>>                                 (?:${all}\b)

>>                         )

>> @@ -546,7 +629,6 @@ sub build_types {

>>                         (?:

>>                                 (?:typeof|__typeof__)\s*\([^\)]*\)|

>>                                 (?:$typeTypedefs\b)|

>> -                               (?:$typeOtherOSTypedefs\b)|

>>                                 (?:${allWithAttr}\b)

>>                         )

>>                         (?:\s+$Modifier|\s+const)*

>> @@ -577,7 +659,7 @@ our $LvalOrFunc     = qr{((?:[\&\*]\s*)?$Lval)\s*($b

>> alanced_parens{0,1})\s*};

>>   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,2}\s*\(|

>> +       (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)

>> (?:_[A-Z0-9]+){1,6}\s*\(|

>>         (?:$Storage\s+)?LIST_HEAD\s*\(|

>>         (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(

>>   )};

>> @@ -719,10 +801,42 @@ my @fixed_inserted = ();

>>   my @fixed_deleted = ();

>>   my $fixlinenr = -1;

>>   +# If input is git commits, extract all commits from the commit

>> expressions.

>> +# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.

>> +die "$P: No git repository found\n" if ($git && !-e ".git");

>> +

>> +if ($git) {

>> +       my @commits = ();

>> +       foreach my $commit_expr (@ARGV) {

>> +               my $git_range;

>> +               if ($commit_expr =~ m/^(.*)-(\d+)$/) {

>> +                       $git_range = "-$2 $1";

>> +               } elsif ($commit_expr =~ m/\.\./) {

>> +                       $git_range = "$commit_expr";

>> +               } else {

>> +                       $git_range = "-1 $commit_expr";

>> +               }

>> +               my $lines = `git log --no-color --no-merges

>> --pretty=format:'%H %s' $git_range`;

>> +               foreach my $line (split(/\n/, $lines)) {

>> +                       $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;

>> +                       next if (!defined($1) || !defined($2));

>> +                       my $sha1 = $1;

>> +                       my $subject = $2;

>> +                       unshift(@commits, $sha1);

>> +                       $git_commits{$sha1} = $subject;

>> +               }

>> +       }

>> +       die "$P: no git commits after extraction!\n" if (@commits == 0);

>> +       @ARGV = @commits;

>> +}

>> +

>>   my $vname;

>>   for my $filename (@ARGV) {

>>         my $FILE;

>> -       if ($file) {

>> +       if ($git) {

>> +               open($FILE, '-|', "git format-patch -M --stdout -1

>> $filename") ||

>> +                       die "$P: $filename: git format-patch failed -

>> $!\n";

>> +       } elsif ($file) {

>>                 open($FILE, '-|', "diff -u /dev/null $filename") ||

>>                         die "$P: $filename: diff failed - $!\n";

>>         } elsif ($filename eq '-') {

>> @@ -733,6 +847,8 @@ for my $filename (@ARGV) {

>>         }

>>         if ($filename eq '-') {

>>                 $vname = 'Your patch';

>> +       } elsif ($git) {

>> +               $vname = "Commit " . substr($filename, 0, 12) . ' ("' .

>> $git_commits{$filename} . '")';

>>         } else {

>>                 $vname = $filename;

>>         }

>> @@ -741,6 +857,13 @@ for my $filename (@ARGV) {

>>                 push(@rawlines, $_);

>>         }

>>         close($FILE);

>> +

>> +       if ($#ARGV > 0 && $quiet == 0) {

>> +               print '-' x length($vname) . "\n";

>> +               print "$vname\n";

>> +               print '-' x length($vname) . "\n";

>> +       }

>> +

>>         if (!process($filename)) {

>>                 $exit = 1;

>>         }

>> @@ -750,6 +873,29 @@ for my $filename (@ARGV) {

>>         @fixed_inserted = ();

>>         @fixed_deleted = ();

>>         $fixlinenr = -1;

>> +       @modifierListFile = ();

>> +       @typeListFile = ();

>> +       build_types();

>> +}

>> +

>> +if (!$quiet) {

>> +       hash_show_words(\%use_type, "Used");

>> +       hash_show_words(\%ignore_type, "Ignored");

>> +

>> +       if ($^V lt 5.10.0) {

>> +               print << "EOM"

>> +

>> +NOTE: perl $^V is not modern enough to detect all possible issues.

>> +      An upgrade to at least perl v5.10.0 is suggested.

>> +EOM

>> +       }

>> +       if ($exit) {

>> +               print << "EOM"

>> +

>> +NOTE: If any of the errors are false positives, please report

>> +      them to the maintainer, see CHECKPATCH in MAINTAINERS.

>> +EOM

>> +       }

>>   }

>>     exit($exit);

>> @@ -999,13 +1145,18 @@ sub sanitise_line {

>>                 $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;

>>         }

>>   +     if ($allow_c99_comments && $res =~ m@(//.*$)@) {

>> +               my $match = $1;

>> +               $res =~ s/\Q$match\E/"$;" x length($match)/e;

>> +       }

>> +

>>         return $res;

>>   }

>>     sub get_quoted_string {

>>         my ($line, $rawline) = @_;

>>   -     return "" if ($line !~ m/(\"[X\t]+\")/g);

>> +       return "" if ($line !~ m/($String)/g);

>>         return substr($rawline, $-[0], $+[0] - $-[0]);

>>   }

>>   @@ -1614,13 +1765,13 @@ sub possible {

>>                         for my $modifier (split(' ', $possible)) {

>>                                 if ($modifier !~ $notPermitted) {

>>                                         warn "MODIFIER: $modifier

>> ($possible) ($line)\n" if ($dbg_possible);

>> -                                       push(@modifierList, $modifier);

>> +                                       push(@modifierListFile,

>> $modifier);

>>                                 }

>>                         }

>>                 } else {

>>                         warn "POSSIBLE: $possible ($line)\n" if

>> ($dbg_possible);

>> -                       push(@typeList, $possible);

>> +                       push(@typeListFile, $possible);

>>                 }

>>                 build_types();

>>         } else {

>> @@ -1645,15 +1796,32 @@ sub report {

>>             (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {

>>                 return 0;

>>         }

>> -       my $line;

>> +       my $output = '';

>> +       if (-t STDOUT && $color) {

>> +               if ($level eq 'ERROR') {

>> +                       $output .= RED;

>> +               } elsif ($level eq 'WARNING') {

>> +                       $output .= YELLOW;

>> +               } else {

>> +                       $output .= GREEN;

>> +               }

>> +       }

>> +       $output .= $prefix . $level . ':';

>>         if ($show_types) {

>> -               $line = "$prefix$level:$type: $msg\n";

>> -       } else {

>> -               $line = "$prefix$level: $msg\n";

>> +               $output .= BLUE if (-t STDOUT && $color);

>> +               $output .= "$type:";

>>         }

>> -       $line = (split('\n', $line))[0] . "\n" if ($terse);

>> +       $output .= RESET if (-t STDOUT && $color);

>> +       $output .= ' ' . $msg . "\n";

>>   -     push(our @report, $line);

>> +       if ($showfile) {

>> +               my @lines = split("\n", $output, -1);

>> +               splice(@lines, 1, 1);

>> +               $output = join("\n", @lines);

>> +       }

>> +       $output = (split('\n', $output))[0] . "\n" if ($terse);

>> +

>> +       push(our @report, $output);

>>         return 1;

>>   }

>> @@ -1899,11 +2067,13 @@ sub process {

>>         our $clean = 1;

>>         my $signoff = 0;

>>         my $is_patch = 0;

>> -

>>         my $in_header_lines = $file ? 0 : 1;

>>         my $in_commit_log = 0;          #Scanning lines before patch

>> +       my $has_commit_log = 0;         #Encountered lines before patch

>> +       my $commit_log_possible_stack_dump = 0;

>>         my $commit_log_long_line = 0;

>> -       my $reported_maintainer_file = 1; # No MAINTAINTERS so silence

>> warning

>> +       my $commit_log_has_diff = 0;

>> +       my $reported_maintainer_file = 0;

>>         my $non_utf8_charset = 0;

>>         my $last_blank_line = 0;

>> @@ -2036,7 +2206,8 @@ sub process {

>>                 my $rawline = $rawlines[$linenr - 1];

>>     #extract the line range in the file after the patch is applied

>> -               if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {

>> +               if (!$in_commit_log &&

>> +                   $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/)

>> {

>>                         $is_patch = 1;

>>                         $first_line = $linenr + 1;

>>                         $realline=$1-1;

>> @@ -2077,10 +2248,6 @@ sub process {

>>                 my $hunk_line = ($realcnt != 0);

>>   -#make up the handle for any error we report on this line

>> -               $prefix = "$filename:$realline: " if ($emacs && $file);

>> -               $prefix = "$filename:$linenr: " if ($emacs && !$file);

>> -

>>                 $here = "#$linenr: " if (!$file);

>>                 $here = "#$realline: " if ($file);

>>   @@ -2110,8 +2277,19 @@ sub process {

>>                         $found_file = 1;

>>                 }

>>   +#make up the handle for any error we report on this line

>> +               if ($showfile) {

>> +                       $prefix = "$realfile:$realline: "

>> +               } elsif ($emacs) {

>> +                       if ($file) {

>> +                               $prefix = "$filename:$realline: ";

>> +                       } else {

>> +                               $prefix = "$filename:$linenr: ";

>> +                       }

>> +               }

>> +

>>                 if ($found_file) {

>> -                       if ($realfile =~ m@^(drivers/net/|net/)@) {

>> +                       if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@)

>> {

>>                                 $check = 1;

>>                         } else {

>>                                 $check = $check_orig;

>> @@ -2127,6 +2305,17 @@ sub process {

>>                 $cnt_lines++ if ($realcnt != 0);

>>   +# Check if the commit log has what seems like a diff which can confuse

>> patch

>> +               if ($in_commit_log && !$commit_log_has_diff &&

>> +                   (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&

>> +                     $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||

>> +                    $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||

>> +                    $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {

>> +                       ERROR("DIFF_IN_COMMIT_MSG",

>> +                             "Avoid using diff content in the commit

>> message - patch(1) might not work\n" . $herecurr);

>> +                       $commit_log_has_diff = 1;

>> +               }

>> +

>>   # Check for incorrect file permissions

>>                 if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {

>>                         my $permhere = $here . "FILE: $realfile\n";

>> @@ -2238,18 +2427,46 @@ sub process {

>>                               "Remove Gerrit Change-Id's before

>> submitting upstream.\n" . $herecurr);

>>                 }

>>   +# Check if the commit log is in a possible stack dump

>> +               if ($in_commit_log && !$commit_log_possible_stack_dump &&

>> +                   ($line =~ /^\s*(?:WARNING:|BUG:)/ ||

>> +                    $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||

>> +                                       # timestamp

>> +                    $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) {

>> +                                       # stack dump address

>> +                       $commit_log_possible_stack_dump = 1;

>> +               }

>> +

>>   # Check for line lengths > 75 in commit log, warn once

>>                 if ($in_commit_log && !$commit_log_long_line &&

>> -                   length($line) > 75) {

>> +                   length($line) > 75 &&

>> +                   !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||

>> +                                       # file delta changes

>> +                     $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||

>> +                                       # filename then :

>> +                     $line =~ /^\s*(?:Fixes:|Link:)/i ||

>> +                                       # A Fixes: or Link: line

>> +                     $commit_log_possible_stack_dump)) {

>>                         WARN("COMMIT_LOG_LONG_LINE",

>>                              "Possible unwrapped commit description

>> (prefer a maximum 75 chars per line)\n" . $herecurr);

>>                         $commit_log_long_line = 1;

>>                 }

>>   +# Reset possible stack dump if a blank line is found

>> +               if ($in_commit_log && $commit_log_possible_stack_dump &&

>> +                   $line =~ /^\s*$/) {

>> +                       $commit_log_possible_stack_dump = 0;

>> +               }

>> +

>>   # Check for git id commit length and improperly formed commit

>> descriptions

>> -               if ($in_commit_log && $line =~

>> /\b(c)ommit\s+([0-9a-f]{5,})/i) {

>> -                       my $init_char = $1;

>> -                       my $orig_commit = lc($2);

>> +               if ($in_commit_log && !$commit_log_possible_stack_dump &&

>> +                   $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i

>> &&

>> +                   ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||

>> +                    ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i

>> &&

>> +                     $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&

>> +                     $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {

>> +                       my $init_char = "c";

>> +                       my $orig_commit = "";

>>                         my $short = 1;

>>                         my $long = 0;

>>                         my $case = 1;

>> @@ -2260,6 +2477,13 @@ sub process {

>>                         my $orig_desc = "commit description";

>>                         my $description = "";

>>   +                     if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {

>> +                               $init_char = $1;

>> +                               $orig_commit = lc($2);

>> +                       } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {

>> +                               $orig_commit = lc($1);

>> +                       }

>> +

>>                         $short = 0 if ($line =~

>> /\bcommit\s+[0-9a-f]{12,40}/i);

>>                         $long = 1 if ($line =~

>> /\bcommit\s+[0-9a-f]{41,}/i);

>>                         $space = 0 if ($line =~ /\bcommit [0-9a-f]/i);

>> @@ -2343,6 +2567,7 @@ sub process {

>>                       $rawline =~ /^(commit\b|from\b|[\w-]+:).*$/i)) {

>>                         $in_header_lines = 0;

>>                         $in_commit_log = 1;

>> +                       $has_commit_log = 1;

>>                 }

>>     # Check if there is UTF-8 in a commit log when a mail header has

>> explicitly

>> @@ -2514,16 +2739,60 @@ sub process {

>>   # check we are in a valid source file if not then ignore this hunk

>>                 next if ($realfile !~ /\.(h|c|s|S|pl|sh|dtsi|dts)$/);

>>   -#line length limit

>> -               if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&

>> -                   $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&

>> -                   !($line =~ /^\+\s*$logFunctions\s*\(\s*(?

>> :(KERN_\S+\s*|[^"]*))?$String\s*(?:|,|\)\s*;)\s*$/ ||

>> -                     $line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||

>> -                     $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) &&

>> -                   $length > $max_line_length)

>> -               {

>> -                       WARN("LONG_LINE",

>> -                            "line over $max_line_length characters\n" .

>> $herecurr);

>> +# line length limit (with some exclusions)

>> +#

>> +# There are a few types of lines that may extend beyond $max_line_length:

>> +#      logging functions like pr_info that end in a string

>> +#      lines with a single string

>> +#      #defines that are a single string

>> +#

>> +# There are 3 different line length message types:

>> +# LONG_LINE_COMMENT    a comment starts before but extends beyond

>> $max_linelength

>> +# LONG_LINE_STRING     a string starts before but extends beyond

>> $max_line_length

>> +# LONG_LINE            all other lines longer than $max_line_length

>> +#

>> +# if LONG_LINE is ignored, the other 2 types are also ignored

>> +#

>> +

>> +               if ($line =~ /^\+/ && $length > $max_line_length) {

>> +                       my $msg_type = "LONG_LINE";

>> +

>> +                       # Check the allowed long line types first

>> +

>> +                       # logging functions that end in a string that

>> starts

>> +                       # before $max_line_length

>> +                       if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?

>> :(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&

>> +                           length(expand_tabs(substr($line, 1,

>> length($line) - length($1) - 1))) <= $max_line_length) {

>> +                               $msg_type = "";

>> +

>> +                       # lines with only strings (w/ possible

>> termination)

>> +                       # #defines with only strings

>> +                       } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/

>> ||

>> +                                $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/)

>> {

>> +                               $msg_type = "";

>> +

>> +                       # EFI_GUID is another special case

>> +                       } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) {

>> +                               $msg_type = "";

>> +

>> +                       # Otherwise set the alternate message types

>> +

>> +                       # a comment starts before $max_line_length

>> +                       } elsif ($line =~ /($;[\s$;]*)$/ &&

>> +                                length(expand_tabs(substr($line, 1,

>> length($line) - length($1) - 1))) <= $max_line_length) {

>> +                               $msg_type = "LONG_LINE_COMMENT"

>> +

>> +                       # a quoted string starts before $max_line_length

>> +                       } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/

>> &&

>> +                                length(expand_tabs(substr($line, 1,

>> length($line) - length($1) - 1))) <= $max_line_length) {

>> +                               $msg_type = "LONG_LINE_STRING"

>> +                       }

>> +

>> +                       if ($msg_type ne "" &&

>> +                           (show_type("LONG_LINE") ||

>> show_type($msg_type))) {

>> +                               WARN($msg_type,

>> +                                    "line over $max_line_length

>> characters\n" . $herecurr);

>> +                       }

>>                 }

>>     # check for adding lines without a newline.

>> @@ -2581,6 +2850,19 @@ sub process {

>>                             "Logical continuations should be on the

>> previous line\n" . $hereprev);

>>                 }

>>   +# check indentation starts on a tab stop

>> +               if ($^V && $^V ge 5.10.0 &&

>> +                   $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$))/)

>> {

>> +                       my $indent = length($1);

>> +                       if ($indent % 8) {

>> +                               if (WARN("TABSTOP",

>> +                                        "Statements should start on a

>> tabstop\n" . $herecurr) &&

>> +                                   $fix) {

>> +                                       $fixed[$fixlinenr] =~ s@(^\+\t+)

>> +@$1 . "\t" x ($indent/8)@e;

>> +                               }

>> +                       }

>> +               }

>> +

>>   # 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*$/) {

>> @@ -2628,6 +2910,8 @@ sub process {

>>                         }

>>                 }

>>   +# Block comment styles

>> +# Networking with an initial /*

>>                 if ($realfile =~ m@^(drivers/net/|net/)@ &&

>>                     $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&

>>                     $rawline =~ /^\+[ \t]*\*/ &&

>> @@ -2636,22 +2920,23 @@ sub process {

>>                              "networking block comments don't use an

>> empty /* line, use /* Comment...\n" . $hereprev);

>>                 }

>>   -             if ($realfile =~ m@^(drivers/net/|net/)@ &&

>> -                   $prevrawline =~ /^\+[ \t]*\/\*/ &&          #starting

>> /*

>> +# Block comments use * on subsequent lines

>> +               if ($prevline =~ /$;[ \t]*$/ &&                 #ends in

>> comment

>> +                   $prevrawline =~ /^\+.*?\/\*/ &&             #starting

>> /*

>>                     $prevrawline !~ /\*\/[ \t]*$/ &&            #no

>> trailing */

>>                     $rawline =~ /^\+/ &&                        #line is

>> new

>>                     $rawline !~ /^\+[ \t]*\*/) {                #no

>> leading *

>> -                       WARN("NETWORKING_BLOCK_COMMENT_STYLE",

>> -                            "networking block comments start with * on

>> subsequent lines\n" . $hereprev);

>> +                       WARN("BLOCK_COMMENT_STYLE",

>> +                            "Block comments use * on subsequent lines\n"

>> . $hereprev);

>>                 }

>>   -             if ($realfile =~ m@^(drivers/net/|net/)@ &&

>> -                   $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&

>>  #trailing */

>> +# Block comments use */ on trailing lines

>> +               if ($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);

>> +                       WARN("BLOCK_COMMENT_STYLE",

>> +                            "Block comments use a trailing */ on a

>> separate line\n" . $herecurr);

>>                 }

>>     # check for missing blank lines after struct/union declarations

>> @@ -2957,14 +3242,21 @@ sub process {

>>                         substr($s, 0, length($c), '');

>>   +                     # remove inline comments

>> +                       $s =~ s/$;/ /g;

>> +                       $c =~ s/$;/ /g;

>> +

>> +                       # Find out how long the conditional actually is.

>> +                       my @newlines = ($c =~ /\n/gs);

>> +                       my $cond_lines = 1 + $#newlines;

>> +

>>                         # 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;

>> +                       while ($s =~ /\n\s+\\\n/) {

>> +                               $cond_lines += $s =~ s/\n\s+\\\n/\n/g;

>> +                       }

>>                         # We want to check the first line inside the block

>>                         # starting at the end of the conditional, so

>> remove:

>> @@ -3031,8 +3323,10 @@ sub process {

>>                         #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 ''))) {

>> +                       if ($check && $s ne '' &&

>> +                           (($sindent % 8) != 0 ||

>> +                            ($sindent < $indent) ||

>> +                            ($sindent > $indent + 8))) {

>>                                 WARN("SUSPECT_CODE_INDENT",

>>                                      "suspect code indent for conditional

>> statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");

>>                         }

>> @@ -3054,6 +3348,30 @@ sub process {

>>   #ignore lines not being added

>>                 next if ($line =~ /^[^\+]/);

>>   +# check for declarations of signed or unsigned without int

>> +               while ($line =~ m{\b($Declare)\s*(?!char\b|sho

>> rt\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {

>> +                       my $type = $1;

>> +                       my $var = $2;

>> +                       $var = "" if (!defined $var);

>> +                       if ($type =~ /^(?:(?:$Storage|$Inline|$Attr

>> ibute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {

>> +                               my $sign = $1;

>> +                               my $pointer = $2;

>> +

>> +                               $pointer = "" if (!defined $pointer);

>> +

>> +                               if (WARN("UNSPECIFIED_INT",

>> +                                        "Prefer '" . trim($sign) . "

>> int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) .

>> "'\n" . $herecurr) &&

>> +                                   $fix) {

>> +                                       my $decl = trim($sign) . " int ";

>> +                                       my $comp_pointer = $pointer;

>> +                                       $comp_pointer =~ s/\s//g;

>> +                                       $decl .= $comp_pointer;

>> +                                       $decl = rtrim($decl) if ($var eq

>> "");

>> +                                       $fixed[$fixlinenr] =~ s@

>> \b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;

>> +                               }

>> +                       }

>> +               }

>> +

>>   # TEST: allow direct testing of the type matcher.

>>                 if ($dbg_type) {

>>                         if ($line =~ /^.\s*$Declare\s*$/) {

>> @@ -3173,21 +3491,20 @@ sub process {

>>                 }

>>     # check for global initialisers.

>> -               if ($line =~ /^\+(\s*$Type\s*$Ident\s*(?:\s

>> +$Modifier))*\s*=\s*(0|NULL|false)\s*;/) {

>> +               if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modif

>> ier)*\s*=\s*($zero_initializer)\s*;/) {

>>                         if (ERROR("GLOBAL_INITIALISERS",

>> -                                 "do not initialise globals to 0 or

>> NULL\n" .

>> -                                     $herecurr) &&

>> +                                 "do not initialise globals to $1\n" .

>> $herecurr) &&

>>                             $fix) {

>> -                               $fixed[$fixlinenr] =~

>> s/($Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/$1;/;

>> +                               $fixed[$fixlinenr] =~

>> s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;

>>                         }

>>                 }

>>   # check for static initialisers.

>> -               if ($line =~ /^\+.*\bstatic\s.*=\s*(0|NULL|false)\s*;/) {

>> +               if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/)

>> {

>>                         if (ERROR("INITIALISED_STATIC",

>> -                                 "do not initialise statics to 0 or

>> NULL\n" .

>> +                                 "do not initialise statics to $1\n" .

>>                                       $herecurr) &&

>>                             $fix) {

>> -                               $fixed[$fixlinenr] =~

>> s/(\bstatic\s.*?)\s*=\s*(0|NULL|false)\s*;/$1;/;

>> +                               $fixed[$fixlinenr] =~

>> s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;

>>                         }

>>                 }

>>   @@ -3268,7 +3585,6 @@ sub process {

>>                     $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/

>> &&

>>                     $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&

>>                     $line !~ /\b$typeTypedefs\b/ &&

>> -                   $line !~ /\b$typeOtherOSTypedefs\b/ &&

>>                     $line !~ /\b__bitwise(?:__|)\b/) {

>>                         WARN("NEW_TYPEDEFS",

>>                              "do not add new typedefs\n" . $herecurr);

>> @@ -3330,13 +3646,15 @@ sub process {

>>                         }

>>                 }

>>   -# # 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;

>> -#              }

>> +# avoid BUG() or BUG_ON()

>> +               if ($line =~ /\b(?:BUG|BUG_ON)\b/) {

>> +                       my $msg_type = \&WARN;

>> +                       $msg_type = \&CHK if ($file);

>> +                       &{$msg_type}("AVOID_BUG",

>> +                                    "Avoid crashing the kernel - try

>> using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);

>> +               }

>>   +# avoid LINUX_VERSION_CODE

>>                 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);

>> @@ -3923,7 +4241,7 @@ sub process {

>>   ##            }

>>     #need space before brace following if, while, etc

>> -               if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\){/) ||

>> +               if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||

>>                     $line =~ /do\{/) {

>>                         if (ERROR("SPACING",

>>                                   "space required before the open brace

>> '{'\n" . $herecurr) &&

>> @@ -4070,6 +4388,35 @@ sub process {

>>                         }

>>                 }

>>   +# comparisons with a constant or upper case identifier on the left

>> +#      avoid cases like "foo + BAR < baz"

>> +#      only fix matches surrounded by parentheses to avoid incorrect

>> +#      conversions like "FOO < baz() + 5" being "misfixed" to "baz() >

>> FOO + 5"

>> +               if ($^V && $^V ge 5.10.0 &&

>> +                   $line =~ /^\+(.*)\b($Constant|[A-Z_][A-

>> Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {

>> +                       my $lead = $1;

>> +                       my $const = $2;

>> +                       my $comp = $3;

>> +                       my $to = $4;

>> +                       my $newcomp = $comp;

>> +                       if ($lead !~ /(?:$Operators|\.)\s*$/ &&

>> +                           $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&

>> +                           WARN("CONSTANT_COMPARISON",

>> +                                "Comparisons should place the constant

>> on the right side of the test\n" . $herecurr) &&

>> +                           $fix) {

>> +                               if ($comp eq "<") {

>> +                                       $newcomp = ">";

>> +                               } elsif ($comp eq "<=") {

>> +                                       $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;

>> @@ -4256,12 +4603,6 @@ sub process {

>>   #Ignore SI style variants like nS, mV and dB (ie: max_uV,

>> regulator_min_uA_show)

>>                             $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/

>> &&

>>   #Ignore some three character SI units explicitly, like MiB and KHz

>> -                           $var !~ /\bCU_/ &&

>> -                           $var !~ /\bPRI[diux]32/ &&

>> -                           $var !~ /\bPRI[diux]64/ &&

>> -                           $var !~ /\bSCN[diux]8/ &&

>> -                           $var !~ /\bSCN[diux]32/ &&

>> -                           $var !~ /\bSCN[diux]64/ &&

>>                             $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/)

>> {

>>                                 while ($var =~ m{($Ident)}g) {

>>                                         my $word = $1;

>> @@ -4331,7 +4672,7 @@ sub process {

>>                         #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 =~ /\#\#/);

>> +                       $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~

>> /\#\#\s*(?:__VA_ARGS__|args)\b/);

>>                         $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:

>> \([^\)]*\))?\s*//;

>>                         $dstat =~ s/$;//g;

>> @@ -4342,16 +4683,19 @@ 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/)

>> +                       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/a

>> sm_volatile/g;

>> +

>>                         my $exceptions = qr{

>>                                 $Declare|

>>                                 module_param_named|

>> @@ -4362,7 +4706,8 @@ sub process {

>>                                 union|

>>                                 struct|

>>                                 \.$Ident\s*=\s*|

>> -                               ^\"|\"$

>> +                               ^\"|\"$|

>> +                               ^\[

>>                         }x;

>>                         #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";

>>                         if ($dstat ne '' &&

>> @@ -4629,7 +4974,7 @@ sub process {

>>   # to grep for the string.  Make exceptions when the previous string

>> ends in a

>>   # newline (multiple lines in one string constant) or '\t', '\r', ';',

>> or '{'

>>   # (common in inline assembly) or is a octal \123 or hexadecimal \xaf

>> value

>> -               if ($line =~ /^\+\s*"[X\t]*"/ &&

>> +               if ($line =~ /^\+\s*$String/ &&

>>                     $prevline =~ /"\s*$/ &&

>>                     $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-

>> 9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {

>>                         if (WARN("SPLIT_STRING",

>> @@ -4675,27 +5020,31 @@ sub process {

>>                 }

>>     # concatenated string without spaces between elements

>> -               if ($line =~ /"X+"[A-Z_]+/ || $line =~ /[A-Z_]+"X+"/) {

>> +               if ($line =~ /$String[A-Z_]/ || $line =~

>> /[A-Za-z0-9_]$String/) {

>>                         CHK("CONCATENATED_STRING",

>>                             "Concatenated strings should use spaces

>> between elements\n" . $herecurr);

>>                 }

>>     # uncoalesced string fragments

>> -               if ($line =~ /"X*"\s*"/) {

>> +               if ($line =~ /$String\s*"/) {

>>                         WARN("STRING_FRAGMENTS",

>>                              "Consecutive strings are generally better as

>> a single string\n" . $herecurr);

>>                 }

>>   -# check for %L{u,d,i} in strings

>> +# check for %L{u,d,i} and 0x%[udi] in strings

>>                 my $string;

>>                 while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {

>>                         $string = substr($rawline, $-[1], $+[1] - $-[1]);

>>                         $string =~ s/%%/__/g;

>> -                       if ($string =~ /(?<!%)%L[udi]/) {

>> +                       if ($string =~ /(?<!%)%[\*\d\.\$]*L[udi]/) {

>>                                 WARN("PRINTF_L",

>>                                      "\%Ld/%Lu are not-standard C, use

>> %lld/%llu\n" . $herecurr);

>>                                 last;

>>                         }

>> +                       if ($string =~ /0x%[\*\d\.\$\Llzth]*[udi]/) {

>> +                               ERROR("PRINTF_0xDECIMAL",

>> +                                     "Prefixing 0x with decimal output

>> is defective\n" . $herecurr);

>> +                       }

>>                 }

>>     # check for line continuations in quoted strings with odd counts of "

>> @@ -4713,10 +5062,34 @@ sub process {

>>     # 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 and this check is

>> probably not required\n" . $hereprev);

>> +                       my $tested = quotemeta($1);

>> +                       my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';

>> +                       if ($line =~ /\b(kfree|usb_free_urb|debugfs

>> _remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {

>> +                               my $func = $1;

>> +                               if (WARN('NEEDLESS_IF',

>> +                                        "$func(NULL) is safe and this

>> check is probably not required\n" . $hereprev) &&

>> +                                   $fix) {

>> +                                       my $do_fix = 1;

>> +                                       my $leading_tabs = "";

>> +                                       my $new_leading_tabs = "";

>> +                                       if ($lines[$linenr - 2] =~

>> /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {

>> +                                               $leading_tabs = $1;

>> +                                       } else {

>> +                                               $do_fix = 0;

>> +                                       }

>> +                                       if ($lines[$linenr - 1] =~

>> /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {

>> +                                               $new_leading_tabs = $1;

>> +                                               if (length($leading_tabs)

>> + 1 ne length($new_leading_tabs)) {

>> +                                                       $do_fix = 0;

>> +                                               }

>> +                                       } else {

>> +                                               $do_fix = 0;

>> +                                       }

>> +                                       if ($do_fix) {

>> +

>>  fix_delete_line($fixlinenr - 1, $prevrawline);

>> +                                               $fixed[$fixlinenr] =~

>> s/^\+$new_leading_tabs/\+$leading_tabs/;

>> +                                       }

>> +                               }

>>                         }

>>                 }

>>   @@ -4902,12 +5275,69 @@ sub process {

>>                         }

>>                 }

>>   # check for memory barriers without a comment.

>> -               if ($line =~ /\b(mb|rmb|wmb|read_barrier_de

>> pends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) {

>> +

>> +               my $barriers = qr{

>> +                       mb|

>> +                       rmb|

>> +                       wmb|

>> +                       read_barrier_depends

>> +               }x;

>> +               my $barrier_stems = qr{

>> +                       mb__before_atomic|

>> +                       mb__after_atomic|

>> +                       store_release|

>> +                       load_acquire|

>> +                       store_mb|

>> +                       (?:$barriers)

>> +               }x;

>> +               my $all_barriers = qr{

>> +                       (?:$barriers)|

>> +                       smp_(?:$barrier_stems)|

>> +                       virt_(?:$barrier_stems)

>> +               }x;

>> +

>> +               if ($line =~ /\b(?:$all_barriers)\s*\(/) {

>>                         if (!ctx_has_comment($first_line, $linenr)) {

>>                                 WARN("MEMORY_BARRIER",

>>                                      "memory barrier without comment\n" .

>> $herecurr);

>>                         }

>>                 }

>> +

>> +               my $underscore_smp_barriers =

>> qr{__smp_(?:$barrier_stems)}x;

>> +

>> +               if ($realfile !~ m@^include/asm-generic/@ &&

>> +                   $realfile !~ m@/barrier\.h$@ &&

>> +                   $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&

>> +                   $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/)

>> {

>> +                       WARN("MEMORY_BARRIER",

>> +                            "__smp memory barriers shouldn't be used

>> outside barrier.h and asm-generic\n" . $herecurr);

>> +               }

>> +

>> +# check for waitqueue_active without a comment.

>> +               if ($line =~ /\bwaitqueue_active\s*\(/) {

>> +                       if (!ctx_has_comment($first_line, $linenr)) {

>> +                               WARN("WAITQUEUE_ACTIVE",

>> +                                    "waitqueue_active without comment\n"

>> . $herecurr);

>> +                       }

>> +               }

>> +

>> +# Check for expedited grace periods that interrupt non-idle non-nohz

>> +# online CPUs.  These expedited can therefore degrade real-time response

>> +# if used carelessly, and should be avoided where not absolutely

>> +# needed.  It is always OK to use synchronize_rcu_expedited() and

>> +# synchronize_sched_expedited() at boot time (before real-time

>> applications

>> +# start) and in error situations where real-time response is compromised

>> in

>> +# any case.  Note that synchronize_srcu_expedited() does -not- interrupt

>> +# other CPUs, so don't warn on uses of synchronize_srcu_expedited().

>> +# Of course, nothing comes for free, and srcu_read_lock() and

>

>
Mike Holmes Aug. 31, 2016, 3:16 p.m. UTC | #3
On 30 August 2016 at 15:23, Bill Fischofer <bill.fischofer@linaro.org>
wrote:

> This new checkpatch seems to also generate a new warning that probably

> means we need to tweak it more as well:

>

> ./scripts/checkpatch.pl

> 0001-linux-dpdk-configure-harmonize-inline-support-with-l.patch

>

> Gives this:

>


I dont see any of these, will sync with you



>

> WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?

> #128:

> deleted file mode 100644

>

> Both this version and the previous one also generate a bunch of weird

> warnings that I can't quite figure out:

>

> WARNING: adding a line without newline at end of file

> #343: FILE: platform/linux-dpdk/include/odp/api/plat/atomic_inlines.h:1:

> +../../../../../linux-generic/include/odp/api/plat/atomic_inlines.h

>

> CHECK: spaces preferred around that '/' (ctx:VxV)

> #343: FILE: platform/linux-dpdk/include/odp/api/plat/atomic_inlines.h:1:

> +../../../../../linux-generic/include/odp/api/plat/atomic_inlines.h

>    ^

>

> CHECK: spaces preferred around that '/' (ctx:VxV)

> #343: FILE: platform/linux-dpdk/include/odp/api/plat/atomic_inlines.h:1:

> +../../../../../linux-generic/include/odp/api/plat/atomic_inlines.h

>       ^

>

> CHECK: spaces preferred around that '/' (ctx:VxV)

> #343: FILE: platform/linux-dpdk/include/odp/api/plat/atomic_inlines.h:1:

> +../../../../../linux-generic/include/odp/api/plat/atomic_inlines.h

>          ^

>

> CHECK: spaces preferred around that '/' (ctx:VxV)

> #343: FILE: platform/linux-dpdk/include/odp/api/plat/atomic_inlines.h:1:

> +../../../../../linux-generic/include/odp/api/plat/atomic_inlines.h

>             ^

>

> CHECK: spaces preferred around that '/' (ctx:VxV)

> #343: FILE: platform/linux-dpdk/include/odp/api/plat/atomic_inlines.h:1:

> +../../../../../linux-generic/include/odp/api/plat/atomic_inlines.h

>                ^

>

> CHECK: spaces preferred around that '-' (ctx:VxV)

> #343: FILE: platform/linux-dpdk/include/odp/api/plat/atomic_inlines.h:1:

> +../../../../../linux-generic/include/odp/api/plat/atomic_inlines.h

>                      ^

>

> These go on and on. Is checkpatch being confused by symbolic links?  These

> are is what linux-dpdk uses to refer to linux-generic files in the same

> repo.

>

> On Tue, Aug 30, 2016 at 2:17 PM, Maxim Uvarov <maxim.uvarov@linaro.org>

> wrote:

>

> > How is this patch was generated? Did you apply upstream patches on top of

> > our current checkpatch? Were local changes included to that patch?

> > We should not forget to pull all local things on top of updates.

> >

> > Maxim.

> >

> > On 08/30/16 20:14, Mike Holmes wrote:

> >

> >> The existing checkpatch used by ODP crashes when used on recent patches

> >> by Bill,

> >> update to the latest version. The latest version has a new test that we

> >> need to disable

> >> that warns about not using kernel types:

> >>

> >> PREFER_KERNEL_TYPES

> >> check for c99 types like uint8_t used outside of uapi

> >>

> >> Signed-off-by: Mike Holmes <mike.holmes@linaro.org>

> >> ---

> >>   .checkpatch.conf      |   1 +

> >>   scripts/checkpatch.pl | 820 ++++++++++++++++++++++++++++++

> >> ++++++++++++--------

> >>   2 files changed, 690 insertions(+), 131 deletions(-)

> >>

> >> diff --git a/.checkpatch.conf b/.checkpatch.conf

> >> index 1e7d663..81723d6 100644

> >> --- a/.checkpatch.conf

> >> +++ b/.checkpatch.conf

> >> @@ -8,3 +8,4 @@

> >>   --ignore=BIT_MACRO

> >>   --codespell

> >>   --codespellfile=/usr/share/codespell/dictionary.txt

> >> +--ignore=PREFER_KERNEL_TYPES

> >> diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl

> >> index 16316b9..4de3cc4 100755

> >> --- a/scripts/checkpatch.pl

> >> +++ b/scripts/checkpatch.pl

> >> @@ -9,6 +9,7 @@ use strict;

> >>   use POSIX;

> >>   use File::Basename;

> >>   use Cwd 'abs_path';

> >> +use Term::ANSIColor qw(:constants);

> >>     my $P = $0;

> >>   my $D = dirname(abs_path($P));

> >> @@ -24,13 +25,17 @@ 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;

> >> @@ -48,7 +53,9 @@ 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/local/share/codespell/dictionary.txt";

> >> +my $codespellfile = "/usr/share/codespell/dictionary.txt";

> >> +my $color = 1;

> >> +my $allow_c99_comments = 1;

> >>     sub help {

> >>         my ($exitcode) = @_;

> >> @@ -64,13 +71,25 @@ Options:

> >>     --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

> >> -  --show-types               show the message "types" in the output

> >>     --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

> >> @@ -91,8 +110,9 @@ Options:

> >>     --ignore-perl-version      override checking of perl version.

> expect

> >>                                runtime errors.

> >>     --codespell                Use the codespell dictionary for

> >> spelling/typos

> >> -                             (default:/usr/local/share/cod

> >> espell/dictionary.txt)

> >> +                             (default:/usr/share/

> >> codespell/dictionary.txt)

> >>     --codespellfile            Use this codespell dictionary

> >> +  --color                    Use colors when output is STDOUT (default:

> >> on)

> >>     -h, --help, --version      display this help and exit

> >>     When FILE is - read standard input.

> >> @@ -101,6 +121,37 @@ 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 = ();

> >> +       for ($text =~ /\b(?:(?:CHK|WARN|ERROR)\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;

> >> @@ -134,12 +185,15 @@ GetOptions(

> >>         '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,

> >> @@ -153,12 +207,15 @@ GetOptions(

> >>         'test-only=s'   => \$tst_only,

> >>         'codespell!'    => \$codespell,

> >>         'codespellfile=s'       => \$codespellfile,

> >> +       'color!'        => \$color,

> >>         '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;

> >>   @@ -171,9 +228,9 @@ if ($^V && $^V lt $minimum_perl_version) {

> >>         }

> >>   }

> >>   +#if no filenames are given, push '-' to read patch from stdin

> >>   if ($#ARGV < 0) {

> >> -       print "$P: no input files\n";

> >> -       exit(1);

> >> +       push(@ARGV, '-');

> >>   }

> >>     sub hash_save_array_words {

> >> @@ -196,12 +253,12 @@ sub hash_save_array_words {

> >>   sub hash_show_words {

> >>         my ($hashRef, $prefix) = @_;

> >>   -     if ($quiet == 0 && keys %$hashRef) {

> >> -               print "NOTE: $prefix message types:";

> >> +       if (keys %$hashRef) {

> >> +               print "\nNOTE: $prefix message types:";

> >>                 foreach my $word (sort keys %$hashRef) {

> >>                         print " $word";

> >>                 }

> >> -               print "\n\n";

> >> +               print "\n";

> >>         }

> >>   }

> >>   @@ -261,7 +318,8 @@ our $Sparse       = qr{

> >>                         __init_refok|

> >>                         __kprobes|

> >>                         __ref|

> >> -                       __rcu

> >> +                       __rcu|

> >> +                       __private

> >>                 }x;

> >>   our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};

> >>   our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};

> >> @@ -347,15 +405,22 @@ our $UTF8 = qr{

> >>         | $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 $typeTypedefs = qr{(?x:

> >> +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|)|

> >> @@ -363,11 +428,7 @@ our $logFunctions = qr{(?x:

> >>         WARN(?:_RATELIMIT|_ONCE|)|

> >>         panic|

> >>         MODULE_[A-Z_]+|

> >> -       seq_vprintf|seq_printf|seq_puts|

> >> -       ODP_ASSERT|ODP_DBG|ODP_ERR|ODP_ABORT|ODP_LOG|ODP_PRINT|

> >> -       EXAMPLE_DBG|EXAMPLE_ERR|EXAMPLE_ABORT|

> >> -       LOG_DBG|LOG_ERR|LOG_ABORT|

> >> -       printf

> >> +       seq_vprintf|seq_printf|seq_puts

> >>   )};

> >>     our $signature_tags = qr{(?xi:

> >> @@ -422,6 +483,29 @@ our @typeList = (

> >>         qr{${Ident}_handler_fn},

> >>         @typeListMisordered,

> >>   );

> >> +

> >> +our $C90_int_types = qr{(?x:

> >> +       long\s+long\s+int\s+(?:un)?signed|

> >> +       long\s+long\s+(?:un)?signed\s+int|

> >> +       long\s+long\s+(?:un)?signed|

> >> +       (?:(?:un)?signed\s+)?long\s+long\s+int|

> >> +       (?:(?:un)?signed\s+)?long\s+long|

> >> +       int\s+long\s+long\s+(?:un)?signed|

> >> +       int\s+(?:(?:un)?signed\s+)?long\s+long|

> >> +

> >> +       long\s+int\s+(?:un)?signed|

> >> +       long\s+(?:un)?signed\s+int|

> >> +       long\s+(?:un)?signed|

> >> +       (?:(?:un)?signed\s+)?long\s+int|

> >> +       (?:(?:un)?signed\s+)?long|

> >> +       int\s+long\s+(?:un)?signed|

> >> +       int\s+(?:(?:un)?signed\s+)?long|

> >> +

> >> +       int\s+(?:un)?signed|

> >> +       (?:(?:un)?signed\s+)?int

> >> +)};

> >> +

> >> +our @typeListFile = ();

> >>   our @typeListWithAttr = (

> >>         @typeList,

> >>         qr{struct\s+$InitAttribute\s+$Ident},

> >> @@ -431,6 +515,7 @@ our @typeListWithAttr = (

> >>   our @modifierList = (

> >>         qr{fastcall},

> >>   );

> >> +our @modifierListFile = ();

> >>     our @mode_permission_funcs = (

> >>         ["module_param", 3],

> >> @@ -514,13 +599,12 @@ if ($codespell) {

> >>   $misspellings = join("|", sort keys %spelling_fix) if keys

> >> %spelling_fix;

> >>     sub build_types {

> >> -       my $mods = "(?x:  \n" . join("|\n  ", @modifierList) . "\n)";

> >> -       my $all = "(?x:  \n" . join("|\n  ", @typeList) . "\n)";

> >> +       my $mods = "(?x:  \n" . join("|\n  ", (@modifierList,

> >> @modifierListFile)) . "\n)";

> >> +       my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile))

> >> . "\n)";

> >>         my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered)

> >> . "\n)";

> >>         my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr)

> .

> >> "\n)";

> >>         $Modifier       = qr{(?:$Attribute|$Sparse|$mods)};

> >>         $BasicType      = qr{

> >> -                               (?:$typeOtherOSTypedefs\b)|

> >>                                 (?:$typeTypedefs\b)|

> >>                                 (?:${all}\b)

> >>                 }x;

> >> @@ -528,7 +612,6 @@ sub build_types {

> >>                         (?:$Modifier\s+|const\s+)*

> >>                         (?:

> >>                                 (?:typeof|__typeof__)\s*\([^\)]*\)|

> >> -                               (?:$typeOtherOSTypedefs\b)|

> >>                                 (?:$typeTypedefs\b)|

> >>                                 (?:${all}\b)

> >>                         )

> >> @@ -546,7 +629,6 @@ sub build_types {

> >>                         (?:

> >>                                 (?:typeof|__typeof__)\s*\([^\)]*\)|

> >>                                 (?:$typeTypedefs\b)|

> >> -                               (?:$typeOtherOSTypedefs\b)|

> >>                                 (?:${allWithAttr}\b)

> >>                         )

> >>                         (?:\s+$Modifier|\s+const)*

> >> @@ -577,7 +659,7 @@ our $LvalOrFunc     = qr{((?:[\&\*]\s*)?$Lval)\s*($b

> >> alanced_parens{0,1})\s*};

> >>   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,2}\s*\(|

> >> +       (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)

> >> (?:_[A-Z0-9]+){1,6}\s*\(|

> >>         (?:$Storage\s+)?LIST_HEAD\s*\(|

> >>         (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(

> >>   )};

> >> @@ -719,10 +801,42 @@ my @fixed_inserted = ();

> >>   my @fixed_deleted = ();

> >>   my $fixlinenr = -1;

> >>   +# If input is git commits, extract all commits from the commit

> >> expressions.

> >> +# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.

> >> +die "$P: No git repository found\n" if ($git && !-e ".git");

> >> +

> >> +if ($git) {

> >> +       my @commits = ();

> >> +       foreach my $commit_expr (@ARGV) {

> >> +               my $git_range;

> >> +               if ($commit_expr =~ m/^(.*)-(\d+)$/) {

> >> +                       $git_range = "-$2 $1";

> >> +               } elsif ($commit_expr =~ m/\.\./) {

> >> +                       $git_range = "$commit_expr";

> >> +               } else {

> >> +                       $git_range = "-1 $commit_expr";

> >> +               }

> >> +               my $lines = `git log --no-color --no-merges

> >> --pretty=format:'%H %s' $git_range`;

> >> +               foreach my $line (split(/\n/, $lines)) {

> >> +                       $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;

> >> +                       next if (!defined($1) || !defined($2));

> >> +                       my $sha1 = $1;

> >> +                       my $subject = $2;

> >> +                       unshift(@commits, $sha1);

> >> +                       $git_commits{$sha1} = $subject;

> >> +               }

> >> +       }

> >> +       die "$P: no git commits after extraction!\n" if (@commits == 0);

> >> +       @ARGV = @commits;

> >> +}

> >> +

> >>   my $vname;

> >>   for my $filename (@ARGV) {

> >>         my $FILE;

> >> -       if ($file) {

> >> +       if ($git) {

> >> +               open($FILE, '-|', "git format-patch -M --stdout -1

> >> $filename") ||

> >> +                       die "$P: $filename: git format-patch failed -

> >> $!\n";

> >> +       } elsif ($file) {

> >>                 open($FILE, '-|', "diff -u /dev/null $filename") ||

> >>                         die "$P: $filename: diff failed - $!\n";

> >>         } elsif ($filename eq '-') {

> >> @@ -733,6 +847,8 @@ for my $filename (@ARGV) {

> >>         }

> >>         if ($filename eq '-') {

> >>                 $vname = 'Your patch';

> >> +       } elsif ($git) {

> >> +               $vname = "Commit " . substr($filename, 0, 12) . ' ("' .

> >> $git_commits{$filename} . '")';

> >>         } else {

> >>                 $vname = $filename;

> >>         }

> >> @@ -741,6 +857,13 @@ for my $filename (@ARGV) {

> >>                 push(@rawlines, $_);

> >>         }

> >>         close($FILE);

> >> +

> >> +       if ($#ARGV > 0 && $quiet == 0) {

> >> +               print '-' x length($vname) . "\n";

> >> +               print "$vname\n";

> >> +               print '-' x length($vname) . "\n";

> >> +       }

> >> +

> >>         if (!process($filename)) {

> >>                 $exit = 1;

> >>         }

> >> @@ -750,6 +873,29 @@ for my $filename (@ARGV) {

> >>         @fixed_inserted = ();

> >>         @fixed_deleted = ();

> >>         $fixlinenr = -1;

> >> +       @modifierListFile = ();

> >> +       @typeListFile = ();

> >> +       build_types();

> >> +}

> >> +

> >> +if (!$quiet) {

> >> +       hash_show_words(\%use_type, "Used");

> >> +       hash_show_words(\%ignore_type, "Ignored");

> >> +

> >> +       if ($^V lt 5.10.0) {

> >> +               print << "EOM"

> >> +

> >> +NOTE: perl $^V is not modern enough to detect all possible issues.

> >> +      An upgrade to at least perl v5.10.0 is suggested.

> >> +EOM

> >> +       }

> >> +       if ($exit) {

> >> +               print << "EOM"

> >> +

> >> +NOTE: If any of the errors are false positives, please report

> >> +      them to the maintainer, see CHECKPATCH in MAINTAINERS.

> >> +EOM

> >> +       }

> >>   }

> >>     exit($exit);

> >> @@ -999,13 +1145,18 @@ sub sanitise_line {

> >>                 $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;

> >>         }

> >>   +     if ($allow_c99_comments && $res =~ m@(//.*$)@) {

> >> +               my $match = $1;

> >> +               $res =~ s/\Q$match\E/"$;" x length($match)/e;

> >> +       }

> >> +

> >>         return $res;

> >>   }

> >>     sub get_quoted_string {

> >>         my ($line, $rawline) = @_;

> >>   -     return "" if ($line !~ m/(\"[X\t]+\")/g);

> >> +       return "" if ($line !~ m/($String)/g);

> >>         return substr($rawline, $-[0], $+[0] - $-[0]);

> >>   }

> >>   @@ -1614,13 +1765,13 @@ sub possible {

> >>                         for my $modifier (split(' ', $possible)) {

> >>                                 if ($modifier !~ $notPermitted) {

> >>                                         warn "MODIFIER: $modifier

> >> ($possible) ($line)\n" if ($dbg_possible);

> >> -                                       push(@modifierList, $modifier);

> >> +                                       push(@modifierListFile,

> >> $modifier);

> >>                                 }

> >>                         }

> >>                 } else {

> >>                         warn "POSSIBLE: $possible ($line)\n" if

> >> ($dbg_possible);

> >> -                       push(@typeList, $possible);

> >> +                       push(@typeListFile, $possible);

> >>                 }

> >>                 build_types();

> >>         } else {

> >> @@ -1645,15 +1796,32 @@ sub report {

> >>             (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {

> >>                 return 0;

> >>         }

> >> -       my $line;

> >> +       my $output = '';

> >> +       if (-t STDOUT && $color) {

> >> +               if ($level eq 'ERROR') {

> >> +                       $output .= RED;

> >> +               } elsif ($level eq 'WARNING') {

> >> +                       $output .= YELLOW;

> >> +               } else {

> >> +                       $output .= GREEN;

> >> +               }

> >> +       }

> >> +       $output .= $prefix . $level . ':';

> >>         if ($show_types) {

> >> -               $line = "$prefix$level:$type: $msg\n";

> >> -       } else {

> >> -               $line = "$prefix$level: $msg\n";

> >> +               $output .= BLUE if (-t STDOUT && $color);

> >> +               $output .= "$type:";

> >>         }

> >> -       $line = (split('\n', $line))[0] . "\n" if ($terse);

> >> +       $output .= RESET if (-t STDOUT && $color);

> >> +       $output .= ' ' . $msg . "\n";

> >>   -     push(our @report, $line);

> >> +       if ($showfile) {

> >> +               my @lines = split("\n", $output, -1);

> >> +               splice(@lines, 1, 1);

> >> +               $output = join("\n", @lines);

> >> +       }

> >> +       $output = (split('\n', $output))[0] . "\n" if ($terse);

> >> +

> >> +       push(our @report, $output);

> >>         return 1;

> >>   }

> >> @@ -1899,11 +2067,13 @@ sub process {

> >>         our $clean = 1;

> >>         my $signoff = 0;

> >>         my $is_patch = 0;

> >> -

> >>         my $in_header_lines = $file ? 0 : 1;

> >>         my $in_commit_log = 0;          #Scanning lines before patch

> >> +       my $has_commit_log = 0;         #Encountered lines before patch

> >> +       my $commit_log_possible_stack_dump = 0;

> >>         my $commit_log_long_line = 0;

> >> -       my $reported_maintainer_file = 1; # No MAINTAINTERS so silence

> >> warning

> >> +       my $commit_log_has_diff = 0;

> >> +       my $reported_maintainer_file = 0;

> >>         my $non_utf8_charset = 0;

> >>         my $last_blank_line = 0;

> >> @@ -2036,7 +2206,8 @@ sub process {

> >>                 my $rawline = $rawlines[$linenr - 1];

> >>     #extract the line range in the file after the patch is applied

> >> -               if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/)

> {

> >> +               if (!$in_commit_log &&

> >> +                   $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))?

> \@\@/)

> >> {

> >>                         $is_patch = 1;

> >>                         $first_line = $linenr + 1;

> >>                         $realline=$1-1;

> >> @@ -2077,10 +2248,6 @@ sub process {

> >>                 my $hunk_line = ($realcnt != 0);

> >>   -#make up the handle for any error we report on this line

> >> -               $prefix = "$filename:$realline: " if ($emacs && $file);

> >> -               $prefix = "$filename:$linenr: " if ($emacs && !$file);

> >> -

> >>                 $here = "#$linenr: " if (!$file);

> >>                 $here = "#$realline: " if ($file);

> >>   @@ -2110,8 +2277,19 @@ sub process {

> >>                         $found_file = 1;

> >>                 }

> >>   +#make up the handle for any error we report on this line

> >> +               if ($showfile) {

> >> +                       $prefix = "$realfile:$realline: "

> >> +               } elsif ($emacs) {

> >> +                       if ($file) {

> >> +                               $prefix = "$filename:$realline: ";

> >> +                       } else {

> >> +                               $prefix = "$filename:$linenr: ";

> >> +                       }

> >> +               }

> >> +

> >>                 if ($found_file) {

> >> -                       if ($realfile =~ m@^(drivers/net/|net/)@) {

> >> +                       if ($realfile =~ m@^(?:drivers/net/|net/|

> drivers/staging/)@)

> >> {

> >>                                 $check = 1;

> >>                         } else {

> >>                                 $check = $check_orig;

> >> @@ -2127,6 +2305,17 @@ sub process {

> >>                 $cnt_lines++ if ($realcnt != 0);

> >>   +# Check if the commit log has what seems like a diff which can

> confuse

> >> patch

> >> +               if ($in_commit_log && !$commit_log_has_diff &&

> >> +                   (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&

> >> +                     $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||

> >> +                    $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||

> >> +                    $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {

> >> +                       ERROR("DIFF_IN_COMMIT_MSG",

> >> +                             "Avoid using diff content in the commit

> >> message - patch(1) might not work\n" . $herecurr);

> >> +                       $commit_log_has_diff = 1;

> >> +               }

> >> +

> >>   # Check for incorrect file permissions

> >>                 if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {

> >>                         my $permhere = $here . "FILE: $realfile\n";

> >> @@ -2238,18 +2427,46 @@ sub process {

> >>                               "Remove Gerrit Change-Id's before

> >> submitting upstream.\n" . $herecurr);

> >>                 }

> >>   +# Check if the commit log is in a possible stack dump

> >> +               if ($in_commit_log && !$commit_log_possible_stack_dump

> &&

> >> +                   ($line =~ /^\s*(?:WARNING:|BUG:)/ ||

> >> +                    $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||

> >> +                                       # timestamp

> >> +                    $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) {

> >> +                                       # stack dump address

> >> +                       $commit_log_possible_stack_dump = 1;

> >> +               }

> >> +

> >>   # Check for line lengths > 75 in commit log, warn once

> >>                 if ($in_commit_log && !$commit_log_long_line &&

> >> -                   length($line) > 75) {

> >> +                   length($line) > 75 &&

> >> +                   !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||

> >> +                                       # file delta changes

> >> +                     $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||

> >> +                                       # filename then :

> >> +                     $line =~ /^\s*(?:Fixes:|Link:)/i ||

> >> +                                       # A Fixes: or Link: line

> >> +                     $commit_log_possible_stack_dump)) {

> >>                         WARN("COMMIT_LOG_LONG_LINE",

> >>                              "Possible unwrapped commit description

> >> (prefer a maximum 75 chars per line)\n" . $herecurr);

> >>                         $commit_log_long_line = 1;

> >>                 }

> >>   +# Reset possible stack dump if a blank line is found

> >> +               if ($in_commit_log && $commit_log_possible_stack_dump

> &&

> >> +                   $line =~ /^\s*$/) {

> >> +                       $commit_log_possible_stack_dump = 0;

> >> +               }

> >> +

> >>   # Check for git id commit length and improperly formed commit

> >> descriptions

> >> -               if ($in_commit_log && $line =~

> >> /\b(c)ommit\s+([0-9a-f]{5,})/i) {

> >> -                       my $init_char = $1;

> >> -                       my $orig_commit = lc($2);

> >> +               if ($in_commit_log && !$commit_log_possible_stack_dump

> &&

> >> +                   $line !~ /^\s*(?:Link|Patchwork|http|

> https|BugLink):/i

> >> &&

> >> +                   ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||

> >> +                    ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\

> s"'\(\[]|$)/i

> >> &&

> >> +                     $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&

> >> +                     $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {

> >> +                       my $init_char = "c";

> >> +                       my $orig_commit = "";

> >>                         my $short = 1;

> >>                         my $long = 0;

> >>                         my $case = 1;

> >> @@ -2260,6 +2477,13 @@ sub process {

> >>                         my $orig_desc = "commit description";

> >>                         my $description = "";

> >>   +                     if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i)

> {

> >> +                               $init_char = $1;

> >> +                               $orig_commit = lc($2);

> >> +                       } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {

> >> +                               $orig_commit = lc($1);

> >> +                       }

> >> +

> >>                         $short = 0 if ($line =~

> >> /\bcommit\s+[0-9a-f]{12,40}/i);

> >>                         $long = 1 if ($line =~

> >> /\bcommit\s+[0-9a-f]{41,}/i);

> >>                         $space = 0 if ($line =~ /\bcommit [0-9a-f]/i);

> >> @@ -2343,6 +2567,7 @@ sub process {

> >>                       $rawline =~ /^(commit\b|from\b|[\w-]+:).*$/i)) {

> >>                         $in_header_lines = 0;

> >>                         $in_commit_log = 1;

> >> +                       $has_commit_log = 1;

> >>                 }

> >>     # Check if there is UTF-8 in a commit log when a mail header has

> >> explicitly

> >> @@ -2514,16 +2739,60 @@ sub process {

> >>   # check we are in a valid source file if not then ignore this hunk

> >>                 next if ($realfile !~ /\.(h|c|s|S|pl|sh|dtsi|dts)$/);

> >>   -#line length limit

> >> -               if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&

> >> -                   $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&

> >> -                   !($line =~ /^\+\s*$logFunctions\s*\(\s*(?

> >> :(KERN_\S+\s*|[^"]*))?$String\s*(?:|,|\)\s*;)\s*$/ ||

> >> -                     $line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/

> ||

> >> -                     $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) &&

> >> -                   $length > $max_line_length)

> >> -               {

> >> -                       WARN("LONG_LINE",

> >> -                            "line over $max_line_length characters\n" .

> >> $herecurr);

> >> +# line length limit (with some exclusions)

> >> +#

> >> +# There are a few types of lines that may extend beyond

> $max_line_length:

> >> +#      logging functions like pr_info that end in a string

> >> +#      lines with a single string

> >> +#      #defines that are a single string

> >> +#

> >> +# There are 3 different line length message types:

> >> +# LONG_LINE_COMMENT    a comment starts before but extends beyond

> >> $max_linelength

> >> +# LONG_LINE_STRING     a string starts before but extends beyond

> >> $max_line_length

> >> +# LONG_LINE            all other lines longer than $max_line_length

> >> +#

> >> +# if LONG_LINE is ignored, the other 2 types are also ignored

> >> +#

> >> +

> >> +               if ($line =~ /^\+/ && $length > $max_line_length) {

> >> +                       my $msg_type = "LONG_LINE";

> >> +

> >> +                       # Check the allowed long line types first

> >> +

> >> +                       # logging functions that end in a string that

> >> starts

> >> +                       # before $max_line_length

> >> +                       if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?

> >> :(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&

> >> +                           length(expand_tabs(substr($line, 1,

> >> length($line) - length($1) - 1))) <= $max_line_length) {

> >> +                               $msg_type = "";

> >> +

> >> +                       # lines with only strings (w/ possible

> >> termination)

> >> +                       # #defines with only strings

> >> +                       } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\

> s*;)\s*$/

> >> ||

> >> +                                $line =~ /^\+\s*#\s*define\s+\w+\s+$

> String$/)

> >> {

> >> +                               $msg_type = "";

> >> +

> >> +                       # EFI_GUID is another special case

> >> +                       } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) {

> >> +                               $msg_type = "";

> >> +

> >> +                       # Otherwise set the alternate message types

> >> +

> >> +                       # a comment starts before $max_line_length

> >> +                       } elsif ($line =~ /($;[\s$;]*)$/ &&

> >> +                                length(expand_tabs(substr($line, 1,

> >> length($line) - length($1) - 1))) <= $max_line_length) {

> >> +                               $msg_type = "LONG_LINE_COMMENT"

> >> +

> >> +                       # a quoted string starts before $max_line_length

> >> +                       } elsif ($sline =~

> /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/

> >> &&

> >> +                                length(expand_tabs(substr($line, 1,

> >> length($line) - length($1) - 1))) <= $max_line_length) {

> >> +                               $msg_type = "LONG_LINE_STRING"

> >> +                       }

> >> +

> >> +                       if ($msg_type ne "" &&

> >> +                           (show_type("LONG_LINE") ||

> >> show_type($msg_type))) {

> >> +                               WARN($msg_type,

> >> +                                    "line over $max_line_length

> >> characters\n" . $herecurr);

> >> +                       }

> >>                 }

> >>     # check for adding lines without a newline.

> >> @@ -2581,6 +2850,19 @@ sub process {

> >>                             "Logical continuations should be on the

> >> previous line\n" . $hereprev);

> >>                 }

> >>   +# check indentation starts on a tab stop

> >> +               if ($^V && $^V ge 5.10.0 &&

> >> +                   $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}

> \s*(?:else\b|while\b|\s*$))/)

> >> {

> >> +                       my $indent = length($1);

> >> +                       if ($indent % 8) {

> >> +                               if (WARN("TABSTOP",

> >> +                                        "Statements should start on a

> >> tabstop\n" . $herecurr) &&

> >> +                                   $fix) {

> >> +                                       $fixed[$fixlinenr] =~ s@

> (^\+\t+)

> >> +@$1 . "\t" x ($indent/8)@e;

> >> +                               }

> >> +                       }

> >> +               }

> >> +

> >>   # 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*$/) {

> >> @@ -2628,6 +2910,8 @@ sub process {

> >>                         }

> >>                 }

> >>   +# Block comment styles

> >> +# Networking with an initial /*

> >>                 if ($realfile =~ m@^(drivers/net/|net/)@ &&

> >>                     $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&

> >>                     $rawline =~ /^\+[ \t]*\*/ &&

> >> @@ -2636,22 +2920,23 @@ sub process {

> >>                              "networking block comments don't use an

> >> empty /* line, use /* Comment...\n" . $hereprev);

> >>                 }

> >>   -             if ($realfile =~ m@^(drivers/net/|net/)@ &&

> >> -                   $prevrawline =~ /^\+[ \t]*\/\*/ &&

> #starting

> >> /*

> >> +# Block comments use * on subsequent lines

> >> +               if ($prevline =~ /$;[ \t]*$/ &&                 #ends in

> >> comment

> >> +                   $prevrawline =~ /^\+.*?\/\*/ &&

>  #starting

> >> /*

> >>                     $prevrawline !~ /\*\/[ \t]*$/ &&            #no

> >> trailing */

> >>                     $rawline =~ /^\+/ &&                        #line is

> >> new

> >>                     $rawline !~ /^\+[ \t]*\*/) {                #no

> >> leading *

> >> -                       WARN("NETWORKING_BLOCK_COMMENT_STYLE",

> >> -                            "networking block comments start with * on

> >> subsequent lines\n" . $hereprev);

> >> +                       WARN("BLOCK_COMMENT_STYLE",

> >> +                            "Block comments use * on subsequent

> lines\n"

> >> . $hereprev);

> >>                 }

> >>   -             if ($realfile =~ m@^(drivers/net/|net/)@ &&

> >> -                   $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&

> >>  #trailing */

> >> +# Block comments use */ on trailing lines

> >> +               if ($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);

> >> +                       WARN("BLOCK_COMMENT_STYLE",

> >> +                            "Block comments use a trailing */ on a

> >> separate line\n" . $herecurr);

> >>                 }

> >>     # check for missing blank lines after struct/union declarations

> >> @@ -2957,14 +3242,21 @@ sub process {

> >>                         substr($s, 0, length($c), '');

> >>   +                     # remove inline comments

> >> +                       $s =~ s/$;/ /g;

> >> +                       $c =~ s/$;/ /g;

> >> +

> >> +                       # Find out how long the conditional actually is.

> >> +                       my @newlines = ($c =~ /\n/gs);

> >> +                       my $cond_lines = 1 + $#newlines;

> >> +

> >>                         # 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;

> >> +                       while ($s =~ /\n\s+\\\n/) {

> >> +                               $cond_lines += $s =~ s/\n\s+\\\n/\n/g;

> >> +                       }

> >>                         # We want to check the first line inside the

> block

> >>                         # starting at the end of the conditional, so

> >> remove:

> >> @@ -3031,8 +3323,10 @@ sub process {

> >>                         #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 ''))) {

> >> +                       if ($check && $s ne '' &&

> >> +                           (($sindent % 8) != 0 ||

> >> +                            ($sindent < $indent) ||

> >> +                            ($sindent > $indent + 8))) {

> >>                                 WARN("SUSPECT_CODE_INDENT",

> >>                                      "suspect code indent for

> conditional

> >> statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");

> >>                         }

> >> @@ -3054,6 +3348,30 @@ sub process {

> >>   #ignore lines not being added

> >>                 next if ($line =~ /^[^\+]/);

> >>   +# check for declarations of signed or unsigned without int

> >> +               while ($line =~ m{\b($Declare)\s*(?!char\b|sho

> >> rt\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {

> >> +                       my $type = $1;

> >> +                       my $var = $2;

> >> +                       $var = "" if (!defined $var);

> >> +                       if ($type =~ /^(?:(?:$Storage|$Inline|$Attr

> >> ibute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {

> >> +                               my $sign = $1;

> >> +                               my $pointer = $2;

> >> +

> >> +                               $pointer = "" if (!defined $pointer);

> >> +

> >> +                               if (WARN("UNSPECIFIED_INT",

> >> +                                        "Prefer '" . trim($sign) . "

> >> int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) .

> >> "'\n" . $herecurr) &&

> >> +                                   $fix) {

> >> +                                       my $decl = trim($sign) . " int

> ";

> >> +                                       my $comp_pointer = $pointer;

> >> +                                       $comp_pointer =~ s/\s//g;

> >> +                                       $decl .= $comp_pointer;

> >> +                                       $decl = rtrim($decl) if ($var eq

> >> "");

> >> +                                       $fixed[$fixlinenr] =~ s@

> >> \b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;

> >> +                               }

> >> +                       }

> >> +               }

> >> +

> >>   # TEST: allow direct testing of the type matcher.

> >>                 if ($dbg_type) {

> >>                         if ($line =~ /^.\s*$Declare\s*$/) {

> >> @@ -3173,21 +3491,20 @@ sub process {

> >>                 }

> >>     # check for global initialisers.

> >> -               if ($line =~ /^\+(\s*$Type\s*$Ident\s*(?:\s

> >> +$Modifier))*\s*=\s*(0|NULL|false)\s*;/) {

> >> +               if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modif

> >> ier)*\s*=\s*($zero_initializer)\s*;/) {

> >>                         if (ERROR("GLOBAL_INITIALISERS",

> >> -                                 "do not initialise globals to 0 or

> >> NULL\n" .

> >> -                                     $herecurr) &&

> >> +                                 "do not initialise globals to $1\n" .

> >> $herecurr) &&

> >>                             $fix) {

> >> -                               $fixed[$fixlinenr] =~

> >> s/($Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/$1;/;

> >> +                               $fixed[$fixlinenr] =~

> >> s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;

> >>                         }

> >>                 }

> >>   # check for static initialisers.

> >> -               if ($line =~ /^\+.*\bstatic\s.*=\s*(0|NULL|false)\s*;/)

> {

> >> +               if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_

> initializer)\s*;/)

> >> {

> >>                         if (ERROR("INITIALISED_STATIC",

> >> -                                 "do not initialise statics to 0 or

> >> NULL\n" .

> >> +                                 "do not initialise statics to $1\n" .

> >>                                       $herecurr) &&

> >>                             $fix) {

> >> -                               $fixed[$fixlinenr] =~

> >> s/(\bstatic\s.*?)\s*=\s*(0|NULL|false)\s*;/$1;/;

> >> +                               $fixed[$fixlinenr] =~

> >> s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;

> >>                         }

> >>                 }

> >>   @@ -3268,7 +3585,6 @@ sub process {

> >>                     $line !~ /\btypedef\s+$Type\s*\(\s*\*?$

> Ident\s*\)\s*\(/

> >> &&

> >>                     $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&

> >>                     $line !~ /\b$typeTypedefs\b/ &&

> >> -                   $line !~ /\b$typeOtherOSTypedefs\b/ &&

> >>                     $line !~ /\b__bitwise(?:__|)\b/) {

> >>                         WARN("NEW_TYPEDEFS",

> >>                              "do not add new typedefs\n" . $herecurr);

> >> @@ -3330,13 +3646,15 @@ sub process {

> >>                         }

> >>                 }

> >>   -# # 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;

> >> -#              }

> >> +# avoid BUG() or BUG_ON()

> >> +               if ($line =~ /\b(?:BUG|BUG_ON)\b/) {

> >> +                       my $msg_type = \&WARN;

> >> +                       $msg_type = \&CHK if ($file);

> >> +                       &{$msg_type}("AVOID_BUG",

> >> +                                    "Avoid crashing the kernel - try

> >> using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" .

> $herecurr);

> >> +               }

> >>   +# avoid LINUX_VERSION_CODE

> >>                 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);

> >> @@ -3923,7 +4241,7 @@ sub process {

> >>   ##            }

> >>     #need space before brace following if, while, etc

> >> -               if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\){/) ||

> >> +               if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||

> >>                     $line =~ /do\{/) {

> >>                         if (ERROR("SPACING",

> >>                                   "space required before the open brace

> >> '{'\n" . $herecurr) &&

> >> @@ -4070,6 +4388,35 @@ sub process {

> >>                         }

> >>                 }

> >>   +# comparisons with a constant or upper case identifier on the left

> >> +#      avoid cases like "foo + BAR < baz"

> >> +#      only fix matches surrounded by parentheses to avoid incorrect

> >> +#      conversions like "FOO < baz() + 5" being "misfixed" to "baz() >

> >> FOO + 5"

> >> +               if ($^V && $^V ge 5.10.0 &&

> >> +                   $line =~ /^\+(.*)\b($Constant|[A-Z_][A-

> >> Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {

> >> +                       my $lead = $1;

> >> +                       my $const = $2;

> >> +                       my $comp = $3;

> >> +                       my $to = $4;

> >> +                       my $newcomp = $comp;

> >> +                       if ($lead !~ /(?:$Operators|\.)\s*$/ &&

> >> +                           $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&

> >> +                           WARN("CONSTANT_COMPARISON",

> >> +                                "Comparisons should place the constant

> >> on the right side of the test\n" . $herecurr) &&

> >> +                           $fix) {

> >> +                               if ($comp eq "<") {

> >> +                                       $newcomp = ">";

> >> +                               } elsif ($comp eq "<=") {

> >> +                                       $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;

> >> @@ -4256,12 +4603,6 @@ sub process {

> >>   #Ignore SI style variants like nS, mV and dB (ie: max_uV,

> >> regulator_min_uA_show)

> >>                             $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_

> [a-z_]+)?$/

> >> &&

> >>   #Ignore some three character SI units explicitly, like MiB and KHz

> >> -                           $var !~ /\bCU_/ &&

> >> -                           $var !~ /\bPRI[diux]32/ &&

> >> -                           $var !~ /\bPRI[diux]64/ &&

> >> -                           $var !~ /\bSCN[diux]8/ &&

> >> -                           $var !~ /\bSCN[diux]32/ &&

> >> -                           $var !~ /\bSCN[diux]64/ &&

> >>                             $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[

> KMGT]?Hz)(?:_[a-z_]+)?$/)

> >> {

> >>                                 while ($var =~ m{($Ident)}g) {

> >>                                         my $word = $1;

> >> @@ -4331,7 +4672,7 @@ sub process {

> >>                         #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 =~ /\#\#/);

> >> +                       $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx

> !~

> >> /\#\#\s*(?:__VA_ARGS__|args)\b/);

> >>                         $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:

> >> \([^\)]*\))?\s*//;

> >>                         $dstat =~ s/$;//g;

> >> @@ -4342,16 +4683,19 @@ 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/)

> >> +                       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/a

> >> sm_volatile/g;

> >> +

> >>                         my $exceptions = qr{

> >>                                 $Declare|

> >>                                 module_param_named|

> >> @@ -4362,7 +4706,8 @@ sub process {

> >>                                 union|

> >>                                 struct|

> >>                                 \.$Ident\s*=\s*|

> >> -                               ^\"|\"$

> >> +                               ^\"|\"$|

> >> +                               ^\[

> >>                         }x;

> >>                         #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";

> >>                         if ($dstat ne '' &&

> >> @@ -4629,7 +4974,7 @@ sub process {

> >>   # to grep for the string.  Make exceptions when the previous string

> >> ends in a

> >>   # newline (multiple lines in one string constant) or '\t', '\r', ';',

> >> or '{'

> >>   # (common in inline assembly) or is a octal \123 or hexadecimal \xaf

> >> value

> >> -               if ($line =~ /^\+\s*"[X\t]*"/ &&

> >> +               if ($line =~ /^\+\s*$String/ &&

> >>                     $prevline =~ /"\s*$/ &&

> >>                     $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-

> >> 9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {

> >>                         if (WARN("SPLIT_STRING",

> >> @@ -4675,27 +5020,31 @@ sub process {

> >>                 }

> >>     # concatenated string without spaces between elements

> >> -               if ($line =~ /"X+"[A-Z_]+/ || $line =~ /[A-Z_]+"X+"/) {

> >> +               if ($line =~ /$String[A-Z_]/ || $line =~

> >> /[A-Za-z0-9_]$String/) {

> >>                         CHK("CONCATENATED_STRING",

> >>                             "Concatenated strings should use spaces

> >> between elements\n" . $herecurr);

> >>                 }

> >>     # uncoalesced string fragments

> >> -               if ($line =~ /"X*"\s*"/) {

> >> +               if ($line =~ /$String\s*"/) {

> >>                         WARN("STRING_FRAGMENTS",

> >>                              "Consecutive strings are generally better

> as

> >> a single string\n" . $herecurr);

> >>                 }

> >>   -# check for %L{u,d,i} in strings

> >> +# check for %L{u,d,i} and 0x%[udi] in strings

> >>                 my $string;

> >>                 while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {

> >>                         $string = substr($rawline, $-[1], $+[1] -

> $-[1]);

> >>                         $string =~ s/%%/__/g;

> >> -                       if ($string =~ /(?<!%)%L[udi]/) {

> >> +                       if ($string =~ /(?<!%)%[\*\d\.\$]*L[udi]/) {

> >>                                 WARN("PRINTF_L",

> >>                                      "\%Ld/%Lu are not-standard C, use

> >> %lld/%llu\n" . $herecurr);

> >>                                 last;

> >>                         }

> >> +                       if ($string =~ /0x%[\*\d\.\$\Llzth]*[udi]/) {

> >> +                               ERROR("PRINTF_0xDECIMAL",

> >> +                                     "Prefixing 0x with decimal output

> >> is defective\n" . $herecurr);

> >> +                       }

> >>                 }

> >>     # check for line continuations in quoted strings with odd counts of

> "

> >> @@ -4713,10 +5062,34 @@ sub process {

> >>     # 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 and this check is

> >> probably not required\n" . $hereprev);

> >> +                       my $tested = quotemeta($1);

> >> +                       my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';

> >> +                       if ($line =~ /\b(kfree|usb_free_urb|debugfs

> >> _remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/)

> {

> >> +                               my $func = $1;

> >> +                               if (WARN('NEEDLESS_IF',

> >> +                                        "$func(NULL) is safe and this

> >> check is probably not required\n" . $hereprev) &&

> >> +                                   $fix) {

> >> +                                       my $do_fix = 1;

> >> +                                       my $leading_tabs = "";

> >> +                                       my $new_leading_tabs = "";

> >> +                                       if ($lines[$linenr - 2] =~

> >> /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {

> >> +                                               $leading_tabs = $1;

> >> +                                       } else {

> >> +                                               $do_fix = 0;

> >> +                                       }

> >> +                                       if ($lines[$linenr - 1] =~

> >> /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {

> >> +                                               $new_leading_tabs = $1;

> >> +                                               if

> (length($leading_tabs)

> >> + 1 ne length($new_leading_tabs)) {

> >> +                                                       $do_fix = 0;

> >> +                                               }

> >> +                                       } else {

> >> +                                               $do_fix = 0;

> >> +                                       }

> >> +                                       if ($do_fix) {

> >> +

> >>  fix_delete_line($fixlinenr - 1, $prevrawline);

> >> +                                               $fixed[$fixlinenr] =~

> >> s/^\+$new_leading_tabs/\+$leading_tabs/;

> >> +                                       }

> >> +                               }

> >>                         }

> >>                 }

> >>   @@ -4902,12 +5275,69 @@ sub process {

> >>                         }

> >>                 }

> >>   # check for memory barriers without a comment.

> >> -               if ($line =~ /\b(mb|rmb|wmb|read_barrier_de

> >> pends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) {

> >> +

> >> +               my $barriers = qr{

> >> +                       mb|

> >> +                       rmb|

> >> +                       wmb|

> >> +                       read_barrier_depends

> >> +               }x;

> >> +               my $barrier_stems = qr{

> >> +                       mb__before_atomic|

> >> +                       mb__after_atomic|

> >> +                       store_release|

> >> +                       load_acquire|

> >> +                       store_mb|

> >> +                       (?:$barriers)

> >> +               }x;

> >> +               my $all_barriers = qr{

> >> +                       (?:$barriers)|

> >> +                       smp_(?:$barrier_stems)|

> >> +                       virt_(?:$barrier_stems)

> >> +               }x;

> >> +

> >> +               if ($line =~ /\b(?:$all_barriers)\s*\(/) {

> >>                         if (!ctx_has_comment($first_line, $linenr)) {

> >>                                 WARN("MEMORY_BARRIER",

> >>                                      "memory barrier without comment\n"

> .

> >> $herecurr);

> >>                         }

> >>                 }

> >> +

> >> +               my $underscore_smp_barriers =

> >> qr{__smp_(?:$barrier_stems)}x;

> >> +

> >> +               if ($realfile !~ m@^include/asm-generic/@ &&

> >> +                   $realfile !~ m@/barrier\.h$@ &&

> >> +                   $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&

> >> +                   $line !~ m/^.\s*\#\s*define\s+(?:$

> underscore_smp_barriers)\s*\(/)

> >> {

> >> +                       WARN("MEMORY_BARRIER",

> >> +                            "__smp memory barriers shouldn't be used

> >> outside barrier.h and asm-generic\n" . $herecurr);

> >> +               }

> >> +

> >> +# check for waitqueue_active without a comment.

> >> +               if ($line =~ /\bwaitqueue_active\s*\(/) {

> >> +                       if (!ctx_has_comment($first_line, $linenr)) {

> >> +                               WARN("WAITQUEUE_ACTIVE",

> >> +                                    "waitqueue_active without

> comment\n"

> >> . $herecurr);

> >> +                       }

> >> +               }

> >> +

> >> +# Check for expedited grace periods that interrupt non-idle non-nohz

> >> +# online CPUs.  These expedited can therefore degrade real-time

> response

> >> +# if used carelessly, and should be avoided where not absolutely

> >> +# needed.  It is always OK to use synchronize_rcu_expedited() and

> >> +# synchronize_sched_expedited() at boot time (before real-time

> >> applications

> >> +# start) and in error situations where real-time response is

> compromised

> >> in

> >> +# any case.  Note that synchronize_srcu_expedited() does -not-

> interrupt

> >> +# other CPUs, so don't warn on uses of synchronize_srcu_expedited().

> >> +# Of course, nothing comes for free, and srcu_read_lock() and

> >

> >

>




-- 
Mike Holmes
Program Manager - Linaro Networking Group
Linaro.org <http://www.linaro.org/> *│ *Open source software for ARM SoCs
"Work should be fun and collaborative, the rest follows"
Mike Holmes Aug. 31, 2016, 3:31 p.m. UTC | #4
On 30 August 2016 at 15:17, Maxim Uvarov <maxim.uvarov@linaro.org> wrote:

> How is this patch was generated? Did you apply upstream patches on top of

> our current checkpatch? Were local changes included to that patch?

> We should not forget to pull all local things on top of updates.

>


That is an issue, I see we touched this code, if we do that we need to call
it odpcheckpatch.pl becasue it is calrly not chackpatch any longer - very
confusing

I will merge and then change its name so that it is obvious


>

> Maxim.

>

> On 08/30/16 20:14, Mike Holmes wrote:

>

>> The existing checkpatch used by ODP crashes when used on recent patches

>> by Bill,

>> update to the latest version. The latest version has a new test that we

>> need to disable

>> that warns about not using kernel types:

>>

>> PREFER_KERNEL_TYPES

>> check for c99 types like uint8_t used outside of uapi

>>

>> Signed-off-by: Mike Holmes <mike.holmes@linaro.org>

>> ---

>>   .checkpatch.conf      |   1 +

>>   scripts/checkpatch.pl | 820 ++++++++++++++++++++++++++++++

>> ++++++++++++--------

>>   2 files changed, 690 insertions(+), 131 deletions(-)

>>

>> diff --git a/.checkpatch.conf b/.checkpatch.conf

>> index 1e7d663..81723d6 100644

>> --- a/.checkpatch.conf

>> +++ b/.checkpatch.conf

>> @@ -8,3 +8,4 @@

>>   --ignore=BIT_MACRO

>>   --codespell

>>   --codespellfile=/usr/share/codespell/dictionary.txt

>> +--ignore=PREFER_KERNEL_TYPES

>> diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl

>> index 16316b9..4de3cc4 100755

>> --- a/scripts/checkpatch.pl

>> +++ b/scripts/checkpatch.pl

>> @@ -9,6 +9,7 @@ use strict;

>>   use POSIX;

>>   use File::Basename;

>>   use Cwd 'abs_path';

>> +use Term::ANSIColor qw(:constants);

>>     my $P = $0;

>>   my $D = dirname(abs_path($P));

>> @@ -24,13 +25,17 @@ 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;

>> @@ -48,7 +53,9 @@ 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/local/share/codespell/dictionary.txt";

>> +my $codespellfile = "/usr/share/codespell/dictionary.txt";

>> +my $color = 1;

>> +my $allow_c99_comments = 1;

>>     sub help {

>>         my ($exitcode) = @_;

>> @@ -64,13 +71,25 @@ Options:

>>     --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

>> -  --show-types               show the message "types" in the output

>>     --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

>> @@ -91,8 +110,9 @@ Options:

>>     --ignore-perl-version      override checking of perl version.  expect

>>                                runtime errors.

>>     --codespell                Use the codespell dictionary for

>> spelling/typos

>> -                             (default:/usr/local/share/cod

>> espell/dictionary.txt)

>> +                             (default:/usr/share/

>> codespell/dictionary.txt)

>>     --codespellfile            Use this codespell dictionary

>> +  --color                    Use colors when output is STDOUT (default:

>> on)

>>     -h, --help, --version      display this help and exit

>>     When FILE is - read standard input.

>> @@ -101,6 +121,37 @@ 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 = ();

>> +       for ($text =~ /\b(?:(?:CHK|WARN|ERROR)\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;

>> @@ -134,12 +185,15 @@ GetOptions(

>>         '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,

>> @@ -153,12 +207,15 @@ GetOptions(

>>         'test-only=s'   => \$tst_only,

>>         'codespell!'    => \$codespell,

>>         'codespellfile=s'       => \$codespellfile,

>> +       'color!'        => \$color,

>>         '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;

>>   @@ -171,9 +228,9 @@ if ($^V && $^V lt $minimum_perl_version) {

>>         }

>>   }

>>   +#if no filenames are given, push '-' to read patch from stdin

>>   if ($#ARGV < 0) {

>> -       print "$P: no input files\n";

>> -       exit(1);

>> +       push(@ARGV, '-');

>>   }

>>     sub hash_save_array_words {

>> @@ -196,12 +253,12 @@ sub hash_save_array_words {

>>   sub hash_show_words {

>>         my ($hashRef, $prefix) = @_;

>>   -     if ($quiet == 0 && keys %$hashRef) {

>> -               print "NOTE: $prefix message types:";

>> +       if (keys %$hashRef) {

>> +               print "\nNOTE: $prefix message types:";

>>                 foreach my $word (sort keys %$hashRef) {

>>                         print " $word";

>>                 }

>> -               print "\n\n";

>> +               print "\n";

>>         }

>>   }

>>   @@ -261,7 +318,8 @@ our $Sparse       = qr{

>>                         __init_refok|

>>                         __kprobes|

>>                         __ref|

>> -                       __rcu

>> +                       __rcu|

>> +                       __private

>>                 }x;

>>   our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};

>>   our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};

>> @@ -347,15 +405,22 @@ our $UTF8 = qr{

>>         | $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 $typeTypedefs = qr{(?x:

>> +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|)|

>> @@ -363,11 +428,7 @@ our $logFunctions = qr{(?x:

>>         WARN(?:_RATELIMIT|_ONCE|)|

>>         panic|

>>         MODULE_[A-Z_]+|

>> -       seq_vprintf|seq_printf|seq_puts|

>> -       ODP_ASSERT|ODP_DBG|ODP_ERR|ODP_ABORT|ODP_LOG|ODP_PRINT|

>> -       EXAMPLE_DBG|EXAMPLE_ERR|EXAMPLE_ABORT|

>> -       LOG_DBG|LOG_ERR|LOG_ABORT|

>> -       printf

>> +       seq_vprintf|seq_printf|seq_puts

>>   )};

>>     our $signature_tags = qr{(?xi:

>> @@ -422,6 +483,29 @@ our @typeList = (

>>         qr{${Ident}_handler_fn},

>>         @typeListMisordered,

>>   );

>> +

>> +our $C90_int_types = qr{(?x:

>> +       long\s+long\s+int\s+(?:un)?signed|

>> +       long\s+long\s+(?:un)?signed\s+int|

>> +       long\s+long\s+(?:un)?signed|

>> +       (?:(?:un)?signed\s+)?long\s+long\s+int|

>> +       (?:(?:un)?signed\s+)?long\s+long|

>> +       int\s+long\s+long\s+(?:un)?signed|

>> +       int\s+(?:(?:un)?signed\s+)?long\s+long|

>> +

>> +       long\s+int\s+(?:un)?signed|

>> +       long\s+(?:un)?signed\s+int|

>> +       long\s+(?:un)?signed|

>> +       (?:(?:un)?signed\s+)?long\s+int|

>> +       (?:(?:un)?signed\s+)?long|

>> +       int\s+long\s+(?:un)?signed|

>> +       int\s+(?:(?:un)?signed\s+)?long|

>> +

>> +       int\s+(?:un)?signed|

>> +       (?:(?:un)?signed\s+)?int

>> +)};

>> +

>> +our @typeListFile = ();

>>   our @typeListWithAttr = (

>>         @typeList,

>>         qr{struct\s+$InitAttribute\s+$Ident},

>> @@ -431,6 +515,7 @@ our @typeListWithAttr = (

>>   our @modifierList = (

>>         qr{fastcall},

>>   );

>> +our @modifierListFile = ();

>>     our @mode_permission_funcs = (

>>         ["module_param", 3],

>> @@ -514,13 +599,12 @@ if ($codespell) {

>>   $misspellings = join("|", sort keys %spelling_fix) if keys

>> %spelling_fix;

>>     sub build_types {

>> -       my $mods = "(?x:  \n" . join("|\n  ", @modifierList) . "\n)";

>> -       my $all = "(?x:  \n" . join("|\n  ", @typeList) . "\n)";

>> +       my $mods = "(?x:  \n" . join("|\n  ", (@modifierList,

>> @modifierListFile)) . "\n)";

>> +       my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile))

>> . "\n)";

>>         my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered)

>> . "\n)";

>>         my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr) .

>> "\n)";

>>         $Modifier       = qr{(?:$Attribute|$Sparse|$mods)};

>>         $BasicType      = qr{

>> -                               (?:$typeOtherOSTypedefs\b)|

>>                                 (?:$typeTypedefs\b)|

>>                                 (?:${all}\b)

>>                 }x;

>> @@ -528,7 +612,6 @@ sub build_types {

>>                         (?:$Modifier\s+|const\s+)*

>>                         (?:

>>                                 (?:typeof|__typeof__)\s*\([^\)]*\)|

>> -                               (?:$typeOtherOSTypedefs\b)|

>>                                 (?:$typeTypedefs\b)|

>>                                 (?:${all}\b)

>>                         )

>> @@ -546,7 +629,6 @@ sub build_types {

>>                         (?:

>>                                 (?:typeof|__typeof__)\s*\([^\)]*\)|

>>                                 (?:$typeTypedefs\b)|

>> -                               (?:$typeOtherOSTypedefs\b)|

>>                                 (?:${allWithAttr}\b)

>>                         )

>>                         (?:\s+$Modifier|\s+const)*

>> @@ -577,7 +659,7 @@ our $LvalOrFunc     = qr{((?:[\&\*]\s*)?$Lval)\s*($b

>> alanced_parens{0,1})\s*};

>>   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,2}\s*\(|

>> +       (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)

>> (?:_[A-Z0-9]+){1,6}\s*\(|

>>         (?:$Storage\s+)?LIST_HEAD\s*\(|

>>         (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(

>>   )};

>> @@ -719,10 +801,42 @@ my @fixed_inserted = ();

>>   my @fixed_deleted = ();

>>   my $fixlinenr = -1;

>>   +# If input is git commits, extract all commits from the commit

>> expressions.

>> +# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.

>> +die "$P: No git repository found\n" if ($git && !-e ".git");

>> +

>> +if ($git) {

>> +       my @commits = ();

>> +       foreach my $commit_expr (@ARGV) {

>> +               my $git_range;

>> +               if ($commit_expr =~ m/^(.*)-(\d+)$/) {

>> +                       $git_range = "-$2 $1";

>> +               } elsif ($commit_expr =~ m/\.\./) {

>> +                       $git_range = "$commit_expr";

>> +               } else {

>> +                       $git_range = "-1 $commit_expr";

>> +               }

>> +               my $lines = `git log --no-color --no-merges

>> --pretty=format:'%H %s' $git_range`;

>> +               foreach my $line (split(/\n/, $lines)) {

>> +                       $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;

>> +                       next if (!defined($1) || !defined($2));

>> +                       my $sha1 = $1;

>> +                       my $subject = $2;

>> +                       unshift(@commits, $sha1);

>> +                       $git_commits{$sha1} = $subject;

>> +               }

>> +       }

>> +       die "$P: no git commits after extraction!\n" if (@commits == 0);

>> +       @ARGV = @commits;

>> +}

>> +

>>   my $vname;

>>   for my $filename (@ARGV) {

>>         my $FILE;

>> -       if ($file) {

>> +       if ($git) {

>> +               open($FILE, '-|', "git format-patch -M --stdout -1

>> $filename") ||

>> +                       die "$P: $filename: git format-patch failed -

>> $!\n";

>> +       } elsif ($file) {

>>                 open($FILE, '-|', "diff -u /dev/null $filename") ||

>>                         die "$P: $filename: diff failed - $!\n";

>>         } elsif ($filename eq '-') {

>> @@ -733,6 +847,8 @@ for my $filename (@ARGV) {

>>         }

>>         if ($filename eq '-') {

>>                 $vname = 'Your patch';

>> +       } elsif ($git) {

>> +               $vname = "Commit " . substr($filename, 0, 12) . ' ("' .

>> $git_commits{$filename} . '")';

>>         } else {

>>                 $vname = $filename;

>>         }

>> @@ -741,6 +857,13 @@ for my $filename (@ARGV) {

>>                 push(@rawlines, $_);

>>         }

>>         close($FILE);

>> +

>> +       if ($#ARGV > 0 && $quiet == 0) {

>> +               print '-' x length($vname) . "\n";

>> +               print "$vname\n";

>> +               print '-' x length($vname) . "\n";

>> +       }

>> +

>>         if (!process($filename)) {

>>                 $exit = 1;

>>         }

>> @@ -750,6 +873,29 @@ for my $filename (@ARGV) {

>>         @fixed_inserted = ();

>>         @fixed_deleted = ();

>>         $fixlinenr = -1;

>> +       @modifierListFile = ();

>> +       @typeListFile = ();

>> +       build_types();

>> +}

>> +

>> +if (!$quiet) {

>> +       hash_show_words(\%use_type, "Used");

>> +       hash_show_words(\%ignore_type, "Ignored");

>> +

>> +       if ($^V lt 5.10.0) {

>> +               print << "EOM"

>> +

>> +NOTE: perl $^V is not modern enough to detect all possible issues.

>> +      An upgrade to at least perl v5.10.0 is suggested.

>> +EOM

>> +       }

>> +       if ($exit) {

>> +               print << "EOM"

>> +

>> +NOTE: If any of the errors are false positives, please report

>> +      them to the maintainer, see CHECKPATCH in MAINTAINERS.

>> +EOM

>> +       }

>>   }

>>     exit($exit);

>> @@ -999,13 +1145,18 @@ sub sanitise_line {

>>                 $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;

>>         }

>>   +     if ($allow_c99_comments && $res =~ m@(//.*$)@) {

>> +               my $match = $1;

>> +               $res =~ s/\Q$match\E/"$;" x length($match)/e;

>> +       }

>> +

>>         return $res;

>>   }

>>     sub get_quoted_string {

>>         my ($line, $rawline) = @_;

>>   -     return "" if ($line !~ m/(\"[X\t]+\")/g);

>> +       return "" if ($line !~ m/($String)/g);

>>         return substr($rawline, $-[0], $+[0] - $-[0]);

>>   }

>>   @@ -1614,13 +1765,13 @@ sub possible {

>>                         for my $modifier (split(' ', $possible)) {

>>                                 if ($modifier !~ $notPermitted) {

>>                                         warn "MODIFIER: $modifier

>> ($possible) ($line)\n" if ($dbg_possible);

>> -                                       push(@modifierList, $modifier);

>> +                                       push(@modifierListFile,

>> $modifier);

>>                                 }

>>                         }

>>                 } else {

>>                         warn "POSSIBLE: $possible ($line)\n" if

>> ($dbg_possible);

>> -                       push(@typeList, $possible);

>> +                       push(@typeListFile, $possible);

>>                 }

>>                 build_types();

>>         } else {

>> @@ -1645,15 +1796,32 @@ sub report {

>>             (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {

>>                 return 0;

>>         }

>> -       my $line;

>> +       my $output = '';

>> +       if (-t STDOUT && $color) {

>> +               if ($level eq 'ERROR') {

>> +                       $output .= RED;

>> +               } elsif ($level eq 'WARNING') {

>> +                       $output .= YELLOW;

>> +               } else {

>> +                       $output .= GREEN;

>> +               }

>> +       }

>> +       $output .= $prefix . $level . ':';

>>         if ($show_types) {

>> -               $line = "$prefix$level:$type: $msg\n";

>> -       } else {

>> -               $line = "$prefix$level: $msg\n";

>> +               $output .= BLUE if (-t STDOUT && $color);

>> +               $output .= "$type:";

>>         }

>> -       $line = (split('\n', $line))[0] . "\n" if ($terse);

>> +       $output .= RESET if (-t STDOUT && $color);

>> +       $output .= ' ' . $msg . "\n";

>>   -     push(our @report, $line);

>> +       if ($showfile) {

>> +               my @lines = split("\n", $output, -1);

>> +               splice(@lines, 1, 1);

>> +               $output = join("\n", @lines);

>> +       }

>> +       $output = (split('\n', $output))[0] . "\n" if ($terse);

>> +

>> +       push(our @report, $output);

>>         return 1;

>>   }

>> @@ -1899,11 +2067,13 @@ sub process {

>>         our $clean = 1;

>>         my $signoff = 0;

>>         my $is_patch = 0;

>> -

>>         my $in_header_lines = $file ? 0 : 1;

>>         my $in_commit_log = 0;          #Scanning lines before patch

>> +       my $has_commit_log = 0;         #Encountered lines before patch

>> +       my $commit_log_possible_stack_dump = 0;

>>         my $commit_log_long_line = 0;

>> -       my $reported_maintainer_file = 1; # No MAINTAINTERS so silence

>> warning

>> +       my $commit_log_has_diff = 0;

>> +       my $reported_maintainer_file = 0;

>>         my $non_utf8_charset = 0;

>>         my $last_blank_line = 0;

>> @@ -2036,7 +2206,8 @@ sub process {

>>                 my $rawline = $rawlines[$linenr - 1];

>>     #extract the line range in the file after the patch is applied

>> -               if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {

>> +               if (!$in_commit_log &&

>> +                   $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/)

>> {

>>                         $is_patch = 1;

>>                         $first_line = $linenr + 1;

>>                         $realline=$1-1;

>> @@ -2077,10 +2248,6 @@ sub process {

>>                 my $hunk_line = ($realcnt != 0);

>>   -#make up the handle for any error we report on this line

>> -               $prefix = "$filename:$realline: " if ($emacs && $file);

>> -               $prefix = "$filename:$linenr: " if ($emacs && !$file);

>> -

>>                 $here = "#$linenr: " if (!$file);

>>                 $here = "#$realline: " if ($file);

>>   @@ -2110,8 +2277,19 @@ sub process {

>>                         $found_file = 1;

>>                 }

>>   +#make up the handle for any error we report on this line

>> +               if ($showfile) {

>> +                       $prefix = "$realfile:$realline: "

>> +               } elsif ($emacs) {

>> +                       if ($file) {

>> +                               $prefix = "$filename:$realline: ";

>> +                       } else {

>> +                               $prefix = "$filename:$linenr: ";

>> +                       }

>> +               }

>> +

>>                 if ($found_file) {

>> -                       if ($realfile =~ m@^(drivers/net/|net/)@) {

>> +                       if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@)

>> {

>>                                 $check = 1;

>>                         } else {

>>                                 $check = $check_orig;

>> @@ -2127,6 +2305,17 @@ sub process {

>>                 $cnt_lines++ if ($realcnt != 0);

>>   +# Check if the commit log has what seems like a diff which can confuse

>> patch

>> +               if ($in_commit_log && !$commit_log_has_diff &&

>> +                   (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&

>> +                     $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||

>> +                    $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||

>> +                    $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {

>> +                       ERROR("DIFF_IN_COMMIT_MSG",

>> +                             "Avoid using diff content in the commit

>> message - patch(1) might not work\n" . $herecurr);

>> +                       $commit_log_has_diff = 1;

>> +               }

>> +

>>   # Check for incorrect file permissions

>>                 if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {

>>                         my $permhere = $here . "FILE: $realfile\n";

>> @@ -2238,18 +2427,46 @@ sub process {

>>                               "Remove Gerrit Change-Id's before

>> submitting upstream.\n" . $herecurr);

>>                 }

>>   +# Check if the commit log is in a possible stack dump

>> +               if ($in_commit_log && !$commit_log_possible_stack_dump &&

>> +                   ($line =~ /^\s*(?:WARNING:|BUG:)/ ||

>> +                    $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||

>> +                                       # timestamp

>> +                    $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) {

>> +                                       # stack dump address

>> +                       $commit_log_possible_stack_dump = 1;

>> +               }

>> +

>>   # Check for line lengths > 75 in commit log, warn once

>>                 if ($in_commit_log && !$commit_log_long_line &&

>> -                   length($line) > 75) {

>> +                   length($line) > 75 &&

>> +                   !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||

>> +                                       # file delta changes

>> +                     $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||

>> +                                       # filename then :

>> +                     $line =~ /^\s*(?:Fixes:|Link:)/i ||

>> +                                       # A Fixes: or Link: line

>> +                     $commit_log_possible_stack_dump)) {

>>                         WARN("COMMIT_LOG_LONG_LINE",

>>                              "Possible unwrapped commit description

>> (prefer a maximum 75 chars per line)\n" . $herecurr);

>>                         $commit_log_long_line = 1;

>>                 }

>>   +# Reset possible stack dump if a blank line is found

>> +               if ($in_commit_log && $commit_log_possible_stack_dump &&

>> +                   $line =~ /^\s*$/) {

>> +                       $commit_log_possible_stack_dump = 0;

>> +               }

>> +

>>   # Check for git id commit length and improperly formed commit

>> descriptions

>> -               if ($in_commit_log && $line =~

>> /\b(c)ommit\s+([0-9a-f]{5,})/i) {

>> -                       my $init_char = $1;

>> -                       my $orig_commit = lc($2);

>> +               if ($in_commit_log && !$commit_log_possible_stack_dump &&

>> +                   $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i

>> &&

>> +                   ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||

>> +                    ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i

>> &&

>> +                     $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&

>> +                     $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {

>> +                       my $init_char = "c";

>> +                       my $orig_commit = "";

>>                         my $short = 1;

>>                         my $long = 0;

>>                         my $case = 1;

>> @@ -2260,6 +2477,13 @@ sub process {

>>                         my $orig_desc = "commit description";

>>                         my $description = "";

>>   +                     if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {

>> +                               $init_char = $1;

>> +                               $orig_commit = lc($2);

>> +                       } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {

>> +                               $orig_commit = lc($1);

>> +                       }

>> +

>>                         $short = 0 if ($line =~

>> /\bcommit\s+[0-9a-f]{12,40}/i);

>>                         $long = 1 if ($line =~

>> /\bcommit\s+[0-9a-f]{41,}/i);

>>                         $space = 0 if ($line =~ /\bcommit [0-9a-f]/i);

>> @@ -2343,6 +2567,7 @@ sub process {

>>                       $rawline =~ /^(commit\b|from\b|[\w-]+:).*$/i)) {

>>                         $in_header_lines = 0;

>>                         $in_commit_log = 1;

>> +                       $has_commit_log = 1;

>>                 }

>>     # Check if there is UTF-8 in a commit log when a mail header has

>> explicitly

>> @@ -2514,16 +2739,60 @@ sub process {

>>   # check we are in a valid source file if not then ignore this hunk

>>                 next if ($realfile !~ /\.(h|c|s|S|pl|sh|dtsi|dts)$/);

>>   -#line length limit

>> -               if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&

>> -                   $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&

>> -                   !($line =~ /^\+\s*$logFunctions\s*\(\s*(?

>> :(KERN_\S+\s*|[^"]*))?$String\s*(?:|,|\)\s*;)\s*$/ ||

>> -                     $line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||

>> -                     $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) &&

>> -                   $length > $max_line_length)

>> -               {

>> -                       WARN("LONG_LINE",

>> -                            "line over $max_line_length characters\n" .

>> $herecurr);

>> +# line length limit (with some exclusions)

>> +#

>> +# There are a few types of lines that may extend beyond $max_line_length:

>> +#      logging functions like pr_info that end in a string

>> +#      lines with a single string

>> +#      #defines that are a single string

>> +#

>> +# There are 3 different line length message types:

>> +# LONG_LINE_COMMENT    a comment starts before but extends beyond

>> $max_linelength

>> +# LONG_LINE_STRING     a string starts before but extends beyond

>> $max_line_length

>> +# LONG_LINE            all other lines longer than $max_line_length

>> +#

>> +# if LONG_LINE is ignored, the other 2 types are also ignored

>> +#

>> +

>> +               if ($line =~ /^\+/ && $length > $max_line_length) {

>> +                       my $msg_type = "LONG_LINE";

>> +

>> +                       # Check the allowed long line types first

>> +

>> +                       # logging functions that end in a string that

>> starts

>> +                       # before $max_line_length

>> +                       if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?

>> :(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&

>> +                           length(expand_tabs(substr($line, 1,

>> length($line) - length($1) - 1))) <= $max_line_length) {

>> +                               $msg_type = "";

>> +

>> +                       # lines with only strings (w/ possible

>> termination)

>> +                       # #defines with only strings

>> +                       } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/

>> ||

>> +                                $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/)

>> {

>> +                               $msg_type = "";

>> +

>> +                       # EFI_GUID is another special case

>> +                       } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) {

>> +                               $msg_type = "";

>> +

>> +                       # Otherwise set the alternate message types

>> +

>> +                       # a comment starts before $max_line_length

>> +                       } elsif ($line =~ /($;[\s$;]*)$/ &&

>> +                                length(expand_tabs(substr($line, 1,

>> length($line) - length($1) - 1))) <= $max_line_length) {

>> +                               $msg_type = "LONG_LINE_COMMENT"

>> +

>> +                       # a quoted string starts before $max_line_length

>> +                       } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/

>> &&

>> +                                length(expand_tabs(substr($line, 1,

>> length($line) - length($1) - 1))) <= $max_line_length) {

>> +                               $msg_type = "LONG_LINE_STRING"

>> +                       }

>> +

>> +                       if ($msg_type ne "" &&

>> +                           (show_type("LONG_LINE") ||

>> show_type($msg_type))) {

>> +                               WARN($msg_type,

>> +                                    "line over $max_line_length

>> characters\n" . $herecurr);

>> +                       }

>>                 }

>>     # check for adding lines without a newline.

>> @@ -2581,6 +2850,19 @@ sub process {

>>                             "Logical continuations should be on the

>> previous line\n" . $hereprev);

>>                 }

>>   +# check indentation starts on a tab stop

>> +               if ($^V && $^V ge 5.10.0 &&

>> +                   $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$))/)

>> {

>> +                       my $indent = length($1);

>> +                       if ($indent % 8) {

>> +                               if (WARN("TABSTOP",

>> +                                        "Statements should start on a

>> tabstop\n" . $herecurr) &&

>> +                                   $fix) {

>> +                                       $fixed[$fixlinenr] =~ s@(^\+\t+)

>> +@$1 . "\t" x ($indent/8)@e;

>> +                               }

>> +                       }

>> +               }

>> +

>>   # 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*$/) {

>> @@ -2628,6 +2910,8 @@ sub process {

>>                         }

>>                 }

>>   +# Block comment styles

>> +# Networking with an initial /*

>>                 if ($realfile =~ m@^(drivers/net/|net/)@ &&

>>                     $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&

>>                     $rawline =~ /^\+[ \t]*\*/ &&

>> @@ -2636,22 +2920,23 @@ sub process {

>>                              "networking block comments don't use an

>> empty /* line, use /* Comment...\n" . $hereprev);

>>                 }

>>   -             if ($realfile =~ m@^(drivers/net/|net/)@ &&

>> -                   $prevrawline =~ /^\+[ \t]*\/\*/ &&          #starting

>> /*

>> +# Block comments use * on subsequent lines

>> +               if ($prevline =~ /$;[ \t]*$/ &&                 #ends in

>> comment

>> +                   $prevrawline =~ /^\+.*?\/\*/ &&             #starting

>> /*

>>                     $prevrawline !~ /\*\/[ \t]*$/ &&            #no

>> trailing */

>>                     $rawline =~ /^\+/ &&                        #line is

>> new

>>                     $rawline !~ /^\+[ \t]*\*/) {                #no

>> leading *

>> -                       WARN("NETWORKING_BLOCK_COMMENT_STYLE",

>> -                            "networking block comments start with * on

>> subsequent lines\n" . $hereprev);

>> +                       WARN("BLOCK_COMMENT_STYLE",

>> +                            "Block comments use * on subsequent lines\n"

>> . $hereprev);

>>                 }

>>   -             if ($realfile =~ m@^(drivers/net/|net/)@ &&

>> -                   $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&

>>  #trailing */

>> +# Block comments use */ on trailing lines

>> +               if ($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);

>> +                       WARN("BLOCK_COMMENT_STYLE",

>> +                            "Block comments use a trailing */ on a

>> separate line\n" . $herecurr);

>>                 }

>>     # check for missing blank lines after struct/union declarations

>> @@ -2957,14 +3242,21 @@ sub process {

>>                         substr($s, 0, length($c), '');

>>   +                     # remove inline comments

>> +                       $s =~ s/$;/ /g;

>> +                       $c =~ s/$;/ /g;

>> +

>> +                       # Find out how long the conditional actually is.

>> +                       my @newlines = ($c =~ /\n/gs);

>> +                       my $cond_lines = 1 + $#newlines;

>> +

>>                         # 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;

>> +                       while ($s =~ /\n\s+\\\n/) {

>> +                               $cond_lines += $s =~ s/\n\s+\\\n/\n/g;

>> +                       }

>>                         # We want to check the first line inside the block

>>                         # starting at the end of the conditional, so

>> remove:

>> @@ -3031,8 +3323,10 @@ sub process {

>>                         #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 ''))) {

>> +                       if ($check && $s ne '' &&

>> +                           (($sindent % 8) != 0 ||

>> +                            ($sindent < $indent) ||

>> +                            ($sindent > $indent + 8))) {

>>                                 WARN("SUSPECT_CODE_INDENT",

>>                                      "suspect code indent for conditional

>> statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");

>>                         }

>> @@ -3054,6 +3348,30 @@ sub process {

>>   #ignore lines not being added

>>                 next if ($line =~ /^[^\+]/);

>>   +# check for declarations of signed or unsigned without int

>> +               while ($line =~ m{\b($Declare)\s*(?!char\b|sho

>> rt\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {

>> +                       my $type = $1;

>> +                       my $var = $2;

>> +                       $var = "" if (!defined $var);

>> +                       if ($type =~ /^(?:(?:$Storage|$Inline|$Attr

>> ibute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {

>> +                               my $sign = $1;

>> +                               my $pointer = $2;

>> +

>> +                               $pointer = "" if (!defined $pointer);

>> +

>> +                               if (WARN("UNSPECIFIED_INT",

>> +                                        "Prefer '" . trim($sign) . "

>> int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) .

>> "'\n" . $herecurr) &&

>> +                                   $fix) {

>> +                                       my $decl = trim($sign) . " int ";

>> +                                       my $comp_pointer = $pointer;

>> +                                       $comp_pointer =~ s/\s//g;

>> +                                       $decl .= $comp_pointer;

>> +                                       $decl = rtrim($decl) if ($var eq

>> "");

>> +                                       $fixed[$fixlinenr] =~ s@

>> \b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;

>> +                               }

>> +                       }

>> +               }

>> +

>>   # TEST: allow direct testing of the type matcher.

>>                 if ($dbg_type) {

>>                         if ($line =~ /^.\s*$Declare\s*$/) {

>> @@ -3173,21 +3491,20 @@ sub process {

>>                 }

>>     # check for global initialisers.

>> -               if ($line =~ /^\+(\s*$Type\s*$Ident\s*(?:\s

>> +$Modifier))*\s*=\s*(0|NULL|false)\s*;/) {

>> +               if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modif

>> ier)*\s*=\s*($zero_initializer)\s*;/) {

>>                         if (ERROR("GLOBAL_INITIALISERS",

>> -                                 "do not initialise globals to 0 or

>> NULL\n" .

>> -                                     $herecurr) &&

>> +                                 "do not initialise globals to $1\n" .

>> $herecurr) &&

>>                             $fix) {

>> -                               $fixed[$fixlinenr] =~

>> s/($Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/$1;/;

>> +                               $fixed[$fixlinenr] =~

>> s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;

>>                         }

>>                 }

>>   # check for static initialisers.

>> -               if ($line =~ /^\+.*\bstatic\s.*=\s*(0|NULL|false)\s*;/) {

>> +               if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/)

>> {

>>                         if (ERROR("INITIALISED_STATIC",

>> -                                 "do not initialise statics to 0 or

>> NULL\n" .

>> +                                 "do not initialise statics to $1\n" .

>>                                       $herecurr) &&

>>                             $fix) {

>> -                               $fixed[$fixlinenr] =~

>> s/(\bstatic\s.*?)\s*=\s*(0|NULL|false)\s*;/$1;/;

>> +                               $fixed[$fixlinenr] =~

>> s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;

>>                         }

>>                 }

>>   @@ -3268,7 +3585,6 @@ sub process {

>>                     $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/

>> &&

>>                     $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&

>>                     $line !~ /\b$typeTypedefs\b/ &&

>> -                   $line !~ /\b$typeOtherOSTypedefs\b/ &&

>>                     $line !~ /\b__bitwise(?:__|)\b/) {

>>                         WARN("NEW_TYPEDEFS",

>>                              "do not add new typedefs\n" . $herecurr);

>> @@ -3330,13 +3646,15 @@ sub process {

>>                         }

>>                 }

>>   -# # 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;

>> -#              }

>> +# avoid BUG() or BUG_ON()

>> +               if ($line =~ /\b(?:BUG|BUG_ON)\b/) {

>> +                       my $msg_type = \&WARN;

>> +                       $msg_type = \&CHK if ($file);

>> +                       &{$msg_type}("AVOID_BUG",

>> +                                    "Avoid crashing the kernel - try

>> using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);

>> +               }

>>   +# avoid LINUX_VERSION_CODE

>>                 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);

>> @@ -3923,7 +4241,7 @@ sub process {

>>   ##            }

>>     #need space before brace following if, while, etc

>> -               if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\){/) ||

>> +               if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||

>>                     $line =~ /do\{/) {

>>                         if (ERROR("SPACING",

>>                                   "space required before the open brace

>> '{'\n" . $herecurr) &&

>> @@ -4070,6 +4388,35 @@ sub process {

>>                         }

>>                 }

>>   +# comparisons with a constant or upper case identifier on the left

>> +#      avoid cases like "foo + BAR < baz"

>> +#      only fix matches surrounded by parentheses to avoid incorrect

>> +#      conversions like "FOO < baz() + 5" being "misfixed" to "baz() >

>> FOO + 5"

>> +               if ($^V && $^V ge 5.10.0 &&

>> +                   $line =~ /^\+(.*)\b($Constant|[A-Z_][A-

>> Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {

>> +                       my $lead = $1;

>> +                       my $const = $2;

>> +                       my $comp = $3;

>> +                       my $to = $4;

>> +                       my $newcomp = $comp;

>> +                       if ($lead !~ /(?:$Operators|\.)\s*$/ &&

>> +                           $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&

>> +                           WARN("CONSTANT_COMPARISON",

>> +                                "Comparisons should place the constant

>> on the right side of the test\n" . $herecurr) &&

>> +                           $fix) {

>> +                               if ($comp eq "<") {

>> +                                       $newcomp = ">";

>> +                               } elsif ($comp eq "<=") {

>> +                                       $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;

>> @@ -4256,12 +4603,6 @@ sub process {

>>   #Ignore SI style variants like nS, mV and dB (ie: max_uV,

>> regulator_min_uA_show)

>>                             $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/

>> &&

>>   #Ignore some three character SI units explicitly, like MiB and KHz

>> -                           $var !~ /\bCU_/ &&

>> -                           $var !~ /\bPRI[diux]32/ &&

>> -                           $var !~ /\bPRI[diux]64/ &&

>> -                           $var !~ /\bSCN[diux]8/ &&

>> -                           $var !~ /\bSCN[diux]32/ &&

>> -                           $var !~ /\bSCN[diux]64/ &&

>>                             $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/)

>> {

>>                                 while ($var =~ m{($Ident)}g) {

>>                                         my $word = $1;

>> @@ -4331,7 +4672,7 @@ sub process {

>>                         #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 =~ /\#\#/);

>> +                       $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~

>> /\#\#\s*(?:__VA_ARGS__|args)\b/);

>>                         $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:

>> \([^\)]*\))?\s*//;

>>                         $dstat =~ s/$;//g;

>> @@ -4342,16 +4683,19 @@ 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/)

>> +                       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/a

>> sm_volatile/g;

>> +

>>                         my $exceptions = qr{

>>                                 $Declare|

>>                                 module_param_named|

>> @@ -4362,7 +4706,8 @@ sub process {

>>                                 union|

>>                                 struct|

>>                                 \.$Ident\s*=\s*|

>> -                               ^\"|\"$

>> +                               ^\"|\"$|

>> +                               ^\[

>>                         }x;

>>                         #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";

>>                         if ($dstat ne '' &&

>> @@ -4629,7 +4974,7 @@ sub process {

>>   # to grep for the string.  Make exceptions when the previous string

>> ends in a

>>   # newline (multiple lines in one string constant) or '\t', '\r', ';',

>> or '{'

>>   # (common in inline assembly) or is a octal \123 or hexadecimal \xaf

>> value

>> -               if ($line =~ /^\+\s*"[X\t]*"/ &&

>> +               if ($line =~ /^\+\s*$String/ &&

>>                     $prevline =~ /"\s*$/ &&

>>                     $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-

>> 9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {

>>                         if (WARN("SPLIT_STRING",

>> @@ -4675,27 +5020,31 @@ sub process {

>>                 }

>>     # concatenated string without spaces between elements

>> -               if ($line =~ /"X+"[A-Z_]+/ || $line =~ /[A-Z_]+"X+"/) {

>> +               if ($line =~ /$String[A-Z_]/ || $line =~

>> /[A-Za-z0-9_]$String/) {

>>                         CHK("CONCATENATED_STRING",

>>                             "Concatenated strings should use spaces

>> between elements\n" . $herecurr);

>>                 }

>>     # uncoalesced string fragments

>> -               if ($line =~ /"X*"\s*"/) {

>> +               if ($line =~ /$String\s*"/) {

>>                         WARN("STRING_FRAGMENTS",

>>                              "Consecutive strings are generally better as

>> a single string\n" . $herecurr);

>>                 }

>>   -# check for %L{u,d,i} in strings

>> +# check for %L{u,d,i} and 0x%[udi] in strings

>>                 my $string;

>>                 while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {

>>                         $string = substr($rawline, $-[1], $+[1] - $-[1]);

>>                         $string =~ s/%%/__/g;

>> -                       if ($string =~ /(?<!%)%L[udi]/) {

>> +                       if ($string =~ /(?<!%)%[\*\d\.\$]*L[udi]/) {

>>                                 WARN("PRINTF_L",

>>                                      "\%Ld/%Lu are not-standard C, use

>> %lld/%llu\n" . $herecurr);

>>                                 last;

>>                         }

>> +                       if ($string =~ /0x%[\*\d\.\$\Llzth]*[udi]/) {

>> +                               ERROR("PRINTF_0xDECIMAL",

>> +                                     "Prefixing 0x with decimal output

>> is defective\n" . $herecurr);

>> +                       }

>>                 }

>>     # check for line continuations in quoted strings with odd counts of "

>> @@ -4713,10 +5062,34 @@ sub process {

>>     # 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 and this check is

>> probably not required\n" . $hereprev);

>> +                       my $tested = quotemeta($1);

>> +                       my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';

>> +                       if ($line =~ /\b(kfree|usb_free_urb|debugfs

>> _remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {

>> +                               my $func = $1;

>> +                               if (WARN('NEEDLESS_IF',

>> +                                        "$func(NULL) is safe and this

>> check is probably not required\n" . $hereprev) &&

>> +                                   $fix) {

>> +                                       my $do_fix = 1;

>> +                                       my $leading_tabs = "";

>> +                                       my $new_leading_tabs = "";

>> +                                       if ($lines[$linenr - 2] =~

>> /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {

>> +                                               $leading_tabs = $1;

>> +                                       } else {

>> +                                               $do_fix = 0;

>> +                                       }

>> +                                       if ($lines[$linenr - 1] =~

>> /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {

>> +                                               $new_leading_tabs = $1;

>> +                                               if (length($leading_tabs)

>> + 1 ne length($new_leading_tabs)) {

>> +                                                       $do_fix = 0;

>> +                                               }

>> +                                       } else {

>> +                                               $do_fix = 0;

>> +                                       }

>> +                                       if ($do_fix) {

>> +

>>  fix_delete_line($fixlinenr - 1, $prevrawline);

>> +                                               $fixed[$fixlinenr] =~

>> s/^\+$new_leading_tabs/\+$leading_tabs/;

>> +                                       }

>> +                               }

>>                         }

>>                 }

>>   @@ -4902,12 +5275,69 @@ sub process {

>>                         }

>>                 }

>>   # check for memory barriers without a comment.

>> -               if ($line =~ /\b(mb|rmb|wmb|read_barrier_de

>> pends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) {

>> +

>> +               my $barriers = qr{

>> +                       mb|

>> +                       rmb|

>> +                       wmb|

>> +                       read_barrier_depends

>> +               }x;

>> +               my $barrier_stems = qr{

>> +                       mb__before_atomic|

>> +                       mb__after_atomic|

>> +                       store_release|

>> +                       load_acquire|

>> +                       store_mb|

>> +                       (?:$barriers)

>> +               }x;

>> +               my $all_barriers = qr{

>> +                       (?:$barriers)|

>> +                       smp_(?:$barrier_stems)|

>> +                       virt_(?:$barrier_stems)

>> +               }x;

>> +

>> +               if ($line =~ /\b(?:$all_barriers)\s*\(/) {

>>                         if (!ctx_has_comment($first_line, $linenr)) {

>>                                 WARN("MEMORY_BARRIER",

>>                                      "memory barrier without comment\n" .

>> $herecurr);

>>                         }

>>                 }

>> +

>> +               my $underscore_smp_barriers =

>> qr{__smp_(?:$barrier_stems)}x;

>> +

>> +               if ($realfile !~ m@^include/asm-generic/@ &&

>> +                   $realfile !~ m@/barrier\.h$@ &&

>> +                   $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&

>> +                   $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/)

>> {

>> +                       WARN("MEMORY_BARRIER",

>> +                            "__smp memory barriers shouldn't be used

>> outside barrier.h and asm-generic\n" . $herecurr);

>> +               }

>> +

>> +# check for waitqueue_active without a comment.

>> +               if ($line =~ /\bwaitqueue_active\s*\(/) {

>> +                       if (!ctx_has_comment($first_line, $linenr)) {

>> +                               WARN("WAITQUEUE_ACTIVE",

>> +                                    "waitqueue_active without comment\n"

>> . $herecurr);

>> +                       }

>> +               }

>> +

>> +# Check for expedited grace periods that interrupt non-idle non-nohz

>> +# online CPUs.  These expedited can therefore degrade real-time response

>> +# if used carelessly, and should be avoided where not absolutely

>> +# needed.  It is always OK to use synchronize_rcu_expedited() and

>> +# synchronize_sched_expedited() at boot time (before real-time

>> applications

>> +# start) and in error situations where real-time response is compromised

>> in

>> +# any case.  Note that synchronize_srcu_expedited() does -not- interrupt

>> +# other CPUs, so don't warn on uses of synchronize_srcu_expedited().

>> +# Of course, nothing comes for free, and srcu_read_lock() and

>

>



-- 
Mike Holmes
Program Manager - Linaro Networking Group
Linaro.org <http://www.linaro.org/> *│ *Open source software for ARM SoCs
"Work should be fun and collaborative, the rest follows"
Bill Fischofer Aug. 31, 2016, 8:29 p.m. UTC | #5
Should we merge or just have odpcheckpatch.pl be a wrapper around the
standard checkpatch.pl that calls it with the --ignore options we need?
That would seem to make future maintenance easier since we could just use
the vanilla checkpatch.pl from kernel.org as-is as the base code.

On Wed, Aug 31, 2016 at 10:31 AM, Mike Holmes <mike.holmes@linaro.org>
wrote:

> On 30 August 2016 at 15:17, Maxim Uvarov <maxim.uvarov@linaro.org> wrote:

>

> > How is this patch was generated? Did you apply upstream patches on top of

> > our current checkpatch? Were local changes included to that patch?

> > We should not forget to pull all local things on top of updates.

> >

>

> That is an issue, I see we touched this code, if we do that we need to call

> it odpcheckpatch.pl becasue it is calrly not chackpatch any longer - very

> confusing

>

> I will merge and then change its name so that it is obvious

>

>

> >

> > Maxim.

> >

> > On 08/30/16 20:14, Mike Holmes wrote:

> >

> >> The existing checkpatch used by ODP crashes when used on recent patches

> >> by Bill,

> >> update to the latest version. The latest version has a new test that we

> >> need to disable

> >> that warns about not using kernel types:

> >>

> >> PREFER_KERNEL_TYPES

> >> check for c99 types like uint8_t used outside of uapi

> >>

> >> Signed-off-by: Mike Holmes <mike.holmes@linaro.org>

> >> ---

> >>   .checkpatch.conf      |   1 +

> >>   scripts/checkpatch.pl | 820 ++++++++++++++++++++++++++++++

> >> ++++++++++++--------

> >>   2 files changed, 690 insertions(+), 131 deletions(-)

> >>

> >> diff --git a/.checkpatch.conf b/.checkpatch.conf

> >> index 1e7d663..81723d6 100644

> >> --- a/.checkpatch.conf

> >> +++ b/.checkpatch.conf

> >> @@ -8,3 +8,4 @@

> >>   --ignore=BIT_MACRO

> >>   --codespell

> >>   --codespellfile=/usr/share/codespell/dictionary.txt

> >> +--ignore=PREFER_KERNEL_TYPES

> >> diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl

> >> index 16316b9..4de3cc4 100755

> >> --- a/scripts/checkpatch.pl

> >> +++ b/scripts/checkpatch.pl

> >> @@ -9,6 +9,7 @@ use strict;

> >>   use POSIX;

> >>   use File::Basename;

> >>   use Cwd 'abs_path';

> >> +use Term::ANSIColor qw(:constants);

> >>     my $P = $0;

> >>   my $D = dirname(abs_path($P));

> >> @@ -24,13 +25,17 @@ 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;

> >> @@ -48,7 +53,9 @@ 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/local/share/codespell/dictionary.txt";

> >> +my $codespellfile = "/usr/share/codespell/dictionary.txt";

> >> +my $color = 1;

> >> +my $allow_c99_comments = 1;

> >>     sub help {

> >>         my ($exitcode) = @_;

> >> @@ -64,13 +71,25 @@ Options:

> >>     --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

> >> -  --show-types               show the message "types" in the output

> >>     --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

> >> @@ -91,8 +110,9 @@ Options:

> >>     --ignore-perl-version      override checking of perl version.

> expect

> >>                                runtime errors.

> >>     --codespell                Use the codespell dictionary for

> >> spelling/typos

> >> -                             (default:/usr/local/share/cod

> >> espell/dictionary.txt)

> >> +                             (default:/usr/share/

> >> codespell/dictionary.txt)

> >>     --codespellfile            Use this codespell dictionary

> >> +  --color                    Use colors when output is STDOUT (default:

> >> on)

> >>     -h, --help, --version      display this help and exit

> >>     When FILE is - read standard input.

> >> @@ -101,6 +121,37 @@ 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 = ();

> >> +       for ($text =~ /\b(?:(?:CHK|WARN|ERROR)\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;

> >> @@ -134,12 +185,15 @@ GetOptions(

> >>         '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,

> >> @@ -153,12 +207,15 @@ GetOptions(

> >>         'test-only=s'   => \$tst_only,

> >>         'codespell!'    => \$codespell,

> >>         'codespellfile=s'       => \$codespellfile,

> >> +       'color!'        => \$color,

> >>         '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;

> >>   @@ -171,9 +228,9 @@ if ($^V && $^V lt $minimum_perl_version) {

> >>         }

> >>   }

> >>   +#if no filenames are given, push '-' to read patch from stdin

> >>   if ($#ARGV < 0) {

> >> -       print "$P: no input files\n";

> >> -       exit(1);

> >> +       push(@ARGV, '-');

> >>   }

> >>     sub hash_save_array_words {

> >> @@ -196,12 +253,12 @@ sub hash_save_array_words {

> >>   sub hash_show_words {

> >>         my ($hashRef, $prefix) = @_;

> >>   -     if ($quiet == 0 && keys %$hashRef) {

> >> -               print "NOTE: $prefix message types:";

> >> +       if (keys %$hashRef) {

> >> +               print "\nNOTE: $prefix message types:";

> >>                 foreach my $word (sort keys %$hashRef) {

> >>                         print " $word";

> >>                 }

> >> -               print "\n\n";

> >> +               print "\n";

> >>         }

> >>   }

> >>   @@ -261,7 +318,8 @@ our $Sparse       = qr{

> >>                         __init_refok|

> >>                         __kprobes|

> >>                         __ref|

> >> -                       __rcu

> >> +                       __rcu|

> >> +                       __private

> >>                 }x;

> >>   our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};

> >>   our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};

> >> @@ -347,15 +405,22 @@ our $UTF8 = qr{

> >>         | $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 $typeTypedefs = qr{(?x:

> >> +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|)|

> >> @@ -363,11 +428,7 @@ our $logFunctions = qr{(?x:

> >>         WARN(?:_RATELIMIT|_ONCE|)|

> >>         panic|

> >>         MODULE_[A-Z_]+|

> >> -       seq_vprintf|seq_printf|seq_puts|

> >> -       ODP_ASSERT|ODP_DBG|ODP_ERR|ODP_ABORT|ODP_LOG|ODP_PRINT|

> >> -       EXAMPLE_DBG|EXAMPLE_ERR|EXAMPLE_ABORT|

> >> -       LOG_DBG|LOG_ERR|LOG_ABORT|

> >> -       printf

> >> +       seq_vprintf|seq_printf|seq_puts

> >>   )};

> >>     our $signature_tags = qr{(?xi:

> >> @@ -422,6 +483,29 @@ our @typeList = (

> >>         qr{${Ident}_handler_fn},

> >>         @typeListMisordered,

> >>   );

> >> +

> >> +our $C90_int_types = qr{(?x:

> >> +       long\s+long\s+int\s+(?:un)?signed|

> >> +       long\s+long\s+(?:un)?signed\s+int|

> >> +       long\s+long\s+(?:un)?signed|

> >> +       (?:(?:un)?signed\s+)?long\s+long\s+int|

> >> +       (?:(?:un)?signed\s+)?long\s+long|

> >> +       int\s+long\s+long\s+(?:un)?signed|

> >> +       int\s+(?:(?:un)?signed\s+)?long\s+long|

> >> +

> >> +       long\s+int\s+(?:un)?signed|

> >> +       long\s+(?:un)?signed\s+int|

> >> +       long\s+(?:un)?signed|

> >> +       (?:(?:un)?signed\s+)?long\s+int|

> >> +       (?:(?:un)?signed\s+)?long|

> >> +       int\s+long\s+(?:un)?signed|

> >> +       int\s+(?:(?:un)?signed\s+)?long|

> >> +

> >> +       int\s+(?:un)?signed|

> >> +       (?:(?:un)?signed\s+)?int

> >> +)};

> >> +

> >> +our @typeListFile = ();

> >>   our @typeListWithAttr = (

> >>         @typeList,

> >>         qr{struct\s+$InitAttribute\s+$Ident},

> >> @@ -431,6 +515,7 @@ our @typeListWithAttr = (

> >>   our @modifierList = (

> >>         qr{fastcall},

> >>   );

> >> +our @modifierListFile = ();

> >>     our @mode_permission_funcs = (

> >>         ["module_param", 3],

> >> @@ -514,13 +599,12 @@ if ($codespell) {

> >>   $misspellings = join("|", sort keys %spelling_fix) if keys

> >> %spelling_fix;

> >>     sub build_types {

> >> -       my $mods = "(?x:  \n" . join("|\n  ", @modifierList) . "\n)";

> >> -       my $all = "(?x:  \n" . join("|\n  ", @typeList) . "\n)";

> >> +       my $mods = "(?x:  \n" . join("|\n  ", (@modifierList,

> >> @modifierListFile)) . "\n)";

> >> +       my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile))

> >> . "\n)";

> >>         my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered)

> >> . "\n)";

> >>         my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr)

> .

> >> "\n)";

> >>         $Modifier       = qr{(?:$Attribute|$Sparse|$mods)};

> >>         $BasicType      = qr{

> >> -                               (?:$typeOtherOSTypedefs\b)|

> >>                                 (?:$typeTypedefs\b)|

> >>                                 (?:${all}\b)

> >>                 }x;

> >> @@ -528,7 +612,6 @@ sub build_types {

> >>                         (?:$Modifier\s+|const\s+)*

> >>                         (?:

> >>                                 (?:typeof|__typeof__)\s*\([^\)]*\)|

> >> -                               (?:$typeOtherOSTypedefs\b)|

> >>                                 (?:$typeTypedefs\b)|

> >>                                 (?:${all}\b)

> >>                         )

> >> @@ -546,7 +629,6 @@ sub build_types {

> >>                         (?:

> >>                                 (?:typeof|__typeof__)\s*\([^\)]*\)|

> >>                                 (?:$typeTypedefs\b)|

> >> -                               (?:$typeOtherOSTypedefs\b)|

> >>                                 (?:${allWithAttr}\b)

> >>                         )

> >>                         (?:\s+$Modifier|\s+const)*

> >> @@ -577,7 +659,7 @@ our $LvalOrFunc     = qr{((?:[\&\*]\s*)?$Lval)\s*($b

> >> alanced_parens{0,1})\s*};

> >>   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,2}\s*\(|

> >> +       (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)

> >> (?:_[A-Z0-9]+){1,6}\s*\(|

> >>         (?:$Storage\s+)?LIST_HEAD\s*\(|

> >>         (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(

> >>   )};

> >> @@ -719,10 +801,42 @@ my @fixed_inserted = ();

> >>   my @fixed_deleted = ();

> >>   my $fixlinenr = -1;

> >>   +# If input is git commits, extract all commits from the commit

> >> expressions.

> >> +# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.

> >> +die "$P: No git repository found\n" if ($git && !-e ".git");

> >> +

> >> +if ($git) {

> >> +       my @commits = ();

> >> +       foreach my $commit_expr (@ARGV) {

> >> +               my $git_range;

> >> +               if ($commit_expr =~ m/^(.*)-(\d+)$/) {

> >> +                       $git_range = "-$2 $1";

> >> +               } elsif ($commit_expr =~ m/\.\./) {

> >> +                       $git_range = "$commit_expr";

> >> +               } else {

> >> +                       $git_range = "-1 $commit_expr";

> >> +               }

> >> +               my $lines = `git log --no-color --no-merges

> >> --pretty=format:'%H %s' $git_range`;

> >> +               foreach my $line (split(/\n/, $lines)) {

> >> +                       $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;

> >> +                       next if (!defined($1) || !defined($2));

> >> +                       my $sha1 = $1;

> >> +                       my $subject = $2;

> >> +                       unshift(@commits, $sha1);

> >> +                       $git_commits{$sha1} = $subject;

> >> +               }

> >> +       }

> >> +       die "$P: no git commits after extraction!\n" if (@commits == 0);

> >> +       @ARGV = @commits;

> >> +}

> >> +

> >>   my $vname;

> >>   for my $filename (@ARGV) {

> >>         my $FILE;

> >> -       if ($file) {

> >> +       if ($git) {

> >> +               open($FILE, '-|', "git format-patch -M --stdout -1

> >> $filename") ||

> >> +                       die "$P: $filename: git format-patch failed -

> >> $!\n";

> >> +       } elsif ($file) {

> >>                 open($FILE, '-|', "diff -u /dev/null $filename") ||

> >>                         die "$P: $filename: diff failed - $!\n";

> >>         } elsif ($filename eq '-') {

> >> @@ -733,6 +847,8 @@ for my $filename (@ARGV) {

> >>         }

> >>         if ($filename eq '-') {

> >>                 $vname = 'Your patch';

> >> +       } elsif ($git) {

> >> +               $vname = "Commit " . substr($filename, 0, 12) . ' ("' .

> >> $git_commits{$filename} . '")';

> >>         } else {

> >>                 $vname = $filename;

> >>         }

> >> @@ -741,6 +857,13 @@ for my $filename (@ARGV) {

> >>                 push(@rawlines, $_);

> >>         }

> >>         close($FILE);

> >> +

> >> +       if ($#ARGV > 0 && $quiet == 0) {

> >> +               print '-' x length($vname) . "\n";

> >> +               print "$vname\n";

> >> +               print '-' x length($vname) . "\n";

> >> +       }

> >> +

> >>         if (!process($filename)) {

> >>                 $exit = 1;

> >>         }

> >> @@ -750,6 +873,29 @@ for my $filename (@ARGV) {

> >>         @fixed_inserted = ();

> >>         @fixed_deleted = ();

> >>         $fixlinenr = -1;

> >> +       @modifierListFile = ();

> >> +       @typeListFile = ();

> >> +       build_types();

> >> +}

> >> +

> >> +if (!$quiet) {

> >> +       hash_show_words(\%use_type, "Used");

> >> +       hash_show_words(\%ignore_type, "Ignored");

> >> +

> >> +       if ($^V lt 5.10.0) {

> >> +               print << "EOM"

> >> +

> >> +NOTE: perl $^V is not modern enough to detect all possible issues.

> >> +      An upgrade to at least perl v5.10.0 is suggested.

> >> +EOM

> >> +       }

> >> +       if ($exit) {

> >> +               print << "EOM"

> >> +

> >> +NOTE: If any of the errors are false positives, please report

> >> +      them to the maintainer, see CHECKPATCH in MAINTAINERS.

> >> +EOM

> >> +       }

> >>   }

> >>     exit($exit);

> >> @@ -999,13 +1145,18 @@ sub sanitise_line {

> >>                 $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;

> >>         }

> >>   +     if ($allow_c99_comments && $res =~ m@(//.*$)@) {

> >> +               my $match = $1;

> >> +               $res =~ s/\Q$match\E/"$;" x length($match)/e;

> >> +       }

> >> +

> >>         return $res;

> >>   }

> >>     sub get_quoted_string {

> >>         my ($line, $rawline) = @_;

> >>   -     return "" if ($line !~ m/(\"[X\t]+\")/g);

> >> +       return "" if ($line !~ m/($String)/g);

> >>         return substr($rawline, $-[0], $+[0] - $-[0]);

> >>   }

> >>   @@ -1614,13 +1765,13 @@ sub possible {

> >>                         for my $modifier (split(' ', $possible)) {

> >>                                 if ($modifier !~ $notPermitted) {

> >>                                         warn "MODIFIER: $modifier

> >> ($possible) ($line)\n" if ($dbg_possible);

> >> -                                       push(@modifierList, $modifier);

> >> +                                       push(@modifierListFile,

> >> $modifier);

> >>                                 }

> >>                         }

> >>                 } else {

> >>                         warn "POSSIBLE: $possible ($line)\n" if

> >> ($dbg_possible);

> >> -                       push(@typeList, $possible);

> >> +                       push(@typeListFile, $possible);

> >>                 }

> >>                 build_types();

> >>         } else {

> >> @@ -1645,15 +1796,32 @@ sub report {

> >>             (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {

> >>                 return 0;

> >>         }

> >> -       my $line;

> >> +       my $output = '';

> >> +       if (-t STDOUT && $color) {

> >> +               if ($level eq 'ERROR') {

> >> +                       $output .= RED;

> >> +               } elsif ($level eq 'WARNING') {

> >> +                       $output .= YELLOW;

> >> +               } else {

> >> +                       $output .= GREEN;

> >> +               }

> >> +       }

> >> +       $output .= $prefix . $level . ':';

> >>         if ($show_types) {

> >> -               $line = "$prefix$level:$type: $msg\n";

> >> -       } else {

> >> -               $line = "$prefix$level: $msg\n";

> >> +               $output .= BLUE if (-t STDOUT && $color);

> >> +               $output .= "$type:";

> >>         }

> >> -       $line = (split('\n', $line))[0] . "\n" if ($terse);

> >> +       $output .= RESET if (-t STDOUT && $color);

> >> +       $output .= ' ' . $msg . "\n";

> >>   -     push(our @report, $line);

> >> +       if ($showfile) {

> >> +               my @lines = split("\n", $output, -1);

> >> +               splice(@lines, 1, 1);

> >> +               $output = join("\n", @lines);

> >> +       }

> >> +       $output = (split('\n', $output))[0] . "\n" if ($terse);

> >> +

> >> +       push(our @report, $output);

> >>         return 1;

> >>   }

> >> @@ -1899,11 +2067,13 @@ sub process {

> >>         our $clean = 1;

> >>         my $signoff = 0;

> >>         my $is_patch = 0;

> >> -

> >>         my $in_header_lines = $file ? 0 : 1;

> >>         my $in_commit_log = 0;          #Scanning lines before patch

> >> +       my $has_commit_log = 0;         #Encountered lines before patch

> >> +       my $commit_log_possible_stack_dump = 0;

> >>         my $commit_log_long_line = 0;

> >> -       my $reported_maintainer_file = 1; # No MAINTAINTERS so silence

> >> warning

> >> +       my $commit_log_has_diff = 0;

> >> +       my $reported_maintainer_file = 0;

> >>         my $non_utf8_charset = 0;

> >>         my $last_blank_line = 0;

> >> @@ -2036,7 +2206,8 @@ sub process {

> >>                 my $rawline = $rawlines[$linenr - 1];

> >>     #extract the line range in the file after the patch is applied

> >> -               if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/)

> {

> >> +               if (!$in_commit_log &&

> >> +                   $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))?

> \@\@/)

> >> {

> >>                         $is_patch = 1;

> >>                         $first_line = $linenr + 1;

> >>                         $realline=$1-1;

> >> @@ -2077,10 +2248,6 @@ sub process {

> >>                 my $hunk_line = ($realcnt != 0);

> >>   -#make up the handle for any error we report on this line

> >> -               $prefix = "$filename:$realline: " if ($emacs && $file);

> >> -               $prefix = "$filename:$linenr: " if ($emacs && !$file);

> >> -

> >>                 $here = "#$linenr: " if (!$file);

> >>                 $here = "#$realline: " if ($file);

> >>   @@ -2110,8 +2277,19 @@ sub process {

> >>                         $found_file = 1;

> >>                 }

> >>   +#make up the handle for any error we report on this line

> >> +               if ($showfile) {

> >> +                       $prefix = "$realfile:$realline: "

> >> +               } elsif ($emacs) {

> >> +                       if ($file) {

> >> +                               $prefix = "$filename:$realline: ";

> >> +                       } else {

> >> +                               $prefix = "$filename:$linenr: ";

> >> +                       }

> >> +               }

> >> +

> >>                 if ($found_file) {

> >> -                       if ($realfile =~ m@^(drivers/net/|net/)@) {

> >> +                       if ($realfile =~ m@^(?:drivers/net/|net/|

> drivers/staging/)@)

> >> {

> >>                                 $check = 1;

> >>                         } else {

> >>                                 $check = $check_orig;

> >> @@ -2127,6 +2305,17 @@ sub process {

> >>                 $cnt_lines++ if ($realcnt != 0);

> >>   +# Check if the commit log has what seems like a diff which can

> confuse

> >> patch

> >> +               if ($in_commit_log && !$commit_log_has_diff &&

> >> +                   (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&

> >> +                     $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||

> >> +                    $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||

> >> +                    $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {

> >> +                       ERROR("DIFF_IN_COMMIT_MSG",

> >> +                             "Avoid using diff content in the commit

> >> message - patch(1) might not work\n" . $herecurr);

> >> +                       $commit_log_has_diff = 1;

> >> +               }

> >> +

> >>   # Check for incorrect file permissions

> >>                 if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {

> >>                         my $permhere = $here . "FILE: $realfile\n";

> >> @@ -2238,18 +2427,46 @@ sub process {

> >>                               "Remove Gerrit Change-Id's before

> >> submitting upstream.\n" . $herecurr);

> >>                 }

> >>   +# Check if the commit log is in a possible stack dump

> >> +               if ($in_commit_log && !$commit_log_possible_stack_dump

> &&

> >> +                   ($line =~ /^\s*(?:WARNING:|BUG:)/ ||

> >> +                    $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||

> >> +                                       # timestamp

> >> +                    $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) {

> >> +                                       # stack dump address

> >> +                       $commit_log_possible_stack_dump = 1;

> >> +               }

> >> +

> >>   # Check for line lengths > 75 in commit log, warn once

> >>                 if ($in_commit_log && !$commit_log_long_line &&

> >> -                   length($line) > 75) {

> >> +                   length($line) > 75 &&

> >> +                   !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||

> >> +                                       # file delta changes

> >> +                     $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||

> >> +                                       # filename then :

> >> +                     $line =~ /^\s*(?:Fixes:|Link:)/i ||

> >> +                                       # A Fixes: or Link: line

> >> +                     $commit_log_possible_stack_dump)) {

> >>                         WARN("COMMIT_LOG_LONG_LINE",

> >>                              "Possible unwrapped commit description

> >> (prefer a maximum 75 chars per line)\n" . $herecurr);

> >>                         $commit_log_long_line = 1;

> >>                 }

> >>   +# Reset possible stack dump if a blank line is found

> >> +               if ($in_commit_log && $commit_log_possible_stack_dump

> &&

> >> +                   $line =~ /^\s*$/) {

> >> +                       $commit_log_possible_stack_dump = 0;

> >> +               }

> >> +

> >>   # Check for git id commit length and improperly formed commit

> >> descriptions

> >> -               if ($in_commit_log && $line =~

> >> /\b(c)ommit\s+([0-9a-f]{5,})/i) {

> >> -                       my $init_char = $1;

> >> -                       my $orig_commit = lc($2);

> >> +               if ($in_commit_log && !$commit_log_possible_stack_dump

> &&

> >> +                   $line !~ /^\s*(?:Link|Patchwork|http|

> https|BugLink):/i

> >> &&

> >> +                   ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||

> >> +                    ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\

> s"'\(\[]|$)/i

> >> &&

> >> +                     $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&

> >> +                     $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {

> >> +                       my $init_char = "c";

> >> +                       my $orig_commit = "";

> >>                         my $short = 1;

> >>                         my $long = 0;

> >>                         my $case = 1;

> >> @@ -2260,6 +2477,13 @@ sub process {

> >>                         my $orig_desc = "commit description";

> >>                         my $description = "";

> >>   +                     if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i)

> {

> >> +                               $init_char = $1;

> >> +                               $orig_commit = lc($2);

> >> +                       } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {

> >> +                               $orig_commit = lc($1);

> >> +                       }

> >> +

> >>                         $short = 0 if ($line =~

> >> /\bcommit\s+[0-9a-f]{12,40}/i);

> >>                         $long = 1 if ($line =~

> >> /\bcommit\s+[0-9a-f]{41,}/i);

> >>                         $space = 0 if ($line =~ /\bcommit [0-9a-f]/i);

> >> @@ -2343,6 +2567,7 @@ sub process {

> >>                       $rawline =~ /^(commit\b|from\b|[\w-]+:).*$/i)) {

> >>                         $in_header_lines = 0;

> >>                         $in_commit_log = 1;

> >> +                       $has_commit_log = 1;

> >>                 }

> >>     # Check if there is UTF-8 in a commit log when a mail header has

> >> explicitly

> >> @@ -2514,16 +2739,60 @@ sub process {

> >>   # check we are in a valid source file if not then ignore this hunk

> >>                 next if ($realfile !~ /\.(h|c|s|S|pl|sh|dtsi|dts)$/);

> >>   -#line length limit

> >> -               if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&

> >> -                   $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&

> >> -                   !($line =~ /^\+\s*$logFunctions\s*\(\s*(?

> >> :(KERN_\S+\s*|[^"]*))?$String\s*(?:|,|\)\s*;)\s*$/ ||

> >> -                     $line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/

> ||

> >> -                     $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) &&

> >> -                   $length > $max_line_length)

> >> -               {

> >> -                       WARN("LONG_LINE",

> >> -                            "line over $max_line_length characters\n" .

> >> $herecurr);

> >> +# line length limit (with some exclusions)

> >> +#

> >> +# There are a few types of lines that may extend beyond

> $max_line_length:

> >> +#      logging functions like pr_info that end in a string

> >> +#      lines with a single string

> >> +#      #defines that are a single string

> >> +#

> >> +# There are 3 different line length message types:

> >> +# LONG_LINE_COMMENT    a comment starts before but extends beyond

> >> $max_linelength

> >> +# LONG_LINE_STRING     a string starts before but extends beyond

> >> $max_line_length

> >> +# LONG_LINE            all other lines longer than $max_line_length

> >> +#

> >> +# if LONG_LINE is ignored, the other 2 types are also ignored

> >> +#

> >> +

> >> +               if ($line =~ /^\+/ && $length > $max_line_length) {

> >> +                       my $msg_type = "LONG_LINE";

> >> +

> >> +                       # Check the allowed long line types first

> >> +

> >> +                       # logging functions that end in a string that

> >> starts

> >> +                       # before $max_line_length

> >> +                       if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?

> >> :(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&

> >> +                           length(expand_tabs(substr($line, 1,

> >> length($line) - length($1) - 1))) <= $max_line_length) {

> >> +                               $msg_type = "";

> >> +

> >> +                       # lines with only strings (w/ possible

> >> termination)

> >> +                       # #defines with only strings

> >> +                       } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\

> s*;)\s*$/

> >> ||

> >> +                                $line =~ /^\+\s*#\s*define\s+\w+\s+$

> String$/)

> >> {

> >> +                               $msg_type = "";

> >> +

> >> +                       # EFI_GUID is another special case

> >> +                       } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) {

> >> +                               $msg_type = "";

> >> +

> >> +                       # Otherwise set the alternate message types

> >> +

> >> +                       # a comment starts before $max_line_length

> >> +                       } elsif ($line =~ /($;[\s$;]*)$/ &&

> >> +                                length(expand_tabs(substr($line, 1,

> >> length($line) - length($1) - 1))) <= $max_line_length) {

> >> +                               $msg_type = "LONG_LINE_COMMENT"

> >> +

> >> +                       # a quoted string starts before $max_line_length

> >> +                       } elsif ($sline =~

> /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/

> >> &&

> >> +                                length(expand_tabs(substr($line, 1,

> >> length($line) - length($1) - 1))) <= $max_line_length) {

> >> +                               $msg_type = "LONG_LINE_STRING"

> >> +                       }

> >> +

> >> +                       if ($msg_type ne "" &&

> >> +                           (show_type("LONG_LINE") ||

> >> show_type($msg_type))) {

> >> +                               WARN($msg_type,

> >> +                                    "line over $max_line_length

> >> characters\n" . $herecurr);

> >> +                       }

> >>                 }

> >>     # check for adding lines without a newline.

> >> @@ -2581,6 +2850,19 @@ sub process {

> >>                             "Logical continuations should be on the

> >> previous line\n" . $hereprev);

> >>                 }

> >>   +# check indentation starts on a tab stop

> >> +               if ($^V && $^V ge 5.10.0 &&

> >> +                   $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}

> \s*(?:else\b|while\b|\s*$))/)

> >> {

> >> +                       my $indent = length($1);

> >> +                       if ($indent % 8) {

> >> +                               if (WARN("TABSTOP",

> >> +                                        "Statements should start on a

> >> tabstop\n" . $herecurr) &&

> >> +                                   $fix) {

> >> +                                       $fixed[$fixlinenr] =~ s@

> (^\+\t+)

> >> +@$1 . "\t" x ($indent/8)@e;

> >> +                               }

> >> +                       }

> >> +               }

> >> +

> >>   # 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*$/) {

> >> @@ -2628,6 +2910,8 @@ sub process {

> >>                         }

> >>                 }

> >>   +# Block comment styles

> >> +# Networking with an initial /*

> >>                 if ($realfile =~ m@^(drivers/net/|net/)@ &&

> >>                     $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&

> >>                     $rawline =~ /^\+[ \t]*\*/ &&

> >> @@ -2636,22 +2920,23 @@ sub process {

> >>                              "networking block comments don't use an

> >> empty /* line, use /* Comment...\n" . $hereprev);

> >>                 }

> >>   -             if ($realfile =~ m@^(drivers/net/|net/)@ &&

> >> -                   $prevrawline =~ /^\+[ \t]*\/\*/ &&

> #starting

> >> /*

> >> +# Block comments use * on subsequent lines

> >> +               if ($prevline =~ /$;[ \t]*$/ &&                 #ends in

> >> comment

> >> +                   $prevrawline =~ /^\+.*?\/\*/ &&

>  #starting

> >> /*

> >>                     $prevrawline !~ /\*\/[ \t]*$/ &&            #no

> >> trailing */

> >>                     $rawline =~ /^\+/ &&                        #line is

> >> new

> >>                     $rawline !~ /^\+[ \t]*\*/) {                #no

> >> leading *

> >> -                       WARN("NETWORKING_BLOCK_COMMENT_STYLE",

> >> -                            "networking block comments start with * on

> >> subsequent lines\n" . $hereprev);

> >> +                       WARN("BLOCK_COMMENT_STYLE",

> >> +                            "Block comments use * on subsequent

> lines\n"

> >> . $hereprev);

> >>                 }

> >>   -             if ($realfile =~ m@^(drivers/net/|net/)@ &&

> >> -                   $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&

> >>  #trailing */

> >> +# Block comments use */ on trailing lines

> >> +               if ($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);

> >> +                       WARN("BLOCK_COMMENT_STYLE",

> >> +                            "Block comments use a trailing */ on a

> >> separate line\n" . $herecurr);

> >>                 }

> >>     # check for missing blank lines after struct/union declarations

> >> @@ -2957,14 +3242,21 @@ sub process {

> >>                         substr($s, 0, length($c), '');

> >>   +                     # remove inline comments

> >> +                       $s =~ s/$;/ /g;

> >> +                       $c =~ s/$;/ /g;

> >> +

> >> +                       # Find out how long the conditional actually is.

> >> +                       my @newlines = ($c =~ /\n/gs);

> >> +                       my $cond_lines = 1 + $#newlines;

> >> +

> >>                         # 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;

> >> +                       while ($s =~ /\n\s+\\\n/) {

> >> +                               $cond_lines += $s =~ s/\n\s+\\\n/\n/g;

> >> +                       }

> >>                         # We want to check the first line inside the

> block

> >>                         # starting at the end of the conditional, so

> >> remove:

> >> @@ -3031,8 +3323,10 @@ sub process {

> >>                         #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 ''))) {

> >> +                       if ($check && $s ne '' &&

> >> +                           (($sindent % 8) != 0 ||

> >> +                            ($sindent < $indent) ||

> >> +                            ($sindent > $indent + 8))) {

> >>                                 WARN("SUSPECT_CODE_INDENT",

> >>                                      "suspect code indent for

> conditional

> >> statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");

> >>                         }

> >> @@ -3054,6 +3348,30 @@ sub process {

> >>   #ignore lines not being added

> >>                 next if ($line =~ /^[^\+]/);

> >>   +# check for declarations of signed or unsigned without int

> >> +               while ($line =~ m{\b($Declare)\s*(?!char\b|sho

> >> rt\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {

> >> +                       my $type = $1;

> >> +                       my $var = $2;

> >> +                       $var = "" if (!defined $var);

> >> +                       if ($type =~ /^(?:(?:$Storage|$Inline|$Attr

> >> ibute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {

> >> +                               my $sign = $1;

> >> +                               my $pointer = $2;

> >> +

> >> +                               $pointer = "" if (!defined $pointer);

> >> +

> >> +                               if (WARN("UNSPECIFIED_INT",

> >> +                                        "Prefer '" . trim($sign) . "

> >> int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) .

> >> "'\n" . $herecurr) &&

> >> +                                   $fix) {

> >> +                                       my $decl = trim($sign) . " int

> ";

> >> +                                       my $comp_pointer = $pointer;

> >> +                                       $comp_pointer =~ s/\s//g;

> >> +                                       $decl .= $comp_pointer;

> >> +                                       $decl = rtrim($decl) if ($var eq

> >> "");

> >> +                                       $fixed[$fixlinenr] =~ s@

> >> \b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;

> >> +                               }

> >> +                       }

> >> +               }

> >> +

> >>   # TEST: allow direct testing of the type matcher.

> >>                 if ($dbg_type) {

> >>                         if ($line =~ /^.\s*$Declare\s*$/) {

> >> @@ -3173,21 +3491,20 @@ sub process {

> >>                 }

> >>     # check for global initialisers.

> >> -               if ($line =~ /^\+(\s*$Type\s*$Ident\s*(?:\s

> >> +$Modifier))*\s*=\s*(0|NULL|false)\s*;/) {

> >> +               if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modif

> >> ier)*\s*=\s*($zero_initializer)\s*;/) {

> >>                         if (ERROR("GLOBAL_INITIALISERS",

> >> -                                 "do not initialise globals to 0 or

> >> NULL\n" .

> >> -                                     $herecurr) &&

> >> +                                 "do not initialise globals to $1\n" .

> >> $herecurr) &&

> >>                             $fix) {

> >> -                               $fixed[$fixlinenr] =~

> >> s/($Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/$1;/;

> >> +                               $fixed[$fixlinenr] =~

> >> s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;

> >>                         }

> >>                 }

> >>   # check for static initialisers.

> >> -               if ($line =~ /^\+.*\bstatic\s.*=\s*(0|NULL|false)\s*;/)

> {

> >> +               if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_

> initializer)\s*;/)

> >> {

> >>                         if (ERROR("INITIALISED_STATIC",

> >> -                                 "do not initialise statics to 0 or

> >> NULL\n" .

> >> +                                 "do not initialise statics to $1\n" .

> >>                                       $herecurr) &&

> >>                             $fix) {

> >> -                               $fixed[$fixlinenr] =~

> >> s/(\bstatic\s.*?)\s*=\s*(0|NULL|false)\s*;/$1;/;

> >> +                               $fixed[$fixlinenr] =~

> >> s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;

> >>                         }

> >>                 }

> >>   @@ -3268,7 +3585,6 @@ sub process {

> >>                     $line !~ /\btypedef\s+$Type\s*\(\s*\*?$

> Ident\s*\)\s*\(/

> >> &&

> >>                     $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&

> >>                     $line !~ /\b$typeTypedefs\b/ &&

> >> -                   $line !~ /\b$typeOtherOSTypedefs\b/ &&

> >>                     $line !~ /\b__bitwise(?:__|)\b/) {

> >>                         WARN("NEW_TYPEDEFS",

> >>                              "do not add new typedefs\n" . $herecurr);

> >> @@ -3330,13 +3646,15 @@ sub process {

> >>                         }

> >>                 }

> >>   -# # 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;

> >> -#              }

> >> +# avoid BUG() or BUG_ON()

> >> +               if ($line =~ /\b(?:BUG|BUG_ON)\b/) {

> >> +                       my $msg_type = \&WARN;

> >> +                       $msg_type = \&CHK if ($file);

> >> +                       &{$msg_type}("AVOID_BUG",

> >> +                                    "Avoid crashing the kernel - try

> >> using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" .

> $herecurr);

> >> +               }

> >>   +# avoid LINUX_VERSION_CODE

> >>                 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);

> >> @@ -3923,7 +4241,7 @@ sub process {

> >>   ##            }

> >>     #need space before brace following if, while, etc

> >> -               if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\){/) ||

> >> +               if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||

> >>                     $line =~ /do\{/) {

> >>                         if (ERROR("SPACING",

> >>                                   "space required before the open brace

> >> '{'\n" . $herecurr) &&

> >> @@ -4070,6 +4388,35 @@ sub process {

> >>                         }

> >>                 }

> >>   +# comparisons with a constant or upper case identifier on the left

> >> +#      avoid cases like "foo + BAR < baz"

> >> +#      only fix matches surrounded by parentheses to avoid incorrect

> >> +#      conversions like "FOO < baz() + 5" being "misfixed" to "baz() >

> >> FOO + 5"

> >> +               if ($^V && $^V ge 5.10.0 &&

> >> +                   $line =~ /^\+(.*)\b($Constant|[A-Z_][A-

> >> Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {

> >> +                       my $lead = $1;

> >> +                       my $const = $2;

> >> +                       my $comp = $3;

> >> +                       my $to = $4;

> >> +                       my $newcomp = $comp;

> >> +                       if ($lead !~ /(?:$Operators|\.)\s*$/ &&

> >> +                           $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&

> >> +                           WARN("CONSTANT_COMPARISON",

> >> +                                "Comparisons should place the constant

> >> on the right side of the test\n" . $herecurr) &&

> >> +                           $fix) {

> >> +                               if ($comp eq "<") {

> >> +                                       $newcomp = ">";

> >> +                               } elsif ($comp eq "<=") {

> >> +                                       $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;

> >> @@ -4256,12 +4603,6 @@ sub process {

> >>   #Ignore SI style variants like nS, mV and dB (ie: max_uV,

> >> regulator_min_uA_show)

> >>                             $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_

> [a-z_]+)?$/

> >> &&

> >>   #Ignore some three character SI units explicitly, like MiB and KHz

> >> -                           $var !~ /\bCU_/ &&

> >> -                           $var !~ /\bPRI[diux]32/ &&

> >> -                           $var !~ /\bPRI[diux]64/ &&

> >> -                           $var !~ /\bSCN[diux]8/ &&

> >> -                           $var !~ /\bSCN[diux]32/ &&

> >> -                           $var !~ /\bSCN[diux]64/ &&

> >>                             $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[

> KMGT]?Hz)(?:_[a-z_]+)?$/)

> >> {

> >>                                 while ($var =~ m{($Ident)}g) {

> >>                                         my $word = $1;

> >> @@ -4331,7 +4672,7 @@ sub process {

> >>                         #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 =~ /\#\#/);

> >> +                       $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx

> !~

> >> /\#\#\s*(?:__VA_ARGS__|args)\b/);

> >>                         $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:

> >> \([^\)]*\))?\s*//;

> >>                         $dstat =~ s/$;//g;

> >> @@ -4342,16 +4683,19 @@ 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/)

> >> +                       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/a

> >> sm_volatile/g;

> >> +

> >>                         my $exceptions = qr{

> >>                                 $Declare|

> >>                                 module_param_named|

> >> @@ -4362,7 +4706,8 @@ sub process {

> >>                                 union|

> >>                                 struct|

> >>                                 \.$Ident\s*=\s*|

> >> -                               ^\"|\"$

> >> +                               ^\"|\"$|

> >> +                               ^\[

> >>                         }x;

> >>                         #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";

> >>                         if ($dstat ne '' &&

> >> @@ -4629,7 +4974,7 @@ sub process {

> >>   # to grep for the string.  Make exceptions when the previous string

> >> ends in a

> >>   # newline (multiple lines in one string constant) or '\t', '\r', ';',

> >> or '{'

> >>   # (common in inline assembly) or is a octal \123 or hexadecimal \xaf

> >> value

> >> -               if ($line =~ /^\+\s*"[X\t]*"/ &&

> >> +               if ($line =~ /^\+\s*$String/ &&

> >>                     $prevline =~ /"\s*$/ &&

> >>                     $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-

> >> 9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {

> >>                         if (WARN("SPLIT_STRING",

> >> @@ -4675,27 +5020,31 @@ sub process {

> >>                 }

> >>     # concatenated string without spaces between elements

> >> -               if ($line =~ /"X+"[A-Z_]+/ || $line =~ /[A-Z_]+"X+"/) {

> >> +               if ($line =~ /$String[A-Z_]/ || $line =~

> >> /[A-Za-z0-9_]$String/) {

> >>                         CHK("CONCATENATED_STRING",

> >>                             "Concatenated strings should use spaces

> >> between elements\n" . $herecurr);

> >>                 }

> >>     # uncoalesced string fragments

> >> -               if ($line =~ /"X*"\s*"/) {

> >> +               if ($line =~ /$String\s*"/) {

> >>                         WARN("STRING_FRAGMENTS",

> >>                              "Consecutive strings are generally better

> as

> >> a single string\n" . $herecurr);

> >>                 }

> >>   -# check for %L{u,d,i} in strings

> >> +# check for %L{u,d,i} and 0x%[udi] in strings

> >>                 my $string;

> >>                 while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {

> >>                         $string = substr($rawline, $-[1], $+[1] -

> $-[1]);

> >>                         $string =~ s/%%/__/g;

> >> -                       if ($string =~ /(?<!%)%L[udi]/) {

> >> +                       if ($string =~ /(?<!%)%[\*\d\.\$]*L[udi]/) {

> >>                                 WARN("PRINTF_L",

> >>                                      "\%Ld/%Lu are not-standard C, use

> >> %lld/%llu\n" . $herecurr);

> >>                                 last;

> >>                         }

> >> +                       if ($string =~ /0x%[\*\d\.\$\Llzth]*[udi]/) {

> >> +                               ERROR("PRINTF_0xDECIMAL",

> >> +                                     "Prefixing 0x with decimal output

> >> is defective\n" . $herecurr);

> >> +                       }

> >>                 }

> >>     # check for line continuations in quoted strings with odd counts of

> "

> >> @@ -4713,10 +5062,34 @@ sub process {

> >>     # 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 and this check is

> >> probably not required\n" . $hereprev);

> >> +                       my $tested = quotemeta($1);

> >> +                       my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';

> >> +                       if ($line =~ /\b(kfree|usb_free_urb|debugfs

> >> _remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/)

> {

> >> +                               my $func = $1;

> >> +                               if (WARN('NEEDLESS_IF',

> >> +                                        "$func(NULL) is safe and this

> >> check is probably not required\n" . $hereprev) &&

> >> +                                   $fix) {

> >> +                                       my $do_fix = 1;

> >> +                                       my $leading_tabs = "";

> >> +                                       my $new_leading_tabs = "";

> >> +                                       if ($lines[$linenr - 2] =~

> >> /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {

> >> +                                               $leading_tabs = $1;

> >> +                                       } else {

> >> +                                               $do_fix = 0;

> >> +                                       }

> >> +                                       if ($lines[$linenr - 1] =~

> >> /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {

> >> +                                               $new_leading_tabs = $1;

> >> +                                               if

> (length($leading_tabs)

> >> + 1 ne length($new_leading_tabs)) {

> >> +                                                       $do_fix = 0;

> >> +                                               }

> >> +                                       } else {

> >> +                                               $do_fix = 0;

> >> +                                       }

> >> +                                       if ($do_fix) {

> >> +

> >>  fix_delete_line($fixlinenr - 1, $prevrawline);

> >> +                                               $fixed[$fixlinenr] =~

> >> s/^\+$new_leading_tabs/\+$leading_tabs/;

> >> +                                       }

> >> +                               }

> >>                         }

> >>                 }

> >>   @@ -4902,12 +5275,69 @@ sub process {

> >>                         }

> >>                 }

> >>   # check for memory barriers without a comment.

> >> -               if ($line =~ /\b(mb|rmb|wmb|read_barrier_de

> >> pends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) {

> >> +

> >> +               my $barriers = qr{

> >> +                       mb|

> >> +                       rmb|

> >> +                       wmb|

> >> +                       read_barrier_depends

> >> +               }x;

> >> +               my $barrier_stems = qr{

> >> +                       mb__before_atomic|

> >> +                       mb__after_atomic|

> >> +                       store_release|

> >> +                       load_acquire|

> >> +                       store_mb|

> >> +                       (?:$barriers)

> >> +               }x;

> >> +               my $all_barriers = qr{

> >> +                       (?:$barriers)|

> >> +                       smp_(?:$barrier_stems)|

> >> +                       virt_(?:$barrier_stems)

> >> +               }x;

> >> +

> >> +               if ($line =~ /\b(?:$all_barriers)\s*\(/) {

> >>                         if (!ctx_has_comment($first_line, $linenr)) {

> >>                                 WARN("MEMORY_BARRIER",

> >>                                      "memory barrier without comment\n"

> .

> >> $herecurr);

> >>                         }

> >>                 }

> >> +

> >> +               my $underscore_smp_barriers =

> >> qr{__smp_(?:$barrier_stems)}x;

> >> +

> >> +               if ($realfile !~ m@^include/asm-generic/@ &&

> >> +                   $realfile !~ m@/barrier\.h$@ &&

> >> +                   $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&

> >> +                   $line !~ m/^.\s*\#\s*define\s+(?:$

> underscore_smp_barriers)\s*\(/)

> >> {

> >> +                       WARN("MEMORY_BARRIER",

> >> +                            "__smp memory barriers shouldn't be used

> >> outside barrier.h and asm-generic\n" . $herecurr);

> >> +               }

> >> +

> >> +# check for waitqueue_active without a comment.

> >> +               if ($line =~ /\bwaitqueue_active\s*\(/) {

> >> +                       if (!ctx_has_comment($first_line, $linenr)) {

> >> +                               WARN("WAITQUEUE_ACTIVE",

> >> +                                    "waitqueue_active without

> comment\n"

> >> . $herecurr);

> >> +                       }

> >> +               }

> >> +

> >> +# Check for expedited grace periods that interrupt non-idle non-nohz

> >> +# online CPUs.  These expedited can therefore degrade real-time

> response

> >> +# if used carelessly, and should be avoided where not absolutely

> >> +# needed.  It is always OK to use synchronize_rcu_expedited() and

> >> +# synchronize_sched_expedited() at boot time (before real-time

> >> applications

> >> +# start) and in error situations where real-time response is

> compromised

> >> in

> >> +# any case.  Note that synchronize_srcu_expedited() does -not-

> interrupt

> >> +# other CPUs, so don't warn on uses of synchronize_srcu_expedited().

> >> +# Of course, nothing comes for free, and srcu_read_lock() and

> >

> >

>

>

> --

> Mike Holmes

> Program Manager - Linaro Networking Group

> Linaro.org <http://www.linaro.org/> *│ *Open source software for ARM SoCs

> "Work should be fun and collaborative, the rest follows"

>
Mike Holmes Aug. 31, 2016, 9:16 p.m. UTC | #6
On 31 August 2016 at 16:29, Bill Fischofer <bill.fischofer@linaro.org>
wrote:

> Should we merge or just have odpcheckpatch.pl be a wrapper around the

> standard checkpatch.pl that calls it with the --ignore options we need?

>


We have the ignore file already in   .checkpatch.conf



> That would seem to make future maintenance easier since we could just use

> the vanilla checkpatch.pl from kernel.org as-is as the base code.

>


I agree a wrapper might help for anything we find cant be changed to our
liking, but currently there is one small patch we made that helps it ignore
ODP_ABORT etc


>

> On Wed, Aug 31, 2016 at 10:31 AM, Mike Holmes <mike.holmes@linaro.org>

> wrote:

>

>> On 30 August 2016 at 15:17, Maxim Uvarov <maxim.uvarov@linaro.org> wrote:

>>

>> > How is this patch was generated? Did you apply upstream patches on top

>> of

>> > our current checkpatch? Were local changes included to that patch?

>> > We should not forget to pull all local things on top of updates.

>> >

>>

>> That is an issue, I see we touched this code, if we do that we need to

>> call

>> it odpcheckpatch.pl becasue it is calrly not chackpatch any longer - very

>> confusing

>>

>> I will merge and then change its name so that it is obvious

>>

>>

>> >

>> > Maxim.

>> >

>> > On 08/30/16 20:14, Mike Holmes wrote:

>> >

>> >> The existing checkpatch used by ODP crashes when used on recent patches

>> >> by Bill,

>> >> update to the latest version. The latest version has a new test that we

>> >> need to disable

>> >> that warns about not using kernel types:

>> >>

>> >> PREFER_KERNEL_TYPES

>> >> check for c99 types like uint8_t used outside of uapi

>> >>

>> >> Signed-off-by: Mike Holmes <mike.holmes@linaro.org>

>> >> ---

>> >>   .checkpatch.conf      |   1 +

>> >>   scripts/checkpatch.pl | 820 ++++++++++++++++++++++++++++++

>> >> ++++++++++++--------

>> >>   2 files changed, 690 insertions(+), 131 deletions(-)

>> >>

>> >> diff --git a/.checkpatch.conf b/.checkpatch.conf

>> >> index 1e7d663..81723d6 100644

>> >> --- a/.checkpatch.conf

>> >> +++ b/.checkpatch.conf

>> >> @@ -8,3 +8,4 @@

>> >>   --ignore=BIT_MACRO

>> >>   --codespell

>> >>   --codespellfile=/usr/share/codespell/dictionary.txt

>> >> +--ignore=PREFER_KERNEL_TYPES

>> >> diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl

>> >> index 16316b9..4de3cc4 100755

>> >> --- a/scripts/checkpatch.pl

>> >> +++ b/scripts/checkpatch.pl

>> >> @@ -9,6 +9,7 @@ use strict;

>> >>   use POSIX;

>> >>   use File::Basename;

>> >>   use Cwd 'abs_path';

>> >> +use Term::ANSIColor qw(:constants);

>> >>     my $P = $0;

>> >>   my $D = dirname(abs_path($P));

>> >> @@ -24,13 +25,17 @@ 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;

>> >> @@ -48,7 +53,9 @@ 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/local/share/codespell/dictionary.txt";

>> >> +my $codespellfile = "/usr/share/codespell/dictionary.txt";

>> >> +my $color = 1;

>> >> +my $allow_c99_comments = 1;

>> >>     sub help {

>> >>         my ($exitcode) = @_;

>> >> @@ -64,13 +71,25 @@ Options:

>> >>     --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

>> >> -  --show-types               show the message "types" in the output

>> >>     --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

>> >> @@ -91,8 +110,9 @@ Options:

>> >>     --ignore-perl-version      override checking of perl version.

>> expect

>> >>                                runtime errors.

>> >>     --codespell                Use the codespell dictionary for

>> >> spelling/typos

>> >> -                             (default:/usr/local/share/cod

>> >> espell/dictionary.txt)

>> >> +                             (default:/usr/share/

>> >> codespell/dictionary.txt)

>> >>     --codespellfile            Use this codespell dictionary

>> >> +  --color                    Use colors when output is STDOUT

>> (default:

>> >> on)

>> >>     -h, --help, --version      display this help and exit

>> >>     When FILE is - read standard input.

>> >> @@ -101,6 +121,37 @@ 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 = ();

>> >> +       for ($text =~ /\b(?:(?:CHK|WARN|ERROR)\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;

>> >> @@ -134,12 +185,15 @@ GetOptions(

>> >>         '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,

>> >> @@ -153,12 +207,15 @@ GetOptions(

>> >>         'test-only=s'   => \$tst_only,

>> >>         'codespell!'    => \$codespell,

>> >>         'codespellfile=s'       => \$codespellfile,

>> >> +       'color!'        => \$color,

>> >>         '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;

>> >>   @@ -171,9 +228,9 @@ if ($^V && $^V lt $minimum_perl_version) {

>> >>         }

>> >>   }

>> >>   +#if no filenames are given, push '-' to read patch from stdin

>> >>   if ($#ARGV < 0) {

>> >> -       print "$P: no input files\n";

>> >> -       exit(1);

>> >> +       push(@ARGV, '-');

>> >>   }

>> >>     sub hash_save_array_words {

>> >> @@ -196,12 +253,12 @@ sub hash_save_array_words {

>> >>   sub hash_show_words {

>> >>         my ($hashRef, $prefix) = @_;

>> >>   -     if ($quiet == 0 && keys %$hashRef) {

>> >> -               print "NOTE: $prefix message types:";

>> >> +       if (keys %$hashRef) {

>> >> +               print "\nNOTE: $prefix message types:";

>> >>                 foreach my $word (sort keys %$hashRef) {

>> >>                         print " $word";

>> >>                 }

>> >> -               print "\n\n";

>> >> +               print "\n";

>> >>         }

>> >>   }

>> >>   @@ -261,7 +318,8 @@ our $Sparse       = qr{

>> >>                         __init_refok|

>> >>                         __kprobes|

>> >>                         __ref|

>> >> -                       __rcu

>> >> +                       __rcu|

>> >> +                       __private

>> >>                 }x;

>> >>   our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};

>> >>   our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};

>> >> @@ -347,15 +405,22 @@ our $UTF8 = qr{

>> >>         | $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 $typeTypedefs = qr{(?x:

>> >> +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|)|

>> >> @@ -363,11 +428,7 @@ our $logFunctions = qr{(?x:

>> >>         WARN(?:_RATELIMIT|_ONCE|)|

>> >>         panic|

>> >>         MODULE_[A-Z_]+|

>> >> -       seq_vprintf|seq_printf|seq_puts|

>> >> -       ODP_ASSERT|ODP_DBG|ODP_ERR|ODP_ABORT|ODP_LOG|ODP_PRINT|

>> >> -       EXAMPLE_DBG|EXAMPLE_ERR|EXAMPLE_ABORT|

>> >> -       LOG_DBG|LOG_ERR|LOG_ABORT|

>> >> -       printf

>> >> +       seq_vprintf|seq_printf|seq_puts

>> >>   )};

>> >>     our $signature_tags = qr{(?xi:

>> >> @@ -422,6 +483,29 @@ our @typeList = (

>> >>         qr{${Ident}_handler_fn},

>> >>         @typeListMisordered,

>> >>   );

>> >> +

>> >> +our $C90_int_types = qr{(?x:

>> >> +       long\s+long\s+int\s+(?:un)?signed|

>> >> +       long\s+long\s+(?:un)?signed\s+int|

>> >> +       long\s+long\s+(?:un)?signed|

>> >> +       (?:(?:un)?signed\s+)?long\s+long\s+int|

>> >> +       (?:(?:un)?signed\s+)?long\s+long|

>> >> +       int\s+long\s+long\s+(?:un)?signed|

>> >> +       int\s+(?:(?:un)?signed\s+)?long\s+long|

>> >> +

>> >> +       long\s+int\s+(?:un)?signed|

>> >> +       long\s+(?:un)?signed\s+int|

>> >> +       long\s+(?:un)?signed|

>> >> +       (?:(?:un)?signed\s+)?long\s+int|

>> >> +       (?:(?:un)?signed\s+)?long|

>> >> +       int\s+long\s+(?:un)?signed|

>> >> +       int\s+(?:(?:un)?signed\s+)?long|

>> >> +

>> >> +       int\s+(?:un)?signed|

>> >> +       (?:(?:un)?signed\s+)?int

>> >> +)};

>> >> +

>> >> +our @typeListFile = ();

>> >>   our @typeListWithAttr = (

>> >>         @typeList,

>> >>         qr{struct\s+$InitAttribute\s+$Ident},

>> >> @@ -431,6 +515,7 @@ our @typeListWithAttr = (

>> >>   our @modifierList = (

>> >>         qr{fastcall},

>> >>   );

>> >> +our @modifierListFile = ();

>> >>     our @mode_permission_funcs = (

>> >>         ["module_param", 3],

>> >> @@ -514,13 +599,12 @@ if ($codespell) {

>> >>   $misspellings = join("|", sort keys %spelling_fix) if keys

>> >> %spelling_fix;

>> >>     sub build_types {

>> >> -       my $mods = "(?x:  \n" . join("|\n  ", @modifierList) . "\n)";

>> >> -       my $all = "(?x:  \n" . join("|\n  ", @typeList) . "\n)";

>> >> +       my $mods = "(?x:  \n" . join("|\n  ", (@modifierList,

>> >> @modifierListFile)) . "\n)";

>> >> +       my $all = "(?x:  \n" . join("|\n  ", (@typeList,

>> @typeListFile))

>> >> . "\n)";

>> >>         my $Misordered = "(?x:  \n" . join("|\n  ",

>> @typeListMisordered)

>> >> . "\n)";

>> >>         my $allWithAttr = "(?x:  \n" . join("|\n  ",

>> @typeListWithAttr) .

>> >> "\n)";

>> >>         $Modifier       = qr{(?:$Attribute|$Sparse|$mods)};

>> >>         $BasicType      = qr{

>> >> -                               (?:$typeOtherOSTypedefs\b)|

>> >>                                 (?:$typeTypedefs\b)|

>> >>                                 (?:${all}\b)

>> >>                 }x;

>> >> @@ -528,7 +612,6 @@ sub build_types {

>> >>                         (?:$Modifier\s+|const\s+)*

>> >>                         (?:

>> >>                                 (?:typeof|__typeof__)\s*\([^\)]*\)|

>> >> -                               (?:$typeOtherOSTypedefs\b)|

>> >>                                 (?:$typeTypedefs\b)|

>> >>                                 (?:${all}\b)

>> >>                         )

>> >> @@ -546,7 +629,6 @@ sub build_types {

>> >>                         (?:

>> >>                                 (?:typeof|__typeof__)\s*\([^\)]*\)|

>> >>                                 (?:$typeTypedefs\b)|

>> >> -                               (?:$typeOtherOSTypedefs\b)|

>> >>                                 (?:${allWithAttr}\b)

>> >>                         )

>> >>                         (?:\s+$Modifier|\s+const)*

>> >> @@ -577,7 +659,7 @@ our $LvalOrFunc     =

>> qr{((?:[\&\*]\s*)?$Lval)\s*($b

>> >> alanced_parens{0,1})\s*};

>> >>   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,2}\s*\(|

>> >> +       (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)

>> >> (?:_[A-Z0-9]+){1,6}\s*\(|

>> >>         (?:$Storage\s+)?LIST_HEAD\s*\(|

>> >>         (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(

>> >>   )};

>> >> @@ -719,10 +801,42 @@ my @fixed_inserted = ();

>> >>   my @fixed_deleted = ();

>> >>   my $fixlinenr = -1;

>> >>   +# If input is git commits, extract all commits from the commit

>> >> expressions.

>> >> +# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.

>> >> +die "$P: No git repository found\n" if ($git && !-e ".git");

>> >> +

>> >> +if ($git) {

>> >> +       my @commits = ();

>> >> +       foreach my $commit_expr (@ARGV) {

>> >> +               my $git_range;

>> >> +               if ($commit_expr =~ m/^(.*)-(\d+)$/) {

>> >> +                       $git_range = "-$2 $1";

>> >> +               } elsif ($commit_expr =~ m/\.\./) {

>> >> +                       $git_range = "$commit_expr";

>> >> +               } else {

>> >> +                       $git_range = "-1 $commit_expr";

>> >> +               }

>> >> +               my $lines = `git log --no-color --no-merges

>> >> --pretty=format:'%H %s' $git_range`;

>> >> +               foreach my $line (split(/\n/, $lines)) {

>> >> +                       $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;

>> >> +                       next if (!defined($1) || !defined($2));

>> >> +                       my $sha1 = $1;

>> >> +                       my $subject = $2;

>> >> +                       unshift(@commits, $sha1);

>> >> +                       $git_commits{$sha1} = $subject;

>> >> +               }

>> >> +       }

>> >> +       die "$P: no git commits after extraction!\n" if (@commits ==

>> 0);

>> >> +       @ARGV = @commits;

>> >> +}

>> >> +

>> >>   my $vname;

>> >>   for my $filename (@ARGV) {

>> >>         my $FILE;

>> >> -       if ($file) {

>> >> +       if ($git) {

>> >> +               open($FILE, '-|', "git format-patch -M --stdout -1

>> >> $filename") ||

>> >> +                       die "$P: $filename: git format-patch failed -

>> >> $!\n";

>> >> +       } elsif ($file) {

>> >>                 open($FILE, '-|', "diff -u /dev/null $filename") ||

>> >>                         die "$P: $filename: diff failed - $!\n";

>> >>         } elsif ($filename eq '-') {

>> >> @@ -733,6 +847,8 @@ for my $filename (@ARGV) {

>> >>         }

>> >>         if ($filename eq '-') {

>> >>                 $vname = 'Your patch';

>> >> +       } elsif ($git) {

>> >> +               $vname = "Commit " . substr($filename, 0, 12) . ' ("' .

>> >> $git_commits{$filename} . '")';

>> >>         } else {

>> >>                 $vname = $filename;

>> >>         }

>> >> @@ -741,6 +857,13 @@ for my $filename (@ARGV) {

>> >>                 push(@rawlines, $_);

>> >>         }

>> >>         close($FILE);

>> >> +

>> >> +       if ($#ARGV > 0 && $quiet == 0) {

>> >> +               print '-' x length($vname) . "\n";

>> >> +               print "$vname\n";

>> >> +               print '-' x length($vname) . "\n";

>> >> +       }

>> >> +

>> >>         if (!process($filename)) {

>> >>                 $exit = 1;

>> >>         }

>> >> @@ -750,6 +873,29 @@ for my $filename (@ARGV) {

>> >>         @fixed_inserted = ();

>> >>         @fixed_deleted = ();

>> >>         $fixlinenr = -1;

>> >> +       @modifierListFile = ();

>> >> +       @typeListFile = ();

>> >> +       build_types();

>> >> +}

>> >> +

>> >> +if (!$quiet) {

>> >> +       hash_show_words(\%use_type, "Used");

>> >> +       hash_show_words(\%ignore_type, "Ignored");

>> >> +

>> >> +       if ($^V lt 5.10.0) {

>> >> +               print << "EOM"

>> >> +

>> >> +NOTE: perl $^V is not modern enough to detect all possible issues.

>> >> +      An upgrade to at least perl v5.10.0 is suggested.

>> >> +EOM

>> >> +       }

>> >> +       if ($exit) {

>> >> +               print << "EOM"

>> >> +

>> >> +NOTE: If any of the errors are false positives, please report

>> >> +      them to the maintainer, see CHECKPATCH in MAINTAINERS.

>> >> +EOM

>> >> +       }

>> >>   }

>> >>     exit($exit);

>> >> @@ -999,13 +1145,18 @@ sub sanitise_line {

>> >>                 $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;

>> >>         }

>> >>   +     if ($allow_c99_comments && $res =~ m@(//.*$)@) {

>> >> +               my $match = $1;

>> >> +               $res =~ s/\Q$match\E/"$;" x length($match)/e;

>> >> +       }

>> >> +

>> >>         return $res;

>> >>   }

>> >>     sub get_quoted_string {

>> >>         my ($line, $rawline) = @_;

>> >>   -     return "" if ($line !~ m/(\"[X\t]+\")/g);

>> >> +       return "" if ($line !~ m/($String)/g);

>> >>         return substr($rawline, $-[0], $+[0] - $-[0]);

>> >>   }

>> >>   @@ -1614,13 +1765,13 @@ sub possible {

>> >>                         for my $modifier (split(' ', $possible)) {

>> >>                                 if ($modifier !~ $notPermitted) {

>> >>                                         warn "MODIFIER: $modifier

>> >> ($possible) ($line)\n" if ($dbg_possible);

>> >> -                                       push(@modifierList, $modifier);

>> >> +                                       push(@modifierListFile,

>> >> $modifier);

>> >>                                 }

>> >>                         }

>> >>                 } else {

>> >>                         warn "POSSIBLE: $possible ($line)\n" if

>> >> ($dbg_possible);

>> >> -                       push(@typeList, $possible);

>> >> +                       push(@typeListFile, $possible);

>> >>                 }

>> >>                 build_types();

>> >>         } else {

>> >> @@ -1645,15 +1796,32 @@ sub report {

>> >>             (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {

>> >>                 return 0;

>> >>         }

>> >> -       my $line;

>> >> +       my $output = '';

>> >> +       if (-t STDOUT && $color) {

>> >> +               if ($level eq 'ERROR') {

>> >> +                       $output .= RED;

>> >> +               } elsif ($level eq 'WARNING') {

>> >> +                       $output .= YELLOW;

>> >> +               } else {

>> >> +                       $output .= GREEN;

>> >> +               }

>> >> +       }

>> >> +       $output .= $prefix . $level . ':';

>> >>         if ($show_types) {

>> >> -               $line = "$prefix$level:$type: $msg\n";

>> >> -       } else {

>> >> -               $line = "$prefix$level: $msg\n";

>> >> +               $output .= BLUE if (-t STDOUT && $color);

>> >> +               $output .= "$type:";

>> >>         }

>> >> -       $line = (split('\n', $line))[0] . "\n" if ($terse);

>> >> +       $output .= RESET if (-t STDOUT && $color);

>> >> +       $output .= ' ' . $msg . "\n";

>> >>   -     push(our @report, $line);

>> >> +       if ($showfile) {

>> >> +               my @lines = split("\n", $output, -1);

>> >> +               splice(@lines, 1, 1);

>> >> +               $output = join("\n", @lines);

>> >> +       }

>> >> +       $output = (split('\n', $output))[0] . "\n" if ($terse);

>> >> +

>> >> +       push(our @report, $output);

>> >>         return 1;

>> >>   }

>> >> @@ -1899,11 +2067,13 @@ sub process {

>> >>         our $clean = 1;

>> >>         my $signoff = 0;

>> >>         my $is_patch = 0;

>> >> -

>> >>         my $in_header_lines = $file ? 0 : 1;

>> >>         my $in_commit_log = 0;          #Scanning lines before patch

>> >> +       my $has_commit_log = 0;         #Encountered lines before patch

>> >> +       my $commit_log_possible_stack_dump = 0;

>> >>         my $commit_log_long_line = 0;

>> >> -       my $reported_maintainer_file = 1; # No MAINTAINTERS so silence

>> >> warning

>> >> +       my $commit_log_has_diff = 0;

>> >> +       my $reported_maintainer_file = 0;

>> >>         my $non_utf8_charset = 0;

>> >>         my $last_blank_line = 0;

>> >> @@ -2036,7 +2206,8 @@ sub process {

>> >>                 my $rawline = $rawlines[$linenr - 1];

>> >>     #extract the line range in the file after the patch is applied

>> >> -               if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))?

>> \@\@/) {

>> >> +               if (!$in_commit_log &&

>> >> +                   $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))?

>> \@\@/)

>> >> {

>> >>                         $is_patch = 1;

>> >>                         $first_line = $linenr + 1;

>> >>                         $realline=$1-1;

>> >> @@ -2077,10 +2248,6 @@ sub process {

>> >>                 my $hunk_line = ($realcnt != 0);

>> >>   -#make up the handle for any error we report on this line

>> >> -               $prefix = "$filename:$realline: " if ($emacs && $file);

>> >> -               $prefix = "$filename:$linenr: " if ($emacs && !$file);

>> >> -

>> >>                 $here = "#$linenr: " if (!$file);

>> >>                 $here = "#$realline: " if ($file);

>> >>   @@ -2110,8 +2277,19 @@ sub process {

>> >>                         $found_file = 1;

>> >>                 }

>> >>   +#make up the handle for any error we report on this line

>> >> +               if ($showfile) {

>> >> +                       $prefix = "$realfile:$realline: "

>> >> +               } elsif ($emacs) {

>> >> +                       if ($file) {

>> >> +                               $prefix = "$filename:$realline: ";

>> >> +                       } else {

>> >> +                               $prefix = "$filename:$linenr: ";

>> >> +                       }

>> >> +               }

>> >> +

>> >>                 if ($found_file) {

>> >> -                       if ($realfile =~ m@^(drivers/net/|net/)@) {

>> >> +                       if ($realfile =~ m@

>> ^(?:drivers/net/|net/|drivers/staging/)@)

>> >> {

>> >>                                 $check = 1;

>> >>                         } else {

>> >>                                 $check = $check_orig;

>> >> @@ -2127,6 +2305,17 @@ sub process {

>> >>                 $cnt_lines++ if ($realcnt != 0);

>> >>   +# Check if the commit log has what seems like a diff which can

>> confuse

>> >> patch

>> >> +               if ($in_commit_log && !$commit_log_has_diff &&

>> >> +                   (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&

>> >> +                     $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||

>> >> +                    $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||

>> >> +                    $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {

>> >> +                       ERROR("DIFF_IN_COMMIT_MSG",

>> >> +                             "Avoid using diff content in the commit

>> >> message - patch(1) might not work\n" . $herecurr);

>> >> +                       $commit_log_has_diff = 1;

>> >> +               }

>> >> +

>> >>   # Check for incorrect file permissions

>> >>                 if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {

>> >>                         my $permhere = $here . "FILE: $realfile\n";

>> >> @@ -2238,18 +2427,46 @@ sub process {

>> >>                               "Remove Gerrit Change-Id's before

>> >> submitting upstream.\n" . $herecurr);

>> >>                 }

>> >>   +# Check if the commit log is in a possible stack dump

>> >> +               if ($in_commit_log && !$commit_log_possible_stack_dump

>> &&

>> >> +                   ($line =~ /^\s*(?:WARNING:|BUG:)/ ||

>> >> +                    $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||

>> >> +                                       # timestamp

>> >> +                    $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) {

>> >> +                                       # stack dump address

>> >> +                       $commit_log_possible_stack_dump = 1;

>> >> +               }

>> >> +

>> >>   # Check for line lengths > 75 in commit log, warn once

>> >>                 if ($in_commit_log && !$commit_log_long_line &&

>> >> -                   length($line) > 75) {

>> >> +                   length($line) > 75 &&

>> >> +                   !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||

>> >> +                                       # file delta changes

>> >> +                     $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||

>> >> +                                       # filename then :

>> >> +                     $line =~ /^\s*(?:Fixes:|Link:)/i ||

>> >> +                                       # A Fixes: or Link: line

>> >> +                     $commit_log_possible_stack_dump)) {

>> >>                         WARN("COMMIT_LOG_LONG_LINE",

>> >>                              "Possible unwrapped commit description

>> >> (prefer a maximum 75 chars per line)\n" . $herecurr);

>> >>                         $commit_log_long_line = 1;

>> >>                 }

>> >>   +# Reset possible stack dump if a blank line is found

>> >> +               if ($in_commit_log && $commit_log_possible_stack_dump

>> &&

>> >> +                   $line =~ /^\s*$/) {

>> >> +                       $commit_log_possible_stack_dump = 0;

>> >> +               }

>> >> +

>> >>   # Check for git id commit length and improperly formed commit

>> >> descriptions

>> >> -               if ($in_commit_log && $line =~

>> >> /\b(c)ommit\s+([0-9a-f]{5,})/i) {

>> >> -                       my $init_char = $1;

>> >> -                       my $orig_commit = lc($2);

>> >> +               if ($in_commit_log && !$commit_log_possible_stack_dump

>> &&

>> >> +                   $line !~ /^\s*(?:Link|Patchwork|http|ht

>> tps|BugLink):/i

>> >> &&

>> >> +                   ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||

>> >> +                    ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s

>> "'\(\[]|$)/i

>> >> &&

>> >> +                     $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&

>> >> +                     $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {

>> >> +                       my $init_char = "c";

>> >> +                       my $orig_commit = "";

>> >>                         my $short = 1;

>> >>                         my $long = 0;

>> >>                         my $case = 1;

>> >> @@ -2260,6 +2477,13 @@ sub process {

>> >>                         my $orig_desc = "commit description";

>> >>                         my $description = "";

>> >>   +                     if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i)

>> {

>> >> +                               $init_char = $1;

>> >> +                               $orig_commit = lc($2);

>> >> +                       } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {

>> >> +                               $orig_commit = lc($1);

>> >> +                       }

>> >> +

>> >>                         $short = 0 if ($line =~

>> >> /\bcommit\s+[0-9a-f]{12,40}/i);

>> >>                         $long = 1 if ($line =~

>> >> /\bcommit\s+[0-9a-f]{41,}/i);

>> >>                         $space = 0 if ($line =~ /\bcommit [0-9a-f]/i);

>> >> @@ -2343,6 +2567,7 @@ sub process {

>> >>                       $rawline =~ /^(commit\b|from\b|[\w-]+:).*$/i)) {

>> >>                         $in_header_lines = 0;

>> >>                         $in_commit_log = 1;

>> >> +                       $has_commit_log = 1;

>> >>                 }

>> >>     # Check if there is UTF-8 in a commit log when a mail header has

>> >> explicitly

>> >> @@ -2514,16 +2739,60 @@ sub process {

>> >>   # check we are in a valid source file if not then ignore this hunk

>> >>                 next if ($realfile !~ /\.(h|c|s|S|pl|sh|dtsi|dts)$/);

>> >>   -#line length limit

>> >> -               if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&

>> >> -                   $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&

>> >> -                   !($line =~ /^\+\s*$logFunctions\s*\(\s*(?

>> >> :(KERN_\S+\s*|[^"]*))?$String\s*(?:|,|\)\s*;)\s*$/ ||

>> >> -                     $line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/

>> ||

>> >> -                     $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) &&

>> >> -                   $length > $max_line_length)

>> >> -               {

>> >> -                       WARN("LONG_LINE",

>> >> -                            "line over $max_line_length characters\n"

>> .

>> >> $herecurr);

>> >> +# line length limit (with some exclusions)

>> >> +#

>> >> +# There are a few types of lines that may extend beyond

>> $max_line_length:

>> >> +#      logging functions like pr_info that end in a string

>> >> +#      lines with a single string

>> >> +#      #defines that are a single string

>> >> +#

>> >> +# There are 3 different line length message types:

>> >> +# LONG_LINE_COMMENT    a comment starts before but extends beyond

>> >> $max_linelength

>> >> +# LONG_LINE_STRING     a string starts before but extends beyond

>> >> $max_line_length

>> >> +# LONG_LINE            all other lines longer than $max_line_length

>> >> +#

>> >> +# if LONG_LINE is ignored, the other 2 types are also ignored

>> >> +#

>> >> +

>> >> +               if ($line =~ /^\+/ && $length > $max_line_length) {

>> >> +                       my $msg_type = "LONG_LINE";

>> >> +

>> >> +                       # Check the allowed long line types first

>> >> +

>> >> +                       # logging functions that end in a string that

>> >> starts

>> >> +                       # before $max_line_length

>> >> +                       if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?

>> >> :(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&

>> >> +                           length(expand_tabs(substr($line, 1,

>> >> length($line) - length($1) - 1))) <= $max_line_length) {

>> >> +                               $msg_type = "";

>> >> +

>> >> +                       # lines with only strings (w/ possible

>> >> termination)

>> >> +                       # #defines with only strings

>> >> +                       } elsif ($line =~

>> /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/

>> >> ||

>> >> +                                $line =~

>> /^\+\s*#\s*define\s+\w+\s+$String$/)

>> >> {

>> >> +                               $msg_type = "";

>> >> +

>> >> +                       # EFI_GUID is another special case

>> >> +                       } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) {

>> >> +                               $msg_type = "";

>> >> +

>> >> +                       # Otherwise set the alternate message types

>> >> +

>> >> +                       # a comment starts before $max_line_length

>> >> +                       } elsif ($line =~ /($;[\s$;]*)$/ &&

>> >> +                                length(expand_tabs(substr($line, 1,

>> >> length($line) - length($1) - 1))) <= $max_line_length) {

>> >> +                               $msg_type = "LONG_LINE_COMMENT"

>> >> +

>> >> +                       # a quoted string starts before

>> $max_line_length

>> >> +                       } elsif ($sline =~

>> /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/

>> >> &&

>> >> +                                length(expand_tabs(substr($line, 1,

>> >> length($line) - length($1) - 1))) <= $max_line_length) {

>> >> +                               $msg_type = "LONG_LINE_STRING"

>> >> +                       }

>> >> +

>> >> +                       if ($msg_type ne "" &&

>> >> +                           (show_type("LONG_LINE") ||

>> >> show_type($msg_type))) {

>> >> +                               WARN($msg_type,

>> >> +                                    "line over $max_line_length

>> >> characters\n" . $herecurr);

>> >> +                       }

>> >>                 }

>> >>     # check for adding lines without a newline.

>> >> @@ -2581,6 +2850,19 @@ sub process {

>> >>                             "Logical continuations should be on the

>> >> previous line\n" . $hereprev);

>> >>                 }

>> >>   +# check indentation starts on a tab stop

>> >> +               if ($^V && $^V ge 5.10.0 &&

>> >> +                   $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}

>> \s*(?:else\b|while\b|\s*$))/)

>> >> {

>> >> +                       my $indent = length($1);

>> >> +                       if ($indent % 8) {

>> >> +                               if (WARN("TABSTOP",

>> >> +                                        "Statements should start on a

>> >> tabstop\n" . $herecurr) &&

>> >> +                                   $fix) {

>> >> +                                       $fixed[$fixlinenr] =~ s@

>> (^\+\t+)

>> >> +@$1 . "\t" x ($indent/8)@e;

>> >> +                               }

>> >> +                       }

>> >> +               }

>> >> +

>> >>   # 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*$/) {

>> >> @@ -2628,6 +2910,8 @@ sub process {

>> >>                         }

>> >>                 }

>> >>   +# Block comment styles

>> >> +# Networking with an initial /*

>> >>                 if ($realfile =~ m@^(drivers/net/|net/)@ &&

>> >>                     $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&

>> >>                     $rawline =~ /^\+[ \t]*\*/ &&

>> >> @@ -2636,22 +2920,23 @@ sub process {

>> >>                              "networking block comments don't use an

>> >> empty /* line, use /* Comment...\n" . $hereprev);

>> >>                 }

>> >>   -             if ($realfile =~ m@^(drivers/net/|net/)@ &&

>> >> -                   $prevrawline =~ /^\+[ \t]*\/\*/ &&

>> #starting

>> >> /*

>> >> +# Block comments use * on subsequent lines

>> >> +               if ($prevline =~ /$;[ \t]*$/ &&                 #ends

>> in

>> >> comment

>> >> +                   $prevrawline =~ /^\+.*?\/\*/ &&

>>  #starting

>> >> /*

>> >>                     $prevrawline !~ /\*\/[ \t]*$/ &&            #no

>> >> trailing */

>> >>                     $rawline =~ /^\+/ &&                        #line

>> is

>> >> new

>> >>                     $rawline !~ /^\+[ \t]*\*/) {                #no

>> >> leading *

>> >> -                       WARN("NETWORKING_BLOCK_COMMENT_STYLE",

>> >> -                            "networking block comments start with * on

>> >> subsequent lines\n" . $hereprev);

>> >> +                       WARN("BLOCK_COMMENT_STYLE",

>> >> +                            "Block comments use * on subsequent

>> lines\n"

>> >> . $hereprev);

>> >>                 }

>> >>   -             if ($realfile =~ m@^(drivers/net/|net/)@ &&

>> >> -                   $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&

>> >>  #trailing */

>> >> +# Block comments use */ on trailing lines

>> >> +               if ($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);

>> >> +                       WARN("BLOCK_COMMENT_STYLE",

>> >> +                            "Block comments use a trailing */ on a

>> >> separate line\n" . $herecurr);

>> >>                 }

>> >>     # check for missing blank lines after struct/union declarations

>> >> @@ -2957,14 +3242,21 @@ sub process {

>> >>                         substr($s, 0, length($c), '');

>> >>   +                     # remove inline comments

>> >> +                       $s =~ s/$;/ /g;

>> >> +                       $c =~ s/$;/ /g;

>> >> +

>> >> +                       # Find out how long the conditional actually

>> is.

>> >> +                       my @newlines = ($c =~ /\n/gs);

>> >> +                       my $cond_lines = 1 + $#newlines;

>> >> +

>> >>                         # 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;

>> >> +                       while ($s =~ /\n\s+\\\n/) {

>> >> +                               $cond_lines += $s =~ s/\n\s+\\\n/\n/g;

>> >> +                       }

>> >>                         # We want to check the first line inside the

>> block

>> >>                         # starting at the end of the conditional, so

>> >> remove:

>> >> @@ -3031,8 +3323,10 @@ sub process {

>> >>                         #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 ''))) {

>> >> +                       if ($check && $s ne '' &&

>> >> +                           (($sindent % 8) != 0 ||

>> >> +                            ($sindent < $indent) ||

>> >> +                            ($sindent > $indent + 8))) {

>> >>                                 WARN("SUSPECT_CODE_INDENT",

>> >>                                      "suspect code indent for

>> conditional

>> >> statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");

>> >>                         }

>> >> @@ -3054,6 +3348,30 @@ sub process {

>> >>   #ignore lines not being added

>> >>                 next if ($line =~ /^[^\+]/);

>> >>   +# check for declarations of signed or unsigned without int

>> >> +               while ($line =~ m{\b($Declare)\s*(?!char\b|sho

>> >> rt\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {

>> >> +                       my $type = $1;

>> >> +                       my $var = $2;

>> >> +                       $var = "" if (!defined $var);

>> >> +                       if ($type =~ /^(?:(?:$Storage|$Inline|$Attr

>> >> ibute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {

>> >> +                               my $sign = $1;

>> >> +                               my $pointer = $2;

>> >> +

>> >> +                               $pointer = "" if (!defined $pointer);

>> >> +

>> >> +                               if (WARN("UNSPECIFIED_INT",

>> >> +                                        "Prefer '" . trim($sign) . "

>> >> int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) .

>> >> "'\n" . $herecurr) &&

>> >> +                                   $fix) {

>> >> +                                       my $decl = trim($sign) . " int

>> ";

>> >> +                                       my $comp_pointer = $pointer;

>> >> +                                       $comp_pointer =~ s/\s//g;

>> >> +                                       $decl .= $comp_pointer;

>> >> +                                       $decl = rtrim($decl) if ($var

>> eq

>> >> "");

>> >> +                                       $fixed[$fixlinenr] =~ s@

>> >> \b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;

>> >> +                               }

>> >> +                       }

>> >> +               }

>> >> +

>> >>   # TEST: allow direct testing of the type matcher.

>> >>                 if ($dbg_type) {

>> >>                         if ($line =~ /^.\s*$Declare\s*$/) {

>> >> @@ -3173,21 +3491,20 @@ sub process {

>> >>                 }

>> >>     # check for global initialisers.

>> >> -               if ($line =~ /^\+(\s*$Type\s*$Ident\s*(?:\s

>> >> +$Modifier))*\s*=\s*(0|NULL|false)\s*;/) {

>> >> +               if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modif

>> >> ier)*\s*=\s*($zero_initializer)\s*;/) {

>> >>                         if (ERROR("GLOBAL_INITIALISERS",

>> >> -                                 "do not initialise globals to 0 or

>> >> NULL\n" .

>> >> -                                     $herecurr) &&

>> >> +                                 "do not initialise globals to $1\n" .

>> >> $herecurr) &&

>> >>                             $fix) {

>> >> -                               $fixed[$fixlinenr] =~

>> >> s/($Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/$1;/;

>> >> +                               $fixed[$fixlinenr] =~

>> >> s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initialize

>> r\s*;/$1;/;

>> >>                         }

>> >>                 }

>> >>   # check for static initialisers.

>> >> -               if ($line =~ /^\+.*\bstatic\s.*=\s*(0|NULL|false)\s*;/)

>> {

>> >> +               if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_i

>> nitializer)\s*;/)

>> >> {

>> >>                         if (ERROR("INITIALISED_STATIC",

>> >> -                                 "do not initialise statics to 0 or

>> >> NULL\n" .

>> >> +                                 "do not initialise statics to $1\n" .

>> >>                                       $herecurr) &&

>> >>                             $fix) {

>> >> -                               $fixed[$fixlinenr] =~

>> >> s/(\bstatic\s.*?)\s*=\s*(0|NULL|false)\s*;/$1;/;

>> >> +                               $fixed[$fixlinenr] =~

>> >> s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;

>> >>                         }

>> >>                 }

>> >>   @@ -3268,7 +3585,6 @@ sub process {

>> >>                     $line !~ /\btypedef\s+$Type\s*\(\s*\*?$

>> Ident\s*\)\s*\(/

>> >> &&

>> >>                     $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&

>> >>                     $line !~ /\b$typeTypedefs\b/ &&

>> >> -                   $line !~ /\b$typeOtherOSTypedefs\b/ &&

>> >>                     $line !~ /\b__bitwise(?:__|)\b/) {

>> >>                         WARN("NEW_TYPEDEFS",

>> >>                              "do not add new typedefs\n" . $herecurr);

>> >> @@ -3330,13 +3646,15 @@ sub process {

>> >>                         }

>> >>                 }

>> >>   -# # 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;

>> >> -#              }

>> >> +# avoid BUG() or BUG_ON()

>> >> +               if ($line =~ /\b(?:BUG|BUG_ON)\b/) {

>> >> +                       my $msg_type = \&WARN;

>> >> +                       $msg_type = \&CHK if ($file);

>> >> +                       &{$msg_type}("AVOID_BUG",

>> >> +                                    "Avoid crashing the kernel - try

>> >> using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" .

>> $herecurr);

>> >> +               }

>> >>   +# avoid LINUX_VERSION_CODE

>> >>                 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);

>> >> @@ -3923,7 +4241,7 @@ sub process {

>> >>   ##            }

>> >>     #need space before brace following if, while, etc

>> >> -               if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\){/) ||

>> >> +               if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||

>> >>                     $line =~ /do\{/) {

>> >>                         if (ERROR("SPACING",

>> >>                                   "space required before the open brace

>> >> '{'\n" . $herecurr) &&

>> >> @@ -4070,6 +4388,35 @@ sub process {

>> >>                         }

>> >>                 }

>> >>   +# comparisons with a constant or upper case identifier on the left

>> >> +#      avoid cases like "foo + BAR < baz"

>> >> +#      only fix matches surrounded by parentheses to avoid incorrect

>> >> +#      conversions like "FOO < baz() + 5" being "misfixed" to "baz() >

>> >> FOO + 5"

>> >> +               if ($^V && $^V ge 5.10.0 &&

>> >> +                   $line =~ /^\+(.*)\b($Constant|[A-Z_][A-

>> >> Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {

>> >> +                       my $lead = $1;

>> >> +                       my $const = $2;

>> >> +                       my $comp = $3;

>> >> +                       my $to = $4;

>> >> +                       my $newcomp = $comp;

>> >> +                       if ($lead !~ /(?:$Operators|\.)\s*$/ &&

>> >> +                           $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/

>> &&

>> >> +                           WARN("CONSTANT_COMPARISON",

>> >> +                                "Comparisons should place the constant

>> >> on the right side of the test\n" . $herecurr) &&

>> >> +                           $fix) {

>> >> +                               if ($comp eq "<") {

>> >> +                                       $newcomp = ">";

>> >> +                               } elsif ($comp eq "<=") {

>> >> +                                       $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;

>> >> @@ -4256,12 +4603,6 @@ sub process {

>> >>   #Ignore SI style variants like nS, mV and dB (ie: max_uV,

>> >> regulator_min_uA_show)

>> >>                             $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_

>> [a-z_]+)?$/

>> >> &&

>> >>   #Ignore some three character SI units explicitly, like MiB and KHz

>> >> -                           $var !~ /\bCU_/ &&

>> >> -                           $var !~ /\bPRI[diux]32/ &&

>> >> -                           $var !~ /\bPRI[diux]64/ &&

>> >> -                           $var !~ /\bSCN[diux]8/ &&

>> >> -                           $var !~ /\bSCN[diux]32/ &&

>> >> -                           $var !~ /\bSCN[diux]64/ &&

>> >>                             $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[K

>> MGT]?Hz)(?:_[a-z_]+)?$/)

>> >> {

>> >>                                 while ($var =~ m{($Ident)}g) {

>> >>                                         my $word = $1;

>> >> @@ -4331,7 +4672,7 @@ sub process {

>> >>                         #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 =~ /\#\#/);

>> >> +                       $has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx

>> !~

>> >> /\#\#\s*(?:__VA_ARGS__|args)\b/);

>> >>                         $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:

>> >> \([^\)]*\))?\s*//;

>> >>                         $dstat =~ s/$;//g;

>> >> @@ -4342,16 +4683,19 @@ 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/)

>> >> +                       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/a

>> >> sm_volatile/g;

>> >> +

>> >>                         my $exceptions = qr{

>> >>                                 $Declare|

>> >>                                 module_param_named|

>> >> @@ -4362,7 +4706,8 @@ sub process {

>> >>                                 union|

>> >>                                 struct|

>> >>                                 \.$Ident\s*=\s*|

>> >> -                               ^\"|\"$

>> >> +                               ^\"|\"$|

>> >> +                               ^\[

>> >>                         }x;

>> >>                         #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";

>> >>                         if ($dstat ne '' &&

>> >> @@ -4629,7 +4974,7 @@ sub process {

>> >>   # to grep for the string.  Make exceptions when the previous string

>> >> ends in a

>> >>   # newline (multiple lines in one string constant) or '\t', '\r', ';',

>> >> or '{'

>> >>   # (common in inline assembly) or is a octal \123 or hexadecimal \xaf

>> >> value

>> >> -               if ($line =~ /^\+\s*"[X\t]*"/ &&

>> >> +               if ($line =~ /^\+\s*$String/ &&

>> >>                     $prevline =~ /"\s*$/ &&

>> >>                     $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-

>> >> 9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {

>> >>                         if (WARN("SPLIT_STRING",

>> >> @@ -4675,27 +5020,31 @@ sub process {

>> >>                 }

>> >>     # concatenated string without spaces between elements

>> >> -               if ($line =~ /"X+"[A-Z_]+/ || $line =~ /[A-Z_]+"X+"/) {

>> >> +               if ($line =~ /$String[A-Z_]/ || $line =~

>> >> /[A-Za-z0-9_]$String/) {

>> >>                         CHK("CONCATENATED_STRING",

>> >>                             "Concatenated strings should use spaces

>> >> between elements\n" . $herecurr);

>> >>                 }

>> >>     # uncoalesced string fragments

>> >> -               if ($line =~ /"X*"\s*"/) {

>> >> +               if ($line =~ /$String\s*"/) {

>> >>                         WARN("STRING_FRAGMENTS",

>> >>                              "Consecutive strings are generally better

>> as

>> >> a single string\n" . $herecurr);

>> >>                 }

>> >>   -# check for %L{u,d,i} in strings

>> >> +# check for %L{u,d,i} and 0x%[udi] in strings

>> >>                 my $string;

>> >>                 while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {

>> >>                         $string = substr($rawline, $-[1], $+[1] -

>> $-[1]);

>> >>                         $string =~ s/%%/__/g;

>> >> -                       if ($string =~ /(?<!%)%L[udi]/) {

>> >> +                       if ($string =~ /(?<!%)%[\*\d\.\$]*L[udi]/) {

>> >>                                 WARN("PRINTF_L",

>> >>                                      "\%Ld/%Lu are not-standard C, use

>> >> %lld/%llu\n" . $herecurr);

>> >>                                 last;

>> >>                         }

>> >> +                       if ($string =~ /0x%[\*\d\.\$\Llzth]*[udi]/) {

>> >> +                               ERROR("PRINTF_0xDECIMAL",

>> >> +                                     "Prefixing 0x with decimal output

>> >> is defective\n" . $herecurr);

>> >> +                       }

>> >>                 }

>> >>     # check for line continuations in quoted strings with odd counts

>> of "

>> >> @@ -4713,10 +5062,34 @@ sub process {

>> >>     # 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 and this check

>> is

>> >> probably not required\n" . $hereprev);

>> >> +                       my $tested = quotemeta($1);

>> >> +                       my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';

>> >> +                       if ($line =~ /\b(kfree|usb_free_urb|debugfs

>> >> _remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/)

>> {

>> >> +                               my $func = $1;

>> >> +                               if (WARN('NEEDLESS_IF',

>> >> +                                        "$func(NULL) is safe and this

>> >> check is probably not required\n" . $hereprev) &&

>> >> +                                   $fix) {

>> >> +                                       my $do_fix = 1;

>> >> +                                       my $leading_tabs = "";

>> >> +                                       my $new_leading_tabs = "";

>> >> +                                       if ($lines[$linenr - 2] =~

>> >> /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {

>> >> +                                               $leading_tabs = $1;

>> >> +                                       } else {

>> >> +                                               $do_fix = 0;

>> >> +                                       }

>> >> +                                       if ($lines[$linenr - 1] =~

>> >> /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {

>> >> +                                               $new_leading_tabs = $1;

>> >> +                                               if

>> (length($leading_tabs)

>> >> + 1 ne length($new_leading_tabs)) {

>> >> +                                                       $do_fix = 0;

>> >> +                                               }

>> >> +                                       } else {

>> >> +                                               $do_fix = 0;

>> >> +                                       }

>> >> +                                       if ($do_fix) {

>> >> +

>> >>  fix_delete_line($fixlinenr - 1, $prevrawline);

>> >> +                                               $fixed[$fixlinenr] =~

>> >> s/^\+$new_leading_tabs/\+$leading_tabs/;

>> >> +                                       }

>> >> +                               }

>> >>                         }

>> >>                 }

>> >>   @@ -4902,12 +5275,69 @@ sub process {

>> >>                         }

>> >>                 }

>> >>   # check for memory barriers without a comment.

>> >> -               if ($line =~ /\b(mb|rmb|wmb|read_barrier_de

>> >> pends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) {

>> >> +

>> >> +               my $barriers = qr{

>> >> +                       mb|

>> >> +                       rmb|

>> >> +                       wmb|

>> >> +                       read_barrier_depends

>> >> +               }x;

>> >> +               my $barrier_stems = qr{

>> >> +                       mb__before_atomic|

>> >> +                       mb__after_atomic|

>> >> +                       store_release|

>> >> +                       load_acquire|

>> >> +                       store_mb|

>> >> +                       (?:$barriers)

>> >> +               }x;

>> >> +               my $all_barriers = qr{

>> >> +                       (?:$barriers)|

>> >> +                       smp_(?:$barrier_stems)|

>> >> +                       virt_(?:$barrier_stems)

>> >> +               }x;

>> >> +

>> >> +               if ($line =~ /\b(?:$all_barriers)\s*\(/) {

>> >>                         if (!ctx_has_comment($first_line, $linenr)) {

>> >>                                 WARN("MEMORY_BARRIER",

>> >>                                      "memory barrier without

>> comment\n" .

>> >> $herecurr);

>> >>                         }

>> >>                 }

>> >> +

>> >> +               my $underscore_smp_barriers =

>> >> qr{__smp_(?:$barrier_stems)}x;

>> >> +

>> >> +               if ($realfile !~ m@^include/asm-generic/@ &&

>> >> +                   $realfile !~ m@/barrier\.h$@ &&

>> >> +                   $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&

>> >> +                   $line !~ m/^.\s*\#\s*define\s+(?:$under

>> score_smp_barriers)\s*\(/)

>> >> {

>> >> +                       WARN("MEMORY_BARRIER",

>> >> +                            "__smp memory barriers shouldn't be used

>> >> outside barrier.h and asm-generic\n" . $herecurr);

>> >> +               }

>> >> +

>> >> +# check for waitqueue_active without a comment.

>> >> +               if ($line =~ /\bwaitqueue_active\s*\(/) {

>> >> +                       if (!ctx_has_comment($first_line, $linenr)) {

>> >> +                               WARN("WAITQUEUE_ACTIVE",

>> >> +                                    "waitqueue_active without

>> comment\n"

>> >> . $herecurr);

>> >> +                       }

>> >> +               }

>> >> +

>> >> +# Check for expedited grace periods that interrupt non-idle non-nohz

>> >> +# online CPUs.  These expedited can therefore degrade real-time

>> response

>> >> +# if used carelessly, and should be avoided where not absolutely

>> >> +# needed.  It is always OK to use synchronize_rcu_expedited() and

>> >> +# synchronize_sched_expedited() at boot time (before real-time

>> >> applications

>> >> +# start) and in error situations where real-time response is

>> compromised

>> >> in

>> >> +# any case.  Note that synchronize_srcu_expedited() does -not-

>> interrupt

>> >> +# other CPUs, so don't warn on uses of synchronize_srcu_expedited().

>> >> +# Of course, nothing comes for free, and srcu_read_lock() and

>> >

>> >

>>

>>

>> --

>> Mike Holmes

>> Program Manager - Linaro Networking Group

>> Linaro.org <http://www.linaro.org/> *│ *Open source software for ARM SoCs

>> "Work should be fun and collaborative, the rest follows"

>>

>

>



-- 
Mike Holmes
Program Manager - Linaro Networking Group
Linaro.org <http://www.linaro.org/> *│ *Open source software for ARM SoCs
"Work should be fun and collaborative, the rest follows"
diff mbox

Patch

diff --git a/.checkpatch.conf b/.checkpatch.conf
index 1e7d663..81723d6 100644
--- a/.checkpatch.conf
+++ b/.checkpatch.conf
@@ -8,3 +8,4 @@ 
 --ignore=BIT_MACRO
 --codespell
 --codespellfile=/usr/share/codespell/dictionary.txt
+--ignore=PREFER_KERNEL_TYPES
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 16316b9..4de3cc4 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -9,6 +9,7 @@  use strict;
 use POSIX;
 use File::Basename;
 use Cwd 'abs_path';
+use Term::ANSIColor qw(:constants);
 
 my $P = $0;
 my $D = dirname(abs_path($P));
@@ -24,13 +25,17 @@  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;
@@ -48,7 +53,9 @@  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/local/share/codespell/dictionary.txt";
+my $codespellfile = "/usr/share/codespell/dictionary.txt";
+my $color = 1;
+my $allow_c99_comments = 1;
 
 sub help {
 	my ($exitcode) = @_;
@@ -64,13 +71,25 @@  Options:
   --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
-  --show-types               show the message "types" in the output
   --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
@@ -91,8 +110,9 @@  Options:
   --ignore-perl-version      override checking of perl version.  expect
                              runtime errors.
   --codespell                Use the codespell dictionary for spelling/typos
-                             (default:/usr/local/share/codespell/dictionary.txt)
+                             (default:/usr/share/codespell/dictionary.txt)
   --codespellfile            Use this codespell dictionary
+  --color                    Use colors when output is STDOUT (default: on)
   -h, --help, --version      display this help and exit
 
 When FILE is - read standard input.
@@ -101,6 +121,37 @@  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 = ();
+	for ($text =~ /\b(?:(?:CHK|WARN|ERROR)\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;
@@ -134,12 +185,15 @@  GetOptions(
 	'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,
@@ -153,12 +207,15 @@  GetOptions(
 	'test-only=s'	=> \$tst_only,
 	'codespell!'	=> \$codespell,
 	'codespellfile=s'	=> \$codespellfile,
+	'color!'	=> \$color,
 	'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;
 
@@ -171,9 +228,9 @@  if ($^V && $^V lt $minimum_perl_version) {
 	}
 }
 
+#if no filenames are given, push '-' to read patch from stdin
 if ($#ARGV < 0) {
-	print "$P: no input files\n";
-	exit(1);
+	push(@ARGV, '-');
 }
 
 sub hash_save_array_words {
@@ -196,12 +253,12 @@  sub hash_save_array_words {
 sub hash_show_words {
 	my ($hashRef, $prefix) = @_;
 
-	if ($quiet == 0 && keys %$hashRef) {
-		print "NOTE: $prefix message types:";
+	if (keys %$hashRef) {
+		print "\nNOTE: $prefix message types:";
 		foreach my $word (sort keys %$hashRef) {
 			print " $word";
 		}
-		print "\n\n";
+		print "\n";
 	}
 }
 
@@ -261,7 +318,8 @@  our $Sparse	= qr{
 			__init_refok|
 			__kprobes|
 			__ref|
-			__rcu
+			__rcu|
+			__private
 		}x;
 our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
 our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
@@ -347,15 +405,22 @@  our $UTF8	= qr{
 	| $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 $typeTypedefs = qr{(?x:
+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|)|
@@ -363,11 +428,7 @@  our $logFunctions = qr{(?x:
 	WARN(?:_RATELIMIT|_ONCE|)|
 	panic|
 	MODULE_[A-Z_]+|
-	seq_vprintf|seq_printf|seq_puts|
-	ODP_ASSERT|ODP_DBG|ODP_ERR|ODP_ABORT|ODP_LOG|ODP_PRINT|
-	EXAMPLE_DBG|EXAMPLE_ERR|EXAMPLE_ABORT|
-	LOG_DBG|LOG_ERR|LOG_ABORT|
-	printf
+	seq_vprintf|seq_printf|seq_puts
 )};
 
 our $signature_tags = qr{(?xi:
@@ -422,6 +483,29 @@  our @typeList = (
 	qr{${Ident}_handler_fn},
 	@typeListMisordered,
 );
+
+our $C90_int_types = qr{(?x:
+	long\s+long\s+int\s+(?:un)?signed|
+	long\s+long\s+(?:un)?signed\s+int|
+	long\s+long\s+(?:un)?signed|
+	(?:(?:un)?signed\s+)?long\s+long\s+int|
+	(?:(?:un)?signed\s+)?long\s+long|
+	int\s+long\s+long\s+(?:un)?signed|
+	int\s+(?:(?:un)?signed\s+)?long\s+long|
+
+	long\s+int\s+(?:un)?signed|
+	long\s+(?:un)?signed\s+int|
+	long\s+(?:un)?signed|
+	(?:(?:un)?signed\s+)?long\s+int|
+	(?:(?:un)?signed\s+)?long|
+	int\s+long\s+(?:un)?signed|
+	int\s+(?:(?:un)?signed\s+)?long|
+
+	int\s+(?:un)?signed|
+	(?:(?:un)?signed\s+)?int
+)};
+
+our @typeListFile = ();
 our @typeListWithAttr = (
 	@typeList,
 	qr{struct\s+$InitAttribute\s+$Ident},
@@ -431,6 +515,7 @@  our @typeListWithAttr = (
 our @modifierList = (
 	qr{fastcall},
 );
+our @modifierListFile = ();
 
 our @mode_permission_funcs = (
 	["module_param", 3],
@@ -514,13 +599,12 @@  if ($codespell) {
 $misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
 
 sub build_types {
-	my $mods = "(?x:  \n" . join("|\n  ", @modifierList) . "\n)";
-	my $all = "(?x:  \n" . join("|\n  ", @typeList) . "\n)";
+	my $mods = "(?x:  \n" . join("|\n  ", (@modifierList, @modifierListFile)) . "\n)";
+	my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile)) . "\n)";
 	my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered) . "\n)";
 	my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr) . "\n)";
 	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};
 	$BasicType	= qr{
-				(?:$typeOtherOSTypedefs\b)|
 				(?:$typeTypedefs\b)|
 				(?:${all}\b)
 		}x;
@@ -528,7 +612,6 @@  sub build_types {
 			(?:$Modifier\s+|const\s+)*
 			(?:
 				(?:typeof|__typeof__)\s*\([^\)]*\)|
-				(?:$typeOtherOSTypedefs\b)|
 				(?:$typeTypedefs\b)|
 				(?:${all}\b)
 			)
@@ -546,7 +629,6 @@  sub build_types {
 			(?:
 				(?:typeof|__typeof__)\s*\([^\)]*\)|
 				(?:$typeTypedefs\b)|
-				(?:$typeOtherOSTypedefs\b)|
 				(?:${allWithAttr}\b)
 			)
 			(?:\s+$Modifier|\s+const)*
@@ -577,7 +659,7 @@  our $LvalOrFunc	= qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
 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,2}\s*\(|
+	(?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
 	(?:$Storage\s+)?LIST_HEAD\s*\(|
 	(?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(
 )};
@@ -719,10 +801,42 @@  my @fixed_inserted = ();
 my @fixed_deleted = ();
 my $fixlinenr = -1;
 
+# If input is git commits, extract all commits from the commit expressions.
+# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
+die "$P: No git repository found\n" if ($git && !-e ".git");
+
+if ($git) {
+	my @commits = ();
+	foreach my $commit_expr (@ARGV) {
+		my $git_range;
+		if ($commit_expr =~ m/^(.*)-(\d+)$/) {
+			$git_range = "-$2 $1";
+		} elsif ($commit_expr =~ m/\.\./) {
+			$git_range = "$commit_expr";
+		} else {
+			$git_range = "-1 $commit_expr";
+		}
+		my $lines = `git log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
+		foreach my $line (split(/\n/, $lines)) {
+			$line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
+			next if (!defined($1) || !defined($2));
+			my $sha1 = $1;
+			my $subject = $2;
+			unshift(@commits, $sha1);
+			$git_commits{$sha1} = $subject;
+		}
+	}
+	die "$P: no git commits after extraction!\n" if (@commits == 0);
+	@ARGV = @commits;
+}
+
 my $vname;
 for my $filename (@ARGV) {
 	my $FILE;
-	if ($file) {
+	if ($git) {
+		open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
+			die "$P: $filename: git format-patch failed - $!\n";
+	} elsif ($file) {
 		open($FILE, '-|', "diff -u /dev/null $filename") ||
 			die "$P: $filename: diff failed - $!\n";
 	} elsif ($filename eq '-') {
@@ -733,6 +847,8 @@  for my $filename (@ARGV) {
 	}
 	if ($filename eq '-') {
 		$vname = 'Your patch';
+	} elsif ($git) {
+		$vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
 	} else {
 		$vname = $filename;
 	}
@@ -741,6 +857,13 @@  for my $filename (@ARGV) {
 		push(@rawlines, $_);
 	}
 	close($FILE);
+
+	if ($#ARGV > 0 && $quiet == 0) {
+		print '-' x length($vname) . "\n";
+		print "$vname\n";
+		print '-' x length($vname) . "\n";
+	}
+
 	if (!process($filename)) {
 		$exit = 1;
 	}
@@ -750,6 +873,29 @@  for my $filename (@ARGV) {
 	@fixed_inserted = ();
 	@fixed_deleted = ();
 	$fixlinenr = -1;
+	@modifierListFile = ();
+	@typeListFile = ();
+	build_types();
+}
+
+if (!$quiet) {
+	hash_show_words(\%use_type, "Used");
+	hash_show_words(\%ignore_type, "Ignored");
+
+	if ($^V lt 5.10.0) {
+		print << "EOM"
+
+NOTE: perl $^V is not modern enough to detect all possible issues.
+      An upgrade to at least perl v5.10.0 is suggested.
+EOM
+	}
+	if ($exit) {
+		print << "EOM"
+
+NOTE: If any of the errors are false positives, please report
+      them to the maintainer, see CHECKPATCH in MAINTAINERS.
+EOM
+	}
 }
 
 exit($exit);
@@ -999,13 +1145,18 @@  sub sanitise_line {
 		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
 	}
 
+	if ($allow_c99_comments && $res =~ m@(//.*$)@) {
+		my $match = $1;
+		$res =~ s/\Q$match\E/"$;" x length($match)/e;
+	}
+
 	return $res;
 }
 
 sub get_quoted_string {
 	my ($line, $rawline) = @_;
 
-	return "" if ($line !~ m/(\"[X\t]+\")/g);
+	return "" if ($line !~ m/($String)/g);
 	return substr($rawline, $-[0], $+[0] - $-[0]);
 }
 
@@ -1614,13 +1765,13 @@  sub possible {
 			for my $modifier (split(' ', $possible)) {
 				if ($modifier !~ $notPermitted) {
 					warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
-					push(@modifierList, $modifier);
+					push(@modifierListFile, $modifier);
 				}
 			}
 
 		} else {
 			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
-			push(@typeList, $possible);
+			push(@typeListFile, $possible);
 		}
 		build_types();
 	} else {
@@ -1645,15 +1796,32 @@  sub report {
 	    (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
 		return 0;
 	}
-	my $line;
+	my $output = '';
+	if (-t STDOUT && $color) {
+		if ($level eq 'ERROR') {
+			$output .= RED;
+		} elsif ($level eq 'WARNING') {
+			$output .= YELLOW;
+		} else {
+			$output .= GREEN;
+		}
+	}
+	$output .= $prefix . $level . ':';
 	if ($show_types) {
-		$line = "$prefix$level:$type: $msg\n";
-	} else {
-		$line = "$prefix$level: $msg\n";
+		$output .= BLUE if (-t STDOUT && $color);
+		$output .= "$type:";
 	}
-	$line = (split('\n', $line))[0] . "\n" if ($terse);
+	$output .= RESET if (-t STDOUT && $color);
+	$output .= ' ' . $msg . "\n";
 
-	push(our @report, $line);
+	if ($showfile) {
+		my @lines = split("\n", $output, -1);
+		splice(@lines, 1, 1);
+		$output = join("\n", @lines);
+	}
+	$output = (split('\n', $output))[0] . "\n" if ($terse);
+
+	push(our @report, $output);
 
 	return 1;
 }
@@ -1899,11 +2067,13 @@  sub process {
 	our $clean = 1;
 	my $signoff = 0;
 	my $is_patch = 0;
-
 	my $in_header_lines = $file ? 0 : 1;
 	my $in_commit_log = 0;		#Scanning lines before patch
+	my $has_commit_log = 0;		#Encountered lines before patch
+       my $commit_log_possible_stack_dump = 0;
 	my $commit_log_long_line = 0;
-	my $reported_maintainer_file = 1; # No MAINTAINTERS so silence warning
+	my $commit_log_has_diff = 0;
+	my $reported_maintainer_file = 0;
 	my $non_utf8_charset = 0;
 
 	my $last_blank_line = 0;
@@ -2036,7 +2206,8 @@  sub process {
 		my $rawline = $rawlines[$linenr - 1];
 
 #extract the line range in the file after the patch is applied
-		if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
+		if (!$in_commit_log &&
+		    $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
 			$is_patch = 1;
 			$first_line = $linenr + 1;
 			$realline=$1-1;
@@ -2077,10 +2248,6 @@  sub process {
 
 		my $hunk_line = ($realcnt != 0);
 
-#make up the handle for any error we report on this line
-		$prefix = "$filename:$realline: " if ($emacs && $file);
-		$prefix = "$filename:$linenr: " if ($emacs && !$file);
-
 		$here = "#$linenr: " if (!$file);
 		$here = "#$realline: " if ($file);
 
@@ -2110,8 +2277,19 @@  sub process {
 			$found_file = 1;
 		}
 
+#make up the handle for any error we report on this line
+		if ($showfile) {
+			$prefix = "$realfile:$realline: "
+		} elsif ($emacs) {
+			if ($file) {
+				$prefix = "$filename:$realline: ";
+			} else {
+				$prefix = "$filename:$linenr: ";
+			}
+		}
+
 		if ($found_file) {
-			if ($realfile =~ m@^(drivers/net/|net/)@) {
+			if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
 				$check = 1;
 			} else {
 				$check = $check_orig;
@@ -2127,6 +2305,17 @@  sub process {
 
 		$cnt_lines++ if ($realcnt != 0);
 
+# Check if the commit log has what seems like a diff which can confuse patch
+		if ($in_commit_log && !$commit_log_has_diff &&
+		    (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&
+		      $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||
+		     $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
+		     $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
+			ERROR("DIFF_IN_COMMIT_MSG",
+			      "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
+			$commit_log_has_diff = 1;
+		}
+
 # Check for incorrect file permissions
 		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
 			my $permhere = $here . "FILE: $realfile\n";
@@ -2238,18 +2427,46 @@  sub process {
 			      "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr);
 		}
 
+# Check if the commit log is in a possible stack dump
+		if ($in_commit_log && !$commit_log_possible_stack_dump &&
+		    ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
+		     $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
+					# timestamp
+		     $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) {
+					# stack dump address
+			$commit_log_possible_stack_dump = 1;
+		}
+
 # Check for line lengths > 75 in commit log, warn once
 		if ($in_commit_log && !$commit_log_long_line &&
-		    length($line) > 75) {
+		    length($line) > 75 &&
+		    !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
+					# file delta changes
+		      $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||
+					# filename then :
+		      $line =~ /^\s*(?:Fixes:|Link:)/i ||
+					# A Fixes: or Link: line
+		      $commit_log_possible_stack_dump)) {
 			WARN("COMMIT_LOG_LONG_LINE",
 			     "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
 			$commit_log_long_line = 1;
 		}
 
+# Reset possible stack dump if a blank line is found
+		if ($in_commit_log && $commit_log_possible_stack_dump &&
+		    $line =~ /^\s*$/) {
+			$commit_log_possible_stack_dump = 0;
+		}
+
 # Check for git id commit length and improperly formed commit descriptions
-		if ($in_commit_log && $line =~ /\b(c)ommit\s+([0-9a-f]{5,})/i) {
-			my $init_char = $1;
-			my $orig_commit = lc($2);
+		if ($in_commit_log && !$commit_log_possible_stack_dump &&
+		    $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i &&
+		    ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
+		     ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
+		      $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
+		      $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
+			my $init_char = "c";
+			my $orig_commit = "";
 			my $short = 1;
 			my $long = 0;
 			my $case = 1;
@@ -2260,6 +2477,13 @@  sub process {
 			my $orig_desc = "commit description";
 			my $description = "";
 
+			if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
+				$init_char = $1;
+				$orig_commit = lc($2);
+			} elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {
+				$orig_commit = lc($1);
+			}
+
 			$short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);
 			$long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);
 			$space = 0 if ($line =~ /\bcommit [0-9a-f]/i);
@@ -2343,6 +2567,7 @@  sub process {
 		      $rawline =~ /^(commit\b|from\b|[\w-]+:).*$/i)) {
 			$in_header_lines = 0;
 			$in_commit_log = 1;
+			$has_commit_log = 1;
 		}
 
 # Check if there is UTF-8 in a commit log when a mail header has explicitly
@@ -2514,16 +2739,60 @@  sub process {
 # check we are in a valid source file if not then ignore this hunk
 		next if ($realfile !~ /\.(h|c|s|S|pl|sh|dtsi|dts)$/);
 
-#line length limit
-		if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
-		    $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
-		    !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?$String\s*(?:|,|\)\s*;)\s*$/ ||
-		      $line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
-		      $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) &&
-		    $length > $max_line_length)
-		{
-			WARN("LONG_LINE",
-			     "line over $max_line_length characters\n" . $herecurr);
+# line length limit (with some exclusions)
+#
+# There are a few types of lines that may extend beyond $max_line_length:
+#	logging functions like pr_info that end in a string
+#	lines with a single string
+#	#defines that are a single string
+#
+# There are 3 different line length message types:
+# LONG_LINE_COMMENT	a comment starts before but extends beyond $max_linelength
+# LONG_LINE_STRING	a string starts before but extends beyond $max_line_length
+# LONG_LINE		all other lines longer than $max_line_length
+#
+# if LONG_LINE is ignored, the other 2 types are also ignored
+#
+
+		if ($line =~ /^\+/ && $length > $max_line_length) {
+			my $msg_type = "LONG_LINE";
+
+			# Check the allowed long line types first
+
+			# logging functions that end in a string that starts
+			# before $max_line_length
+			if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
+			    length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
+				$msg_type = "";
+
+			# lines with only strings (w/ possible termination)
+			# #defines with only strings
+			} elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
+				 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
+				$msg_type = "";
+
+			# EFI_GUID is another special case
+			} elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) {
+				$msg_type = "";
+
+			# Otherwise set the alternate message types
+
+			# a comment starts before $max_line_length
+			} elsif ($line =~ /($;[\s$;]*)$/ &&
+				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
+				$msg_type = "LONG_LINE_COMMENT"
+
+			# a quoted string starts before $max_line_length
+			} elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
+				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
+				$msg_type = "LONG_LINE_STRING"
+			}
+
+			if ($msg_type ne "" &&
+			    (show_type("LONG_LINE") || show_type($msg_type))) {
+				WARN($msg_type,
+				     "line over $max_line_length characters\n" . $herecurr);
+			}
 		}
 
 # check for adding lines without a newline.
@@ -2581,6 +2850,19 @@  sub process {
 			    "Logical continuations should be on the previous line\n" . $hereprev);
 		}
 
+# check indentation starts on a tab stop
+		if ($^V && $^V ge 5.10.0 &&
+		    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$))/) {
+			my $indent = length($1);
+			if ($indent % 8) {
+				if (WARN("TABSTOP",
+					 "Statements should start on a tabstop\n" . $herecurr) &&
+				    $fix) {
+					$fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e;
+				}
+			}
+		}
+
 # 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*$/) {
@@ -2628,6 +2910,8 @@  sub process {
 			}
 		}
 
+# Block comment styles
+# Networking with an initial /*
 		if ($realfile =~ m@^(drivers/net/|net/)@ &&
 		    $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
 		    $rawline =~ /^\+[ \t]*\*/ &&
@@ -2636,22 +2920,23 @@  sub process {
 			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
 		}
 
-		if ($realfile =~ m@^(drivers/net/|net/)@ &&
-		    $prevrawline =~ /^\+[ \t]*\/\*/ &&		#starting /*
+# Block comments use * on subsequent lines
+		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
+		    $prevrawline =~ /^\+.*?\/\*/ &&		#starting /*
 		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */
 		    $rawline =~ /^\+/ &&			#line is new
 		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *
-			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
-			     "networking block comments start with * on subsequent lines\n" . $hereprev);
+			WARN("BLOCK_COMMENT_STYLE",
+			     "Block comments use * on subsequent lines\n" . $hereprev);
 		}
 
-		if ($realfile =~ m@^(drivers/net/|net/)@ &&
-		    $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
+# Block comments use */ on trailing lines
+		if ($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);
+			WARN("BLOCK_COMMENT_STYLE",
+			     "Block comments use a trailing */ on a separate line\n" . $herecurr);
 		}
 
 # check for missing blank lines after struct/union declarations
@@ -2957,14 +3242,21 @@  sub process {
 
 			substr($s, 0, length($c), '');
 
+			# remove inline comments
+			$s =~ s/$;/ /g;
+			$c =~ s/$;/ /g;
+
+			# Find out how long the conditional actually is.
+			my @newlines = ($c =~ /\n/gs);
+			my $cond_lines = 1 + $#newlines;
+
 			# 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;
+			while ($s =~ /\n\s+\\\n/) {
+				$cond_lines += $s =~ s/\n\s+\\\n/\n/g;
+			}
 
 			# We want to check the first line inside the block
 			# starting at the end of the conditional, so remove:
@@ -3031,8 +3323,10 @@  sub process {
 
 			#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 ''))) {
+			if ($check && $s ne '' &&
+			    (($sindent % 8) != 0 ||
+			     ($sindent < $indent) ||
+			     ($sindent > $indent + 8))) {
 				WARN("SUSPECT_CODE_INDENT",
 				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
 			}
@@ -3054,6 +3348,30 @@  sub process {
 #ignore lines not being added
 		next if ($line =~ /^[^\+]/);
 
+# check for declarations of signed or unsigned without int
+		while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
+			my $type = $1;
+			my $var = $2;
+			$var = "" if (!defined $var);
+			if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
+				my $sign = $1;
+				my $pointer = $2;
+
+				$pointer = "" if (!defined $pointer);
+
+				if (WARN("UNSPECIFIED_INT",
+					 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
+				    $fix) {
+					my $decl = trim($sign) . " int ";
+					my $comp_pointer = $pointer;
+					$comp_pointer =~ s/\s//g;
+					$decl .= $comp_pointer;
+					$decl = rtrim($decl) if ($var eq "");
+					$fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
+				}
+			}
+		}
+
 # TEST: allow direct testing of the type matcher.
 		if ($dbg_type) {
 			if ($line =~ /^.\s*$Declare\s*$/) {
@@ -3173,21 +3491,20 @@  sub process {
 		}
 
 # check for global initialisers.
-		if ($line =~ /^\+(\s*$Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/) {
+		if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) {
 			if (ERROR("GLOBAL_INITIALISERS",
-				  "do not initialise globals to 0 or NULL\n" .
-				      $herecurr) &&
+				  "do not initialise globals to $1\n" . $herecurr) &&
 			    $fix) {
-				$fixed[$fixlinenr] =~ s/($Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/$1;/;
+				$fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
 			}
 		}
 # check for static initialisers.
-		if ($line =~ /^\+.*\bstatic\s.*=\s*(0|NULL|false)\s*;/) {
+		if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
 			if (ERROR("INITIALISED_STATIC",
-				  "do not initialise statics to 0 or NULL\n" .
+				  "do not initialise statics to $1\n" .
 				      $herecurr) &&
 			    $fix) {
-				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*(0|NULL|false)\s*;/$1;/;
+				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
 			}
 		}
 
@@ -3268,7 +3585,6 @@  sub process {
 		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
 		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
 		    $line !~ /\b$typeTypedefs\b/ &&
-		    $line !~ /\b$typeOtherOSTypedefs\b/ &&
 		    $line !~ /\b__bitwise(?:__|)\b/) {
 			WARN("NEW_TYPEDEFS",
 			     "do not add new typedefs\n" . $herecurr);
@@ -3330,13 +3646,15 @@  sub process {
 			}
 		}
 
-# # 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;
-# 		}
+# avoid BUG() or BUG_ON()
+		if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
+			my $msg_type = \&WARN;
+			$msg_type = \&CHK if ($file);
+			&{$msg_type}("AVOID_BUG",
+				     "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
+		}
 
+# avoid LINUX_VERSION_CODE
 		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);
@@ -3923,7 +4241,7 @@  sub process {
 ## 		}
 
 #need space before brace following if, while, etc
-		if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\){/) ||
+		if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
 		    $line =~ /do\{/) {
 			if (ERROR("SPACING",
 				  "space required before the open brace '{'\n" . $herecurr) &&
@@ -4070,6 +4388,35 @@  sub process {
 			}
 		}
 
+# comparisons with a constant or upper case identifier on the left
+#	avoid cases like "foo + BAR < baz"
+#	only fix matches surrounded by parentheses to avoid incorrect
+#	conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
+		if ($^V && $^V ge 5.10.0 &&
+		    $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
+			my $lead = $1;
+			my $const = $2;
+			my $comp = $3;
+			my $to = $4;
+			my $newcomp = $comp;
+			if ($lead !~ /(?:$Operators|\.)\s*$/ &&
+			    $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
+			    WARN("CONSTANT_COMPARISON",
+				 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
+			    $fix) {
+				if ($comp eq "<") {
+					$newcomp = ">";
+				} elsif ($comp eq "<=") {
+					$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;
@@ -4256,12 +4603,6 @@  sub process {
 #Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show)
 			    $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ &&
 #Ignore some three character SI units explicitly, like MiB and KHz
-			    $var !~ /\bCU_/ &&
-			    $var !~ /\bPRI[diux]32/ &&
-			    $var !~ /\bPRI[diux]64/ &&
-			    $var !~ /\bSCN[diux]8/ &&
-			    $var !~ /\bSCN[diux]32/ &&
-			    $var !~ /\bSCN[diux]64/ &&
 			    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
 				while ($var =~ m{($Ident)}g) {
 					my $word = $1;
@@ -4331,7 +4672,7 @@  sub process {
 			#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 =~ /\#\#/);
+			$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
 
 			$dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//;
 			$dstat =~ s/$;//g;
@@ -4342,16 +4683,19 @@  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/)
+			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|
@@ -4362,7 +4706,8 @@  sub process {
 				union|
 				struct|
 				\.$Ident\s*=\s*|
-				^\"|\"$
+				^\"|\"$|
+				^\[
 			}x;
 			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
 			if ($dstat ne '' &&
@@ -4629,7 +4974,7 @@  sub process {
 # to grep for the string.  Make exceptions when the previous string ends in a
 # newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
 # (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
-		if ($line =~ /^\+\s*"[X\t]*"/ &&
+		if ($line =~ /^\+\s*$String/ &&
 		    $prevline =~ /"\s*$/ &&
 		    $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
 			if (WARN("SPLIT_STRING",
@@ -4675,27 +5020,31 @@  sub process {
 		}
 
 # concatenated string without spaces between elements
-		if ($line =~ /"X+"[A-Z_]+/ || $line =~ /[A-Z_]+"X+"/) {
+		if ($line =~ /$String[A-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) {
 			CHK("CONCATENATED_STRING",
 			    "Concatenated strings should use spaces between elements\n" . $herecurr);
 		}
 
 # uncoalesced string fragments
-		if ($line =~ /"X*"\s*"/) {
+		if ($line =~ /$String\s*"/) {
 			WARN("STRING_FRAGMENTS",
 			     "Consecutive strings are generally better as a single string\n" . $herecurr);
 		}
 
-# check for %L{u,d,i} in strings
+# check for %L{u,d,i} and 0x%[udi] in strings
 		my $string;
 		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
 			$string = substr($rawline, $-[1], $+[1] - $-[1]);
 			$string =~ s/%%/__/g;
-			if ($string =~ /(?<!%)%L[udi]/) {
+			if ($string =~ /(?<!%)%[\*\d\.\$]*L[udi]/) {
 				WARN("PRINTF_L",
 				     "\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr);
 				last;
 			}
+			if ($string =~ /0x%[\*\d\.\$\Llzth]*[udi]/) {
+				ERROR("PRINTF_0xDECIMAL",
+				      "Prefixing 0x with decimal output is defective\n" . $herecurr);
+			}
 		}
 
 # check for line continuations in quoted strings with odd counts of "
@@ -4713,10 +5062,34 @@  sub process {
 
 # 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 and this check is probably not required\n" . $hereprev);
+			my $tested = quotemeta($1);
+			my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
+			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
+				my $func = $1;
+				if (WARN('NEEDLESS_IF',
+					 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
+				    $fix) {
+					my $do_fix = 1;
+					my $leading_tabs = "";
+					my $new_leading_tabs = "";
+					if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
+						$leading_tabs = $1;
+					} else {
+						$do_fix = 0;
+					}
+					if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
+						$new_leading_tabs = $1;
+						if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
+							$do_fix = 0;
+						}
+					} else {
+						$do_fix = 0;
+					}
+					if ($do_fix) {
+						fix_delete_line($fixlinenr - 1, $prevrawline);
+						$fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
+					}
+				}
 			}
 		}
 
@@ -4902,12 +5275,69 @@  sub process {
 			}
 		}
 # check for memory barriers without a comment.
-		if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) {
+
+		my $barriers = qr{
+			mb|
+			rmb|
+			wmb|
+			read_barrier_depends
+		}x;
+		my $barrier_stems = qr{
+			mb__before_atomic|
+			mb__after_atomic|
+			store_release|
+			load_acquire|
+			store_mb|
+			(?:$barriers)
+		}x;
+		my $all_barriers = qr{
+			(?:$barriers)|
+			smp_(?:$barrier_stems)|
+			virt_(?:$barrier_stems)
+		}x;
+
+		if ($line =~ /\b(?:$all_barriers)\s*\(/) {
 			if (!ctx_has_comment($first_line, $linenr)) {
 				WARN("MEMORY_BARRIER",
 				     "memory barrier without comment\n" . $herecurr);
 			}
 		}
+
+		my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
+
+		if ($realfile !~ m@^include/asm-generic/@ &&
+		    $realfile !~ m@/barrier\.h$@ &&
+		    $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
+		    $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
+			WARN("MEMORY_BARRIER",
+			     "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
+		}
+
+# check for waitqueue_active without a comment.
+		if ($line =~ /\bwaitqueue_active\s*\(/) {
+			if (!ctx_has_comment($first_line, $linenr)) {
+				WARN("WAITQUEUE_ACTIVE",
+				     "waitqueue_active without comment\n" . $herecurr);
+			}
+		}
+
+# Check for expedited grace periods that interrupt non-idle non-nohz
+# online CPUs.  These expedited can therefore degrade real-time response
+# if used carelessly, and should be avoided where not absolutely
+# needed.  It is always OK to use synchronize_rcu_expedited() and
+# synchronize_sched_expedited() at boot time (before real-time applications
+# start) and in error situations where real-time response is compromised in
+# any case.  Note that synchronize_srcu_expedited() does -not- interrupt
+# other CPUs, so don't warn on uses of synchronize_srcu_expedited().
+# Of course, nothing comes for free, and srcu_read_lock() and
+# srcu_read_unlock() do contain full memory barriers in payment for
+# synchronize_srcu_expedited() non-interruption properties.
+		if ($line =~ /\b(synchronize_rcu_expedited|synchronize_sched_expedited)\(/) {
+			WARN("EXPEDITED_RCU_GRACE_PERIOD",
+			     "expedited RCU grace periods should be avoided where they can degrade real-time response\n" . $herecurr);
+
+		}
+
 # check of hardware specific defines
 		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
 			CHK("ARCH_DEFINES",
@@ -4983,6 +5413,44 @@  sub process {
 			      "Using weak declarations can have unintended link defects\n" . $herecurr);
 		}
 
+# check for c99 types like uint8_t used outside of uapi/
+		if ($realfile !~ m@\binclude/uapi/@ &&
+		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
+			my $type = $1;
+			if ($type =~ /\b($typeC99Typedefs)\b/) {
+				$type = $1;
+				my $kernel_type = 'u';
+				$kernel_type = 's' if ($type =~ /^_*[si]/);
+				$type =~ /(\d+)/;
+				$kernel_type .= $1;
+				if (CHK("PREFER_KERNEL_TYPES",
+					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
+				    $fix) {
+					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
+				}
+			}
+		}
+
+# check for cast of C90 native int or longer types constants
+		if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
+			my $cast = $1;
+			my $const = $2;
+			if (WARN("TYPECAST_INT_CONSTANT",
+				 "Unnecessary typecast of c90 int constant\n" . $herecurr) &&
+			    $fix) {
+				my $suffix = "";
+				my $newconst = $const;
+				$newconst =~ s/${Int_type}$//;
+				$suffix .= 'U' if ($cast =~ /\bunsigned\b/);
+				if ($cast =~ /\blong\s+long\b/) {
+					$suffix .= 'LL';
+				} elsif ($cast =~ /\blong\b/) {
+					$suffix .= 'L';
+				}
+				$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
+			}
+		}
+
 # check for sizeof(&)
 		if ($line =~ /\bsizeof\s*\(\s*\&/) {
 			WARN("SIZEOF_ADDRESS",
@@ -5020,7 +5488,7 @@  sub process {
 # 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) {
+		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
 
 			my $ms_addr = $2;
 			my $ms_val = $7;
@@ -5035,6 +5503,48 @@  sub process {
 			}
 		}
 
+# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
+		if ($^V && $^V ge 5.10.0 &&
+		    defined $stat &&
+		    $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
+			if (WARN("PREFER_ETHER_ADDR_COPY",
+				 "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
+			    $fix) {
+				$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
+			}
+		}
+
+# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
+		if ($^V && $^V ge 5.10.0 &&
+		    defined $stat &&
+		    $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
+			WARN("PREFER_ETHER_ADDR_EQUAL",
+			     "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
+		}
+
+# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
+# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
+		if ($^V && $^V ge 5.10.0 &&
+		    defined $stat &&
+		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
+
+			my $ms_val = $7;
+
+			if ($ms_val =~ /^(?:0x|)0+$/i) {
+				if (WARN("PREFER_ETH_ZERO_ADDR",
+					 "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
+				    $fix) {
+					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
+				}
+			} elsif ($ms_val =~ /^(?:0xff|255)$/i) {
+				if (WARN("PREFER_ETH_BROADCAST_ADDR",
+					 "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
+				    $fix) {
+					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
+				}
+			}
+		}
+
 # typecasts on min/max could be min_t/max_t
 		if ($^V && $^V ge 5.10.0 &&
 		    defined $stat &&
@@ -5224,8 +5734,9 @@  sub process {
 			}
 		}
 
-# check for #defines like: 1 << <digit> that could be BIT(digit)
-		if ($line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
+# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
+		if ($realfile !~ m@^include/uapi/@ &&
+		    $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
 			my $ull = "";
 			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
 			if (CHK("BIT_MACRO",
@@ -5235,6 +5746,16 @@  sub process {
 			}
 		}
 
+# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
+		if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {
+			my $config = $1;
+			if (WARN("PREFER_IS_ENABLED",
+				 "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) &&
+			    $fix) {
+				$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
+			}
+		}
+
 # check for case / default statements not preceded by break/fallthrough/switch
 		if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
 			my $has_break = 0;
@@ -5425,6 +5946,28 @@  sub process {
 			}
 		}
 
+# whine about ACCESS_ONCE
+		if ($^V && $^V ge 5.10.0 &&
+		    $line =~ /\bACCESS_ONCE\s*$balanced_parens\s*(=(?!=))?\s*($FuncArg)?/) {
+			my $par = $1;
+			my $eq = $2;
+			my $fun = $3;
+			$par =~ s/^\(\s*(.*)\s*\)$/$1/;
+			if (defined($eq)) {
+				if (WARN("PREFER_WRITE_ONCE",
+					 "Prefer WRITE_ONCE(<FOO>, <BAR>) over ACCESS_ONCE(<FOO>) = <BAR>\n" . $herecurr) &&
+				    $fix) {
+					$fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)\s*$eq\s*\Q$fun\E/WRITE_ONCE($par, $fun)/;
+				}
+			} else {
+				if (WARN("PREFER_READ_ONCE",
+					 "Prefer READ_ONCE(<FOO>) over ACCESS_ONCE(<FOO>)\n" . $herecurr) &&
+				    $fix) {
+					$fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)/READ_ONCE($par)/;
+				}
+			}
+		}
+
 # check for lockdep_set_novalidate_class
 		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
 		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
@@ -5472,6 +6015,24 @@  sub process {
 				}
 			}
 		}
+
+# validate content of MODULE_LICENSE against list from include/linux/module.h
+		if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
+			my $extracted_string = get_quoted_string($line, $rawline);
+			my $valid_licenses = qr{
+						GPL|
+						GPL\ v2|
+						GPL\ and\ additional\ rights|
+						Dual\ BSD/GPL|
+						Dual\ MIT/GPL|
+						Dual\ MPL/GPL|
+						Proprietary
+					}x;
+			if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
+				WARN("MODULE_LICENSE",
+				     "unknown module license " . $extracted_string . "\n" . $herecurr);
+			}
+		}
 	}
 
 	# If we have no input at all, then there is nothing to report on
@@ -5492,11 +6053,11 @@  sub process {
 		exit(0);
 	}
 
-	if (!$is_patch) {
+	if (!$is_patch && $file !~ /cover-letter\.patch$/) {
 		ERROR("NOT_UNIFIED_DIFF",
 		      "Does not appear to be a unified-diff format patch\n");
 	}
-	if ($is_patch && $chk_signoff && $signoff == 0) {
+	if ($is_patch && $has_commit_log && $chk_signoff && $signoff == 0) {
 		ERROR("MISSING_SIGN_OFF",
 		      "Missing Signed-off-by: line(s)\n");
 	}
@@ -5507,28 +6068,29 @@  sub process {
 		print "total: $cnt_error errors, $cnt_warn warnings, " .
 			(($check)? "$cnt_chk checks, " : "") .
 			"$cnt_lines lines checked\n";
-		print "\n" if ($quiet == 0);
 	}
 
 	if ($quiet == 0) {
+		# If there were any defects found and not already fixing them
+		if (!$clean and !$fix) {
+			print << "EOM"
 
-		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");
+NOTE: For some of the reported defects, checkpatch may be able to
+      mechanically convert to the typical style using --fix or --fix-inplace.
+EOM
 		}
-
 		# If there were whitespace errors which cleanpatch can fix
 		# then suggest that.
 		if ($rpt_cleaners) {
-			print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n";
-			print "      scripts/cleanfile\n\n";
 			$rpt_cleaners = 0;
+			print << "EOM"
+
+NOTE: Whitespace errors detected.
+      You may wish to use scripts/cleanpatch or scripts/cleanfile
+EOM
 		}
 	}
 
-	hash_show_words(\%use_type, "Used");
-	hash_show_words(\%ignore_type, "Ignored");
-
 	if ($clean == 0 && $fix &&
 	    ("@rawlines" ne "@fixed" ||
 	     $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
@@ -5556,6 +6118,7 @@  sub process {
 
 		if (!$quiet) {
 			print << "EOM";
+
 Wrote EXPERIMENTAL --fix correction(s) to '$newfile'
 
 Do _NOT_ trust the results written to this file.
@@ -5563,22 +6126,17 @@  Do _NOT_ submit these changes without inspecting them for correctness.
 
 This EXPERIMENTAL file is simply a convenience to help rewrite patches.
 No warranties, expressed or implied...
-
 EOM
 		}
 	}
 
-	if ($clean == 1 && $quiet == 0) {
-		print "$vname has no obvious style problems and is ready for submission.\n"
-	}
-	if ($clean == 0 && $quiet == 0) {
-		print << "EOM";
-$vname has style problems, please review.
-
-If any of these errors are false positives, please report
-them to the maintainer, see CHECKPATCH in MAINTAINERS.
-EOM
+	if ($quiet == 0) {
+		print "\n";
+		if ($clean == 1) {
+			print "$vname has no obvious style problems and is ready for submission.\n";
+		} else {
+			print "$vname has style problems, please review.\n";
+		}
 	}
-
 	return $clean;
 }