xref: /linux-6.15/scripts/checkpatch.pl (revision 7ccf41a8)
1cb77f0d6SKamil Rytarowski#!/usr/bin/env perl
2882ea1d6SJoe Perches# SPDX-License-Identifier: GPL-2.0
3882ea1d6SJoe Perches#
4dbf004d7SDave Jones# (c) 2001, Dave Jones. (the file handling bit)
500df344fSAndy Whitcroft# (c) 2005, Joel Schopp <[email protected]> (the ugly bit)
62a5a2c25SAndy Whitcroft# (c) 2007,2008, Andy Whitcroft <[email protected]> (new conditions, test suite)
7015830beSAndy Whitcroft# (c) 2008-2010 Andy Whitcroft <[email protected]>
8882ea1d6SJoe Perches# (c) 2010-2018 Joe Perches <[email protected]>
90a920b5bSAndy Whitcroft
100a920b5bSAndy Whitcroftuse strict;
11cb77f0d6SKamil Rytarowskiuse warnings;
12c707a81dSJoe Perchesuse POSIX;
1336061e38SJoe Perchesuse File::Basename;
1436061e38SJoe Perchesuse Cwd 'abs_path';
1557230297SJoe Perchesuse Term::ANSIColor qw(:constants);
16cd261496SGeert Uytterhoevenuse Encode qw(decode encode);
170a920b5bSAndy Whitcroft
180a920b5bSAndy Whitcroftmy $P = $0;
1936061e38SJoe Perchesmy $D = dirname(abs_path($P));
200a920b5bSAndy Whitcroft
21000d1cc1SJoe Perchesmy $V = '0.32';
220a920b5bSAndy Whitcroft
230a920b5bSAndy Whitcroftuse Getopt::Long qw(:config no_auto_abbrev);
240a920b5bSAndy Whitcroft
250a920b5bSAndy Whitcroftmy $quiet = 0;
260a920b5bSAndy Whitcroftmy $tree = 1;
270a920b5bSAndy Whitcroftmy $chk_signoff = 1;
280a920b5bSAndy Whitcroftmy $chk_patch = 1;
29773647a0SAndy Whitcroftmy $tst_only;
306c72ffaaSAndy Whitcroftmy $emacs = 0;
318905a67cSAndy Whitcroftmy $terse = 0;
3234d8815fSJoe Perchesmy $showfile = 0;
336c72ffaaSAndy Whitcroftmy $file = 0;
344a593c34SDu, Changbinmy $git = 0;
350dea9f1eSJoe Perchesmy %git_commits = ();
366c72ffaaSAndy Whitcroftmy $check = 0;
372ac73b4fSJoe Perchesmy $check_orig = 0;
388905a67cSAndy Whitcroftmy $summary = 1;
398905a67cSAndy Whitcroftmy $mailback = 0;
4013214adfSAndy Whitcroftmy $summary_file = 0;
41000d1cc1SJoe Perchesmy $show_types = 0;
423beb42ecSJoe Perchesmy $list_types = 0;
433705ce5bSJoe Perchesmy $fix = 0;
449624b8d6SJoe Perchesmy $fix_inplace = 0;
456c72ffaaSAndy Whitcroftmy $root;
46c2fdda0dSAndy Whitcroftmy %debug;
473445686aSJoe Perchesmy %camelcase = ();
4891bfe484SJoe Perchesmy %use_type = ();
4991bfe484SJoe Perchesmy @use = ();
5091bfe484SJoe Perchesmy %ignore_type = ();
51000d1cc1SJoe Perchesmy @ignore = ();
5277f5b10aSHannes Edermy $help = 0;
53000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf";
54bdc48fa1SJoe Perchesmy $max_line_length = 100;
55d62a201fSDave Hansenmy $ignore_perl_version = 0;
56d62a201fSDave Hansenmy $minimum_perl_version = 5.10.0;
5756193274SVadim Bendeburymy $min_conf_desc_length = 4;
5866b47b4aSKees Cookmy $spelling_file = "$D/spelling.txt";
59ebfd7d62SJoe Perchesmy $codespell = 0;
60f1a63678SMaxim Uvarovmy $codespellfile = "/usr/share/codespell/dictionary.txt";
61bf1fa1daSJoe Perchesmy $conststructsfile = "$D/const_structs.checkpatch";
6275ad8c57SJerome Forissiermy $typedefsfile = "";
63737c0767SJohn Brooksmy $color = "auto";
6498005e8cSVadim Bendeburymy $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE
65dbbf869dSJoe Perches# git output parsing needs US English output, so first set backtick child process LANGUAGE
66dbbf869dSJoe Perchesmy $git_command ='export LANGUAGE=en_US.UTF-8; git';
67713a09deSAntonio Borneomy $tabsize = 8;
6877f5b10aSHannes Eder
6977f5b10aSHannes Edersub help {
7077f5b10aSHannes Eder	my ($exitcode) = @_;
7177f5b10aSHannes Eder
7277f5b10aSHannes Eder	print << "EOM";
7377f5b10aSHannes EderUsage: $P [OPTION]... [FILE]...
7477f5b10aSHannes EderVersion: $V
7577f5b10aSHannes Eder
7677f5b10aSHannes EderOptions:
7777f5b10aSHannes Eder  -q, --quiet                quiet
7877f5b10aSHannes Eder  --no-tree                  run without a kernel tree
7977f5b10aSHannes Eder  --no-signoff               do not check for 'Signed-off-by' line
8077f5b10aSHannes Eder  --patch                    treat FILE as patchfile (default)
8177f5b10aSHannes Eder  --emacs                    emacs compile window format
8277f5b10aSHannes Eder  --terse                    one line per report
8334d8815fSJoe Perches  --showfile                 emit diffed file position, not input file position
844a593c34SDu, Changbin  -g, --git                  treat FILE as a single commit or git revision range
854a593c34SDu, Changbin                             single git commit with:
864a593c34SDu, Changbin                               <rev>
874a593c34SDu, Changbin                               <rev>^
884a593c34SDu, Changbin                               <rev>~n
894a593c34SDu, Changbin                             multiple git commits with:
904a593c34SDu, Changbin                               <rev1>..<rev2>
914a593c34SDu, Changbin                               <rev1>...<rev2>
924a593c34SDu, Changbin                               <rev>-<count>
934a593c34SDu, Changbin                             git merges are ignored
9477f5b10aSHannes Eder  -f, --file                 treat FILE as regular source file
9577f5b10aSHannes Eder  --subjective, --strict     enable more subjective tests
963beb42ecSJoe Perches  --list-types               list the possible message types
9791bfe484SJoe Perches  --types TYPE(,TYPE2...)    show only these comma separated message types
98000d1cc1SJoe Perches  --ignore TYPE(,TYPE2...)   ignore various comma separated message types
993beb42ecSJoe Perches  --show-types               show the specific message type in the output
100bdc48fa1SJoe Perches  --max-line-length=n        set the maximum line length, (default $max_line_length)
101bdc48fa1SJoe Perches                             if exceeded, warn on patches
102bdc48fa1SJoe Perches                             requires --strict for use with --file
10356193274SVadim Bendebury  --min-conf-desc-length=n   set the min description length, if shorter, warn
104bdc48fa1SJoe Perches  --tab-size=n               set the number of spaces for tab (default $tabsize)
10577f5b10aSHannes Eder  --root=PATH                PATH to the kernel tree root
10677f5b10aSHannes Eder  --no-summary               suppress the per-file summary
10777f5b10aSHannes Eder  --mailback                 only produce a report in case of warnings/errors
10877f5b10aSHannes Eder  --summary-file             include the filename in summary
10977f5b10aSHannes Eder  --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of
11077f5b10aSHannes Eder                             'values', 'possible', 'type', and 'attr' (default
11177f5b10aSHannes Eder                             is all off)
11277f5b10aSHannes Eder  --test-only=WORD           report only warnings/errors containing WORD
11377f5b10aSHannes Eder                             literally
1143705ce5bSJoe Perches  --fix                      EXPERIMENTAL - may create horrible results
1153705ce5bSJoe Perches                             If correctable single-line errors exist, create
1163705ce5bSJoe Perches                             "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
1173705ce5bSJoe Perches                             with potential errors corrected to the preferred
1183705ce5bSJoe Perches                             checkpatch style
1199624b8d6SJoe Perches  --fix-inplace              EXPERIMENTAL - may create horrible results
1209624b8d6SJoe Perches                             Is the same as --fix, but overwrites the input
1219624b8d6SJoe Perches                             file.  It's your fault if there's no backup or git
122d62a201fSDave Hansen  --ignore-perl-version      override checking of perl version.  expect
123d62a201fSDave Hansen                             runtime errors.
124ebfd7d62SJoe Perches  --codespell                Use the codespell dictionary for spelling/typos
125f1a63678SMaxim Uvarov                             (default:/usr/share/codespell/dictionary.txt)
126ebfd7d62SJoe Perches  --codespellfile            Use this codespell dictionary
12775ad8c57SJerome Forissier  --typedefsfile             Read additional types from this file
128737c0767SJohn Brooks  --color[=WHEN]             Use colors 'always', 'never', or only when output
129737c0767SJohn Brooks                             is a terminal ('auto'). Default is 'auto'.
13077f5b10aSHannes Eder  -h, --help, --version      display this help and exit
13177f5b10aSHannes Eder
13277f5b10aSHannes EderWhen FILE is - read standard input.
13377f5b10aSHannes EderEOM
13477f5b10aSHannes Eder
13577f5b10aSHannes Eder	exit($exitcode);
13677f5b10aSHannes Eder}
13777f5b10aSHannes Eder
1383beb42ecSJoe Perchessub uniq {
1393beb42ecSJoe Perches	my %seen;
1403beb42ecSJoe Perches	return grep { !$seen{$_}++ } @_;
1413beb42ecSJoe Perches}
1423beb42ecSJoe Perches
1433beb42ecSJoe Perchessub list_types {
1443beb42ecSJoe Perches	my ($exitcode) = @_;
1453beb42ecSJoe Perches
1463beb42ecSJoe Perches	my $count = 0;
1473beb42ecSJoe Perches
1483beb42ecSJoe Perches	local $/ = undef;
1493beb42ecSJoe Perches
1503beb42ecSJoe Perches	open(my $script, '<', abs_path($P)) or
1513beb42ecSJoe Perches	    die "$P: Can't read '$P' $!\n";
1523beb42ecSJoe Perches
1533beb42ecSJoe Perches	my $text = <$script>;
1543beb42ecSJoe Perches	close($script);
1553beb42ecSJoe Perches
1563beb42ecSJoe Perches	my @types = ();
1570547fa58SJean Delvare	# Also catch when type or level is passed through a variable
1580547fa58SJean Delvare	for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {
1593beb42ecSJoe Perches		push (@types, $_);
1603beb42ecSJoe Perches	}
1613beb42ecSJoe Perches	@types = sort(uniq(@types));
1623beb42ecSJoe Perches	print("#\tMessage type\n\n");
1633beb42ecSJoe Perches	foreach my $type (@types) {
1643beb42ecSJoe Perches		print(++$count . "\t" . $type . "\n");
1653beb42ecSJoe Perches	}
1663beb42ecSJoe Perches
1673beb42ecSJoe Perches	exit($exitcode);
1683beb42ecSJoe Perches}
1693beb42ecSJoe Perches
170000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file);
171000d1cc1SJoe Perchesif (-f $conf) {
172000d1cc1SJoe Perches	my @conf_args;
173000d1cc1SJoe Perches	open(my $conffile, '<', "$conf")
174000d1cc1SJoe Perches	    or warn "$P: Can't find a readable $configuration_file file $!\n";
175000d1cc1SJoe Perches
176000d1cc1SJoe Perches	while (<$conffile>) {
177000d1cc1SJoe Perches		my $line = $_;
178000d1cc1SJoe Perches
179000d1cc1SJoe Perches		$line =~ s/\s*\n?$//g;
180000d1cc1SJoe Perches		$line =~ s/^\s*//g;
181000d1cc1SJoe Perches		$line =~ s/\s+/ /g;
182000d1cc1SJoe Perches
183000d1cc1SJoe Perches		next if ($line =~ m/^\s*#/);
184000d1cc1SJoe Perches		next if ($line =~ m/^\s*$/);
185000d1cc1SJoe Perches
186000d1cc1SJoe Perches		my @words = split(" ", $line);
187000d1cc1SJoe Perches		foreach my $word (@words) {
188000d1cc1SJoe Perches			last if ($word =~ m/^#/);
189000d1cc1SJoe Perches			push (@conf_args, $word);
190000d1cc1SJoe Perches		}
191000d1cc1SJoe Perches	}
192000d1cc1SJoe Perches	close($conffile);
193000d1cc1SJoe Perches	unshift(@ARGV, @conf_args) if @conf_args;
194000d1cc1SJoe Perches}
195000d1cc1SJoe Perches
196737c0767SJohn Brooks# Perl's Getopt::Long allows options to take optional arguments after a space.
197737c0767SJohn Brooks# Prevent --color by itself from consuming other arguments
198737c0767SJohn Brooksforeach (@ARGV) {
199737c0767SJohn Brooks	if ($_ eq "--color" || $_ eq "-color") {
200737c0767SJohn Brooks		$_ = "--color=$color";
201737c0767SJohn Brooks	}
202737c0767SJohn Brooks}
203737c0767SJohn Brooks
2040a920b5bSAndy WhitcroftGetOptions(
2056c72ffaaSAndy Whitcroft	'q|quiet+'	=> \$quiet,
2060a920b5bSAndy Whitcroft	'tree!'		=> \$tree,
2070a920b5bSAndy Whitcroft	'signoff!'	=> \$chk_signoff,
2080a920b5bSAndy Whitcroft	'patch!'	=> \$chk_patch,
2096c72ffaaSAndy Whitcroft	'emacs!'	=> \$emacs,
2108905a67cSAndy Whitcroft	'terse!'	=> \$terse,
21134d8815fSJoe Perches	'showfile!'	=> \$showfile,
21277f5b10aSHannes Eder	'f|file!'	=> \$file,
2134a593c34SDu, Changbin	'g|git!'	=> \$git,
2146c72ffaaSAndy Whitcroft	'subjective!'	=> \$check,
2156c72ffaaSAndy Whitcroft	'strict!'	=> \$check,
216000d1cc1SJoe Perches	'ignore=s'	=> \@ignore,
21791bfe484SJoe Perches	'types=s'	=> \@use,
218000d1cc1SJoe Perches	'show-types!'	=> \$show_types,
2193beb42ecSJoe Perches	'list-types!'	=> \$list_types,
2206cd7f386SJoe Perches	'max-line-length=i' => \$max_line_length,
22156193274SVadim Bendebury	'min-conf-desc-length=i' => \$min_conf_desc_length,
222713a09deSAntonio Borneo	'tab-size=i'	=> \$tabsize,
2236c72ffaaSAndy Whitcroft	'root=s'	=> \$root,
2248905a67cSAndy Whitcroft	'summary!'	=> \$summary,
2258905a67cSAndy Whitcroft	'mailback!'	=> \$mailback,
22613214adfSAndy Whitcroft	'summary-file!'	=> \$summary_file,
2273705ce5bSJoe Perches	'fix!'		=> \$fix,
2289624b8d6SJoe Perches	'fix-inplace!'	=> \$fix_inplace,
229d62a201fSDave Hansen	'ignore-perl-version!' => \$ignore_perl_version,
230c2fdda0dSAndy Whitcroft	'debug=s'	=> \%debug,
231773647a0SAndy Whitcroft	'test-only=s'	=> \$tst_only,
232ebfd7d62SJoe Perches	'codespell!'	=> \$codespell,
233ebfd7d62SJoe Perches	'codespellfile=s'	=> \$codespellfile,
23475ad8c57SJerome Forissier	'typedefsfile=s'	=> \$typedefsfile,
235737c0767SJohn Brooks	'color=s'	=> \$color,
236737c0767SJohn Brooks	'no-color'	=> \$color,	#keep old behaviors of -nocolor
237737c0767SJohn Brooks	'nocolor'	=> \$color,	#keep old behaviors of -nocolor
23877f5b10aSHannes Eder	'h|help'	=> \$help,
23977f5b10aSHannes Eder	'version'	=> \$help
24077f5b10aSHannes Eder) or help(1);
24177f5b10aSHannes Eder
24277f5b10aSHannes Ederhelp(0) if ($help);
2430a920b5bSAndy Whitcroft
2443beb42ecSJoe Percheslist_types(0) if ($list_types);
2453beb42ecSJoe Perches
2469624b8d6SJoe Perches$fix = 1 if ($fix_inplace);
2472ac73b4fSJoe Perches$check_orig = $check;
2489624b8d6SJoe Perches
2490a920b5bSAndy Whitcroftmy $exit = 0;
2500a920b5bSAndy Whitcroft
2515b57980dSJoe Perchesmy $perl_version_ok = 1;
252d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) {
2535b57980dSJoe Perches	$perl_version_ok = 0;
254d62a201fSDave Hansen	printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
2555b57980dSJoe Perches	exit(1) if (!$ignore_perl_version);
256d62a201fSDave Hansen}
257d62a201fSDave Hansen
25845107ff6SAllen Hubbe#if no filenames are given, push '-' to read patch from stdin
2590a920b5bSAndy Whitcroftif ($#ARGV < 0) {
26045107ff6SAllen Hubbe	push(@ARGV, '-');
2610a920b5bSAndy Whitcroft}
2620a920b5bSAndy Whitcroft
263737c0767SJohn Brooksif ($color =~ /^[01]$/) {
264737c0767SJohn Brooks	$color = !$color;
265737c0767SJohn Brooks} elsif ($color =~ /^always$/i) {
266737c0767SJohn Brooks	$color = 1;
267737c0767SJohn Brooks} elsif ($color =~ /^never$/i) {
268737c0767SJohn Brooks	$color = 0;
269737c0767SJohn Brooks} elsif ($color =~ /^auto$/i) {
270737c0767SJohn Brooks	$color = (-t STDOUT);
271737c0767SJohn Brooks} else {
272737c0767SJohn Brooks	die "Invalid color mode: $color\n";
273737c0767SJohn Brooks}
274737c0767SJohn Brooks
275713a09deSAntonio Borneo# skip TAB size 1 to avoid additional checks on $tabsize - 1
276713a09deSAntonio Borneodie "Invalid TAB size: $tabsize\n" if ($tabsize < 2);
277713a09deSAntonio Borneo
27891bfe484SJoe Perchessub hash_save_array_words {
27991bfe484SJoe Perches	my ($hashRef, $arrayRef) = @_;
28091bfe484SJoe Perches
28191bfe484SJoe Perches	my @array = split(/,/, join(',', @$arrayRef));
28291bfe484SJoe Perches	foreach my $word (@array) {
283000d1cc1SJoe Perches		$word =~ s/\s*\n?$//g;
284000d1cc1SJoe Perches		$word =~ s/^\s*//g;
285000d1cc1SJoe Perches		$word =~ s/\s+/ /g;
286000d1cc1SJoe Perches		$word =~ tr/[a-z]/[A-Z]/;
287000d1cc1SJoe Perches
288000d1cc1SJoe Perches		next if ($word =~ m/^\s*#/);
289000d1cc1SJoe Perches		next if ($word =~ m/^\s*$/);
290000d1cc1SJoe Perches
29191bfe484SJoe Perches		$hashRef->{$word}++;
292000d1cc1SJoe Perches	}
29391bfe484SJoe Perches}
29491bfe484SJoe Perches
29591bfe484SJoe Perchessub hash_show_words {
29691bfe484SJoe Perches	my ($hashRef, $prefix) = @_;
29791bfe484SJoe Perches
2983c816e49SJoe Perches	if (keys %$hashRef) {
299d8469f16SJoe Perches		print "\nNOTE: $prefix message types:";
30058cb3cf6SJoe Perches		foreach my $word (sort keys %$hashRef) {
30191bfe484SJoe Perches			print " $word";
30291bfe484SJoe Perches		}
303d8469f16SJoe Perches		print "\n";
30491bfe484SJoe Perches	}
30591bfe484SJoe Perches}
30691bfe484SJoe Perches
30791bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore);
30891bfe484SJoe Percheshash_save_array_words(\%use_type, \@use);
309000d1cc1SJoe Perches
310c2fdda0dSAndy Whitcroftmy $dbg_values = 0;
311c2fdda0dSAndy Whitcroftmy $dbg_possible = 0;
3127429c690SAndy Whitcroftmy $dbg_type = 0;
313a1ef277eSAndy Whitcroftmy $dbg_attr = 0;
314c2fdda0dSAndy Whitcroftfor my $key (keys %debug) {
31521caa13cSAndy Whitcroft	## no critic
31621caa13cSAndy Whitcroft	eval "\${dbg_$key} = '$debug{$key}';";
31721caa13cSAndy Whitcroft	die "$@" if ($@);
318c2fdda0dSAndy Whitcroft}
319c2fdda0dSAndy Whitcroft
320d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0;
321d2c0a235SAndy Whitcroft
3228905a67cSAndy Whitcroftif ($terse) {
3238905a67cSAndy Whitcroft	$emacs = 1;
3248905a67cSAndy Whitcroft	$quiet++;
3258905a67cSAndy Whitcroft}
3268905a67cSAndy Whitcroft
3276c72ffaaSAndy Whitcroftif ($tree) {
3286c72ffaaSAndy Whitcroft	if (defined $root) {
3296c72ffaaSAndy Whitcroft		if (!top_of_kernel_tree($root)) {
3306c72ffaaSAndy Whitcroft			die "$P: $root: --root does not point at a valid tree\n";
3316c72ffaaSAndy Whitcroft		}
3326c72ffaaSAndy Whitcroft	} else {
3336c72ffaaSAndy Whitcroft		if (top_of_kernel_tree('.')) {
3346c72ffaaSAndy Whitcroft			$root = '.';
3356c72ffaaSAndy Whitcroft		} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
3366c72ffaaSAndy Whitcroft						top_of_kernel_tree($1)) {
3376c72ffaaSAndy Whitcroft			$root = $1;
3386c72ffaaSAndy Whitcroft		}
3396c72ffaaSAndy Whitcroft	}
3406c72ffaaSAndy Whitcroft
3416c72ffaaSAndy Whitcroft	if (!defined $root) {
3420a920b5bSAndy Whitcroft		print "Must be run from the top-level dir. of a kernel tree\n";
3430a920b5bSAndy Whitcroft		exit(2);
3440a920b5bSAndy Whitcroft	}
3456c72ffaaSAndy Whitcroft}
3466c72ffaaSAndy Whitcroft
3476c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0;
3486c72ffaaSAndy Whitcroft
3492ceb532bSAndy Whitcroftour $Ident	= qr{
3502ceb532bSAndy Whitcroft			[A-Za-z_][A-Za-z\d_]*
3512ceb532bSAndy Whitcroft			(?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
3522ceb532bSAndy Whitcroft		}x;
3536c72ffaaSAndy Whitcroftour $Storage	= qr{extern|static|asmlinkage};
3546c72ffaaSAndy Whitcroftour $Sparse	= qr{
3556c72ffaaSAndy Whitcroft			__user|
3566c72ffaaSAndy Whitcroft			__kernel|
3576c72ffaaSAndy Whitcroft			__force|
3586c72ffaaSAndy Whitcroft			__iomem|
3596c72ffaaSAndy Whitcroft			__must_check|
360417495edSAndy Whitcroft			__kprobes|
361165e72a6SSven Eckelmann			__ref|
36233aa4597SGeert Uytterhoeven			__refconst|
36333aa4597SGeert Uytterhoeven			__refdata|
364ad315455SBoqun Feng			__rcu|
365ad315455SBoqun Feng			__private
3666c72ffaaSAndy Whitcroft		}x;
367e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
368e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
369e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
370e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
371e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
3728716de38SJoe Perches
37352131292SWolfram Sang# Notes to $Attribute:
37452131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
3756c72ffaaSAndy Whitcroftour $Attribute	= qr{
3766c72ffaaSAndy Whitcroft			const|
37703f1df7dSJoe Perches			__percpu|
37803f1df7dSJoe Perches			__nocast|
37903f1df7dSJoe Perches			__safe|
38046d832f5SMichael S. Tsirkin			__bitwise|
38103f1df7dSJoe Perches			__packed__|
38203f1df7dSJoe Perches			__packed2__|
38303f1df7dSJoe Perches			__naked|
38403f1df7dSJoe Perches			__maybe_unused|
38503f1df7dSJoe Perches			__always_unused|
38603f1df7dSJoe Perches			__noreturn|
38703f1df7dSJoe Perches			__used|
38803f1df7dSJoe Perches			__cold|
389e23ef1f3SJoe Perches			__pure|
39003f1df7dSJoe Perches			__noclone|
39103f1df7dSJoe Perches			__deprecated|
3926c72ffaaSAndy Whitcroft			__read_mostly|
393c5967e98SJoe Perches			__ro_after_init|
3946c72ffaaSAndy Whitcroft			__kprobes|
3958716de38SJoe Perches			$InitAttribute|
39624e1d81aSAndy Whitcroft			____cacheline_aligned|
39724e1d81aSAndy Whitcroft			____cacheline_aligned_in_smp|
3985fe3af11SAndy Whitcroft			____cacheline_internodealigned_in_smp|
3995fe3af11SAndy Whitcroft			__weak
4006c72ffaaSAndy Whitcroft		  }x;
401c45dcabdSAndy Whitcroftour $Modifier;
40291cb5195SJoe Perchesour $Inline	= qr{inline|__always_inline|noinline|__inline|__inline__};
4036c72ffaaSAndy Whitcroftour $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};
4046c72ffaaSAndy Whitcroftour $Lval	= qr{$Ident(?:$Member)*};
4056c72ffaaSAndy Whitcroft
40695e2c602SJoe Perchesour $Int_type	= qr{(?i)llu|ull|ll|lu|ul|l|u};
40795e2c602SJoe Perchesour $Binary	= qr{(?i)0b[01]+$Int_type?};
40895e2c602SJoe Perchesour $Hex	= qr{(?i)0x[0-9a-f]+$Int_type?};
40995e2c602SJoe Perchesour $Int	= qr{[0-9]+$Int_type?};
4102435880fSJoe Perchesour $Octal	= qr{0[0-7]+$Int_type?};
411c0a5c898SJoe Perchesour $String	= qr{"[X\t]*"};
412326b1ffcSJoe Perchesour $Float_hex	= qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
413326b1ffcSJoe Perchesour $Float_dec	= qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
414326b1ffcSJoe Perchesour $Float_int	= qr{(?i)[0-9]+e-?[0-9]+[fl]?};
41574349bccSJoe Perchesour $Float	= qr{$Float_hex|$Float_dec|$Float_int};
4162435880fSJoe Perchesour $Constant	= qr{$Float|$Binary|$Octal|$Hex|$Int};
417326b1ffcSJoe Perchesour $Assignment	= qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
418447432f3SJoe Perchesour $Compare    = qr{<=|>=|==|!=|<|(?<!-)>};
41923f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%};
4206c72ffaaSAndy Whitcroftour $Operators	= qr{
4216c72ffaaSAndy Whitcroft			<=|>=|==|!=|
4226c72ffaaSAndy Whitcroft			=>|->|<<|>>|<|>|!|~|
42323f780c9SJoe Perches			&&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
4246c72ffaaSAndy Whitcroft		  }x;
4256c72ffaaSAndy Whitcroft
42691cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
42791cb5195SJoe Perches
428ab7e23f3SJoe Perchesour $BasicType;
4298905a67cSAndy Whitcroftour $NonptrType;
4301813087dSJoe Perchesour $NonptrTypeMisordered;
4318716de38SJoe Perchesour $NonptrTypeWithAttr;
4328905a67cSAndy Whitcroftour $Type;
4331813087dSJoe Perchesour $TypeMisordered;
4348905a67cSAndy Whitcroftour $Declare;
4351813087dSJoe Perchesour $DeclareMisordered;
4368905a67cSAndy Whitcroft
43715662b3eSJoe Perchesour $NON_ASCII_UTF8	= qr{
43815662b3eSJoe Perches	[\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte
439171ae1a4SAndy Whitcroft	|  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
440171ae1a4SAndy Whitcroft	| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
441171ae1a4SAndy Whitcroft	|  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
442171ae1a4SAndy Whitcroft	|  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
443171ae1a4SAndy Whitcroft	| [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
444171ae1a4SAndy Whitcroft	|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
445171ae1a4SAndy Whitcroft}x;
446171ae1a4SAndy Whitcroft
44715662b3eSJoe Perchesour $UTF8	= qr{
44815662b3eSJoe Perches	[\x09\x0A\x0D\x20-\x7E]              # ASCII
44915662b3eSJoe Perches	| $NON_ASCII_UTF8
45015662b3eSJoe Perches}x;
45115662b3eSJoe Perches
452e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
453021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x:
454021158b4SJoe Perches	u_(?:char|short|int|long) |          # bsd
455021158b4SJoe Perches	u(?:nchar|short|int|long)            # sysv
456021158b4SJoe Perches)};
457e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x:
458fb9e9096SAndy Whitcroft	(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
4598ed22cadSAndy Whitcroft	atomic_t
4608ed22cadSAndy Whitcroft)};
461e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x:
462e6176fa4SJoe Perches	$typeC99Typedefs\b|
463e6176fa4SJoe Perches	$typeOtherOSTypedefs\b|
464e6176fa4SJoe Perches	$typeKernelTypedefs\b
465e6176fa4SJoe Perches)};
4668ed22cadSAndy Whitcroft
4676d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
4686d32f7a3SJoe Perches
469691e669bSJoe Perchesour $logFunctions = qr{(?x:
470758d7aadSMiles Chen	printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
4717d0b6594SJacob Keller	(?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
47287bd499aSJoe Perches	TP_printk|
4736e60c02eSJoe Perches	WARN(?:_RATELIMIT|_ONCE|)|
474b0531722SJoe Perches	panic|
47506668727SJoe Perches	MODULE_[A-Z_]+|
47606668727SJoe Perches	seq_vprintf|seq_printf|seq_puts
477691e669bSJoe Perches)};
478691e669bSJoe Perches
479e29a70f1SJoe Perchesour $allocFunctions = qr{(?x:
480e29a70f1SJoe Perches	(?:(?:devm_)?
481e29a70f1SJoe Perches		(?:kv|k|v)[czm]alloc(?:_node|_array)? |
482e29a70f1SJoe Perches		kstrdup(?:_const)? |
483e29a70f1SJoe Perches		kmemdup(?:_nul)?) |
484461e1565SChristophe JAILLET	(?:\w+)?alloc_skb(?:_ip_align)? |
485e29a70f1SJoe Perches				# dev_alloc_skb/netdev_alloc_skb, et al
486e29a70f1SJoe Perches	dma_alloc_coherent
487e29a70f1SJoe Perches)};
488e29a70f1SJoe Perches
48920112475SJoe Perchesour $signature_tags = qr{(?xi:
49020112475SJoe Perches	Signed-off-by:|
491d499480cSJorge Ramirez-Ortiz	Co-developed-by:|
49220112475SJoe Perches	Acked-by:|
49320112475SJoe Perches	Tested-by:|
49420112475SJoe Perches	Reviewed-by:|
49520112475SJoe Perches	Reported-by:|
4968543ae12SMugunthan V N	Suggested-by:|
49720112475SJoe Perches	To:|
49820112475SJoe Perches	Cc:
49920112475SJoe Perches)};
50020112475SJoe Perches
5011813087dSJoe Perchesour @typeListMisordered = (
5021813087dSJoe Perches	qr{char\s+(?:un)?signed},
5031813087dSJoe Perches	qr{int\s+(?:(?:un)?signed\s+)?short\s},
5041813087dSJoe Perches	qr{int\s+short(?:\s+(?:un)?signed)},
5051813087dSJoe Perches	qr{short\s+int(?:\s+(?:un)?signed)},
5061813087dSJoe Perches	qr{(?:un)?signed\s+int\s+short},
5071813087dSJoe Perches	qr{short\s+(?:un)?signed},
5081813087dSJoe Perches	qr{long\s+int\s+(?:un)?signed},
5091813087dSJoe Perches	qr{int\s+long\s+(?:un)?signed},
5101813087dSJoe Perches	qr{long\s+(?:un)?signed\s+int},
5111813087dSJoe Perches	qr{int\s+(?:un)?signed\s+long},
5121813087dSJoe Perches	qr{int\s+(?:un)?signed},
5131813087dSJoe Perches	qr{int\s+long\s+long\s+(?:un)?signed},
5141813087dSJoe Perches	qr{long\s+long\s+int\s+(?:un)?signed},
5151813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed\s+int},
5161813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed},
5171813087dSJoe Perches	qr{long\s+(?:un)?signed},
5181813087dSJoe Perches);
5191813087dSJoe Perches
5208905a67cSAndy Whitcroftour @typeList = (
5218905a67cSAndy Whitcroft	qr{void},
5220c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?char},
5230c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short\s+int},
5240c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short},
5250c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?int},
5260c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+int},
5270c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
5280c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long},
5290c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long},
5300c773d9dSJoe Perches	qr{(?:un)?signed},
5318905a67cSAndy Whitcroft	qr{float},
5328905a67cSAndy Whitcroft	qr{double},
5338905a67cSAndy Whitcroft	qr{bool},
5348905a67cSAndy Whitcroft	qr{struct\s+$Ident},
5358905a67cSAndy Whitcroft	qr{union\s+$Ident},
5368905a67cSAndy Whitcroft	qr{enum\s+$Ident},
5378905a67cSAndy Whitcroft	qr{${Ident}_t},
5388905a67cSAndy Whitcroft	qr{${Ident}_handler},
5398905a67cSAndy Whitcroft	qr{${Ident}_handler_fn},
5401813087dSJoe Perches	@typeListMisordered,
5418905a67cSAndy Whitcroft);
542938224b5SJoe Perches
543938224b5SJoe Perchesour $C90_int_types = qr{(?x:
544938224b5SJoe Perches	long\s+long\s+int\s+(?:un)?signed|
545938224b5SJoe Perches	long\s+long\s+(?:un)?signed\s+int|
546938224b5SJoe Perches	long\s+long\s+(?:un)?signed|
547938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long\s+int|
548938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long|
549938224b5SJoe Perches	int\s+long\s+long\s+(?:un)?signed|
550938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long\s+long|
551938224b5SJoe Perches
552938224b5SJoe Perches	long\s+int\s+(?:un)?signed|
553938224b5SJoe Perches	long\s+(?:un)?signed\s+int|
554938224b5SJoe Perches	long\s+(?:un)?signed|
555938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+int|
556938224b5SJoe Perches	(?:(?:un)?signed\s+)?long|
557938224b5SJoe Perches	int\s+long\s+(?:un)?signed|
558938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long|
559938224b5SJoe Perches
560938224b5SJoe Perches	int\s+(?:un)?signed|
561938224b5SJoe Perches	(?:(?:un)?signed\s+)?int
562938224b5SJoe Perches)};
563938224b5SJoe Perches
564485ff23eSAlex Dowadour @typeListFile = ();
5658716de38SJoe Perchesour @typeListWithAttr = (
5668716de38SJoe Perches	@typeList,
5678716de38SJoe Perches	qr{struct\s+$InitAttribute\s+$Ident},
5688716de38SJoe Perches	qr{union\s+$InitAttribute\s+$Ident},
5698716de38SJoe Perches);
5708716de38SJoe Perches
571c45dcabdSAndy Whitcroftour @modifierList = (
572c45dcabdSAndy Whitcroft	qr{fastcall},
573c45dcabdSAndy Whitcroft);
574485ff23eSAlex Dowadour @modifierListFile = ();
5758905a67cSAndy Whitcroft
5762435880fSJoe Perchesour @mode_permission_funcs = (
5772435880fSJoe Perches	["module_param", 3],
5782435880fSJoe Perches	["module_param_(?:array|named|string)", 4],
5792435880fSJoe Perches	["module_param_array_named", 5],
5802435880fSJoe Perches	["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
5812435880fSJoe Perches	["proc_create(?:_data|)", 2],
582459cf0aeSJoe Perches	["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
583459cf0aeSJoe Perches	["IIO_DEV_ATTR_[A-Z_]+", 1],
584459cf0aeSJoe Perches	["SENSOR_(?:DEVICE_|)ATTR_2", 2],
585459cf0aeSJoe Perches	["SENSOR_TEMPLATE(?:_2|)", 3],
586459cf0aeSJoe Perches	["__ATTR", 2],
5872435880fSJoe Perches);
5882435880fSJoe Perches
589515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below
590515a235eSJoe Perchesour $mode_perms_search = "";
591515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) {
592515a235eSJoe Perches	$mode_perms_search .= '|' if ($mode_perms_search ne "");
593515a235eSJoe Perches	$mode_perms_search .= $entry->[0];
594515a235eSJoe Perches}
59500180468SJoe Perches$mode_perms_search = "(?:${mode_perms_search})";
596515a235eSJoe Perches
5979189c7e7SJoe Perchesour %deprecated_apis = (
5989189c7e7SJoe Perches	"synchronize_rcu_bh"			=> "synchronize_rcu",
5999189c7e7SJoe Perches	"synchronize_rcu_bh_expedited"		=> "synchronize_rcu_expedited",
6009189c7e7SJoe Perches	"call_rcu_bh"				=> "call_rcu",
6019189c7e7SJoe Perches	"rcu_barrier_bh"			=> "rcu_barrier",
6029189c7e7SJoe Perches	"synchronize_sched"			=> "synchronize_rcu",
6039189c7e7SJoe Perches	"synchronize_sched_expedited"		=> "synchronize_rcu_expedited",
6049189c7e7SJoe Perches	"call_rcu_sched"			=> "call_rcu",
6059189c7e7SJoe Perches	"rcu_barrier_sched"			=> "rcu_barrier",
6069189c7e7SJoe Perches	"get_state_synchronize_sched"		=> "get_state_synchronize_rcu",
6079189c7e7SJoe Perches	"cond_synchronize_sched"		=> "cond_synchronize_rcu",
6089189c7e7SJoe Perches);
6099189c7e7SJoe Perches
6109189c7e7SJoe Perches#Create a search pattern for all these strings to speed up a loop below
6119189c7e7SJoe Perchesour $deprecated_apis_search = "";
6129189c7e7SJoe Perchesforeach my $entry (keys %deprecated_apis) {
6139189c7e7SJoe Perches	$deprecated_apis_search .= '|' if ($deprecated_apis_search ne "");
6149189c7e7SJoe Perches	$deprecated_apis_search .= $entry;
6159189c7e7SJoe Perches}
6169189c7e7SJoe Perches$deprecated_apis_search = "(?:${deprecated_apis_search})";
6179189c7e7SJoe Perches
618b392c64fSJoe Perchesour $mode_perms_world_writable = qr{
619b392c64fSJoe Perches	S_IWUGO		|
620b392c64fSJoe Perches	S_IWOTH		|
621b392c64fSJoe Perches	S_IRWXUGO	|
622b392c64fSJoe Perches	S_IALLUGO	|
623b392c64fSJoe Perches	0[0-7][0-7][2367]
624b392c64fSJoe Perches}x;
625b392c64fSJoe Perches
626f90774e1SJoe Perchesour %mode_permission_string_types = (
627f90774e1SJoe Perches	"S_IRWXU" => 0700,
628f90774e1SJoe Perches	"S_IRUSR" => 0400,
629f90774e1SJoe Perches	"S_IWUSR" => 0200,
630f90774e1SJoe Perches	"S_IXUSR" => 0100,
631f90774e1SJoe Perches	"S_IRWXG" => 0070,
632f90774e1SJoe Perches	"S_IRGRP" => 0040,
633f90774e1SJoe Perches	"S_IWGRP" => 0020,
634f90774e1SJoe Perches	"S_IXGRP" => 0010,
635f90774e1SJoe Perches	"S_IRWXO" => 0007,
636f90774e1SJoe Perches	"S_IROTH" => 0004,
637f90774e1SJoe Perches	"S_IWOTH" => 0002,
638f90774e1SJoe Perches	"S_IXOTH" => 0001,
639f90774e1SJoe Perches	"S_IRWXUGO" => 0777,
640f90774e1SJoe Perches	"S_IRUGO" => 0444,
641f90774e1SJoe Perches	"S_IWUGO" => 0222,
642f90774e1SJoe Perches	"S_IXUGO" => 0111,
643f90774e1SJoe Perches);
644f90774e1SJoe Perches
645f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below
646f90774e1SJoe Perchesour $mode_perms_string_search = "";
647f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) {
648f90774e1SJoe Perches	$mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
649f90774e1SJoe Perches	$mode_perms_string_search .= $entry;
650f90774e1SJoe Perches}
65100180468SJoe Perchesour $single_mode_perms_string_search = "(?:${mode_perms_string_search})";
65200180468SJoe Perchesour $multi_mode_perms_string_search = qr{
65300180468SJoe Perches	${single_mode_perms_string_search}
65400180468SJoe Perches	(?:\s*\|\s*${single_mode_perms_string_search})*
65500180468SJoe Perches}x;
65600180468SJoe Perches
65700180468SJoe Perchessub perms_to_octal {
65800180468SJoe Perches	my ($string) = @_;
65900180468SJoe Perches
66000180468SJoe Perches	return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/);
66100180468SJoe Perches
66200180468SJoe Perches	my $val = "";
66300180468SJoe Perches	my $oval = "";
66400180468SJoe Perches	my $to = 0;
66500180468SJoe Perches	my $curpos = 0;
66600180468SJoe Perches	my $lastpos = 0;
66700180468SJoe Perches	while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
66800180468SJoe Perches		$curpos = pos($string);
66900180468SJoe Perches		my $match = $2;
67000180468SJoe Perches		my $omatch = $1;
67100180468SJoe Perches		last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
67200180468SJoe Perches		$lastpos = $curpos;
67300180468SJoe Perches		$to |= $mode_permission_string_types{$match};
67400180468SJoe Perches		$val .= '\s*\|\s*' if ($val ne "");
67500180468SJoe Perches		$val .= $match;
67600180468SJoe Perches		$oval .= $omatch;
67700180468SJoe Perches	}
67800180468SJoe Perches	$oval =~ s/^\s*\|\s*//;
67900180468SJoe Perches	$oval =~ s/\s*\|\s*$//;
68000180468SJoe Perches	return sprintf("%04o", $to);
68100180468SJoe Perches}
682f90774e1SJoe Perches
6837840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x:
6847840a94cSWolfram Sang	irq|
685cdcee686SSergey Ryazanov	memory|
686cdcee686SSergey Ryazanov	time|
687cdcee686SSergey Ryazanov	reboot
6887840a94cSWolfram Sang)};
6897840a94cSWolfram Sang# memory.h: ARM has a custom one
6907840a94cSWolfram Sang
69166b47b4aSKees Cook# Load common spelling mistakes and build regular expression list.
69266b47b4aSKees Cookmy $misspellings;
69366b47b4aSKees Cookmy %spelling_fix;
69436061e38SJoe Perches
69536061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) {
69666b47b4aSKees Cook	while (<$spelling>) {
69766b47b4aSKees Cook		my $line = $_;
69866b47b4aSKees Cook
69966b47b4aSKees Cook		$line =~ s/\s*\n?$//g;
70066b47b4aSKees Cook		$line =~ s/^\s*//g;
70166b47b4aSKees Cook
70266b47b4aSKees Cook		next if ($line =~ m/^\s*#/);
70366b47b4aSKees Cook		next if ($line =~ m/^\s*$/);
70466b47b4aSKees Cook
70566b47b4aSKees Cook		my ($suspect, $fix) = split(/\|\|/, $line);
70666b47b4aSKees Cook
70766b47b4aSKees Cook		$spelling_fix{$suspect} = $fix;
70866b47b4aSKees Cook	}
70966b47b4aSKees Cook	close($spelling);
71036061e38SJoe Perches} else {
71136061e38SJoe Perches	warn "No typos will be found - file '$spelling_file': $!\n";
71236061e38SJoe Perches}
71366b47b4aSKees Cook
714ebfd7d62SJoe Perchesif ($codespell) {
715ebfd7d62SJoe Perches	if (open(my $spelling, '<', $codespellfile)) {
716ebfd7d62SJoe Perches		while (<$spelling>) {
717ebfd7d62SJoe Perches			my $line = $_;
718ebfd7d62SJoe Perches
719ebfd7d62SJoe Perches			$line =~ s/\s*\n?$//g;
720ebfd7d62SJoe Perches			$line =~ s/^\s*//g;
721ebfd7d62SJoe Perches
722ebfd7d62SJoe Perches			next if ($line =~ m/^\s*#/);
723ebfd7d62SJoe Perches			next if ($line =~ m/^\s*$/);
724ebfd7d62SJoe Perches			next if ($line =~ m/, disabled/i);
725ebfd7d62SJoe Perches
726ebfd7d62SJoe Perches			$line =~ s/,.*$//;
727ebfd7d62SJoe Perches
728ebfd7d62SJoe Perches			my ($suspect, $fix) = split(/->/, $line);
729ebfd7d62SJoe Perches
730ebfd7d62SJoe Perches			$spelling_fix{$suspect} = $fix;
731ebfd7d62SJoe Perches		}
732ebfd7d62SJoe Perches		close($spelling);
733ebfd7d62SJoe Perches	} else {
734ebfd7d62SJoe Perches		warn "No codespell typos will be found - file '$codespellfile': $!\n";
735ebfd7d62SJoe Perches	}
736ebfd7d62SJoe Perches}
737ebfd7d62SJoe Perches
738ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
739ebfd7d62SJoe Perches
74075ad8c57SJerome Forissiersub read_words {
74175ad8c57SJerome Forissier	my ($wordsRef, $file) = @_;
74275ad8c57SJerome Forissier
74375ad8c57SJerome Forissier	if (open(my $words, '<', $file)) {
74475ad8c57SJerome Forissier		while (<$words>) {
745bf1fa1daSJoe Perches			my $line = $_;
746bf1fa1daSJoe Perches
747bf1fa1daSJoe Perches			$line =~ s/\s*\n?$//g;
748bf1fa1daSJoe Perches			$line =~ s/^\s*//g;
749bf1fa1daSJoe Perches
750bf1fa1daSJoe Perches			next if ($line =~ m/^\s*#/);
751bf1fa1daSJoe Perches			next if ($line =~ m/^\s*$/);
752bf1fa1daSJoe Perches			if ($line =~ /\s/) {
75375ad8c57SJerome Forissier				print("$file: '$line' invalid - ignored\n");
754bf1fa1daSJoe Perches				next;
755bf1fa1daSJoe Perches			}
756bf1fa1daSJoe Perches
75775ad8c57SJerome Forissier			$$wordsRef .= '|' if ($$wordsRef ne "");
75875ad8c57SJerome Forissier			$$wordsRef .= $line;
759bf1fa1daSJoe Perches		}
76075ad8c57SJerome Forissier		close($file);
76175ad8c57SJerome Forissier		return 1;
762bf1fa1daSJoe Perches	}
763bf1fa1daSJoe Perches
76475ad8c57SJerome Forissier	return 0;
76575ad8c57SJerome Forissier}
76675ad8c57SJerome Forissier
76775ad8c57SJerome Forissiermy $const_structs = "";
76875ad8c57SJerome Forissierread_words(\$const_structs, $conststructsfile)
76975ad8c57SJerome Forissier    or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
77075ad8c57SJerome Forissier
77175ad8c57SJerome Forissiermy $typeOtherTypedefs = "";
77275ad8c57SJerome Forissierif (length($typedefsfile)) {
77375ad8c57SJerome Forissier	read_words(\$typeOtherTypedefs, $typedefsfile)
77475ad8c57SJerome Forissier	    or warn "No additional types will be considered - file '$typedefsfile': $!\n";
77575ad8c57SJerome Forissier}
77675ad8c57SJerome Forissier$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne "");
77775ad8c57SJerome Forissier
7788905a67cSAndy Whitcroftsub build_types {
779485ff23eSAlex Dowad	my $mods = "(?x:  \n" . join("|\n  ", (@modifierList, @modifierListFile)) . "\n)";
780485ff23eSAlex Dowad	my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile)) . "\n)";
7811813087dSJoe Perches	my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered) . "\n)";
7828716de38SJoe Perches	my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr) . "\n)";
783c8cb2ca3SAndy Whitcroft	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};
784ab7e23f3SJoe Perches	$BasicType	= qr{
785ab7e23f3SJoe Perches				(?:$typeTypedefs\b)|
786ab7e23f3SJoe Perches				(?:${all}\b)
787ab7e23f3SJoe Perches		}x;
7888905a67cSAndy Whitcroft	$NonptrType	= qr{
789d2172eb5SAndy Whitcroft			(?:$Modifier\s+|const\s+)*
790cf655043SAndy Whitcroft			(?:
7916b48db24SAndy Whitcroft				(?:typeof|__typeof__)\s*\([^\)]*\)|
7928ed22cadSAndy Whitcroft				(?:$typeTypedefs\b)|
793c45dcabdSAndy Whitcroft				(?:${all}\b)
794cf655043SAndy Whitcroft			)
795c8cb2ca3SAndy Whitcroft			(?:\s+$Modifier|\s+const)*
7968905a67cSAndy Whitcroft		  }x;
7971813087dSJoe Perches	$NonptrTypeMisordered	= qr{
7981813087dSJoe Perches			(?:$Modifier\s+|const\s+)*
7991813087dSJoe Perches			(?:
8001813087dSJoe Perches				(?:${Misordered}\b)
8011813087dSJoe Perches			)
8021813087dSJoe Perches			(?:\s+$Modifier|\s+const)*
8031813087dSJoe Perches		  }x;
8048716de38SJoe Perches	$NonptrTypeWithAttr	= qr{
8058716de38SJoe Perches			(?:$Modifier\s+|const\s+)*
8068716de38SJoe Perches			(?:
8078716de38SJoe Perches				(?:typeof|__typeof__)\s*\([^\)]*\)|
8088716de38SJoe Perches				(?:$typeTypedefs\b)|
8098716de38SJoe Perches				(?:${allWithAttr}\b)
8108716de38SJoe Perches			)
8118716de38SJoe Perches			(?:\s+$Modifier|\s+const)*
8128716de38SJoe Perches		  }x;
8138905a67cSAndy Whitcroft	$Type	= qr{
814c45dcabdSAndy Whitcroft			$NonptrType
8157b18496cSAntonio Borneo			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
816c8cb2ca3SAndy Whitcroft			(?:\s+$Inline|\s+$Modifier)*
8178905a67cSAndy Whitcroft		  }x;
8181813087dSJoe Perches	$TypeMisordered	= qr{
8191813087dSJoe Perches			$NonptrTypeMisordered
8207b18496cSAntonio Borneo			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+){0,4}
8211813087dSJoe Perches			(?:\s+$Inline|\s+$Modifier)*
8221813087dSJoe Perches		  }x;
82391cb5195SJoe Perches	$Declare	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
8241813087dSJoe Perches	$DeclareMisordered	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
8258905a67cSAndy Whitcroft}
8268905a67cSAndy Whitcroftbuild_types();
8276c72ffaaSAndy Whitcroft
8287d2367afSJoe Perchesour $Typecast	= qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
829d1fe9c09SJoe Perches
830d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg
831d1fe9c09SJoe Perches# requires at least perl version v5.10.0
832d1fe9c09SJoe Perches# Any use must be runtime checked with $^V
833d1fe9c09SJoe Perches
834d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
8352435880fSJoe Perchesour $LvalOrFunc	= qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
836c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
8377d2367afSJoe Perches
838f8422308SJoe Perchesour $declaration_macros = qr{(?x:
8393e838b6cSJoe Perches	(?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
840fe658f94SSteffen Maier	(?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
8413d102fc0SGilad Ben-Yossef	(?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(|
8423d102fc0SGilad Ben-Yossef	(?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(
843f8422308SJoe Perches)};
844f8422308SJoe Perches
8457d2367afSJoe Perchessub deparenthesize {
8467d2367afSJoe Perches	my ($string) = @_;
8477d2367afSJoe Perches	return "" if (!defined($string));
8485b9553abSJoe Perches
8495b9553abSJoe Perches	while ($string =~ /^\s*\(.*\)\s*$/) {
8505b9553abSJoe Perches		$string =~ s@^\s*\(\s*@@;
8515b9553abSJoe Perches		$string =~ s@\s*\)\s*$@@;
8525b9553abSJoe Perches	}
8535b9553abSJoe Perches
8547d2367afSJoe Perches	$string =~ s@\s+@ @g;
8555b9553abSJoe Perches
8567d2367afSJoe Perches	return $string;
8577d2367afSJoe Perches}
8587d2367afSJoe Perches
8593445686aSJoe Perchessub seed_camelcase_file {
8603445686aSJoe Perches	my ($file) = @_;
8613445686aSJoe Perches
8623445686aSJoe Perches	return if (!(-f $file));
8633445686aSJoe Perches
8643445686aSJoe Perches	local $/;
8653445686aSJoe Perches
8663445686aSJoe Perches	open(my $include_file, '<', "$file")
8673445686aSJoe Perches	    or warn "$P: Can't read '$file' $!\n";
8683445686aSJoe Perches	my $text = <$include_file>;
8693445686aSJoe Perches	close($include_file);
8703445686aSJoe Perches
8713445686aSJoe Perches	my @lines = split('\n', $text);
8723445686aSJoe Perches
8733445686aSJoe Perches	foreach my $line (@lines) {
8743445686aSJoe Perches		next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
8753445686aSJoe Perches		if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
8763445686aSJoe Perches			$camelcase{$1} = 1;
87711ea516aSJoe Perches		} elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
87811ea516aSJoe Perches			$camelcase{$1} = 1;
87911ea516aSJoe Perches		} elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
8803445686aSJoe Perches			$camelcase{$1} = 1;
8813445686aSJoe Perches		}
8823445686aSJoe Perches	}
8833445686aSJoe Perches}
8843445686aSJoe Perches
885cd28b119SJoe Perchesour %maintained_status = ();
886cd28b119SJoe Perches
88785b0ee18SJoe Perchessub is_maintained_obsolete {
88885b0ee18SJoe Perches	my ($filename) = @_;
88985b0ee18SJoe Perches
890f2c19c2fSJerome Forissier	return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
89185b0ee18SJoe Perches
892cd28b119SJoe Perches	if (!exists($maintained_status{$filename})) {
893cd28b119SJoe Perches		$maintained_status{$filename} = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
894cd28b119SJoe Perches	}
89585b0ee18SJoe Perches
896cd28b119SJoe Perches	return $maintained_status{$filename} =~ /obsolete/i;
89785b0ee18SJoe Perches}
89885b0ee18SJoe Perches
8993b6e8ac9SJoe Perchessub is_SPDX_License_valid {
9003b6e8ac9SJoe Perches	my ($license) = @_;
9013b6e8ac9SJoe Perches
90256294112SJoe Perches	return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$root/.git"));
9033b6e8ac9SJoe Perches
90456294112SJoe Perches	my $root_path = abs_path($root);
90556294112SJoe Perches	my $status = `cd "$root_path"; echo "$license" | python scripts/spdxcheck.py -`;
9063b6e8ac9SJoe Perches	return 0 if ($status ne "");
9073b6e8ac9SJoe Perches	return 1;
9083b6e8ac9SJoe Perches}
9093b6e8ac9SJoe Perches
9103445686aSJoe Perchesmy $camelcase_seeded = 0;
9113445686aSJoe Perchessub seed_camelcase_includes {
9123445686aSJoe Perches	return if ($camelcase_seeded);
9133445686aSJoe Perches
9143445686aSJoe Perches	my $files;
915c707a81dSJoe Perches	my $camelcase_cache = "";
916c707a81dSJoe Perches	my @include_files = ();
917c707a81dSJoe Perches
918c707a81dSJoe Perches	$camelcase_seeded = 1;
919351b2a1fSJoe Perches
9203645e328SRichard Genoud	if (-e ".git") {
921dbbf869dSJoe Perches		my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`;
922351b2a1fSJoe Perches		chomp $git_last_include_commit;
923c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
924c707a81dSJoe Perches	} else {
925c707a81dSJoe Perches		my $last_mod_date = 0;
926c707a81dSJoe Perches		$files = `find $root/include -name "*.h"`;
927c707a81dSJoe Perches		@include_files = split('\n', $files);
928c707a81dSJoe Perches		foreach my $file (@include_files) {
929c707a81dSJoe Perches			my $date = POSIX::strftime("%Y%m%d%H%M",
930c707a81dSJoe Perches						   localtime((stat $file)[9]));
931c707a81dSJoe Perches			$last_mod_date = $date if ($last_mod_date < $date);
932c707a81dSJoe Perches		}
933c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
934c707a81dSJoe Perches	}
935c707a81dSJoe Perches
936c707a81dSJoe Perches	if ($camelcase_cache ne "" && -f $camelcase_cache) {
937c707a81dSJoe Perches		open(my $camelcase_file, '<', "$camelcase_cache")
938c707a81dSJoe Perches		    or warn "$P: Can't read '$camelcase_cache' $!\n";
939351b2a1fSJoe Perches		while (<$camelcase_file>) {
940351b2a1fSJoe Perches			chomp;
941351b2a1fSJoe Perches			$camelcase{$_} = 1;
942351b2a1fSJoe Perches		}
943351b2a1fSJoe Perches		close($camelcase_file);
944351b2a1fSJoe Perches
945351b2a1fSJoe Perches		return;
946351b2a1fSJoe Perches	}
947c707a81dSJoe Perches
9483645e328SRichard Genoud	if (-e ".git") {
949dbbf869dSJoe Perches		$files = `${git_command} ls-files "include/*.h"`;
950c707a81dSJoe Perches		@include_files = split('\n', $files);
9513445686aSJoe Perches	}
952c707a81dSJoe Perches
9533445686aSJoe Perches	foreach my $file (@include_files) {
9543445686aSJoe Perches		seed_camelcase_file($file);
9553445686aSJoe Perches	}
956351b2a1fSJoe Perches
957c707a81dSJoe Perches	if ($camelcase_cache ne "") {
958351b2a1fSJoe Perches		unlink glob ".checkpatch-camelcase.*";
959c707a81dSJoe Perches		open(my $camelcase_file, '>', "$camelcase_cache")
960c707a81dSJoe Perches		    or warn "$P: Can't write '$camelcase_cache' $!\n";
961351b2a1fSJoe Perches		foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
962351b2a1fSJoe Perches			print $camelcase_file ("$_\n");
963351b2a1fSJoe Perches		}
964351b2a1fSJoe Perches		close($camelcase_file);
965351b2a1fSJoe Perches	}
9663445686aSJoe Perches}
9673445686aSJoe Perches
968d311cd44SJoe Perchessub git_commit_info {
969d311cd44SJoe Perches	my ($commit, $id, $desc) = @_;
970d311cd44SJoe Perches
971d311cd44SJoe Perches	return ($id, $desc) if ((which("git") eq "") || !(-e ".git"));
972d311cd44SJoe Perches
973dbbf869dSJoe Perches	my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`;
974d311cd44SJoe Perches	$output =~ s/^\s*//gm;
975d311cd44SJoe Perches	my @lines = split("\n", $output);
976d311cd44SJoe Perches
9770d7835fcSJoe Perches	return ($id, $desc) if ($#lines < 0);
9780d7835fcSJoe Perches
9795a7f4455SSean Christopherson	if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) {
980d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns
981d311cd44SJoe Perches# all matching commit ids, but it's very slow...
982d311cd44SJoe Perches#
983d311cd44SJoe Perches#		echo "checking commits $1..."
984d311cd44SJoe Perches#		git rev-list --remotes | grep -i "^$1" |
985d311cd44SJoe Perches#		while read line ; do
986d311cd44SJoe Perches#		    git log --format='%H %s' -1 $line |
987d311cd44SJoe Perches#		    echo "commit $(cut -c 1-12,41-)"
988d311cd44SJoe Perches#		done
989d311cd44SJoe Perches	} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) {
990948b133aSHeinrich Schuchardt		$id = undef;
991d311cd44SJoe Perches	} else {
992d311cd44SJoe Perches		$id = substr($lines[0], 0, 12);
993d311cd44SJoe Perches		$desc = substr($lines[0], 41);
994d311cd44SJoe Perches	}
995d311cd44SJoe Perches
996d311cd44SJoe Perches	return ($id, $desc);
997d311cd44SJoe Perches}
998d311cd44SJoe Perches
9996c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file);
10000a920b5bSAndy Whitcroft
100100df344fSAndy Whitcroftmy @rawlines = ();
1002c2fdda0dSAndy Whitcroftmy @lines = ();
10033705ce5bSJoe Perchesmy @fixed = ();
1004d752fcc8SJoe Perchesmy @fixed_inserted = ();
1005d752fcc8SJoe Perchesmy @fixed_deleted = ();
1006194f66fcSJoe Perchesmy $fixlinenr = -1;
1007194f66fcSJoe Perches
10084a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions.
10094a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
10104a593c34SDu, Changbindie "$P: No git repository found\n" if ($git && !-e ".git");
10114a593c34SDu, Changbin
10124a593c34SDu, Changbinif ($git) {
10134a593c34SDu, Changbin	my @commits = ();
10140dea9f1eSJoe Perches	foreach my $commit_expr (@ARGV) {
10154a593c34SDu, Changbin		my $git_range;
101628898fd1SJoe Perches		if ($commit_expr =~ m/^(.*)-(\d+)$/) {
101728898fd1SJoe Perches			$git_range = "-$2 $1";
10184a593c34SDu, Changbin		} elsif ($commit_expr =~ m/\.\./) {
10194a593c34SDu, Changbin			$git_range = "$commit_expr";
10204a593c34SDu, Changbin		} else {
10210dea9f1eSJoe Perches			$git_range = "-1 $commit_expr";
10220dea9f1eSJoe Perches		}
1023dbbf869dSJoe Perches		my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
10240dea9f1eSJoe Perches		foreach my $line (split(/\n/, $lines)) {
102528898fd1SJoe Perches			$line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
102628898fd1SJoe Perches			next if (!defined($1) || !defined($2));
10270dea9f1eSJoe Perches			my $sha1 = $1;
10280dea9f1eSJoe Perches			my $subject = $2;
10290dea9f1eSJoe Perches			unshift(@commits, $sha1);
10300dea9f1eSJoe Perches			$git_commits{$sha1} = $subject;
10314a593c34SDu, Changbin		}
10324a593c34SDu, Changbin	}
10334a593c34SDu, Changbin	die "$P: no git commits after extraction!\n" if (@commits == 0);
10344a593c34SDu, Changbin	@ARGV = @commits;
10354a593c34SDu, Changbin}
10364a593c34SDu, Changbin
1037c2fdda0dSAndy Whitcroftmy $vname;
103898005e8cSVadim Bendebury$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"};
10396c72ffaaSAndy Whitcroftfor my $filename (@ARGV) {
104021caa13cSAndy Whitcroft	my $FILE;
10414a593c34SDu, Changbin	if ($git) {
10424a593c34SDu, Changbin		open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
10434a593c34SDu, Changbin			die "$P: $filename: git format-patch failed - $!\n";
10444a593c34SDu, Changbin	} elsif ($file) {
104521caa13cSAndy Whitcroft		open($FILE, '-|', "diff -u /dev/null $filename") ||
10466c72ffaaSAndy Whitcroft			die "$P: $filename: diff failed - $!\n";
104721caa13cSAndy Whitcroft	} elsif ($filename eq '-') {
104821caa13cSAndy Whitcroft		open($FILE, '<&STDIN');
10496c72ffaaSAndy Whitcroft	} else {
105021caa13cSAndy Whitcroft		open($FILE, '<', "$filename") ||
10516c72ffaaSAndy Whitcroft			die "$P: $filename: open failed - $!\n";
10526c72ffaaSAndy Whitcroft	}
1053c2fdda0dSAndy Whitcroft	if ($filename eq '-') {
1054c2fdda0dSAndy Whitcroft		$vname = 'Your patch';
10554a593c34SDu, Changbin	} elsif ($git) {
10560dea9f1eSJoe Perches		$vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
1057c2fdda0dSAndy Whitcroft	} else {
1058c2fdda0dSAndy Whitcroft		$vname = $filename;
1059c2fdda0dSAndy Whitcroft	}
106021caa13cSAndy Whitcroft	while (<$FILE>) {
10610a920b5bSAndy Whitcroft		chomp;
106200df344fSAndy Whitcroft		push(@rawlines, $_);
10636c72ffaaSAndy Whitcroft	}
106421caa13cSAndy Whitcroft	close($FILE);
1065d8469f16SJoe Perches
1066d8469f16SJoe Perches	if ($#ARGV > 0 && $quiet == 0) {
1067d8469f16SJoe Perches		print '-' x length($vname) . "\n";
1068d8469f16SJoe Perches		print "$vname\n";
1069d8469f16SJoe Perches		print '-' x length($vname) . "\n";
1070d8469f16SJoe Perches	}
1071d8469f16SJoe Perches
1072c2fdda0dSAndy Whitcroft	if (!process($filename)) {
10730a920b5bSAndy Whitcroft		$exit = 1;
10740a920b5bSAndy Whitcroft	}
107500df344fSAndy Whitcroft	@rawlines = ();
107613214adfSAndy Whitcroft	@lines = ();
10773705ce5bSJoe Perches	@fixed = ();
1078d752fcc8SJoe Perches	@fixed_inserted = ();
1079d752fcc8SJoe Perches	@fixed_deleted = ();
1080194f66fcSJoe Perches	$fixlinenr = -1;
1081485ff23eSAlex Dowad	@modifierListFile = ();
1082485ff23eSAlex Dowad	@typeListFile = ();
1083485ff23eSAlex Dowad	build_types();
10840a920b5bSAndy Whitcroft}
10850a920b5bSAndy Whitcroft
1086d8469f16SJoe Perchesif (!$quiet) {
10873c816e49SJoe Perches	hash_show_words(\%use_type, "Used");
10883c816e49SJoe Perches	hash_show_words(\%ignore_type, "Ignored");
10893c816e49SJoe Perches
10905b57980dSJoe Perches	if (!$perl_version_ok) {
1091d8469f16SJoe Perches		print << "EOM"
1092d8469f16SJoe Perches
1093d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues.
10945b57980dSJoe Perches      An upgrade to at least perl $minimum_perl_version is suggested.
1095d8469f16SJoe PerchesEOM
1096d8469f16SJoe Perches	}
1097d8469f16SJoe Perches	if ($exit) {
1098d8469f16SJoe Perches		print << "EOM"
1099d8469f16SJoe Perches
1100d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report
1101d8469f16SJoe Perches      them to the maintainer, see CHECKPATCH in MAINTAINERS.
1102d8469f16SJoe PerchesEOM
1103d8469f16SJoe Perches	}
1104d8469f16SJoe Perches}
1105d8469f16SJoe Perches
11060a920b5bSAndy Whitcroftexit($exit);
11070a920b5bSAndy Whitcroft
11080a920b5bSAndy Whitcroftsub top_of_kernel_tree {
11096c72ffaaSAndy Whitcroft	my ($root) = @_;
11106c72ffaaSAndy Whitcroft
11116c72ffaaSAndy Whitcroft	my @tree_check = (
11126c72ffaaSAndy Whitcroft		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
11136c72ffaaSAndy Whitcroft		"README", "Documentation", "arch", "include", "drivers",
11146c72ffaaSAndy Whitcroft		"fs", "init", "ipc", "kernel", "lib", "scripts",
11156c72ffaaSAndy Whitcroft	);
11166c72ffaaSAndy Whitcroft
11176c72ffaaSAndy Whitcroft	foreach my $check (@tree_check) {
11186c72ffaaSAndy Whitcroft		if (! -e $root . '/' . $check) {
11190a920b5bSAndy Whitcroft			return 0;
11200a920b5bSAndy Whitcroft		}
11216c72ffaaSAndy Whitcroft	}
11226c72ffaaSAndy Whitcroft	return 1;
11236c72ffaaSAndy Whitcroft}
11240a920b5bSAndy Whitcroft
112520112475SJoe Perchessub parse_email {
112620112475SJoe Perches	my ($formatted_email) = @_;
112720112475SJoe Perches
112820112475SJoe Perches	my $name = "";
1129dfa05c28SJoe Perches	my $name_comment = "";
113020112475SJoe Perches	my $address = "";
113120112475SJoe Perches	my $comment = "";
113220112475SJoe Perches
113320112475SJoe Perches	if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
113420112475SJoe Perches		$name = $1;
113520112475SJoe Perches		$address = $2;
113620112475SJoe Perches		$comment = $3 if defined $3;
113720112475SJoe Perches	} elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
113820112475SJoe Perches		$address = $1;
113920112475SJoe Perches		$comment = $2 if defined $2;
114020112475SJoe Perches	} elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
114120112475SJoe Perches		$address = $1;
114220112475SJoe Perches		$comment = $2 if defined $2;
114385e12066SJoe Perches		$formatted_email =~ s/\Q$address\E.*$//;
114420112475SJoe Perches		$name = $formatted_email;
11453705ce5bSJoe Perches		$name = trim($name);
114620112475SJoe Perches		$name =~ s/^\"|\"$//g;
114720112475SJoe Perches		# If there's a name left after stripping spaces and
114820112475SJoe Perches		# leading quotes, and the address doesn't have both
114920112475SJoe Perches		# leading and trailing angle brackets, the address
115020112475SJoe Perches		# is invalid. ie:
115120112475SJoe Perches		#   "joe smith [email protected]" bad
115220112475SJoe Perches		#   "joe smith <[email protected]" bad
115320112475SJoe Perches		if ($name ne "" && $address !~ /^<[^>]+>$/) {
115420112475SJoe Perches			$name = "";
115520112475SJoe Perches			$address = "";
115620112475SJoe Perches			$comment = "";
115720112475SJoe Perches		}
115820112475SJoe Perches	}
115920112475SJoe Perches
11603705ce5bSJoe Perches	$name = trim($name);
116120112475SJoe Perches	$name =~ s/^\"|\"$//g;
1162dfa05c28SJoe Perches	$name =~ s/(\s*\([^\)]+\))\s*//;
1163dfa05c28SJoe Perches	if (defined($1)) {
1164dfa05c28SJoe Perches		$name_comment = trim($1);
1165dfa05c28SJoe Perches	}
11663705ce5bSJoe Perches	$address = trim($address);
116720112475SJoe Perches	$address =~ s/^\<|\>$//g;
116820112475SJoe Perches
116920112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
117020112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
117120112475SJoe Perches		$name = "\"$name\"";
117220112475SJoe Perches	}
117320112475SJoe Perches
1174dfa05c28SJoe Perches	return ($name, $name_comment, $address, $comment);
117520112475SJoe Perches}
117620112475SJoe Perches
117720112475SJoe Perchessub format_email {
117820112475SJoe Perches	my ($name, $address) = @_;
117920112475SJoe Perches
118020112475SJoe Perches	my $formatted_email;
118120112475SJoe Perches
11823705ce5bSJoe Perches	$name = trim($name);
118320112475SJoe Perches	$name =~ s/^\"|\"$//g;
11843705ce5bSJoe Perches	$address = trim($address);
118520112475SJoe Perches
118620112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
118720112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
118820112475SJoe Perches		$name = "\"$name\"";
118920112475SJoe Perches	}
119020112475SJoe Perches
119120112475SJoe Perches	if ("$name" eq "") {
119220112475SJoe Perches		$formatted_email = "$address";
119320112475SJoe Perches	} else {
119420112475SJoe Perches		$formatted_email = "$name <$address>";
119520112475SJoe Perches	}
119620112475SJoe Perches
119720112475SJoe Perches	return $formatted_email;
119820112475SJoe Perches}
119920112475SJoe Perches
1200dfa05c28SJoe Perchessub reformat_email {
1201dfa05c28SJoe Perches	my ($email) = @_;
1202dfa05c28SJoe Perches
1203dfa05c28SJoe Perches	my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
1204dfa05c28SJoe Perches	return format_email($email_name, $email_address);
1205dfa05c28SJoe Perches}
1206dfa05c28SJoe Perches
1207dfa05c28SJoe Perchessub same_email_addresses {
1208dfa05c28SJoe Perches	my ($email1, $email2) = @_;
1209dfa05c28SJoe Perches
1210dfa05c28SJoe Perches	my ($email1_name, $name1_comment, $email1_address, $comment1) = parse_email($email1);
1211dfa05c28SJoe Perches	my ($email2_name, $name2_comment, $email2_address, $comment2) = parse_email($email2);
1212dfa05c28SJoe Perches
1213dfa05c28SJoe Perches	return $email1_name eq $email2_name &&
1214dfa05c28SJoe Perches	       $email1_address eq $email2_address;
1215dfa05c28SJoe Perches}
1216dfa05c28SJoe Perches
1217d311cd44SJoe Perchessub which {
1218d311cd44SJoe Perches	my ($bin) = @_;
1219d311cd44SJoe Perches
1220d311cd44SJoe Perches	foreach my $path (split(/:/, $ENV{PATH})) {
1221d311cd44SJoe Perches		if (-e "$path/$bin") {
1222d311cd44SJoe Perches			return "$path/$bin";
1223d311cd44SJoe Perches		}
1224d311cd44SJoe Perches	}
1225d311cd44SJoe Perches
1226d311cd44SJoe Perches	return "";
1227d311cd44SJoe Perches}
1228d311cd44SJoe Perches
1229000d1cc1SJoe Perchessub which_conf {
1230000d1cc1SJoe Perches	my ($conf) = @_;
1231000d1cc1SJoe Perches
1232000d1cc1SJoe Perches	foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
1233000d1cc1SJoe Perches		if (-e "$path/$conf") {
1234000d1cc1SJoe Perches			return "$path/$conf";
1235000d1cc1SJoe Perches		}
1236000d1cc1SJoe Perches	}
1237000d1cc1SJoe Perches
1238000d1cc1SJoe Perches	return "";
1239000d1cc1SJoe Perches}
1240000d1cc1SJoe Perches
12410a920b5bSAndy Whitcroftsub expand_tabs {
12420a920b5bSAndy Whitcroft	my ($str) = @_;
12430a920b5bSAndy Whitcroft
12440a920b5bSAndy Whitcroft	my $res = '';
12450a920b5bSAndy Whitcroft	my $n = 0;
12460a920b5bSAndy Whitcroft	for my $c (split(//, $str)) {
12470a920b5bSAndy Whitcroft		if ($c eq "\t") {
12480a920b5bSAndy Whitcroft			$res .= ' ';
12490a920b5bSAndy Whitcroft			$n++;
1250713a09deSAntonio Borneo			for (; ($n % $tabsize) != 0; $n++) {
12510a920b5bSAndy Whitcroft				$res .= ' ';
12520a920b5bSAndy Whitcroft			}
12530a920b5bSAndy Whitcroft			next;
12540a920b5bSAndy Whitcroft		}
12550a920b5bSAndy Whitcroft		$res .= $c;
12560a920b5bSAndy Whitcroft		$n++;
12570a920b5bSAndy Whitcroft	}
12580a920b5bSAndy Whitcroft
12590a920b5bSAndy Whitcroft	return $res;
12600a920b5bSAndy Whitcroft}
12616c72ffaaSAndy Whitcroftsub copy_spacing {
1262773647a0SAndy Whitcroft	(my $res = shift) =~ tr/\t/ /c;
12636c72ffaaSAndy Whitcroft	return $res;
12646c72ffaaSAndy Whitcroft}
12650a920b5bSAndy Whitcroft
12664a0df2efSAndy Whitcroftsub line_stats {
12674a0df2efSAndy Whitcroft	my ($line) = @_;
12684a0df2efSAndy Whitcroft
12694a0df2efSAndy Whitcroft	# Drop the diff line leader and expand tabs
12704a0df2efSAndy Whitcroft	$line =~ s/^.//;
12714a0df2efSAndy Whitcroft	$line = expand_tabs($line);
12724a0df2efSAndy Whitcroft
12734a0df2efSAndy Whitcroft	# Pick the indent from the front of the line.
12744a0df2efSAndy Whitcroft	my ($white) = ($line =~ /^(\s*)/);
12754a0df2efSAndy Whitcroft
12764a0df2efSAndy Whitcroft	return (length($line), length($white));
12774a0df2efSAndy Whitcroft}
12784a0df2efSAndy Whitcroft
1279773647a0SAndy Whitcroftmy $sanitise_quote = '';
1280773647a0SAndy Whitcroft
1281773647a0SAndy Whitcroftsub sanitise_line_reset {
1282773647a0SAndy Whitcroft	my ($in_comment) = @_;
1283773647a0SAndy Whitcroft
1284773647a0SAndy Whitcroft	if ($in_comment) {
1285773647a0SAndy Whitcroft		$sanitise_quote = '*/';
1286773647a0SAndy Whitcroft	} else {
1287773647a0SAndy Whitcroft		$sanitise_quote = '';
1288773647a0SAndy Whitcroft	}
1289773647a0SAndy Whitcroft}
129000df344fSAndy Whitcroftsub sanitise_line {
129100df344fSAndy Whitcroft	my ($line) = @_;
129200df344fSAndy Whitcroft
129300df344fSAndy Whitcroft	my $res = '';
129400df344fSAndy Whitcroft	my $l = '';
129500df344fSAndy Whitcroft
1296c2fdda0dSAndy Whitcroft	my $qlen = 0;
1297773647a0SAndy Whitcroft	my $off = 0;
1298773647a0SAndy Whitcroft	my $c;
129900df344fSAndy Whitcroft
1300773647a0SAndy Whitcroft	# Always copy over the diff marker.
1301773647a0SAndy Whitcroft	$res = substr($line, 0, 1);
1302773647a0SAndy Whitcroft
1303773647a0SAndy Whitcroft	for ($off = 1; $off < length($line); $off++) {
1304773647a0SAndy Whitcroft		$c = substr($line, $off, 1);
1305773647a0SAndy Whitcroft
13068d2e11b2SClaudio Fontana		# Comments we are whacking completely including the begin
1307773647a0SAndy Whitcroft		# and end, all to $;.
1308773647a0SAndy Whitcroft		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
1309773647a0SAndy Whitcroft			$sanitise_quote = '*/';
1310773647a0SAndy Whitcroft
1311773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1312773647a0SAndy Whitcroft			$off++;
131300df344fSAndy Whitcroft			next;
1314773647a0SAndy Whitcroft		}
131581bc0e02SAndy Whitcroft		if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
1316773647a0SAndy Whitcroft			$sanitise_quote = '';
1317773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1318773647a0SAndy Whitcroft			$off++;
1319773647a0SAndy Whitcroft			next;
1320773647a0SAndy Whitcroft		}
1321113f04a8SDaniel Walker		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
1322113f04a8SDaniel Walker			$sanitise_quote = '//';
1323113f04a8SDaniel Walker
1324113f04a8SDaniel Walker			substr($res, $off, 2, $sanitise_quote);
1325113f04a8SDaniel Walker			$off++;
1326113f04a8SDaniel Walker			next;
1327113f04a8SDaniel Walker		}
1328773647a0SAndy Whitcroft
1329773647a0SAndy Whitcroft		# A \ in a string means ignore the next character.
1330773647a0SAndy Whitcroft		if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
1331773647a0SAndy Whitcroft		    $c eq "\\") {
1332773647a0SAndy Whitcroft			substr($res, $off, 2, 'XX');
1333773647a0SAndy Whitcroft			$off++;
1334773647a0SAndy Whitcroft			next;
1335773647a0SAndy Whitcroft		}
1336773647a0SAndy Whitcroft		# Regular quotes.
1337773647a0SAndy Whitcroft		if ($c eq "'" || $c eq '"') {
1338773647a0SAndy Whitcroft			if ($sanitise_quote eq '') {
1339773647a0SAndy Whitcroft				$sanitise_quote = $c;
1340773647a0SAndy Whitcroft
1341773647a0SAndy Whitcroft				substr($res, $off, 1, $c);
1342773647a0SAndy Whitcroft				next;
1343773647a0SAndy Whitcroft			} elsif ($sanitise_quote eq $c) {
1344773647a0SAndy Whitcroft				$sanitise_quote = '';
134500df344fSAndy Whitcroft			}
134600df344fSAndy Whitcroft		}
1347773647a0SAndy Whitcroft
1348fae17daeSAndy Whitcroft		#print "c<$c> SQ<$sanitise_quote>\n";
1349773647a0SAndy Whitcroft		if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
1350773647a0SAndy Whitcroft			substr($res, $off, 1, $;);
1351113f04a8SDaniel Walker		} elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
1352113f04a8SDaniel Walker			substr($res, $off, 1, $;);
1353773647a0SAndy Whitcroft		} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
1354773647a0SAndy Whitcroft			substr($res, $off, 1, 'X');
135500df344fSAndy Whitcroft		} else {
1356773647a0SAndy Whitcroft			substr($res, $off, 1, $c);
135700df344fSAndy Whitcroft		}
1358c2fdda0dSAndy Whitcroft	}
1359c2fdda0dSAndy Whitcroft
1360113f04a8SDaniel Walker	if ($sanitise_quote eq '//') {
1361113f04a8SDaniel Walker		$sanitise_quote = '';
1362113f04a8SDaniel Walker	}
1363113f04a8SDaniel Walker
1364c2fdda0dSAndy Whitcroft	# The pathname on a #include may be surrounded by '<' and '>'.
1365c45dcabdSAndy Whitcroft	if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
1366c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1367c2fdda0dSAndy Whitcroft		$res =~ s@\<.*\>@<$clean>@;
1368c2fdda0dSAndy Whitcroft
1369c2fdda0dSAndy Whitcroft	# The whole of a #error is a string.
1370c45dcabdSAndy Whitcroft	} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
1371c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1372c45dcabdSAndy Whitcroft		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
1373c2fdda0dSAndy Whitcroft	}
1374c2fdda0dSAndy Whitcroft
1375dadf680dSJoe Perches	if ($allow_c99_comments && $res =~ m@(//.*$)@) {
1376dadf680dSJoe Perches		my $match = $1;
1377dadf680dSJoe Perches		$res =~ s/\Q$match\E/"$;" x length($match)/e;
1378dadf680dSJoe Perches	}
1379dadf680dSJoe Perches
138000df344fSAndy Whitcroft	return $res;
138100df344fSAndy Whitcroft}
138200df344fSAndy Whitcroft
1383a6962d72SJoe Perchessub get_quoted_string {
1384a6962d72SJoe Perches	my ($line, $rawline) = @_;
1385a6962d72SJoe Perches
1386478b1799SJoe Perches	return "" if (!defined($line) || !defined($rawline));
138733acb54aSJoe Perches	return "" if ($line !~ m/($String)/g);
1388a6962d72SJoe Perches	return substr($rawline, $-[0], $+[0] - $-[0]);
1389a6962d72SJoe Perches}
1390a6962d72SJoe Perches
13918905a67cSAndy Whitcroftsub ctx_statement_block {
13928905a67cSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
13938905a67cSAndy Whitcroft	my $line = $linenr - 1;
13948905a67cSAndy Whitcroft	my $blk = '';
13958905a67cSAndy Whitcroft	my $soff = $off;
13968905a67cSAndy Whitcroft	my $coff = $off - 1;
1397773647a0SAndy Whitcroft	my $coff_set = 0;
13988905a67cSAndy Whitcroft
139913214adfSAndy Whitcroft	my $loff = 0;
140013214adfSAndy Whitcroft
14018905a67cSAndy Whitcroft	my $type = '';
14028905a67cSAndy Whitcroft	my $level = 0;
1403a2750645SAndy Whitcroft	my @stack = ();
1404cf655043SAndy Whitcroft	my $p;
14058905a67cSAndy Whitcroft	my $c;
14068905a67cSAndy Whitcroft	my $len = 0;
140713214adfSAndy Whitcroft
140813214adfSAndy Whitcroft	my $remainder;
14098905a67cSAndy Whitcroft	while (1) {
1410a2750645SAndy Whitcroft		@stack = (['', 0]) if ($#stack == -1);
1411a2750645SAndy Whitcroft
1412773647a0SAndy Whitcroft		#warn "CSB: blk<$blk> remain<$remain>\n";
14138905a67cSAndy Whitcroft		# If we are about to drop off the end, pull in more
14148905a67cSAndy Whitcroft		# context.
14158905a67cSAndy Whitcroft		if ($off >= $len) {
14168905a67cSAndy Whitcroft			for (; $remain > 0; $line++) {
1417dea33496SAndy Whitcroft				last if (!defined $lines[$line]);
1418c2fdda0dSAndy Whitcroft				next if ($lines[$line] =~ /^-/);
14198905a67cSAndy Whitcroft				$remain--;
142013214adfSAndy Whitcroft				$loff = $len;
1421c2fdda0dSAndy Whitcroft				$blk .= $lines[$line] . "\n";
14228905a67cSAndy Whitcroft				$len = length($blk);
14238905a67cSAndy Whitcroft				$line++;
14248905a67cSAndy Whitcroft				last;
14258905a67cSAndy Whitcroft			}
14268905a67cSAndy Whitcroft			# Bail if there is no further context.
14278905a67cSAndy Whitcroft			#warn "CSB: blk<$blk> off<$off> len<$len>\n";
142813214adfSAndy Whitcroft			if ($off >= $len) {
14298905a67cSAndy Whitcroft				last;
14308905a67cSAndy Whitcroft			}
1431f74bd194SAndy Whitcroft			if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
1432f74bd194SAndy Whitcroft				$level++;
1433f74bd194SAndy Whitcroft				$type = '#';
1434f74bd194SAndy Whitcroft			}
14358905a67cSAndy Whitcroft		}
1436cf655043SAndy Whitcroft		$p = $c;
14378905a67cSAndy Whitcroft		$c = substr($blk, $off, 1);
143813214adfSAndy Whitcroft		$remainder = substr($blk, $off);
14398905a67cSAndy Whitcroft
1440773647a0SAndy Whitcroft		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
14414635f4fbSAndy Whitcroft
14424635f4fbSAndy Whitcroft		# Handle nested #if/#else.
14434635f4fbSAndy Whitcroft		if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
14444635f4fbSAndy Whitcroft			push(@stack, [ $type, $level ]);
14454635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
14464635f4fbSAndy Whitcroft			($type, $level) = @{$stack[$#stack - 1]};
14474635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*endif\b/) {
14484635f4fbSAndy Whitcroft			($type, $level) = @{pop(@stack)};
14494635f4fbSAndy Whitcroft		}
14504635f4fbSAndy Whitcroft
14518905a67cSAndy Whitcroft		# Statement ends at the ';' or a close '}' at the
14528905a67cSAndy Whitcroft		# outermost level.
14538905a67cSAndy Whitcroft		if ($level == 0 && $c eq ';') {
14548905a67cSAndy Whitcroft			last;
14558905a67cSAndy Whitcroft		}
14568905a67cSAndy Whitcroft
145713214adfSAndy Whitcroft		# An else is really a conditional as long as its not else if
1458773647a0SAndy Whitcroft		if ($level == 0 && $coff_set == 0 &&
1459773647a0SAndy Whitcroft				(!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
1460773647a0SAndy Whitcroft				$remainder =~ /^(else)(?:\s|{)/ &&
1461773647a0SAndy Whitcroft				$remainder !~ /^else\s+if\b/) {
1462773647a0SAndy Whitcroft			$coff = $off + length($1) - 1;
1463773647a0SAndy Whitcroft			$coff_set = 1;
1464773647a0SAndy Whitcroft			#warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
1465773647a0SAndy Whitcroft			#warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
146613214adfSAndy Whitcroft		}
146713214adfSAndy Whitcroft
14688905a67cSAndy Whitcroft		if (($type eq '' || $type eq '(') && $c eq '(') {
14698905a67cSAndy Whitcroft			$level++;
14708905a67cSAndy Whitcroft			$type = '(';
14718905a67cSAndy Whitcroft		}
14728905a67cSAndy Whitcroft		if ($type eq '(' && $c eq ')') {
14738905a67cSAndy Whitcroft			$level--;
14748905a67cSAndy Whitcroft			$type = ($level != 0)? '(' : '';
14758905a67cSAndy Whitcroft
14768905a67cSAndy Whitcroft			if ($level == 0 && $coff < $soff) {
14778905a67cSAndy Whitcroft				$coff = $off;
1478773647a0SAndy Whitcroft				$coff_set = 1;
1479773647a0SAndy Whitcroft				#warn "CSB: mark coff<$coff>\n";
14808905a67cSAndy Whitcroft			}
14818905a67cSAndy Whitcroft		}
14828905a67cSAndy Whitcroft		if (($type eq '' || $type eq '{') && $c eq '{') {
14838905a67cSAndy Whitcroft			$level++;
14848905a67cSAndy Whitcroft			$type = '{';
14858905a67cSAndy Whitcroft		}
14868905a67cSAndy Whitcroft		if ($type eq '{' && $c eq '}') {
14878905a67cSAndy Whitcroft			$level--;
14888905a67cSAndy Whitcroft			$type = ($level != 0)? '{' : '';
14898905a67cSAndy Whitcroft
14908905a67cSAndy Whitcroft			if ($level == 0) {
1491b998e001SPatrick Pannuto				if (substr($blk, $off + 1, 1) eq ';') {
1492b998e001SPatrick Pannuto					$off++;
1493b998e001SPatrick Pannuto				}
14948905a67cSAndy Whitcroft				last;
14958905a67cSAndy Whitcroft			}
14968905a67cSAndy Whitcroft		}
1497f74bd194SAndy Whitcroft		# Preprocessor commands end at the newline unless escaped.
1498f74bd194SAndy Whitcroft		if ($type eq '#' && $c eq "\n" && $p ne "\\") {
1499f74bd194SAndy Whitcroft			$level--;
1500f74bd194SAndy Whitcroft			$type = '';
1501f74bd194SAndy Whitcroft			$off++;
1502f74bd194SAndy Whitcroft			last;
1503f74bd194SAndy Whitcroft		}
15048905a67cSAndy Whitcroft		$off++;
15058905a67cSAndy Whitcroft	}
1506a3bb97a7SAndy Whitcroft	# We are truly at the end, so shuffle to the next line.
150713214adfSAndy Whitcroft	if ($off == $len) {
1508a3bb97a7SAndy Whitcroft		$loff = $len + 1;
150913214adfSAndy Whitcroft		$line++;
151013214adfSAndy Whitcroft		$remain--;
151113214adfSAndy Whitcroft	}
15128905a67cSAndy Whitcroft
15138905a67cSAndy Whitcroft	my $statement = substr($blk, $soff, $off - $soff + 1);
15148905a67cSAndy Whitcroft	my $condition = substr($blk, $soff, $coff - $soff + 1);
15158905a67cSAndy Whitcroft
15168905a67cSAndy Whitcroft	#warn "STATEMENT<$statement>\n";
15178905a67cSAndy Whitcroft	#warn "CONDITION<$condition>\n";
15188905a67cSAndy Whitcroft
1519773647a0SAndy Whitcroft	#print "coff<$coff> soff<$off> loff<$loff>\n";
152013214adfSAndy Whitcroft
152113214adfSAndy Whitcroft	return ($statement, $condition,
152213214adfSAndy Whitcroft			$line, $remain + 1, $off - $loff + 1, $level);
152313214adfSAndy Whitcroft}
152413214adfSAndy Whitcroft
1525cf655043SAndy Whitcroftsub statement_lines {
1526cf655043SAndy Whitcroft	my ($stmt) = @_;
1527cf655043SAndy Whitcroft
1528cf655043SAndy Whitcroft	# Strip the diff line prefixes and rip blank lines at start and end.
1529cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1530cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1531cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1532cf655043SAndy Whitcroft
1533cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1534cf655043SAndy Whitcroft
1535cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1536cf655043SAndy Whitcroft}
1537cf655043SAndy Whitcroft
1538cf655043SAndy Whitcroftsub statement_rawlines {
1539cf655043SAndy Whitcroft	my ($stmt) = @_;
1540cf655043SAndy Whitcroft
1541cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1542cf655043SAndy Whitcroft
1543cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1544cf655043SAndy Whitcroft}
1545cf655043SAndy Whitcroft
1546cf655043SAndy Whitcroftsub statement_block_size {
1547cf655043SAndy Whitcroft	my ($stmt) = @_;
1548cf655043SAndy Whitcroft
1549cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1550cf655043SAndy Whitcroft	$stmt =~ s/^\s*{//;
1551cf655043SAndy Whitcroft	$stmt =~ s/}\s*$//;
1552cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1553cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1554cf655043SAndy Whitcroft
1555cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1556cf655043SAndy Whitcroft	my @stmt_statements = ($stmt =~ /;/g);
1557cf655043SAndy Whitcroft
1558cf655043SAndy Whitcroft	my $stmt_lines = $#stmt_lines + 2;
1559cf655043SAndy Whitcroft	my $stmt_statements = $#stmt_statements + 1;
1560cf655043SAndy Whitcroft
1561cf655043SAndy Whitcroft	if ($stmt_lines > $stmt_statements) {
1562cf655043SAndy Whitcroft		return $stmt_lines;
1563cf655043SAndy Whitcroft	} else {
1564cf655043SAndy Whitcroft		return $stmt_statements;
1565cf655043SAndy Whitcroft	}
1566cf655043SAndy Whitcroft}
1567cf655043SAndy Whitcroft
156813214adfSAndy Whitcroftsub ctx_statement_full {
156913214adfSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
157013214adfSAndy Whitcroft	my ($statement, $condition, $level);
157113214adfSAndy Whitcroft
157213214adfSAndy Whitcroft	my (@chunks);
157313214adfSAndy Whitcroft
1574cf655043SAndy Whitcroft	# Grab the first conditional/block pair.
157513214adfSAndy Whitcroft	($statement, $condition, $linenr, $remain, $off, $level) =
157613214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1577773647a0SAndy Whitcroft	#print "F: c<$condition> s<$statement> remain<$remain>\n";
157813214adfSAndy Whitcroft	push(@chunks, [ $condition, $statement ]);
1579cf655043SAndy Whitcroft	if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1580cf655043SAndy Whitcroft		return ($level, $linenr, @chunks);
1581cf655043SAndy Whitcroft	}
1582cf655043SAndy Whitcroft
1583cf655043SAndy Whitcroft	# Pull in the following conditional/block pairs and see if they
1584cf655043SAndy Whitcroft	# could continue the statement.
1585cf655043SAndy Whitcroft	for (;;) {
158613214adfSAndy Whitcroft		($statement, $condition, $linenr, $remain, $off, $level) =
158713214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1588cf655043SAndy Whitcroft		#print "C: c<$condition> s<$statement> remain<$remain>\n";
1589773647a0SAndy Whitcroft		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1590cf655043SAndy Whitcroft		#print "C: push\n";
1591cf655043SAndy Whitcroft		push(@chunks, [ $condition, $statement ]);
159213214adfSAndy Whitcroft	}
159313214adfSAndy Whitcroft
159413214adfSAndy Whitcroft	return ($level, $linenr, @chunks);
15958905a67cSAndy Whitcroft}
15968905a67cSAndy Whitcroft
15974a0df2efSAndy Whitcroftsub ctx_block_get {
1598f0a594c1SAndy Whitcroft	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
15994a0df2efSAndy Whitcroft	my $line;
16004a0df2efSAndy Whitcroft	my $start = $linenr - 1;
16014a0df2efSAndy Whitcroft	my $blk = '';
16024a0df2efSAndy Whitcroft	my @o;
16034a0df2efSAndy Whitcroft	my @c;
16044a0df2efSAndy Whitcroft	my @res = ();
16054a0df2efSAndy Whitcroft
1606f0a594c1SAndy Whitcroft	my $level = 0;
16074635f4fbSAndy Whitcroft	my @stack = ($level);
160800df344fSAndy Whitcroft	for ($line = $start; $remain > 0; $line++) {
160900df344fSAndy Whitcroft		next if ($rawlines[$line] =~ /^-/);
161000df344fSAndy Whitcroft		$remain--;
161100df344fSAndy Whitcroft
161200df344fSAndy Whitcroft		$blk .= $rawlines[$line];
16134635f4fbSAndy Whitcroft
16144635f4fbSAndy Whitcroft		# Handle nested #if/#else.
161501464f30SAndy Whitcroft		if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
16164635f4fbSAndy Whitcroft			push(@stack, $level);
161701464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
16184635f4fbSAndy Whitcroft			$level = $stack[$#stack - 1];
161901464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
16204635f4fbSAndy Whitcroft			$level = pop(@stack);
16214635f4fbSAndy Whitcroft		}
16224635f4fbSAndy Whitcroft
162301464f30SAndy Whitcroft		foreach my $c (split(//, $lines[$line])) {
1624f0a594c1SAndy Whitcroft			##print "C<$c>L<$level><$open$close>O<$off>\n";
1625f0a594c1SAndy Whitcroft			if ($off > 0) {
1626f0a594c1SAndy Whitcroft				$off--;
1627f0a594c1SAndy Whitcroft				next;
1628f0a594c1SAndy Whitcroft			}
16294a0df2efSAndy Whitcroft
1630f0a594c1SAndy Whitcroft			if ($c eq $close && $level > 0) {
1631f0a594c1SAndy Whitcroft				$level--;
1632f0a594c1SAndy Whitcroft				last if ($level == 0);
1633f0a594c1SAndy Whitcroft			} elsif ($c eq $open) {
1634f0a594c1SAndy Whitcroft				$level++;
1635f0a594c1SAndy Whitcroft			}
1636f0a594c1SAndy Whitcroft		}
16374a0df2efSAndy Whitcroft
1638f0a594c1SAndy Whitcroft		if (!$outer || $level <= 1) {
163900df344fSAndy Whitcroft			push(@res, $rawlines[$line]);
16404a0df2efSAndy Whitcroft		}
16414a0df2efSAndy Whitcroft
1642f0a594c1SAndy Whitcroft		last if ($level == 0);
16434a0df2efSAndy Whitcroft	}
16444a0df2efSAndy Whitcroft
1645f0a594c1SAndy Whitcroft	return ($level, @res);
16464a0df2efSAndy Whitcroft}
16474a0df2efSAndy Whitcroftsub ctx_block_outer {
16484a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
16494a0df2efSAndy Whitcroft
1650f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1651f0a594c1SAndy Whitcroft	return @r;
16524a0df2efSAndy Whitcroft}
16534a0df2efSAndy Whitcroftsub ctx_block {
16544a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
16554a0df2efSAndy Whitcroft
1656f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1657f0a594c1SAndy Whitcroft	return @r;
1658653d4876SAndy Whitcroft}
1659653d4876SAndy Whitcroftsub ctx_statement {
1660f0a594c1SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
1661f0a594c1SAndy Whitcroft
1662f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1663f0a594c1SAndy Whitcroft	return @r;
1664f0a594c1SAndy Whitcroft}
1665f0a594c1SAndy Whitcroftsub ctx_block_level {
1666653d4876SAndy Whitcroft	my ($linenr, $remain) = @_;
1667653d4876SAndy Whitcroft
1668f0a594c1SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
16694a0df2efSAndy Whitcroft}
16709c0ca6f9SAndy Whitcroftsub ctx_statement_level {
16719c0ca6f9SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
16729c0ca6f9SAndy Whitcroft
16739c0ca6f9SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
16749c0ca6f9SAndy Whitcroft}
16754a0df2efSAndy Whitcroft
16764a0df2efSAndy Whitcroftsub ctx_locate_comment {
16774a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
16784a0df2efSAndy Whitcroft
16794a0df2efSAndy Whitcroft	# Catch a comment on the end of the line itself.
1680beae6332SAndy Whitcroft	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
16814a0df2efSAndy Whitcroft	return $current_comment if (defined $current_comment);
16824a0df2efSAndy Whitcroft
16834a0df2efSAndy Whitcroft	# Look through the context and try and figure out if there is a
16844a0df2efSAndy Whitcroft	# comment.
16854a0df2efSAndy Whitcroft	my $in_comment = 0;
16864a0df2efSAndy Whitcroft	$current_comment = '';
16874a0df2efSAndy Whitcroft	for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
168800df344fSAndy Whitcroft		my $line = $rawlines[$linenr - 1];
168900df344fSAndy Whitcroft		#warn "           $line\n";
16904a0df2efSAndy Whitcroft		if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
16914a0df2efSAndy Whitcroft			$in_comment = 1;
16924a0df2efSAndy Whitcroft		}
16934a0df2efSAndy Whitcroft		if ($line =~ m@/\*@) {
16944a0df2efSAndy Whitcroft			$in_comment = 1;
16954a0df2efSAndy Whitcroft		}
16964a0df2efSAndy Whitcroft		if (!$in_comment && $current_comment ne '') {
16974a0df2efSAndy Whitcroft			$current_comment = '';
16984a0df2efSAndy Whitcroft		}
16994a0df2efSAndy Whitcroft		$current_comment .= $line . "\n" if ($in_comment);
17004a0df2efSAndy Whitcroft		if ($line =~ m@\*/@) {
17014a0df2efSAndy Whitcroft			$in_comment = 0;
17024a0df2efSAndy Whitcroft		}
17034a0df2efSAndy Whitcroft	}
17044a0df2efSAndy Whitcroft
17054a0df2efSAndy Whitcroft	chomp($current_comment);
17064a0df2efSAndy Whitcroft	return($current_comment);
17074a0df2efSAndy Whitcroft}
17084a0df2efSAndy Whitcroftsub ctx_has_comment {
17094a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
17104a0df2efSAndy Whitcroft	my $cmt = ctx_locate_comment($first_line, $end_line);
17114a0df2efSAndy Whitcroft
171200df344fSAndy Whitcroft	##print "LINE: $rawlines[$end_line - 1 ]\n";
17134a0df2efSAndy Whitcroft	##print "CMMT: $cmt\n";
17144a0df2efSAndy Whitcroft
17154a0df2efSAndy Whitcroft	return ($cmt ne '');
17164a0df2efSAndy Whitcroft}
17174a0df2efSAndy Whitcroft
17184d001e4dSAndy Whitcroftsub raw_line {
17194d001e4dSAndy Whitcroft	my ($linenr, $cnt) = @_;
17204d001e4dSAndy Whitcroft
17214d001e4dSAndy Whitcroft	my $offset = $linenr - 1;
17224d001e4dSAndy Whitcroft	$cnt++;
17234d001e4dSAndy Whitcroft
17244d001e4dSAndy Whitcroft	my $line;
17254d001e4dSAndy Whitcroft	while ($cnt) {
17264d001e4dSAndy Whitcroft		$line = $rawlines[$offset++];
17274d001e4dSAndy Whitcroft		next if (defined($line) && $line =~ /^-/);
17284d001e4dSAndy Whitcroft		$cnt--;
17294d001e4dSAndy Whitcroft	}
17304d001e4dSAndy Whitcroft
17314d001e4dSAndy Whitcroft	return $line;
17324d001e4dSAndy Whitcroft}
17334d001e4dSAndy Whitcroft
17342a9f9d85STobin C. Hardingsub get_stat_real {
17352a9f9d85STobin C. Harding	my ($linenr, $lc) = @_;
17362a9f9d85STobin C. Harding
17372a9f9d85STobin C. Harding	my $stat_real = raw_line($linenr, 0);
17382a9f9d85STobin C. Harding	for (my $count = $linenr + 1; $count <= $lc; $count++) {
17392a9f9d85STobin C. Harding		$stat_real = $stat_real . "\n" . raw_line($count, 0);
17402a9f9d85STobin C. Harding	}
17412a9f9d85STobin C. Harding
17422a9f9d85STobin C. Harding	return $stat_real;
17432a9f9d85STobin C. Harding}
17442a9f9d85STobin C. Harding
1745e3d95a2aSTobin C. Hardingsub get_stat_here {
1746e3d95a2aSTobin C. Harding	my ($linenr, $cnt, $here) = @_;
1747e3d95a2aSTobin C. Harding
1748e3d95a2aSTobin C. Harding	my $herectx = $here . "\n";
1749e3d95a2aSTobin C. Harding	for (my $n = 0; $n < $cnt; $n++) {
1750e3d95a2aSTobin C. Harding		$herectx .= raw_line($linenr, $n) . "\n";
1751e3d95a2aSTobin C. Harding	}
1752e3d95a2aSTobin C. Harding
1753e3d95a2aSTobin C. Harding	return $herectx;
1754e3d95a2aSTobin C. Harding}
1755e3d95a2aSTobin C. Harding
17560a920b5bSAndy Whitcroftsub cat_vet {
17570a920b5bSAndy Whitcroft	my ($vet) = @_;
17589c0ca6f9SAndy Whitcroft	my ($res, $coded);
17590a920b5bSAndy Whitcroft
17609c0ca6f9SAndy Whitcroft	$res = '';
17616c72ffaaSAndy Whitcroft	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
17626c72ffaaSAndy Whitcroft		$res .= $1;
17636c72ffaaSAndy Whitcroft		if ($2 ne '') {
17649c0ca6f9SAndy Whitcroft			$coded = sprintf("^%c", unpack('C', $2) + 64);
17656c72ffaaSAndy Whitcroft			$res .= $coded;
17666c72ffaaSAndy Whitcroft		}
17679c0ca6f9SAndy Whitcroft	}
17689c0ca6f9SAndy Whitcroft	$res =~ s/$/\$/;
17690a920b5bSAndy Whitcroft
17709c0ca6f9SAndy Whitcroft	return $res;
17710a920b5bSAndy Whitcroft}
17720a920b5bSAndy Whitcroft
1773c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0;
1774cf655043SAndy Whitcroftmy $av_pending;
1775c2fdda0dSAndy Whitcroftmy @av_paren_type;
17761f65f947SAndy Whitcroftmy $av_pend_colon;
1777c2fdda0dSAndy Whitcroft
1778c2fdda0dSAndy Whitcroftsub annotate_reset {
1779c2fdda0dSAndy Whitcroft	$av_preprocessor = 0;
1780cf655043SAndy Whitcroft	$av_pending = '_';
1781cf655043SAndy Whitcroft	@av_paren_type = ('E');
17821f65f947SAndy Whitcroft	$av_pend_colon = 'O';
1783c2fdda0dSAndy Whitcroft}
1784c2fdda0dSAndy Whitcroft
17856c72ffaaSAndy Whitcroftsub annotate_values {
17866c72ffaaSAndy Whitcroft	my ($stream, $type) = @_;
17876c72ffaaSAndy Whitcroft
17886c72ffaaSAndy Whitcroft	my $res;
17891f65f947SAndy Whitcroft	my $var = '_' x length($stream);
17906c72ffaaSAndy Whitcroft	my $cur = $stream;
17916c72ffaaSAndy Whitcroft
1792c2fdda0dSAndy Whitcroft	print "$stream\n" if ($dbg_values > 1);
17936c72ffaaSAndy Whitcroft
17946c72ffaaSAndy Whitcroft	while (length($cur)) {
1795773647a0SAndy Whitcroft		@av_paren_type = ('E') if ($#av_paren_type < 0);
1796cf655043SAndy Whitcroft		print " <" . join('', @av_paren_type) .
1797171ae1a4SAndy Whitcroft				"> <$type> <$av_pending>" if ($dbg_values > 1);
17986c72ffaaSAndy Whitcroft		if ($cur =~ /^(\s+)/o) {
1799c2fdda0dSAndy Whitcroft			print "WS($1)\n" if ($dbg_values > 1);
1800c2fdda0dSAndy Whitcroft			if ($1 =~ /\n/ && $av_preprocessor) {
1801cf655043SAndy Whitcroft				$type = pop(@av_paren_type);
1802c2fdda0dSAndy Whitcroft				$av_preprocessor = 0;
18036c72ffaaSAndy Whitcroft			}
18046c72ffaaSAndy Whitcroft
1805c023e473SFlorian Mickler		} elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
18069446ef56SAndy Whitcroft			print "CAST($1)\n" if ($dbg_values > 1);
18079446ef56SAndy Whitcroft			push(@av_paren_type, $type);
1808addcdceaSAndy Whitcroft			$type = 'c';
18099446ef56SAndy Whitcroft
1810e91b6e26SAndy Whitcroft		} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
1811c2fdda0dSAndy Whitcroft			print "DECLARE($1)\n" if ($dbg_values > 1);
18126c72ffaaSAndy Whitcroft			$type = 'T';
18136c72ffaaSAndy Whitcroft
1814389a2fe5SAndy Whitcroft		} elsif ($cur =~ /^($Modifier)\s*/) {
1815389a2fe5SAndy Whitcroft			print "MODIFIER($1)\n" if ($dbg_values > 1);
1816389a2fe5SAndy Whitcroft			$type = 'T';
1817389a2fe5SAndy Whitcroft
1818c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
1819171ae1a4SAndy Whitcroft			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
1820c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1821171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
1822171ae1a4SAndy Whitcroft			if ($2 ne '') {
1823cf655043SAndy Whitcroft				$av_pending = 'N';
1824171ae1a4SAndy Whitcroft			}
1825171ae1a4SAndy Whitcroft			$type = 'E';
1826171ae1a4SAndy Whitcroft
1827c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
1828171ae1a4SAndy Whitcroft			print "UNDEF($1)\n" if ($dbg_values > 1);
1829171ae1a4SAndy Whitcroft			$av_preprocessor = 1;
1830171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
18316c72ffaaSAndy Whitcroft
1832c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
1833cf655043SAndy Whitcroft			print "PRE_START($1)\n" if ($dbg_values > 1);
1834c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1835cf655043SAndy Whitcroft
1836cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1837cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1838171ae1a4SAndy Whitcroft			$type = 'E';
1839cf655043SAndy Whitcroft
1840c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
1841cf655043SAndy Whitcroft			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
1842cf655043SAndy Whitcroft			$av_preprocessor = 1;
1843cf655043SAndy Whitcroft
1844cf655043SAndy Whitcroft			push(@av_paren_type, $av_paren_type[$#av_paren_type]);
1845cf655043SAndy Whitcroft
1846171ae1a4SAndy Whitcroft			$type = 'E';
1847cf655043SAndy Whitcroft
1848c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
1849cf655043SAndy Whitcroft			print "PRE_END($1)\n" if ($dbg_values > 1);
1850cf655043SAndy Whitcroft
1851cf655043SAndy Whitcroft			$av_preprocessor = 1;
1852cf655043SAndy Whitcroft
1853cf655043SAndy Whitcroft			# Assume all arms of the conditional end as this
1854cf655043SAndy Whitcroft			# one does, and continue as if the #endif was not here.
1855cf655043SAndy Whitcroft			pop(@av_paren_type);
1856cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1857171ae1a4SAndy Whitcroft			$type = 'E';
18586c72ffaaSAndy Whitcroft
18596c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\\\n)/o) {
1860c2fdda0dSAndy Whitcroft			print "PRECONT($1)\n" if ($dbg_values > 1);
18616c72ffaaSAndy Whitcroft
1862171ae1a4SAndy Whitcroft		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
1863171ae1a4SAndy Whitcroft			print "ATTR($1)\n" if ($dbg_values > 1);
1864171ae1a4SAndy Whitcroft			$av_pending = $type;
1865171ae1a4SAndy Whitcroft			$type = 'N';
1866171ae1a4SAndy Whitcroft
18676c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
1868c2fdda0dSAndy Whitcroft			print "SIZEOF($1)\n" if ($dbg_values > 1);
18696c72ffaaSAndy Whitcroft			if (defined $2) {
1870cf655043SAndy Whitcroft				$av_pending = 'V';
18716c72ffaaSAndy Whitcroft			}
18726c72ffaaSAndy Whitcroft			$type = 'N';
18736c72ffaaSAndy Whitcroft
187414b111c1SAndy Whitcroft		} elsif ($cur =~ /^(if|while|for)\b/o) {
1875c2fdda0dSAndy Whitcroft			print "COND($1)\n" if ($dbg_values > 1);
187614b111c1SAndy Whitcroft			$av_pending = 'E';
18776c72ffaaSAndy Whitcroft			$type = 'N';
18786c72ffaaSAndy Whitcroft
18791f65f947SAndy Whitcroft		} elsif ($cur =~/^(case)/o) {
18801f65f947SAndy Whitcroft			print "CASE($1)\n" if ($dbg_values > 1);
18811f65f947SAndy Whitcroft			$av_pend_colon = 'C';
18821f65f947SAndy Whitcroft			$type = 'N';
18831f65f947SAndy Whitcroft
188414b111c1SAndy Whitcroft		} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
1885c2fdda0dSAndy Whitcroft			print "KEYWORD($1)\n" if ($dbg_values > 1);
18866c72ffaaSAndy Whitcroft			$type = 'N';
18876c72ffaaSAndy Whitcroft
18886c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\()/o) {
1889c2fdda0dSAndy Whitcroft			print "PAREN('$1')\n" if ($dbg_values > 1);
1890cf655043SAndy Whitcroft			push(@av_paren_type, $av_pending);
1891cf655043SAndy Whitcroft			$av_pending = '_';
18926c72ffaaSAndy Whitcroft			$type = 'N';
18936c72ffaaSAndy Whitcroft
18946c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\))/o) {
1895cf655043SAndy Whitcroft			my $new_type = pop(@av_paren_type);
1896cf655043SAndy Whitcroft			if ($new_type ne '_') {
1897cf655043SAndy Whitcroft				$type = $new_type;
1898c2fdda0dSAndy Whitcroft				print "PAREN('$1') -> $type\n"
1899c2fdda0dSAndy Whitcroft							if ($dbg_values > 1);
19006c72ffaaSAndy Whitcroft			} else {
1901c2fdda0dSAndy Whitcroft				print "PAREN('$1')\n" if ($dbg_values > 1);
19026c72ffaaSAndy Whitcroft			}
19036c72ffaaSAndy Whitcroft
1904c8cb2ca3SAndy Whitcroft		} elsif ($cur =~ /^($Ident)\s*\(/o) {
1905c2fdda0dSAndy Whitcroft			print "FUNC($1)\n" if ($dbg_values > 1);
1906c8cb2ca3SAndy Whitcroft			$type = 'V';
1907cf655043SAndy Whitcroft			$av_pending = 'V';
19086c72ffaaSAndy Whitcroft
19098e761b04SAndy Whitcroft		} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
19108e761b04SAndy Whitcroft			if (defined $2 && $type eq 'C' || $type eq 'T') {
19111f65f947SAndy Whitcroft				$av_pend_colon = 'B';
19128e761b04SAndy Whitcroft			} elsif ($type eq 'E') {
19138e761b04SAndy Whitcroft				$av_pend_colon = 'L';
19141f65f947SAndy Whitcroft			}
19151f65f947SAndy Whitcroft			print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
19161f65f947SAndy Whitcroft			$type = 'V';
19171f65f947SAndy Whitcroft
19186c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Ident|$Constant)/o) {
1919c2fdda0dSAndy Whitcroft			print "IDENT($1)\n" if ($dbg_values > 1);
19206c72ffaaSAndy Whitcroft			$type = 'V';
19216c72ffaaSAndy Whitcroft
19226c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Assignment)/o) {
1923c2fdda0dSAndy Whitcroft			print "ASSIGN($1)\n" if ($dbg_values > 1);
19246c72ffaaSAndy Whitcroft			$type = 'N';
19256c72ffaaSAndy Whitcroft
1926cf655043SAndy Whitcroft		} elsif ($cur =~/^(;|{|})/) {
1927c2fdda0dSAndy Whitcroft			print "END($1)\n" if ($dbg_values > 1);
192813214adfSAndy Whitcroft			$type = 'E';
19291f65f947SAndy Whitcroft			$av_pend_colon = 'O';
193013214adfSAndy Whitcroft
19318e761b04SAndy Whitcroft		} elsif ($cur =~/^(,)/) {
19328e761b04SAndy Whitcroft			print "COMMA($1)\n" if ($dbg_values > 1);
19338e761b04SAndy Whitcroft			$type = 'C';
19348e761b04SAndy Whitcroft
19351f65f947SAndy Whitcroft		} elsif ($cur =~ /^(\?)/o) {
19361f65f947SAndy Whitcroft			print "QUESTION($1)\n" if ($dbg_values > 1);
19371f65f947SAndy Whitcroft			$type = 'N';
19381f65f947SAndy Whitcroft
19391f65f947SAndy Whitcroft		} elsif ($cur =~ /^(:)/o) {
19401f65f947SAndy Whitcroft			print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
19411f65f947SAndy Whitcroft
19421f65f947SAndy Whitcroft			substr($var, length($res), 1, $av_pend_colon);
19431f65f947SAndy Whitcroft			if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
19441f65f947SAndy Whitcroft				$type = 'E';
19451f65f947SAndy Whitcroft			} else {
19461f65f947SAndy Whitcroft				$type = 'N';
19471f65f947SAndy Whitcroft			}
19481f65f947SAndy Whitcroft			$av_pend_colon = 'O';
19491f65f947SAndy Whitcroft
19508e761b04SAndy Whitcroft		} elsif ($cur =~ /^(\[)/o) {
195113214adfSAndy Whitcroft			print "CLOSE($1)\n" if ($dbg_values > 1);
19526c72ffaaSAndy Whitcroft			$type = 'N';
19536c72ffaaSAndy Whitcroft
19540d413866SAndy Whitcroft		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
195574048ed8SAndy Whitcroft			my $variant;
195674048ed8SAndy Whitcroft
195774048ed8SAndy Whitcroft			print "OPV($1)\n" if ($dbg_values > 1);
195874048ed8SAndy Whitcroft			if ($type eq 'V') {
195974048ed8SAndy Whitcroft				$variant = 'B';
196074048ed8SAndy Whitcroft			} else {
196174048ed8SAndy Whitcroft				$variant = 'U';
196274048ed8SAndy Whitcroft			}
196374048ed8SAndy Whitcroft
196474048ed8SAndy Whitcroft			substr($var, length($res), 1, $variant);
196574048ed8SAndy Whitcroft			$type = 'N';
196674048ed8SAndy Whitcroft
19676c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Operators)/o) {
1968c2fdda0dSAndy Whitcroft			print "OP($1)\n" if ($dbg_values > 1);
19696c72ffaaSAndy Whitcroft			if ($1 ne '++' && $1 ne '--') {
19706c72ffaaSAndy Whitcroft				$type = 'N';
19716c72ffaaSAndy Whitcroft			}
19726c72ffaaSAndy Whitcroft
19736c72ffaaSAndy Whitcroft		} elsif ($cur =~ /(^.)/o) {
1974c2fdda0dSAndy Whitcroft			print "C($1)\n" if ($dbg_values > 1);
19756c72ffaaSAndy Whitcroft		}
19766c72ffaaSAndy Whitcroft		if (defined $1) {
19776c72ffaaSAndy Whitcroft			$cur = substr($cur, length($1));
19786c72ffaaSAndy Whitcroft			$res .= $type x length($1);
19796c72ffaaSAndy Whitcroft		}
19806c72ffaaSAndy Whitcroft	}
19816c72ffaaSAndy Whitcroft
19821f65f947SAndy Whitcroft	return ($res, $var);
19836c72ffaaSAndy Whitcroft}
19846c72ffaaSAndy Whitcroft
19858905a67cSAndy Whitcroftsub possible {
198613214adfSAndy Whitcroft	my ($possible, $line) = @_;
19879a974fdbSAndy Whitcroft	my $notPermitted = qr{(?:
19880776e594SAndy Whitcroft		^(?:
19890776e594SAndy Whitcroft			$Modifier|
19900776e594SAndy Whitcroft			$Storage|
19910776e594SAndy Whitcroft			$Type|
19929a974fdbSAndy Whitcroft			DEFINE_\S+
19939a974fdbSAndy Whitcroft		)$|
19949a974fdbSAndy Whitcroft		^(?:
19950776e594SAndy Whitcroft			goto|
19960776e594SAndy Whitcroft			return|
19970776e594SAndy Whitcroft			case|
19980776e594SAndy Whitcroft			else|
19990776e594SAndy Whitcroft			asm|__asm__|
200089a88353SAndy Whitcroft			do|
200189a88353SAndy Whitcroft			\#|
200289a88353SAndy Whitcroft			\#\#|
20039a974fdbSAndy Whitcroft		)(?:\s|$)|
20040776e594SAndy Whitcroft		^(?:typedef|struct|enum)\b
20059a974fdbSAndy Whitcroft	    )}x;
20069a974fdbSAndy Whitcroft	warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
20079a974fdbSAndy Whitcroft	if ($possible !~ $notPermitted) {
2008c45dcabdSAndy Whitcroft		# Check for modifiers.
2009c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Storage\s*//g;
2010c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Sparse\s*//g;
2011c45dcabdSAndy Whitcroft		if ($possible =~ /^\s*$/) {
2012c45dcabdSAndy Whitcroft
2013c45dcabdSAndy Whitcroft		} elsif ($possible =~ /\s/) {
2014c45dcabdSAndy Whitcroft			$possible =~ s/\s*$Type\s*//g;
2015d2506586SAndy Whitcroft			for my $modifier (split(' ', $possible)) {
20169a974fdbSAndy Whitcroft				if ($modifier !~ $notPermitted) {
2017d2506586SAndy Whitcroft					warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
2018485ff23eSAlex Dowad					push(@modifierListFile, $modifier);
2019d2506586SAndy Whitcroft				}
20209a974fdbSAndy Whitcroft			}
2021c45dcabdSAndy Whitcroft
2022c45dcabdSAndy Whitcroft		} else {
202313214adfSAndy Whitcroft			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
2024485ff23eSAlex Dowad			push(@typeListFile, $possible);
2025c45dcabdSAndy Whitcroft		}
20268905a67cSAndy Whitcroft		build_types();
20270776e594SAndy Whitcroft	} else {
20280776e594SAndy Whitcroft		warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
20298905a67cSAndy Whitcroft	}
20308905a67cSAndy Whitcroft}
20318905a67cSAndy Whitcroft
20326c72ffaaSAndy Whitcroftmy $prefix = '';
20336c72ffaaSAndy Whitcroft
2034000d1cc1SJoe Perchessub show_type {
2035cbec18afSJoe Perches	my ($type) = @_;
203691bfe484SJoe Perches
2037522b837cSAlexey Dobriyan	$type =~ tr/[a-z]/[A-Z]/;
2038522b837cSAlexey Dobriyan
2039cbec18afSJoe Perches	return defined $use_type{$type} if (scalar keys %use_type > 0);
2040cbec18afSJoe Perches
2041cbec18afSJoe Perches	return !defined $ignore_type{$type};
2042000d1cc1SJoe Perches}
2043000d1cc1SJoe Perches
2044f0a594c1SAndy Whitcroftsub report {
2045cbec18afSJoe Perches	my ($level, $type, $msg) = @_;
2046cbec18afSJoe Perches
2047cbec18afSJoe Perches	if (!show_type($type) ||
2048cbec18afSJoe Perches	    (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
2049773647a0SAndy Whitcroft		return 0;
2050773647a0SAndy Whitcroft	}
205157230297SJoe Perches	my $output = '';
2052737c0767SJohn Brooks	if ($color) {
205357230297SJoe Perches		if ($level eq 'ERROR') {
205457230297SJoe Perches			$output .= RED;
205557230297SJoe Perches		} elsif ($level eq 'WARNING') {
205657230297SJoe Perches			$output .= YELLOW;
2057000d1cc1SJoe Perches		} else {
205857230297SJoe Perches			$output .= GREEN;
2059000d1cc1SJoe Perches		}
206057230297SJoe Perches	}
206157230297SJoe Perches	$output .= $prefix . $level . ':';
206257230297SJoe Perches	if ($show_types) {
2063737c0767SJohn Brooks		$output .= BLUE if ($color);
206457230297SJoe Perches		$output .= "$type:";
206557230297SJoe Perches	}
2066737c0767SJohn Brooks	$output .= RESET if ($color);
206757230297SJoe Perches	$output .= ' ' . $msg . "\n";
206834d8815fSJoe Perches
206934d8815fSJoe Perches	if ($showfile) {
207034d8815fSJoe Perches		my @lines = split("\n", $output, -1);
207134d8815fSJoe Perches		splice(@lines, 1, 1);
207234d8815fSJoe Perches		$output = join("\n", @lines);
207334d8815fSJoe Perches	}
207457230297SJoe Perches	$output = (split('\n', $output))[0] . "\n" if ($terse);
20758905a67cSAndy Whitcroft
207657230297SJoe Perches	push(our @report, $output);
2077773647a0SAndy Whitcroft
2078773647a0SAndy Whitcroft	return 1;
2079f0a594c1SAndy Whitcroft}
2080cbec18afSJoe Perches
2081f0a594c1SAndy Whitcroftsub report_dump {
208213214adfSAndy Whitcroft	our @report;
2083f0a594c1SAndy Whitcroft}
2084000d1cc1SJoe Perches
2085d752fcc8SJoe Perchessub fixup_current_range {
2086d752fcc8SJoe Perches	my ($lineRef, $offset, $length) = @_;
2087d752fcc8SJoe Perches
2088d752fcc8SJoe Perches	if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
2089d752fcc8SJoe Perches		my $o = $1;
2090d752fcc8SJoe Perches		my $l = $2;
2091d752fcc8SJoe Perches		my $no = $o + $offset;
2092d752fcc8SJoe Perches		my $nl = $l + $length;
2093d752fcc8SJoe Perches		$$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
2094d752fcc8SJoe Perches	}
2095d752fcc8SJoe Perches}
2096d752fcc8SJoe Perches
2097d752fcc8SJoe Perchessub fix_inserted_deleted_lines {
2098d752fcc8SJoe Perches	my ($linesRef, $insertedRef, $deletedRef) = @_;
2099d752fcc8SJoe Perches
2100d752fcc8SJoe Perches	my $range_last_linenr = 0;
2101d752fcc8SJoe Perches	my $delta_offset = 0;
2102d752fcc8SJoe Perches
2103d752fcc8SJoe Perches	my $old_linenr = 0;
2104d752fcc8SJoe Perches	my $new_linenr = 0;
2105d752fcc8SJoe Perches
2106d752fcc8SJoe Perches	my $next_insert = 0;
2107d752fcc8SJoe Perches	my $next_delete = 0;
2108d752fcc8SJoe Perches
2109d752fcc8SJoe Perches	my @lines = ();
2110d752fcc8SJoe Perches
2111d752fcc8SJoe Perches	my $inserted = @{$insertedRef}[$next_insert++];
2112d752fcc8SJoe Perches	my $deleted = @{$deletedRef}[$next_delete++];
2113d752fcc8SJoe Perches
2114d752fcc8SJoe Perches	foreach my $old_line (@{$linesRef}) {
2115d752fcc8SJoe Perches		my $save_line = 1;
2116d752fcc8SJoe Perches		my $line = $old_line;	#don't modify the array
2117323b267fSJoe Perches		if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) {	#new filename
2118d752fcc8SJoe Perches			$delta_offset = 0;
2119d752fcc8SJoe Perches		} elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) {	#new hunk
2120d752fcc8SJoe Perches			$range_last_linenr = $new_linenr;
2121d752fcc8SJoe Perches			fixup_current_range(\$line, $delta_offset, 0);
2122d752fcc8SJoe Perches		}
2123d752fcc8SJoe Perches
2124d752fcc8SJoe Perches		while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
2125d752fcc8SJoe Perches			$deleted = @{$deletedRef}[$next_delete++];
2126d752fcc8SJoe Perches			$save_line = 0;
2127d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
2128d752fcc8SJoe Perches		}
2129d752fcc8SJoe Perches
2130d752fcc8SJoe Perches		while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
2131d752fcc8SJoe Perches			push(@lines, ${$inserted}{'LINE'});
2132d752fcc8SJoe Perches			$inserted = @{$insertedRef}[$next_insert++];
2133d752fcc8SJoe Perches			$new_linenr++;
2134d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
2135d752fcc8SJoe Perches		}
2136d752fcc8SJoe Perches
2137d752fcc8SJoe Perches		if ($save_line) {
2138d752fcc8SJoe Perches			push(@lines, $line);
2139d752fcc8SJoe Perches			$new_linenr++;
2140d752fcc8SJoe Perches		}
2141d752fcc8SJoe Perches
2142d752fcc8SJoe Perches		$old_linenr++;
2143d752fcc8SJoe Perches	}
2144d752fcc8SJoe Perches
2145d752fcc8SJoe Perches	return @lines;
2146d752fcc8SJoe Perches}
2147d752fcc8SJoe Perches
2148f2d7e4d4SJoe Perchessub fix_insert_line {
2149f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
2150f2d7e4d4SJoe Perches
2151f2d7e4d4SJoe Perches	my $inserted = {
2152f2d7e4d4SJoe Perches		LINENR => $linenr,
2153f2d7e4d4SJoe Perches		LINE => $line,
2154f2d7e4d4SJoe Perches	};
2155f2d7e4d4SJoe Perches	push(@fixed_inserted, $inserted);
2156f2d7e4d4SJoe Perches}
2157f2d7e4d4SJoe Perches
2158f2d7e4d4SJoe Perchessub fix_delete_line {
2159f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
2160f2d7e4d4SJoe Perches
2161f2d7e4d4SJoe Perches	my $deleted = {
2162f2d7e4d4SJoe Perches		LINENR => $linenr,
2163f2d7e4d4SJoe Perches		LINE => $line,
2164f2d7e4d4SJoe Perches	};
2165f2d7e4d4SJoe Perches
2166f2d7e4d4SJoe Perches	push(@fixed_deleted, $deleted);
2167f2d7e4d4SJoe Perches}
2168f2d7e4d4SJoe Perches
2169de7d4f0eSAndy Whitcroftsub ERROR {
2170cbec18afSJoe Perches	my ($type, $msg) = @_;
2171cbec18afSJoe Perches
2172cbec18afSJoe Perches	if (report("ERROR", $type, $msg)) {
2173de7d4f0eSAndy Whitcroft		our $clean = 0;
21746c72ffaaSAndy Whitcroft		our $cnt_error++;
21753705ce5bSJoe Perches		return 1;
2176de7d4f0eSAndy Whitcroft	}
21773705ce5bSJoe Perches	return 0;
2178773647a0SAndy Whitcroft}
2179de7d4f0eSAndy Whitcroftsub WARN {
2180cbec18afSJoe Perches	my ($type, $msg) = @_;
2181cbec18afSJoe Perches
2182cbec18afSJoe Perches	if (report("WARNING", $type, $msg)) {
2183de7d4f0eSAndy Whitcroft		our $clean = 0;
21846c72ffaaSAndy Whitcroft		our $cnt_warn++;
21853705ce5bSJoe Perches		return 1;
2186de7d4f0eSAndy Whitcroft	}
21873705ce5bSJoe Perches	return 0;
2188773647a0SAndy Whitcroft}
2189de7d4f0eSAndy Whitcroftsub CHK {
2190cbec18afSJoe Perches	my ($type, $msg) = @_;
2191cbec18afSJoe Perches
2192cbec18afSJoe Perches	if ($check && report("CHECK", $type, $msg)) {
2193de7d4f0eSAndy Whitcroft		our $clean = 0;
21946c72ffaaSAndy Whitcroft		our $cnt_chk++;
21953705ce5bSJoe Perches		return 1;
21966c72ffaaSAndy Whitcroft	}
21973705ce5bSJoe Perches	return 0;
2198de7d4f0eSAndy Whitcroft}
2199de7d4f0eSAndy Whitcroft
22006ecd9674SAndy Whitcroftsub check_absolute_file {
22016ecd9674SAndy Whitcroft	my ($absolute, $herecurr) = @_;
22026ecd9674SAndy Whitcroft	my $file = $absolute;
22036ecd9674SAndy Whitcroft
22046ecd9674SAndy Whitcroft	##print "absolute<$absolute>\n";
22056ecd9674SAndy Whitcroft
22066ecd9674SAndy Whitcroft	# See if any suffix of this path is a path within the tree.
22076ecd9674SAndy Whitcroft	while ($file =~ s@^[^/]*/@@) {
22086ecd9674SAndy Whitcroft		if (-f "$root/$file") {
22096ecd9674SAndy Whitcroft			##print "file<$file>\n";
22106ecd9674SAndy Whitcroft			last;
22116ecd9674SAndy Whitcroft		}
22126ecd9674SAndy Whitcroft	}
22136ecd9674SAndy Whitcroft	if (! -f _)  {
22146ecd9674SAndy Whitcroft		return 0;
22156ecd9674SAndy Whitcroft	}
22166ecd9674SAndy Whitcroft
22176ecd9674SAndy Whitcroft	# It is, so see if the prefix is acceptable.
22186ecd9674SAndy Whitcroft	my $prefix = $absolute;
22196ecd9674SAndy Whitcroft	substr($prefix, -length($file)) = '';
22206ecd9674SAndy Whitcroft
22216ecd9674SAndy Whitcroft	##print "prefix<$prefix>\n";
22226ecd9674SAndy Whitcroft	if ($prefix ne ".../") {
2223000d1cc1SJoe Perches		WARN("USE_RELATIVE_PATH",
2224000d1cc1SJoe Perches		     "use relative pathname instead of absolute in changelog text\n" . $herecurr);
22256ecd9674SAndy Whitcroft	}
22266ecd9674SAndy Whitcroft}
22276ecd9674SAndy Whitcroft
22283705ce5bSJoe Perchessub trim {
22293705ce5bSJoe Perches	my ($string) = @_;
22303705ce5bSJoe Perches
2231b34c648bSJoe Perches	$string =~ s/^\s+|\s+$//g;
2232b34c648bSJoe Perches
2233b34c648bSJoe Perches	return $string;
2234b34c648bSJoe Perches}
2235b34c648bSJoe Perches
2236b34c648bSJoe Perchessub ltrim {
2237b34c648bSJoe Perches	my ($string) = @_;
2238b34c648bSJoe Perches
2239b34c648bSJoe Perches	$string =~ s/^\s+//;
2240b34c648bSJoe Perches
2241b34c648bSJoe Perches	return $string;
2242b34c648bSJoe Perches}
2243b34c648bSJoe Perches
2244b34c648bSJoe Perchessub rtrim {
2245b34c648bSJoe Perches	my ($string) = @_;
2246b34c648bSJoe Perches
2247b34c648bSJoe Perches	$string =~ s/\s+$//;
22483705ce5bSJoe Perches
22493705ce5bSJoe Perches	return $string;
22503705ce5bSJoe Perches}
22513705ce5bSJoe Perches
225252ea8506SJoe Perchessub string_find_replace {
225352ea8506SJoe Perches	my ($string, $find, $replace) = @_;
225452ea8506SJoe Perches
225552ea8506SJoe Perches	$string =~ s/$find/$replace/g;
225652ea8506SJoe Perches
225752ea8506SJoe Perches	return $string;
225852ea8506SJoe Perches}
225952ea8506SJoe Perches
22603705ce5bSJoe Perchessub tabify {
22613705ce5bSJoe Perches	my ($leading) = @_;
22623705ce5bSJoe Perches
2263713a09deSAntonio Borneo	my $source_indent = $tabsize;
22643705ce5bSJoe Perches	my $max_spaces_before_tab = $source_indent - 1;
22653705ce5bSJoe Perches	my $spaces_to_tab = " " x $source_indent;
22663705ce5bSJoe Perches
22673705ce5bSJoe Perches	#convert leading spaces to tabs
22683705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
22693705ce5bSJoe Perches	#Remove spaces before a tab
22703705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
22713705ce5bSJoe Perches
22723705ce5bSJoe Perches	return "$leading";
22733705ce5bSJoe Perches}
22743705ce5bSJoe Perches
2275d1fe9c09SJoe Perchessub pos_last_openparen {
2276d1fe9c09SJoe Perches	my ($line) = @_;
2277d1fe9c09SJoe Perches
2278d1fe9c09SJoe Perches	my $pos = 0;
2279d1fe9c09SJoe Perches
2280d1fe9c09SJoe Perches	my $opens = $line =~ tr/\(/\(/;
2281d1fe9c09SJoe Perches	my $closes = $line =~ tr/\)/\)/;
2282d1fe9c09SJoe Perches
2283d1fe9c09SJoe Perches	my $last_openparen = 0;
2284d1fe9c09SJoe Perches
2285d1fe9c09SJoe Perches	if (($opens == 0) || ($closes >= $opens)) {
2286d1fe9c09SJoe Perches		return -1;
2287d1fe9c09SJoe Perches	}
2288d1fe9c09SJoe Perches
2289d1fe9c09SJoe Perches	my $len = length($line);
2290d1fe9c09SJoe Perches
2291d1fe9c09SJoe Perches	for ($pos = 0; $pos < $len; $pos++) {
2292d1fe9c09SJoe Perches		my $string = substr($line, $pos);
2293d1fe9c09SJoe Perches		if ($string =~ /^($FuncArg|$balanced_parens)/) {
2294d1fe9c09SJoe Perches			$pos += length($1) - 1;
2295d1fe9c09SJoe Perches		} elsif (substr($line, $pos, 1) eq '(') {
2296d1fe9c09SJoe Perches			$last_openparen = $pos;
2297d1fe9c09SJoe Perches		} elsif (index($string, '(') == -1) {
2298d1fe9c09SJoe Perches			last;
2299d1fe9c09SJoe Perches		}
2300d1fe9c09SJoe Perches	}
2301d1fe9c09SJoe Perches
230291cb5195SJoe Perches	return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
2303d1fe9c09SJoe Perches}
2304d1fe9c09SJoe Perches
2305f36d3eb8SJoe Perchessub get_raw_comment {
2306f36d3eb8SJoe Perches	my ($line, $rawline) = @_;
2307f36d3eb8SJoe Perches	my $comment = '';
2308f36d3eb8SJoe Perches
2309f36d3eb8SJoe Perches	for my $i (0 .. (length($line) - 1)) {
2310f36d3eb8SJoe Perches		if (substr($line, $i, 1) eq "$;") {
2311f36d3eb8SJoe Perches			$comment .= substr($rawline, $i, 1);
2312f36d3eb8SJoe Perches		}
2313f36d3eb8SJoe Perches	}
2314f36d3eb8SJoe Perches
2315f36d3eb8SJoe Perches	return $comment;
2316f36d3eb8SJoe Perches}
2317f36d3eb8SJoe Perches
23180a920b5bSAndy Whitcroftsub process {
23190a920b5bSAndy Whitcroft	my $filename = shift;
23200a920b5bSAndy Whitcroft
23210a920b5bSAndy Whitcroft	my $linenr=0;
23220a920b5bSAndy Whitcroft	my $prevline="";
2323c2fdda0dSAndy Whitcroft	my $prevrawline="";
23240a920b5bSAndy Whitcroft	my $stashline="";
2325c2fdda0dSAndy Whitcroft	my $stashrawline="";
23260a920b5bSAndy Whitcroft
23274a0df2efSAndy Whitcroft	my $length;
23280a920b5bSAndy Whitcroft	my $indent;
23290a920b5bSAndy Whitcroft	my $previndent=0;
23300a920b5bSAndy Whitcroft	my $stashindent=0;
23310a920b5bSAndy Whitcroft
2332de7d4f0eSAndy Whitcroft	our $clean = 1;
23330a920b5bSAndy Whitcroft	my $signoff = 0;
2334cd261496SGeert Uytterhoeven	my $author = '';
2335cd261496SGeert Uytterhoeven	my $authorsignoff = 0;
23360a920b5bSAndy Whitcroft	my $is_patch = 0;
2337133712a2SRob Herring	my $is_binding_patch = -1;
233829ee1b0cSJoe Perches	my $in_header_lines = $file ? 0 : 1;
233915662b3eSJoe Perches	my $in_commit_log = 0;		#Scanning lines before patch
234044d303ebSJoe Perches	my $has_patch_separator = 0;	#Found a --- line
2341ed43c4e5SAllen Hubbe	my $has_commit_log = 0;		#Encountered lines before patch
2342490b292cSJoe Perches	my $commit_log_lines = 0;	#Number of commit log lines
2343bf4daf12SJoe Perches	my $commit_log_possible_stack_dump = 0;
23442a076f40SJoe Perches	my $commit_log_long_line = 0;
2345e518e9a5SJoe Perches	my $commit_log_has_diff = 0;
234613f1937eSJoe Perches	my $reported_maintainer_file = 0;
2347fa64205dSPasi Savanainen	my $non_utf8_charset = 0;
2348fa64205dSPasi Savanainen
2349365dd4eaSJoe Perches	my $last_blank_line = 0;
23505e4f6ba5SJoe Perches	my $last_coalesced_string_linenr = -1;
2351365dd4eaSJoe Perches
235213214adfSAndy Whitcroft	our @report = ();
23536c72ffaaSAndy Whitcroft	our $cnt_lines = 0;
23546c72ffaaSAndy Whitcroft	our $cnt_error = 0;
23556c72ffaaSAndy Whitcroft	our $cnt_warn = 0;
23566c72ffaaSAndy Whitcroft	our $cnt_chk = 0;
23576c72ffaaSAndy Whitcroft
23580a920b5bSAndy Whitcroft	# Trace the real file/line as we go.
23590a920b5bSAndy Whitcroft	my $realfile = '';
23600a920b5bSAndy Whitcroft	my $realline = 0;
23610a920b5bSAndy Whitcroft	my $realcnt = 0;
23620a920b5bSAndy Whitcroft	my $here = '';
236377cb8546SJoe Perches	my $context_function;		#undef'd unless there's a known function
23640a920b5bSAndy Whitcroft	my $in_comment = 0;
2365c2fdda0dSAndy Whitcroft	my $comment_edge = 0;
23660a920b5bSAndy Whitcroft	my $first_line = 0;
23671e855726SWolfram Sang	my $p1_prefix = '';
23680a920b5bSAndy Whitcroft
236913214adfSAndy Whitcroft	my $prev_values = 'E';
237013214adfSAndy Whitcroft
237113214adfSAndy Whitcroft	# suppression flags
2372773647a0SAndy Whitcroft	my %suppress_ifbraces;
2373170d3a22SAndy Whitcroft	my %suppress_whiletrailers;
23742b474a1aSAndy Whitcroft	my %suppress_export;
23753e469cdcSAndy Whitcroft	my $suppress_statement = 0;
2376653d4876SAndy Whitcroft
23777e51f197SJoe Perches	my %signatures = ();
2378323c1260SJoe Perches
2379c2fdda0dSAndy Whitcroft	# Pre-scan the patch sanitizing the lines.
2380de7d4f0eSAndy Whitcroft	# Pre-scan the patch looking for any __setup documentation.
2381c2fdda0dSAndy Whitcroft	#
2382de7d4f0eSAndy Whitcroft	my @setup_docs = ();
2383de7d4f0eSAndy Whitcroft	my $setup_docs = 0;
2384773647a0SAndy Whitcroft
2385d8b07710SJoe Perches	my $camelcase_file_seeded = 0;
2386d8b07710SJoe Perches
23879f3a8992SRob Herring	my $checklicenseline = 1;
23889f3a8992SRob Herring
2389773647a0SAndy Whitcroft	sanitise_line_reset();
2390c2fdda0dSAndy Whitcroft	my $line;
2391c2fdda0dSAndy Whitcroft	foreach my $rawline (@rawlines) {
2392773647a0SAndy Whitcroft		$linenr++;
2393773647a0SAndy Whitcroft		$line = $rawline;
2394c2fdda0dSAndy Whitcroft
23953705ce5bSJoe Perches		push(@fixed, $rawline) if ($fix);
23963705ce5bSJoe Perches
2397773647a0SAndy Whitcroft		if ($rawline=~/^\+\+\+\s+(\S+)/) {
2398de7d4f0eSAndy Whitcroft			$setup_docs = 0;
23998c27ceffSMauro Carvalho Chehab			if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) {
2400de7d4f0eSAndy Whitcroft				$setup_docs = 1;
2401de7d4f0eSAndy Whitcroft			}
2402773647a0SAndy Whitcroft			#next;
2403de7d4f0eSAndy Whitcroft		}
240474fd4f34SJoe Perches		if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
2405773647a0SAndy Whitcroft			$realline=$1-1;
2406773647a0SAndy Whitcroft			if (defined $2) {
2407773647a0SAndy Whitcroft				$realcnt=$3+1;
2408773647a0SAndy Whitcroft			} else {
2409773647a0SAndy Whitcroft				$realcnt=1+1;
2410773647a0SAndy Whitcroft			}
2411c45dcabdSAndy Whitcroft			$in_comment = 0;
2412773647a0SAndy Whitcroft
2413773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  Run
2414773647a0SAndy Whitcroft			# the context looking for a comment "edge".  If this
2415773647a0SAndy Whitcroft			# edge is a close comment then we must be in a comment
2416773647a0SAndy Whitcroft			# at context start.
2417773647a0SAndy Whitcroft			my $edge;
241801fa9147SAndy Whitcroft			my $cnt = $realcnt;
241901fa9147SAndy Whitcroft			for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
242001fa9147SAndy Whitcroft				next if (defined $rawlines[$ln - 1] &&
242101fa9147SAndy Whitcroft					 $rawlines[$ln - 1] =~ /^-/);
242201fa9147SAndy Whitcroft				$cnt--;
242301fa9147SAndy Whitcroft				#print "RAW<$rawlines[$ln - 1]>\n";
2424721c1cb6SAndy Whitcroft				last if (!defined $rawlines[$ln - 1]);
2425fae17daeSAndy Whitcroft				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
2426fae17daeSAndy Whitcroft				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
2427fae17daeSAndy Whitcroft					($edge) = $1;
2428fae17daeSAndy Whitcroft					last;
2429fae17daeSAndy Whitcroft				}
2430773647a0SAndy Whitcroft			}
2431773647a0SAndy Whitcroft			if (defined $edge && $edge eq '*/') {
2432773647a0SAndy Whitcroft				$in_comment = 1;
2433773647a0SAndy Whitcroft			}
2434773647a0SAndy Whitcroft
2435773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  If this
2436773647a0SAndy Whitcroft			# is the start of a diff block and this line starts
2437773647a0SAndy Whitcroft			# ' *' then it is very likely a comment.
2438773647a0SAndy Whitcroft			if (!defined $edge &&
243983242e0cSAndy Whitcroft			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
2440773647a0SAndy Whitcroft			{
2441773647a0SAndy Whitcroft				$in_comment = 1;
2442773647a0SAndy Whitcroft			}
2443773647a0SAndy Whitcroft
2444773647a0SAndy Whitcroft			##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2445773647a0SAndy Whitcroft			sanitise_line_reset($in_comment);
2446773647a0SAndy Whitcroft
2447171ae1a4SAndy Whitcroft		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
2448773647a0SAndy Whitcroft			# Standardise the strings and chars within the input to
2449171ae1a4SAndy Whitcroft			# simplify matching -- only bother with positive lines.
2450773647a0SAndy Whitcroft			$line = sanitise_line($rawline);
2451773647a0SAndy Whitcroft		}
2452773647a0SAndy Whitcroft		push(@lines, $line);
2453773647a0SAndy Whitcroft
2454773647a0SAndy Whitcroft		if ($realcnt > 1) {
2455773647a0SAndy Whitcroft			$realcnt-- if ($line =~ /^(?:\+| |$)/);
2456773647a0SAndy Whitcroft		} else {
2457773647a0SAndy Whitcroft			$realcnt = 0;
2458773647a0SAndy Whitcroft		}
2459773647a0SAndy Whitcroft
2460773647a0SAndy Whitcroft		#print "==>$rawline\n";
2461773647a0SAndy Whitcroft		#print "-->$line\n";
2462de7d4f0eSAndy Whitcroft
2463de7d4f0eSAndy Whitcroft		if ($setup_docs && $line =~ /^\+/) {
2464de7d4f0eSAndy Whitcroft			push(@setup_docs, $line);
2465de7d4f0eSAndy Whitcroft		}
2466de7d4f0eSAndy Whitcroft	}
2467de7d4f0eSAndy Whitcroft
24686c72ffaaSAndy Whitcroft	$prefix = '';
24696c72ffaaSAndy Whitcroft
2470773647a0SAndy Whitcroft	$realcnt = 0;
2471773647a0SAndy Whitcroft	$linenr = 0;
2472194f66fcSJoe Perches	$fixlinenr = -1;
24730a920b5bSAndy Whitcroft	foreach my $line (@lines) {
24740a920b5bSAndy Whitcroft		$linenr++;
2475194f66fcSJoe Perches		$fixlinenr++;
24761b5539b1SJoe Perches		my $sline = $line;	#copy of $line
24771b5539b1SJoe Perches		$sline =~ s/$;/ /g;	#with comments as spaces
24780a920b5bSAndy Whitcroft
2479c2fdda0dSAndy Whitcroft		my $rawline = $rawlines[$linenr - 1];
2480f36d3eb8SJoe Perches		my $raw_comment = get_raw_comment($line, $rawline);
24816c72ffaaSAndy Whitcroft
248212c253abSJoe Perches# check if it's a mode change, rename or start of a patch
248312c253abSJoe Perches		if (!$in_commit_log &&
248412c253abSJoe Perches		    ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ ||
248512c253abSJoe Perches		    ($line =~ /^rename (?:from|to) \S+\s*$/ ||
248612c253abSJoe Perches		     $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) {
248712c253abSJoe Perches			$is_patch = 1;
248812c253abSJoe Perches		}
248912c253abSJoe Perches
24900a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied
2491e518e9a5SJoe Perches		if (!$in_commit_log &&
249274fd4f34SJoe Perches		    $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
249374fd4f34SJoe Perches			my $context = $4;
24940a920b5bSAndy Whitcroft			$is_patch = 1;
24954a0df2efSAndy Whitcroft			$first_line = $linenr + 1;
24960a920b5bSAndy Whitcroft			$realline=$1-1;
24970a920b5bSAndy Whitcroft			if (defined $2) {
24980a920b5bSAndy Whitcroft				$realcnt=$3+1;
24990a920b5bSAndy Whitcroft			} else {
25000a920b5bSAndy Whitcroft				$realcnt=1+1;
25010a920b5bSAndy Whitcroft			}
2502c2fdda0dSAndy Whitcroft			annotate_reset();
250313214adfSAndy Whitcroft			$prev_values = 'E';
250413214adfSAndy Whitcroft
2505773647a0SAndy Whitcroft			%suppress_ifbraces = ();
2506170d3a22SAndy Whitcroft			%suppress_whiletrailers = ();
25072b474a1aSAndy Whitcroft			%suppress_export = ();
25083e469cdcSAndy Whitcroft			$suppress_statement = 0;
250974fd4f34SJoe Perches			if ($context =~ /\b(\w+)\s*\(/) {
251074fd4f34SJoe Perches				$context_function = $1;
251174fd4f34SJoe Perches			} else {
251274fd4f34SJoe Perches				undef $context_function;
251374fd4f34SJoe Perches			}
25140a920b5bSAndy Whitcroft			next;
25150a920b5bSAndy Whitcroft
25164a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that
25174a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely
25184a0df2efSAndy Whitcroft# blank context lines so we need to count that too.
2519773647a0SAndy Whitcroft		} elsif ($line =~ /^( |\+|$)/) {
25200a920b5bSAndy Whitcroft			$realline++;
2521d8aaf121SAndy Whitcroft			$realcnt-- if ($realcnt != 0);
25220a920b5bSAndy Whitcroft
25234a0df2efSAndy Whitcroft			# Measure the line length and indent.
2524c2fdda0dSAndy Whitcroft			($length, $indent) = line_stats($rawline);
25250a920b5bSAndy Whitcroft
25260a920b5bSAndy Whitcroft			# Track the previous line.
25270a920b5bSAndy Whitcroft			($prevline, $stashline) = ($stashline, $line);
25280a920b5bSAndy Whitcroft			($previndent, $stashindent) = ($stashindent, $indent);
2529c2fdda0dSAndy Whitcroft			($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2530c2fdda0dSAndy Whitcroft
2531773647a0SAndy Whitcroft			#warn "line<$line>\n";
25326c72ffaaSAndy Whitcroft
2533d8aaf121SAndy Whitcroft		} elsif ($realcnt == 1) {
2534d8aaf121SAndy Whitcroft			$realcnt--;
25350a920b5bSAndy Whitcroft		}
25360a920b5bSAndy Whitcroft
2537cc77cdcaSAndy Whitcroft		my $hunk_line = ($realcnt != 0);
2538cc77cdcaSAndy Whitcroft
25396c72ffaaSAndy Whitcroft		$here = "#$linenr: " if (!$file);
25406c72ffaaSAndy Whitcroft		$here = "#$realline: " if ($file);
2541773647a0SAndy Whitcroft
25422ac73b4fSJoe Perches		my $found_file = 0;
2543773647a0SAndy Whitcroft		# extract the filename as it passes
25443bf9a009SRabin Vincent		if ($line =~ /^diff --git.*?(\S+)$/) {
25453bf9a009SRabin Vincent			$realfile = $1;
25462b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2547270c49a0SJoe Perches			$in_commit_log = 0;
25482ac73b4fSJoe Perches			$found_file = 1;
25493bf9a009SRabin Vincent		} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
2550773647a0SAndy Whitcroft			$realfile = $1;
25512b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2552270c49a0SJoe Perches			$in_commit_log = 0;
25531e855726SWolfram Sang
25541e855726SWolfram Sang			$p1_prefix = $1;
2555e2f7aa4bSAndy Whitcroft			if (!$file && $tree && $p1_prefix ne '' &&
2556e2f7aa4bSAndy Whitcroft			    -e "$root/$p1_prefix") {
2557000d1cc1SJoe Perches				WARN("PATCH_PREFIX",
2558000d1cc1SJoe Perches				     "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
25591e855726SWolfram Sang			}
2560773647a0SAndy Whitcroft
2561c1ab3326SAndy Whitcroft			if ($realfile =~ m@^include/asm/@) {
2562000d1cc1SJoe Perches				ERROR("MODIFIED_INCLUDE_ASM",
2563000d1cc1SJoe Perches				      "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
2564773647a0SAndy Whitcroft			}
25652ac73b4fSJoe Perches			$found_file = 1;
25662ac73b4fSJoe Perches		}
25672ac73b4fSJoe Perches
256834d8815fSJoe Perches#make up the handle for any error we report on this line
256934d8815fSJoe Perches		if ($showfile) {
257034d8815fSJoe Perches			$prefix = "$realfile:$realline: "
257134d8815fSJoe Perches		} elsif ($emacs) {
25727d3a9f67SJoe Perches			if ($file) {
25737d3a9f67SJoe Perches				$prefix = "$filename:$realline: ";
25747d3a9f67SJoe Perches			} else {
257534d8815fSJoe Perches				$prefix = "$filename:$linenr: ";
257634d8815fSJoe Perches			}
25777d3a9f67SJoe Perches		}
257834d8815fSJoe Perches
25792ac73b4fSJoe Perches		if ($found_file) {
258085b0ee18SJoe Perches			if (is_maintained_obsolete($realfile)) {
258185b0ee18SJoe Perches				WARN("OBSOLETE",
258285b0ee18SJoe Perches				     "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.\n");
258385b0ee18SJoe Perches			}
25847bd7e483SJoe Perches			if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
25852ac73b4fSJoe Perches				$check = 1;
25862ac73b4fSJoe Perches			} else {
25872ac73b4fSJoe Perches				$check = $check_orig;
25882ac73b4fSJoe Perches			}
25899f3a8992SRob Herring			$checklicenseline = 1;
2590133712a2SRob Herring
2591133712a2SRob Herring			if ($realfile !~ /^MAINTAINERS/) {
2592133712a2SRob Herring				my $last_binding_patch = $is_binding_patch;
2593133712a2SRob Herring
2594133712a2SRob Herring				$is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;
2595133712a2SRob Herring
2596133712a2SRob Herring				if (($last_binding_patch != -1) &&
2597133712a2SRob Herring				    ($last_binding_patch ^ $is_binding_patch)) {
2598133712a2SRob Herring					WARN("DT_SPLIT_BINDING_PATCH",
2599133712a2SRob Herring					     "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.txt\n");
2600133712a2SRob Herring				}
2601133712a2SRob Herring			}
2602133712a2SRob Herring
2603773647a0SAndy Whitcroft			next;
2604773647a0SAndy Whitcroft		}
2605773647a0SAndy Whitcroft
2606389834b6SRandy Dunlap		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
26070a920b5bSAndy Whitcroft
2608c2fdda0dSAndy Whitcroft		my $hereline = "$here\n$rawline\n";
2609c2fdda0dSAndy Whitcroft		my $herecurr = "$here\n$rawline\n";
2610c2fdda0dSAndy Whitcroft		my $hereprev = "$here\n$prevrawline\n$rawline\n";
26110a920b5bSAndy Whitcroft
26126c72ffaaSAndy Whitcroft		$cnt_lines++ if ($realcnt != 0);
26136c72ffaaSAndy Whitcroft
2614490b292cSJoe Perches# Verify the existence of a commit log if appropriate
2615490b292cSJoe Perches# 2 is used because a $signature is counted in $commit_log_lines
2616490b292cSJoe Perches		if ($in_commit_log) {
2617490b292cSJoe Perches			if ($line !~ /^\s*$/) {
2618490b292cSJoe Perches				$commit_log_lines++;	#could be a $signature
2619490b292cSJoe Perches			}
2620490b292cSJoe Perches		} elsif ($has_commit_log && $commit_log_lines < 2) {
2621490b292cSJoe Perches			WARN("COMMIT_MESSAGE",
2622490b292cSJoe Perches			     "Missing commit description - Add an appropriate one\n");
2623490b292cSJoe Perches			$commit_log_lines = 2;	#warn only once
2624490b292cSJoe Perches		}
2625490b292cSJoe Perches
2626e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch
2627e518e9a5SJoe Perches		if ($in_commit_log && !$commit_log_has_diff &&
2628e518e9a5SJoe Perches		    (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&
2629e518e9a5SJoe Perches		      $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||
2630e518e9a5SJoe Perches		     $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
2631e518e9a5SJoe Perches		     $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
2632e518e9a5SJoe Perches			ERROR("DIFF_IN_COMMIT_MSG",
2633e518e9a5SJoe Perches			      "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
2634e518e9a5SJoe Perches			$commit_log_has_diff = 1;
2635e518e9a5SJoe Perches		}
2636e518e9a5SJoe Perches
26373bf9a009SRabin Vincent# Check for incorrect file permissions
26383bf9a009SRabin Vincent		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
26393bf9a009SRabin Vincent			my $permhere = $here . "FILE: $realfile\n";
264004db4d25SJoe Perches			if ($realfile !~ m@scripts/@ &&
264104db4d25SJoe Perches			    $realfile !~ /\.(py|pl|awk|sh)$/) {
2642000d1cc1SJoe Perches				ERROR("EXECUTE_PERMISSIONS",
2643000d1cc1SJoe Perches				      "do not set execute permissions for source files\n" . $permhere);
26443bf9a009SRabin Vincent			}
26453bf9a009SRabin Vincent		}
26463bf9a009SRabin Vincent
2647cd261496SGeert Uytterhoeven# Check the patch for a From:
2648cd261496SGeert Uytterhoeven		if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
2649cd261496SGeert Uytterhoeven			$author = $1;
2650cd261496SGeert Uytterhoeven			$author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
2651cd261496SGeert Uytterhoeven			$author =~ s/"//g;
2652dfa05c28SJoe Perches			$author = reformat_email($author);
2653cd261496SGeert Uytterhoeven		}
2654cd261496SGeert Uytterhoeven
265520112475SJoe Perches# Check the patch for a signoff:
2656dfa05c28SJoe Perches		if ($line =~ /^\s*signed-off-by:\s*(.*)/i) {
26574a0df2efSAndy Whitcroft			$signoff++;
265815662b3eSJoe Perches			$in_commit_log = 0;
2659cd261496SGeert Uytterhoeven			if ($author ne '') {
2660dfa05c28SJoe Perches				if (same_email_addresses($1, $author)) {
2661cd261496SGeert Uytterhoeven					$authorsignoff = 1;
2662cd261496SGeert Uytterhoeven				}
2663cd261496SGeert Uytterhoeven			}
26640a920b5bSAndy Whitcroft		}
266520112475SJoe Perches
266644d303ebSJoe Perches# Check for patch separator
266744d303ebSJoe Perches		if ($line =~ /^---$/) {
266844d303ebSJoe Perches			$has_patch_separator = 1;
266944d303ebSJoe Perches			$in_commit_log = 0;
267044d303ebSJoe Perches		}
267144d303ebSJoe Perches
2672e0d975b1SJoe Perches# Check if MAINTAINERS is being updated.  If so, there's probably no need to
2673e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete
2674e0d975b1SJoe Perches		if ($line =~ /^\s*MAINTAINERS\s*\|/) {
2675e0d975b1SJoe Perches			$reported_maintainer_file = 1;
2676e0d975b1SJoe Perches		}
2677e0d975b1SJoe Perches
267820112475SJoe Perches# Check signature styles
2679270c49a0SJoe Perches		if (!$in_header_lines &&
2680ce0338dfSJoe Perches		    $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
268120112475SJoe Perches			my $space_before = $1;
268220112475SJoe Perches			my $sign_off = $2;
268320112475SJoe Perches			my $space_after = $3;
268420112475SJoe Perches			my $email = $4;
268520112475SJoe Perches			my $ucfirst_sign_off = ucfirst(lc($sign_off));
268620112475SJoe Perches
2687ce0338dfSJoe Perches			if ($sign_off !~ /$signature_tags/) {
2688ce0338dfSJoe Perches				WARN("BAD_SIGN_OFF",
2689ce0338dfSJoe Perches				     "Non-standard signature: $sign_off\n" . $herecurr);
2690ce0338dfSJoe Perches			}
269120112475SJoe Perches			if (defined $space_before && $space_before ne "") {
26923705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
26933705ce5bSJoe Perches					 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
26943705ce5bSJoe Perches				    $fix) {
2695194f66fcSJoe Perches					$fixed[$fixlinenr] =
26963705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
26973705ce5bSJoe Perches				}
269820112475SJoe Perches			}
269920112475SJoe Perches			if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
27003705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
27013705ce5bSJoe Perches					 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
27023705ce5bSJoe Perches				    $fix) {
2703194f66fcSJoe Perches					$fixed[$fixlinenr] =
27043705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
27053705ce5bSJoe Perches				}
27063705ce5bSJoe Perches
270720112475SJoe Perches			}
270820112475SJoe Perches			if (!defined $space_after || $space_after ne " ") {
27093705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
27103705ce5bSJoe Perches					 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
27113705ce5bSJoe Perches				    $fix) {
2712194f66fcSJoe Perches					$fixed[$fixlinenr] =
27133705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
27143705ce5bSJoe Perches				}
271520112475SJoe Perches			}
271620112475SJoe Perches
2717dfa05c28SJoe Perches			my ($email_name, $name_comment, $email_address, $comment) = parse_email($email);
271820112475SJoe Perches			my $suggested_email = format_email(($email_name, $email_address));
271920112475SJoe Perches			if ($suggested_email eq "") {
2720000d1cc1SJoe Perches				ERROR("BAD_SIGN_OFF",
2721000d1cc1SJoe Perches				      "Unrecognized email address: '$email'\n" . $herecurr);
272220112475SJoe Perches			} else {
272320112475SJoe Perches				my $dequoted = $suggested_email;
272420112475SJoe Perches				$dequoted =~ s/^"//;
272520112475SJoe Perches				$dequoted =~ s/" </ </;
272620112475SJoe Perches				# Don't force email to have quotes
272720112475SJoe Perches				# Allow just an angle bracketed address
2728dfa05c28SJoe Perches				if (!same_email_addresses($email, $suggested_email)) {
2729000d1cc1SJoe Perches					WARN("BAD_SIGN_OFF",
2730000d1cc1SJoe Perches					     "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
273120112475SJoe Perches				}
27320a920b5bSAndy Whitcroft			}
27337e51f197SJoe Perches
27347e51f197SJoe Perches# Check for duplicate signatures
27357e51f197SJoe Perches			my $sig_nospace = $line;
27367e51f197SJoe Perches			$sig_nospace =~ s/\s//g;
27377e51f197SJoe Perches			$sig_nospace = lc($sig_nospace);
27387e51f197SJoe Perches			if (defined $signatures{$sig_nospace}) {
27397e51f197SJoe Perches				WARN("BAD_SIGN_OFF",
27407e51f197SJoe Perches				     "Duplicate signature\n" . $herecurr);
27417e51f197SJoe Perches			} else {
27427e51f197SJoe Perches				$signatures{$sig_nospace} = 1;
27437e51f197SJoe Perches			}
27446c5d24eeSSean Christopherson
27456c5d24eeSSean Christopherson# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email
27466c5d24eeSSean Christopherson			if ($sign_off =~ /^co-developed-by:$/i) {
27476c5d24eeSSean Christopherson				if ($email eq $author) {
27486c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
27496c5d24eeSSean Christopherson					      "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline);
27506c5d24eeSSean Christopherson				}
27516c5d24eeSSean Christopherson				if (!defined $lines[$linenr]) {
27526c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
27536c5d24eeSSean Christopherson                                             "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);
27546c5d24eeSSean Christopherson				} elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {
27556c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
27566c5d24eeSSean Christopherson					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
27576c5d24eeSSean Christopherson				} elsif ($1 ne $email) {
27586c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
27596c5d24eeSSean Christopherson					     "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
27606c5d24eeSSean Christopherson				}
27616c5d24eeSSean Christopherson			}
27620a920b5bSAndy Whitcroft		}
27630a920b5bSAndy Whitcroft
2764a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned
2765a2fe16b9SJoe Perches		if ($in_header_lines &&
2766a2fe16b9SJoe Perches		    $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
2767a2fe16b9SJoe Perches			WARN("EMAIL_SUBJECT",
2768a2fe16b9SJoe Perches			     "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
2769a2fe16b9SJoe Perches		}
2770a2fe16b9SJoe Perches
277144d303ebSJoe Perches# Check for Gerrit Change-Ids not in any patch context
277244d303ebSJoe Perches		if ($realfile eq '' && !$has_patch_separator && $line =~ /^\s*change-id:/i) {
27737ebd05efSChristopher Covington			ERROR("GERRIT_CHANGE_ID",
277444d303ebSJoe Perches			      "Remove Gerrit Change-Id's before submitting upstream\n" . $herecurr);
27757ebd05efSChristopher Covington		}
27767ebd05efSChristopher Covington
2777369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump
2778369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
2779369c8dd3SJoe Perches		    ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
2780369c8dd3SJoe Perches		     $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
2781369c8dd3SJoe Perches					# timestamp
2782634cffccSJoe Perches		     $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) ||
2783634cffccSJoe Perches		     $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ ||
2784634cffccSJoe Perches		     $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) {
2785634cffccSJoe Perches					# stack dump address styles
2786369c8dd3SJoe Perches			$commit_log_possible_stack_dump = 1;
2787369c8dd3SJoe Perches		}
2788369c8dd3SJoe Perches
27892a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once
27902a076f40SJoe Perches		if ($in_commit_log && !$commit_log_long_line &&
2791bf4daf12SJoe Perches		    length($line) > 75 &&
2792bf4daf12SJoe Perches		    !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
2793bf4daf12SJoe Perches					# file delta changes
2794bf4daf12SJoe Perches		      $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||
2795bf4daf12SJoe Perches					# filename then :
2796bf4daf12SJoe Perches		      $line =~ /^\s*(?:Fixes:|Link:)/i ||
2797bf4daf12SJoe Perches					# A Fixes: or Link: line
2798bf4daf12SJoe Perches		      $commit_log_possible_stack_dump)) {
27992a076f40SJoe Perches			WARN("COMMIT_LOG_LONG_LINE",
28002a076f40SJoe Perches			     "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
28012a076f40SJoe Perches			$commit_log_long_line = 1;
28022a076f40SJoe Perches		}
28032a076f40SJoe Perches
2804bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found
2805bf4daf12SJoe Perches		if ($in_commit_log && $commit_log_possible_stack_dump &&
2806bf4daf12SJoe Perches		    $line =~ /^\s*$/) {
2807bf4daf12SJoe Perches			$commit_log_possible_stack_dump = 0;
2808bf4daf12SJoe Perches		}
2809bf4daf12SJoe Perches
28100d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions
2811369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
2812a8972573SJohn Hubbard		    $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink|base-commit):/i &&
2813e882dbfcSWei Wang		    $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
2814fe043ea1SJoe Perches		    ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
2815aab38f51SJoe Perches		     ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
2816369c8dd3SJoe Perches		      $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
2817bf4daf12SJoe Perches		      $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
2818fe043ea1SJoe Perches			my $init_char = "c";
2819fe043ea1SJoe Perches			my $orig_commit = "";
28200d7835fcSJoe Perches			my $short = 1;
28210d7835fcSJoe Perches			my $long = 0;
28220d7835fcSJoe Perches			my $case = 1;
28230d7835fcSJoe Perches			my $space = 1;
28240d7835fcSJoe Perches			my $hasdesc = 0;
282519c146a6SJoe Perches			my $hasparens = 0;
28260d7835fcSJoe Perches			my $id = '0123456789ab';
28270d7835fcSJoe Perches			my $orig_desc = "commit description";
28280d7835fcSJoe Perches			my $description = "";
28290d7835fcSJoe Perches
2830fe043ea1SJoe Perches			if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
2831fe043ea1SJoe Perches				$init_char = $1;
2832fe043ea1SJoe Perches				$orig_commit = lc($2);
2833fe043ea1SJoe Perches			} elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {
2834fe043ea1SJoe Perches				$orig_commit = lc($1);
2835fe043ea1SJoe Perches			}
2836fe043ea1SJoe Perches
28370d7835fcSJoe Perches			$short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);
28380d7835fcSJoe Perches			$long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);
28390d7835fcSJoe Perches			$space = 0 if ($line =~ /\bcommit [0-9a-f]/i);
28400d7835fcSJoe Perches			$case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
28410d7835fcSJoe Perches			if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) {
28420d7835fcSJoe Perches				$orig_desc = $1;
284319c146a6SJoe Perches				$hasparens = 1;
28440d7835fcSJoe Perches			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i &&
28450d7835fcSJoe Perches				 defined $rawlines[$linenr] &&
28460d7835fcSJoe Perches				 $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) {
28470d7835fcSJoe Perches				$orig_desc = $1;
284819c146a6SJoe Perches				$hasparens = 1;
2849b671fde0SJoe Perches			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i &&
2850b671fde0SJoe Perches				 defined $rawlines[$linenr] &&
2851b671fde0SJoe Perches				 $rawlines[$linenr] =~ /^\s*[^"]+"\)/) {
2852b671fde0SJoe Perches				$line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i;
2853b671fde0SJoe Perches				$orig_desc = $1;
2854b671fde0SJoe Perches				$rawlines[$linenr] =~ /^\s*([^"]+)"\)/;
2855b671fde0SJoe Perches				$orig_desc .= " " . $1;
285619c146a6SJoe Perches				$hasparens = 1;
28570d7835fcSJoe Perches			}
28580d7835fcSJoe Perches
28590d7835fcSJoe Perches			($id, $description) = git_commit_info($orig_commit,
28600d7835fcSJoe Perches							      $id, $orig_desc);
28610d7835fcSJoe Perches
2862948b133aSHeinrich Schuchardt			if (defined($id) &&
2863948b133aSHeinrich Schuchardt			   ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) {
2864d311cd44SJoe Perches				ERROR("GIT_COMMIT_ID",
28650d7835fcSJoe Perches				      "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);
28660d7835fcSJoe Perches			}
2867d311cd44SJoe Perches		}
2868d311cd44SJoe Perches
286913f1937eSJoe Perches# Check for added, moved or deleted files
287013f1937eSJoe Perches		if (!$reported_maintainer_file && !$in_commit_log &&
287113f1937eSJoe Perches		    ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
287213f1937eSJoe Perches		     $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
287313f1937eSJoe Perches		     ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
287413f1937eSJoe Perches		      (defined($1) || defined($2))))) {
2875a82603a8SAndrew Jeffery			$is_patch = 1;
287613f1937eSJoe Perches			$reported_maintainer_file = 1;
287713f1937eSJoe Perches			WARN("FILE_PATH_CHANGES",
287813f1937eSJoe Perches			     "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
287913f1937eSJoe Perches		}
288013f1937eSJoe Perches
2881e400edb1SRob Herring# Check for adding new DT bindings not in schema format
2882e400edb1SRob Herring		if (!$in_commit_log &&
2883e400edb1SRob Herring		    ($line =~ /^new file mode\s*\d+\s*$/) &&
2884e400edb1SRob Herring		    ($realfile =~ m@^Documentation/devicetree/bindings/.*\.txt$@)) {
2885e400edb1SRob Herring			WARN("DT_SCHEMA_BINDING_PATCH",
2886e400edb1SRob Herring			     "DT bindings should be in DT schema format. See: Documentation/devicetree/writing-schema.rst\n");
2887e400edb1SRob Herring		}
2888e400edb1SRob Herring
288900df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file
28908905a67cSAndy Whitcroft		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
2891000d1cc1SJoe Perches			ERROR("CORRUPTED_PATCH",
2892000d1cc1SJoe Perches			      "patch seems to be corrupt (line wrapped?)\n" .
28936c72ffaaSAndy Whitcroft				$herecurr) if (!$emitted_corrupt++);
2894de7d4f0eSAndy Whitcroft		}
2895de7d4f0eSAndy Whitcroft
2896de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
2897de7d4f0eSAndy Whitcroft		if (($realfile =~ /^$/ || $line =~ /^\+/) &&
2898171ae1a4SAndy Whitcroft		    $rawline !~ m/^$UTF8*$/) {
2899171ae1a4SAndy Whitcroft			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
2900171ae1a4SAndy Whitcroft
2901171ae1a4SAndy Whitcroft			my $blank = copy_spacing($rawline);
2902171ae1a4SAndy Whitcroft			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
2903171ae1a4SAndy Whitcroft			my $hereptr = "$hereline$ptr\n";
2904171ae1a4SAndy Whitcroft
290534d99219SJoe Perches			CHK("INVALID_UTF8",
2906000d1cc1SJoe Perches			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
290700df344fSAndy Whitcroft		}
29080a920b5bSAndy Whitcroft
290915662b3eSJoe Perches# Check if it's the start of a commit log
291015662b3eSJoe Perches# (not a header line and we haven't seen the patch filename)
291115662b3eSJoe Perches		if ($in_header_lines && $realfile =~ /^$/ &&
2912eb3a58deSJoe Perches		    !($rawline =~ /^\s+(?:\S|$)/ ||
2913eb3a58deSJoe Perches		      $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
291415662b3eSJoe Perches			$in_header_lines = 0;
291515662b3eSJoe Perches			$in_commit_log = 1;
2916ed43c4e5SAllen Hubbe			$has_commit_log = 1;
291715662b3eSJoe Perches		}
291815662b3eSJoe Perches
2919fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly
2920fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing.
2921fa64205dSPasi Savanainen		if ($in_header_lines &&
2922fa64205dSPasi Savanainen		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
2923fa64205dSPasi Savanainen		    $1 !~ /utf-8/i) {
2924fa64205dSPasi Savanainen			$non_utf8_charset = 1;
2925fa64205dSPasi Savanainen		}
2926fa64205dSPasi Savanainen
2927fa64205dSPasi Savanainen		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
292815662b3eSJoe Perches		    $rawline =~ /$NON_ASCII_UTF8/) {
2929fa64205dSPasi Savanainen			WARN("UTF8_BEFORE_PATCH",
293015662b3eSJoe Perches			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);
293115662b3eSJoe Perches		}
293215662b3eSJoe Perches
2933d6430f71SJoe Perches# Check for absolute kernel paths in commit message
2934d6430f71SJoe Perches		if ($tree && $in_commit_log) {
2935d6430f71SJoe Perches			while ($line =~ m{(?:^|\s)(/\S*)}g) {
2936d6430f71SJoe Perches				my $file = $1;
2937d6430f71SJoe Perches
2938d6430f71SJoe Perches				if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
2939d6430f71SJoe Perches				    check_absolute_file($1, $herecurr)) {
2940d6430f71SJoe Perches					#
2941d6430f71SJoe Perches				} else {
2942d6430f71SJoe Perches					check_absolute_file($file, $herecurr);
2943d6430f71SJoe Perches				}
2944d6430f71SJoe Perches			}
2945d6430f71SJoe Perches		}
2946d6430f71SJoe Perches
294766b47b4aSKees Cook# Check for various typo / spelling mistakes
294866d7a382SJoe Perches		if (defined($misspellings) &&
294966d7a382SJoe Perches		    ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
2950ebfd7d62SJoe Perches			while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) {
295166b47b4aSKees Cook				my $typo = $1;
295266b47b4aSKees Cook				my $typo_fix = $spelling_fix{lc($typo)};
295366b47b4aSKees Cook				$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
295466b47b4aSKees Cook				$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
29550675a8fbSJean Delvare				my $msg_level = \&WARN;
29560675a8fbSJean Delvare				$msg_level = \&CHK if ($file);
29570675a8fbSJean Delvare				if (&{$msg_level}("TYPO_SPELLING",
295866b47b4aSKees Cook						  "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) &&
295966b47b4aSKees Cook				    $fix) {
296066b47b4aSKees Cook					$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
296166b47b4aSKees Cook				}
296266b47b4aSKees Cook			}
296366b47b4aSKees Cook		}
296466b47b4aSKees Cook
2965a8dd86bfSMatteo Croce# check for invalid commit id
2966a8dd86bfSMatteo Croce		if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) {
2967a8dd86bfSMatteo Croce			my $id;
2968a8dd86bfSMatteo Croce			my $description;
2969a8dd86bfSMatteo Croce			($id, $description) = git_commit_info($2, undef, undef);
2970a8dd86bfSMatteo Croce			if (!defined($id)) {
2971a8dd86bfSMatteo Croce				WARN("UNKNOWN_COMMIT_ID",
2972a8dd86bfSMatteo Croce				     "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr);
2973a8dd86bfSMatteo Croce			}
2974a8dd86bfSMatteo Croce		}
2975a8dd86bfSMatteo Croce
297630670854SAndy Whitcroft# ignore non-hunk lines and lines being removed
297730670854SAndy Whitcroft		next if (!$hunk_line || $line =~ /^-/);
297800df344fSAndy Whitcroft
29790a920b5bSAndy Whitcroft#trailing whitespace
29809c0ca6f9SAndy Whitcroft		if ($line =~ /^\+.*\015/) {
2981c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2982d5e616fcSJoe Perches			if (ERROR("DOS_LINE_ENDINGS",
2983d5e616fcSJoe Perches				  "DOS line endings\n" . $herevet) &&
2984d5e616fcSJoe Perches			    $fix) {
2985194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/[\s\015]+$//;
2986d5e616fcSJoe Perches			}
2987c2fdda0dSAndy Whitcroft		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
2988c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
29893705ce5bSJoe Perches			if (ERROR("TRAILING_WHITESPACE",
29903705ce5bSJoe Perches				  "trailing whitespace\n" . $herevet) &&
29913705ce5bSJoe Perches			    $fix) {
2992194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
29933705ce5bSJoe Perches			}
29943705ce5bSJoe Perches
2995d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
29960a920b5bSAndy Whitcroft		}
29975368df20SAndy Whitcroft
29984783f894SJosh Triplett# Check for FSF mailing addresses.
2999109d8cb2SAlexander Duyck		if ($rawline =~ /\bwrite to the Free/i ||
30001bde561eSMatthew Wilcox		    $rawline =~ /\b675\s+Mass\s+Ave/i ||
30013e2232f2SJoe Perches		    $rawline =~ /\b59\s+Temple\s+Pl/i ||
30023e2232f2SJoe Perches		    $rawline =~ /\b51\s+Franklin\s+St/i) {
30034783f894SJosh Triplett			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
30040675a8fbSJean Delvare			my $msg_level = \&ERROR;
30050675a8fbSJean Delvare			$msg_level = \&CHK if ($file);
30060675a8fbSJean Delvare			&{$msg_level}("FSF_MAILING_ADDRESS",
30074783f894SJosh Triplett				      "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet)
30084783f894SJosh Triplett		}
30094783f894SJosh Triplett
30103354957aSAndi Kleen# check for Kconfig help text having a real description
30119fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have
30129fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough.
30133354957aSAndi Kleen		if ($realfile =~ /Kconfig/ &&
3014678ae162SUlf Magnusson		    # 'choice' is usually the last thing on the line (though
3015678ae162SUlf Magnusson		    # Kconfig supports named choices), so use a word boundary
3016678ae162SUlf Magnusson		    # (\b) rather than a whitespace character (\s)
3017678ae162SUlf Magnusson		    $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
30183354957aSAndi Kleen			my $length = 0;
30199fe287d7SAndy Whitcroft			my $cnt = $realcnt;
30209fe287d7SAndy Whitcroft			my $ln = $linenr + 1;
30219fe287d7SAndy Whitcroft			my $f;
3022a1385803SAndy Whitcroft			my $is_start = 0;
30239fe287d7SAndy Whitcroft			my $is_end = 0;
3024a1385803SAndy Whitcroft			for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
30259fe287d7SAndy Whitcroft				$f = $lines[$ln - 1];
30269fe287d7SAndy Whitcroft				$cnt-- if ($lines[$ln - 1] !~ /^-/);
30279fe287d7SAndy Whitcroft				$is_end = $lines[$ln - 1] =~ /^\+/;
30289fe287d7SAndy Whitcroft
30299fe287d7SAndy Whitcroft				next if ($f =~ /^-/);
30308d73e0e7SJoe Perches				last if (!$file && $f =~ /^\@\@/);
3031a1385803SAndy Whitcroft
303286adf1a0SUlf Magnusson				if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
3033a1385803SAndy Whitcroft					$is_start = 1;
303484af7a61SUlf Magnusson				} elsif ($lines[$ln - 1] =~ /^\+\s*(?:help|---help---)\s*$/) {
303584af7a61SUlf Magnusson					if ($lines[$ln - 1] =~ "---help---") {
303684af7a61SUlf Magnusson						WARN("CONFIG_DESCRIPTION",
303784af7a61SUlf Magnusson						     "prefer 'help' over '---help---' for new help texts\n" . $herecurr);
303884af7a61SUlf Magnusson					}
3039a1385803SAndy Whitcroft					$length = -1;
3040a1385803SAndy Whitcroft				}
3041a1385803SAndy Whitcroft
30429fe287d7SAndy Whitcroft				$f =~ s/^.//;
30433354957aSAndi Kleen				$f =~ s/#.*//;
30443354957aSAndi Kleen				$f =~ s/^\s+//;
30453354957aSAndi Kleen				next if ($f =~ /^$/);
3046678ae162SUlf Magnusson
3047678ae162SUlf Magnusson				# This only checks context lines in the patch
3048678ae162SUlf Magnusson				# and so hopefully shouldn't trigger false
3049678ae162SUlf Magnusson				# positives, even though some of these are
3050678ae162SUlf Magnusson				# common words in help texts
3051678ae162SUlf Magnusson				if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice|
3052678ae162SUlf Magnusson						  if|endif|menu|endmenu|source)\b/x) {
30539fe287d7SAndy Whitcroft					$is_end = 1;
30549fe287d7SAndy Whitcroft					last;
30559fe287d7SAndy Whitcroft				}
30563354957aSAndi Kleen				$length++;
30573354957aSAndi Kleen			}
305856193274SVadim Bendebury			if ($is_start && $is_end && $length < $min_conf_desc_length) {
3059000d1cc1SJoe Perches				WARN("CONFIG_DESCRIPTION",
306056193274SVadim Bendebury				     "please write a paragraph that describes the config symbol fully\n" . $herecurr);
306156193274SVadim Bendebury			}
3062a1385803SAndy Whitcroft			#print "is_start<$is_start> is_end<$is_end> length<$length>\n";
30633354957aSAndi Kleen		}
30643354957aSAndi Kleen
3065*7ccf41a8SJoe Perches# check MAINTAINERS entries
3066*7ccf41a8SJoe Perches		if ($realfile =~ /^MAINTAINERS$/) {
3067*7ccf41a8SJoe Perches# check MAINTAINERS entries for the right form
3068*7ccf41a8SJoe Perches			if ($rawline =~ /^\+[A-Z]:/ &&
3069628f91a2SJoe Perches			    $rawline !~ /^\+[A-Z]:\t\S/) {
3070628f91a2SJoe Perches				if (WARN("MAINTAINERS_STYLE",
3071628f91a2SJoe Perches					 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
3072628f91a2SJoe Perches				    $fix) {
3073628f91a2SJoe Perches					$fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
3074628f91a2SJoe Perches				}
3075628f91a2SJoe Perches			}
3076*7ccf41a8SJoe Perches# check MAINTAINERS entries for the right ordering too
3077*7ccf41a8SJoe Perches			my $preferred_order = 'MRLSWQBCPTFXNK';
3078*7ccf41a8SJoe Perches			if ($rawline =~ /^\+[A-Z]:/ &&
3079*7ccf41a8SJoe Perches			    $prevrawline =~ /^[\+ ][A-Z]:/) {
3080*7ccf41a8SJoe Perches				$rawline =~ /^\+([A-Z]):\s*(.*)/;
3081*7ccf41a8SJoe Perches				my $cur = $1;
3082*7ccf41a8SJoe Perches				my $curval = $2;
3083*7ccf41a8SJoe Perches				$prevrawline =~ /^[\+ ]([A-Z]):\s*(.*)/;
3084*7ccf41a8SJoe Perches				my $prev = $1;
3085*7ccf41a8SJoe Perches				my $prevval = $2;
3086*7ccf41a8SJoe Perches				my $curindex = index($preferred_order, $cur);
3087*7ccf41a8SJoe Perches				my $previndex = index($preferred_order, $prev);
3088*7ccf41a8SJoe Perches				if ($curindex < 0) {
3089*7ccf41a8SJoe Perches					WARN("MAINTAINERS_STYLE",
3090*7ccf41a8SJoe Perches					     "Unknown MAINTAINERS entry type: '$cur'\n" . $herecurr);
3091*7ccf41a8SJoe Perches				} else {
3092*7ccf41a8SJoe Perches					if ($previndex >= 0 && $curindex < $previndex) {
3093*7ccf41a8SJoe Perches						WARN("MAINTAINERS_STYLE",
3094*7ccf41a8SJoe Perches						     "Misordered MAINTAINERS entry - list '$cur:' before '$prev:'\n" . $hereprev);
3095*7ccf41a8SJoe Perches					} elsif ((($prev eq 'F' && $cur eq 'F') ||
3096*7ccf41a8SJoe Perches						  ($prev eq 'X' && $cur eq 'X')) &&
3097*7ccf41a8SJoe Perches						 ($prevval cmp $curval) > 0) {
3098*7ccf41a8SJoe Perches						WARN("MAINTAINERS_STYLE",
3099*7ccf41a8SJoe Perches						     "Misordered MAINTAINERS entry - list file patterns in alphabetic order\n" . $hereprev);
3100*7ccf41a8SJoe Perches					}
3101*7ccf41a8SJoe Perches				}
3102*7ccf41a8SJoe Perches			}
3103*7ccf41a8SJoe Perches		}
3104628f91a2SJoe Perches
3105327953e9SChristoph Jaeger# discourage the use of boolean for type definition attributes of Kconfig options
3106327953e9SChristoph Jaeger		if ($realfile =~ /Kconfig/ &&
3107327953e9SChristoph Jaeger		    $line =~ /^\+\s*\bboolean\b/) {
3108327953e9SChristoph Jaeger			WARN("CONFIG_TYPE_BOOLEAN",
3109327953e9SChristoph Jaeger			     "Use of boolean is deprecated, please use bool instead.\n" . $herecurr);
3110327953e9SChristoph Jaeger		}
3111327953e9SChristoph Jaeger
3112c68e5878SArnaud Lacombe		if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
3113c68e5878SArnaud Lacombe		    ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
3114c68e5878SArnaud Lacombe			my $flag = $1;
3115c68e5878SArnaud Lacombe			my $replacement = {
3116c68e5878SArnaud Lacombe				'EXTRA_AFLAGS' =>   'asflags-y',
3117c68e5878SArnaud Lacombe				'EXTRA_CFLAGS' =>   'ccflags-y',
3118c68e5878SArnaud Lacombe				'EXTRA_CPPFLAGS' => 'cppflags-y',
3119c68e5878SArnaud Lacombe				'EXTRA_LDFLAGS' =>  'ldflags-y',
3120c68e5878SArnaud Lacombe			};
3121c68e5878SArnaud Lacombe
3122c68e5878SArnaud Lacombe			WARN("DEPRECATED_VARIABLE",
3123c68e5878SArnaud Lacombe			     "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
3124c68e5878SArnaud Lacombe		}
3125c68e5878SArnaud Lacombe
3126bff5da43SRob Herring# check for DT compatible documentation
31277dd05b38SFlorian Vaussard		if (defined $root &&
31287dd05b38SFlorian Vaussard			(($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
31297dd05b38SFlorian Vaussard			 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
31307dd05b38SFlorian Vaussard
3131bff5da43SRob Herring			my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
3132bff5da43SRob Herring
3133cc93319bSFlorian Vaussard			my $dt_path = $root . "/Documentation/devicetree/bindings/";
3134852d095dSRob Herring			my $vp_file = $dt_path . "vendor-prefixes.yaml";
3135cc93319bSFlorian Vaussard
3136bff5da43SRob Herring			foreach my $compat (@compats) {
3137bff5da43SRob Herring				my $compat2 = $compat;
3138185d566bSRob Herring				$compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
3139185d566bSRob Herring				my $compat3 = $compat;
3140185d566bSRob Herring				$compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
3141185d566bSRob Herring				`grep -Erq "$compat|$compat2|$compat3" $dt_path`;
3142bff5da43SRob Herring				if ( $? >> 8 ) {
3143bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
3144bff5da43SRob Herring					     "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
3145bff5da43SRob Herring				}
3146bff5da43SRob Herring
31474fbf32a6SFlorian Vaussard				next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
31484fbf32a6SFlorian Vaussard				my $vendor = $1;
3149852d095dSRob Herring				`grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`;
3150bff5da43SRob Herring				if ( $? >> 8 ) {
3151bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
3152cc93319bSFlorian Vaussard					     "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
3153bff5da43SRob Herring				}
3154bff5da43SRob Herring			}
3155bff5da43SRob Herring		}
3156bff5da43SRob Herring
31579f3a8992SRob Herring# check for using SPDX license tag at beginning of files
31589f3a8992SRob Herring		if ($realline == $checklicenseline) {
31599f3a8992SRob Herring			if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {
31609f3a8992SRob Herring				$checklicenseline = 2;
31619f3a8992SRob Herring			} elsif ($rawline =~ /^\+/) {
31629f3a8992SRob Herring				my $comment = "";
31639f3a8992SRob Herring				if ($realfile =~ /\.(h|s|S)$/) {
31649f3a8992SRob Herring					$comment = '/*';
31659f3a8992SRob Herring				} elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
31669f3a8992SRob Herring					$comment = '//';
3167c8df0ab6SLubomir Rintel				} elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc|yaml)$/) {
31689f3a8992SRob Herring					$comment = '#';
31699f3a8992SRob Herring				} elsif ($realfile =~ /\.rst$/) {
31709f3a8992SRob Herring					$comment = '..';
31719f3a8992SRob Herring				}
31729f3a8992SRob Herring
3173fdf13693SJoe Perches# check SPDX comment style for .[chsS] files
3174fdf13693SJoe Perches				if ($realfile =~ /\.[chsS]$/ &&
3175fdf13693SJoe Perches				    $rawline =~ /SPDX-License-Identifier:/ &&
3176ffbce897SJoe Perches				    $rawline !~ m@^\+\s*\Q$comment\E\s*@) {
3177fdf13693SJoe Perches					WARN("SPDX_LICENSE_TAG",
3178fdf13693SJoe Perches					     "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);
3179fdf13693SJoe Perches				}
3180fdf13693SJoe Perches
31819f3a8992SRob Herring				if ($comment !~ /^$/ &&
3182ffbce897SJoe Perches				    $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) {
31839f3a8992SRob Herring					WARN("SPDX_LICENSE_TAG",
31849f3a8992SRob Herring					     "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
31853b6e8ac9SJoe Perches				} elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
31863b6e8ac9SJoe Perches					my $spdx_license = $1;
31873b6e8ac9SJoe Perches					if (!is_SPDX_License_valid($spdx_license)) {
31883b6e8ac9SJoe Perches						WARN("SPDX_LICENSE_TAG",
31893b6e8ac9SJoe Perches						     "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
31903b6e8ac9SJoe Perches					}
319150c92900SLubomir Rintel					if ($realfile =~ m@^Documentation/devicetree/bindings/@ &&
319250c92900SLubomir Rintel					    not $spdx_license =~ /GPL-2\.0.*BSD-2-Clause/) {
319350c92900SLubomir Rintel						my $msg_level = \&WARN;
319450c92900SLubomir Rintel						$msg_level = \&CHK if ($file);
319550c92900SLubomir Rintel						if (&{$msg_level}("SPDX_LICENSE_TAG",
319650c92900SLubomir Rintel
319750c92900SLubomir Rintel								  "DT binding documents should be licensed (GPL-2.0-only OR BSD-2-Clause)\n" . $herecurr) &&
319850c92900SLubomir Rintel						    $fix) {
319950c92900SLubomir Rintel							$fixed[$fixlinenr] =~ s/SPDX-License-Identifier: .*/SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)/;
320050c92900SLubomir Rintel						}
320150c92900SLubomir Rintel					}
32029f3a8992SRob Herring				}
32039f3a8992SRob Herring			}
32049f3a8992SRob Herring		}
32059f3a8992SRob Herring
32065368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk
3207d6430f71SJoe Perches		next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
32085368df20SAndy Whitcroft
3209a8da38a9SJoe Perches# check for using SPDX-License-Identifier on the wrong line number
3210a8da38a9SJoe Perches		if ($realline != $checklicenseline &&
3211a8da38a9SJoe Perches		    $rawline =~ /\bSPDX-License-Identifier:/ &&
3212a8da38a9SJoe Perches		    substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {
3213a8da38a9SJoe Perches			WARN("SPDX_LICENSE_TAG",
3214a8da38a9SJoe Perches			     "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);
3215a8da38a9SJoe Perches		}
3216a8da38a9SJoe Perches
321747e0c88bSJoe Perches# line length limit (with some exclusions)
321847e0c88bSJoe Perches#
321947e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length:
322047e0c88bSJoe Perches#	logging functions like pr_info that end in a string
322147e0c88bSJoe Perches#	lines with a single string
322247e0c88bSJoe Perches#	#defines that are a single string
32232e4bbbc5SAndreas Brauchli#	lines with an RFC3986 like URL
322447e0c88bSJoe Perches#
322547e0c88bSJoe Perches# There are 3 different line length message types:
3226ab1ecabfSJean Delvare# LONG_LINE_COMMENT	a comment starts before but extends beyond $max_line_length
322747e0c88bSJoe Perches# LONG_LINE_STRING	a string starts before but extends beyond $max_line_length
322847e0c88bSJoe Perches# LONG_LINE		all other lines longer than $max_line_length
322947e0c88bSJoe Perches#
323047e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored
323147e0c88bSJoe Perches#
323247e0c88bSJoe Perches
3233b4749e96SJoe Perches		if ($line =~ /^\+/ && $length > $max_line_length) {
323447e0c88bSJoe Perches			my $msg_type = "LONG_LINE";
323547e0c88bSJoe Perches
323647e0c88bSJoe Perches			# Check the allowed long line types first
323747e0c88bSJoe Perches
323847e0c88bSJoe Perches			# logging functions that end in a string that starts
323947e0c88bSJoe Perches			# before $max_line_length
324047e0c88bSJoe Perches			if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
324147e0c88bSJoe Perches			    length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
324247e0c88bSJoe Perches				$msg_type = "";
324347e0c88bSJoe Perches
324447e0c88bSJoe Perches			# lines with only strings (w/ possible termination)
324547e0c88bSJoe Perches			# #defines with only strings
324647e0c88bSJoe Perches			} elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
324747e0c88bSJoe Perches				 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
324847e0c88bSJoe Perches				$msg_type = "";
324947e0c88bSJoe Perches
3250cc147506SJoe Perches			# More special cases
3251cc147506SJoe Perches			} elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ ||
3252cc147506SJoe Perches				 $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
3253d560a5f8SJoe Perches				$msg_type = "";
3254d560a5f8SJoe Perches
32552e4bbbc5SAndreas Brauchli			# URL ($rawline is used in case the URL is in a comment)
32562e4bbbc5SAndreas Brauchli			} elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
32572e4bbbc5SAndreas Brauchli				$msg_type = "";
32582e4bbbc5SAndreas Brauchli
325947e0c88bSJoe Perches			# Otherwise set the alternate message types
326047e0c88bSJoe Perches
326147e0c88bSJoe Perches			# a comment starts before $max_line_length
326247e0c88bSJoe Perches			} elsif ($line =~ /($;[\s$;]*)$/ &&
326347e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
326447e0c88bSJoe Perches				$msg_type = "LONG_LINE_COMMENT"
326547e0c88bSJoe Perches
326647e0c88bSJoe Perches			# a quoted string starts before $max_line_length
326747e0c88bSJoe Perches			} elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
326847e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
326947e0c88bSJoe Perches				$msg_type = "LONG_LINE_STRING"
327047e0c88bSJoe Perches			}
327147e0c88bSJoe Perches
327247e0c88bSJoe Perches			if ($msg_type ne "" &&
327347e0c88bSJoe Perches			    (show_type("LONG_LINE") || show_type($msg_type))) {
3274bdc48fa1SJoe Perches				my $msg_level = \&WARN;
3275bdc48fa1SJoe Perches				$msg_level = \&CHK if ($file);
3276bdc48fa1SJoe Perches				&{$msg_level}($msg_type,
3277bdc48fa1SJoe Perches					      "line length of $length exceeds $max_line_length columns\n" . $herecurr);
32780a920b5bSAndy Whitcroft			}
327947e0c88bSJoe Perches		}
32800a920b5bSAndy Whitcroft
32818905a67cSAndy Whitcroft# check for adding lines without a newline.
32828905a67cSAndy Whitcroft		if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
3283000d1cc1SJoe Perches			WARN("MISSING_EOF_NEWLINE",
3284000d1cc1SJoe Perches			     "adding a line without newline at end of file\n" . $herecurr);
32858905a67cSAndy Whitcroft		}
32868905a67cSAndy Whitcroft
3287b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk
3288de4c924cSGeert Uytterhoeven		next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
32890a920b5bSAndy Whitcroft
32900a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything
3291713a09deSAntonio Borneo# more than $tabsize must use tabs.
3292c2fdda0dSAndy Whitcroft		if ($rawline =~ /^\+\s* \t\s*\S/ ||
3293c2fdda0dSAndy Whitcroft		    $rawline =~ /^\+\s*        \s*/) {
3294c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3295d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
32963705ce5bSJoe Perches			if (ERROR("CODE_INDENT",
32973705ce5bSJoe Perches				  "code indent should use tabs where possible\n" . $herevet) &&
32983705ce5bSJoe Perches			    $fix) {
3299194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
33003705ce5bSJoe Perches			}
33010a920b5bSAndy Whitcroft		}
33020a920b5bSAndy Whitcroft
330308e44365SAlberto Panizzo# check for space before tabs.
330408e44365SAlberto Panizzo		if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
330508e44365SAlberto Panizzo			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
33063705ce5bSJoe Perches			if (WARN("SPACE_BEFORE_TAB",
33073705ce5bSJoe Perches				"please, no space before tabs\n" . $herevet) &&
33083705ce5bSJoe Perches			    $fix) {
3309194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
3310713a09deSAntonio Borneo					   s/(^\+.*) {$tabsize,$tabsize}\t/$1\t\t/) {}
3311194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
3312c76f4cb3SJoe Perches					   s/(^\+.*) +\t/$1\t/) {}
33133705ce5bSJoe Perches			}
331408e44365SAlberto Panizzo		}
331508e44365SAlberto Panizzo
33166a487211SJoe Perches# check for assignments on the start of a line
33176a487211SJoe Perches		if ($sline =~ /^\+\s+($Assignment)[^=]/) {
33186a487211SJoe Perches			CHK("ASSIGNMENT_CONTINUATIONS",
33196a487211SJoe Perches			    "Assignment operator '$1' should be on the previous line\n" . $hereprev);
33206a487211SJoe Perches		}
33216a487211SJoe Perches
3322d1fe9c09SJoe Perches# check for && or || at the start of a line
3323d1fe9c09SJoe Perches		if ($rawline =~ /^\+\s*(&&|\|\|)/) {
3324d1fe9c09SJoe Perches			CHK("LOGICAL_CONTINUATIONS",
3325d1fe9c09SJoe Perches			    "Logical continuations should be on the previous line\n" . $hereprev);
3326d1fe9c09SJoe Perches		}
3327d1fe9c09SJoe Perches
3328a91e8994SJoe Perches# check indentation starts on a tab stop
33295b57980dSJoe Perches		if ($perl_version_ok &&
3330bd49111fSJoe Perches		    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
3331a91e8994SJoe Perches			my $indent = length($1);
3332713a09deSAntonio Borneo			if ($indent % $tabsize) {
3333a91e8994SJoe Perches				if (WARN("TABSTOP",
3334a91e8994SJoe Perches					 "Statements should start on a tabstop\n" . $herecurr) &&
3335a91e8994SJoe Perches				    $fix) {
3336713a09deSAntonio Borneo					$fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/$tabsize)@e;
3337a91e8994SJoe Perches				}
3338a91e8994SJoe Perches			}
3339a91e8994SJoe Perches		}
3340a91e8994SJoe Perches
3341d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line
33425b57980dSJoe Perches		if ($perl_version_ok &&
3343fd71f632SJoe Perches		    $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
3344d1fe9c09SJoe Perches			$prevline =~ /^\+(\t*)(.*)$/;
3345d1fe9c09SJoe Perches			my $oldindent = $1;
3346d1fe9c09SJoe Perches			my $rest = $2;
3347d1fe9c09SJoe Perches
3348d1fe9c09SJoe Perches			my $pos = pos_last_openparen($rest);
3349d1fe9c09SJoe Perches			if ($pos >= 0) {
3350b34a26f3SJoe Perches				$line =~ /^(\+| )([ \t]*)/;
3351b34a26f3SJoe Perches				my $newindent = $2;
3352d1fe9c09SJoe Perches
3353d1fe9c09SJoe Perches				my $goodtabindent = $oldindent .
3354713a09deSAntonio Borneo					"\t" x ($pos / $tabsize) .
3355713a09deSAntonio Borneo					" "  x ($pos % $tabsize);
3356d1fe9c09SJoe Perches				my $goodspaceindent = $oldindent . " "  x $pos;
3357d1fe9c09SJoe Perches
3358d1fe9c09SJoe Perches				if ($newindent ne $goodtabindent &&
3359d1fe9c09SJoe Perches				    $newindent ne $goodspaceindent) {
33603705ce5bSJoe Perches
33613705ce5bSJoe Perches					if (CHK("PARENTHESIS_ALIGNMENT",
33623705ce5bSJoe Perches						"Alignment should match open parenthesis\n" . $hereprev) &&
33633705ce5bSJoe Perches					    $fix && $line =~ /^\+/) {
3364194f66fcSJoe Perches						$fixed[$fixlinenr] =~
33653705ce5bSJoe Perches						    s/^\+[ \t]*/\+$goodtabindent/;
33663705ce5bSJoe Perches					}
3367d1fe9c09SJoe Perches				}
3368d1fe9c09SJoe Perches			}
3369d1fe9c09SJoe Perches		}
3370d1fe9c09SJoe Perches
33716ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar"
33726ab3a970SJoe Perches# avoid checking a few false positives:
33736ab3a970SJoe Perches#   "sizeof(<type>)" or "__alignof__(<type>)"
33746ab3a970SJoe Perches#   function pointer declarations like "(*foo)(int) = bar;"
33756ab3a970SJoe Perches#   structure definitions like "(struct foo) { 0 };"
33766ab3a970SJoe Perches#   multiline macros that define functions
33776ab3a970SJoe Perches#   known attributes or the __attribute__ keyword
33786ab3a970SJoe Perches		if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
33796ab3a970SJoe Perches		    (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
33803705ce5bSJoe Perches			if (CHK("SPACING",
3381f27c95dbSJoe Perches				"No space is necessary after a cast\n" . $herecurr) &&
33823705ce5bSJoe Perches			    $fix) {
3383194f66fcSJoe Perches				$fixed[$fixlinenr] =~
3384f27c95dbSJoe Perches				    s/(\(\s*$Type\s*\))[ \t]+/$1/;
33853705ce5bSJoe Perches			}
3386aad4f614SJoe Perches		}
3387aad4f614SJoe Perches
338886406b1cSJoe Perches# Block comment styles
338986406b1cSJoe Perches# Networking with an initial /*
339005880600SJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
3391fdb4bcd6SJoe Perches		    $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
339285ad978cSJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&
339385ad978cSJoe Perches		    $realline > 2) {
339405880600SJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
339505880600SJoe Perches			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
339605880600SJoe Perches		}
339705880600SJoe Perches
339886406b1cSJoe Perches# Block comments use * on subsequent lines
339986406b1cSJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
340086406b1cSJoe Perches		    $prevrawline =~ /^\+.*?\/\*/ &&		#starting /*
3401a605e32eSJoe Perches		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */
340261135e96SJoe Perches		    $rawline =~ /^\+/ &&			#line is new
3403a605e32eSJoe Perches		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *
340486406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
340586406b1cSJoe Perches			     "Block comments use * on subsequent lines\n" . $hereprev);
3406a605e32eSJoe Perches		}
3407a605e32eSJoe Perches
340886406b1cSJoe Perches# Block comments use */ on trailing lines
340986406b1cSJoe Perches		if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
3410c24f9f19SJoe Perches		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/
3411c24f9f19SJoe Perches		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/
3412c24f9f19SJoe Perches		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */
341386406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
341486406b1cSJoe Perches			     "Block comments use a trailing */ on a separate line\n" . $herecurr);
341505880600SJoe Perches		}
341605880600SJoe Perches
341708eb9b80SJoe Perches# Block comment * alignment
341808eb9b80SJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
3419af207524SJoe Perches		    $line =~ /^\+[ \t]*$;/ &&			#leading comment
3420af207524SJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&		#leading *
3421af207524SJoe Perches		    (($prevrawline =~ /^\+.*?\/\*/ &&		#leading /*
342208eb9b80SJoe Perches		      $prevrawline !~ /\*\/[ \t]*$/) ||		#no trailing */
3423af207524SJoe Perches		     $prevrawline =~ /^\+[ \t]*\*/)) {		#leading *
3424af207524SJoe Perches			my $oldindent;
342508eb9b80SJoe Perches			$prevrawline =~ m@^\+([ \t]*/?)\*@;
3426af207524SJoe Perches			if (defined($1)) {
3427af207524SJoe Perches				$oldindent = expand_tabs($1);
3428af207524SJoe Perches			} else {
3429af207524SJoe Perches				$prevrawline =~ m@^\+(.*/?)\*@;
3430af207524SJoe Perches				$oldindent = expand_tabs($1);
3431af207524SJoe Perches			}
343208eb9b80SJoe Perches			$rawline =~ m@^\+([ \t]*)\*@;
343308eb9b80SJoe Perches			my $newindent = $1;
343408eb9b80SJoe Perches			$newindent = expand_tabs($newindent);
3435af207524SJoe Perches			if (length($oldindent) ne length($newindent)) {
343608eb9b80SJoe Perches				WARN("BLOCK_COMMENT_STYLE",
343708eb9b80SJoe Perches				     "Block comments should align the * on each line\n" . $hereprev);
343808eb9b80SJoe Perches			}
343908eb9b80SJoe Perches		}
344008eb9b80SJoe Perches
34417f619191SJoe Perches# check for missing blank lines after struct/union declarations
34427f619191SJoe Perches# with exceptions for various attributes and macros
34437f619191SJoe Perches		if ($prevline =~ /^[\+ ]};?\s*$/ &&
34447f619191SJoe Perches		    $line =~ /^\+/ &&
34457f619191SJoe Perches		    !($line =~ /^\+\s*$/ ||
34467f619191SJoe Perches		      $line =~ /^\+\s*EXPORT_SYMBOL/ ||
34477f619191SJoe Perches		      $line =~ /^\+\s*MODULE_/i ||
34487f619191SJoe Perches		      $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
34497f619191SJoe Perches		      $line =~ /^\+[a-z_]*init/ ||
34507f619191SJoe Perches		      $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
34517f619191SJoe Perches		      $line =~ /^\+\s*DECLARE/ ||
34520bc989ffSMasahiro Yamada		      $line =~ /^\+\s*builtin_[\w_]*driver/ ||
34537f619191SJoe Perches		      $line =~ /^\+\s*__setup/)) {
3454d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
3455d752fcc8SJoe Perches				"Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
3456d752fcc8SJoe Perches			    $fix) {
3457f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, "\+");
3458d752fcc8SJoe Perches			}
34597f619191SJoe Perches		}
34607f619191SJoe Perches
3461365dd4eaSJoe Perches# check for multiple consecutive blank lines
3462365dd4eaSJoe Perches		if ($prevline =~ /^[\+ ]\s*$/ &&
3463365dd4eaSJoe Perches		    $line =~ /^\+\s*$/ &&
3464365dd4eaSJoe Perches		    $last_blank_line != ($linenr - 1)) {
3465d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
3466d752fcc8SJoe Perches				"Please don't use multiple blank lines\n" . $hereprev) &&
3467d752fcc8SJoe Perches			    $fix) {
3468f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
3469d752fcc8SJoe Perches			}
3470d752fcc8SJoe Perches
3471365dd4eaSJoe Perches			$last_blank_line = $linenr;
3472365dd4eaSJoe Perches		}
3473365dd4eaSJoe Perches
34743b617e3bSJoe Perches# check for missing blank lines after declarations
34753f7bac03SJoe Perches		if ($sline =~ /^\+\s+\S/ &&			#Not at char 1
34763f7bac03SJoe Perches			# actual declarations
34773f7bac03SJoe Perches		    ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
34785a4e1fd3SJoe Perches			# function pointer declarations
34795a4e1fd3SJoe Perches		     $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
34803f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
34813f7bac03SJoe Perches		     $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
34823f7bac03SJoe Perches			# known declaration macros
34833f7bac03SJoe Perches		     $prevline =~ /^\+\s+$declaration_macros/) &&
34843f7bac03SJoe Perches			# for "else if" which can look like "$Ident $Ident"
34853f7bac03SJoe Perches		    !($prevline =~ /^\+\s+$c90_Keywords\b/ ||
34863f7bac03SJoe Perches			# other possible extensions of declaration lines
34873f7bac03SJoe Perches		      $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
34883f7bac03SJoe Perches			# not starting a section or a macro "\" extended line
34893f7bac03SJoe Perches		      $prevline =~ /(?:\{\s*|\\)$/) &&
34903f7bac03SJoe Perches			# looks like a declaration
34913f7bac03SJoe Perches		    !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
34925a4e1fd3SJoe Perches			# function pointer declarations
34935a4e1fd3SJoe Perches		      $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
34943f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
34953f7bac03SJoe Perches		      $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
34963f7bac03SJoe Perches			# known declaration macros
34973f7bac03SJoe Perches		      $sline =~ /^\+\s+$declaration_macros/ ||
34983f7bac03SJoe Perches			# start of struct or union or enum
3499328b5f41SJoe Perches		      $sline =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ ||
35003f7bac03SJoe Perches			# start or end of block or continuation of declaration
35013f7bac03SJoe Perches		      $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
35023f7bac03SJoe Perches			# bitfield continuation
35033f7bac03SJoe Perches		      $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
35043f7bac03SJoe Perches			# other possible extensions of declaration lines
35053f7bac03SJoe Perches		      $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) &&
35063f7bac03SJoe Perches			# indentation of previous and current line are the same
35073f7bac03SJoe Perches		    (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) {
3508d752fcc8SJoe Perches			if (WARN("LINE_SPACING",
3509d752fcc8SJoe Perches				 "Missing a blank line after declarations\n" . $hereprev) &&
3510d752fcc8SJoe Perches			    $fix) {
3511f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, "\+");
3512d752fcc8SJoe Perches			}
35133b617e3bSJoe Perches		}
35143b617e3bSJoe Perches
35155f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line.
35166b4c5bebSAndy Whitcroft# Exceptions:
35176b4c5bebSAndy Whitcroft#  1) within comments
35186b4c5bebSAndy Whitcroft#  2) indented preprocessor commands
35196b4c5bebSAndy Whitcroft#  3) hanging labels
35203705ce5bSJoe Perches		if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/)  {
35215f7ddae6SRaffaele Recalcati			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
35223705ce5bSJoe Perches			if (WARN("LEADING_SPACE",
35233705ce5bSJoe Perches				 "please, no spaces at the start of a line\n" . $herevet) &&
35243705ce5bSJoe Perches			    $fix) {
3525194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
35263705ce5bSJoe Perches			}
35275f7ddae6SRaffaele Recalcati		}
35285f7ddae6SRaffaele Recalcati
3529b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk
3530b9ea10d6SAndy Whitcroft		next if ($realfile !~ /\.(h|c)$/);
3531b9ea10d6SAndy Whitcroft
35325751a24eSJoe Perches# check for unusual line ending [ or (
35335751a24eSJoe Perches		if ($line =~ /^\+.*([\[\(])\s*$/) {
35345751a24eSJoe Perches			CHK("OPEN_ENDED_LINE",
35355751a24eSJoe Perches			    "Lines should not end with a '$1'\n" . $herecurr);
35365751a24eSJoe Perches		}
35375751a24eSJoe Perches
35384dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name
35394dbed76fSJoe Perches		if ($sline =~ /^\+\{\s*$/ &&
35404dbed76fSJoe Perches		    $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
35414dbed76fSJoe Perches			$context_function = $1;
35424dbed76fSJoe Perches		}
35434dbed76fSJoe Perches
35444dbed76fSJoe Perches# check if this appears to be the end of function declaration
35454dbed76fSJoe Perches		if ($sline =~ /^\+\}\s*$/) {
35464dbed76fSJoe Perches			undef $context_function;
35474dbed76fSJoe Perches		}
35484dbed76fSJoe Perches
3549032a4c0fSJoe Perches# check indentation of any line with a bare else
3550840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;")
3551032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more...
3552032a4c0fSJoe Perches		if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
3553032a4c0fSJoe Perches			my $tabs = length($1) + 1;
3554840080a0SJoe Perches			if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
3555840080a0SJoe Perches			    ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
3556840080a0SJoe Perches			     defined $lines[$linenr] &&
3557840080a0SJoe Perches			     $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
3558032a4c0fSJoe Perches				WARN("UNNECESSARY_ELSE",
3559032a4c0fSJoe Perches				     "else is not generally useful after a break or return\n" . $hereprev);
3560032a4c0fSJoe Perches			}
3561032a4c0fSJoe Perches		}
3562032a4c0fSJoe Perches
3563c00df19aSJoe Perches# check indentation of a line with a break;
3564c00df19aSJoe Perches# if the previous line is a goto or return and is indented the same # of tabs
3565c00df19aSJoe Perches		if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
3566c00df19aSJoe Perches			my $tabs = $1;
3567c00df19aSJoe Perches			if ($prevline =~ /^\+$tabs(?:goto|return)\b/) {
3568c00df19aSJoe Perches				WARN("UNNECESSARY_BREAK",
3569c00df19aSJoe Perches				     "break is not useful after a goto or return\n" . $hereprev);
3570c00df19aSJoe Perches			}
3571c00df19aSJoe Perches		}
3572c00df19aSJoe Perches
3573c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers
3574cf655043SAndy Whitcroft		if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
3575000d1cc1SJoe Perches			WARN("CVS_KEYWORD",
3576000d1cc1SJoe Perches			     "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
3577c2fdda0dSAndy Whitcroft		}
357822f2a2efSAndy Whitcroft
357956e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings
358056e77d70SJoe Perches		if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
358156e77d70SJoe Perches			WARN("HOTPLUG_SECTION",
358256e77d70SJoe Perches			     "Using $1 is unnecessary\n" . $herecurr);
358356e77d70SJoe Perches		}
358456e77d70SJoe Perches
35859c0ca6f9SAndy Whitcroft# Check for potential 'bare' types
35862b474a1aSAndy Whitcroft		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
35872b474a1aSAndy Whitcroft		    $realline_next);
35883e469cdcSAndy Whitcroft#print "LINE<$line>\n";
3589ca819864SJoe Perches		if ($linenr > $suppress_statement &&
35901b5539b1SJoe Perches		    $realcnt && $sline =~ /.\s*\S/) {
3591170d3a22SAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
3592f5fe35ddSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
3593171ae1a4SAndy Whitcroft			$stat =~ s/\n./\n /g;
3594171ae1a4SAndy Whitcroft			$cond =~ s/\n./\n /g;
3595171ae1a4SAndy Whitcroft
35963e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n";
35973e469cdcSAndy Whitcroft			# If this statement has no statement boundaries within
35983e469cdcSAndy Whitcroft			# it there is no point in retrying a statement scan
35993e469cdcSAndy Whitcroft			# until we hit end of it.
36003e469cdcSAndy Whitcroft			my $frag = $stat; $frag =~ s/;+\s*$//;
36013e469cdcSAndy Whitcroft			if ($frag !~ /(?:{|;)/) {
36023e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n";
36033e469cdcSAndy Whitcroft				$suppress_statement = $line_nr_next;
36043e469cdcSAndy Whitcroft			}
3605f74bd194SAndy Whitcroft
36062b474a1aSAndy Whitcroft			# Find the real next line.
36072b474a1aSAndy Whitcroft			$realline_next = $line_nr_next;
36082b474a1aSAndy Whitcroft			if (defined $realline_next &&
36092b474a1aSAndy Whitcroft			    (!defined $lines[$realline_next - 1] ||
36102b474a1aSAndy Whitcroft			     substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
36112b474a1aSAndy Whitcroft				$realline_next++;
36122b474a1aSAndy Whitcroft			}
36132b474a1aSAndy Whitcroft
3614171ae1a4SAndy Whitcroft			my $s = $stat;
3615171ae1a4SAndy Whitcroft			$s =~ s/{.*$//s;
3616cf655043SAndy Whitcroft
3617c2fdda0dSAndy Whitcroft			# Ignore goto labels.
3618171ae1a4SAndy Whitcroft			if ($s =~ /$Ident:\*$/s) {
3619c2fdda0dSAndy Whitcroft
3620c2fdda0dSAndy Whitcroft			# Ignore functions being called
3621171ae1a4SAndy Whitcroft			} elsif ($s =~ /^.\s*$Ident\s*\(/s) {
3622c2fdda0dSAndy Whitcroft
3623463f2864SAndy Whitcroft			} elsif ($s =~ /^.\s*else\b/s) {
3624463f2864SAndy Whitcroft
3625c45dcabdSAndy Whitcroft			# declarations always start with types
3626d2506586SAndy Whitcroft			} elsif ($prev_values eq 'E' && $s =~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?((?:\s*$Ident)+?)\b(?:\s+$Sparse)?\s*\**\s*(?:$Ident|\(\*[^\)]*\))(?:\s*$Modifier)?\s*(?:;|=|,|\()/s) {
3627c45dcabdSAndy Whitcroft				my $type = $1;
3628c45dcabdSAndy Whitcroft				$type =~ s/\s+/ /g;
3629c45dcabdSAndy Whitcroft				possible($type, "A:" . $s);
3630c45dcabdSAndy Whitcroft
36316c72ffaaSAndy Whitcroft			# definitions in global scope can only start with types
3632a6a84062SAndy Whitcroft			} elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
3633c45dcabdSAndy Whitcroft				possible($1, "B:" . $s);
3634c2fdda0dSAndy Whitcroft			}
36358905a67cSAndy Whitcroft
36366c72ffaaSAndy Whitcroft			# any (foo ... *) is a pointer cast, and foo is a type
363765863862SAndy Whitcroft			while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
3638c45dcabdSAndy Whitcroft				possible($1, "C:" . $s);
36399c0ca6f9SAndy Whitcroft			}
36408905a67cSAndy Whitcroft
36418905a67cSAndy Whitcroft			# Check for any sort of function declaration.
36428905a67cSAndy Whitcroft			# int foo(something bar, other baz);
36438905a67cSAndy Whitcroft			# void (*store_gdt)(x86_descr_ptr *);
3644171ae1a4SAndy Whitcroft			if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
36458905a67cSAndy Whitcroft				my ($name_len) = length($1);
36468905a67cSAndy Whitcroft
3647cf655043SAndy Whitcroft				my $ctx = $s;
3648773647a0SAndy Whitcroft				substr($ctx, 0, $name_len + 1, '');
36498905a67cSAndy Whitcroft				$ctx =~ s/\)[^\)]*$//;
3650cf655043SAndy Whitcroft
36518905a67cSAndy Whitcroft				for my $arg (split(/\s*,\s*/, $ctx)) {
3652c45dcabdSAndy Whitcroft					if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
36538905a67cSAndy Whitcroft
3654c45dcabdSAndy Whitcroft						possible($1, "D:" . $s);
36558905a67cSAndy Whitcroft					}
36568905a67cSAndy Whitcroft				}
36578905a67cSAndy Whitcroft			}
36588905a67cSAndy Whitcroft
36599c0ca6f9SAndy Whitcroft		}
36609c0ca6f9SAndy Whitcroft
366100df344fSAndy Whitcroft#
366200df344fSAndy Whitcroft# Checks which may be anchored in the context.
366300df344fSAndy Whitcroft#
366400df344fSAndy Whitcroft
366500df344fSAndy Whitcroft# Check for switch () and associated case and default
366600df344fSAndy Whitcroft# statements should be at the same indent.
366700df344fSAndy Whitcroft		if ($line=~/\bswitch\s*\(.*\)/) {
366800df344fSAndy Whitcroft			my $err = '';
366900df344fSAndy Whitcroft			my $sep = '';
367000df344fSAndy Whitcroft			my @ctx = ctx_block_outer($linenr, $realcnt);
367100df344fSAndy Whitcroft			shift(@ctx);
367200df344fSAndy Whitcroft			for my $ctx (@ctx) {
367300df344fSAndy Whitcroft				my ($clen, $cindent) = line_stats($ctx);
367400df344fSAndy Whitcroft				if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
367500df344fSAndy Whitcroft							$indent != $cindent) {
367600df344fSAndy Whitcroft					$err .= "$sep$ctx\n";
367700df344fSAndy Whitcroft					$sep = '';
367800df344fSAndy Whitcroft				} else {
367900df344fSAndy Whitcroft					$sep = "[...]\n";
368000df344fSAndy Whitcroft				}
368100df344fSAndy Whitcroft			}
368200df344fSAndy Whitcroft			if ($err ne '') {
3683000d1cc1SJoe Perches				ERROR("SWITCH_CASE_INDENT_LEVEL",
3684000d1cc1SJoe Perches				      "switch and case should be at the same indent\n$hereline$err");
3685de7d4f0eSAndy Whitcroft			}
3686de7d4f0eSAndy Whitcroft		}
3687de7d4f0eSAndy Whitcroft
3688de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop,
3689de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else
36900fe3dc2bSJoe Perches		if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
3691773647a0SAndy Whitcroft			my $pre_ctx = "$1$2";
3692773647a0SAndy Whitcroft
36939c0ca6f9SAndy Whitcroft			my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
36948eef05ddSJoe Perches
36958eef05ddSJoe Perches			if ($line =~ /^\+\t{6,}/) {
36968eef05ddSJoe Perches				WARN("DEEP_INDENTATION",
36978eef05ddSJoe Perches				     "Too many leading tabs - consider code refactoring\n" . $herecurr);
36988eef05ddSJoe Perches			}
36998eef05ddSJoe Perches
3700de7d4f0eSAndy Whitcroft			my $ctx_cnt = $realcnt - $#ctx - 1;
3701de7d4f0eSAndy Whitcroft			my $ctx = join("\n", @ctx);
3702de7d4f0eSAndy Whitcroft
3703548596d5SAndy Whitcroft			my $ctx_ln = $linenr;
3704548596d5SAndy Whitcroft			my $ctx_skip = $realcnt;
3705de7d4f0eSAndy Whitcroft
3706548596d5SAndy Whitcroft			while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
3707548596d5SAndy Whitcroft					defined $lines[$ctx_ln - 1] &&
3708548596d5SAndy Whitcroft					$lines[$ctx_ln - 1] =~ /^-/)) {
3709548596d5SAndy Whitcroft				##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
3710548596d5SAndy Whitcroft				$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
3711773647a0SAndy Whitcroft				$ctx_ln++;
3712773647a0SAndy Whitcroft			}
3713548596d5SAndy Whitcroft
371453210168SAndy Whitcroft			#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
371553210168SAndy Whitcroft			#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
3716773647a0SAndy Whitcroft
3717773647a0SAndy Whitcroft			if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
3718000d1cc1SJoe Perches				ERROR("OPEN_BRACE",
3719000d1cc1SJoe Perches				      "that open brace { should be on the previous line\n" .
372001464f30SAndy Whitcroft					"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
372100df344fSAndy Whitcroft			}
3722773647a0SAndy Whitcroft			if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
3723773647a0SAndy Whitcroft			    $ctx =~ /\)\s*\;\s*$/ &&
3724773647a0SAndy Whitcroft			    defined $lines[$ctx_ln - 1])
3725773647a0SAndy Whitcroft			{
37269c0ca6f9SAndy Whitcroft				my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
37279c0ca6f9SAndy Whitcroft				if ($nindent > $indent) {
3728000d1cc1SJoe Perches					WARN("TRAILING_SEMICOLON",
3729000d1cc1SJoe Perches					     "trailing semicolon indicates no statements, indent implies otherwise\n" .
373001464f30SAndy Whitcroft						"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
37319c0ca6f9SAndy Whitcroft				}
37329c0ca6f9SAndy Whitcroft			}
373300df344fSAndy Whitcroft		}
373400df344fSAndy Whitcroft
37354d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks.
3736f6950a73SJoe Perches		if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
37373e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
37383e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
37393e469cdcSAndy Whitcroft					if (!defined $stat);
37404d001e4dSAndy Whitcroft			my ($s, $c) = ($stat, $cond);
37414d001e4dSAndy Whitcroft
37424d001e4dSAndy Whitcroft			substr($s, 0, length($c), '');
37434d001e4dSAndy Whitcroft
37449f5af480SJoe Perches			# remove inline comments
37459f5af480SJoe Perches			$s =~ s/$;/ /g;
37469f5af480SJoe Perches			$c =~ s/$;/ /g;
37474d001e4dSAndy Whitcroft
37484d001e4dSAndy Whitcroft			# Find out how long the conditional actually is.
37496f779c18SAndy Whitcroft			my @newlines = ($c =~ /\n/gs);
37506f779c18SAndy Whitcroft			my $cond_lines = 1 + $#newlines;
37514d001e4dSAndy Whitcroft
37529f5af480SJoe Perches			# Make sure we remove the line prefixes as we have
37539f5af480SJoe Perches			# none on the first line, and are going to readd them
37549f5af480SJoe Perches			# where necessary.
37559f5af480SJoe Perches			$s =~ s/\n./\n/gs;
37569f5af480SJoe Perches			while ($s =~ /\n\s+\\\n/) {
37579f5af480SJoe Perches				$cond_lines += $s =~ s/\n\s+\\\n/\n/g;
37589f5af480SJoe Perches			}
37599f5af480SJoe Perches
37604d001e4dSAndy Whitcroft			# We want to check the first line inside the block
37614d001e4dSAndy Whitcroft			# starting at the end of the conditional, so remove:
37624d001e4dSAndy Whitcroft			#  1) any blank line termination
37634d001e4dSAndy Whitcroft			#  2) any opening brace { on end of the line
37644d001e4dSAndy Whitcroft			#  3) any do (...) {
37654d001e4dSAndy Whitcroft			my $continuation = 0;
37664d001e4dSAndy Whitcroft			my $check = 0;
37674d001e4dSAndy Whitcroft			$s =~ s/^.*\bdo\b//;
37684d001e4dSAndy Whitcroft			$s =~ s/^\s*{//;
37694d001e4dSAndy Whitcroft			if ($s =~ s/^\s*\\//) {
37704d001e4dSAndy Whitcroft				$continuation = 1;
37714d001e4dSAndy Whitcroft			}
37729bd49efeSAndy Whitcroft			if ($s =~ s/^\s*?\n//) {
37734d001e4dSAndy Whitcroft				$check = 1;
37744d001e4dSAndy Whitcroft				$cond_lines++;
37754d001e4dSAndy Whitcroft			}
37764d001e4dSAndy Whitcroft
37774d001e4dSAndy Whitcroft			# Also ignore a loop construct at the end of a
37784d001e4dSAndy Whitcroft			# preprocessor statement.
37794d001e4dSAndy Whitcroft			if (($prevline =~ /^.\s*#\s*define\s/ ||
37804d001e4dSAndy Whitcroft			    $prevline =~ /\\\s*$/) && $continuation == 0) {
37814d001e4dSAndy Whitcroft				$check = 0;
37824d001e4dSAndy Whitcroft			}
37834d001e4dSAndy Whitcroft
37849bd49efeSAndy Whitcroft			my $cond_ptr = -1;
3785740504c6SAndy Whitcroft			$continuation = 0;
37869bd49efeSAndy Whitcroft			while ($cond_ptr != $cond_lines) {
37879bd49efeSAndy Whitcroft				$cond_ptr = $cond_lines;
37884d001e4dSAndy Whitcroft
3789f16fa28fSAndy Whitcroft				# If we see an #else/#elif then the code
3790f16fa28fSAndy Whitcroft				# is not linear.
3791f16fa28fSAndy Whitcroft				if ($s =~ /^\s*\#\s*(?:else|elif)/) {
3792f16fa28fSAndy Whitcroft					$check = 0;
3793f16fa28fSAndy Whitcroft				}
3794f16fa28fSAndy Whitcroft
37959bd49efeSAndy Whitcroft				# Ignore:
37969bd49efeSAndy Whitcroft				#  1) blank lines, they should be at 0,
37979bd49efeSAndy Whitcroft				#  2) preprocessor lines, and
37989bd49efeSAndy Whitcroft				#  3) labels.
3799740504c6SAndy Whitcroft				if ($continuation ||
3800740504c6SAndy Whitcroft				    $s =~ /^\s*?\n/ ||
38019bd49efeSAndy Whitcroft				    $s =~ /^\s*#\s*?/ ||
38029bd49efeSAndy Whitcroft				    $s =~ /^\s*$Ident\s*:/) {
3803740504c6SAndy Whitcroft					$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
380430dad6ebSAndy Whitcroft					if ($s =~ s/^.*?\n//) {
38059bd49efeSAndy Whitcroft						$cond_lines++;
38069bd49efeSAndy Whitcroft					}
38074d001e4dSAndy Whitcroft				}
380830dad6ebSAndy Whitcroft			}
38094d001e4dSAndy Whitcroft
38104d001e4dSAndy Whitcroft			my (undef, $sindent) = line_stats("+" . $s);
38114d001e4dSAndy Whitcroft			my $stat_real = raw_line($linenr, $cond_lines);
38124d001e4dSAndy Whitcroft
38134d001e4dSAndy Whitcroft			# Check if either of these lines are modified, else
38144d001e4dSAndy Whitcroft			# this is not this patch's fault.
38154d001e4dSAndy Whitcroft			if (!defined($stat_real) ||
38164d001e4dSAndy Whitcroft			    $stat !~ /^\+/ && $stat_real !~ /^\+/) {
38174d001e4dSAndy Whitcroft				$check = 0;
38184d001e4dSAndy Whitcroft			}
38194d001e4dSAndy Whitcroft			if (defined($stat_real) && $cond_lines > 1) {
38204d001e4dSAndy Whitcroft				$stat_real = "[...]\n$stat_real";
38214d001e4dSAndy Whitcroft			}
38224d001e4dSAndy Whitcroft
38239bd49efeSAndy Whitcroft			#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";
38244d001e4dSAndy Whitcroft
38259f5af480SJoe Perches			if ($check && $s ne '' &&
3826713a09deSAntonio Borneo			    (($sindent % $tabsize) != 0 ||
38279f5af480SJoe Perches			     ($sindent < $indent) ||
3828f6950a73SJoe Perches			     ($sindent == $indent &&
3829f6950a73SJoe Perches			      ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
3830713a09deSAntonio Borneo			     ($sindent > $indent + $tabsize))) {
3831000d1cc1SJoe Perches				WARN("SUSPECT_CODE_INDENT",
3832000d1cc1SJoe Perches				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
38334d001e4dSAndy Whitcroft			}
38344d001e4dSAndy Whitcroft		}
38354d001e4dSAndy Whitcroft
38366c72ffaaSAndy Whitcroft		# Track the 'values' across context and added lines.
38376c72ffaaSAndy Whitcroft		my $opline = $line; $opline =~ s/^./ /;
38381f65f947SAndy Whitcroft		my ($curr_values, $curr_vars) =
38391f65f947SAndy Whitcroft				annotate_values($opline . "\n", $prev_values);
38406c72ffaaSAndy Whitcroft		$curr_values = $prev_values . $curr_values;
3841c2fdda0dSAndy Whitcroft		if ($dbg_values) {
3842c2fdda0dSAndy Whitcroft			my $outline = $opline; $outline =~ s/\t/ /g;
3843cf655043SAndy Whitcroft			print "$linenr > .$outline\n";
3844cf655043SAndy Whitcroft			print "$linenr > $curr_values\n";
38451f65f947SAndy Whitcroft			print "$linenr >  $curr_vars\n";
3846c2fdda0dSAndy Whitcroft		}
38476c72ffaaSAndy Whitcroft		$prev_values = substr($curr_values, -1);
38486c72ffaaSAndy Whitcroft
384900df344fSAndy Whitcroft#ignore lines not being added
38503705ce5bSJoe Perches		next if ($line =~ /^[^\+]/);
385100df344fSAndy Whitcroft
385211ca40a0SJoe Perches# check for dereferences that span multiple lines
385311ca40a0SJoe Perches		if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
385411ca40a0SJoe Perches		    $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
385511ca40a0SJoe Perches			$prevline =~ /($Lval\s*(?:\.|->))\s*$/;
385611ca40a0SJoe Perches			my $ref = $1;
385711ca40a0SJoe Perches			$line =~ /^.\s*($Lval)/;
385811ca40a0SJoe Perches			$ref .= $1;
385911ca40a0SJoe Perches			$ref =~ s/\s//g;
386011ca40a0SJoe Perches			WARN("MULTILINE_DEREFERENCE",
386111ca40a0SJoe Perches			     "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
386211ca40a0SJoe Perches		}
386311ca40a0SJoe Perches
3864a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int
3865c8447115SJoe Perches		while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
3866a1ce18e4SJoe Perches			my $type = $1;
3867a1ce18e4SJoe Perches			my $var = $2;
3868207a8e84SJoe Perches			$var = "" if (!defined $var);
3869207a8e84SJoe Perches			if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
3870a1ce18e4SJoe Perches				my $sign = $1;
3871a1ce18e4SJoe Perches				my $pointer = $2;
3872a1ce18e4SJoe Perches
3873a1ce18e4SJoe Perches				$pointer = "" if (!defined $pointer);
3874a1ce18e4SJoe Perches
3875a1ce18e4SJoe Perches				if (WARN("UNSPECIFIED_INT",
3876a1ce18e4SJoe Perches					 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
3877a1ce18e4SJoe Perches				    $fix) {
3878a1ce18e4SJoe Perches					my $decl = trim($sign) . " int ";
3879207a8e84SJoe Perches					my $comp_pointer = $pointer;
3880207a8e84SJoe Perches					$comp_pointer =~ s/\s//g;
3881207a8e84SJoe Perches					$decl .= $comp_pointer;
3882207a8e84SJoe Perches					$decl = rtrim($decl) if ($var eq "");
3883207a8e84SJoe Perches					$fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
3884a1ce18e4SJoe Perches				}
3885a1ce18e4SJoe Perches			}
3886a1ce18e4SJoe Perches		}
3887a1ce18e4SJoe Perches
3888653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher.
38897429c690SAndy Whitcroft		if ($dbg_type) {
38907429c690SAndy Whitcroft			if ($line =~ /^.\s*$Declare\s*$/) {
3891000d1cc1SJoe Perches				ERROR("TEST_TYPE",
3892000d1cc1SJoe Perches				      "TEST: is type\n" . $herecurr);
38937429c690SAndy Whitcroft			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
3894000d1cc1SJoe Perches				ERROR("TEST_NOT_TYPE",
3895000d1cc1SJoe Perches				      "TEST: is not type ($1 is)\n". $herecurr);
38967429c690SAndy Whitcroft			}
3897653d4876SAndy Whitcroft			next;
3898653d4876SAndy Whitcroft		}
3899a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher.
3900a1ef277eSAndy Whitcroft		if ($dbg_attr) {
39019360b0e5SAndy Whitcroft			if ($line =~ /^.\s*$Modifier\s*$/) {
3902000d1cc1SJoe Perches				ERROR("TEST_ATTR",
3903000d1cc1SJoe Perches				      "TEST: is attr\n" . $herecurr);
39049360b0e5SAndy Whitcroft			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
3905000d1cc1SJoe Perches				ERROR("TEST_NOT_ATTR",
3906000d1cc1SJoe Perches				      "TEST: is not attr ($1 is)\n". $herecurr);
3907a1ef277eSAndy Whitcroft			}
3908a1ef277eSAndy Whitcroft			next;
3909a1ef277eSAndy Whitcroft		}
3910653d4876SAndy Whitcroft
3911f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line
391299423c20SAndy Whitcroft		if ($line =~ /^.\s*{/ &&
391399423c20SAndy Whitcroft		    $prevline =~ /(?:^|[^=])=\s*$/) {
3914d752fcc8SJoe Perches			if (ERROR("OPEN_BRACE",
3915d752fcc8SJoe Perches				  "that open brace { should be on the previous line\n" . $hereprev) &&
3916f2d7e4d4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
3917f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
3918f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
3919d752fcc8SJoe Perches				my $fixedline = $prevrawline;
3920d752fcc8SJoe Perches				$fixedline =~ s/\s*=\s*$/ = {/;
3921f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
3922d752fcc8SJoe Perches				$fixedline = $line;
39238d81ae05SCyril Bur				$fixedline =~ s/^(.\s*)\{\s*/$1/;
3924f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
3925d752fcc8SJoe Perches			}
3926f0a594c1SAndy Whitcroft		}
3927f0a594c1SAndy Whitcroft
392800df344fSAndy Whitcroft#
392900df344fSAndy Whitcroft# Checks which are anchored on the added line.
393000df344fSAndy Whitcroft#
393100df344fSAndy Whitcroft
3932653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line)
3933c45dcabdSAndy Whitcroft		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
3934653d4876SAndy Whitcroft			my $path = $1;
3935653d4876SAndy Whitcroft			if ($path =~ m{//}) {
3936000d1cc1SJoe Perches				ERROR("MALFORMED_INCLUDE",
3937495e9d84SJoe Perches				      "malformed #include filename\n" . $herecurr);
3938495e9d84SJoe Perches			}
3939495e9d84SJoe Perches			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
3940495e9d84SJoe Perches				ERROR("UAPI_INCLUDE",
3941495e9d84SJoe Perches				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
3942653d4876SAndy Whitcroft			}
3943653d4876SAndy Whitcroft		}
3944653d4876SAndy Whitcroft
394500df344fSAndy Whitcroft# no C99 // comments
394600df344fSAndy Whitcroft		if ($line =~ m{//}) {
39473705ce5bSJoe Perches			if (ERROR("C99_COMMENTS",
39483705ce5bSJoe Perches				  "do not use C99 // comments\n" . $herecurr) &&
39493705ce5bSJoe Perches			    $fix) {
3950194f66fcSJoe Perches				my $line = $fixed[$fixlinenr];
39513705ce5bSJoe Perches				if ($line =~ /\/\/(.*)$/) {
39523705ce5bSJoe Perches					my $comment = trim($1);
3953194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
39543705ce5bSJoe Perches				}
39553705ce5bSJoe Perches			}
395600df344fSAndy Whitcroft		}
395700df344fSAndy Whitcroft		# Remove C99 comments.
39580a920b5bSAndy Whitcroft		$line =~ s@//.*@@;
39596c72ffaaSAndy Whitcroft		$opline =~ s@//.*@@;
39600a920b5bSAndy Whitcroft
39612b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
39622b474a1aSAndy Whitcroft# the whole statement.
39632b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n";
39642b474a1aSAndy Whitcroft		if (defined $realline_next &&
39652b474a1aSAndy Whitcroft		    exists $lines[$realline_next - 1] &&
39662b474a1aSAndy Whitcroft		    !defined $suppress_export{$realline_next} &&
39672b474a1aSAndy Whitcroft		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
39682b474a1aSAndy Whitcroft		     $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
39693cbf62dfSAndy Whitcroft			# Handle definitions which produce identifiers with
39703cbf62dfSAndy Whitcroft			# a prefix:
39713cbf62dfSAndy Whitcroft			#   XXX(foo);
39723cbf62dfSAndy Whitcroft			#   EXPORT_SYMBOL(something_foo);
3973653d4876SAndy Whitcroft			my $name = $1;
397487a53877SAndy Whitcroft			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
39753cbf62dfSAndy Whitcroft			    $name =~ /^${Ident}_$2/) {
39763cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n";
39773cbf62dfSAndy Whitcroft				$suppress_export{$realline_next} = 1;
39783cbf62dfSAndy Whitcroft
39793cbf62dfSAndy Whitcroft			} elsif ($stat !~ /(?:
39802b474a1aSAndy Whitcroft				\n.}\s*$|
398148012058SAndy Whitcroft				^.DEFINE_$Ident\(\Q$name\E\)|
398248012058SAndy Whitcroft				^.DECLARE_$Ident\(\Q$name\E\)|
398348012058SAndy Whitcroft				^.LIST_HEAD\(\Q$name\E\)|
39842b474a1aSAndy Whitcroft				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
39852b474a1aSAndy Whitcroft				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
398648012058SAndy Whitcroft			    )/x) {
39872b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
39882b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 2;
39892b474a1aSAndy Whitcroft			} else {
39902b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 1;
39910a920b5bSAndy Whitcroft			}
39920a920b5bSAndy Whitcroft		}
39932b474a1aSAndy Whitcroft		if (!defined $suppress_export{$linenr} &&
39942b474a1aSAndy Whitcroft		    $prevline =~ /^.\s*$/ &&
39952b474a1aSAndy Whitcroft		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
39962b474a1aSAndy Whitcroft		     $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
39972b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n";
39982b474a1aSAndy Whitcroft			$suppress_export{$linenr} = 2;
39992b474a1aSAndy Whitcroft		}
40002b474a1aSAndy Whitcroft		if (defined $suppress_export{$linenr} &&
40012b474a1aSAndy Whitcroft		    $suppress_export{$linenr} == 2) {
4002000d1cc1SJoe Perches			WARN("EXPORT_SYMBOL",
4003000d1cc1SJoe Perches			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
40042b474a1aSAndy Whitcroft		}
40050a920b5bSAndy Whitcroft
40065150bda4SJoe Eloff# check for global initialisers.
40076d32f7a3SJoe Perches		if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) {
4008d5e616fcSJoe Perches			if (ERROR("GLOBAL_INITIALISERS",
40096d32f7a3SJoe Perches				  "do not initialise globals to $1\n" . $herecurr) &&
4010d5e616fcSJoe Perches			    $fix) {
40116d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
4012d5e616fcSJoe Perches			}
4013f0a594c1SAndy Whitcroft		}
40140a920b5bSAndy Whitcroft# check for static initialisers.
40156d32f7a3SJoe Perches		if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
4016d5e616fcSJoe Perches			if (ERROR("INITIALISED_STATIC",
40176d32f7a3SJoe Perches				  "do not initialise statics to $1\n" .
4018d5e616fcSJoe Perches				      $herecurr) &&
4019d5e616fcSJoe Perches			    $fix) {
40206d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
4021d5e616fcSJoe Perches			}
40220a920b5bSAndy Whitcroft		}
40230a920b5bSAndy Whitcroft
40241813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned
40251813087dSJoe Perches		while ($sline =~ m{(\b$TypeMisordered\b)}g) {
40261813087dSJoe Perches			my $tmp = trim($1);
40271813087dSJoe Perches			WARN("MISORDERED_TYPE",
40281813087dSJoe Perches			     "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
40291813087dSJoe Perches		}
40301813087dSJoe Perches
4031809e082eSJoe Perches# check for unnecessary <signed> int declarations of short/long/long long
4032809e082eSJoe Perches		while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) {
4033809e082eSJoe Perches			my $type = trim($1);
4034809e082eSJoe Perches			next if ($type !~ /\bint\b/);
4035809e082eSJoe Perches			next if ($type !~ /\b(?:short|long\s+long|long)\b/);
4036809e082eSJoe Perches			my $new_type = $type;
4037809e082eSJoe Perches			$new_type =~ s/\b\s*int\s*\b/ /;
4038809e082eSJoe Perches			$new_type =~ s/\b\s*(?:un)?signed\b\s*/ /;
4039809e082eSJoe Perches			$new_type =~ s/^const\s+//;
4040809e082eSJoe Perches			$new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/);
4041809e082eSJoe Perches			$new_type = "const $new_type" if ($type =~ /^const\b/);
4042809e082eSJoe Perches			$new_type =~ s/\s+/ /g;
4043809e082eSJoe Perches			$new_type = trim($new_type);
4044809e082eSJoe Perches			if (WARN("UNNECESSARY_INT",
4045809e082eSJoe Perches				 "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) &&
4046809e082eSJoe Perches			    $fix) {
4047809e082eSJoe Perches				$fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/;
4048809e082eSJoe Perches			}
4049809e082eSJoe Perches		}
4050809e082eSJoe Perches
4051cb710ecaSJoe Perches# check for static const char * arrays.
4052cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
4053000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
4054000d1cc1SJoe Perches			     "static const char * array should probably be static const char * const\n" .
4055cb710ecaSJoe Perches				$herecurr);
4056cb710ecaSJoe Perches		}
4057cb710ecaSJoe Perches
405877b8c0a8SJoe Perches# check for initialized const char arrays that should be static const
405977b8c0a8SJoe Perches		if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) {
406077b8c0a8SJoe Perches			if (WARN("STATIC_CONST_CHAR_ARRAY",
406177b8c0a8SJoe Perches				 "const array should probably be static const\n" . $herecurr) &&
406277b8c0a8SJoe Perches			    $fix) {
406377b8c0a8SJoe Perches				$fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/;
406477b8c0a8SJoe Perches			}
406577b8c0a8SJoe Perches		}
406677b8c0a8SJoe Perches
4067cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations.
4068cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
4069000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
4070000d1cc1SJoe Perches			     "static char array declaration should probably be static const char\n" .
4071cb710ecaSJoe Perches				$herecurr);
4072cb710ecaSJoe Perches		}
4073cb710ecaSJoe Perches
4074ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type
4075ab7e23f3SJoe Perches		if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
4076ab7e23f3SJoe Perches			my $found = $1;
4077ab7e23f3SJoe Perches			if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
4078ab7e23f3SJoe Perches				WARN("CONST_CONST",
4079ab7e23f3SJoe Perches				     "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
4080ab7e23f3SJoe Perches			} elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
4081ab7e23f3SJoe Perches				WARN("CONST_CONST",
4082ab7e23f3SJoe Perches				     "'const $found const' should probably be 'const $found'\n" . $herecurr);
4083ab7e23f3SJoe Perches			}
4084ab7e23f3SJoe Perches		}
4085ab7e23f3SJoe Perches
40869b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations.
40879b0fa60dSJoe Perches		if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
40889b0fa60dSJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
40899b0fa60dSJoe Perches			     "char * array declaration might be better as static const\n" .
40909b0fa60dSJoe Perches				$herecurr);
40919b0fa60dSJoe Perches               }
40929b0fa60dSJoe Perches
4093b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
4094b598b670SJoe Perches		if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
4095b598b670SJoe Perches			my $array = $1;
4096b598b670SJoe Perches			if ($line =~ m@\b(sizeof\s*\(\s*\Q$array\E\s*\)\s*/\s*sizeof\s*\(\s*\Q$array\E\s*\[\s*0\s*\]\s*\))@) {
4097b598b670SJoe Perches				my $array_div = $1;
4098b598b670SJoe Perches				if (WARN("ARRAY_SIZE",
4099b598b670SJoe Perches					 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
4100b598b670SJoe Perches				    $fix) {
4101b598b670SJoe Perches					$fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
4102b598b670SJoe Perches				}
4103b598b670SJoe Perches			}
4104b598b670SJoe Perches		}
4105b598b670SJoe Perches
4106b36190c5SJoe Perches# check for function declarations without arguments like "int foo()"
410716b7f3c8SJoe Perches		if ($line =~ /(\b$Type\s*$Ident)\s*\(\s*\)/) {
4108b36190c5SJoe Perches			if (ERROR("FUNCTION_WITHOUT_ARGS",
4109b36190c5SJoe Perches				  "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
4110b36190c5SJoe Perches			    $fix) {
4111194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
4112b36190c5SJoe Perches			}
4113b36190c5SJoe Perches		}
4114b36190c5SJoe Perches
4115653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations
4116653d4876SAndy Whitcroft# make sense.
4117653d4876SAndy Whitcroft		if ($line =~ /\btypedef\s/ &&
41188054576dSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
4119c45dcabdSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
41208ed22cadSAndy Whitcroft		    $line !~ /\b$typeTypedefs\b/ &&
412146d832f5SMichael S. Tsirkin		    $line !~ /\b__bitwise\b/) {
4122000d1cc1SJoe Perches			WARN("NEW_TYPEDEFS",
4123000d1cc1SJoe Perches			     "do not add new typedefs\n" . $herecurr);
41240a920b5bSAndy Whitcroft		}
41250a920b5bSAndy Whitcroft
41260a920b5bSAndy Whitcroft# * goes on variable not on type
412765863862SAndy Whitcroft		# (char*[ const])
4128bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
4129bfcb2cc7SAndy Whitcroft			#print "AA<$1>\n";
41303705ce5bSJoe Perches			my ($ident, $from, $to) = ($1, $2, $2);
4131d8aaf121SAndy Whitcroft
413265863862SAndy Whitcroft			# Should start with a space.
413365863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
413465863862SAndy Whitcroft			# Should not end with a space.
413565863862SAndy Whitcroft			$to =~ s/\s+$//;
413665863862SAndy Whitcroft			# '*'s should not have spaces between.
4137f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
413865863862SAndy Whitcroft			}
4139d8aaf121SAndy Whitcroft
41403705ce5bSJoe Perches##			print "1: from<$from> to<$to> ident<$ident>\n";
414165863862SAndy Whitcroft			if ($from ne $to) {
41423705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
41433705ce5bSJoe Perches					  "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
41443705ce5bSJoe Perches				    $fix) {
41453705ce5bSJoe Perches					my $sub_from = $ident;
41463705ce5bSJoe Perches					my $sub_to = $ident;
41473705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
4148194f66fcSJoe Perches					$fixed[$fixlinenr] =~
41493705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
41503705ce5bSJoe Perches				}
415165863862SAndy Whitcroft			}
4152bfcb2cc7SAndy Whitcroft		}
4153bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
4154bfcb2cc7SAndy Whitcroft			#print "BB<$1>\n";
41553705ce5bSJoe Perches			my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
4156d8aaf121SAndy Whitcroft
415765863862SAndy Whitcroft			# Should start with a space.
415865863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
415965863862SAndy Whitcroft			# Should not end with a space.
416065863862SAndy Whitcroft			$to =~ s/\s+$//;
416165863862SAndy Whitcroft			# '*'s should not have spaces between.
4162f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
416365863862SAndy Whitcroft			}
416465863862SAndy Whitcroft			# Modifiers should have spaces.
416565863862SAndy Whitcroft			$to =~ s/(\b$Modifier$)/$1 /;
416665863862SAndy Whitcroft
41673705ce5bSJoe Perches##			print "2: from<$from> to<$to> ident<$ident>\n";
4168667026e7SAndy Whitcroft			if ($from ne $to && $ident !~ /^$Modifier$/) {
41693705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
41703705ce5bSJoe Perches					  "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
41713705ce5bSJoe Perches				    $fix) {
41723705ce5bSJoe Perches
41733705ce5bSJoe Perches					my $sub_from = $match;
41743705ce5bSJoe Perches					my $sub_to = $match;
41753705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
4176194f66fcSJoe Perches					$fixed[$fixlinenr] =~
41773705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
41783705ce5bSJoe Perches				}
417965863862SAndy Whitcroft			}
41800a920b5bSAndy Whitcroft		}
41810a920b5bSAndy Whitcroft
41829d3e3c70SJoe Perches# avoid BUG() or BUG_ON()
41839d3e3c70SJoe Perches		if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
41840675a8fbSJean Delvare			my $msg_level = \&WARN;
41850675a8fbSJean Delvare			$msg_level = \&CHK if ($file);
41860675a8fbSJean Delvare			&{$msg_level}("AVOID_BUG",
41879d3e3c70SJoe Perches				      "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
41889d3e3c70SJoe Perches		}
41890a920b5bSAndy Whitcroft
41909d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE
41918905a67cSAndy Whitcroft		if ($line =~ /\bLINUX_VERSION_CODE\b/) {
4192000d1cc1SJoe Perches			WARN("LINUX_VERSION_CODE",
4193000d1cc1SJoe Perches			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
41948905a67cSAndy Whitcroft		}
41958905a67cSAndy Whitcroft
419617441227SJoe Perches# check for uses of printk_ratelimit
419717441227SJoe Perches		if ($line =~ /\bprintk_ratelimit\s*\(/) {
4198000d1cc1SJoe Perches			WARN("PRINTK_RATELIMITED",
4199000d1cc1SJoe Perches			     "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
420017441227SJoe Perches		}
420117441227SJoe Perches
4202eeef5733SJoe Perches# printk should use KERN_* levels
4203eeef5733SJoe Perches		if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) {
4204000d1cc1SJoe Perches			WARN("PRINTK_WITHOUT_KERN_LEVEL",
4205eeef5733SJoe Perches			     "printk() should include KERN_<LEVEL> facility level\n" . $herecurr);
420600df344fSAndy Whitcroft		}
42070a920b5bSAndy Whitcroft
4208243f3803SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) {
4209243f3803SJoe Perches			my $orig = $1;
4210243f3803SJoe Perches			my $level = lc($orig);
4211243f3803SJoe Perches			$level = "warn" if ($level eq "warning");
42128f26b837SJoe Perches			my $level2 = $level;
42138f26b837SJoe Perches			$level2 = "dbg" if ($level eq "debug");
4214243f3803SJoe Perches			WARN("PREFER_PR_LEVEL",
4215daa8b059SYogesh Chaudhari			     "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(...  to printk(KERN_$orig ...\n" . $herecurr);
4216243f3803SJoe Perches		}
4217243f3803SJoe Perches
4218dc139313SJoe Perches		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
4219dc139313SJoe Perches			my $orig = $1;
4220dc139313SJoe Perches			my $level = lc($orig);
4221dc139313SJoe Perches			$level = "warn" if ($level eq "warning");
4222dc139313SJoe Perches			$level = "dbg" if ($level eq "debug");
4223dc139313SJoe Perches			WARN("PREFER_DEV_LEVEL",
4224dc139313SJoe Perches			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
4225dc139313SJoe Perches		}
4226dc139313SJoe Perches
422791c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else.  This will have a small
422891c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at
422991c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning.
423091c9afafSAndy Lutomirski		if ($line =~ /\bENOSYS\b/) {
423191c9afafSAndy Lutomirski			WARN("ENOSYS",
423291c9afafSAndy Lutomirski			     "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
423391c9afafSAndy Lutomirski		}
423491c9afafSAndy Lutomirski
42356b9ea5ffSJakub Kicinski# ENOTSUPP is not a standard error code and should be avoided in new patches.
42366b9ea5ffSJakub Kicinski# Folks usually mean EOPNOTSUPP (also called ENOTSUP), when they type ENOTSUPP.
42376b9ea5ffSJakub Kicinski# Similarly to ENOSYS warning a small number of false positives is expected.
42386b9ea5ffSJakub Kicinski		if (!$file && $line =~ /\bENOTSUPP\b/) {
42396b9ea5ffSJakub Kicinski			if (WARN("ENOTSUPP",
42406b9ea5ffSJakub Kicinski				 "ENOTSUPP is not a SUSV4 error code, prefer EOPNOTSUPP\n" . $herecurr) &&
42416b9ea5ffSJakub Kicinski			    $fix) {
42426b9ea5ffSJakub Kicinski				$fixed[$fixlinenr] =~ s/\bENOTSUPP\b/EOPNOTSUPP/;
42436b9ea5ffSJakub Kicinski			}
42446b9ea5ffSJakub Kicinski		}
42456b9ea5ffSJakub Kicinski
4246653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while,
4247653d4876SAndy Whitcroft# or if closed on same line
42485b57980dSJoe Perches		if ($perl_version_ok &&
42492d453e3bSJoe Perches		    $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
42502d453e3bSJoe Perches		    $sline !~ /\#\s*define\b.*do\s*\{/ &&
42512d453e3bSJoe Perches		    $sline !~ /}/) {
42528d182478SJoe Perches			if (ERROR("OPEN_BRACE",
42532d453e3bSJoe Perches				  "open brace '{' following function definitions go on the next line\n" . $herecurr) &&
42548d182478SJoe Perches			    $fix) {
42558d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
42568d182478SJoe Perches				my $fixed_line = $rawline;
42578d182478SJoe Perches				$fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/;
42588d182478SJoe Perches				my $line1 = $1;
42598d182478SJoe Perches				my $line2 = $2;
42608d182478SJoe Perches				fix_insert_line($fixlinenr, ltrim($line1));
42618d182478SJoe Perches				fix_insert_line($fixlinenr, "\+{");
42628d182478SJoe Perches				if ($line2 !~ /^\s*$/) {
42638d182478SJoe Perches					fix_insert_line($fixlinenr, "\+\t" . trim($line2));
42648d182478SJoe Perches				}
42658d182478SJoe Perches			}
42660a920b5bSAndy Whitcroft		}
4267653d4876SAndy Whitcroft
42688905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line.
42698905a67cSAndy Whitcroft		if ($line =~ /^.\s*{/ &&
42708905a67cSAndy Whitcroft		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
42718d182478SJoe Perches			if (ERROR("OPEN_BRACE",
42728d182478SJoe Perches				  "open brace '{' following $1 go on the same line\n" . $hereprev) &&
42738d182478SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
42748d182478SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
42758d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
42768d182478SJoe Perches				my $fixedline = rtrim($prevrawline) . " {";
42778d182478SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
42788d182478SJoe Perches				$fixedline = $rawline;
42798d81ae05SCyril Bur				$fixedline =~ s/^(.\s*)\{\s*/$1\t/;
42808d182478SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
42818d182478SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
42828d182478SJoe Perches				}
42838d182478SJoe Perches			}
42848905a67cSAndy Whitcroft		}
42858905a67cSAndy Whitcroft
42860c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition
42873705ce5bSJoe Perches		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
42883705ce5bSJoe Perches			if (WARN("SPACING",
42893705ce5bSJoe Perches				 "missing space after $1 definition\n" . $herecurr) &&
42903705ce5bSJoe Perches			    $fix) {
4291194f66fcSJoe Perches				$fixed[$fixlinenr] =~
42923705ce5bSJoe Perches				    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
42933705ce5bSJoe Perches			}
42940c73b4ebSAndy Whitcroft		}
42950c73b4ebSAndy Whitcroft
429631070b5dSJoe Perches# Function pointer declarations
429731070b5dSJoe Perches# check spacing between type, funcptr, and args
429831070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)"
429991f72e9cSJoe Perches		if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
430031070b5dSJoe Perches			my $declare = $1;
430131070b5dSJoe Perches			my $pre_pointer_space = $2;
430231070b5dSJoe Perches			my $post_pointer_space = $3;
430331070b5dSJoe Perches			my $funcname = $4;
430431070b5dSJoe Perches			my $post_funcname_space = $5;
430531070b5dSJoe Perches			my $pre_args_space = $6;
430631070b5dSJoe Perches
430791f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type
430891f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types
430991f72e9cSJoe Perches# don't need a space so don't warn for those.
431091f72e9cSJoe Perches			my $post_declare_space = "";
431191f72e9cSJoe Perches			if ($declare =~ /(\s+)$/) {
431291f72e9cSJoe Perches				$post_declare_space = $1;
431391f72e9cSJoe Perches				$declare = rtrim($declare);
431491f72e9cSJoe Perches			}
431591f72e9cSJoe Perches			if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
431631070b5dSJoe Perches				WARN("SPACING",
431731070b5dSJoe Perches				     "missing space after return type\n" . $herecurr);
431891f72e9cSJoe Perches				$post_declare_space = " ";
431931070b5dSJoe Perches			}
432031070b5dSJoe Perches
432131070b5dSJoe Perches# unnecessary space "type  (*funcptr)(args...)"
432291f72e9cSJoe Perches# This test is not currently implemented because these declarations are
432391f72e9cSJoe Perches# equivalent to
432491f72e9cSJoe Perches#	int  foo(int bar, ...)
432591f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning.
432691f72e9cSJoe Perches#
432791f72e9cSJoe Perches#			elsif ($declare =~ /\s{2,}$/) {
432891f72e9cSJoe Perches#				WARN("SPACING",
432991f72e9cSJoe Perches#				     "Multiple spaces after return type\n" . $herecurr);
433091f72e9cSJoe Perches#			}
433131070b5dSJoe Perches
433231070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)"
433331070b5dSJoe Perches			if (defined $pre_pointer_space &&
433431070b5dSJoe Perches			    $pre_pointer_space =~ /^\s/) {
433531070b5dSJoe Perches				WARN("SPACING",
433631070b5dSJoe Perches				     "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
433731070b5dSJoe Perches			}
433831070b5dSJoe Perches
433931070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)"
434031070b5dSJoe Perches			if (defined $post_pointer_space &&
434131070b5dSJoe Perches			    $post_pointer_space =~ /^\s/) {
434231070b5dSJoe Perches				WARN("SPACING",
434331070b5dSJoe Perches				     "Unnecessary space before function pointer name\n" . $herecurr);
434431070b5dSJoe Perches			}
434531070b5dSJoe Perches
434631070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)"
434731070b5dSJoe Perches			if (defined $post_funcname_space &&
434831070b5dSJoe Perches			    $post_funcname_space =~ /^\s/) {
434931070b5dSJoe Perches				WARN("SPACING",
435031070b5dSJoe Perches				     "Unnecessary space after function pointer name\n" . $herecurr);
435131070b5dSJoe Perches			}
435231070b5dSJoe Perches
435331070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)"
435431070b5dSJoe Perches			if (defined $pre_args_space &&
435531070b5dSJoe Perches			    $pre_args_space =~ /^\s/) {
435631070b5dSJoe Perches				WARN("SPACING",
435731070b5dSJoe Perches				     "Unnecessary space before function pointer arguments\n" . $herecurr);
435831070b5dSJoe Perches			}
435931070b5dSJoe Perches
436031070b5dSJoe Perches			if (show_type("SPACING") && $fix) {
4361194f66fcSJoe Perches				$fixed[$fixlinenr] =~
436291f72e9cSJoe Perches				    s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
436331070b5dSJoe Perches			}
436431070b5dSJoe Perches		}
436531070b5dSJoe Perches
43668d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed:
43678d31cfceSAndy Whitcroft#  1. with a type on the left -- int [] a;
4368fe2a7dbcSAndy Whitcroft#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
4369fe2a7dbcSAndy Whitcroft#  3. inside a curly brace -- = { [0...10] = 5 }
43708d31cfceSAndy Whitcroft		while ($line =~ /(.*?\s)\[/g) {
43718d31cfceSAndy Whitcroft			my ($where, $prefix) = ($-[1], $1);
43728d31cfceSAndy Whitcroft			if ($prefix !~ /$Type\s+$/ &&
4373fe2a7dbcSAndy Whitcroft			    ($where != 0 || $prefix !~ /^.\s+$/) &&
437438dca988SHeinrich Schuchardt			    $prefix !~ /[{,:]\s+$/) {
43753705ce5bSJoe Perches				if (ERROR("BRACKET_SPACE",
43763705ce5bSJoe Perches					  "space prohibited before open square bracket '['\n" . $herecurr) &&
43773705ce5bSJoe Perches				    $fix) {
4378194f66fcSJoe Perches				    $fixed[$fixlinenr] =~
43793705ce5bSJoe Perches					s/^(\+.*?)\s+\[/$1\[/;
43803705ce5bSJoe Perches				}
43818d31cfceSAndy Whitcroft			}
43828d31cfceSAndy Whitcroft		}
43838d31cfceSAndy Whitcroft
4384f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses.
43856c72ffaaSAndy Whitcroft		while ($line =~ /($Ident)\s+\(/g) {
4386c2fdda0dSAndy Whitcroft			my $name = $1;
4387773647a0SAndy Whitcroft			my $ctx_before = substr($line, 0, $-[1]);
4388773647a0SAndy Whitcroft			my $ctx = "$ctx_before$name";
4389c2fdda0dSAndy Whitcroft
4390c2fdda0dSAndy Whitcroft			# Ignore those directives where spaces _are_ permitted.
4391773647a0SAndy Whitcroft			if ($name =~ /^(?:
4392773647a0SAndy Whitcroft				if|for|while|switch|return|case|
4393773647a0SAndy Whitcroft				volatile|__volatile__|
4394773647a0SAndy Whitcroft				__attribute__|format|__extension__|
4395773647a0SAndy Whitcroft				asm|__asm__)$/x)
4396773647a0SAndy Whitcroft			{
4397c2fdda0dSAndy Whitcroft			# cpp #define statements have non-optional spaces, ie
4398c2fdda0dSAndy Whitcroft			# if there is a space between the name and the open
4399c2fdda0dSAndy Whitcroft			# parenthesis it is simply not a parameter group.
4400c45dcabdSAndy Whitcroft			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
4401773647a0SAndy Whitcroft
4402773647a0SAndy Whitcroft			# cpp #elif statement condition may start with a (
4403c45dcabdSAndy Whitcroft			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
4404c2fdda0dSAndy Whitcroft
4405c2fdda0dSAndy Whitcroft			# If this whole things ends with a type its most
4406c2fdda0dSAndy Whitcroft			# likely a typedef for a function.
4407773647a0SAndy Whitcroft			} elsif ($ctx =~ /$Type$/) {
4408c2fdda0dSAndy Whitcroft
4409c2fdda0dSAndy Whitcroft			} else {
44103705ce5bSJoe Perches				if (WARN("SPACING",
44113705ce5bSJoe Perches					 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
44123705ce5bSJoe Perches					     $fix) {
4413194f66fcSJoe Perches					$fixed[$fixlinenr] =~
44143705ce5bSJoe Perches					    s/\b$name\s+\(/$name\(/;
44153705ce5bSJoe Perches				}
4416f0a594c1SAndy Whitcroft			}
44176c72ffaaSAndy Whitcroft		}
44189a4cad4eSEric Nelson
4419653d4876SAndy Whitcroft# Check operator spacing.
44200a920b5bSAndy Whitcroft		if (!($line=~/\#\s*include/)) {
44213705ce5bSJoe Perches			my $fixed_line = "";
44223705ce5bSJoe Perches			my $line_fixed = 0;
44233705ce5bSJoe Perches
44249c0ca6f9SAndy Whitcroft			my $ops = qr{
44259c0ca6f9SAndy Whitcroft				<<=|>>=|<=|>=|==|!=|
44269c0ca6f9SAndy Whitcroft				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
44279c0ca6f9SAndy Whitcroft				=>|->|<<|>>|<|>|=|!|~|
44281f65f947SAndy Whitcroft				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
442984731623SJoe Perches				\?:|\?|:
44309c0ca6f9SAndy Whitcroft			}x;
4431cf655043SAndy Whitcroft			my @elements = split(/($ops|;)/, $opline);
44323705ce5bSJoe Perches
44333705ce5bSJoe Perches##			print("element count: <" . $#elements . ">\n");
44343705ce5bSJoe Perches##			foreach my $el (@elements) {
44353705ce5bSJoe Perches##				print("el: <$el>\n");
44363705ce5bSJoe Perches##			}
44373705ce5bSJoe Perches
44383705ce5bSJoe Perches			my @fix_elements = ();
443900df344fSAndy Whitcroft			my $off = 0;
44406c72ffaaSAndy Whitcroft
44413705ce5bSJoe Perches			foreach my $el (@elements) {
44423705ce5bSJoe Perches				push(@fix_elements, substr($rawline, $off, length($el)));
44433705ce5bSJoe Perches				$off += length($el);
44443705ce5bSJoe Perches			}
44453705ce5bSJoe Perches
44463705ce5bSJoe Perches			$off = 0;
44473705ce5bSJoe Perches
44486c72ffaaSAndy Whitcroft			my $blank = copy_spacing($opline);
4449b34c648bSJoe Perches			my $last_after = -1;
44506c72ffaaSAndy Whitcroft
44510a920b5bSAndy Whitcroft			for (my $n = 0; $n < $#elements; $n += 2) {
44523705ce5bSJoe Perches
44533705ce5bSJoe Perches				my $good = $fix_elements[$n] . $fix_elements[$n + 1];
44543705ce5bSJoe Perches
44553705ce5bSJoe Perches##				print("n: <$n> good: <$good>\n");
44563705ce5bSJoe Perches
44574a0df2efSAndy Whitcroft				$off += length($elements[$n]);
44584a0df2efSAndy Whitcroft
445925985edcSLucas De Marchi				# Pick up the preceding and succeeding characters.
4460773647a0SAndy Whitcroft				my $ca = substr($opline, 0, $off);
4461773647a0SAndy Whitcroft				my $cc = '';
4462773647a0SAndy Whitcroft				if (length($opline) >= ($off + length($elements[$n + 1]))) {
4463773647a0SAndy Whitcroft					$cc = substr($opline, $off + length($elements[$n + 1]));
4464773647a0SAndy Whitcroft				}
4465773647a0SAndy Whitcroft				my $cb = "$ca$;$cc";
4466773647a0SAndy Whitcroft
44674a0df2efSAndy Whitcroft				my $a = '';
44684a0df2efSAndy Whitcroft				$a = 'V' if ($elements[$n] ne '');
44694a0df2efSAndy Whitcroft				$a = 'W' if ($elements[$n] =~ /\s$/);
4470cf655043SAndy Whitcroft				$a = 'C' if ($elements[$n] =~ /$;$/);
44714a0df2efSAndy Whitcroft				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
44724a0df2efSAndy Whitcroft				$a = 'O' if ($elements[$n] eq '');
4473773647a0SAndy Whitcroft				$a = 'E' if ($ca =~ /^\s*$/);
44744a0df2efSAndy Whitcroft
44750a920b5bSAndy Whitcroft				my $op = $elements[$n + 1];
44764a0df2efSAndy Whitcroft
44774a0df2efSAndy Whitcroft				my $c = '';
44780a920b5bSAndy Whitcroft				if (defined $elements[$n + 2]) {
44794a0df2efSAndy Whitcroft					$c = 'V' if ($elements[$n + 2] ne '');
44804a0df2efSAndy Whitcroft					$c = 'W' if ($elements[$n + 2] =~ /^\s/);
4481cf655043SAndy Whitcroft					$c = 'C' if ($elements[$n + 2] =~ /^$;/);
44824a0df2efSAndy Whitcroft					$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
44834a0df2efSAndy Whitcroft					$c = 'O' if ($elements[$n + 2] eq '');
44848b1b3378SAndy Whitcroft					$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
44854a0df2efSAndy Whitcroft				} else {
44864a0df2efSAndy Whitcroft					$c = 'E';
44870a920b5bSAndy Whitcroft				}
44880a920b5bSAndy Whitcroft
44894a0df2efSAndy Whitcroft				my $ctx = "${a}x${c}";
44904a0df2efSAndy Whitcroft
44914a0df2efSAndy Whitcroft				my $at = "(ctx:$ctx)";
44924a0df2efSAndy Whitcroft
44936c72ffaaSAndy Whitcroft				my $ptr = substr($blank, 0, $off) . "^";
4494de7d4f0eSAndy Whitcroft				my $hereptr = "$hereline$ptr\n";
44950a920b5bSAndy Whitcroft
449674048ed8SAndy Whitcroft				# Pull out the value of this operator.
44976c72ffaaSAndy Whitcroft				my $op_type = substr($curr_values, $off + 1, 1);
44980a920b5bSAndy Whitcroft
44991f65f947SAndy Whitcroft				# Get the full operator variant.
45001f65f947SAndy Whitcroft				my $opv = $op . substr($curr_vars, $off, 1);
45011f65f947SAndy Whitcroft
450213214adfSAndy Whitcroft				# Ignore operators passed as parameters.
450313214adfSAndy Whitcroft				if ($op_type ne 'V' &&
4504d7fe8065SSam Bobroff				    $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
450513214adfSAndy Whitcroft
4506cf655043SAndy Whitcroft#				# Ignore comments
4507cf655043SAndy Whitcroft#				} elsif ($op =~ /^$;+$/) {
450813214adfSAndy Whitcroft
4509d8aaf121SAndy Whitcroft				# ; should have either the end of line or a space or \ after it
451013214adfSAndy Whitcroft				} elsif ($op eq ';') {
4511cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEBC]/ &&
4512cf655043SAndy Whitcroft					    $cc !~ /^\\/ && $cc !~ /^;/) {
45133705ce5bSJoe Perches						if (ERROR("SPACING",
45143705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
4515b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
45163705ce5bSJoe Perches							$line_fixed = 1;
45173705ce5bSJoe Perches						}
4518d8aaf121SAndy Whitcroft					}
4519d8aaf121SAndy Whitcroft
4520d8aaf121SAndy Whitcroft				# // is a comment
4521d8aaf121SAndy Whitcroft				} elsif ($op eq '//') {
45220a920b5bSAndy Whitcroft
4523b00e4814SJoe Perches				#   :   when part of a bitfield
4524b00e4814SJoe Perches				} elsif ($opv eq ':B') {
4525b00e4814SJoe Perches					# skip the bitfield test for now
4526b00e4814SJoe Perches
45271f65f947SAndy Whitcroft				# No spaces for:
45281f65f947SAndy Whitcroft				#   ->
4529b00e4814SJoe Perches				} elsif ($op eq '->') {
45304a0df2efSAndy Whitcroft					if ($ctx =~ /Wx.|.xW/) {
45313705ce5bSJoe Perches						if (ERROR("SPACING",
45323705ce5bSJoe Perches							  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
4533b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
45343705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
45353705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
45363705ce5bSJoe Perches							}
4537b34c648bSJoe Perches							$line_fixed = 1;
45383705ce5bSJoe Perches						}
45390a920b5bSAndy Whitcroft					}
45400a920b5bSAndy Whitcroft
45412381097bSJoe Perches				# , must not have a space before and must have a space on the right.
45420a920b5bSAndy Whitcroft				} elsif ($op eq ',') {
45432381097bSJoe Perches					my $rtrim_before = 0;
45442381097bSJoe Perches					my $space_after = 0;
45452381097bSJoe Perches					if ($ctx =~ /Wx./) {
45462381097bSJoe Perches						if (ERROR("SPACING",
45472381097bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
45482381097bSJoe Perches							$line_fixed = 1;
45492381097bSJoe Perches							$rtrim_before = 1;
45502381097bSJoe Perches						}
45512381097bSJoe Perches					}
4552cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
45533705ce5bSJoe Perches						if (ERROR("SPACING",
45543705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
45553705ce5bSJoe Perches							$line_fixed = 1;
4556b34c648bSJoe Perches							$last_after = $n;
45572381097bSJoe Perches							$space_after = 1;
45582381097bSJoe Perches						}
45592381097bSJoe Perches					}
45602381097bSJoe Perches					if ($rtrim_before || $space_after) {
45612381097bSJoe Perches						if ($rtrim_before) {
45622381097bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
45632381097bSJoe Perches						} else {
45642381097bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
45652381097bSJoe Perches						}
45662381097bSJoe Perches						if ($space_after) {
45672381097bSJoe Perches							$good .= " ";
45683705ce5bSJoe Perches						}
45690a920b5bSAndy Whitcroft					}
45700a920b5bSAndy Whitcroft
45719c0ca6f9SAndy Whitcroft				# '*' as part of a type definition -- reported already.
457274048ed8SAndy Whitcroft				} elsif ($opv eq '*_') {
45739c0ca6f9SAndy Whitcroft					#warn "'*' is part of type\n";
45749c0ca6f9SAndy Whitcroft
45759c0ca6f9SAndy Whitcroft				# unary operators should have a space before and
45769c0ca6f9SAndy Whitcroft				# none after.  May be left adjacent to another
45779c0ca6f9SAndy Whitcroft				# unary operator, or a cast
45789c0ca6f9SAndy Whitcroft				} elsif ($op eq '!' || $op eq '~' ||
457974048ed8SAndy Whitcroft					 $opv eq '*U' || $opv eq '-U' ||
45800d413866SAndy Whitcroft					 $opv eq '&U' || $opv eq '&&U') {
4581cf655043SAndy Whitcroft					if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
45823705ce5bSJoe Perches						if (ERROR("SPACING",
45833705ce5bSJoe Perches							  "space required before that '$op' $at\n" . $hereptr)) {
4584b34c648bSJoe Perches							if ($n != $last_after + 2) {
4585b34c648bSJoe Perches								$good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
45863705ce5bSJoe Perches								$line_fixed = 1;
45873705ce5bSJoe Perches							}
45880a920b5bSAndy Whitcroft						}
4589b34c648bSJoe Perches					}
4590a3340b35SAndy Whitcroft					if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
4591171ae1a4SAndy Whitcroft						# A unary '*' may be const
4592171ae1a4SAndy Whitcroft
4593171ae1a4SAndy Whitcroft					} elsif ($ctx =~ /.xW/) {
45943705ce5bSJoe Perches						if (ERROR("SPACING",
45953705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
4596b34c648bSJoe Perches							$good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
45973705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
45983705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
45993705ce5bSJoe Perches							}
4600b34c648bSJoe Perches							$line_fixed = 1;
46013705ce5bSJoe Perches						}
46020a920b5bSAndy Whitcroft					}
46030a920b5bSAndy Whitcroft
46040a920b5bSAndy Whitcroft				# unary ++ and unary -- are allowed no space on one side.
46050a920b5bSAndy Whitcroft				} elsif ($op eq '++' or $op eq '--') {
4606773647a0SAndy Whitcroft					if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
46073705ce5bSJoe Perches						if (ERROR("SPACING",
46083705ce5bSJoe Perches							  "space required one side of that '$op' $at\n" . $hereptr)) {
4609b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
46103705ce5bSJoe Perches							$line_fixed = 1;
46113705ce5bSJoe Perches						}
46120a920b5bSAndy Whitcroft					}
4613773647a0SAndy Whitcroft					if ($ctx =~ /Wx[BE]/ ||
4614773647a0SAndy Whitcroft					    ($ctx =~ /Wx./ && $cc =~ /^;/)) {
46153705ce5bSJoe Perches						if (ERROR("SPACING",
46163705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
4617b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
46183705ce5bSJoe Perches							$line_fixed = 1;
46193705ce5bSJoe Perches						}
4620653d4876SAndy Whitcroft					}
4621773647a0SAndy Whitcroft					if ($ctx =~ /ExW/) {
46223705ce5bSJoe Perches						if (ERROR("SPACING",
46233705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
4624b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
46253705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
46263705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4627773647a0SAndy Whitcroft							}
4628b34c648bSJoe Perches							$line_fixed = 1;
46293705ce5bSJoe Perches						}
46303705ce5bSJoe Perches					}
46310a920b5bSAndy Whitcroft
46320a920b5bSAndy Whitcroft				# << and >> may either have or not have spaces both sides
46339c0ca6f9SAndy Whitcroft				} elsif ($op eq '<<' or $op eq '>>' or
46349c0ca6f9SAndy Whitcroft					 $op eq '&' or $op eq '^' or $op eq '|' or
46359c0ca6f9SAndy Whitcroft					 $op eq '+' or $op eq '-' or
4636c2fdda0dSAndy Whitcroft					 $op eq '*' or $op eq '/' or
4637c2fdda0dSAndy Whitcroft					 $op eq '%')
46380a920b5bSAndy Whitcroft				{
4639d2e025f3SJoe Perches					if ($check) {
4640d2e025f3SJoe Perches						if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
4641d2e025f3SJoe Perches							if (CHK("SPACING",
4642d2e025f3SJoe Perches								"spaces preferred around that '$op' $at\n" . $hereptr)) {
4643d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4644d2e025f3SJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4645d2e025f3SJoe Perches								$line_fixed = 1;
4646d2e025f3SJoe Perches							}
4647d2e025f3SJoe Perches						} elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
4648d2e025f3SJoe Perches							if (CHK("SPACING",
4649d2e025f3SJoe Perches								"space preferred before that '$op' $at\n" . $hereptr)) {
4650d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
4651d2e025f3SJoe Perches								$line_fixed = 1;
4652d2e025f3SJoe Perches							}
4653d2e025f3SJoe Perches						}
4654d2e025f3SJoe Perches					} elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
46553705ce5bSJoe Perches						if (ERROR("SPACING",
46563705ce5bSJoe Perches							  "need consistent spacing around '$op' $at\n" . $hereptr)) {
4657b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4658b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
4659b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4660b34c648bSJoe Perches							}
46613705ce5bSJoe Perches							$line_fixed = 1;
46623705ce5bSJoe Perches						}
46630a920b5bSAndy Whitcroft					}
46640a920b5bSAndy Whitcroft
46651f65f947SAndy Whitcroft				# A colon needs no spaces before when it is
46661f65f947SAndy Whitcroft				# terminating a case value or a label.
46671f65f947SAndy Whitcroft				} elsif ($opv eq ':C' || $opv eq ':L') {
46681f65f947SAndy Whitcroft					if ($ctx =~ /Wx./) {
46693705ce5bSJoe Perches						if (ERROR("SPACING",
46703705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
4671b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
46723705ce5bSJoe Perches							$line_fixed = 1;
46733705ce5bSJoe Perches						}
46741f65f947SAndy Whitcroft					}
46751f65f947SAndy Whitcroft
46760a920b5bSAndy Whitcroft				# All the others need spaces both sides.
4677cf655043SAndy Whitcroft				} elsif ($ctx !~ /[EWC]x[CWE]/) {
46781f65f947SAndy Whitcroft					my $ok = 0;
46791f65f947SAndy Whitcroft
468022f2a2efSAndy Whitcroft					# Ignore email addresses <foo@bar>
46811f65f947SAndy Whitcroft					if (($op eq '<' &&
46821f65f947SAndy Whitcroft					     $cc =~ /^\S+\@\S+>/) ||
46831f65f947SAndy Whitcroft					    ($op eq '>' &&
46841f65f947SAndy Whitcroft					     $ca =~ /<\S+\@\S+$/))
46851f65f947SAndy Whitcroft					{
46861f65f947SAndy Whitcroft						$ok = 1;
46871f65f947SAndy Whitcroft					}
46881f65f947SAndy Whitcroft
4689e0df7e1fSJoe Perches					# for asm volatile statements
4690e0df7e1fSJoe Perches					# ignore a colon with another
4691e0df7e1fSJoe Perches					# colon immediately before or after
4692e0df7e1fSJoe Perches					if (($op eq ':') &&
4693e0df7e1fSJoe Perches					    ($ca =~ /:$/ || $cc =~ /^:/)) {
4694e0df7e1fSJoe Perches						$ok = 1;
4695e0df7e1fSJoe Perches					}
4696e0df7e1fSJoe Perches
469784731623SJoe Perches					# messages are ERROR, but ?: are CHK
46981f65f947SAndy Whitcroft					if ($ok == 0) {
46990675a8fbSJean Delvare						my $msg_level = \&ERROR;
47000675a8fbSJean Delvare						$msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
470184731623SJoe Perches
47020675a8fbSJean Delvare						if (&{$msg_level}("SPACING",
47033705ce5bSJoe Perches								  "spaces required around that '$op' $at\n" . $hereptr)) {
4704b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4705b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
4706b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4707b34c648bSJoe Perches							}
47083705ce5bSJoe Perches							$line_fixed = 1;
47093705ce5bSJoe Perches						}
47100a920b5bSAndy Whitcroft					}
471122f2a2efSAndy Whitcroft				}
47124a0df2efSAndy Whitcroft				$off += length($elements[$n + 1]);
47133705ce5bSJoe Perches
47143705ce5bSJoe Perches##				print("n: <$n> GOOD: <$good>\n");
47153705ce5bSJoe Perches
47163705ce5bSJoe Perches				$fixed_line = $fixed_line . $good;
47170a920b5bSAndy Whitcroft			}
47183705ce5bSJoe Perches
47193705ce5bSJoe Perches			if (($#elements % 2) == 0) {
47203705ce5bSJoe Perches				$fixed_line = $fixed_line . $fix_elements[$#elements];
47213705ce5bSJoe Perches			}
47223705ce5bSJoe Perches
4723194f66fcSJoe Perches			if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
4724194f66fcSJoe Perches				$fixed[$fixlinenr] = $fixed_line;
47253705ce5bSJoe Perches			}
47263705ce5bSJoe Perches
47273705ce5bSJoe Perches
47280a920b5bSAndy Whitcroft		}
47290a920b5bSAndy Whitcroft
4730786b6326SJoe Perches# check for whitespace before a non-naked semicolon
4731d2e248e7SJoe Perches		if ($line =~ /^\+.*\S\s+;\s*$/) {
4732786b6326SJoe Perches			if (WARN("SPACING",
4733786b6326SJoe Perches				 "space prohibited before semicolon\n" . $herecurr) &&
4734786b6326SJoe Perches			    $fix) {
4735194f66fcSJoe Perches				1 while $fixed[$fixlinenr] =~
4736786b6326SJoe Perches				    s/^(\+.*\S)\s+;/$1;/;
4737786b6326SJoe Perches			}
4738786b6326SJoe Perches		}
4739786b6326SJoe Perches
4740f0a594c1SAndy Whitcroft# check for multiple assignments
4741f0a594c1SAndy Whitcroft		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
4742000d1cc1SJoe Perches			CHK("MULTIPLE_ASSIGNMENTS",
4743000d1cc1SJoe Perches			    "multiple assignments should be avoided\n" . $herecurr);
4744f0a594c1SAndy Whitcroft		}
4745f0a594c1SAndy Whitcroft
474622f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration
474722f2a2efSAndy Whitcroft## # continuation.
474822f2a2efSAndy Whitcroft## 		if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
474922f2a2efSAndy Whitcroft## 		    $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
475022f2a2efSAndy Whitcroft##
475122f2a2efSAndy Whitcroft## 			# Remove any bracketed sections to ensure we do not
475222f2a2efSAndy Whitcroft## 			# falsly report the parameters of functions.
475322f2a2efSAndy Whitcroft## 			my $ln = $line;
475422f2a2efSAndy Whitcroft## 			while ($ln =~ s/\([^\(\)]*\)//g) {
475522f2a2efSAndy Whitcroft## 			}
475622f2a2efSAndy Whitcroft## 			if ($ln =~ /,/) {
4757000d1cc1SJoe Perches## 				WARN("MULTIPLE_DECLARATION",
4758000d1cc1SJoe Perches##				     "declaring multiple variables together should be avoided\n" . $herecurr);
475922f2a2efSAndy Whitcroft## 			}
476022f2a2efSAndy Whitcroft## 		}
4761f0a594c1SAndy Whitcroft
47620a920b5bSAndy Whitcroft#need space before brace following if, while, etc
47636b8c69e4SGeyslan G. Bem		if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
47646ad724e2SMichal Zylowski		    $line =~ /\b(?:else|do)\{/) {
47653705ce5bSJoe Perches			if (ERROR("SPACING",
47663705ce5bSJoe Perches				  "space required before the open brace '{'\n" . $herecurr) &&
47673705ce5bSJoe Perches			    $fix) {
47686ad724e2SMichal Zylowski				$fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/;
47693705ce5bSJoe Perches			}
4770de7d4f0eSAndy Whitcroft		}
4771de7d4f0eSAndy Whitcroft
4772c4a62ef9SJoe Perches## # check for blank lines before declarations
4773c4a62ef9SJoe Perches##		if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
4774c4a62ef9SJoe Perches##		    $prevrawline =~ /^.\s*$/) {
4775c4a62ef9SJoe Perches##			WARN("SPACING",
4776c4a62ef9SJoe Perches##			     "No blank lines before declarations\n" . $hereprev);
4777c4a62ef9SJoe Perches##		}
4778c4a62ef9SJoe Perches##
4779c4a62ef9SJoe Perches
4780de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything
4781de7d4f0eSAndy Whitcroft# on the line
478294fb9845SJoe Perches		if ($line =~ /}(?!(?:,|;|\)|\}))\S/) {
4783d5e616fcSJoe Perches			if (ERROR("SPACING",
4784d5e616fcSJoe Perches				  "space required after that close brace '}'\n" . $herecurr) &&
4785d5e616fcSJoe Perches			    $fix) {
4786194f66fcSJoe Perches				$fixed[$fixlinenr] =~
4787d5e616fcSJoe Perches				    s/}((?!(?:,|;|\)))\S)/} $1/;
4788d5e616fcSJoe Perches			}
47890a920b5bSAndy Whitcroft		}
47900a920b5bSAndy Whitcroft
479122f2a2efSAndy Whitcroft# check spacing on square brackets
479222f2a2efSAndy Whitcroft		if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
47933705ce5bSJoe Perches			if (ERROR("SPACING",
47943705ce5bSJoe Perches				  "space prohibited after that open square bracket '['\n" . $herecurr) &&
47953705ce5bSJoe Perches			    $fix) {
4796194f66fcSJoe Perches				$fixed[$fixlinenr] =~
47973705ce5bSJoe Perches				    s/\[\s+/\[/;
47983705ce5bSJoe Perches			}
479922f2a2efSAndy Whitcroft		}
480022f2a2efSAndy Whitcroft		if ($line =~ /\s\]/) {
48013705ce5bSJoe Perches			if (ERROR("SPACING",
48023705ce5bSJoe Perches				  "space prohibited before that close square bracket ']'\n" . $herecurr) &&
48033705ce5bSJoe Perches			    $fix) {
4804194f66fcSJoe Perches				$fixed[$fixlinenr] =~
48053705ce5bSJoe Perches				    s/\s+\]/\]/;
48063705ce5bSJoe Perches			}
480722f2a2efSAndy Whitcroft		}
480822f2a2efSAndy Whitcroft
4809c45dcabdSAndy Whitcroft# check spacing on parentheses
48109c0ca6f9SAndy Whitcroft		if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
48119c0ca6f9SAndy Whitcroft		    $line !~ /for\s*\(\s+;/) {
48123705ce5bSJoe Perches			if (ERROR("SPACING",
48133705ce5bSJoe Perches				  "space prohibited after that open parenthesis '('\n" . $herecurr) &&
48143705ce5bSJoe Perches			    $fix) {
4815194f66fcSJoe Perches				$fixed[$fixlinenr] =~
48163705ce5bSJoe Perches				    s/\(\s+/\(/;
48173705ce5bSJoe Perches			}
481822f2a2efSAndy Whitcroft		}
481913214adfSAndy Whitcroft		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
4820c45dcabdSAndy Whitcroft		    $line !~ /for\s*\(.*;\s+\)/ &&
4821c45dcabdSAndy Whitcroft		    $line !~ /:\s+\)/) {
48223705ce5bSJoe Perches			if (ERROR("SPACING",
48233705ce5bSJoe Perches				  "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
48243705ce5bSJoe Perches			    $fix) {
4825194f66fcSJoe Perches				$fixed[$fixlinenr] =~
48263705ce5bSJoe Perches				    s/\s+\)/\)/;
48273705ce5bSJoe Perches			}
482822f2a2efSAndy Whitcroft		}
482922f2a2efSAndy Whitcroft
4830e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals
4831e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
4832e2826fd0SJoe Perches
4833e2826fd0SJoe Perches		while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
4834ea4acbb1SJoe Perches			my $var = $1;
4835ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
4836ea4acbb1SJoe Perches				"Unnecessary parentheses around $var\n" . $herecurr) &&
4837ea4acbb1SJoe Perches			    $fix) {
4838ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
4839ea4acbb1SJoe Perches			}
4840ea4acbb1SJoe Perches		}
4841ea4acbb1SJoe Perches
4842ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses
4843ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar();
4844ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives
4845ea4acbb1SJoe Perches		if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
4846ea4acbb1SJoe Perches			my $var = $2;
4847ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
4848ea4acbb1SJoe Perches				"Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
4849ea4acbb1SJoe Perches			    $fix) {
4850ea4acbb1SJoe Perches				my $var2 = deparenthesize($var);
4851ea4acbb1SJoe Perches				$var2 =~ s/\s//g;
4852ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
4853ea4acbb1SJoe Perches			}
4854e2826fd0SJoe Perches		}
4855e2826fd0SJoe Perches
485663b7c73eSJoe Perches# check for unnecessary parentheses around comparisons in if uses
4857a032aa4cSJoe Perches# when !drivers/staging or command-line uses --strict
4858a032aa4cSJoe Perches		if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
48595b57980dSJoe Perches		    $perl_version_ok && defined($stat) &&
486063b7c73eSJoe Perches		    $stat =~ /(^.\s*if\s*($balanced_parens))/) {
486163b7c73eSJoe Perches			my $if_stat = $1;
486263b7c73eSJoe Perches			my $test = substr($2, 1, -1);
486363b7c73eSJoe Perches			my $herectx;
486463b7c73eSJoe Perches			while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) {
486563b7c73eSJoe Perches				my $match = $1;
486663b7c73eSJoe Perches				# avoid parentheses around potential macro args
486763b7c73eSJoe Perches				next if ($match =~ /^\s*\w+\s*$/);
486863b7c73eSJoe Perches				if (!defined($herectx)) {
486963b7c73eSJoe Perches					$herectx = $here . "\n";
487063b7c73eSJoe Perches					my $cnt = statement_rawlines($if_stat);
487163b7c73eSJoe Perches					for (my $n = 0; $n < $cnt; $n++) {
487263b7c73eSJoe Perches						my $rl = raw_line($linenr, $n);
487363b7c73eSJoe Perches						$herectx .=  $rl . "\n";
487463b7c73eSJoe Perches						last if $rl =~ /^[ \+].*\{/;
487563b7c73eSJoe Perches					}
487663b7c73eSJoe Perches				}
487763b7c73eSJoe Perches				CHK("UNNECESSARY_PARENTHESES",
487863b7c73eSJoe Perches				    "Unnecessary parentheses around '$match'\n" . $herectx);
487963b7c73eSJoe Perches			}
488063b7c73eSJoe Perches		}
488163b7c73eSJoe Perches
48820a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however
48834a0df2efSAndy Whitcroft		if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
48840a920b5bSAndy Whitcroft		   !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
48853705ce5bSJoe Perches			if (WARN("INDENTED_LABEL",
48863705ce5bSJoe Perches				 "labels should not be indented\n" . $herecurr) &&
48873705ce5bSJoe Perches			    $fix) {
4888194f66fcSJoe Perches				$fixed[$fixlinenr] =~
48893705ce5bSJoe Perches				    s/^(.)\s+/$1/;
48903705ce5bSJoe Perches			}
48910a920b5bSAndy Whitcroft		}
48920a920b5bSAndy Whitcroft
48935b9553abSJoe Perches# return is not a function
4894507e5141SJoe Perches		if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
4895c45dcabdSAndy Whitcroft			my $spacing = $1;
48965b57980dSJoe Perches			if ($perl_version_ok &&
48975b9553abSJoe Perches			    $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
48985b9553abSJoe Perches				my $value = $1;
48995b9553abSJoe Perches				$value = deparenthesize($value);
49005b9553abSJoe Perches				if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
4901000d1cc1SJoe Perches					ERROR("RETURN_PARENTHESES",
4902000d1cc1SJoe Perches					      "return is not a function, parentheses are not required\n" . $herecurr);
49035b9553abSJoe Perches				}
4904c45dcabdSAndy Whitcroft			} elsif ($spacing !~ /\s+/) {
4905000d1cc1SJoe Perches				ERROR("SPACING",
4906000d1cc1SJoe Perches				      "space required before the open parenthesis '('\n" . $herecurr);
4907c45dcabdSAndy Whitcroft			}
4908c45dcabdSAndy Whitcroft		}
4909507e5141SJoe Perches
4910b43ae21bSJoe Perches# unnecessary return in a void function
4911b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return;
4912b43ae21bSJoe Perches# and the line before that not a goto label target like "out:"
4913b43ae21bSJoe Perches		if ($sline =~ /^[ \+]}\s*$/ &&
4914b43ae21bSJoe Perches		    $prevline =~ /^\+\treturn\s*;\s*$/ &&
4915b43ae21bSJoe Perches		    $linenr >= 3 &&
4916b43ae21bSJoe Perches		    $lines[$linenr - 3] =~ /^[ +]/ &&
4917b43ae21bSJoe Perches		    $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
49189819cf25SJoe Perches			WARN("RETURN_VOID",
4919b43ae21bSJoe Perches			     "void function return statements are not generally useful\n" . $hereprev);
49209819cf25SJoe Perches               }
49219819cf25SJoe Perches
4922189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar))
49235b57980dSJoe Perches		if ($perl_version_ok &&
4924189248d8SJoe Perches		    $line =~ /\bif\s*((?:\(\s*){2,})/) {
4925189248d8SJoe Perches			my $openparens = $1;
4926189248d8SJoe Perches			my $count = $openparens =~ tr@\(@\(@;
4927189248d8SJoe Perches			my $msg = "";
4928189248d8SJoe Perches			if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
4929189248d8SJoe Perches				my $comp = $4;	#Not $1 because of $LvalOrFunc
4930189248d8SJoe Perches				$msg = " - maybe == should be = ?" if ($comp eq "==");
4931189248d8SJoe Perches				WARN("UNNECESSARY_PARENTHESES",
4932189248d8SJoe Perches				     "Unnecessary parentheses$msg\n" . $herecurr);
4933189248d8SJoe Perches			}
4934189248d8SJoe Perches		}
4935189248d8SJoe Perches
4936c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left
4937c5595fa2SJoe Perches#	avoid cases like "foo + BAR < baz"
4938c5595fa2SJoe Perches#	only fix matches surrounded by parentheses to avoid incorrect
4939c5595fa2SJoe Perches#	conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
49405b57980dSJoe Perches		if ($perl_version_ok &&
4941c5595fa2SJoe Perches		    $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
4942c5595fa2SJoe Perches			my $lead = $1;
4943c5595fa2SJoe Perches			my $const = $2;
4944c5595fa2SJoe Perches			my $comp = $3;
4945c5595fa2SJoe Perches			my $to = $4;
4946c5595fa2SJoe Perches			my $newcomp = $comp;
4947f39e1769SJoe Perches			if ($lead !~ /(?:$Operators|\.)\s*$/ &&
4948c5595fa2SJoe Perches			    $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
4949c5595fa2SJoe Perches			    WARN("CONSTANT_COMPARISON",
4950c5595fa2SJoe Perches				 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
4951c5595fa2SJoe Perches			    $fix) {
4952c5595fa2SJoe Perches				if ($comp eq "<") {
4953c5595fa2SJoe Perches					$newcomp = ">";
4954c5595fa2SJoe Perches				} elsif ($comp eq "<=") {
4955c5595fa2SJoe Perches					$newcomp = ">=";
4956c5595fa2SJoe Perches				} elsif ($comp eq ">") {
4957c5595fa2SJoe Perches					$newcomp = "<";
4958c5595fa2SJoe Perches				} elsif ($comp eq ">=") {
4959c5595fa2SJoe Perches					$newcomp = "<=";
4960c5595fa2SJoe Perches				}
4961c5595fa2SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
4962c5595fa2SJoe Perches			}
4963c5595fa2SJoe Perches		}
4964c5595fa2SJoe Perches
4965f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative
4966f34e4a4fSJoe Perches		if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
496753a3c448SAndy Whitcroft			my $name = $1;
496853a3c448SAndy Whitcroft			if ($name ne 'EOF' && $name ne 'ERROR') {
4969000d1cc1SJoe Perches				WARN("USE_NEGATIVE_ERRNO",
4970f34e4a4fSJoe Perches				     "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
497153a3c448SAndy Whitcroft			}
497253a3c448SAndy Whitcroft		}
4973c45dcabdSAndy Whitcroft
49740a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc
49754a0df2efSAndy Whitcroft		if ($line =~ /\b(if|while|for|switch)\(/) {
49763705ce5bSJoe Perches			if (ERROR("SPACING",
49773705ce5bSJoe Perches				  "space required before the open parenthesis '('\n" . $herecurr) &&
49783705ce5bSJoe Perches			    $fix) {
4979194f66fcSJoe Perches				$fixed[$fixlinenr] =~
49803705ce5bSJoe Perches				    s/\b(if|while|for|switch)\(/$1 \(/;
49813705ce5bSJoe Perches			}
49820a920b5bSAndy Whitcroft		}
49830a920b5bSAndy Whitcroft
4984f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing
4985f5fe35ddSAndy Whitcroft# statements after the conditional.
4986170d3a22SAndy Whitcroft		if ($line =~ /do\s*(?!{)/) {
49873e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
49883e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
49893e469cdcSAndy Whitcroft					if (!defined $stat);
4990170d3a22SAndy Whitcroft			my ($stat_next) = ctx_statement_block($line_nr_next,
4991170d3a22SAndy Whitcroft						$remain_next, $off_next);
4992170d3a22SAndy Whitcroft			$stat_next =~ s/\n./\n /g;
4993170d3a22SAndy Whitcroft			##print "stat<$stat> stat_next<$stat_next>\n";
4994170d3a22SAndy Whitcroft
4995170d3a22SAndy Whitcroft			if ($stat_next =~ /^\s*while\b/) {
4996170d3a22SAndy Whitcroft				# If the statement carries leading newlines,
4997170d3a22SAndy Whitcroft				# then count those as offsets.
4998170d3a22SAndy Whitcroft				my ($whitespace) =
4999170d3a22SAndy Whitcroft					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
5000170d3a22SAndy Whitcroft				my $offset =
5001170d3a22SAndy Whitcroft					statement_rawlines($whitespace) - 1;
5002170d3a22SAndy Whitcroft
5003170d3a22SAndy Whitcroft				$suppress_whiletrailers{$line_nr_next +
5004170d3a22SAndy Whitcroft								$offset} = 1;
5005170d3a22SAndy Whitcroft			}
5006170d3a22SAndy Whitcroft		}
5007170d3a22SAndy Whitcroft		if (!defined $suppress_whiletrailers{$linenr} &&
5008c11230f4SJoe Perches		    defined($stat) && defined($cond) &&
5009170d3a22SAndy Whitcroft		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
5010171ae1a4SAndy Whitcroft			my ($s, $c) = ($stat, $cond);
50118905a67cSAndy Whitcroft
5012b53c8e10SAndy Whitcroft			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
5013000d1cc1SJoe Perches				ERROR("ASSIGN_IN_IF",
5014000d1cc1SJoe Perches				      "do not use assignment in if condition\n" . $herecurr);
50158905a67cSAndy Whitcroft			}
50168905a67cSAndy Whitcroft
50178905a67cSAndy Whitcroft			# Find out what is on the end of the line after the
50188905a67cSAndy Whitcroft			# conditional.
5019773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
50208905a67cSAndy Whitcroft			$s =~ s/\n.*//g;
502113214adfSAndy Whitcroft			$s =~ s/$;//g;	# Remove any comments
502253210168SAndy Whitcroft			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
502353210168SAndy Whitcroft			    $c !~ /}\s*while\s*/)
5024773647a0SAndy Whitcroft			{
5025bb44ad39SAndy Whitcroft				# Find out how long the conditional actually is.
5026bb44ad39SAndy Whitcroft				my @newlines = ($c =~ /\n/gs);
5027bb44ad39SAndy Whitcroft				my $cond_lines = 1 + $#newlines;
502842bdf74cSHidetoshi Seto				my $stat_real = '';
5029bb44ad39SAndy Whitcroft
503042bdf74cSHidetoshi Seto				$stat_real = raw_line($linenr, $cond_lines)
503142bdf74cSHidetoshi Seto							. "\n" if ($cond_lines);
5032bb44ad39SAndy Whitcroft				if (defined($stat_real) && $cond_lines > 1) {
5033bb44ad39SAndy Whitcroft					$stat_real = "[...]\n$stat_real";
5034bb44ad39SAndy Whitcroft				}
5035bb44ad39SAndy Whitcroft
5036000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
5037000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr . $stat_real);
50388905a67cSAndy Whitcroft			}
50398905a67cSAndy Whitcroft		}
50408905a67cSAndy Whitcroft
504113214adfSAndy Whitcroft# Check for bitwise tests written as boolean
504213214adfSAndy Whitcroft		if ($line =~ /
504313214adfSAndy Whitcroft			(?:
504413214adfSAndy Whitcroft				(?:\[|\(|\&\&|\|\|)
504513214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
504613214adfSAndy Whitcroft				(?:\&\&|\|\|)
504713214adfSAndy Whitcroft			|
504813214adfSAndy Whitcroft				(?:\&\&|\|\|)
504913214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
505013214adfSAndy Whitcroft				(?:\&\&|\|\||\)|\])
505113214adfSAndy Whitcroft			)/x)
505213214adfSAndy Whitcroft		{
5053000d1cc1SJoe Perches			WARN("HEXADECIMAL_BOOLEAN_TEST",
5054000d1cc1SJoe Perches			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
505513214adfSAndy Whitcroft		}
505613214adfSAndy Whitcroft
50578905a67cSAndy Whitcroft# if and else should not have general statements after it
505813214adfSAndy Whitcroft		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
505913214adfSAndy Whitcroft			my $s = $1;
506013214adfSAndy Whitcroft			$s =~ s/$;//g;	# Remove any comments
506113214adfSAndy Whitcroft			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
5062000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
5063000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr);
50640a920b5bSAndy Whitcroft			}
506513214adfSAndy Whitcroft		}
506639667782SAndy Whitcroft# if should not continue a brace
506739667782SAndy Whitcroft		if ($line =~ /}\s*if\b/) {
5068000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
5069048b123fSRasmus Villemoes			      "trailing statements should be on next line (or did you mean 'else if'?)\n" .
507039667782SAndy Whitcroft				$herecurr);
507139667782SAndy Whitcroft		}
5072a1080bf8SAndy Whitcroft# case and default should not have general statements after them
5073a1080bf8SAndy Whitcroft		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
5074a1080bf8SAndy Whitcroft		    $line !~ /\G(?:
50753fef12d6SAndy Whitcroft			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
5076a1080bf8SAndy Whitcroft			\s*return\s+
5077a1080bf8SAndy Whitcroft		    )/xg)
5078a1080bf8SAndy Whitcroft		{
5079000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
5080000d1cc1SJoe Perches			      "trailing statements should be on next line\n" . $herecurr);
5081a1080bf8SAndy Whitcroft		}
50820a920b5bSAndy Whitcroft
50830a920b5bSAndy Whitcroft		# Check for }<nl>else {, these must be at the same
50840a920b5bSAndy Whitcroft		# indent level to be relevant to each other.
50858b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
50860a920b5bSAndy Whitcroft		    $previndent == $indent) {
50878b8856f4SJoe Perches			if (ERROR("ELSE_AFTER_BRACE",
50888b8856f4SJoe Perches				  "else should follow close brace '}'\n" . $hereprev) &&
50898b8856f4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
50908b8856f4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
50918b8856f4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
50928b8856f4SJoe Perches				my $fixedline = $prevrawline;
50938b8856f4SJoe Perches				$fixedline =~ s/}\s*$//;
50948b8856f4SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
50958b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
50968b8856f4SJoe Perches				}
50978b8856f4SJoe Perches				$fixedline = $rawline;
50988b8856f4SJoe Perches				$fixedline =~ s/^(.\s*)else/$1} else/;
50998b8856f4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
51008b8856f4SJoe Perches			}
51010a920b5bSAndy Whitcroft		}
51020a920b5bSAndy Whitcroft
51038b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
5104c2fdda0dSAndy Whitcroft		    $previndent == $indent) {
5105c2fdda0dSAndy Whitcroft			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
5106c2fdda0dSAndy Whitcroft
5107c2fdda0dSAndy Whitcroft			# Find out what is on the end of the line after the
5108c2fdda0dSAndy Whitcroft			# conditional.
5109773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
5110c2fdda0dSAndy Whitcroft			$s =~ s/\n.*//g;
5111c2fdda0dSAndy Whitcroft
5112c2fdda0dSAndy Whitcroft			if ($s =~ /^\s*;/) {
51138b8856f4SJoe Perches				if (ERROR("WHILE_AFTER_BRACE",
51148b8856f4SJoe Perches					  "while should follow close brace '}'\n" . $hereprev) &&
51158b8856f4SJoe Perches				    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
51168b8856f4SJoe Perches					fix_delete_line($fixlinenr - 1, $prevrawline);
51178b8856f4SJoe Perches					fix_delete_line($fixlinenr, $rawline);
51188b8856f4SJoe Perches					my $fixedline = $prevrawline;
51198b8856f4SJoe Perches					my $trailing = $rawline;
51208b8856f4SJoe Perches					$trailing =~ s/^\+//;
51218b8856f4SJoe Perches					$trailing = trim($trailing);
51228b8856f4SJoe Perches					$fixedline =~ s/}\s*$/} $trailing/;
51238b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
51248b8856f4SJoe Perches				}
5125c2fdda0dSAndy Whitcroft			}
5126c2fdda0dSAndy Whitcroft		}
5127c2fdda0dSAndy Whitcroft
512895e2c602SJoe Perches#Specific variable tests
5129323c1260SJoe Perches		while ($line =~ m{($Constant|$Lval)}g) {
5130323c1260SJoe Perches			my $var = $1;
513195e2c602SJoe Perches
513295e2c602SJoe Perches#CamelCase
5133807bd26cSJoe Perches			if ($var !~ /^$Constant$/ &&
5134be79794bSJoe Perches			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
513522735ce8SJoe Perches#Ignore Page<foo> variants
5136807bd26cSJoe Perches			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
5137d439e6a5SJoe Perches#Ignore SI style variants like nS, mV and dB
5138d439e6a5SJoe Perches#(ie: max_uV, regulator_min_uA_show, RANGE_mA_VALUE)
5139d439e6a5SJoe Perches			    $var !~ /^(?:[a-z0-9_]*|[A-Z0-9_]*)?_?[a-z][A-Z](?:_[a-z0-9_]+|_[A-Z0-9_]+)?$/ &&
5140f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz
5141f5123576SJulius Werner			    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
51427e781f67SJoe Perches				while ($var =~ m{($Ident)}g) {
51437e781f67SJoe Perches					my $word = $1;
51447e781f67SJoe Perches					next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
5145d8b07710SJoe Perches					if ($check) {
5146d8b07710SJoe Perches						seed_camelcase_includes();
5147d8b07710SJoe Perches						if (!$file && !$camelcase_file_seeded) {
5148d8b07710SJoe Perches							seed_camelcase_file($realfile);
5149d8b07710SJoe Perches							$camelcase_file_seeded = 1;
5150d8b07710SJoe Perches						}
5151d8b07710SJoe Perches					}
51527e781f67SJoe Perches					if (!defined $camelcase{$word}) {
51537e781f67SJoe Perches						$camelcase{$word} = 1;
5154be79794bSJoe Perches						CHK("CAMELCASE",
51557e781f67SJoe Perches						    "Avoid CamelCase: <$word>\n" . $herecurr);
51567e781f67SJoe Perches					}
5157323c1260SJoe Perches				}
5158323c1260SJoe Perches			}
51593445686aSJoe Perches		}
51600a920b5bSAndy Whitcroft
51610a920b5bSAndy Whitcroft#no spaces allowed after \ in define
5162d5e616fcSJoe Perches		if ($line =~ /\#\s*define.*\\\s+$/) {
5163d5e616fcSJoe Perches			if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
5164d5e616fcSJoe Perches				 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
5165d5e616fcSJoe Perches			    $fix) {
5166194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
5167d5e616fcSJoe Perches			}
51680a920b5bSAndy Whitcroft		}
51690a920b5bSAndy Whitcroft
51700e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
51710e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line)
5172c45dcabdSAndy Whitcroft		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
5173e09dec48SAndy Whitcroft			my $file = "$1.h";
5174e09dec48SAndy Whitcroft			my $checkfile = "include/linux/$file";
5175e09dec48SAndy Whitcroft			if (-f "$root/$checkfile" &&
5176e09dec48SAndy Whitcroft			    $realfile ne $checkfile &&
51777840a94cSWolfram Sang			    $1 !~ /$allowed_asm_includes/)
5178c45dcabdSAndy Whitcroft			{
51790e212e0aSFabian Frederick				my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
51800e212e0aSFabian Frederick				if ($asminclude > 0) {
5181e09dec48SAndy Whitcroft					if ($realfile =~ m{^arch/}) {
5182000d1cc1SJoe Perches						CHK("ARCH_INCLUDE_LINUX",
5183000d1cc1SJoe Perches						    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5184e09dec48SAndy Whitcroft					} else {
5185000d1cc1SJoe Perches						WARN("INCLUDE_LINUX",
5186000d1cc1SJoe Perches						     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5187e09dec48SAndy Whitcroft					}
51880a920b5bSAndy Whitcroft				}
51890a920b5bSAndy Whitcroft			}
51900e212e0aSFabian Frederick		}
51910a920b5bSAndy Whitcroft
5192653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the
5193653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed
5194cf655043SAndy Whitcroft# in a known good container
5195b8f96a31SAndy Whitcroft		if ($realfile !~ m@/vmlinux.lds.h$@ &&
5196b8f96a31SAndy Whitcroft		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
5197d8aaf121SAndy Whitcroft			my $ln = $linenr;
5198d8aaf121SAndy Whitcroft			my $cnt = $realcnt;
5199c45dcabdSAndy Whitcroft			my ($off, $dstat, $dcond, $rest);
5200c45dcabdSAndy Whitcroft			my $ctx = '';
520108a2843eSJoe Perches			my $has_flow_statement = 0;
520208a2843eSJoe Perches			my $has_arg_concat = 0;
5203c45dcabdSAndy Whitcroft			($dstat, $dcond, $ln, $cnt, $off) =
5204f74bd194SAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
5205f74bd194SAndy Whitcroft			$ctx = $dstat;
5206c45dcabdSAndy Whitcroft			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
5207a3bb97a7SAndy Whitcroft			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
5208c45dcabdSAndy Whitcroft
520908a2843eSJoe Perches			$has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
521062e15a6dSJoe Perches			$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
521108a2843eSJoe Perches
5212f59b64bfSJoe Perches			$dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
5213f59b64bfSJoe Perches			my $define_args = $1;
5214f59b64bfSJoe Perches			my $define_stmt = $dstat;
5215f59b64bfSJoe Perches			my @def_args = ();
5216f59b64bfSJoe Perches
5217f59b64bfSJoe Perches			if (defined $define_args && $define_args ne "") {
5218f59b64bfSJoe Perches				$define_args = substr($define_args, 1, length($define_args) - 2);
5219f59b64bfSJoe Perches				$define_args =~ s/\s*//g;
52208c8c45cfSJoe Perches				$define_args =~ s/\\\+?//g;
5221f59b64bfSJoe Perches				@def_args = split(",", $define_args);
5222f59b64bfSJoe Perches			}
5223f59b64bfSJoe Perches
5224292f1a9bSAndy Whitcroft			$dstat =~ s/$;//g;
5225c45dcabdSAndy Whitcroft			$dstat =~ s/\\\n.//g;
5226c45dcabdSAndy Whitcroft			$dstat =~ s/^\s*//s;
5227c45dcabdSAndy Whitcroft			$dstat =~ s/\s*$//s;
5228c45dcabdSAndy Whitcroft
5229c45dcabdSAndy Whitcroft			# Flatten any parentheses and braces
5230bf30d6edSAndy Whitcroft			while ($dstat =~ s/\([^\(\)]*\)/1/ ||
5231bf30d6edSAndy Whitcroft			       $dstat =~ s/\{[^\{\}]*\}/1/ ||
52326b10df42SVladimir Zapolskiy			       $dstat =~ s/.\[[^\[\]]*\]/1/)
5233bf30d6edSAndy Whitcroft			{
5234c45dcabdSAndy Whitcroft			}
5235c45dcabdSAndy Whitcroft
5236342d3d2fSAntonio Borneo			# Flatten any obvious string concatenation.
523733acb54aSJoe Perches			while ($dstat =~ s/($String)\s*$Ident/$1/ ||
523833acb54aSJoe Perches			       $dstat =~ s/$Ident\s*($String)/$1/)
5239e45bab8eSAndy Whitcroft			{
5240e45bab8eSAndy Whitcroft			}
5241e45bab8eSAndy Whitcroft
524242e15293SJoe Perches			# Make asm volatile uses seem like a generic function
524342e15293SJoe Perches			$dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
524442e15293SJoe Perches
5245c45dcabdSAndy Whitcroft			my $exceptions = qr{
5246c45dcabdSAndy Whitcroft				$Declare|
5247c45dcabdSAndy Whitcroft				module_param_named|
5248a0a0a7a9SKees Cook				MODULE_PARM_DESC|
5249c45dcabdSAndy Whitcroft				DECLARE_PER_CPU|
5250c45dcabdSAndy Whitcroft				DEFINE_PER_CPU|
5251383099fdSAndy Whitcroft				__typeof__\(|
525222fd2d3eSStefani Seibold				union|
525322fd2d3eSStefani Seibold				struct|
5254ea71a0a0SAndy Whitcroft				\.$Ident\s*=\s*|
52556b10df42SVladimir Zapolskiy				^\"|\"$|
52566b10df42SVladimir Zapolskiy				^\[
5257c45dcabdSAndy Whitcroft			}x;
52585eaa20b9SAndy Whitcroft			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
5259f59b64bfSJoe Perches
5260f59b64bfSJoe Perches			$ctx =~ s/\n*$//;
5261f59b64bfSJoe Perches			my $stmt_cnt = statement_rawlines($ctx);
5262e3d95a2aSTobin C. Harding			my $herectx = get_stat_here($linenr, $stmt_cnt, $here);
5263f59b64bfSJoe Perches
5264f74bd194SAndy Whitcroft			if ($dstat ne '' &&
5265f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),
5266f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();
52673cc4b1c3SJoe Perches			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
5268356fd398SJoe Perches			    $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ &&			# character constants
5269f74bd194SAndy Whitcroft			    $dstat !~ /$exceptions/ &&
5270f74bd194SAndy Whitcroft			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
5271e942e2c3SJoe Perches			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #foo
527272f115f9SAndy Whitcroft			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
5273f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
5274f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
5275f74bd194SAndy Whitcroft			    $dstat !~ /^do\s*{/ &&					# do {...
52764e5d56bdSEddie Kovsky			    $dstat !~ /^\(\{/ &&						# ({...
5277f95a7e6aSJoe Perches			    $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
5278c45dcabdSAndy Whitcroft			{
5279e795556aSJoe Perches				if ($dstat =~ /^\s*if\b/) {
5280e795556aSJoe Perches					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5281e795556aSJoe Perches					      "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
5282e795556aSJoe Perches				} elsif ($dstat =~ /;/) {
5283f74bd194SAndy Whitcroft					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5284f74bd194SAndy Whitcroft					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
5285f74bd194SAndy Whitcroft				} else {
5286000d1cc1SJoe Perches					ERROR("COMPLEX_MACRO",
5287388982b5SAndrew Morton					      "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
5288d8aaf121SAndy Whitcroft				}
5289f59b64bfSJoe Perches
5290f59b64bfSJoe Perches			}
52915207649bSJoe Perches
52925207649bSJoe Perches			# Make $define_stmt single line, comment-free, etc
52935207649bSJoe Perches			my @stmt_array = split('\n', $define_stmt);
52945207649bSJoe Perches			my $first = 1;
52955207649bSJoe Perches			$define_stmt = "";
52965207649bSJoe Perches			foreach my $l (@stmt_array) {
52975207649bSJoe Perches				$l =~ s/\\$//;
52985207649bSJoe Perches				if ($first) {
52995207649bSJoe Perches					$define_stmt = $l;
53005207649bSJoe Perches					$first = 0;
53015207649bSJoe Perches				} elsif ($l =~ /^[\+ ]/) {
53025207649bSJoe Perches					$define_stmt .= substr($l, 1);
53035207649bSJoe Perches				}
53045207649bSJoe Perches			}
53055207649bSJoe Perches			$define_stmt =~ s/$;//g;
53065207649bSJoe Perches			$define_stmt =~ s/\s+/ /g;
53075207649bSJoe Perches			$define_stmt = trim($define_stmt);
53085207649bSJoe Perches
5309f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type')
5310f59b64bfSJoe Perches			foreach my $arg (@def_args) {
5311f59b64bfSJoe Perches			        next if ($arg =~ /\.\.\./);
53129192d41aSJoe Perches			        next if ($arg =~ /^type$/i);
53137fe528a2SJoe Perches				my $tmp_stmt = $define_stmt;
53146dba824eSBrendan Jackman				$tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
53157fe528a2SJoe Perches				$tmp_stmt =~ s/\#+\s*$arg\b//g;
53167fe528a2SJoe Perches				$tmp_stmt =~ s/\b$arg\s*\#\#//g;
5317d41362edSJoe Perches				my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
5318f59b64bfSJoe Perches				if ($use_cnt > 1) {
5319f59b64bfSJoe Perches					CHK("MACRO_ARG_REUSE",
5320f59b64bfSJoe Perches					    "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
5321f59b64bfSJoe Perches				    }
53229192d41aSJoe Perches# check if any macro arguments may have other precedence issues
53237fe528a2SJoe Perches				if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
53249192d41aSJoe Perches				    ((defined($1) && $1 ne ',') ||
53259192d41aSJoe Perches				     (defined($2) && $2 ne ','))) {
53269192d41aSJoe Perches					CHK("MACRO_ARG_PRECEDENCE",
53279192d41aSJoe Perches					    "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
53289192d41aSJoe Perches				}
53290a920b5bSAndy Whitcroft			}
53305023d347SJoe Perches
533108a2843eSJoe Perches# check for macros with flow control, but without ## concatenation
533208a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those
533308a2843eSJoe Perches			if ($has_flow_statement && !$has_arg_concat) {
533408a2843eSJoe Perches				my $cnt = statement_rawlines($ctx);
5335e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
533608a2843eSJoe Perches
533708a2843eSJoe Perches				WARN("MACRO_WITH_FLOW_CONTROL",
533808a2843eSJoe Perches				     "Macros with flow control statements should be avoided\n" . "$herectx");
533908a2843eSJoe Perches			}
534008a2843eSJoe Perches
5341481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm
53425023d347SJoe Perches
53435023d347SJoe Perches		} else {
53445023d347SJoe Perches			if ($prevline !~ /^..*\\$/ &&
5345481eb486SJoe Perches			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
5346481eb486SJoe Perches			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
53475023d347SJoe Perches			    $line =~ /^\+.*\\$/) {
53485023d347SJoe Perches				WARN("LINE_CONTINUATIONS",
53495023d347SJoe Perches				     "Avoid unnecessary line continuations\n" . $herecurr);
53505023d347SJoe Perches			}
5351653d4876SAndy Whitcroft		}
53520a920b5bSAndy Whitcroft
5353b13edf7fSJoe Perches# do {} while (0) macro tests:
5354b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop,
5355b13edf7fSJoe Perches# macro should not end with a semicolon
53565b57980dSJoe Perches		if ($perl_version_ok &&
5357b13edf7fSJoe Perches		    $realfile !~ m@/vmlinux.lds.h$@ &&
5358b13edf7fSJoe Perches		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
5359b13edf7fSJoe Perches			my $ln = $linenr;
5360b13edf7fSJoe Perches			my $cnt = $realcnt;
5361b13edf7fSJoe Perches			my ($off, $dstat, $dcond, $rest);
5362b13edf7fSJoe Perches			my $ctx = '';
5363b13edf7fSJoe Perches			($dstat, $dcond, $ln, $cnt, $off) =
5364b13edf7fSJoe Perches				ctx_statement_block($linenr, $realcnt, 0);
5365b13edf7fSJoe Perches			$ctx = $dstat;
5366b13edf7fSJoe Perches
5367b13edf7fSJoe Perches			$dstat =~ s/\\\n.//g;
53681b36b201SJoe Perches			$dstat =~ s/$;/ /g;
5369b13edf7fSJoe Perches
5370b13edf7fSJoe Perches			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
5371b13edf7fSJoe Perches				my $stmts = $2;
5372b13edf7fSJoe Perches				my $semis = $3;
5373b13edf7fSJoe Perches
5374b13edf7fSJoe Perches				$ctx =~ s/\n*$//;
5375b13edf7fSJoe Perches				my $cnt = statement_rawlines($ctx);
5376e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
5377b13edf7fSJoe Perches
5378ac8e97f8SJoe Perches				if (($stmts =~ tr/;/;/) == 1 &&
5379ac8e97f8SJoe Perches				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
5380b13edf7fSJoe Perches					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
5381b13edf7fSJoe Perches					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
5382b13edf7fSJoe Perches				}
5383b13edf7fSJoe Perches				if (defined $semis && $semis ne "") {
5384b13edf7fSJoe Perches					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
5385b13edf7fSJoe Perches					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
5386b13edf7fSJoe Perches				}
5387f5ef95b1SJoe Perches			} elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
5388f5ef95b1SJoe Perches				$ctx =~ s/\n*$//;
5389f5ef95b1SJoe Perches				my $cnt = statement_rawlines($ctx);
5390e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
5391f5ef95b1SJoe Perches
5392f5ef95b1SJoe Perches				WARN("TRAILING_SEMICOLON",
5393f5ef95b1SJoe Perches				     "macros should not use a trailing semicolon\n" . "$herectx");
5394b13edf7fSJoe Perches			}
5395b13edf7fSJoe Perches		}
5396b13edf7fSJoe Perches
5397f0a594c1SAndy Whitcroft# check for redundant bracing round if etc
539813214adfSAndy Whitcroft		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
539913214adfSAndy Whitcroft			my ($level, $endln, @chunks) =
5400cf655043SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, 1);
540113214adfSAndy Whitcroft			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
5402cf655043SAndy Whitcroft			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
5403cf655043SAndy Whitcroft			if ($#chunks > 0 && $level == 0) {
5404aad4f614SJoe Perches				my @allowed = ();
5405aad4f614SJoe Perches				my $allow = 0;
540613214adfSAndy Whitcroft				my $seen = 0;
5407773647a0SAndy Whitcroft				my $herectx = $here . "\n";
5408cf655043SAndy Whitcroft				my $ln = $linenr - 1;
540913214adfSAndy Whitcroft				for my $chunk (@chunks) {
541013214adfSAndy Whitcroft					my ($cond, $block) = @{$chunk};
541113214adfSAndy Whitcroft
5412773647a0SAndy Whitcroft					# If the condition carries leading newlines, then count those as offsets.
5413773647a0SAndy Whitcroft					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
5414773647a0SAndy Whitcroft					my $offset = statement_rawlines($whitespace) - 1;
5415773647a0SAndy Whitcroft
5416aad4f614SJoe Perches					$allowed[$allow] = 0;
5417773647a0SAndy Whitcroft					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
5418773647a0SAndy Whitcroft
5419773647a0SAndy Whitcroft					# We have looked at and allowed this specific line.
5420773647a0SAndy Whitcroft					$suppress_ifbraces{$ln + $offset} = 1;
5421773647a0SAndy Whitcroft
5422773647a0SAndy Whitcroft					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
5423cf655043SAndy Whitcroft					$ln += statement_rawlines($block) - 1;
5424cf655043SAndy Whitcroft
5425773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
542613214adfSAndy Whitcroft
542713214adfSAndy Whitcroft					$seen++ if ($block =~ /^\s*{/);
542813214adfSAndy Whitcroft
5429aad4f614SJoe Perches					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
5430cf655043SAndy Whitcroft					if (statement_lines($cond) > 1) {
5431cf655043SAndy Whitcroft						#print "APW: ALLOWED: cond<$cond>\n";
5432aad4f614SJoe Perches						$allowed[$allow] = 1;
543313214adfSAndy Whitcroft					}
543413214adfSAndy Whitcroft					if ($block =~/\b(?:if|for|while)\b/) {
5435cf655043SAndy Whitcroft						#print "APW: ALLOWED: block<$block>\n";
5436aad4f614SJoe Perches						$allowed[$allow] = 1;
543713214adfSAndy Whitcroft					}
5438cf655043SAndy Whitcroft					if (statement_block_size($block) > 1) {
5439cf655043SAndy Whitcroft						#print "APW: ALLOWED: lines block<$block>\n";
5440aad4f614SJoe Perches						$allowed[$allow] = 1;
544113214adfSAndy Whitcroft					}
5442aad4f614SJoe Perches					$allow++;
544313214adfSAndy Whitcroft				}
5444aad4f614SJoe Perches				if ($seen) {
5445aad4f614SJoe Perches					my $sum_allowed = 0;
5446aad4f614SJoe Perches					foreach (@allowed) {
5447aad4f614SJoe Perches						$sum_allowed += $_;
5448aad4f614SJoe Perches					}
5449aad4f614SJoe Perches					if ($sum_allowed == 0) {
5450000d1cc1SJoe Perches						WARN("BRACES",
5451000d1cc1SJoe Perches						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
5452aad4f614SJoe Perches					} elsif ($sum_allowed != $allow &&
5453aad4f614SJoe Perches						 $seen != $allow) {
5454aad4f614SJoe Perches						CHK("BRACES",
5455aad4f614SJoe Perches						    "braces {} should be used on all arms of this statement\n" . $herectx);
5456aad4f614SJoe Perches					}
545713214adfSAndy Whitcroft				}
545813214adfSAndy Whitcroft			}
545913214adfSAndy Whitcroft		}
5460773647a0SAndy Whitcroft		if (!defined $suppress_ifbraces{$linenr - 1} &&
546113214adfSAndy Whitcroft					$line =~ /\b(if|while|for|else)\b/) {
5462cf655043SAndy Whitcroft			my $allowed = 0;
5463f0a594c1SAndy Whitcroft
5464cf655043SAndy Whitcroft			# Check the pre-context.
5465cf655043SAndy Whitcroft			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
5466cf655043SAndy Whitcroft				#print "APW: ALLOWED: pre<$1>\n";
5467cf655043SAndy Whitcroft				$allowed = 1;
5468f0a594c1SAndy Whitcroft			}
5469773647a0SAndy Whitcroft
5470773647a0SAndy Whitcroft			my ($level, $endln, @chunks) =
5471773647a0SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, $-[0]);
5472773647a0SAndy Whitcroft
5473cf655043SAndy Whitcroft			# Check the condition.
5474cf655043SAndy Whitcroft			my ($cond, $block) = @{$chunks[0]};
5475773647a0SAndy Whitcroft			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
5476cf655043SAndy Whitcroft			if (defined $cond) {
5477773647a0SAndy Whitcroft				substr($block, 0, length($cond), '');
5478cf655043SAndy Whitcroft			}
5479cf655043SAndy Whitcroft			if (statement_lines($cond) > 1) {
5480cf655043SAndy Whitcroft				#print "APW: ALLOWED: cond<$cond>\n";
5481cf655043SAndy Whitcroft				$allowed = 1;
5482cf655043SAndy Whitcroft			}
5483cf655043SAndy Whitcroft			if ($block =~/\b(?:if|for|while)\b/) {
5484cf655043SAndy Whitcroft				#print "APW: ALLOWED: block<$block>\n";
5485cf655043SAndy Whitcroft				$allowed = 1;
5486cf655043SAndy Whitcroft			}
5487cf655043SAndy Whitcroft			if (statement_block_size($block) > 1) {
5488cf655043SAndy Whitcroft				#print "APW: ALLOWED: lines block<$block>\n";
5489cf655043SAndy Whitcroft				$allowed = 1;
5490cf655043SAndy Whitcroft			}
5491cf655043SAndy Whitcroft			# Check the post-context.
5492cf655043SAndy Whitcroft			if (defined $chunks[1]) {
5493cf655043SAndy Whitcroft				my ($cond, $block) = @{$chunks[1]};
5494cf655043SAndy Whitcroft				if (defined $cond) {
5495773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
5496cf655043SAndy Whitcroft				}
5497cf655043SAndy Whitcroft				if ($block =~ /^\s*\{/) {
5498cf655043SAndy Whitcroft					#print "APW: ALLOWED: chunk-1 block<$block>\n";
5499cf655043SAndy Whitcroft					$allowed = 1;
5500cf655043SAndy Whitcroft				}
5501cf655043SAndy Whitcroft			}
5502cf655043SAndy Whitcroft			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
5503f055663cSAndy Whitcroft				my $cnt = statement_rawlines($block);
5504e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
5505cf655043SAndy Whitcroft
5506000d1cc1SJoe Perches				WARN("BRACES",
5507000d1cc1SJoe Perches				     "braces {} are not necessary for single statement blocks\n" . $herectx);
5508f0a594c1SAndy Whitcroft			}
5509f0a594c1SAndy Whitcroft		}
5510f0a594c1SAndy Whitcroft
5511e4c5babdSJoe Perches# check for single line unbalanced braces
551295330473SSven Eckelmann		if ($sline =~ /^.\s*\}\s*else\s*$/ ||
551395330473SSven Eckelmann		    $sline =~ /^.\s*else\s*\{\s*$/) {
5514e4c5babdSJoe Perches			CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
5515e4c5babdSJoe Perches		}
5516e4c5babdSJoe Perches
55170979ae66SJoe Perches# check for unnecessary blank lines around braces
551877b9a53aSJoe Perches		if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
5519f8e58219SJoe Perches			if (CHK("BRACES",
5520f8e58219SJoe Perches				"Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
5521f8e58219SJoe Perches			    $fix && $prevrawline =~ /^\+/) {
5522f8e58219SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
5523f8e58219SJoe Perches			}
55240979ae66SJoe Perches		}
552577b9a53aSJoe Perches		if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
5526f8e58219SJoe Perches			if (CHK("BRACES",
5527f8e58219SJoe Perches				"Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
5528f8e58219SJoe Perches			    $fix) {
5529f8e58219SJoe Perches				fix_delete_line($fixlinenr, $rawline);
5530f8e58219SJoe Perches			}
55310979ae66SJoe Perches		}
55320979ae66SJoe Perches
55334a0df2efSAndy Whitcroft# no volatiles please
55346c72ffaaSAndy Whitcroft		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
55356c72ffaaSAndy Whitcroft		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
5536000d1cc1SJoe Perches			WARN("VOLATILE",
55378c27ceffSMauro Carvalho Chehab			     "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
55384a0df2efSAndy Whitcroft		}
55394a0df2efSAndy Whitcroft
55405e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability
55415e4f6ba5SJoe Perches# to grep for the string.  Make exceptions when the previous string ends in a
55425e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
55435e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
554433acb54aSJoe Perches		if ($line =~ /^\+\s*$String/ &&
55455e4f6ba5SJoe Perches		    $prevline =~ /"\s*$/ &&
55465e4f6ba5SJoe Perches		    $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
55475e4f6ba5SJoe Perches			if (WARN("SPLIT_STRING",
55485e4f6ba5SJoe Perches				 "quoted string split across lines\n" . $hereprev) &&
55495e4f6ba5SJoe Perches				     $fix &&
55505e4f6ba5SJoe Perches				     $prevrawline =~ /^\+.*"\s*$/ &&
55515e4f6ba5SJoe Perches				     $last_coalesced_string_linenr != $linenr - 1) {
55525e4f6ba5SJoe Perches				my $extracted_string = get_quoted_string($line, $rawline);
55535e4f6ba5SJoe Perches				my $comma_close = "";
55545e4f6ba5SJoe Perches				if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
55555e4f6ba5SJoe Perches					$comma_close = $1;
55565e4f6ba5SJoe Perches				}
55575e4f6ba5SJoe Perches
55585e4f6ba5SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
55595e4f6ba5SJoe Perches				fix_delete_line($fixlinenr, $rawline);
55605e4f6ba5SJoe Perches				my $fixedline = $prevrawline;
55615e4f6ba5SJoe Perches				$fixedline =~ s/"\s*$//;
55625e4f6ba5SJoe Perches				$fixedline .= substr($extracted_string, 1) . trim($comma_close);
55635e4f6ba5SJoe Perches				fix_insert_line($fixlinenr - 1, $fixedline);
55645e4f6ba5SJoe Perches				$fixedline = $rawline;
55655e4f6ba5SJoe Perches				$fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
55665e4f6ba5SJoe Perches				if ($fixedline !~ /\+\s*$/) {
55675e4f6ba5SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
55685e4f6ba5SJoe Perches				}
55695e4f6ba5SJoe Perches				$last_coalesced_string_linenr = $linenr;
55705e4f6ba5SJoe Perches			}
55715e4f6ba5SJoe Perches		}
55725e4f6ba5SJoe Perches
55735e4f6ba5SJoe Perches# check for missing a space in a string concatenation
55745e4f6ba5SJoe Perches		if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
55755e4f6ba5SJoe Perches			WARN('MISSING_SPACE',
55765e4f6ba5SJoe Perches			     "break quoted strings at a space character\n" . $hereprev);
55775e4f6ba5SJoe Perches		}
55785e4f6ba5SJoe Perches
557977cb8546SJoe Perches# check for an embedded function name in a string when the function is known
5580e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch
5581e4b7d309SJoe Perches# context providing the function name or a single line form for in-file
5582e4b7d309SJoe Perches# function declarations
558377cb8546SJoe Perches		if ($line =~ /^\+.*$String/ &&
558477cb8546SJoe Perches		    defined($context_function) &&
5585e4b7d309SJoe Perches		    get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
5586e4b7d309SJoe Perches		    length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
558777cb8546SJoe Perches			WARN("EMBEDDED_FUNCTION_NAME",
5588e4b7d309SJoe Perches			     "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
558977cb8546SJoe Perches		}
559077cb8546SJoe Perches
55915e4f6ba5SJoe Perches# check for spaces before a quoted newline
55925e4f6ba5SJoe Perches		if ($rawline =~ /^.*\".*\s\\n/) {
55935e4f6ba5SJoe Perches			if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
55945e4f6ba5SJoe Perches				 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
55955e4f6ba5SJoe Perches			    $fix) {
55965e4f6ba5SJoe Perches				$fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
55975e4f6ba5SJoe Perches			}
55985e4f6ba5SJoe Perches
55995e4f6ba5SJoe Perches		}
56005e4f6ba5SJoe Perches
5601f17dba4fSJoe Perches# concatenated string without spaces between elements
560279682c0cSJoe Perches		if ($line =~ /$String[A-Za-z0-9_]/ || $line =~ /[A-Za-z0-9_]$String/) {
560379682c0cSJoe Perches			if (CHK("CONCATENATED_STRING",
560479682c0cSJoe Perches				"Concatenated strings should use spaces between elements\n" . $herecurr) &&
560579682c0cSJoe Perches			    $fix) {
560679682c0cSJoe Perches				while ($line =~ /($String)/g) {
560779682c0cSJoe Perches					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
560879682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/;
560979682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/;
561079682c0cSJoe Perches				}
561179682c0cSJoe Perches			}
5612f17dba4fSJoe Perches		}
5613f17dba4fSJoe Perches
561490ad30e5SJoe Perches# uncoalesced string fragments
561533acb54aSJoe Perches		if ($line =~ /$String\s*"/) {
561679682c0cSJoe Perches			if (WARN("STRING_FRAGMENTS",
561779682c0cSJoe Perches				 "Consecutive strings are generally better as a single string\n" . $herecurr) &&
561879682c0cSJoe Perches			    $fix) {
561979682c0cSJoe Perches				while ($line =~ /($String)(?=\s*")/g) {
562079682c0cSJoe Perches					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
562179682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e;
562279682c0cSJoe Perches				}
562379682c0cSJoe Perches			}
562490ad30e5SJoe Perches		}
562590ad30e5SJoe Perches
5626522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats
5627522b837cSAlexey Dobriyan		my $show_L = 1;	#don't show the same defect twice
5628522b837cSAlexey Dobriyan		my $show_Z = 1;
56295e4f6ba5SJoe Perches		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
5630522b837cSAlexey Dobriyan			my $string = substr($rawline, $-[1], $+[1] - $-[1]);
56315e4f6ba5SJoe Perches			$string =~ s/%%/__/g;
5632522b837cSAlexey Dobriyan			# check for %L
5633522b837cSAlexey Dobriyan			if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
56345e4f6ba5SJoe Perches				WARN("PRINTF_L",
5635522b837cSAlexey Dobriyan				     "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
5636522b837cSAlexey Dobriyan				$show_L = 0;
56375e4f6ba5SJoe Perches			}
5638522b837cSAlexey Dobriyan			# check for %Z
5639522b837cSAlexey Dobriyan			if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
5640522b837cSAlexey Dobriyan				WARN("PRINTF_Z",
5641522b837cSAlexey Dobriyan				     "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
5642522b837cSAlexey Dobriyan				$show_Z = 0;
5643522b837cSAlexey Dobriyan			}
5644522b837cSAlexey Dobriyan			# check for 0x<decimal>
5645522b837cSAlexey Dobriyan			if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
5646522b837cSAlexey Dobriyan				ERROR("PRINTF_0XDECIMAL",
56476e300757SJoe Perches				      "Prefixing 0x with decimal output is defective\n" . $herecurr);
56486e300757SJoe Perches			}
56495e4f6ba5SJoe Perches		}
56505e4f6ba5SJoe Perches
56515e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of "
56523f7f335dSJoe Perches		if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) {
56535e4f6ba5SJoe Perches			WARN("LINE_CONTINUATIONS",
56545e4f6ba5SJoe Perches			     "Avoid line continuations in quoted strings\n" . $herecurr);
56555e4f6ba5SJoe Perches		}
56565e4f6ba5SJoe Perches
565700df344fSAndy Whitcroft# warn about #if 0
5658c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
565960f89010SPrakruthi Deepak Heragu			WARN("IF_0",
566060f89010SPrakruthi Deepak Heragu			     "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr);
566160f89010SPrakruthi Deepak Heragu		}
566260f89010SPrakruthi Deepak Heragu
566360f89010SPrakruthi Deepak Heragu# warn about #if 1
566460f89010SPrakruthi Deepak Heragu		if ($line =~ /^.\s*\#\s*if\s+1\b/) {
566560f89010SPrakruthi Deepak Heragu			WARN("IF_1",
566660f89010SPrakruthi Deepak Heragu			     "Consider removing the #if 1 and its #endif\n" . $herecurr);
56674a0df2efSAndy Whitcroft		}
56684a0df2efSAndy Whitcroft
566903df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses
567003df4b51SAndy Whitcroft		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
5671100425deSJoe Perches			my $tested = quotemeta($1);
5672100425deSJoe Perches			my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
5673100425deSJoe Perches			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
5674100425deSJoe Perches				my $func = $1;
5675100425deSJoe Perches				if (WARN('NEEDLESS_IF',
5676100425deSJoe Perches					 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
5677100425deSJoe Perches				    $fix) {
5678100425deSJoe Perches					my $do_fix = 1;
5679100425deSJoe Perches					my $leading_tabs = "";
5680100425deSJoe Perches					my $new_leading_tabs = "";
5681100425deSJoe Perches					if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
5682100425deSJoe Perches						$leading_tabs = $1;
5683100425deSJoe Perches					} else {
5684100425deSJoe Perches						$do_fix = 0;
5685100425deSJoe Perches					}
5686100425deSJoe Perches					if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
5687100425deSJoe Perches						$new_leading_tabs = $1;
5688100425deSJoe Perches						if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
5689100425deSJoe Perches							$do_fix = 0;
5690100425deSJoe Perches						}
5691100425deSJoe Perches					} else {
5692100425deSJoe Perches						$do_fix = 0;
5693100425deSJoe Perches					}
5694100425deSJoe Perches					if ($do_fix) {
5695100425deSJoe Perches						fix_delete_line($fixlinenr - 1, $prevrawline);
5696100425deSJoe Perches						$fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
5697100425deSJoe Perches					}
5698100425deSJoe Perches				}
56994c432a8fSGreg Kroah-Hartman			}
57004c432a8fSGreg Kroah-Hartman		}
5701f0a594c1SAndy Whitcroft
5702ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages
5703ebfdc409SJoe Perches		if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
5704ebfdc409SJoe Perches		    $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
5705ebfdc409SJoe Perches		    (defined $1 || defined $3) &&
5706ebfdc409SJoe Perches		    $linenr > 3) {
5707ebfdc409SJoe Perches			my $testval = $2;
5708ebfdc409SJoe Perches			my $testline = $lines[$linenr - 3];
5709ebfdc409SJoe Perches
5710ebfdc409SJoe Perches			my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
5711ebfdc409SJoe Perches#			print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
5712ebfdc409SJoe Perches
5713e29a70f1SJoe Perches			if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ &&
5714e29a70f1SJoe Perches			    $s !~ /\b__GFP_NOWARN\b/ ) {
5715ebfdc409SJoe Perches				WARN("OOM_MESSAGE",
5716ebfdc409SJoe Perches				     "Possible unnecessary 'out of memory' message\n" . $hereprev);
5717ebfdc409SJoe Perches			}
5718ebfdc409SJoe Perches		}
5719ebfdc409SJoe Perches
5720f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL>
5721dcaf1123SPaolo Bonzini		if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
5722f78d98f6SJoe Perches		    $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
5723f78d98f6SJoe Perches			my $level = $1;
5724f78d98f6SJoe Perches			if (WARN("UNNECESSARY_KERN_LEVEL",
5725f78d98f6SJoe Perches				 "Possible unnecessary $level\n" . $herecurr) &&
5726f78d98f6SJoe Perches			    $fix) {
5727f78d98f6SJoe Perches				$fixed[$fixlinenr] =~ s/\s*$level\s*//;
5728f78d98f6SJoe Perches			}
5729f78d98f6SJoe Perches		}
5730f78d98f6SJoe Perches
573145c55e92SJoe Perches# check for logging continuations
573245c55e92SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
573345c55e92SJoe Perches			WARN("LOGGING_CONTINUATION",
573445c55e92SJoe Perches			     "Avoid logging continuation uses where feasible\n" . $herecurr);
573545c55e92SJoe Perches		}
573645c55e92SJoe Perches
5737abb08a53SJoe Perches# check for mask then right shift without a parentheses
57385b57980dSJoe Perches		if ($perl_version_ok &&
5739abb08a53SJoe Perches		    $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
5740abb08a53SJoe Perches		    $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
5741abb08a53SJoe Perches			WARN("MASK_THEN_SHIFT",
5742abb08a53SJoe Perches			     "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
5743abb08a53SJoe Perches		}
5744abb08a53SJoe Perches
5745b75ac618SJoe Perches# check for pointer comparisons to NULL
57465b57980dSJoe Perches		if ($perl_version_ok) {
5747b75ac618SJoe Perches			while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
5748b75ac618SJoe Perches				my $val = $1;
5749b75ac618SJoe Perches				my $equal = "!";
5750b75ac618SJoe Perches				$equal = "" if ($4 eq "!=");
5751b75ac618SJoe Perches				if (CHK("COMPARISON_TO_NULL",
5752b75ac618SJoe Perches					"Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
5753b75ac618SJoe Perches					    $fix) {
5754b75ac618SJoe Perches					$fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
5755b75ac618SJoe Perches				}
5756b75ac618SJoe Perches			}
5757b75ac618SJoe Perches		}
5758b75ac618SJoe Perches
57598716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata)
57608716de38SJoe Perches		if ($line =~ /(\b$InitAttribute\b)/) {
57618716de38SJoe Perches			my $attr = $1;
57628716de38SJoe Perches			if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
57638716de38SJoe Perches				my $ptr = $1;
57648716de38SJoe Perches				my $var = $2;
57658716de38SJoe Perches				if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
57668716de38SJoe Perches				      ERROR("MISPLACED_INIT",
57678716de38SJoe Perches					    "$attr should be placed after $var\n" . $herecurr)) ||
57688716de38SJoe Perches				     ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
57698716de38SJoe Perches				      WARN("MISPLACED_INIT",
57708716de38SJoe Perches					   "$attr should be placed after $var\n" . $herecurr))) &&
57718716de38SJoe Perches				    $fix) {
5772194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s/(\bstatic\s+(?:const\s+)?)(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*([=;])\s*/"$1" . trim(string_find_replace($2, "\\s*$attr\\s*", " ")) . " " . trim(string_find_replace($3, "\\s*$attr\\s*", "")) . " $attr" . ("$4" eq ";" ? ";" : " = ")/e;
57738716de38SJoe Perches				}
57748716de38SJoe Perches			}
57758716de38SJoe Perches		}
57768716de38SJoe Perches
5777e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const
5778e970b884SJoe Perches		if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
5779e970b884SJoe Perches			my $attr = $1;
5780e970b884SJoe Perches			$attr =~ /($InitAttributePrefix)(.*)/;
5781e970b884SJoe Perches			my $attr_prefix = $1;
5782e970b884SJoe Perches			my $attr_type = $2;
5783e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
5784e970b884SJoe Perches				  "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
5785e970b884SJoe Perches			    $fix) {
5786194f66fcSJoe Perches				$fixed[$fixlinenr] =~
5787e970b884SJoe Perches				    s/$InitAttributeData/${attr_prefix}initconst/;
5788e970b884SJoe Perches			}
5789e970b884SJoe Perches		}
5790e970b884SJoe Perches
5791e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const
5792e970b884SJoe Perches		if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
5793e970b884SJoe Perches			my $attr = $1;
5794e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
5795e970b884SJoe Perches				  "Use of $attr requires a separate use of const\n" . $herecurr) &&
5796e970b884SJoe Perches			    $fix) {
5797194f66fcSJoe Perches				my $lead = $fixed[$fixlinenr] =~
5798e970b884SJoe Perches				    /(^\+\s*(?:static\s+))/;
5799e970b884SJoe Perches				$lead = rtrim($1);
5800e970b884SJoe Perches				$lead = "$lead " if ($lead !~ /^\+$/);
5801e970b884SJoe Perches				$lead = "${lead}const ";
5802194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
5803e970b884SJoe Perches			}
5804e970b884SJoe Perches		}
5805e970b884SJoe Perches
5806c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const)
5807c17893c7SJoe Perches		if ($line =~ /\b__read_mostly\b/ &&
5808c17893c7SJoe Perches		    $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
5809c17893c7SJoe Perches			if (ERROR("CONST_READ_MOSTLY",
5810c17893c7SJoe Perches				  "Invalid use of __read_mostly with const type\n" . $herecurr) &&
5811c17893c7SJoe Perches			    $fix) {
5812c17893c7SJoe Perches				$fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
5813c17893c7SJoe Perches			}
5814c17893c7SJoe Perches		}
5815c17893c7SJoe Perches
5816fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/
5817fbdb8138SJoe Perches		if ($realfile !~ m@^include/uapi/@ &&
5818fbdb8138SJoe Perches		    $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
5819fbdb8138SJoe Perches			my $constant_func = $1;
5820fbdb8138SJoe Perches			my $func = $constant_func;
5821fbdb8138SJoe Perches			$func =~ s/^__constant_//;
5822fbdb8138SJoe Perches			if (WARN("CONSTANT_CONVERSION",
5823fbdb8138SJoe Perches				 "$constant_func should be $func\n" . $herecurr) &&
5824fbdb8138SJoe Perches			    $fix) {
5825194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
5826fbdb8138SJoe Perches			}
5827fbdb8138SJoe Perches		}
5828fbdb8138SJoe Perches
58291a15a250SPatrick Pannuto# prefer usleep_range over udelay
583037581c28SBruce Allan		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
583143c1d77cSJoe Perches			my $delay = $1;
58321a15a250SPatrick Pannuto			# ignore udelay's < 10, however
583343c1d77cSJoe Perches			if (! ($delay < 10) ) {
5834000d1cc1SJoe Perches				CHK("USLEEP_RANGE",
5835458f69efSMauro Carvalho Chehab				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr);
583643c1d77cSJoe Perches			}
583743c1d77cSJoe Perches			if ($delay > 2000) {
583843c1d77cSJoe Perches				WARN("LONG_UDELAY",
583943c1d77cSJoe Perches				     "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
58401a15a250SPatrick Pannuto			}
58411a15a250SPatrick Pannuto		}
58421a15a250SPatrick Pannuto
584309ef8725SPatrick Pannuto# warn about unexpectedly long msleep's
584409ef8725SPatrick Pannuto		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
584509ef8725SPatrick Pannuto			if ($1 < 20) {
5846000d1cc1SJoe Perches				WARN("MSLEEP",
5847458f69efSMauro Carvalho Chehab				     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr);
584809ef8725SPatrick Pannuto			}
584909ef8725SPatrick Pannuto		}
585009ef8725SPatrick Pannuto
585136ec1939SJoe Perches# check for comparisons of jiffies
585236ec1939SJoe Perches		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
585336ec1939SJoe Perches			WARN("JIFFIES_COMPARISON",
585436ec1939SJoe Perches			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
585536ec1939SJoe Perches		}
585636ec1939SJoe Perches
58579d7a34a5SJoe Perches# check for comparisons of get_jiffies_64()
58589d7a34a5SJoe Perches		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
58599d7a34a5SJoe Perches			WARN("JIFFIES_COMPARISON",
58609d7a34a5SJoe Perches			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
58619d7a34a5SJoe Perches		}
58629d7a34a5SJoe Perches
586300df344fSAndy Whitcroft# warn about #ifdefs in C files
5864c45dcabdSAndy Whitcroft#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
586500df344fSAndy Whitcroft#			print "#ifdef in C files should be avoided\n";
586600df344fSAndy Whitcroft#			print "$herecurr";
586700df344fSAndy Whitcroft#			$clean = 0;
586800df344fSAndy Whitcroft#		}
586900df344fSAndy Whitcroft
587022f2a2efSAndy Whitcroft# warn about spacing in #ifdefs
5871c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
58723705ce5bSJoe Perches			if (ERROR("SPACING",
58733705ce5bSJoe Perches				  "exactly one space required after that #$1\n" . $herecurr) &&
58743705ce5bSJoe Perches			    $fix) {
5875194f66fcSJoe Perches				$fixed[$fixlinenr] =~
58763705ce5bSJoe Perches				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
58773705ce5bSJoe Perches			}
58783705ce5bSJoe Perches
587922f2a2efSAndy Whitcroft		}
588022f2a2efSAndy Whitcroft
58814a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment.
5882171ae1a4SAndy Whitcroft		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
5883171ae1a4SAndy Whitcroft		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
58844a0df2efSAndy Whitcroft			my $which = $1;
58854a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
5886000d1cc1SJoe Perches				CHK("UNCOMMENTED_DEFINITION",
5887000d1cc1SJoe Perches				    "$1 definition without comment\n" . $herecurr);
58884a0df2efSAndy Whitcroft			}
58894a0df2efSAndy Whitcroft		}
58904a0df2efSAndy Whitcroft# check for memory barriers without a comment.
5891402c2553SMichael S. Tsirkin
5892402c2553SMichael S. Tsirkin		my $barriers = qr{
5893402c2553SMichael S. Tsirkin			mb|
5894402c2553SMichael S. Tsirkin			rmb|
5895402c2553SMichael S. Tsirkin			wmb|
5896402c2553SMichael S. Tsirkin			read_barrier_depends
5897402c2553SMichael S. Tsirkin		}x;
5898402c2553SMichael S. Tsirkin		my $barrier_stems = qr{
5899402c2553SMichael S. Tsirkin			mb__before_atomic|
5900402c2553SMichael S. Tsirkin			mb__after_atomic|
5901402c2553SMichael S. Tsirkin			store_release|
5902402c2553SMichael S. Tsirkin			load_acquire|
5903402c2553SMichael S. Tsirkin			store_mb|
5904402c2553SMichael S. Tsirkin			(?:$barriers)
5905402c2553SMichael S. Tsirkin		}x;
5906402c2553SMichael S. Tsirkin		my $all_barriers = qr{
5907402c2553SMichael S. Tsirkin			(?:$barriers)|
590843e361f2SMichael S. Tsirkin			smp_(?:$barrier_stems)|
590943e361f2SMichael S. Tsirkin			virt_(?:$barrier_stems)
5910402c2553SMichael S. Tsirkin		}x;
5911402c2553SMichael S. Tsirkin
5912402c2553SMichael S. Tsirkin		if ($line =~ /\b(?:$all_barriers)\s*\(/) {
59134a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
5914c1fd7bb9SJoe Perches				WARN("MEMORY_BARRIER",
5915000d1cc1SJoe Perches				     "memory barrier without comment\n" . $herecurr);
59164a0df2efSAndy Whitcroft			}
59174a0df2efSAndy Whitcroft		}
59183ad81779SPaul E. McKenney
5919f4073b0fSMichael S. Tsirkin		my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
5920f4073b0fSMichael S. Tsirkin
5921f4073b0fSMichael S. Tsirkin		if ($realfile !~ m@^include/asm-generic/@ &&
5922f4073b0fSMichael S. Tsirkin		    $realfile !~ m@/barrier\.h$@ &&
5923f4073b0fSMichael S. Tsirkin		    $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
5924f4073b0fSMichael S. Tsirkin		    $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
5925f4073b0fSMichael S. Tsirkin			WARN("MEMORY_BARRIER",
5926f4073b0fSMichael S. Tsirkin			     "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
5927f4073b0fSMichael S. Tsirkin		}
5928f4073b0fSMichael S. Tsirkin
5929cb426e99SJoe Perches# check for waitqueue_active without a comment.
5930cb426e99SJoe Perches		if ($line =~ /\bwaitqueue_active\s*\(/) {
5931cb426e99SJoe Perches			if (!ctx_has_comment($first_line, $linenr)) {
5932cb426e99SJoe Perches				WARN("WAITQUEUE_ACTIVE",
5933cb426e99SJoe Perches				     "waitqueue_active without comment\n" . $herecurr);
5934cb426e99SJoe Perches			}
5935cb426e99SJoe Perches		}
59363ad81779SPaul E. McKenney
593791db2592SPaul E. McKenney# check for smp_read_barrier_depends and read_barrier_depends
593891db2592SPaul E. McKenney		if (!$file && $line =~ /\b(smp_|)read_barrier_depends\s*\(/) {
593991db2592SPaul E. McKenney			WARN("READ_BARRIER_DEPENDS",
594091db2592SPaul E. McKenney			     "$1read_barrier_depends should only be used in READ_ONCE or DEC Alpha code\n" . $herecurr);
594191db2592SPaul E. McKenney		}
594291db2592SPaul E. McKenney
59434a0df2efSAndy Whitcroft# check of hardware specific defines
5944c45dcabdSAndy Whitcroft		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
5945000d1cc1SJoe Perches			CHK("ARCH_DEFINES",
5946000d1cc1SJoe Perches			    "architecture specific defines should be avoided\n" .  $herecurr);
59470a920b5bSAndy Whitcroft		}
5948653d4876SAndy Whitcroft
5949596ed45bSJoe Perches# check that the storage class is not after a type
5950596ed45bSJoe Perches		if ($line =~ /\b($Type)\s+($Storage)\b/) {
5951000d1cc1SJoe Perches			WARN("STORAGE_CLASS",
5952596ed45bSJoe Perches			     "storage class '$2' should be located before type '$1'\n" . $herecurr);
5953596ed45bSJoe Perches		}
5954596ed45bSJoe Perches# Check that the storage class is at the beginning of a declaration
5955596ed45bSJoe Perches		if ($line =~ /\b$Storage\b/ &&
5956596ed45bSJoe Perches		    $line !~ /^.\s*$Storage/ &&
5957596ed45bSJoe Perches		    $line =~ /^.\s*(.+?)\$Storage\s/ &&
5958596ed45bSJoe Perches		    $1 !~ /[\,\)]\s*$/) {
5959596ed45bSJoe Perches			WARN("STORAGE_CLASS",
5960596ed45bSJoe Perches			     "storage class should be at the beginning of the declaration\n" . $herecurr);
5961d4977c78STobias Klauser		}
5962d4977c78STobias Klauser
5963de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between
5964de7d4f0eSAndy Whitcroft# storage class and type.
59659c0ca6f9SAndy Whitcroft		if ($line =~ /\b$Type\s+$Inline\b/ ||
59669c0ca6f9SAndy Whitcroft		    $line =~ /\b$Inline\s+$Storage\b/) {
5967000d1cc1SJoe Perches			ERROR("INLINE_LOCATION",
5968000d1cc1SJoe Perches			      "inline keyword should sit between storage class and type\n" . $herecurr);
5969de7d4f0eSAndy Whitcroft		}
5970de7d4f0eSAndy Whitcroft
59718905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline
59722b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
59732b7ab453SJoe Perches		    $line =~ /\b(__inline__|__inline)\b/) {
5974d5e616fcSJoe Perches			if (WARN("INLINE",
5975d5e616fcSJoe Perches				 "plain inline is preferred over $1\n" . $herecurr) &&
5976d5e616fcSJoe Perches			    $fix) {
5977194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
5978d5e616fcSJoe Perches
5979d5e616fcSJoe Perches			}
59808905a67cSAndy Whitcroft		}
59818905a67cSAndy Whitcroft
59823d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed
59832b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
59842b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
5985000d1cc1SJoe Perches			WARN("PREFER_PACKED",
5986000d1cc1SJoe Perches			     "__packed is preferred over __attribute__((packed))\n" . $herecurr);
59873d130fd0SJoe Perches		}
59883d130fd0SJoe Perches
598939b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned
59902b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
59912b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
5992000d1cc1SJoe Perches			WARN("PREFER_ALIGNED",
5993000d1cc1SJoe Perches			     "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
599439b7e287SJoe Perches		}
599539b7e287SJoe Perches
5996462811d9SJoe Perches# Check for __attribute__ section, prefer __section
5997462811d9SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
5998462811d9SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(.*_*section_*\s*\(\s*("[^"]*")/) {
5999462811d9SJoe Perches			my $old = substr($rawline, $-[1], $+[1] - $-[1]);
6000462811d9SJoe Perches			my $new = substr($old, 1, -1);
6001462811d9SJoe Perches			if (WARN("PREFER_SECTION",
6002462811d9SJoe Perches				 "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) &&
6003462811d9SJoe Perches			    $fix) {
6004462811d9SJoe Perches				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/;
6005462811d9SJoe Perches			}
6006462811d9SJoe Perches		}
6007462811d9SJoe Perches
60085f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf
60092b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
60102b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
6011d5e616fcSJoe Perches			if (WARN("PREFER_PRINTF",
6012d5e616fcSJoe Perches				 "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
6013d5e616fcSJoe Perches			    $fix) {
6014194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
6015d5e616fcSJoe Perches
6016d5e616fcSJoe Perches			}
60175f14d3bdSJoe Perches		}
60185f14d3bdSJoe Perches
60196061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf
60202b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
60212b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
6022d5e616fcSJoe Perches			if (WARN("PREFER_SCANF",
6023d5e616fcSJoe Perches				 "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
6024d5e616fcSJoe Perches			    $fix) {
6025194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
6026d5e616fcSJoe Perches			}
60276061d949SJoe Perches		}
60286061d949SJoe Perches
6029619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues)
60305b57980dSJoe Perches		if ($perl_version_ok &&
6031619a908aSJoe Perches		    $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
6032619a908aSJoe Perches		    ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
6033619a908aSJoe Perches		     $line =~ /\b__weak\b/)) {
6034619a908aSJoe Perches			ERROR("WEAK_DECLARATION",
6035619a908aSJoe Perches			      "Using weak declarations can have unintended link defects\n" . $herecurr);
6036619a908aSJoe Perches		}
6037619a908aSJoe Perches
6038fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/
6039e6176fa4SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
6040fd39f904STomas Winkler		    $realfile !~ m@\btools/@ &&
6041e6176fa4SJoe Perches		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
6042e6176fa4SJoe Perches			my $type = $1;
6043e6176fa4SJoe Perches			if ($type =~ /\b($typeC99Typedefs)\b/) {
6044e6176fa4SJoe Perches				$type = $1;
6045e6176fa4SJoe Perches				my $kernel_type = 'u';
6046e6176fa4SJoe Perches				$kernel_type = 's' if ($type =~ /^_*[si]/);
6047e6176fa4SJoe Perches				$type =~ /(\d+)/;
6048e6176fa4SJoe Perches				$kernel_type .= $1;
6049e6176fa4SJoe Perches				if (CHK("PREFER_KERNEL_TYPES",
6050e6176fa4SJoe Perches					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
6051e6176fa4SJoe Perches				    $fix) {
6052e6176fa4SJoe Perches					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
6053e6176fa4SJoe Perches				}
6054e6176fa4SJoe Perches			}
6055e6176fa4SJoe Perches		}
6056e6176fa4SJoe Perches
6057938224b5SJoe Perches# check for cast of C90 native int or longer types constants
6058938224b5SJoe Perches		if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
6059938224b5SJoe Perches			my $cast = $1;
6060938224b5SJoe Perches			my $const = $2;
6061938224b5SJoe Perches			if (WARN("TYPECAST_INT_CONSTANT",
6062938224b5SJoe Perches				 "Unnecessary typecast of c90 int constant\n" . $herecurr) &&
6063938224b5SJoe Perches			    $fix) {
6064938224b5SJoe Perches				my $suffix = "";
6065938224b5SJoe Perches				my $newconst = $const;
6066938224b5SJoe Perches				$newconst =~ s/${Int_type}$//;
6067938224b5SJoe Perches				$suffix .= 'U' if ($cast =~ /\bunsigned\b/);
6068938224b5SJoe Perches				if ($cast =~ /\blong\s+long\b/) {
6069938224b5SJoe Perches					$suffix .= 'LL';
6070938224b5SJoe Perches				} elsif ($cast =~ /\blong\b/) {
6071938224b5SJoe Perches					$suffix .= 'L';
6072938224b5SJoe Perches				}
6073938224b5SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
6074938224b5SJoe Perches			}
6075938224b5SJoe Perches		}
6076938224b5SJoe Perches
60778f53a9b8SJoe Perches# check for sizeof(&)
60788f53a9b8SJoe Perches		if ($line =~ /\bsizeof\s*\(\s*\&/) {
6079000d1cc1SJoe Perches			WARN("SIZEOF_ADDRESS",
6080000d1cc1SJoe Perches			     "sizeof(& should be avoided\n" . $herecurr);
60818f53a9b8SJoe Perches		}
60828f53a9b8SJoe Perches
608366c80b60SJoe Perches# check for sizeof without parenthesis
608466c80b60SJoe Perches		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
6085d5e616fcSJoe Perches			if (WARN("SIZEOF_PARENTHESIS",
6086d5e616fcSJoe Perches				 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
6087d5e616fcSJoe Perches			    $fix) {
6088194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
6089d5e616fcSJoe Perches			}
609066c80b60SJoe Perches		}
609166c80b60SJoe Perches
609288982feaSJoe Perches# check for struct spinlock declarations
609388982feaSJoe Perches		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
609488982feaSJoe Perches			WARN("USE_SPINLOCK_T",
609588982feaSJoe Perches			     "struct spinlock should be spinlock_t\n" . $herecurr);
609688982feaSJoe Perches		}
609788982feaSJoe Perches
6098a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts
609906668727SJoe Perches		if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
6100a6962d72SJoe Perches			my $fmt = get_quoted_string($line, $rawline);
6101caac1d5fSHeba Aamer			$fmt =~ s/%%//g;
6102caac1d5fSHeba Aamer			if ($fmt !~ /%/) {
6103d5e616fcSJoe Perches				if (WARN("PREFER_SEQ_PUTS",
6104d5e616fcSJoe Perches					 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
6105d5e616fcSJoe Perches				    $fix) {
6106194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
6107d5e616fcSJoe Perches				}
6108a6962d72SJoe Perches			}
6109a6962d72SJoe Perches		}
6110a6962d72SJoe Perches
61110b523769SJoe Perches# check for vsprintf extension %p<foo> misuses
61125b57980dSJoe Perches		if ($perl_version_ok &&
61130b523769SJoe Perches		    defined $stat &&
61140b523769SJoe Perches		    $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
61150b523769SJoe Perches		    $1 !~ /^_*volatile_*$/) {
6116e3c6bc95STobin C. Harding			my $stat_real;
6117e3c6bc95STobin C. Harding
61180b523769SJoe Perches			my $lc = $stat =~ tr@\n@@;
61190b523769SJoe Perches			$lc = $lc + $linenr;
61200b523769SJoe Perches		        for (my $count = $linenr; $count <= $lc; $count++) {
6121ffe07513SJoe Perches				my $specifier;
6122ffe07513SJoe Perches				my $extension;
61233bd32d6aSSakari Ailus				my $qualifier;
6124ffe07513SJoe Perches				my $bad_specifier = "";
61250b523769SJoe Perches				my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
61260b523769SJoe Perches				$fmt =~ s/%%//g;
6127e3c6bc95STobin C. Harding
61283bd32d6aSSakari Ailus				while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) {
6129e3c6bc95STobin C. Harding					$specifier = $1;
6130e3c6bc95STobin C. Harding					$extension = $2;
61313bd32d6aSSakari Ailus					$qualifier = $3;
6132361b0d28SLinus Torvalds					if ($extension !~ /[SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||
61333bd32d6aSSakari Ailus					    ($extension eq "f" &&
61343bd32d6aSSakari Ailus					     defined $qualifier && $qualifier !~ /^w/)) {
6135e3c6bc95STobin C. Harding						$bad_specifier = $specifier;
61360b523769SJoe Perches						last;
61370b523769SJoe Perches					}
6138e3c6bc95STobin C. Harding					if ($extension eq "x" && !defined($stat_real)) {
6139e3c6bc95STobin C. Harding						if (!defined($stat_real)) {
6140e3c6bc95STobin C. Harding							$stat_real = get_stat_real($linenr, $lc);
61410b523769SJoe Perches						}
6142e3c6bc95STobin C. Harding						WARN("VSPRINTF_SPECIFIER_PX",
6143e3c6bc95STobin C. Harding						     "Using vsprintf specifier '\%px' potentially exposes the kernel memory layout, if you don't really need the address please consider using '\%p'.\n" . "$here\n$stat_real\n");
6144e3c6bc95STobin C. Harding					}
6145e3c6bc95STobin C. Harding				}
6146e3c6bc95STobin C. Harding				if ($bad_specifier ne "") {
61472a9f9d85STobin C. Harding					my $stat_real = get_stat_real($linenr, $lc);
61481df7338aSSergey Senozhatsky					my $ext_type = "Invalid";
61491df7338aSSergey Senozhatsky					my $use = "";
6150e3c6bc95STobin C. Harding					if ($bad_specifier =~ /p[Ff]/) {
61511df7338aSSergey Senozhatsky						$use = " - use %pS instead";
6152e3c6bc95STobin C. Harding						$use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
61531df7338aSSergey Senozhatsky					}
61542a9f9d85STobin C. Harding
61550b523769SJoe Perches					WARN("VSPRINTF_POINTER_EXTENSION",
6156e3c6bc95STobin C. Harding					     "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
6157e3c6bc95STobin C. Harding				}
61580b523769SJoe Perches			}
61590b523769SJoe Perches		}
61600b523769SJoe Perches
6161554e165cSAndy Whitcroft# Check for misused memsets
61625b57980dSJoe Perches		if ($perl_version_ok &&
6163d1fe9c09SJoe Perches		    defined $stat &&
61649e20a853SMateusz Kulikowski		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
6165554e165cSAndy Whitcroft
6166d7c76ba7SJoe Perches			my $ms_addr = $2;
6167d1fe9c09SJoe Perches			my $ms_val = $7;
6168d1fe9c09SJoe Perches			my $ms_size = $12;
6169d7c76ba7SJoe Perches
6170554e165cSAndy Whitcroft			if ($ms_size =~ /^(0x|)0$/i) {
6171554e165cSAndy Whitcroft				ERROR("MEMSET",
6172d7c76ba7SJoe Perches				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
6173554e165cSAndy Whitcroft			} elsif ($ms_size =~ /^(0x|)1$/i) {
6174554e165cSAndy Whitcroft				WARN("MEMSET",
6175d7c76ba7SJoe Perches				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
6176d7c76ba7SJoe Perches			}
6177d7c76ba7SJoe Perches		}
6178d7c76ba7SJoe Perches
617998a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
61805b57980dSJoe Perches#		if ($perl_version_ok &&
6181f333195dSJoe Perches#		    defined $stat &&
6182f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6183f333195dSJoe Perches#			if (WARN("PREFER_ETHER_ADDR_COPY",
6184f333195dSJoe Perches#				 "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
6185f333195dSJoe Perches#			    $fix) {
6186f333195dSJoe Perches#				$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
6187f333195dSJoe Perches#			}
6188f333195dSJoe Perches#		}
618998a9bba5SJoe Perches
6190b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
61915b57980dSJoe Perches#		if ($perl_version_ok &&
6192f333195dSJoe Perches#		    defined $stat &&
6193f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6194f333195dSJoe Perches#			WARN("PREFER_ETHER_ADDR_EQUAL",
6195f333195dSJoe Perches#			     "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
6196f333195dSJoe Perches#		}
6197b6117d17SMateusz Kulikowski
61988617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
61998617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
62005b57980dSJoe Perches#		if ($perl_version_ok &&
6201f333195dSJoe Perches#		    defined $stat &&
6202f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6203f333195dSJoe Perches#
6204f333195dSJoe Perches#			my $ms_val = $7;
6205f333195dSJoe Perches#
6206f333195dSJoe Perches#			if ($ms_val =~ /^(?:0x|)0+$/i) {
6207f333195dSJoe Perches#				if (WARN("PREFER_ETH_ZERO_ADDR",
6208f333195dSJoe Perches#					 "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
6209f333195dSJoe Perches#				    $fix) {
6210f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
6211f333195dSJoe Perches#				}
6212f333195dSJoe Perches#			} elsif ($ms_val =~ /^(?:0xff|255)$/i) {
6213f333195dSJoe Perches#				if (WARN("PREFER_ETH_BROADCAST_ADDR",
6214f333195dSJoe Perches#					 "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
6215f333195dSJoe Perches#				    $fix) {
6216f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
6217f333195dSJoe Perches#				}
6218f333195dSJoe Perches#			}
6219f333195dSJoe Perches#		}
62208617cd09SMateusz Kulikowski
6221d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t
62225b57980dSJoe Perches		if ($perl_version_ok &&
6223d1fe9c09SJoe Perches		    defined $stat &&
6224d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
6225d1fe9c09SJoe Perches			if (defined $2 || defined $7) {
6226d7c76ba7SJoe Perches				my $call = $1;
6227d7c76ba7SJoe Perches				my $cast1 = deparenthesize($2);
6228d7c76ba7SJoe Perches				my $arg1 = $3;
6229d1fe9c09SJoe Perches				my $cast2 = deparenthesize($7);
6230d1fe9c09SJoe Perches				my $arg2 = $8;
6231d7c76ba7SJoe Perches				my $cast;
6232d7c76ba7SJoe Perches
6233d1fe9c09SJoe Perches				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
6234d7c76ba7SJoe Perches					$cast = "$cast1 or $cast2";
6235d7c76ba7SJoe Perches				} elsif ($cast1 ne "") {
6236d7c76ba7SJoe Perches					$cast = $cast1;
6237d7c76ba7SJoe Perches				} else {
6238d7c76ba7SJoe Perches					$cast = $cast2;
6239d7c76ba7SJoe Perches				}
6240d7c76ba7SJoe Perches				WARN("MINMAX",
6241d7c76ba7SJoe Perches				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
6242554e165cSAndy Whitcroft			}
6243554e165cSAndy Whitcroft		}
6244554e165cSAndy Whitcroft
62454a273195SJoe Perches# check usleep_range arguments
62465b57980dSJoe Perches		if ($perl_version_ok &&
62474a273195SJoe Perches		    defined $stat &&
62484a273195SJoe Perches		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
62494a273195SJoe Perches			my $min = $1;
62504a273195SJoe Perches			my $max = $7;
62514a273195SJoe Perches			if ($min eq $max) {
62524a273195SJoe Perches				WARN("USLEEP_RANGE",
6253458f69efSMauro Carvalho Chehab				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
62544a273195SJoe Perches			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
62554a273195SJoe Perches				 $min > $max) {
62564a273195SJoe Perches				WARN("USLEEP_RANGE",
6257458f69efSMauro Carvalho Chehab				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
62584a273195SJoe Perches			}
62594a273195SJoe Perches		}
62604a273195SJoe Perches
6261823b794cSJoe Perches# check for naked sscanf
62625b57980dSJoe Perches		if ($perl_version_ok &&
6263823b794cSJoe Perches		    defined $stat &&
62646c8bd707SJoe Perches		    $line =~ /\bsscanf\b/ &&
6265823b794cSJoe Perches		    ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
6266823b794cSJoe Perches		     $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
6267823b794cSJoe Perches		     $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
6268823b794cSJoe Perches			my $lc = $stat =~ tr@\n@@;
6269823b794cSJoe Perches			$lc = $lc + $linenr;
62702a9f9d85STobin C. Harding			my $stat_real = get_stat_real($linenr, $lc);
6271823b794cSJoe Perches			WARN("NAKED_SSCANF",
6272823b794cSJoe Perches			     "unchecked sscanf return value\n" . "$here\n$stat_real\n");
6273823b794cSJoe Perches		}
6274823b794cSJoe Perches
6275afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo>
62765b57980dSJoe Perches		if ($perl_version_ok &&
6277afc819abSJoe Perches		    defined $stat &&
6278afc819abSJoe Perches		    $line =~ /\bsscanf\b/) {
6279afc819abSJoe Perches			my $lc = $stat =~ tr@\n@@;
6280afc819abSJoe Perches			$lc = $lc + $linenr;
62812a9f9d85STobin C. Harding			my $stat_real = get_stat_real($linenr, $lc);
6282afc819abSJoe Perches			if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
6283afc819abSJoe Perches				my $format = $6;
6284afc819abSJoe Perches				my $count = $format =~ tr@%@%@;
6285afc819abSJoe Perches				if ($count == 1 &&
6286afc819abSJoe Perches				    $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
6287afc819abSJoe Perches					WARN("SSCANF_TO_KSTRTO",
6288afc819abSJoe Perches					     "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
6289afc819abSJoe Perches				}
6290afc819abSJoe Perches			}
6291afc819abSJoe Perches		}
6292afc819abSJoe Perches
629370dc8a48SJoe Perches# check for new externs in .h files.
629470dc8a48SJoe Perches		if ($realfile =~ /\.h$/ &&
629570dc8a48SJoe Perches		    $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
6296d1d85780SJoe Perches			if (CHK("AVOID_EXTERNS",
629770dc8a48SJoe Perches				"extern prototypes should be avoided in .h files\n" . $herecurr) &&
629870dc8a48SJoe Perches			    $fix) {
6299194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
630070dc8a48SJoe Perches			}
630170dc8a48SJoe Perches		}
630270dc8a48SJoe Perches
6303de7d4f0eSAndy Whitcroft# check for new externs in .c files.
6304171ae1a4SAndy Whitcroft		if ($realfile =~ /\.c$/ && defined $stat &&
6305c45dcabdSAndy Whitcroft		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
6306171ae1a4SAndy Whitcroft		{
6307c45dcabdSAndy Whitcroft			my $function_name = $1;
6308c45dcabdSAndy Whitcroft			my $paren_space = $2;
6309171ae1a4SAndy Whitcroft
6310171ae1a4SAndy Whitcroft			my $s = $stat;
6311171ae1a4SAndy Whitcroft			if (defined $cond) {
6312171ae1a4SAndy Whitcroft				substr($s, 0, length($cond), '');
6313171ae1a4SAndy Whitcroft			}
6314c45dcabdSAndy Whitcroft			if ($s =~ /^\s*;/ &&
6315c45dcabdSAndy Whitcroft			    $function_name ne 'uninitialized_var')
6316c45dcabdSAndy Whitcroft			{
6317000d1cc1SJoe Perches				WARN("AVOID_EXTERNS",
6318000d1cc1SJoe Perches				     "externs should be avoided in .c files\n" .  $herecurr);
6319de7d4f0eSAndy Whitcroft			}
6320de7d4f0eSAndy Whitcroft
6321171ae1a4SAndy Whitcroft			if ($paren_space =~ /\n/) {
6322000d1cc1SJoe Perches				WARN("FUNCTION_ARGUMENTS",
6323000d1cc1SJoe Perches				     "arguments for function declarations should follow identifier\n" . $herecurr);
6324171ae1a4SAndy Whitcroft			}
63259c9ba34eSAndy Whitcroft
63269c9ba34eSAndy Whitcroft		} elsif ($realfile =~ /\.c$/ && defined $stat &&
63279c9ba34eSAndy Whitcroft		    $stat =~ /^.\s*extern\s+/)
63289c9ba34eSAndy Whitcroft		{
6329000d1cc1SJoe Perches			WARN("AVOID_EXTERNS",
6330000d1cc1SJoe Perches			     "externs should be avoided in .c files\n" .  $herecurr);
6331171ae1a4SAndy Whitcroft		}
6332171ae1a4SAndy Whitcroft
6333a0ad7596SJoe Perches# check for function declarations that have arguments without identifier names
633416b7f3c8SJoe Perches# while avoiding uninitialized_var(x)
6335a0ad7596SJoe Perches		if (defined $stat &&
633616b7f3c8SJoe Perches		    $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:($Ident)|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
633716b7f3c8SJoe Perches		    (!defined($1) ||
633816b7f3c8SJoe Perches		     (defined($1) && $1 ne "uninitialized_var")) &&
633916b7f3c8SJoe Perches		     $2 ne "void") {
634016b7f3c8SJoe Perches			my $args = trim($2);
6341ca0d8929SJoe Perches			while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
6342ca0d8929SJoe Perches				my $arg = trim($1);
634316b7f3c8SJoe Perches				if ($arg =~ /^$Type$/ &&
634416b7f3c8SJoe Perches					$arg !~ /enum\s+$Ident$/) {
6345ca0d8929SJoe Perches					WARN("FUNCTION_ARGUMENTS",
6346ca0d8929SJoe Perches					     "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
6347ca0d8929SJoe Perches				}
6348ca0d8929SJoe Perches			}
6349ca0d8929SJoe Perches		}
6350ca0d8929SJoe Perches
6351a0ad7596SJoe Perches# check for function definitions
63525b57980dSJoe Perches		if ($perl_version_ok &&
6353a0ad7596SJoe Perches		    defined $stat &&
6354a0ad7596SJoe Perches		    $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
6355a0ad7596SJoe Perches			$context_function = $1;
6356a0ad7596SJoe Perches
6357a0ad7596SJoe Perches# check for multiline function definition with misplaced open brace
6358a0ad7596SJoe Perches			my $ok = 0;
6359a0ad7596SJoe Perches			my $cnt = statement_rawlines($stat);
6360a0ad7596SJoe Perches			my $herectx = $here . "\n";
6361a0ad7596SJoe Perches			for (my $n = 0; $n < $cnt; $n++) {
6362a0ad7596SJoe Perches				my $rl = raw_line($linenr, $n);
6363a0ad7596SJoe Perches				$herectx .=  $rl . "\n";
6364a0ad7596SJoe Perches				$ok = 1 if ($rl =~ /^[ \+]\{/);
6365a0ad7596SJoe Perches				$ok = 1 if ($rl =~ /\{/ && $n == 0);
6366a0ad7596SJoe Perches				last if $rl =~ /^[ \+].*\{/;
6367a0ad7596SJoe Perches			}
6368a0ad7596SJoe Perches			if (!$ok) {
6369a0ad7596SJoe Perches				ERROR("OPEN_BRACE",
6370a0ad7596SJoe Perches				      "open brace '{' following function definitions go on the next line\n" . $herectx);
6371a0ad7596SJoe Perches			}
6372a0ad7596SJoe Perches		}
6373a0ad7596SJoe Perches
6374de7d4f0eSAndy Whitcroft# checks for new __setup's
6375de7d4f0eSAndy Whitcroft		if ($rawline =~ /\b__setup\("([^"]*)"/) {
6376de7d4f0eSAndy Whitcroft			my $name = $1;
6377de7d4f0eSAndy Whitcroft
6378de7d4f0eSAndy Whitcroft			if (!grep(/$name/, @setup_docs)) {
6379000d1cc1SJoe Perches				CHK("UNDOCUMENTED_SETUP",
63808c27ceffSMauro Carvalho Chehab				    "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr);
6381de7d4f0eSAndy Whitcroft			}
6382653d4876SAndy Whitcroft		}
63839c0ca6f9SAndy Whitcroft
6384e29a70f1SJoe Perches# check for pointless casting of alloc functions
6385e29a70f1SJoe Perches		if ($line =~ /\*\s*\)\s*$allocFunctions\b/) {
6386000d1cc1SJoe Perches			WARN("UNNECESSARY_CASTS",
6387000d1cc1SJoe Perches			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
63889c0ca6f9SAndy Whitcroft		}
638913214adfSAndy Whitcroft
6390a640d25cSJoe Perches# alloc style
6391a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
63925b57980dSJoe Perches		if ($perl_version_ok &&
6393e29a70f1SJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
6394a640d25cSJoe Perches			CHK("ALLOC_SIZEOF_STRUCT",
6395a640d25cSJoe Perches			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
6396a640d25cSJoe Perches		}
6397a640d25cSJoe Perches
639860a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
63995b57980dSJoe Perches		if ($perl_version_ok &&
64001b4a2ed4SJoe Perches		    defined $stat &&
64011b4a2ed4SJoe Perches		    $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
640260a55369SJoe Perches			my $oldfunc = $3;
640360a55369SJoe Perches			my $a1 = $4;
640460a55369SJoe Perches			my $a2 = $10;
640560a55369SJoe Perches			my $newfunc = "kmalloc_array";
640660a55369SJoe Perches			$newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
640760a55369SJoe Perches			my $r1 = $a1;
640860a55369SJoe Perches			my $r2 = $a2;
640960a55369SJoe Perches			if ($a1 =~ /^sizeof\s*\S/) {
641060a55369SJoe Perches				$r1 = $a2;
641160a55369SJoe Perches				$r2 = $a1;
641260a55369SJoe Perches			}
6413e367455aSJoe Perches			if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
6414e367455aSJoe Perches			    !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
64151b4a2ed4SJoe Perches				my $cnt = statement_rawlines($stat);
6416e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
6417e3d95a2aSTobin C. Harding
6418e367455aSJoe Perches				if (WARN("ALLOC_WITH_MULTIPLY",
64191b4a2ed4SJoe Perches					 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
64201b4a2ed4SJoe Perches				    $cnt == 1 &&
6421e367455aSJoe Perches				    $fix) {
6422194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e;
642360a55369SJoe Perches				}
642460a55369SJoe Perches			}
642560a55369SJoe Perches		}
642660a55369SJoe Perches
6427972fdea2SJoe Perches# check for krealloc arg reuse
64285b57980dSJoe Perches		if ($perl_version_ok &&
64294cab63ceSJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ &&
64304cab63ceSJoe Perches		    $1 eq $3) {
6431972fdea2SJoe Perches			WARN("KREALLOC_ARG_REUSE",
6432972fdea2SJoe Perches			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
6433972fdea2SJoe Perches		}
6434972fdea2SJoe Perches
64355ce59ae0SJoe Perches# check for alloc argument mismatch
64365ce59ae0SJoe Perches		if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
64375ce59ae0SJoe Perches			WARN("ALLOC_ARRAY_ARGS",
64385ce59ae0SJoe Perches			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
64395ce59ae0SJoe Perches		}
64405ce59ae0SJoe Perches
6441caf2a54fSJoe Perches# check for multiple semicolons
6442caf2a54fSJoe Perches		if ($line =~ /;\s*;\s*$/) {
6443d5e616fcSJoe Perches			if (WARN("ONE_SEMICOLON",
6444d5e616fcSJoe Perches				 "Statements terminations use 1 semicolon\n" . $herecurr) &&
6445d5e616fcSJoe Perches			    $fix) {
6446194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
6447d5e616fcSJoe Perches			}
6448d1e2ad07SJoe Perches		}
6449d1e2ad07SJoe Perches
6450cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
6451cec3aaa5STomas Winkler		if ($realfile !~ m@^include/uapi/@ &&
6452cec3aaa5STomas Winkler		    $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
64530ab90191SJoe Perches			my $ull = "";
64540ab90191SJoe Perches			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
64550ab90191SJoe Perches			if (CHK("BIT_MACRO",
64560ab90191SJoe Perches				"Prefer using the BIT$ull macro\n" . $herecurr) &&
64570ab90191SJoe Perches			    $fix) {
64580ab90191SJoe Perches				$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
64590ab90191SJoe Perches			}
64600ab90191SJoe Perches		}
64610ab90191SJoe Perches
64622d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
64632d632745SJoe Perches		if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {
64642d632745SJoe Perches			my $config = $1;
64652d632745SJoe Perches			if (WARN("PREFER_IS_ENABLED",
64662d632745SJoe Perches				 "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) &&
64672d632745SJoe Perches			    $fix) {
64682d632745SJoe Perches				$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
64692d632745SJoe Perches			}
64702d632745SJoe Perches		}
64712d632745SJoe Perches
6472e81f239bSJoe Perches# check for case / default statements not preceded by break/fallthrough/switch
6473c34c09a8SJoe Perches		if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
6474c34c09a8SJoe Perches			my $has_break = 0;
6475c34c09a8SJoe Perches			my $has_statement = 0;
6476c34c09a8SJoe Perches			my $count = 0;
6477c34c09a8SJoe Perches			my $prevline = $linenr;
6478e81f239bSJoe Perches			while ($prevline > 1 && ($file || $count < 3) && !$has_break) {
6479c34c09a8SJoe Perches				$prevline--;
6480c34c09a8SJoe Perches				my $rline = $rawlines[$prevline - 1];
6481c34c09a8SJoe Perches				my $fline = $lines[$prevline - 1];
6482c34c09a8SJoe Perches				last if ($fline =~ /^\@\@/);
6483c34c09a8SJoe Perches				next if ($fline =~ /^\-/);
6484c34c09a8SJoe Perches				next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/);
6485c34c09a8SJoe Perches				$has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i);
6486c34c09a8SJoe Perches				next if ($fline =~ /^.[\s$;]*$/);
6487c34c09a8SJoe Perches				$has_statement = 1;
6488c34c09a8SJoe Perches				$count++;
6489258f79d5SHeinrich Schuchardt				$has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|exit\s*\(\b|return\b|goto\b|continue\b)/);
6490c34c09a8SJoe Perches			}
6491c34c09a8SJoe Perches			if (!$has_break && $has_statement) {
6492c34c09a8SJoe Perches				WARN("MISSING_BREAK",
6493224236d9SAndrew Morton				     "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr);
6494c34c09a8SJoe Perches			}
6495c34c09a8SJoe Perches		}
6496c34c09a8SJoe Perches
6497f36d3eb8SJoe Perches# check for /* fallthrough */ like comment, prefer fallthrough;
6498f36d3eb8SJoe Perches		my @fallthroughs = (
6499f36d3eb8SJoe Perches			'fallthrough',
6500f36d3eb8SJoe Perches			'@fallthrough@',
6501f36d3eb8SJoe Perches			'lint -fallthrough[ \t]*',
6502f36d3eb8SJoe Perches			'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)',
6503f36d3eb8SJoe Perches			'(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?',
6504f36d3eb8SJoe Perches			'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
6505f36d3eb8SJoe Perches			'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',
6506f36d3eb8SJoe Perches		    );
6507f36d3eb8SJoe Perches		if ($raw_comment ne '') {
6508f36d3eb8SJoe Perches			foreach my $ft (@fallthroughs) {
6509f36d3eb8SJoe Perches				if ($raw_comment =~ /$ft/) {
6510f36d3eb8SJoe Perches					my $msg_level = \&WARN;
6511f36d3eb8SJoe Perches					$msg_level = \&CHK if ($file);
6512f36d3eb8SJoe Perches					&{$msg_level}("PREFER_FALLTHROUGH",
6513f36d3eb8SJoe Perches						      "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr);
6514f36d3eb8SJoe Perches					last;
6515f36d3eb8SJoe Perches				}
6516f36d3eb8SJoe Perches			}
6517f36d3eb8SJoe Perches		}
6518f36d3eb8SJoe Perches
6519d1e2ad07SJoe Perches# check for switch/default statements without a break;
65205b57980dSJoe Perches		if ($perl_version_ok &&
6521d1e2ad07SJoe Perches		    defined $stat &&
6522d1e2ad07SJoe Perches		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
6523d1e2ad07SJoe Perches			my $cnt = statement_rawlines($stat);
6524e3d95a2aSTobin C. Harding			my $herectx = get_stat_here($linenr, $cnt, $here);
6525e3d95a2aSTobin C. Harding
6526d1e2ad07SJoe Perches			WARN("DEFAULT_NO_BREAK",
6527d1e2ad07SJoe Perches			     "switch default: should use break\n" . $herectx);
6528caf2a54fSJoe Perches		}
6529caf2a54fSJoe Perches
653013214adfSAndy Whitcroft# check for gcc specific __FUNCTION__
6531d5e616fcSJoe Perches		if ($line =~ /\b__FUNCTION__\b/) {
6532d5e616fcSJoe Perches			if (WARN("USE_FUNC",
6533d5e616fcSJoe Perches				 "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr) &&
6534d5e616fcSJoe Perches			    $fix) {
6535194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
6536d5e616fcSJoe Perches			}
653713214adfSAndy Whitcroft		}
6538773647a0SAndy Whitcroft
653962ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__
654062ec818fSJoe Perches		while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
654162ec818fSJoe Perches			ERROR("DATE_TIME",
654262ec818fSJoe Perches			      "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
654362ec818fSJoe Perches		}
654462ec818fSJoe Perches
65452c92488aSJoe Perches# check for use of yield()
65462c92488aSJoe Perches		if ($line =~ /\byield\s*\(\s*\)/) {
65472c92488aSJoe Perches			WARN("YIELD",
65482c92488aSJoe Perches			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
65492c92488aSJoe Perches		}
65502c92488aSJoe Perches
6551179f8f40SJoe Perches# check for comparisons against true and false
6552179f8f40SJoe Perches		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
6553179f8f40SJoe Perches			my $lead = $1;
6554179f8f40SJoe Perches			my $arg = $2;
6555179f8f40SJoe Perches			my $test = $3;
6556179f8f40SJoe Perches			my $otype = $4;
6557179f8f40SJoe Perches			my $trail = $5;
6558179f8f40SJoe Perches			my $op = "!";
6559179f8f40SJoe Perches
6560179f8f40SJoe Perches			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
6561179f8f40SJoe Perches
6562179f8f40SJoe Perches			my $type = lc($otype);
6563179f8f40SJoe Perches			if ($type =~ /^(?:true|false)$/) {
6564179f8f40SJoe Perches				if (("$test" eq "==" && "$type" eq "true") ||
6565179f8f40SJoe Perches				    ("$test" eq "!=" && "$type" eq "false")) {
6566179f8f40SJoe Perches					$op = "";
6567179f8f40SJoe Perches				}
6568179f8f40SJoe Perches
6569179f8f40SJoe Perches				CHK("BOOL_COMPARISON",
6570179f8f40SJoe Perches				    "Using comparison to $otype is error prone\n" . $herecurr);
6571179f8f40SJoe Perches
6572179f8f40SJoe Perches## maybe suggesting a correct construct would better
6573179f8f40SJoe Perches##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
6574179f8f40SJoe Perches
6575179f8f40SJoe Perches			}
6576179f8f40SJoe Perches		}
6577179f8f40SJoe Perches
65784882720bSThomas Gleixner# check for semaphores initialized locked
65794882720bSThomas Gleixner		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
6580000d1cc1SJoe Perches			WARN("CONSIDER_COMPLETION",
6581000d1cc1SJoe Perches			     "consider using a completion\n" . $herecurr);
6582773647a0SAndy Whitcroft		}
65836712d858SJoe Perches
658467d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto*
658567d0a075SJoe Perches		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
6586000d1cc1SJoe Perches			WARN("CONSIDER_KSTRTO",
658767d0a075SJoe Perches			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
6588773647a0SAndy Whitcroft		}
65896712d858SJoe Perches
6590ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please
6591f3db6639SMichael Ellerman		if ($line =~ /^.\s*__initcall\s*\(/) {
6592000d1cc1SJoe Perches			WARN("USE_DEVICE_INITCALL",
6593ae3ccc46SFabian Frederick			     "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
6594f3db6639SMichael Ellerman		}
65956712d858SJoe Perches
65963d709ab5SPaul E. McKenney# check for spin_is_locked(), suggest lockdep instead
65973d709ab5SPaul E. McKenney		if ($line =~ /\bspin_is_locked\(/) {
65983d709ab5SPaul E. McKenney			WARN("USE_LOCKDEP",
65993d709ab5SPaul E. McKenney			     "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr);
66003d709ab5SPaul E. McKenney		}
66013d709ab5SPaul E. McKenney
66029189c7e7SJoe Perches# check for deprecated apis
66039189c7e7SJoe Perches		if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) {
66049189c7e7SJoe Perches			my $deprecated_api = $1;
66059189c7e7SJoe Perches			my $new_api = $deprecated_apis{$deprecated_api};
66069189c7e7SJoe Perches			WARN("DEPRECATED_API",
66079189c7e7SJoe Perches			     "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr);
66089189c7e7SJoe Perches		}
66099189c7e7SJoe Perches
66100f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree)
6611d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {'
66126903ffb2SAndy Whitcroft		if ($line !~ /\bconst\b/ &&
6613d9190e4eSJoe Perches		    $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
6614000d1cc1SJoe Perches			WARN("CONST_STRUCT",
6615d9190e4eSJoe Perches			     "struct $1 should normally be const\n" . $herecurr);
66162b6db5cbSAndy Whitcroft		}
6617773647a0SAndy Whitcroft
6618773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong
6619773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right
6620773647a0SAndy Whitcroft		if ($line =~ /\bNR_CPUS\b/ &&
6621c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
6622c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
6623171ae1a4SAndy Whitcroft		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
6624171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
6625171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/)
6626773647a0SAndy Whitcroft		{
6627000d1cc1SJoe Perches			WARN("NR_CPUS",
6628000d1cc1SJoe Perches			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
6629773647a0SAndy Whitcroft		}
66309c9ba34eSAndy Whitcroft
663152ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
663252ea8506SJoe Perches		if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
663352ea8506SJoe Perches			ERROR("DEFINE_ARCH_HAS",
663452ea8506SJoe Perches			      "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
663552ea8506SJoe Perches		}
663652ea8506SJoe Perches
6637acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)"
66385b57980dSJoe Perches		if ($perl_version_ok &&
6639acd9362cSJoe Perches		    $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
6640acd9362cSJoe Perches			WARN("LIKELY_MISUSE",
6641acd9362cSJoe Perches			     "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
6642acd9362cSJoe Perches		}
6643acd9362cSJoe Perches
6644de3f186fSDenis Efremov# nested likely/unlikely calls
6645de3f186fSDenis Efremov		if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {
6646de3f186fSDenis Efremov			WARN("LIKELY_MISUSE",
6647de3f186fSDenis Efremov			     "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr);
6648de3f186fSDenis Efremov		}
6649de3f186fSDenis Efremov
6650691d77b6SAndy Whitcroft# whine mightly about in_atomic
6651691d77b6SAndy Whitcroft		if ($line =~ /\bin_atomic\s*\(/) {
6652691d77b6SAndy Whitcroft			if ($realfile =~ m@^drivers/@) {
6653000d1cc1SJoe Perches				ERROR("IN_ATOMIC",
6654000d1cc1SJoe Perches				      "do not use in_atomic in drivers\n" . $herecurr);
6655f4a87736SAndy Whitcroft			} elsif ($realfile !~ m@^kernel/@) {
6656000d1cc1SJoe Perches				WARN("IN_ATOMIC",
6657000d1cc1SJoe Perches				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
6658691d77b6SAndy Whitcroft			}
6659691d77b6SAndy Whitcroft		}
66601704f47bSPeter Zijlstra
66610f5225b0SPeter Zijlstra# check for mutex_trylock_recursive usage
66620f5225b0SPeter Zijlstra		if ($line =~ /mutex_trylock_recursive/) {
66630f5225b0SPeter Zijlstra			ERROR("LOCKING",
66640f5225b0SPeter Zijlstra			      "recursive locking is bad, do not use this ever.\n" . $herecurr);
66650f5225b0SPeter Zijlstra		}
66660f5225b0SPeter Zijlstra
66671704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class
66681704f47bSPeter Zijlstra		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
66691704f47bSPeter Zijlstra		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
66701704f47bSPeter Zijlstra			if ($realfile !~ m@^kernel/lockdep@ &&
66711704f47bSPeter Zijlstra			    $realfile !~ m@^include/linux/lockdep@ &&
66721704f47bSPeter Zijlstra			    $realfile !~ m@^drivers/base/core@) {
6673000d1cc1SJoe Perches				ERROR("LOCKDEP",
6674000d1cc1SJoe Perches				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
66751704f47bSPeter Zijlstra			}
66761704f47bSPeter Zijlstra		}
667788f8831cSDave Jones
6678b392c64fSJoe Perches		if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
6679b392c64fSJoe Perches		    $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
6680000d1cc1SJoe Perches			WARN("EXPORTED_WORLD_WRITABLE",
6681000d1cc1SJoe Perches			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
668288f8831cSDave Jones		}
66832435880fSJoe Perches
668400180468SJoe Perches# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
668500180468SJoe Perches# and whether or not function naming is typical and if
668600180468SJoe Perches# DEVICE_ATTR permissions uses are unusual too
66875b57980dSJoe Perches		if ($perl_version_ok &&
668800180468SJoe Perches		    defined $stat &&
668900180468SJoe Perches		    $stat =~ /\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?\s*(\s*(?:${multi_mode_perms_string_search}|0[0-7]{3,3})\s*)\s*\)?\s*,\s*(\w+)\s*,\s*(\w+)\s*\)/) {
669000180468SJoe Perches			my $var = $1;
669100180468SJoe Perches			my $perms = $2;
669200180468SJoe Perches			my $show = $3;
669300180468SJoe Perches			my $store = $4;
669400180468SJoe Perches			my $octal_perms = perms_to_octal($perms);
669500180468SJoe Perches			if ($show =~ /^${var}_show$/ &&
669600180468SJoe Perches			    $store =~ /^${var}_store$/ &&
669700180468SJoe Perches			    $octal_perms eq "0644") {
669800180468SJoe Perches				if (WARN("DEVICE_ATTR_RW",
669900180468SJoe Perches					 "Use DEVICE_ATTR_RW\n" . $herecurr) &&
670000180468SJoe Perches				    $fix) {
670100180468SJoe Perches					$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*$store\s*\)/DEVICE_ATTR_RW(${var})/;
670200180468SJoe Perches				}
670300180468SJoe Perches			} elsif ($show =~ /^${var}_show$/ &&
670400180468SJoe Perches				 $store =~ /^NULL$/ &&
670500180468SJoe Perches				 $octal_perms eq "0444") {
670600180468SJoe Perches				if (WARN("DEVICE_ATTR_RO",
670700180468SJoe Perches					 "Use DEVICE_ATTR_RO\n" . $herecurr) &&
670800180468SJoe Perches				    $fix) {
670900180468SJoe Perches					$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*NULL\s*\)/DEVICE_ATTR_RO(${var})/;
671000180468SJoe Perches				}
671100180468SJoe Perches			} elsif ($show =~ /^NULL$/ &&
671200180468SJoe Perches				 $store =~ /^${var}_store$/ &&
671300180468SJoe Perches				 $octal_perms eq "0200") {
671400180468SJoe Perches				if (WARN("DEVICE_ATTR_WO",
671500180468SJoe Perches					 "Use DEVICE_ATTR_WO\n" . $herecurr) &&
671600180468SJoe Perches				    $fix) {
671700180468SJoe Perches					$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*NULL\s*,\s*$store\s*\)/DEVICE_ATTR_WO(${var})/;
671800180468SJoe Perches				}
671900180468SJoe Perches			} elsif ($octal_perms eq "0644" ||
672000180468SJoe Perches				 $octal_perms eq "0444" ||
672100180468SJoe Perches				 $octal_perms eq "0200") {
672200180468SJoe Perches				my $newshow = "$show";
672300180468SJoe Perches				$newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
672400180468SJoe Perches				my $newstore = $store;
672500180468SJoe Perches				$newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
672600180468SJoe Perches				my $rename = "";
672700180468SJoe Perches				if ($show ne $newshow) {
672800180468SJoe Perches					$rename .= " '$show' to '$newshow'";
672900180468SJoe Perches				}
673000180468SJoe Perches				if ($store ne $newstore) {
673100180468SJoe Perches					$rename .= " '$store' to '$newstore'";
673200180468SJoe Perches				}
673300180468SJoe Perches				WARN("DEVICE_ATTR_FUNCTIONS",
673400180468SJoe Perches				     "Consider renaming function(s)$rename\n" . $herecurr);
673500180468SJoe Perches			} else {
673600180468SJoe Perches				WARN("DEVICE_ATTR_PERMS",
673700180468SJoe Perches				     "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
673800180468SJoe Perches			}
673900180468SJoe Perches		}
674000180468SJoe Perches
6741515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal
6742515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
674373121534SJoe Perches# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
674473121534SJoe Perches#   specific definition of not visible in sysfs.
674573121534SJoe Perches# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
674673121534SJoe Perches#   use the default permissions
67475b57980dSJoe Perches		if ($perl_version_ok &&
6748459cf0aeSJoe Perches		    defined $stat &&
6749515a235eSJoe Perches		    $line =~ /$mode_perms_search/) {
67502435880fSJoe Perches			foreach my $entry (@mode_permission_funcs) {
67512435880fSJoe Perches				my $func = $entry->[0];
67522435880fSJoe Perches				my $arg_pos = $entry->[1];
67532435880fSJoe Perches
6754459cf0aeSJoe Perches				my $lc = $stat =~ tr@\n@@;
6755459cf0aeSJoe Perches				$lc = $lc + $linenr;
67562a9f9d85STobin C. Harding				my $stat_real = get_stat_real($linenr, $lc);
6757459cf0aeSJoe Perches
67582435880fSJoe Perches				my $skip_args = "";
67592435880fSJoe Perches				if ($arg_pos > 1) {
67602435880fSJoe Perches					$arg_pos--;
67612435880fSJoe Perches					$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
67622435880fSJoe Perches				}
6763f90774e1SJoe Perches				my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
6764459cf0aeSJoe Perches				if ($stat =~ /$test/) {
67652435880fSJoe Perches					my $val = $1;
67662435880fSJoe Perches					$val = $6 if ($skip_args ne "");
676773121534SJoe Perches					if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
676873121534SJoe Perches					    (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
676973121534SJoe Perches					     ($val =~ /^$Octal$/ && length($val) ne 4))) {
67702435880fSJoe Perches						ERROR("NON_OCTAL_PERMISSIONS",
6771459cf0aeSJoe Perches						      "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
6772f90774e1SJoe Perches					}
6773f90774e1SJoe Perches					if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
6774c0a5c898SJoe Perches						ERROR("EXPORTED_WORLD_WRITABLE",
6775459cf0aeSJoe Perches						      "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
67762435880fSJoe Perches					}
6777459cf0aeSJoe Perches				}
6778459cf0aeSJoe Perches			}
6779459cf0aeSJoe Perches		}
6780459cf0aeSJoe Perches
6781459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability
6782bc22d9a7SJoe Perches		while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {
678300180468SJoe Perches			my $oval = $1;
678400180468SJoe Perches			my $octal = perms_to_octal($oval);
6785f90774e1SJoe Perches			if (WARN("SYMBOLIC_PERMS",
6786459cf0aeSJoe Perches				 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
6787f90774e1SJoe Perches			    $fix) {
678800180468SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
67892435880fSJoe Perches			}
679013214adfSAndy Whitcroft		}
67915a6d20ceSBjorn Andersson
67925a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h
67935a6d20ceSBjorn Andersson		if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
67945a6d20ceSBjorn Andersson			my $extracted_string = get_quoted_string($line, $rawline);
67955a6d20ceSBjorn Andersson			my $valid_licenses = qr{
67965a6d20ceSBjorn Andersson						GPL|
67975a6d20ceSBjorn Andersson						GPL\ v2|
67985a6d20ceSBjorn Andersson						GPL\ and\ additional\ rights|
67995a6d20ceSBjorn Andersson						Dual\ BSD/GPL|
68005a6d20ceSBjorn Andersson						Dual\ MIT/GPL|
68015a6d20ceSBjorn Andersson						Dual\ MPL/GPL|
68025a6d20ceSBjorn Andersson						Proprietary
68035a6d20ceSBjorn Andersson					}x;
68045a6d20ceSBjorn Andersson			if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
68055a6d20ceSBjorn Andersson				WARN("MODULE_LICENSE",
68065a6d20ceSBjorn Andersson				     "unknown module license " . $extracted_string . "\n" . $herecurr);
68075a6d20ceSBjorn Andersson			}
68085a6d20ceSBjorn Andersson		}
68096a8d76cbSMatteo Croce
68106a8d76cbSMatteo Croce# check for sysctl duplicate constants
68116a8d76cbSMatteo Croce		if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) {
68126a8d76cbSMatteo Croce			WARN("DUPLICATED_SYSCTL_CONST",
68136a8d76cbSMatteo Croce				"duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr);
68146a8d76cbSMatteo Croce		}
6815515a235eSJoe Perches	}
681613214adfSAndy Whitcroft
681713214adfSAndy Whitcroft	# If we have no input at all, then there is nothing to report on
681813214adfSAndy Whitcroft	# so just keep quiet.
681913214adfSAndy Whitcroft	if ($#rawlines == -1) {
682013214adfSAndy Whitcroft		exit(0);
68210a920b5bSAndy Whitcroft	}
68220a920b5bSAndy Whitcroft
68238905a67cSAndy Whitcroft	# In mailback mode only produce a report in the negative, for
68248905a67cSAndy Whitcroft	# things that appear to be patches.
68258905a67cSAndy Whitcroft	if ($mailback && ($clean == 1 || !$is_patch)) {
68268905a67cSAndy Whitcroft		exit(0);
68278905a67cSAndy Whitcroft	}
68288905a67cSAndy Whitcroft
68298905a67cSAndy Whitcroft	# This is not a patch, and we are are in 'no-patch' mode so
68308905a67cSAndy Whitcroft	# just keep quiet.
68318905a67cSAndy Whitcroft	if (!$chk_patch && !$is_patch) {
68328905a67cSAndy Whitcroft		exit(0);
68338905a67cSAndy Whitcroft	}
68348905a67cSAndy Whitcroft
6835a08ffbefSStafford Horne	if (!$is_patch && $filename !~ /cover-letter\.patch$/) {
6836000d1cc1SJoe Perches		ERROR("NOT_UNIFIED_DIFF",
6837000d1cc1SJoe Perches		      "Does not appear to be a unified-diff format patch\n");
68380a920b5bSAndy Whitcroft	}
6839cd261496SGeert Uytterhoeven	if ($is_patch && $has_commit_log && $chk_signoff) {
6840cd261496SGeert Uytterhoeven		if ($signoff == 0) {
6841000d1cc1SJoe Perches			ERROR("MISSING_SIGN_OFF",
6842000d1cc1SJoe Perches			      "Missing Signed-off-by: line(s)\n");
6843cd261496SGeert Uytterhoeven		} elsif (!$authorsignoff) {
6844cd261496SGeert Uytterhoeven			WARN("NO_AUTHOR_SIGN_OFF",
6845cd261496SGeert Uytterhoeven			     "Missing Signed-off-by: line by nominal patch author '$author'\n");
6846cd261496SGeert Uytterhoeven		}
68470a920b5bSAndy Whitcroft	}
68480a920b5bSAndy Whitcroft
6849f0a594c1SAndy Whitcroft	print report_dump();
685013214adfSAndy Whitcroft	if ($summary && !($clean == 1 && $quiet == 1)) {
685113214adfSAndy Whitcroft		print "$filename " if ($summary_file);
68526c72ffaaSAndy Whitcroft		print "total: $cnt_error errors, $cnt_warn warnings, " .
68536c72ffaaSAndy Whitcroft			(($check)? "$cnt_chk checks, " : "") .
68546c72ffaaSAndy Whitcroft			"$cnt_lines lines checked\n";
68556c72ffaaSAndy Whitcroft	}
68568905a67cSAndy Whitcroft
6857d2c0a235SAndy Whitcroft	if ($quiet == 0) {
6858ef212196SJoe Perches		# If there were any defects found and not already fixing them
6859ef212196SJoe Perches		if (!$clean and !$fix) {
6860ef212196SJoe Perches			print << "EOM"
6861ef212196SJoe Perches
6862ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to
6863ef212196SJoe Perches      mechanically convert to the typical style using --fix or --fix-inplace.
6864ef212196SJoe PerchesEOM
6865ef212196SJoe Perches		}
6866d2c0a235SAndy Whitcroft		# If there were whitespace errors which cleanpatch can fix
6867d2c0a235SAndy Whitcroft		# then suggest that.
6868d2c0a235SAndy Whitcroft		if ($rpt_cleaners) {
6869b0781216SMike Frysinger			$rpt_cleaners = 0;
6870d8469f16SJoe Perches			print << "EOM"
6871d8469f16SJoe Perches
6872d8469f16SJoe PerchesNOTE: Whitespace errors detected.
6873d8469f16SJoe Perches      You may wish to use scripts/cleanpatch or scripts/cleanfile
6874d8469f16SJoe PerchesEOM
6875d2c0a235SAndy Whitcroft		}
6876d2c0a235SAndy Whitcroft	}
6877d2c0a235SAndy Whitcroft
6878d752fcc8SJoe Perches	if ($clean == 0 && $fix &&
6879d752fcc8SJoe Perches	    ("@rawlines" ne "@fixed" ||
6880d752fcc8SJoe Perches	     $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
68819624b8d6SJoe Perches		my $newfile = $filename;
68829624b8d6SJoe Perches		$newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
68833705ce5bSJoe Perches		my $linecount = 0;
68843705ce5bSJoe Perches		my $f;
68853705ce5bSJoe Perches
6886d752fcc8SJoe Perches		@fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
6887d752fcc8SJoe Perches
68883705ce5bSJoe Perches		open($f, '>', $newfile)
68893705ce5bSJoe Perches		    or die "$P: Can't open $newfile for write\n";
68903705ce5bSJoe Perches		foreach my $fixed_line (@fixed) {
68913705ce5bSJoe Perches			$linecount++;
68923705ce5bSJoe Perches			if ($file) {
68933705ce5bSJoe Perches				if ($linecount > 3) {
68943705ce5bSJoe Perches					$fixed_line =~ s/^\+//;
68953705ce5bSJoe Perches					print $f $fixed_line . "\n";
68963705ce5bSJoe Perches				}
68973705ce5bSJoe Perches			} else {
68983705ce5bSJoe Perches				print $f $fixed_line . "\n";
68993705ce5bSJoe Perches			}
69003705ce5bSJoe Perches		}
69013705ce5bSJoe Perches		close($f);
69023705ce5bSJoe Perches
69033705ce5bSJoe Perches		if (!$quiet) {
69043705ce5bSJoe Perches			print << "EOM";
6905d8469f16SJoe Perches
69063705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile'
69073705ce5bSJoe Perches
69083705ce5bSJoe PerchesDo _NOT_ trust the results written to this file.
69093705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness.
69103705ce5bSJoe Perches
69113705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches.
69123705ce5bSJoe PerchesNo warranties, expressed or implied...
69133705ce5bSJoe PerchesEOM
69143705ce5bSJoe Perches		}
69153705ce5bSJoe Perches	}
69163705ce5bSJoe Perches
6917d8469f16SJoe Perches	if ($quiet == 0) {
6918d8469f16SJoe Perches		print "\n";
6919d8469f16SJoe Perches		if ($clean == 1) {
6920d8469f16SJoe Perches			print "$vname has no obvious style problems and is ready for submission.\n";
6921d8469f16SJoe Perches		} else {
6922d8469f16SJoe Perches			print "$vname has style problems, please review.\n";
69230a920b5bSAndy Whitcroft		}
69240a920b5bSAndy Whitcroft	}
69250a920b5bSAndy Whitcroft	return $clean;
69260a920b5bSAndy Whitcroft}
6927