xref: /linux-6.15/scripts/checkpatch.pl (revision dbbf869d)
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";
546cd7f386SJoe Perchesmy $max_line_length = 80;
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
65*dbbf869dSJoe Perches# git output parsing needs US English output, so first set backtick child process LANGUAGE
66*dbbf869dSJoe Perchesmy $git_command ='export LANGUAGE=en_US.UTF-8; git';
6777f5b10aSHannes Eder
6877f5b10aSHannes Edersub help {
6977f5b10aSHannes Eder	my ($exitcode) = @_;
7077f5b10aSHannes Eder
7177f5b10aSHannes Eder	print << "EOM";
7277f5b10aSHannes EderUsage: $P [OPTION]... [FILE]...
7377f5b10aSHannes EderVersion: $V
7477f5b10aSHannes Eder
7577f5b10aSHannes EderOptions:
7677f5b10aSHannes Eder  -q, --quiet                quiet
7777f5b10aSHannes Eder  --no-tree                  run without a kernel tree
7877f5b10aSHannes Eder  --no-signoff               do not check for 'Signed-off-by' line
7977f5b10aSHannes Eder  --patch                    treat FILE as patchfile (default)
8077f5b10aSHannes Eder  --emacs                    emacs compile window format
8177f5b10aSHannes Eder  --terse                    one line per report
8234d8815fSJoe Perches  --showfile                 emit diffed file position, not input file position
834a593c34SDu, Changbin  -g, --git                  treat FILE as a single commit or git revision range
844a593c34SDu, Changbin                             single git commit with:
854a593c34SDu, Changbin                               <rev>
864a593c34SDu, Changbin                               <rev>^
874a593c34SDu, Changbin                               <rev>~n
884a593c34SDu, Changbin                             multiple git commits with:
894a593c34SDu, Changbin                               <rev1>..<rev2>
904a593c34SDu, Changbin                               <rev1>...<rev2>
914a593c34SDu, Changbin                               <rev>-<count>
924a593c34SDu, Changbin                             git merges are ignored
9377f5b10aSHannes Eder  -f, --file                 treat FILE as regular source file
9477f5b10aSHannes Eder  --subjective, --strict     enable more subjective tests
953beb42ecSJoe Perches  --list-types               list the possible message types
9691bfe484SJoe Perches  --types TYPE(,TYPE2...)    show only these comma separated message types
97000d1cc1SJoe Perches  --ignore TYPE(,TYPE2...)   ignore various comma separated message types
983beb42ecSJoe Perches  --show-types               show the specific message type in the output
996cd7f386SJoe Perches  --max-line-length=n        set the maximum line length, if exceeded, warn
10056193274SVadim Bendebury  --min-conf-desc-length=n   set the min description length, if shorter, warn
10177f5b10aSHannes Eder  --root=PATH                PATH to the kernel tree root
10277f5b10aSHannes Eder  --no-summary               suppress the per-file summary
10377f5b10aSHannes Eder  --mailback                 only produce a report in case of warnings/errors
10477f5b10aSHannes Eder  --summary-file             include the filename in summary
10577f5b10aSHannes Eder  --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of
10677f5b10aSHannes Eder                             'values', 'possible', 'type', and 'attr' (default
10777f5b10aSHannes Eder                             is all off)
10877f5b10aSHannes Eder  --test-only=WORD           report only warnings/errors containing WORD
10977f5b10aSHannes Eder                             literally
1103705ce5bSJoe Perches  --fix                      EXPERIMENTAL - may create horrible results
1113705ce5bSJoe Perches                             If correctable single-line errors exist, create
1123705ce5bSJoe Perches                             "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
1133705ce5bSJoe Perches                             with potential errors corrected to the preferred
1143705ce5bSJoe Perches                             checkpatch style
1159624b8d6SJoe Perches  --fix-inplace              EXPERIMENTAL - may create horrible results
1169624b8d6SJoe Perches                             Is the same as --fix, but overwrites the input
1179624b8d6SJoe Perches                             file.  It's your fault if there's no backup or git
118d62a201fSDave Hansen  --ignore-perl-version      override checking of perl version.  expect
119d62a201fSDave Hansen                             runtime errors.
120ebfd7d62SJoe Perches  --codespell                Use the codespell dictionary for spelling/typos
121f1a63678SMaxim Uvarov                             (default:/usr/share/codespell/dictionary.txt)
122ebfd7d62SJoe Perches  --codespellfile            Use this codespell dictionary
12375ad8c57SJerome Forissier  --typedefsfile             Read additional types from this file
124737c0767SJohn Brooks  --color[=WHEN]             Use colors 'always', 'never', or only when output
125737c0767SJohn Brooks                             is a terminal ('auto'). Default is 'auto'.
12677f5b10aSHannes Eder  -h, --help, --version      display this help and exit
12777f5b10aSHannes Eder
12877f5b10aSHannes EderWhen FILE is - read standard input.
12977f5b10aSHannes EderEOM
13077f5b10aSHannes Eder
13177f5b10aSHannes Eder	exit($exitcode);
13277f5b10aSHannes Eder}
13377f5b10aSHannes Eder
1343beb42ecSJoe Perchessub uniq {
1353beb42ecSJoe Perches	my %seen;
1363beb42ecSJoe Perches	return grep { !$seen{$_}++ } @_;
1373beb42ecSJoe Perches}
1383beb42ecSJoe Perches
1393beb42ecSJoe Perchessub list_types {
1403beb42ecSJoe Perches	my ($exitcode) = @_;
1413beb42ecSJoe Perches
1423beb42ecSJoe Perches	my $count = 0;
1433beb42ecSJoe Perches
1443beb42ecSJoe Perches	local $/ = undef;
1453beb42ecSJoe Perches
1463beb42ecSJoe Perches	open(my $script, '<', abs_path($P)) or
1473beb42ecSJoe Perches	    die "$P: Can't read '$P' $!\n";
1483beb42ecSJoe Perches
1493beb42ecSJoe Perches	my $text = <$script>;
1503beb42ecSJoe Perches	close($script);
1513beb42ecSJoe Perches
1523beb42ecSJoe Perches	my @types = ();
1530547fa58SJean Delvare	# Also catch when type or level is passed through a variable
1540547fa58SJean Delvare	for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {
1553beb42ecSJoe Perches		push (@types, $_);
1563beb42ecSJoe Perches	}
1573beb42ecSJoe Perches	@types = sort(uniq(@types));
1583beb42ecSJoe Perches	print("#\tMessage type\n\n");
1593beb42ecSJoe Perches	foreach my $type (@types) {
1603beb42ecSJoe Perches		print(++$count . "\t" . $type . "\n");
1613beb42ecSJoe Perches	}
1623beb42ecSJoe Perches
1633beb42ecSJoe Perches	exit($exitcode);
1643beb42ecSJoe Perches}
1653beb42ecSJoe Perches
166000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file);
167000d1cc1SJoe Perchesif (-f $conf) {
168000d1cc1SJoe Perches	my @conf_args;
169000d1cc1SJoe Perches	open(my $conffile, '<', "$conf")
170000d1cc1SJoe Perches	    or warn "$P: Can't find a readable $configuration_file file $!\n";
171000d1cc1SJoe Perches
172000d1cc1SJoe Perches	while (<$conffile>) {
173000d1cc1SJoe Perches		my $line = $_;
174000d1cc1SJoe Perches
175000d1cc1SJoe Perches		$line =~ s/\s*\n?$//g;
176000d1cc1SJoe Perches		$line =~ s/^\s*//g;
177000d1cc1SJoe Perches		$line =~ s/\s+/ /g;
178000d1cc1SJoe Perches
179000d1cc1SJoe Perches		next if ($line =~ m/^\s*#/);
180000d1cc1SJoe Perches		next if ($line =~ m/^\s*$/);
181000d1cc1SJoe Perches
182000d1cc1SJoe Perches		my @words = split(" ", $line);
183000d1cc1SJoe Perches		foreach my $word (@words) {
184000d1cc1SJoe Perches			last if ($word =~ m/^#/);
185000d1cc1SJoe Perches			push (@conf_args, $word);
186000d1cc1SJoe Perches		}
187000d1cc1SJoe Perches	}
188000d1cc1SJoe Perches	close($conffile);
189000d1cc1SJoe Perches	unshift(@ARGV, @conf_args) if @conf_args;
190000d1cc1SJoe Perches}
191000d1cc1SJoe Perches
192737c0767SJohn Brooks# Perl's Getopt::Long allows options to take optional arguments after a space.
193737c0767SJohn Brooks# Prevent --color by itself from consuming other arguments
194737c0767SJohn Brooksforeach (@ARGV) {
195737c0767SJohn Brooks	if ($_ eq "--color" || $_ eq "-color") {
196737c0767SJohn Brooks		$_ = "--color=$color";
197737c0767SJohn Brooks	}
198737c0767SJohn Brooks}
199737c0767SJohn Brooks
2000a920b5bSAndy WhitcroftGetOptions(
2016c72ffaaSAndy Whitcroft	'q|quiet+'	=> \$quiet,
2020a920b5bSAndy Whitcroft	'tree!'		=> \$tree,
2030a920b5bSAndy Whitcroft	'signoff!'	=> \$chk_signoff,
2040a920b5bSAndy Whitcroft	'patch!'	=> \$chk_patch,
2056c72ffaaSAndy Whitcroft	'emacs!'	=> \$emacs,
2068905a67cSAndy Whitcroft	'terse!'	=> \$terse,
20734d8815fSJoe Perches	'showfile!'	=> \$showfile,
20877f5b10aSHannes Eder	'f|file!'	=> \$file,
2094a593c34SDu, Changbin	'g|git!'	=> \$git,
2106c72ffaaSAndy Whitcroft	'subjective!'	=> \$check,
2116c72ffaaSAndy Whitcroft	'strict!'	=> \$check,
212000d1cc1SJoe Perches	'ignore=s'	=> \@ignore,
21391bfe484SJoe Perches	'types=s'	=> \@use,
214000d1cc1SJoe Perches	'show-types!'	=> \$show_types,
2153beb42ecSJoe Perches	'list-types!'	=> \$list_types,
2166cd7f386SJoe Perches	'max-line-length=i' => \$max_line_length,
21756193274SVadim Bendebury	'min-conf-desc-length=i' => \$min_conf_desc_length,
2186c72ffaaSAndy Whitcroft	'root=s'	=> \$root,
2198905a67cSAndy Whitcroft	'summary!'	=> \$summary,
2208905a67cSAndy Whitcroft	'mailback!'	=> \$mailback,
22113214adfSAndy Whitcroft	'summary-file!'	=> \$summary_file,
2223705ce5bSJoe Perches	'fix!'		=> \$fix,
2239624b8d6SJoe Perches	'fix-inplace!'	=> \$fix_inplace,
224d62a201fSDave Hansen	'ignore-perl-version!' => \$ignore_perl_version,
225c2fdda0dSAndy Whitcroft	'debug=s'	=> \%debug,
226773647a0SAndy Whitcroft	'test-only=s'	=> \$tst_only,
227ebfd7d62SJoe Perches	'codespell!'	=> \$codespell,
228ebfd7d62SJoe Perches	'codespellfile=s'	=> \$codespellfile,
22975ad8c57SJerome Forissier	'typedefsfile=s'	=> \$typedefsfile,
230737c0767SJohn Brooks	'color=s'	=> \$color,
231737c0767SJohn Brooks	'no-color'	=> \$color,	#keep old behaviors of -nocolor
232737c0767SJohn Brooks	'nocolor'	=> \$color,	#keep old behaviors of -nocolor
23377f5b10aSHannes Eder	'h|help'	=> \$help,
23477f5b10aSHannes Eder	'version'	=> \$help
23577f5b10aSHannes Eder) or help(1);
23677f5b10aSHannes Eder
23777f5b10aSHannes Ederhelp(0) if ($help);
2380a920b5bSAndy Whitcroft
2393beb42ecSJoe Percheslist_types(0) if ($list_types);
2403beb42ecSJoe Perches
2419624b8d6SJoe Perches$fix = 1 if ($fix_inplace);
2422ac73b4fSJoe Perches$check_orig = $check;
2439624b8d6SJoe Perches
2440a920b5bSAndy Whitcroftmy $exit = 0;
2450a920b5bSAndy Whitcroft
2465b57980dSJoe Perchesmy $perl_version_ok = 1;
247d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) {
2485b57980dSJoe Perches	$perl_version_ok = 0;
249d62a201fSDave Hansen	printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
2505b57980dSJoe Perches	exit(1) if (!$ignore_perl_version);
251d62a201fSDave Hansen}
252d62a201fSDave Hansen
25345107ff6SAllen Hubbe#if no filenames are given, push '-' to read patch from stdin
2540a920b5bSAndy Whitcroftif ($#ARGV < 0) {
25545107ff6SAllen Hubbe	push(@ARGV, '-');
2560a920b5bSAndy Whitcroft}
2570a920b5bSAndy Whitcroft
258737c0767SJohn Brooksif ($color =~ /^[01]$/) {
259737c0767SJohn Brooks	$color = !$color;
260737c0767SJohn Brooks} elsif ($color =~ /^always$/i) {
261737c0767SJohn Brooks	$color = 1;
262737c0767SJohn Brooks} elsif ($color =~ /^never$/i) {
263737c0767SJohn Brooks	$color = 0;
264737c0767SJohn Brooks} elsif ($color =~ /^auto$/i) {
265737c0767SJohn Brooks	$color = (-t STDOUT);
266737c0767SJohn Brooks} else {
267737c0767SJohn Brooks	die "Invalid color mode: $color\n";
268737c0767SJohn Brooks}
269737c0767SJohn Brooks
27091bfe484SJoe Perchessub hash_save_array_words {
27191bfe484SJoe Perches	my ($hashRef, $arrayRef) = @_;
27291bfe484SJoe Perches
27391bfe484SJoe Perches	my @array = split(/,/, join(',', @$arrayRef));
27491bfe484SJoe Perches	foreach my $word (@array) {
275000d1cc1SJoe Perches		$word =~ s/\s*\n?$//g;
276000d1cc1SJoe Perches		$word =~ s/^\s*//g;
277000d1cc1SJoe Perches		$word =~ s/\s+/ /g;
278000d1cc1SJoe Perches		$word =~ tr/[a-z]/[A-Z]/;
279000d1cc1SJoe Perches
280000d1cc1SJoe Perches		next if ($word =~ m/^\s*#/);
281000d1cc1SJoe Perches		next if ($word =~ m/^\s*$/);
282000d1cc1SJoe Perches
28391bfe484SJoe Perches		$hashRef->{$word}++;
284000d1cc1SJoe Perches	}
28591bfe484SJoe Perches}
28691bfe484SJoe Perches
28791bfe484SJoe Perchessub hash_show_words {
28891bfe484SJoe Perches	my ($hashRef, $prefix) = @_;
28991bfe484SJoe Perches
2903c816e49SJoe Perches	if (keys %$hashRef) {
291d8469f16SJoe Perches		print "\nNOTE: $prefix message types:";
29258cb3cf6SJoe Perches		foreach my $word (sort keys %$hashRef) {
29391bfe484SJoe Perches			print " $word";
29491bfe484SJoe Perches		}
295d8469f16SJoe Perches		print "\n";
29691bfe484SJoe Perches	}
29791bfe484SJoe Perches}
29891bfe484SJoe Perches
29991bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore);
30091bfe484SJoe Percheshash_save_array_words(\%use_type, \@use);
301000d1cc1SJoe Perches
302c2fdda0dSAndy Whitcroftmy $dbg_values = 0;
303c2fdda0dSAndy Whitcroftmy $dbg_possible = 0;
3047429c690SAndy Whitcroftmy $dbg_type = 0;
305a1ef277eSAndy Whitcroftmy $dbg_attr = 0;
306c2fdda0dSAndy Whitcroftfor my $key (keys %debug) {
30721caa13cSAndy Whitcroft	## no critic
30821caa13cSAndy Whitcroft	eval "\${dbg_$key} = '$debug{$key}';";
30921caa13cSAndy Whitcroft	die "$@" if ($@);
310c2fdda0dSAndy Whitcroft}
311c2fdda0dSAndy Whitcroft
312d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0;
313d2c0a235SAndy Whitcroft
3148905a67cSAndy Whitcroftif ($terse) {
3158905a67cSAndy Whitcroft	$emacs = 1;
3168905a67cSAndy Whitcroft	$quiet++;
3178905a67cSAndy Whitcroft}
3188905a67cSAndy Whitcroft
3196c72ffaaSAndy Whitcroftif ($tree) {
3206c72ffaaSAndy Whitcroft	if (defined $root) {
3216c72ffaaSAndy Whitcroft		if (!top_of_kernel_tree($root)) {
3226c72ffaaSAndy Whitcroft			die "$P: $root: --root does not point at a valid tree\n";
3236c72ffaaSAndy Whitcroft		}
3246c72ffaaSAndy Whitcroft	} else {
3256c72ffaaSAndy Whitcroft		if (top_of_kernel_tree('.')) {
3266c72ffaaSAndy Whitcroft			$root = '.';
3276c72ffaaSAndy Whitcroft		} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
3286c72ffaaSAndy Whitcroft						top_of_kernel_tree($1)) {
3296c72ffaaSAndy Whitcroft			$root = $1;
3306c72ffaaSAndy Whitcroft		}
3316c72ffaaSAndy Whitcroft	}
3326c72ffaaSAndy Whitcroft
3336c72ffaaSAndy Whitcroft	if (!defined $root) {
3340a920b5bSAndy Whitcroft		print "Must be run from the top-level dir. of a kernel tree\n";
3350a920b5bSAndy Whitcroft		exit(2);
3360a920b5bSAndy Whitcroft	}
3376c72ffaaSAndy Whitcroft}
3386c72ffaaSAndy Whitcroft
3396c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0;
3406c72ffaaSAndy Whitcroft
3412ceb532bSAndy Whitcroftour $Ident	= qr{
3422ceb532bSAndy Whitcroft			[A-Za-z_][A-Za-z\d_]*
3432ceb532bSAndy Whitcroft			(?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
3442ceb532bSAndy Whitcroft		}x;
3456c72ffaaSAndy Whitcroftour $Storage	= qr{extern|static|asmlinkage};
3466c72ffaaSAndy Whitcroftour $Sparse	= qr{
3476c72ffaaSAndy Whitcroft			__user|
3486c72ffaaSAndy Whitcroft			__kernel|
3496c72ffaaSAndy Whitcroft			__force|
3506c72ffaaSAndy Whitcroft			__iomem|
3516c72ffaaSAndy Whitcroft			__must_check|
352417495edSAndy Whitcroft			__kprobes|
353165e72a6SSven Eckelmann			__ref|
35433aa4597SGeert Uytterhoeven			__refconst|
35533aa4597SGeert Uytterhoeven			__refdata|
356ad315455SBoqun Feng			__rcu|
357ad315455SBoqun Feng			__private
3586c72ffaaSAndy Whitcroft		}x;
359e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
360e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
361e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
362e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
363e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
3648716de38SJoe Perches
36552131292SWolfram Sang# Notes to $Attribute:
36652131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
3676c72ffaaSAndy Whitcroftour $Attribute	= qr{
3686c72ffaaSAndy Whitcroft			const|
36903f1df7dSJoe Perches			__percpu|
37003f1df7dSJoe Perches			__nocast|
37103f1df7dSJoe Perches			__safe|
37246d832f5SMichael S. Tsirkin			__bitwise|
37303f1df7dSJoe Perches			__packed__|
37403f1df7dSJoe Perches			__packed2__|
37503f1df7dSJoe Perches			__naked|
37603f1df7dSJoe Perches			__maybe_unused|
37703f1df7dSJoe Perches			__always_unused|
37803f1df7dSJoe Perches			__noreturn|
37903f1df7dSJoe Perches			__used|
38003f1df7dSJoe Perches			__cold|
381e23ef1f3SJoe Perches			__pure|
38203f1df7dSJoe Perches			__noclone|
38303f1df7dSJoe Perches			__deprecated|
3846c72ffaaSAndy Whitcroft			__read_mostly|
385c5967e98SJoe Perches			__ro_after_init|
3866c72ffaaSAndy Whitcroft			__kprobes|
3878716de38SJoe Perches			$InitAttribute|
38824e1d81aSAndy Whitcroft			____cacheline_aligned|
38924e1d81aSAndy Whitcroft			____cacheline_aligned_in_smp|
3905fe3af11SAndy Whitcroft			____cacheline_internodealigned_in_smp|
3915fe3af11SAndy Whitcroft			__weak
3926c72ffaaSAndy Whitcroft		  }x;
393c45dcabdSAndy Whitcroftour $Modifier;
39491cb5195SJoe Perchesour $Inline	= qr{inline|__always_inline|noinline|__inline|__inline__};
3956c72ffaaSAndy Whitcroftour $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};
3966c72ffaaSAndy Whitcroftour $Lval	= qr{$Ident(?:$Member)*};
3976c72ffaaSAndy Whitcroft
39895e2c602SJoe Perchesour $Int_type	= qr{(?i)llu|ull|ll|lu|ul|l|u};
39995e2c602SJoe Perchesour $Binary	= qr{(?i)0b[01]+$Int_type?};
40095e2c602SJoe Perchesour $Hex	= qr{(?i)0x[0-9a-f]+$Int_type?};
40195e2c602SJoe Perchesour $Int	= qr{[0-9]+$Int_type?};
4022435880fSJoe Perchesour $Octal	= qr{0[0-7]+$Int_type?};
403c0a5c898SJoe Perchesour $String	= qr{"[X\t]*"};
404326b1ffcSJoe Perchesour $Float_hex	= qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
405326b1ffcSJoe Perchesour $Float_dec	= qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
406326b1ffcSJoe Perchesour $Float_int	= qr{(?i)[0-9]+e-?[0-9]+[fl]?};
40774349bccSJoe Perchesour $Float	= qr{$Float_hex|$Float_dec|$Float_int};
4082435880fSJoe Perchesour $Constant	= qr{$Float|$Binary|$Octal|$Hex|$Int};
409326b1ffcSJoe Perchesour $Assignment	= qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
410447432f3SJoe Perchesour $Compare    = qr{<=|>=|==|!=|<|(?<!-)>};
41123f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%};
4126c72ffaaSAndy Whitcroftour $Operators	= qr{
4136c72ffaaSAndy Whitcroft			<=|>=|==|!=|
4146c72ffaaSAndy Whitcroft			=>|->|<<|>>|<|>|!|~|
41523f780c9SJoe Perches			&&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
4166c72ffaaSAndy Whitcroft		  }x;
4176c72ffaaSAndy Whitcroft
41891cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
41991cb5195SJoe Perches
420ab7e23f3SJoe Perchesour $BasicType;
4218905a67cSAndy Whitcroftour $NonptrType;
4221813087dSJoe Perchesour $NonptrTypeMisordered;
4238716de38SJoe Perchesour $NonptrTypeWithAttr;
4248905a67cSAndy Whitcroftour $Type;
4251813087dSJoe Perchesour $TypeMisordered;
4268905a67cSAndy Whitcroftour $Declare;
4271813087dSJoe Perchesour $DeclareMisordered;
4288905a67cSAndy Whitcroft
42915662b3eSJoe Perchesour $NON_ASCII_UTF8	= qr{
43015662b3eSJoe Perches	[\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte
431171ae1a4SAndy Whitcroft	|  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
432171ae1a4SAndy Whitcroft	| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
433171ae1a4SAndy Whitcroft	|  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
434171ae1a4SAndy Whitcroft	|  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
435171ae1a4SAndy Whitcroft	| [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
436171ae1a4SAndy Whitcroft	|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
437171ae1a4SAndy Whitcroft}x;
438171ae1a4SAndy Whitcroft
43915662b3eSJoe Perchesour $UTF8	= qr{
44015662b3eSJoe Perches	[\x09\x0A\x0D\x20-\x7E]              # ASCII
44115662b3eSJoe Perches	| $NON_ASCII_UTF8
44215662b3eSJoe Perches}x;
44315662b3eSJoe Perches
444e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
445021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x:
446021158b4SJoe Perches	u_(?:char|short|int|long) |          # bsd
447021158b4SJoe Perches	u(?:nchar|short|int|long)            # sysv
448021158b4SJoe Perches)};
449e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x:
450fb9e9096SAndy Whitcroft	(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
4518ed22cadSAndy Whitcroft	atomic_t
4528ed22cadSAndy Whitcroft)};
453e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x:
454e6176fa4SJoe Perches	$typeC99Typedefs\b|
455e6176fa4SJoe Perches	$typeOtherOSTypedefs\b|
456e6176fa4SJoe Perches	$typeKernelTypedefs\b
457e6176fa4SJoe Perches)};
4588ed22cadSAndy Whitcroft
4596d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
4606d32f7a3SJoe Perches
461691e669bSJoe Perchesour $logFunctions = qr{(?x:
462758d7aadSMiles Chen	printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
4637d0b6594SJacob Keller	(?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
46487bd499aSJoe Perches	TP_printk|
4656e60c02eSJoe Perches	WARN(?:_RATELIMIT|_ONCE|)|
466b0531722SJoe Perches	panic|
46706668727SJoe Perches	MODULE_[A-Z_]+|
46806668727SJoe Perches	seq_vprintf|seq_printf|seq_puts
469691e669bSJoe Perches)};
470691e669bSJoe Perches
471e29a70f1SJoe Perchesour $allocFunctions = qr{(?x:
472e29a70f1SJoe Perches	(?:(?:devm_)?
473e29a70f1SJoe Perches		(?:kv|k|v)[czm]alloc(?:_node|_array)? |
474e29a70f1SJoe Perches		kstrdup(?:_const)? |
475e29a70f1SJoe Perches		kmemdup(?:_nul)?) |
476e29a70f1SJoe Perches	(?:\w+)?alloc_skb(?:ip_align)? |
477e29a70f1SJoe Perches				# dev_alloc_skb/netdev_alloc_skb, et al
478e29a70f1SJoe Perches	dma_alloc_coherent
479e29a70f1SJoe Perches)};
480e29a70f1SJoe Perches
48120112475SJoe Perchesour $signature_tags = qr{(?xi:
48220112475SJoe Perches	Signed-off-by:|
483d499480cSJorge Ramirez-Ortiz	Co-developed-by:|
48420112475SJoe Perches	Acked-by:|
48520112475SJoe Perches	Tested-by:|
48620112475SJoe Perches	Reviewed-by:|
48720112475SJoe Perches	Reported-by:|
4888543ae12SMugunthan V N	Suggested-by:|
48920112475SJoe Perches	To:|
49020112475SJoe Perches	Cc:
49120112475SJoe Perches)};
49220112475SJoe Perches
4931813087dSJoe Perchesour @typeListMisordered = (
4941813087dSJoe Perches	qr{char\s+(?:un)?signed},
4951813087dSJoe Perches	qr{int\s+(?:(?:un)?signed\s+)?short\s},
4961813087dSJoe Perches	qr{int\s+short(?:\s+(?:un)?signed)},
4971813087dSJoe Perches	qr{short\s+int(?:\s+(?:un)?signed)},
4981813087dSJoe Perches	qr{(?:un)?signed\s+int\s+short},
4991813087dSJoe Perches	qr{short\s+(?:un)?signed},
5001813087dSJoe Perches	qr{long\s+int\s+(?:un)?signed},
5011813087dSJoe Perches	qr{int\s+long\s+(?:un)?signed},
5021813087dSJoe Perches	qr{long\s+(?:un)?signed\s+int},
5031813087dSJoe Perches	qr{int\s+(?:un)?signed\s+long},
5041813087dSJoe Perches	qr{int\s+(?:un)?signed},
5051813087dSJoe Perches	qr{int\s+long\s+long\s+(?:un)?signed},
5061813087dSJoe Perches	qr{long\s+long\s+int\s+(?:un)?signed},
5071813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed\s+int},
5081813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed},
5091813087dSJoe Perches	qr{long\s+(?:un)?signed},
5101813087dSJoe Perches);
5111813087dSJoe Perches
5128905a67cSAndy Whitcroftour @typeList = (
5138905a67cSAndy Whitcroft	qr{void},
5140c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?char},
5150c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short\s+int},
5160c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short},
5170c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?int},
5180c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+int},
5190c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
5200c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long},
5210c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long},
5220c773d9dSJoe Perches	qr{(?:un)?signed},
5238905a67cSAndy Whitcroft	qr{float},
5248905a67cSAndy Whitcroft	qr{double},
5258905a67cSAndy Whitcroft	qr{bool},
5268905a67cSAndy Whitcroft	qr{struct\s+$Ident},
5278905a67cSAndy Whitcroft	qr{union\s+$Ident},
5288905a67cSAndy Whitcroft	qr{enum\s+$Ident},
5298905a67cSAndy Whitcroft	qr{${Ident}_t},
5308905a67cSAndy Whitcroft	qr{${Ident}_handler},
5318905a67cSAndy Whitcroft	qr{${Ident}_handler_fn},
5321813087dSJoe Perches	@typeListMisordered,
5338905a67cSAndy Whitcroft);
534938224b5SJoe Perches
535938224b5SJoe Perchesour $C90_int_types = qr{(?x:
536938224b5SJoe Perches	long\s+long\s+int\s+(?:un)?signed|
537938224b5SJoe Perches	long\s+long\s+(?:un)?signed\s+int|
538938224b5SJoe Perches	long\s+long\s+(?:un)?signed|
539938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long\s+int|
540938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long|
541938224b5SJoe Perches	int\s+long\s+long\s+(?:un)?signed|
542938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long\s+long|
543938224b5SJoe Perches
544938224b5SJoe Perches	long\s+int\s+(?:un)?signed|
545938224b5SJoe Perches	long\s+(?:un)?signed\s+int|
546938224b5SJoe Perches	long\s+(?:un)?signed|
547938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+int|
548938224b5SJoe Perches	(?:(?:un)?signed\s+)?long|
549938224b5SJoe Perches	int\s+long\s+(?:un)?signed|
550938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long|
551938224b5SJoe Perches
552938224b5SJoe Perches	int\s+(?:un)?signed|
553938224b5SJoe Perches	(?:(?:un)?signed\s+)?int
554938224b5SJoe Perches)};
555938224b5SJoe Perches
556485ff23eSAlex Dowadour @typeListFile = ();
5578716de38SJoe Perchesour @typeListWithAttr = (
5588716de38SJoe Perches	@typeList,
5598716de38SJoe Perches	qr{struct\s+$InitAttribute\s+$Ident},
5608716de38SJoe Perches	qr{union\s+$InitAttribute\s+$Ident},
5618716de38SJoe Perches);
5628716de38SJoe Perches
563c45dcabdSAndy Whitcroftour @modifierList = (
564c45dcabdSAndy Whitcroft	qr{fastcall},
565c45dcabdSAndy Whitcroft);
566485ff23eSAlex Dowadour @modifierListFile = ();
5678905a67cSAndy Whitcroft
5682435880fSJoe Perchesour @mode_permission_funcs = (
5692435880fSJoe Perches	["module_param", 3],
5702435880fSJoe Perches	["module_param_(?:array|named|string)", 4],
5712435880fSJoe Perches	["module_param_array_named", 5],
5722435880fSJoe Perches	["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
5732435880fSJoe Perches	["proc_create(?:_data|)", 2],
574459cf0aeSJoe Perches	["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
575459cf0aeSJoe Perches	["IIO_DEV_ATTR_[A-Z_]+", 1],
576459cf0aeSJoe Perches	["SENSOR_(?:DEVICE_|)ATTR_2", 2],
577459cf0aeSJoe Perches	["SENSOR_TEMPLATE(?:_2|)", 3],
578459cf0aeSJoe Perches	["__ATTR", 2],
5792435880fSJoe Perches);
5802435880fSJoe Perches
581515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below
582515a235eSJoe Perchesour $mode_perms_search = "";
583515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) {
584515a235eSJoe Perches	$mode_perms_search .= '|' if ($mode_perms_search ne "");
585515a235eSJoe Perches	$mode_perms_search .= $entry->[0];
586515a235eSJoe Perches}
58700180468SJoe Perches$mode_perms_search = "(?:${mode_perms_search})";
588515a235eSJoe Perches
5899189c7e7SJoe Perchesour %deprecated_apis = (
5909189c7e7SJoe Perches	"synchronize_rcu_bh"			=> "synchronize_rcu",
5919189c7e7SJoe Perches	"synchronize_rcu_bh_expedited"		=> "synchronize_rcu_expedited",
5929189c7e7SJoe Perches	"call_rcu_bh"				=> "call_rcu",
5939189c7e7SJoe Perches	"rcu_barrier_bh"			=> "rcu_barrier",
5949189c7e7SJoe Perches	"synchronize_sched"			=> "synchronize_rcu",
5959189c7e7SJoe Perches	"synchronize_sched_expedited"		=> "synchronize_rcu_expedited",
5969189c7e7SJoe Perches	"call_rcu_sched"			=> "call_rcu",
5979189c7e7SJoe Perches	"rcu_barrier_sched"			=> "rcu_barrier",
5989189c7e7SJoe Perches	"get_state_synchronize_sched"		=> "get_state_synchronize_rcu",
5999189c7e7SJoe Perches	"cond_synchronize_sched"		=> "cond_synchronize_rcu",
6009189c7e7SJoe Perches);
6019189c7e7SJoe Perches
6029189c7e7SJoe Perches#Create a search pattern for all these strings to speed up a loop below
6039189c7e7SJoe Perchesour $deprecated_apis_search = "";
6049189c7e7SJoe Perchesforeach my $entry (keys %deprecated_apis) {
6059189c7e7SJoe Perches	$deprecated_apis_search .= '|' if ($deprecated_apis_search ne "");
6069189c7e7SJoe Perches	$deprecated_apis_search .= $entry;
6079189c7e7SJoe Perches}
6089189c7e7SJoe Perches$deprecated_apis_search = "(?:${deprecated_apis_search})";
6099189c7e7SJoe Perches
610b392c64fSJoe Perchesour $mode_perms_world_writable = qr{
611b392c64fSJoe Perches	S_IWUGO		|
612b392c64fSJoe Perches	S_IWOTH		|
613b392c64fSJoe Perches	S_IRWXUGO	|
614b392c64fSJoe Perches	S_IALLUGO	|
615b392c64fSJoe Perches	0[0-7][0-7][2367]
616b392c64fSJoe Perches}x;
617b392c64fSJoe Perches
618f90774e1SJoe Perchesour %mode_permission_string_types = (
619f90774e1SJoe Perches	"S_IRWXU" => 0700,
620f90774e1SJoe Perches	"S_IRUSR" => 0400,
621f90774e1SJoe Perches	"S_IWUSR" => 0200,
622f90774e1SJoe Perches	"S_IXUSR" => 0100,
623f90774e1SJoe Perches	"S_IRWXG" => 0070,
624f90774e1SJoe Perches	"S_IRGRP" => 0040,
625f90774e1SJoe Perches	"S_IWGRP" => 0020,
626f90774e1SJoe Perches	"S_IXGRP" => 0010,
627f90774e1SJoe Perches	"S_IRWXO" => 0007,
628f90774e1SJoe Perches	"S_IROTH" => 0004,
629f90774e1SJoe Perches	"S_IWOTH" => 0002,
630f90774e1SJoe Perches	"S_IXOTH" => 0001,
631f90774e1SJoe Perches	"S_IRWXUGO" => 0777,
632f90774e1SJoe Perches	"S_IRUGO" => 0444,
633f90774e1SJoe Perches	"S_IWUGO" => 0222,
634f90774e1SJoe Perches	"S_IXUGO" => 0111,
635f90774e1SJoe Perches);
636f90774e1SJoe Perches
637f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below
638f90774e1SJoe Perchesour $mode_perms_string_search = "";
639f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) {
640f90774e1SJoe Perches	$mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
641f90774e1SJoe Perches	$mode_perms_string_search .= $entry;
642f90774e1SJoe Perches}
64300180468SJoe Perchesour $single_mode_perms_string_search = "(?:${mode_perms_string_search})";
64400180468SJoe Perchesour $multi_mode_perms_string_search = qr{
64500180468SJoe Perches	${single_mode_perms_string_search}
64600180468SJoe Perches	(?:\s*\|\s*${single_mode_perms_string_search})*
64700180468SJoe Perches}x;
64800180468SJoe Perches
64900180468SJoe Perchessub perms_to_octal {
65000180468SJoe Perches	my ($string) = @_;
65100180468SJoe Perches
65200180468SJoe Perches	return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/);
65300180468SJoe Perches
65400180468SJoe Perches	my $val = "";
65500180468SJoe Perches	my $oval = "";
65600180468SJoe Perches	my $to = 0;
65700180468SJoe Perches	my $curpos = 0;
65800180468SJoe Perches	my $lastpos = 0;
65900180468SJoe Perches	while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
66000180468SJoe Perches		$curpos = pos($string);
66100180468SJoe Perches		my $match = $2;
66200180468SJoe Perches		my $omatch = $1;
66300180468SJoe Perches		last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
66400180468SJoe Perches		$lastpos = $curpos;
66500180468SJoe Perches		$to |= $mode_permission_string_types{$match};
66600180468SJoe Perches		$val .= '\s*\|\s*' if ($val ne "");
66700180468SJoe Perches		$val .= $match;
66800180468SJoe Perches		$oval .= $omatch;
66900180468SJoe Perches	}
67000180468SJoe Perches	$oval =~ s/^\s*\|\s*//;
67100180468SJoe Perches	$oval =~ s/\s*\|\s*$//;
67200180468SJoe Perches	return sprintf("%04o", $to);
67300180468SJoe Perches}
674f90774e1SJoe Perches
6757840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x:
6767840a94cSWolfram Sang	irq|
677cdcee686SSergey Ryazanov	memory|
678cdcee686SSergey Ryazanov	time|
679cdcee686SSergey Ryazanov	reboot
6807840a94cSWolfram Sang)};
6817840a94cSWolfram Sang# memory.h: ARM has a custom one
6827840a94cSWolfram Sang
68366b47b4aSKees Cook# Load common spelling mistakes and build regular expression list.
68466b47b4aSKees Cookmy $misspellings;
68566b47b4aSKees Cookmy %spelling_fix;
68636061e38SJoe Perches
68736061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) {
68866b47b4aSKees Cook	while (<$spelling>) {
68966b47b4aSKees Cook		my $line = $_;
69066b47b4aSKees Cook
69166b47b4aSKees Cook		$line =~ s/\s*\n?$//g;
69266b47b4aSKees Cook		$line =~ s/^\s*//g;
69366b47b4aSKees Cook
69466b47b4aSKees Cook		next if ($line =~ m/^\s*#/);
69566b47b4aSKees Cook		next if ($line =~ m/^\s*$/);
69666b47b4aSKees Cook
69766b47b4aSKees Cook		my ($suspect, $fix) = split(/\|\|/, $line);
69866b47b4aSKees Cook
69966b47b4aSKees Cook		$spelling_fix{$suspect} = $fix;
70066b47b4aSKees Cook	}
70166b47b4aSKees Cook	close($spelling);
70236061e38SJoe Perches} else {
70336061e38SJoe Perches	warn "No typos will be found - file '$spelling_file': $!\n";
70436061e38SJoe Perches}
70566b47b4aSKees Cook
706ebfd7d62SJoe Perchesif ($codespell) {
707ebfd7d62SJoe Perches	if (open(my $spelling, '<', $codespellfile)) {
708ebfd7d62SJoe Perches		while (<$spelling>) {
709ebfd7d62SJoe Perches			my $line = $_;
710ebfd7d62SJoe Perches
711ebfd7d62SJoe Perches			$line =~ s/\s*\n?$//g;
712ebfd7d62SJoe Perches			$line =~ s/^\s*//g;
713ebfd7d62SJoe Perches
714ebfd7d62SJoe Perches			next if ($line =~ m/^\s*#/);
715ebfd7d62SJoe Perches			next if ($line =~ m/^\s*$/);
716ebfd7d62SJoe Perches			next if ($line =~ m/, disabled/i);
717ebfd7d62SJoe Perches
718ebfd7d62SJoe Perches			$line =~ s/,.*$//;
719ebfd7d62SJoe Perches
720ebfd7d62SJoe Perches			my ($suspect, $fix) = split(/->/, $line);
721ebfd7d62SJoe Perches
722ebfd7d62SJoe Perches			$spelling_fix{$suspect} = $fix;
723ebfd7d62SJoe Perches		}
724ebfd7d62SJoe Perches		close($spelling);
725ebfd7d62SJoe Perches	} else {
726ebfd7d62SJoe Perches		warn "No codespell typos will be found - file '$codespellfile': $!\n";
727ebfd7d62SJoe Perches	}
728ebfd7d62SJoe Perches}
729ebfd7d62SJoe Perches
730ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
731ebfd7d62SJoe Perches
73275ad8c57SJerome Forissiersub read_words {
73375ad8c57SJerome Forissier	my ($wordsRef, $file) = @_;
73475ad8c57SJerome Forissier
73575ad8c57SJerome Forissier	if (open(my $words, '<', $file)) {
73675ad8c57SJerome Forissier		while (<$words>) {
737bf1fa1daSJoe Perches			my $line = $_;
738bf1fa1daSJoe Perches
739bf1fa1daSJoe Perches			$line =~ s/\s*\n?$//g;
740bf1fa1daSJoe Perches			$line =~ s/^\s*//g;
741bf1fa1daSJoe Perches
742bf1fa1daSJoe Perches			next if ($line =~ m/^\s*#/);
743bf1fa1daSJoe Perches			next if ($line =~ m/^\s*$/);
744bf1fa1daSJoe Perches			if ($line =~ /\s/) {
74575ad8c57SJerome Forissier				print("$file: '$line' invalid - ignored\n");
746bf1fa1daSJoe Perches				next;
747bf1fa1daSJoe Perches			}
748bf1fa1daSJoe Perches
74975ad8c57SJerome Forissier			$$wordsRef .= '|' if ($$wordsRef ne "");
75075ad8c57SJerome Forissier			$$wordsRef .= $line;
751bf1fa1daSJoe Perches		}
75275ad8c57SJerome Forissier		close($file);
75375ad8c57SJerome Forissier		return 1;
754bf1fa1daSJoe Perches	}
755bf1fa1daSJoe Perches
75675ad8c57SJerome Forissier	return 0;
75775ad8c57SJerome Forissier}
75875ad8c57SJerome Forissier
75975ad8c57SJerome Forissiermy $const_structs = "";
76075ad8c57SJerome Forissierread_words(\$const_structs, $conststructsfile)
76175ad8c57SJerome Forissier    or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
76275ad8c57SJerome Forissier
76375ad8c57SJerome Forissiermy $typeOtherTypedefs = "";
76475ad8c57SJerome Forissierif (length($typedefsfile)) {
76575ad8c57SJerome Forissier	read_words(\$typeOtherTypedefs, $typedefsfile)
76675ad8c57SJerome Forissier	    or warn "No additional types will be considered - file '$typedefsfile': $!\n";
76775ad8c57SJerome Forissier}
76875ad8c57SJerome Forissier$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne "");
76975ad8c57SJerome Forissier
7708905a67cSAndy Whitcroftsub build_types {
771485ff23eSAlex Dowad	my $mods = "(?x:  \n" . join("|\n  ", (@modifierList, @modifierListFile)) . "\n)";
772485ff23eSAlex Dowad	my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile)) . "\n)";
7731813087dSJoe Perches	my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered) . "\n)";
7748716de38SJoe Perches	my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr) . "\n)";
775c8cb2ca3SAndy Whitcroft	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};
776ab7e23f3SJoe Perches	$BasicType	= qr{
777ab7e23f3SJoe Perches				(?:$typeTypedefs\b)|
778ab7e23f3SJoe Perches				(?:${all}\b)
779ab7e23f3SJoe Perches		}x;
7808905a67cSAndy Whitcroft	$NonptrType	= qr{
781d2172eb5SAndy Whitcroft			(?:$Modifier\s+|const\s+)*
782cf655043SAndy Whitcroft			(?:
7836b48db24SAndy Whitcroft				(?:typeof|__typeof__)\s*\([^\)]*\)|
7848ed22cadSAndy Whitcroft				(?:$typeTypedefs\b)|
785c45dcabdSAndy Whitcroft				(?:${all}\b)
786cf655043SAndy Whitcroft			)
787c8cb2ca3SAndy Whitcroft			(?:\s+$Modifier|\s+const)*
7888905a67cSAndy Whitcroft		  }x;
7891813087dSJoe Perches	$NonptrTypeMisordered	= qr{
7901813087dSJoe Perches			(?:$Modifier\s+|const\s+)*
7911813087dSJoe Perches			(?:
7921813087dSJoe Perches				(?:${Misordered}\b)
7931813087dSJoe Perches			)
7941813087dSJoe Perches			(?:\s+$Modifier|\s+const)*
7951813087dSJoe Perches		  }x;
7968716de38SJoe Perches	$NonptrTypeWithAttr	= qr{
7978716de38SJoe Perches			(?:$Modifier\s+|const\s+)*
7988716de38SJoe Perches			(?:
7998716de38SJoe Perches				(?:typeof|__typeof__)\s*\([^\)]*\)|
8008716de38SJoe Perches				(?:$typeTypedefs\b)|
8018716de38SJoe Perches				(?:${allWithAttr}\b)
8028716de38SJoe Perches			)
8038716de38SJoe Perches			(?:\s+$Modifier|\s+const)*
8048716de38SJoe Perches		  }x;
8058905a67cSAndy Whitcroft	$Type	= qr{
806c45dcabdSAndy Whitcroft			$NonptrType
8071574a29fSJoe Perches			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
808c8cb2ca3SAndy Whitcroft			(?:\s+$Inline|\s+$Modifier)*
8098905a67cSAndy Whitcroft		  }x;
8101813087dSJoe Perches	$TypeMisordered	= qr{
8111813087dSJoe Perches			$NonptrTypeMisordered
8121813087dSJoe Perches			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
8131813087dSJoe Perches			(?:\s+$Inline|\s+$Modifier)*
8141813087dSJoe Perches		  }x;
81591cb5195SJoe Perches	$Declare	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
8161813087dSJoe Perches	$DeclareMisordered	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
8178905a67cSAndy Whitcroft}
8188905a67cSAndy Whitcroftbuild_types();
8196c72ffaaSAndy Whitcroft
8207d2367afSJoe Perchesour $Typecast	= qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
821d1fe9c09SJoe Perches
822d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg
823d1fe9c09SJoe Perches# requires at least perl version v5.10.0
824d1fe9c09SJoe Perches# Any use must be runtime checked with $^V
825d1fe9c09SJoe Perches
826d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
8272435880fSJoe Perchesour $LvalOrFunc	= qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
828c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
8297d2367afSJoe Perches
830f8422308SJoe Perchesour $declaration_macros = qr{(?x:
8313e838b6cSJoe Perches	(?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
832fe658f94SSteffen Maier	(?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
8333d102fc0SGilad Ben-Yossef	(?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(|
8343d102fc0SGilad Ben-Yossef	(?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(
835f8422308SJoe Perches)};
836f8422308SJoe Perches
8377d2367afSJoe Perchessub deparenthesize {
8387d2367afSJoe Perches	my ($string) = @_;
8397d2367afSJoe Perches	return "" if (!defined($string));
8405b9553abSJoe Perches
8415b9553abSJoe Perches	while ($string =~ /^\s*\(.*\)\s*$/) {
8425b9553abSJoe Perches		$string =~ s@^\s*\(\s*@@;
8435b9553abSJoe Perches		$string =~ s@\s*\)\s*$@@;
8445b9553abSJoe Perches	}
8455b9553abSJoe Perches
8467d2367afSJoe Perches	$string =~ s@\s+@ @g;
8475b9553abSJoe Perches
8487d2367afSJoe Perches	return $string;
8497d2367afSJoe Perches}
8507d2367afSJoe Perches
8513445686aSJoe Perchessub seed_camelcase_file {
8523445686aSJoe Perches	my ($file) = @_;
8533445686aSJoe Perches
8543445686aSJoe Perches	return if (!(-f $file));
8553445686aSJoe Perches
8563445686aSJoe Perches	local $/;
8573445686aSJoe Perches
8583445686aSJoe Perches	open(my $include_file, '<', "$file")
8593445686aSJoe Perches	    or warn "$P: Can't read '$file' $!\n";
8603445686aSJoe Perches	my $text = <$include_file>;
8613445686aSJoe Perches	close($include_file);
8623445686aSJoe Perches
8633445686aSJoe Perches	my @lines = split('\n', $text);
8643445686aSJoe Perches
8653445686aSJoe Perches	foreach my $line (@lines) {
8663445686aSJoe Perches		next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
8673445686aSJoe Perches		if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
8683445686aSJoe Perches			$camelcase{$1} = 1;
86911ea516aSJoe Perches		} elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
87011ea516aSJoe Perches			$camelcase{$1} = 1;
87111ea516aSJoe Perches		} elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
8723445686aSJoe Perches			$camelcase{$1} = 1;
8733445686aSJoe Perches		}
8743445686aSJoe Perches	}
8753445686aSJoe Perches}
8763445686aSJoe Perches
87785b0ee18SJoe Perchessub is_maintained_obsolete {
87885b0ee18SJoe Perches	my ($filename) = @_;
87985b0ee18SJoe Perches
880f2c19c2fSJerome Forissier	return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
88185b0ee18SJoe Perches
8820616efa4SJoe Perches	my $status = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
88385b0ee18SJoe Perches
88485b0ee18SJoe Perches	return $status =~ /obsolete/i;
88585b0ee18SJoe Perches}
88685b0ee18SJoe Perches
8873b6e8ac9SJoe Perchessub is_SPDX_License_valid {
8883b6e8ac9SJoe Perches	my ($license) = @_;
8893b6e8ac9SJoe Perches
89056294112SJoe Perches	return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$root/.git"));
8913b6e8ac9SJoe Perches
89256294112SJoe Perches	my $root_path = abs_path($root);
89356294112SJoe Perches	my $status = `cd "$root_path"; echo "$license" | python scripts/spdxcheck.py -`;
8943b6e8ac9SJoe Perches	return 0 if ($status ne "");
8953b6e8ac9SJoe Perches	return 1;
8963b6e8ac9SJoe Perches}
8973b6e8ac9SJoe Perches
8983445686aSJoe Perchesmy $camelcase_seeded = 0;
8993445686aSJoe Perchessub seed_camelcase_includes {
9003445686aSJoe Perches	return if ($camelcase_seeded);
9013445686aSJoe Perches
9023445686aSJoe Perches	my $files;
903c707a81dSJoe Perches	my $camelcase_cache = "";
904c707a81dSJoe Perches	my @include_files = ();
905c707a81dSJoe Perches
906c707a81dSJoe Perches	$camelcase_seeded = 1;
907351b2a1fSJoe Perches
9083645e328SRichard Genoud	if (-e ".git") {
909*dbbf869dSJoe Perches		my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`;
910351b2a1fSJoe Perches		chomp $git_last_include_commit;
911c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
912c707a81dSJoe Perches	} else {
913c707a81dSJoe Perches		my $last_mod_date = 0;
914c707a81dSJoe Perches		$files = `find $root/include -name "*.h"`;
915c707a81dSJoe Perches		@include_files = split('\n', $files);
916c707a81dSJoe Perches		foreach my $file (@include_files) {
917c707a81dSJoe Perches			my $date = POSIX::strftime("%Y%m%d%H%M",
918c707a81dSJoe Perches						   localtime((stat $file)[9]));
919c707a81dSJoe Perches			$last_mod_date = $date if ($last_mod_date < $date);
920c707a81dSJoe Perches		}
921c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
922c707a81dSJoe Perches	}
923c707a81dSJoe Perches
924c707a81dSJoe Perches	if ($camelcase_cache ne "" && -f $camelcase_cache) {
925c707a81dSJoe Perches		open(my $camelcase_file, '<', "$camelcase_cache")
926c707a81dSJoe Perches		    or warn "$P: Can't read '$camelcase_cache' $!\n";
927351b2a1fSJoe Perches		while (<$camelcase_file>) {
928351b2a1fSJoe Perches			chomp;
929351b2a1fSJoe Perches			$camelcase{$_} = 1;
930351b2a1fSJoe Perches		}
931351b2a1fSJoe Perches		close($camelcase_file);
932351b2a1fSJoe Perches
933351b2a1fSJoe Perches		return;
934351b2a1fSJoe Perches	}
935c707a81dSJoe Perches
9363645e328SRichard Genoud	if (-e ".git") {
937*dbbf869dSJoe Perches		$files = `${git_command} ls-files "include/*.h"`;
938c707a81dSJoe Perches		@include_files = split('\n', $files);
9393445686aSJoe Perches	}
940c707a81dSJoe Perches
9413445686aSJoe Perches	foreach my $file (@include_files) {
9423445686aSJoe Perches		seed_camelcase_file($file);
9433445686aSJoe Perches	}
944351b2a1fSJoe Perches
945c707a81dSJoe Perches	if ($camelcase_cache ne "") {
946351b2a1fSJoe Perches		unlink glob ".checkpatch-camelcase.*";
947c707a81dSJoe Perches		open(my $camelcase_file, '>', "$camelcase_cache")
948c707a81dSJoe Perches		    or warn "$P: Can't write '$camelcase_cache' $!\n";
949351b2a1fSJoe Perches		foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
950351b2a1fSJoe Perches			print $camelcase_file ("$_\n");
951351b2a1fSJoe Perches		}
952351b2a1fSJoe Perches		close($camelcase_file);
953351b2a1fSJoe Perches	}
9543445686aSJoe Perches}
9553445686aSJoe Perches
956d311cd44SJoe Perchessub git_commit_info {
957d311cd44SJoe Perches	my ($commit, $id, $desc) = @_;
958d311cd44SJoe Perches
959d311cd44SJoe Perches	return ($id, $desc) if ((which("git") eq "") || !(-e ".git"));
960d311cd44SJoe Perches
961*dbbf869dSJoe Perches	my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`;
962d311cd44SJoe Perches	$output =~ s/^\s*//gm;
963d311cd44SJoe Perches	my @lines = split("\n", $output);
964d311cd44SJoe Perches
9650d7835fcSJoe Perches	return ($id, $desc) if ($#lines < 0);
9660d7835fcSJoe Perches
9675a7f4455SSean Christopherson	if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) {
968d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns
969d311cd44SJoe Perches# all matching commit ids, but it's very slow...
970d311cd44SJoe Perches#
971d311cd44SJoe Perches#		echo "checking commits $1..."
972d311cd44SJoe Perches#		git rev-list --remotes | grep -i "^$1" |
973d311cd44SJoe Perches#		while read line ; do
974d311cd44SJoe Perches#		    git log --format='%H %s' -1 $line |
975d311cd44SJoe Perches#		    echo "commit $(cut -c 1-12,41-)"
976d311cd44SJoe Perches#		done
977d311cd44SJoe Perches	} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) {
978948b133aSHeinrich Schuchardt		$id = undef;
979d311cd44SJoe Perches	} else {
980d311cd44SJoe Perches		$id = substr($lines[0], 0, 12);
981d311cd44SJoe Perches		$desc = substr($lines[0], 41);
982d311cd44SJoe Perches	}
983d311cd44SJoe Perches
984d311cd44SJoe Perches	return ($id, $desc);
985d311cd44SJoe Perches}
986d311cd44SJoe Perches
9876c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file);
9880a920b5bSAndy Whitcroft
98900df344fSAndy Whitcroftmy @rawlines = ();
990c2fdda0dSAndy Whitcroftmy @lines = ();
9913705ce5bSJoe Perchesmy @fixed = ();
992d752fcc8SJoe Perchesmy @fixed_inserted = ();
993d752fcc8SJoe Perchesmy @fixed_deleted = ();
994194f66fcSJoe Perchesmy $fixlinenr = -1;
995194f66fcSJoe Perches
9964a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions.
9974a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
9984a593c34SDu, Changbindie "$P: No git repository found\n" if ($git && !-e ".git");
9994a593c34SDu, Changbin
10004a593c34SDu, Changbinif ($git) {
10014a593c34SDu, Changbin	my @commits = ();
10020dea9f1eSJoe Perches	foreach my $commit_expr (@ARGV) {
10034a593c34SDu, Changbin		my $git_range;
100428898fd1SJoe Perches		if ($commit_expr =~ m/^(.*)-(\d+)$/) {
100528898fd1SJoe Perches			$git_range = "-$2 $1";
10064a593c34SDu, Changbin		} elsif ($commit_expr =~ m/\.\./) {
10074a593c34SDu, Changbin			$git_range = "$commit_expr";
10084a593c34SDu, Changbin		} else {
10090dea9f1eSJoe Perches			$git_range = "-1 $commit_expr";
10100dea9f1eSJoe Perches		}
1011*dbbf869dSJoe Perches		my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
10120dea9f1eSJoe Perches		foreach my $line (split(/\n/, $lines)) {
101328898fd1SJoe Perches			$line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
101428898fd1SJoe Perches			next if (!defined($1) || !defined($2));
10150dea9f1eSJoe Perches			my $sha1 = $1;
10160dea9f1eSJoe Perches			my $subject = $2;
10170dea9f1eSJoe Perches			unshift(@commits, $sha1);
10180dea9f1eSJoe Perches			$git_commits{$sha1} = $subject;
10194a593c34SDu, Changbin		}
10204a593c34SDu, Changbin	}
10214a593c34SDu, Changbin	die "$P: no git commits after extraction!\n" if (@commits == 0);
10224a593c34SDu, Changbin	@ARGV = @commits;
10234a593c34SDu, Changbin}
10244a593c34SDu, Changbin
1025c2fdda0dSAndy Whitcroftmy $vname;
102698005e8cSVadim Bendebury$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"};
10276c72ffaaSAndy Whitcroftfor my $filename (@ARGV) {
102821caa13cSAndy Whitcroft	my $FILE;
10294a593c34SDu, Changbin	if ($git) {
10304a593c34SDu, Changbin		open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
10314a593c34SDu, Changbin			die "$P: $filename: git format-patch failed - $!\n";
10324a593c34SDu, Changbin	} elsif ($file) {
103321caa13cSAndy Whitcroft		open($FILE, '-|', "diff -u /dev/null $filename") ||
10346c72ffaaSAndy Whitcroft			die "$P: $filename: diff failed - $!\n";
103521caa13cSAndy Whitcroft	} elsif ($filename eq '-') {
103621caa13cSAndy Whitcroft		open($FILE, '<&STDIN');
10376c72ffaaSAndy Whitcroft	} else {
103821caa13cSAndy Whitcroft		open($FILE, '<', "$filename") ||
10396c72ffaaSAndy Whitcroft			die "$P: $filename: open failed - $!\n";
10406c72ffaaSAndy Whitcroft	}
1041c2fdda0dSAndy Whitcroft	if ($filename eq '-') {
1042c2fdda0dSAndy Whitcroft		$vname = 'Your patch';
10434a593c34SDu, Changbin	} elsif ($git) {
10440dea9f1eSJoe Perches		$vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
1045c2fdda0dSAndy Whitcroft	} else {
1046c2fdda0dSAndy Whitcroft		$vname = $filename;
1047c2fdda0dSAndy Whitcroft	}
104821caa13cSAndy Whitcroft	while (<$FILE>) {
10490a920b5bSAndy Whitcroft		chomp;
105000df344fSAndy Whitcroft		push(@rawlines, $_);
10516c72ffaaSAndy Whitcroft	}
105221caa13cSAndy Whitcroft	close($FILE);
1053d8469f16SJoe Perches
1054d8469f16SJoe Perches	if ($#ARGV > 0 && $quiet == 0) {
1055d8469f16SJoe Perches		print '-' x length($vname) . "\n";
1056d8469f16SJoe Perches		print "$vname\n";
1057d8469f16SJoe Perches		print '-' x length($vname) . "\n";
1058d8469f16SJoe Perches	}
1059d8469f16SJoe Perches
1060c2fdda0dSAndy Whitcroft	if (!process($filename)) {
10610a920b5bSAndy Whitcroft		$exit = 1;
10620a920b5bSAndy Whitcroft	}
106300df344fSAndy Whitcroft	@rawlines = ();
106413214adfSAndy Whitcroft	@lines = ();
10653705ce5bSJoe Perches	@fixed = ();
1066d752fcc8SJoe Perches	@fixed_inserted = ();
1067d752fcc8SJoe Perches	@fixed_deleted = ();
1068194f66fcSJoe Perches	$fixlinenr = -1;
1069485ff23eSAlex Dowad	@modifierListFile = ();
1070485ff23eSAlex Dowad	@typeListFile = ();
1071485ff23eSAlex Dowad	build_types();
10720a920b5bSAndy Whitcroft}
10730a920b5bSAndy Whitcroft
1074d8469f16SJoe Perchesif (!$quiet) {
10753c816e49SJoe Perches	hash_show_words(\%use_type, "Used");
10763c816e49SJoe Perches	hash_show_words(\%ignore_type, "Ignored");
10773c816e49SJoe Perches
10785b57980dSJoe Perches	if (!$perl_version_ok) {
1079d8469f16SJoe Perches		print << "EOM"
1080d8469f16SJoe Perches
1081d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues.
10825b57980dSJoe Perches      An upgrade to at least perl $minimum_perl_version is suggested.
1083d8469f16SJoe PerchesEOM
1084d8469f16SJoe Perches	}
1085d8469f16SJoe Perches	if ($exit) {
1086d8469f16SJoe Perches		print << "EOM"
1087d8469f16SJoe Perches
1088d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report
1089d8469f16SJoe Perches      them to the maintainer, see CHECKPATCH in MAINTAINERS.
1090d8469f16SJoe PerchesEOM
1091d8469f16SJoe Perches	}
1092d8469f16SJoe Perches}
1093d8469f16SJoe Perches
10940a920b5bSAndy Whitcroftexit($exit);
10950a920b5bSAndy Whitcroft
10960a920b5bSAndy Whitcroftsub top_of_kernel_tree {
10976c72ffaaSAndy Whitcroft	my ($root) = @_;
10986c72ffaaSAndy Whitcroft
10996c72ffaaSAndy Whitcroft	my @tree_check = (
11006c72ffaaSAndy Whitcroft		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
11016c72ffaaSAndy Whitcroft		"README", "Documentation", "arch", "include", "drivers",
11026c72ffaaSAndy Whitcroft		"fs", "init", "ipc", "kernel", "lib", "scripts",
11036c72ffaaSAndy Whitcroft	);
11046c72ffaaSAndy Whitcroft
11056c72ffaaSAndy Whitcroft	foreach my $check (@tree_check) {
11066c72ffaaSAndy Whitcroft		if (! -e $root . '/' . $check) {
11070a920b5bSAndy Whitcroft			return 0;
11080a920b5bSAndy Whitcroft		}
11096c72ffaaSAndy Whitcroft	}
11106c72ffaaSAndy Whitcroft	return 1;
11116c72ffaaSAndy Whitcroft}
11120a920b5bSAndy Whitcroft
111320112475SJoe Perchessub parse_email {
111420112475SJoe Perches	my ($formatted_email) = @_;
111520112475SJoe Perches
111620112475SJoe Perches	my $name = "";
111720112475SJoe Perches	my $address = "";
111820112475SJoe Perches	my $comment = "";
111920112475SJoe Perches
112020112475SJoe Perches	if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
112120112475SJoe Perches		$name = $1;
112220112475SJoe Perches		$address = $2;
112320112475SJoe Perches		$comment = $3 if defined $3;
112420112475SJoe Perches	} elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
112520112475SJoe Perches		$address = $1;
112620112475SJoe Perches		$comment = $2 if defined $2;
112720112475SJoe Perches	} elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
112820112475SJoe Perches		$address = $1;
112920112475SJoe Perches		$comment = $2 if defined $2;
113085e12066SJoe Perches		$formatted_email =~ s/\Q$address\E.*$//;
113120112475SJoe Perches		$name = $formatted_email;
11323705ce5bSJoe Perches		$name = trim($name);
113320112475SJoe Perches		$name =~ s/^\"|\"$//g;
113420112475SJoe Perches		# If there's a name left after stripping spaces and
113520112475SJoe Perches		# leading quotes, and the address doesn't have both
113620112475SJoe Perches		# leading and trailing angle brackets, the address
113720112475SJoe Perches		# is invalid. ie:
113820112475SJoe Perches		#   "joe smith [email protected]" bad
113920112475SJoe Perches		#   "joe smith <[email protected]" bad
114020112475SJoe Perches		if ($name ne "" && $address !~ /^<[^>]+>$/) {
114120112475SJoe Perches			$name = "";
114220112475SJoe Perches			$address = "";
114320112475SJoe Perches			$comment = "";
114420112475SJoe Perches		}
114520112475SJoe Perches	}
114620112475SJoe Perches
11473705ce5bSJoe Perches	$name = trim($name);
114820112475SJoe Perches	$name =~ s/^\"|\"$//g;
11493705ce5bSJoe Perches	$address = trim($address);
115020112475SJoe Perches	$address =~ s/^\<|\>$//g;
115120112475SJoe Perches
115220112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
115320112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
115420112475SJoe Perches		$name = "\"$name\"";
115520112475SJoe Perches	}
115620112475SJoe Perches
115720112475SJoe Perches	return ($name, $address, $comment);
115820112475SJoe Perches}
115920112475SJoe Perches
116020112475SJoe Perchessub format_email {
116120112475SJoe Perches	my ($name, $address) = @_;
116220112475SJoe Perches
116320112475SJoe Perches	my $formatted_email;
116420112475SJoe Perches
11653705ce5bSJoe Perches	$name = trim($name);
116620112475SJoe Perches	$name =~ s/^\"|\"$//g;
11673705ce5bSJoe Perches	$address = trim($address);
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
117420112475SJoe Perches	if ("$name" eq "") {
117520112475SJoe Perches		$formatted_email = "$address";
117620112475SJoe Perches	} else {
117720112475SJoe Perches		$formatted_email = "$name <$address>";
117820112475SJoe Perches	}
117920112475SJoe Perches
118020112475SJoe Perches	return $formatted_email;
118120112475SJoe Perches}
118220112475SJoe Perches
1183d311cd44SJoe Perchessub which {
1184d311cd44SJoe Perches	my ($bin) = @_;
1185d311cd44SJoe Perches
1186d311cd44SJoe Perches	foreach my $path (split(/:/, $ENV{PATH})) {
1187d311cd44SJoe Perches		if (-e "$path/$bin") {
1188d311cd44SJoe Perches			return "$path/$bin";
1189d311cd44SJoe Perches		}
1190d311cd44SJoe Perches	}
1191d311cd44SJoe Perches
1192d311cd44SJoe Perches	return "";
1193d311cd44SJoe Perches}
1194d311cd44SJoe Perches
1195000d1cc1SJoe Perchessub which_conf {
1196000d1cc1SJoe Perches	my ($conf) = @_;
1197000d1cc1SJoe Perches
1198000d1cc1SJoe Perches	foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
1199000d1cc1SJoe Perches		if (-e "$path/$conf") {
1200000d1cc1SJoe Perches			return "$path/$conf";
1201000d1cc1SJoe Perches		}
1202000d1cc1SJoe Perches	}
1203000d1cc1SJoe Perches
1204000d1cc1SJoe Perches	return "";
1205000d1cc1SJoe Perches}
1206000d1cc1SJoe Perches
12070a920b5bSAndy Whitcroftsub expand_tabs {
12080a920b5bSAndy Whitcroft	my ($str) = @_;
12090a920b5bSAndy Whitcroft
12100a920b5bSAndy Whitcroft	my $res = '';
12110a920b5bSAndy Whitcroft	my $n = 0;
12120a920b5bSAndy Whitcroft	for my $c (split(//, $str)) {
12130a920b5bSAndy Whitcroft		if ($c eq "\t") {
12140a920b5bSAndy Whitcroft			$res .= ' ';
12150a920b5bSAndy Whitcroft			$n++;
12160a920b5bSAndy Whitcroft			for (; ($n % 8) != 0; $n++) {
12170a920b5bSAndy Whitcroft				$res .= ' ';
12180a920b5bSAndy Whitcroft			}
12190a920b5bSAndy Whitcroft			next;
12200a920b5bSAndy Whitcroft		}
12210a920b5bSAndy Whitcroft		$res .= $c;
12220a920b5bSAndy Whitcroft		$n++;
12230a920b5bSAndy Whitcroft	}
12240a920b5bSAndy Whitcroft
12250a920b5bSAndy Whitcroft	return $res;
12260a920b5bSAndy Whitcroft}
12276c72ffaaSAndy Whitcroftsub copy_spacing {
1228773647a0SAndy Whitcroft	(my $res = shift) =~ tr/\t/ /c;
12296c72ffaaSAndy Whitcroft	return $res;
12306c72ffaaSAndy Whitcroft}
12310a920b5bSAndy Whitcroft
12324a0df2efSAndy Whitcroftsub line_stats {
12334a0df2efSAndy Whitcroft	my ($line) = @_;
12344a0df2efSAndy Whitcroft
12354a0df2efSAndy Whitcroft	# Drop the diff line leader and expand tabs
12364a0df2efSAndy Whitcroft	$line =~ s/^.//;
12374a0df2efSAndy Whitcroft	$line = expand_tabs($line);
12384a0df2efSAndy Whitcroft
12394a0df2efSAndy Whitcroft	# Pick the indent from the front of the line.
12404a0df2efSAndy Whitcroft	my ($white) = ($line =~ /^(\s*)/);
12414a0df2efSAndy Whitcroft
12424a0df2efSAndy Whitcroft	return (length($line), length($white));
12434a0df2efSAndy Whitcroft}
12444a0df2efSAndy Whitcroft
1245773647a0SAndy Whitcroftmy $sanitise_quote = '';
1246773647a0SAndy Whitcroft
1247773647a0SAndy Whitcroftsub sanitise_line_reset {
1248773647a0SAndy Whitcroft	my ($in_comment) = @_;
1249773647a0SAndy Whitcroft
1250773647a0SAndy Whitcroft	if ($in_comment) {
1251773647a0SAndy Whitcroft		$sanitise_quote = '*/';
1252773647a0SAndy Whitcroft	} else {
1253773647a0SAndy Whitcroft		$sanitise_quote = '';
1254773647a0SAndy Whitcroft	}
1255773647a0SAndy Whitcroft}
125600df344fSAndy Whitcroftsub sanitise_line {
125700df344fSAndy Whitcroft	my ($line) = @_;
125800df344fSAndy Whitcroft
125900df344fSAndy Whitcroft	my $res = '';
126000df344fSAndy Whitcroft	my $l = '';
126100df344fSAndy Whitcroft
1262c2fdda0dSAndy Whitcroft	my $qlen = 0;
1263773647a0SAndy Whitcroft	my $off = 0;
1264773647a0SAndy Whitcroft	my $c;
126500df344fSAndy Whitcroft
1266773647a0SAndy Whitcroft	# Always copy over the diff marker.
1267773647a0SAndy Whitcroft	$res = substr($line, 0, 1);
1268773647a0SAndy Whitcroft
1269773647a0SAndy Whitcroft	for ($off = 1; $off < length($line); $off++) {
1270773647a0SAndy Whitcroft		$c = substr($line, $off, 1);
1271773647a0SAndy Whitcroft
12728d2e11b2SClaudio Fontana		# Comments we are whacking completely including the begin
1273773647a0SAndy Whitcroft		# and end, all to $;.
1274773647a0SAndy Whitcroft		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
1275773647a0SAndy Whitcroft			$sanitise_quote = '*/';
1276773647a0SAndy Whitcroft
1277773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1278773647a0SAndy Whitcroft			$off++;
127900df344fSAndy Whitcroft			next;
1280773647a0SAndy Whitcroft		}
128181bc0e02SAndy Whitcroft		if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
1282773647a0SAndy Whitcroft			$sanitise_quote = '';
1283773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1284773647a0SAndy Whitcroft			$off++;
1285773647a0SAndy Whitcroft			next;
1286773647a0SAndy Whitcroft		}
1287113f04a8SDaniel Walker		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
1288113f04a8SDaniel Walker			$sanitise_quote = '//';
1289113f04a8SDaniel Walker
1290113f04a8SDaniel Walker			substr($res, $off, 2, $sanitise_quote);
1291113f04a8SDaniel Walker			$off++;
1292113f04a8SDaniel Walker			next;
1293113f04a8SDaniel Walker		}
1294773647a0SAndy Whitcroft
1295773647a0SAndy Whitcroft		# A \ in a string means ignore the next character.
1296773647a0SAndy Whitcroft		if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
1297773647a0SAndy Whitcroft		    $c eq "\\") {
1298773647a0SAndy Whitcroft			substr($res, $off, 2, 'XX');
1299773647a0SAndy Whitcroft			$off++;
1300773647a0SAndy Whitcroft			next;
1301773647a0SAndy Whitcroft		}
1302773647a0SAndy Whitcroft		# Regular quotes.
1303773647a0SAndy Whitcroft		if ($c eq "'" || $c eq '"') {
1304773647a0SAndy Whitcroft			if ($sanitise_quote eq '') {
1305773647a0SAndy Whitcroft				$sanitise_quote = $c;
1306773647a0SAndy Whitcroft
1307773647a0SAndy Whitcroft				substr($res, $off, 1, $c);
1308773647a0SAndy Whitcroft				next;
1309773647a0SAndy Whitcroft			} elsif ($sanitise_quote eq $c) {
1310773647a0SAndy Whitcroft				$sanitise_quote = '';
131100df344fSAndy Whitcroft			}
131200df344fSAndy Whitcroft		}
1313773647a0SAndy Whitcroft
1314fae17daeSAndy Whitcroft		#print "c<$c> SQ<$sanitise_quote>\n";
1315773647a0SAndy Whitcroft		if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
1316773647a0SAndy Whitcroft			substr($res, $off, 1, $;);
1317113f04a8SDaniel Walker		} elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
1318113f04a8SDaniel Walker			substr($res, $off, 1, $;);
1319773647a0SAndy Whitcroft		} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
1320773647a0SAndy Whitcroft			substr($res, $off, 1, 'X');
132100df344fSAndy Whitcroft		} else {
1322773647a0SAndy Whitcroft			substr($res, $off, 1, $c);
132300df344fSAndy Whitcroft		}
1324c2fdda0dSAndy Whitcroft	}
1325c2fdda0dSAndy Whitcroft
1326113f04a8SDaniel Walker	if ($sanitise_quote eq '//') {
1327113f04a8SDaniel Walker		$sanitise_quote = '';
1328113f04a8SDaniel Walker	}
1329113f04a8SDaniel Walker
1330c2fdda0dSAndy Whitcroft	# The pathname on a #include may be surrounded by '<' and '>'.
1331c45dcabdSAndy Whitcroft	if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
1332c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1333c2fdda0dSAndy Whitcroft		$res =~ s@\<.*\>@<$clean>@;
1334c2fdda0dSAndy Whitcroft
1335c2fdda0dSAndy Whitcroft	# The whole of a #error is a string.
1336c45dcabdSAndy Whitcroft	} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
1337c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1338c45dcabdSAndy Whitcroft		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
1339c2fdda0dSAndy Whitcroft	}
1340c2fdda0dSAndy Whitcroft
1341dadf680dSJoe Perches	if ($allow_c99_comments && $res =~ m@(//.*$)@) {
1342dadf680dSJoe Perches		my $match = $1;
1343dadf680dSJoe Perches		$res =~ s/\Q$match\E/"$;" x length($match)/e;
1344dadf680dSJoe Perches	}
1345dadf680dSJoe Perches
134600df344fSAndy Whitcroft	return $res;
134700df344fSAndy Whitcroft}
134800df344fSAndy Whitcroft
1349a6962d72SJoe Perchessub get_quoted_string {
1350a6962d72SJoe Perches	my ($line, $rawline) = @_;
1351a6962d72SJoe Perches
1352478b1799SJoe Perches	return "" if (!defined($line) || !defined($rawline));
135333acb54aSJoe Perches	return "" if ($line !~ m/($String)/g);
1354a6962d72SJoe Perches	return substr($rawline, $-[0], $+[0] - $-[0]);
1355a6962d72SJoe Perches}
1356a6962d72SJoe Perches
13578905a67cSAndy Whitcroftsub ctx_statement_block {
13588905a67cSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
13598905a67cSAndy Whitcroft	my $line = $linenr - 1;
13608905a67cSAndy Whitcroft	my $blk = '';
13618905a67cSAndy Whitcroft	my $soff = $off;
13628905a67cSAndy Whitcroft	my $coff = $off - 1;
1363773647a0SAndy Whitcroft	my $coff_set = 0;
13648905a67cSAndy Whitcroft
136513214adfSAndy Whitcroft	my $loff = 0;
136613214adfSAndy Whitcroft
13678905a67cSAndy Whitcroft	my $type = '';
13688905a67cSAndy Whitcroft	my $level = 0;
1369a2750645SAndy Whitcroft	my @stack = ();
1370cf655043SAndy Whitcroft	my $p;
13718905a67cSAndy Whitcroft	my $c;
13728905a67cSAndy Whitcroft	my $len = 0;
137313214adfSAndy Whitcroft
137413214adfSAndy Whitcroft	my $remainder;
13758905a67cSAndy Whitcroft	while (1) {
1376a2750645SAndy Whitcroft		@stack = (['', 0]) if ($#stack == -1);
1377a2750645SAndy Whitcroft
1378773647a0SAndy Whitcroft		#warn "CSB: blk<$blk> remain<$remain>\n";
13798905a67cSAndy Whitcroft		# If we are about to drop off the end, pull in more
13808905a67cSAndy Whitcroft		# context.
13818905a67cSAndy Whitcroft		if ($off >= $len) {
13828905a67cSAndy Whitcroft			for (; $remain > 0; $line++) {
1383dea33496SAndy Whitcroft				last if (!defined $lines[$line]);
1384c2fdda0dSAndy Whitcroft				next if ($lines[$line] =~ /^-/);
13858905a67cSAndy Whitcroft				$remain--;
138613214adfSAndy Whitcroft				$loff = $len;
1387c2fdda0dSAndy Whitcroft				$blk .= $lines[$line] . "\n";
13888905a67cSAndy Whitcroft				$len = length($blk);
13898905a67cSAndy Whitcroft				$line++;
13908905a67cSAndy Whitcroft				last;
13918905a67cSAndy Whitcroft			}
13928905a67cSAndy Whitcroft			# Bail if there is no further context.
13938905a67cSAndy Whitcroft			#warn "CSB: blk<$blk> off<$off> len<$len>\n";
139413214adfSAndy Whitcroft			if ($off >= $len) {
13958905a67cSAndy Whitcroft				last;
13968905a67cSAndy Whitcroft			}
1397f74bd194SAndy Whitcroft			if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
1398f74bd194SAndy Whitcroft				$level++;
1399f74bd194SAndy Whitcroft				$type = '#';
1400f74bd194SAndy Whitcroft			}
14018905a67cSAndy Whitcroft		}
1402cf655043SAndy Whitcroft		$p = $c;
14038905a67cSAndy Whitcroft		$c = substr($blk, $off, 1);
140413214adfSAndy Whitcroft		$remainder = substr($blk, $off);
14058905a67cSAndy Whitcroft
1406773647a0SAndy Whitcroft		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
14074635f4fbSAndy Whitcroft
14084635f4fbSAndy Whitcroft		# Handle nested #if/#else.
14094635f4fbSAndy Whitcroft		if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
14104635f4fbSAndy Whitcroft			push(@stack, [ $type, $level ]);
14114635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
14124635f4fbSAndy Whitcroft			($type, $level) = @{$stack[$#stack - 1]};
14134635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*endif\b/) {
14144635f4fbSAndy Whitcroft			($type, $level) = @{pop(@stack)};
14154635f4fbSAndy Whitcroft		}
14164635f4fbSAndy Whitcroft
14178905a67cSAndy Whitcroft		# Statement ends at the ';' or a close '}' at the
14188905a67cSAndy Whitcroft		# outermost level.
14198905a67cSAndy Whitcroft		if ($level == 0 && $c eq ';') {
14208905a67cSAndy Whitcroft			last;
14218905a67cSAndy Whitcroft		}
14228905a67cSAndy Whitcroft
142313214adfSAndy Whitcroft		# An else is really a conditional as long as its not else if
1424773647a0SAndy Whitcroft		if ($level == 0 && $coff_set == 0 &&
1425773647a0SAndy Whitcroft				(!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
1426773647a0SAndy Whitcroft				$remainder =~ /^(else)(?:\s|{)/ &&
1427773647a0SAndy Whitcroft				$remainder !~ /^else\s+if\b/) {
1428773647a0SAndy Whitcroft			$coff = $off + length($1) - 1;
1429773647a0SAndy Whitcroft			$coff_set = 1;
1430773647a0SAndy Whitcroft			#warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
1431773647a0SAndy Whitcroft			#warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
143213214adfSAndy Whitcroft		}
143313214adfSAndy Whitcroft
14348905a67cSAndy Whitcroft		if (($type eq '' || $type eq '(') && $c eq '(') {
14358905a67cSAndy Whitcroft			$level++;
14368905a67cSAndy Whitcroft			$type = '(';
14378905a67cSAndy Whitcroft		}
14388905a67cSAndy Whitcroft		if ($type eq '(' && $c eq ')') {
14398905a67cSAndy Whitcroft			$level--;
14408905a67cSAndy Whitcroft			$type = ($level != 0)? '(' : '';
14418905a67cSAndy Whitcroft
14428905a67cSAndy Whitcroft			if ($level == 0 && $coff < $soff) {
14438905a67cSAndy Whitcroft				$coff = $off;
1444773647a0SAndy Whitcroft				$coff_set = 1;
1445773647a0SAndy Whitcroft				#warn "CSB: mark coff<$coff>\n";
14468905a67cSAndy Whitcroft			}
14478905a67cSAndy Whitcroft		}
14488905a67cSAndy Whitcroft		if (($type eq '' || $type eq '{') && $c eq '{') {
14498905a67cSAndy Whitcroft			$level++;
14508905a67cSAndy Whitcroft			$type = '{';
14518905a67cSAndy Whitcroft		}
14528905a67cSAndy Whitcroft		if ($type eq '{' && $c eq '}') {
14538905a67cSAndy Whitcroft			$level--;
14548905a67cSAndy Whitcroft			$type = ($level != 0)? '{' : '';
14558905a67cSAndy Whitcroft
14568905a67cSAndy Whitcroft			if ($level == 0) {
1457b998e001SPatrick Pannuto				if (substr($blk, $off + 1, 1) eq ';') {
1458b998e001SPatrick Pannuto					$off++;
1459b998e001SPatrick Pannuto				}
14608905a67cSAndy Whitcroft				last;
14618905a67cSAndy Whitcroft			}
14628905a67cSAndy Whitcroft		}
1463f74bd194SAndy Whitcroft		# Preprocessor commands end at the newline unless escaped.
1464f74bd194SAndy Whitcroft		if ($type eq '#' && $c eq "\n" && $p ne "\\") {
1465f74bd194SAndy Whitcroft			$level--;
1466f74bd194SAndy Whitcroft			$type = '';
1467f74bd194SAndy Whitcroft			$off++;
1468f74bd194SAndy Whitcroft			last;
1469f74bd194SAndy Whitcroft		}
14708905a67cSAndy Whitcroft		$off++;
14718905a67cSAndy Whitcroft	}
1472a3bb97a7SAndy Whitcroft	# We are truly at the end, so shuffle to the next line.
147313214adfSAndy Whitcroft	if ($off == $len) {
1474a3bb97a7SAndy Whitcroft		$loff = $len + 1;
147513214adfSAndy Whitcroft		$line++;
147613214adfSAndy Whitcroft		$remain--;
147713214adfSAndy Whitcroft	}
14788905a67cSAndy Whitcroft
14798905a67cSAndy Whitcroft	my $statement = substr($blk, $soff, $off - $soff + 1);
14808905a67cSAndy Whitcroft	my $condition = substr($blk, $soff, $coff - $soff + 1);
14818905a67cSAndy Whitcroft
14828905a67cSAndy Whitcroft	#warn "STATEMENT<$statement>\n";
14838905a67cSAndy Whitcroft	#warn "CONDITION<$condition>\n";
14848905a67cSAndy Whitcroft
1485773647a0SAndy Whitcroft	#print "coff<$coff> soff<$off> loff<$loff>\n";
148613214adfSAndy Whitcroft
148713214adfSAndy Whitcroft	return ($statement, $condition,
148813214adfSAndy Whitcroft			$line, $remain + 1, $off - $loff + 1, $level);
148913214adfSAndy Whitcroft}
149013214adfSAndy Whitcroft
1491cf655043SAndy Whitcroftsub statement_lines {
1492cf655043SAndy Whitcroft	my ($stmt) = @_;
1493cf655043SAndy Whitcroft
1494cf655043SAndy Whitcroft	# Strip the diff line prefixes and rip blank lines at start and end.
1495cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1496cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1497cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1498cf655043SAndy Whitcroft
1499cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1500cf655043SAndy Whitcroft
1501cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1502cf655043SAndy Whitcroft}
1503cf655043SAndy Whitcroft
1504cf655043SAndy Whitcroftsub statement_rawlines {
1505cf655043SAndy Whitcroft	my ($stmt) = @_;
1506cf655043SAndy Whitcroft
1507cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1508cf655043SAndy Whitcroft
1509cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1510cf655043SAndy Whitcroft}
1511cf655043SAndy Whitcroft
1512cf655043SAndy Whitcroftsub statement_block_size {
1513cf655043SAndy Whitcroft	my ($stmt) = @_;
1514cf655043SAndy Whitcroft
1515cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1516cf655043SAndy Whitcroft	$stmt =~ s/^\s*{//;
1517cf655043SAndy Whitcroft	$stmt =~ s/}\s*$//;
1518cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1519cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1520cf655043SAndy Whitcroft
1521cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1522cf655043SAndy Whitcroft	my @stmt_statements = ($stmt =~ /;/g);
1523cf655043SAndy Whitcroft
1524cf655043SAndy Whitcroft	my $stmt_lines = $#stmt_lines + 2;
1525cf655043SAndy Whitcroft	my $stmt_statements = $#stmt_statements + 1;
1526cf655043SAndy Whitcroft
1527cf655043SAndy Whitcroft	if ($stmt_lines > $stmt_statements) {
1528cf655043SAndy Whitcroft		return $stmt_lines;
1529cf655043SAndy Whitcroft	} else {
1530cf655043SAndy Whitcroft		return $stmt_statements;
1531cf655043SAndy Whitcroft	}
1532cf655043SAndy Whitcroft}
1533cf655043SAndy Whitcroft
153413214adfSAndy Whitcroftsub ctx_statement_full {
153513214adfSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
153613214adfSAndy Whitcroft	my ($statement, $condition, $level);
153713214adfSAndy Whitcroft
153813214adfSAndy Whitcroft	my (@chunks);
153913214adfSAndy Whitcroft
1540cf655043SAndy Whitcroft	# Grab the first conditional/block pair.
154113214adfSAndy Whitcroft	($statement, $condition, $linenr, $remain, $off, $level) =
154213214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1543773647a0SAndy Whitcroft	#print "F: c<$condition> s<$statement> remain<$remain>\n";
154413214adfSAndy Whitcroft	push(@chunks, [ $condition, $statement ]);
1545cf655043SAndy Whitcroft	if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1546cf655043SAndy Whitcroft		return ($level, $linenr, @chunks);
1547cf655043SAndy Whitcroft	}
1548cf655043SAndy Whitcroft
1549cf655043SAndy Whitcroft	# Pull in the following conditional/block pairs and see if they
1550cf655043SAndy Whitcroft	# could continue the statement.
1551cf655043SAndy Whitcroft	for (;;) {
155213214adfSAndy Whitcroft		($statement, $condition, $linenr, $remain, $off, $level) =
155313214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1554cf655043SAndy Whitcroft		#print "C: c<$condition> s<$statement> remain<$remain>\n";
1555773647a0SAndy Whitcroft		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1556cf655043SAndy Whitcroft		#print "C: push\n";
1557cf655043SAndy Whitcroft		push(@chunks, [ $condition, $statement ]);
155813214adfSAndy Whitcroft	}
155913214adfSAndy Whitcroft
156013214adfSAndy Whitcroft	return ($level, $linenr, @chunks);
15618905a67cSAndy Whitcroft}
15628905a67cSAndy Whitcroft
15634a0df2efSAndy Whitcroftsub ctx_block_get {
1564f0a594c1SAndy Whitcroft	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
15654a0df2efSAndy Whitcroft	my $line;
15664a0df2efSAndy Whitcroft	my $start = $linenr - 1;
15674a0df2efSAndy Whitcroft	my $blk = '';
15684a0df2efSAndy Whitcroft	my @o;
15694a0df2efSAndy Whitcroft	my @c;
15704a0df2efSAndy Whitcroft	my @res = ();
15714a0df2efSAndy Whitcroft
1572f0a594c1SAndy Whitcroft	my $level = 0;
15734635f4fbSAndy Whitcroft	my @stack = ($level);
157400df344fSAndy Whitcroft	for ($line = $start; $remain > 0; $line++) {
157500df344fSAndy Whitcroft		next if ($rawlines[$line] =~ /^-/);
157600df344fSAndy Whitcroft		$remain--;
157700df344fSAndy Whitcroft
157800df344fSAndy Whitcroft		$blk .= $rawlines[$line];
15794635f4fbSAndy Whitcroft
15804635f4fbSAndy Whitcroft		# Handle nested #if/#else.
158101464f30SAndy Whitcroft		if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
15824635f4fbSAndy Whitcroft			push(@stack, $level);
158301464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
15844635f4fbSAndy Whitcroft			$level = $stack[$#stack - 1];
158501464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
15864635f4fbSAndy Whitcroft			$level = pop(@stack);
15874635f4fbSAndy Whitcroft		}
15884635f4fbSAndy Whitcroft
158901464f30SAndy Whitcroft		foreach my $c (split(//, $lines[$line])) {
1590f0a594c1SAndy Whitcroft			##print "C<$c>L<$level><$open$close>O<$off>\n";
1591f0a594c1SAndy Whitcroft			if ($off > 0) {
1592f0a594c1SAndy Whitcroft				$off--;
1593f0a594c1SAndy Whitcroft				next;
1594f0a594c1SAndy Whitcroft			}
15954a0df2efSAndy Whitcroft
1596f0a594c1SAndy Whitcroft			if ($c eq $close && $level > 0) {
1597f0a594c1SAndy Whitcroft				$level--;
1598f0a594c1SAndy Whitcroft				last if ($level == 0);
1599f0a594c1SAndy Whitcroft			} elsif ($c eq $open) {
1600f0a594c1SAndy Whitcroft				$level++;
1601f0a594c1SAndy Whitcroft			}
1602f0a594c1SAndy Whitcroft		}
16034a0df2efSAndy Whitcroft
1604f0a594c1SAndy Whitcroft		if (!$outer || $level <= 1) {
160500df344fSAndy Whitcroft			push(@res, $rawlines[$line]);
16064a0df2efSAndy Whitcroft		}
16074a0df2efSAndy Whitcroft
1608f0a594c1SAndy Whitcroft		last if ($level == 0);
16094a0df2efSAndy Whitcroft	}
16104a0df2efSAndy Whitcroft
1611f0a594c1SAndy Whitcroft	return ($level, @res);
16124a0df2efSAndy Whitcroft}
16134a0df2efSAndy Whitcroftsub ctx_block_outer {
16144a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
16154a0df2efSAndy Whitcroft
1616f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1617f0a594c1SAndy Whitcroft	return @r;
16184a0df2efSAndy Whitcroft}
16194a0df2efSAndy Whitcroftsub ctx_block {
16204a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
16214a0df2efSAndy Whitcroft
1622f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1623f0a594c1SAndy Whitcroft	return @r;
1624653d4876SAndy Whitcroft}
1625653d4876SAndy Whitcroftsub ctx_statement {
1626f0a594c1SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
1627f0a594c1SAndy Whitcroft
1628f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1629f0a594c1SAndy Whitcroft	return @r;
1630f0a594c1SAndy Whitcroft}
1631f0a594c1SAndy Whitcroftsub ctx_block_level {
1632653d4876SAndy Whitcroft	my ($linenr, $remain) = @_;
1633653d4876SAndy Whitcroft
1634f0a594c1SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
16354a0df2efSAndy Whitcroft}
16369c0ca6f9SAndy Whitcroftsub ctx_statement_level {
16379c0ca6f9SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
16389c0ca6f9SAndy Whitcroft
16399c0ca6f9SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
16409c0ca6f9SAndy Whitcroft}
16414a0df2efSAndy Whitcroft
16424a0df2efSAndy Whitcroftsub ctx_locate_comment {
16434a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
16444a0df2efSAndy Whitcroft
16454a0df2efSAndy Whitcroft	# Catch a comment on the end of the line itself.
1646beae6332SAndy Whitcroft	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
16474a0df2efSAndy Whitcroft	return $current_comment if (defined $current_comment);
16484a0df2efSAndy Whitcroft
16494a0df2efSAndy Whitcroft	# Look through the context and try and figure out if there is a
16504a0df2efSAndy Whitcroft	# comment.
16514a0df2efSAndy Whitcroft	my $in_comment = 0;
16524a0df2efSAndy Whitcroft	$current_comment = '';
16534a0df2efSAndy Whitcroft	for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
165400df344fSAndy Whitcroft		my $line = $rawlines[$linenr - 1];
165500df344fSAndy Whitcroft		#warn "           $line\n";
16564a0df2efSAndy Whitcroft		if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
16574a0df2efSAndy Whitcroft			$in_comment = 1;
16584a0df2efSAndy Whitcroft		}
16594a0df2efSAndy Whitcroft		if ($line =~ m@/\*@) {
16604a0df2efSAndy Whitcroft			$in_comment = 1;
16614a0df2efSAndy Whitcroft		}
16624a0df2efSAndy Whitcroft		if (!$in_comment && $current_comment ne '') {
16634a0df2efSAndy Whitcroft			$current_comment = '';
16644a0df2efSAndy Whitcroft		}
16654a0df2efSAndy Whitcroft		$current_comment .= $line . "\n" if ($in_comment);
16664a0df2efSAndy Whitcroft		if ($line =~ m@\*/@) {
16674a0df2efSAndy Whitcroft			$in_comment = 0;
16684a0df2efSAndy Whitcroft		}
16694a0df2efSAndy Whitcroft	}
16704a0df2efSAndy Whitcroft
16714a0df2efSAndy Whitcroft	chomp($current_comment);
16724a0df2efSAndy Whitcroft	return($current_comment);
16734a0df2efSAndy Whitcroft}
16744a0df2efSAndy Whitcroftsub ctx_has_comment {
16754a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
16764a0df2efSAndy Whitcroft	my $cmt = ctx_locate_comment($first_line, $end_line);
16774a0df2efSAndy Whitcroft
167800df344fSAndy Whitcroft	##print "LINE: $rawlines[$end_line - 1 ]\n";
16794a0df2efSAndy Whitcroft	##print "CMMT: $cmt\n";
16804a0df2efSAndy Whitcroft
16814a0df2efSAndy Whitcroft	return ($cmt ne '');
16824a0df2efSAndy Whitcroft}
16834a0df2efSAndy Whitcroft
16844d001e4dSAndy Whitcroftsub raw_line {
16854d001e4dSAndy Whitcroft	my ($linenr, $cnt) = @_;
16864d001e4dSAndy Whitcroft
16874d001e4dSAndy Whitcroft	my $offset = $linenr - 1;
16884d001e4dSAndy Whitcroft	$cnt++;
16894d001e4dSAndy Whitcroft
16904d001e4dSAndy Whitcroft	my $line;
16914d001e4dSAndy Whitcroft	while ($cnt) {
16924d001e4dSAndy Whitcroft		$line = $rawlines[$offset++];
16934d001e4dSAndy Whitcroft		next if (defined($line) && $line =~ /^-/);
16944d001e4dSAndy Whitcroft		$cnt--;
16954d001e4dSAndy Whitcroft	}
16964d001e4dSAndy Whitcroft
16974d001e4dSAndy Whitcroft	return $line;
16984d001e4dSAndy Whitcroft}
16994d001e4dSAndy Whitcroft
17002a9f9d85STobin C. Hardingsub get_stat_real {
17012a9f9d85STobin C. Harding	my ($linenr, $lc) = @_;
17022a9f9d85STobin C. Harding
17032a9f9d85STobin C. Harding	my $stat_real = raw_line($linenr, 0);
17042a9f9d85STobin C. Harding	for (my $count = $linenr + 1; $count <= $lc; $count++) {
17052a9f9d85STobin C. Harding		$stat_real = $stat_real . "\n" . raw_line($count, 0);
17062a9f9d85STobin C. Harding	}
17072a9f9d85STobin C. Harding
17082a9f9d85STobin C. Harding	return $stat_real;
17092a9f9d85STobin C. Harding}
17102a9f9d85STobin C. Harding
1711e3d95a2aSTobin C. Hardingsub get_stat_here {
1712e3d95a2aSTobin C. Harding	my ($linenr, $cnt, $here) = @_;
1713e3d95a2aSTobin C. Harding
1714e3d95a2aSTobin C. Harding	my $herectx = $here . "\n";
1715e3d95a2aSTobin C. Harding	for (my $n = 0; $n < $cnt; $n++) {
1716e3d95a2aSTobin C. Harding		$herectx .= raw_line($linenr, $n) . "\n";
1717e3d95a2aSTobin C. Harding	}
1718e3d95a2aSTobin C. Harding
1719e3d95a2aSTobin C. Harding	return $herectx;
1720e3d95a2aSTobin C. Harding}
1721e3d95a2aSTobin C. Harding
17220a920b5bSAndy Whitcroftsub cat_vet {
17230a920b5bSAndy Whitcroft	my ($vet) = @_;
17249c0ca6f9SAndy Whitcroft	my ($res, $coded);
17250a920b5bSAndy Whitcroft
17269c0ca6f9SAndy Whitcroft	$res = '';
17276c72ffaaSAndy Whitcroft	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
17286c72ffaaSAndy Whitcroft		$res .= $1;
17296c72ffaaSAndy Whitcroft		if ($2 ne '') {
17309c0ca6f9SAndy Whitcroft			$coded = sprintf("^%c", unpack('C', $2) + 64);
17316c72ffaaSAndy Whitcroft			$res .= $coded;
17326c72ffaaSAndy Whitcroft		}
17339c0ca6f9SAndy Whitcroft	}
17349c0ca6f9SAndy Whitcroft	$res =~ s/$/\$/;
17350a920b5bSAndy Whitcroft
17369c0ca6f9SAndy Whitcroft	return $res;
17370a920b5bSAndy Whitcroft}
17380a920b5bSAndy Whitcroft
1739c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0;
1740cf655043SAndy Whitcroftmy $av_pending;
1741c2fdda0dSAndy Whitcroftmy @av_paren_type;
17421f65f947SAndy Whitcroftmy $av_pend_colon;
1743c2fdda0dSAndy Whitcroft
1744c2fdda0dSAndy Whitcroftsub annotate_reset {
1745c2fdda0dSAndy Whitcroft	$av_preprocessor = 0;
1746cf655043SAndy Whitcroft	$av_pending = '_';
1747cf655043SAndy Whitcroft	@av_paren_type = ('E');
17481f65f947SAndy Whitcroft	$av_pend_colon = 'O';
1749c2fdda0dSAndy Whitcroft}
1750c2fdda0dSAndy Whitcroft
17516c72ffaaSAndy Whitcroftsub annotate_values {
17526c72ffaaSAndy Whitcroft	my ($stream, $type) = @_;
17536c72ffaaSAndy Whitcroft
17546c72ffaaSAndy Whitcroft	my $res;
17551f65f947SAndy Whitcroft	my $var = '_' x length($stream);
17566c72ffaaSAndy Whitcroft	my $cur = $stream;
17576c72ffaaSAndy Whitcroft
1758c2fdda0dSAndy Whitcroft	print "$stream\n" if ($dbg_values > 1);
17596c72ffaaSAndy Whitcroft
17606c72ffaaSAndy Whitcroft	while (length($cur)) {
1761773647a0SAndy Whitcroft		@av_paren_type = ('E') if ($#av_paren_type < 0);
1762cf655043SAndy Whitcroft		print " <" . join('', @av_paren_type) .
1763171ae1a4SAndy Whitcroft				"> <$type> <$av_pending>" if ($dbg_values > 1);
17646c72ffaaSAndy Whitcroft		if ($cur =~ /^(\s+)/o) {
1765c2fdda0dSAndy Whitcroft			print "WS($1)\n" if ($dbg_values > 1);
1766c2fdda0dSAndy Whitcroft			if ($1 =~ /\n/ && $av_preprocessor) {
1767cf655043SAndy Whitcroft				$type = pop(@av_paren_type);
1768c2fdda0dSAndy Whitcroft				$av_preprocessor = 0;
17696c72ffaaSAndy Whitcroft			}
17706c72ffaaSAndy Whitcroft
1771c023e473SFlorian Mickler		} elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
17729446ef56SAndy Whitcroft			print "CAST($1)\n" if ($dbg_values > 1);
17739446ef56SAndy Whitcroft			push(@av_paren_type, $type);
1774addcdceaSAndy Whitcroft			$type = 'c';
17759446ef56SAndy Whitcroft
1776e91b6e26SAndy Whitcroft		} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
1777c2fdda0dSAndy Whitcroft			print "DECLARE($1)\n" if ($dbg_values > 1);
17786c72ffaaSAndy Whitcroft			$type = 'T';
17796c72ffaaSAndy Whitcroft
1780389a2fe5SAndy Whitcroft		} elsif ($cur =~ /^($Modifier)\s*/) {
1781389a2fe5SAndy Whitcroft			print "MODIFIER($1)\n" if ($dbg_values > 1);
1782389a2fe5SAndy Whitcroft			$type = 'T';
1783389a2fe5SAndy Whitcroft
1784c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
1785171ae1a4SAndy Whitcroft			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
1786c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1787171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
1788171ae1a4SAndy Whitcroft			if ($2 ne '') {
1789cf655043SAndy Whitcroft				$av_pending = 'N';
1790171ae1a4SAndy Whitcroft			}
1791171ae1a4SAndy Whitcroft			$type = 'E';
1792171ae1a4SAndy Whitcroft
1793c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
1794171ae1a4SAndy Whitcroft			print "UNDEF($1)\n" if ($dbg_values > 1);
1795171ae1a4SAndy Whitcroft			$av_preprocessor = 1;
1796171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
17976c72ffaaSAndy Whitcroft
1798c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
1799cf655043SAndy Whitcroft			print "PRE_START($1)\n" if ($dbg_values > 1);
1800c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1801cf655043SAndy Whitcroft
1802cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1803cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1804171ae1a4SAndy Whitcroft			$type = 'E';
1805cf655043SAndy Whitcroft
1806c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
1807cf655043SAndy Whitcroft			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
1808cf655043SAndy Whitcroft			$av_preprocessor = 1;
1809cf655043SAndy Whitcroft
1810cf655043SAndy Whitcroft			push(@av_paren_type, $av_paren_type[$#av_paren_type]);
1811cf655043SAndy Whitcroft
1812171ae1a4SAndy Whitcroft			$type = 'E';
1813cf655043SAndy Whitcroft
1814c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
1815cf655043SAndy Whitcroft			print "PRE_END($1)\n" if ($dbg_values > 1);
1816cf655043SAndy Whitcroft
1817cf655043SAndy Whitcroft			$av_preprocessor = 1;
1818cf655043SAndy Whitcroft
1819cf655043SAndy Whitcroft			# Assume all arms of the conditional end as this
1820cf655043SAndy Whitcroft			# one does, and continue as if the #endif was not here.
1821cf655043SAndy Whitcroft			pop(@av_paren_type);
1822cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1823171ae1a4SAndy Whitcroft			$type = 'E';
18246c72ffaaSAndy Whitcroft
18256c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\\\n)/o) {
1826c2fdda0dSAndy Whitcroft			print "PRECONT($1)\n" if ($dbg_values > 1);
18276c72ffaaSAndy Whitcroft
1828171ae1a4SAndy Whitcroft		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
1829171ae1a4SAndy Whitcroft			print "ATTR($1)\n" if ($dbg_values > 1);
1830171ae1a4SAndy Whitcroft			$av_pending = $type;
1831171ae1a4SAndy Whitcroft			$type = 'N';
1832171ae1a4SAndy Whitcroft
18336c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
1834c2fdda0dSAndy Whitcroft			print "SIZEOF($1)\n" if ($dbg_values > 1);
18356c72ffaaSAndy Whitcroft			if (defined $2) {
1836cf655043SAndy Whitcroft				$av_pending = 'V';
18376c72ffaaSAndy Whitcroft			}
18386c72ffaaSAndy Whitcroft			$type = 'N';
18396c72ffaaSAndy Whitcroft
184014b111c1SAndy Whitcroft		} elsif ($cur =~ /^(if|while|for)\b/o) {
1841c2fdda0dSAndy Whitcroft			print "COND($1)\n" if ($dbg_values > 1);
184214b111c1SAndy Whitcroft			$av_pending = 'E';
18436c72ffaaSAndy Whitcroft			$type = 'N';
18446c72ffaaSAndy Whitcroft
18451f65f947SAndy Whitcroft		} elsif ($cur =~/^(case)/o) {
18461f65f947SAndy Whitcroft			print "CASE($1)\n" if ($dbg_values > 1);
18471f65f947SAndy Whitcroft			$av_pend_colon = 'C';
18481f65f947SAndy Whitcroft			$type = 'N';
18491f65f947SAndy Whitcroft
185014b111c1SAndy Whitcroft		} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
1851c2fdda0dSAndy Whitcroft			print "KEYWORD($1)\n" if ($dbg_values > 1);
18526c72ffaaSAndy Whitcroft			$type = 'N';
18536c72ffaaSAndy Whitcroft
18546c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\()/o) {
1855c2fdda0dSAndy Whitcroft			print "PAREN('$1')\n" if ($dbg_values > 1);
1856cf655043SAndy Whitcroft			push(@av_paren_type, $av_pending);
1857cf655043SAndy Whitcroft			$av_pending = '_';
18586c72ffaaSAndy Whitcroft			$type = 'N';
18596c72ffaaSAndy Whitcroft
18606c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\))/o) {
1861cf655043SAndy Whitcroft			my $new_type = pop(@av_paren_type);
1862cf655043SAndy Whitcroft			if ($new_type ne '_') {
1863cf655043SAndy Whitcroft				$type = $new_type;
1864c2fdda0dSAndy Whitcroft				print "PAREN('$1') -> $type\n"
1865c2fdda0dSAndy Whitcroft							if ($dbg_values > 1);
18666c72ffaaSAndy Whitcroft			} else {
1867c2fdda0dSAndy Whitcroft				print "PAREN('$1')\n" if ($dbg_values > 1);
18686c72ffaaSAndy Whitcroft			}
18696c72ffaaSAndy Whitcroft
1870c8cb2ca3SAndy Whitcroft		} elsif ($cur =~ /^($Ident)\s*\(/o) {
1871c2fdda0dSAndy Whitcroft			print "FUNC($1)\n" if ($dbg_values > 1);
1872c8cb2ca3SAndy Whitcroft			$type = 'V';
1873cf655043SAndy Whitcroft			$av_pending = 'V';
18746c72ffaaSAndy Whitcroft
18758e761b04SAndy Whitcroft		} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
18768e761b04SAndy Whitcroft			if (defined $2 && $type eq 'C' || $type eq 'T') {
18771f65f947SAndy Whitcroft				$av_pend_colon = 'B';
18788e761b04SAndy Whitcroft			} elsif ($type eq 'E') {
18798e761b04SAndy Whitcroft				$av_pend_colon = 'L';
18801f65f947SAndy Whitcroft			}
18811f65f947SAndy Whitcroft			print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
18821f65f947SAndy Whitcroft			$type = 'V';
18831f65f947SAndy Whitcroft
18846c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Ident|$Constant)/o) {
1885c2fdda0dSAndy Whitcroft			print "IDENT($1)\n" if ($dbg_values > 1);
18866c72ffaaSAndy Whitcroft			$type = 'V';
18876c72ffaaSAndy Whitcroft
18886c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Assignment)/o) {
1889c2fdda0dSAndy Whitcroft			print "ASSIGN($1)\n" if ($dbg_values > 1);
18906c72ffaaSAndy Whitcroft			$type = 'N';
18916c72ffaaSAndy Whitcroft
1892cf655043SAndy Whitcroft		} elsif ($cur =~/^(;|{|})/) {
1893c2fdda0dSAndy Whitcroft			print "END($1)\n" if ($dbg_values > 1);
189413214adfSAndy Whitcroft			$type = 'E';
18951f65f947SAndy Whitcroft			$av_pend_colon = 'O';
189613214adfSAndy Whitcroft
18978e761b04SAndy Whitcroft		} elsif ($cur =~/^(,)/) {
18988e761b04SAndy Whitcroft			print "COMMA($1)\n" if ($dbg_values > 1);
18998e761b04SAndy Whitcroft			$type = 'C';
19008e761b04SAndy Whitcroft
19011f65f947SAndy Whitcroft		} elsif ($cur =~ /^(\?)/o) {
19021f65f947SAndy Whitcroft			print "QUESTION($1)\n" if ($dbg_values > 1);
19031f65f947SAndy Whitcroft			$type = 'N';
19041f65f947SAndy Whitcroft
19051f65f947SAndy Whitcroft		} elsif ($cur =~ /^(:)/o) {
19061f65f947SAndy Whitcroft			print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
19071f65f947SAndy Whitcroft
19081f65f947SAndy Whitcroft			substr($var, length($res), 1, $av_pend_colon);
19091f65f947SAndy Whitcroft			if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
19101f65f947SAndy Whitcroft				$type = 'E';
19111f65f947SAndy Whitcroft			} else {
19121f65f947SAndy Whitcroft				$type = 'N';
19131f65f947SAndy Whitcroft			}
19141f65f947SAndy Whitcroft			$av_pend_colon = 'O';
19151f65f947SAndy Whitcroft
19168e761b04SAndy Whitcroft		} elsif ($cur =~ /^(\[)/o) {
191713214adfSAndy Whitcroft			print "CLOSE($1)\n" if ($dbg_values > 1);
19186c72ffaaSAndy Whitcroft			$type = 'N';
19196c72ffaaSAndy Whitcroft
19200d413866SAndy Whitcroft		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
192174048ed8SAndy Whitcroft			my $variant;
192274048ed8SAndy Whitcroft
192374048ed8SAndy Whitcroft			print "OPV($1)\n" if ($dbg_values > 1);
192474048ed8SAndy Whitcroft			if ($type eq 'V') {
192574048ed8SAndy Whitcroft				$variant = 'B';
192674048ed8SAndy Whitcroft			} else {
192774048ed8SAndy Whitcroft				$variant = 'U';
192874048ed8SAndy Whitcroft			}
192974048ed8SAndy Whitcroft
193074048ed8SAndy Whitcroft			substr($var, length($res), 1, $variant);
193174048ed8SAndy Whitcroft			$type = 'N';
193274048ed8SAndy Whitcroft
19336c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Operators)/o) {
1934c2fdda0dSAndy Whitcroft			print "OP($1)\n" if ($dbg_values > 1);
19356c72ffaaSAndy Whitcroft			if ($1 ne '++' && $1 ne '--') {
19366c72ffaaSAndy Whitcroft				$type = 'N';
19376c72ffaaSAndy Whitcroft			}
19386c72ffaaSAndy Whitcroft
19396c72ffaaSAndy Whitcroft		} elsif ($cur =~ /(^.)/o) {
1940c2fdda0dSAndy Whitcroft			print "C($1)\n" if ($dbg_values > 1);
19416c72ffaaSAndy Whitcroft		}
19426c72ffaaSAndy Whitcroft		if (defined $1) {
19436c72ffaaSAndy Whitcroft			$cur = substr($cur, length($1));
19446c72ffaaSAndy Whitcroft			$res .= $type x length($1);
19456c72ffaaSAndy Whitcroft		}
19466c72ffaaSAndy Whitcroft	}
19476c72ffaaSAndy Whitcroft
19481f65f947SAndy Whitcroft	return ($res, $var);
19496c72ffaaSAndy Whitcroft}
19506c72ffaaSAndy Whitcroft
19518905a67cSAndy Whitcroftsub possible {
195213214adfSAndy Whitcroft	my ($possible, $line) = @_;
19539a974fdbSAndy Whitcroft	my $notPermitted = qr{(?:
19540776e594SAndy Whitcroft		^(?:
19550776e594SAndy Whitcroft			$Modifier|
19560776e594SAndy Whitcroft			$Storage|
19570776e594SAndy Whitcroft			$Type|
19589a974fdbSAndy Whitcroft			DEFINE_\S+
19599a974fdbSAndy Whitcroft		)$|
19609a974fdbSAndy Whitcroft		^(?:
19610776e594SAndy Whitcroft			goto|
19620776e594SAndy Whitcroft			return|
19630776e594SAndy Whitcroft			case|
19640776e594SAndy Whitcroft			else|
19650776e594SAndy Whitcroft			asm|__asm__|
196689a88353SAndy Whitcroft			do|
196789a88353SAndy Whitcroft			\#|
196889a88353SAndy Whitcroft			\#\#|
19699a974fdbSAndy Whitcroft		)(?:\s|$)|
19700776e594SAndy Whitcroft		^(?:typedef|struct|enum)\b
19719a974fdbSAndy Whitcroft	    )}x;
19729a974fdbSAndy Whitcroft	warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
19739a974fdbSAndy Whitcroft	if ($possible !~ $notPermitted) {
1974c45dcabdSAndy Whitcroft		# Check for modifiers.
1975c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Storage\s*//g;
1976c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Sparse\s*//g;
1977c45dcabdSAndy Whitcroft		if ($possible =~ /^\s*$/) {
1978c45dcabdSAndy Whitcroft
1979c45dcabdSAndy Whitcroft		} elsif ($possible =~ /\s/) {
1980c45dcabdSAndy Whitcroft			$possible =~ s/\s*$Type\s*//g;
1981d2506586SAndy Whitcroft			for my $modifier (split(' ', $possible)) {
19829a974fdbSAndy Whitcroft				if ($modifier !~ $notPermitted) {
1983d2506586SAndy Whitcroft					warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
1984485ff23eSAlex Dowad					push(@modifierListFile, $modifier);
1985d2506586SAndy Whitcroft				}
19869a974fdbSAndy Whitcroft			}
1987c45dcabdSAndy Whitcroft
1988c45dcabdSAndy Whitcroft		} else {
198913214adfSAndy Whitcroft			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
1990485ff23eSAlex Dowad			push(@typeListFile, $possible);
1991c45dcabdSAndy Whitcroft		}
19928905a67cSAndy Whitcroft		build_types();
19930776e594SAndy Whitcroft	} else {
19940776e594SAndy Whitcroft		warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
19958905a67cSAndy Whitcroft	}
19968905a67cSAndy Whitcroft}
19978905a67cSAndy Whitcroft
19986c72ffaaSAndy Whitcroftmy $prefix = '';
19996c72ffaaSAndy Whitcroft
2000000d1cc1SJoe Perchessub show_type {
2001cbec18afSJoe Perches	my ($type) = @_;
200291bfe484SJoe Perches
2003522b837cSAlexey Dobriyan	$type =~ tr/[a-z]/[A-Z]/;
2004522b837cSAlexey Dobriyan
2005cbec18afSJoe Perches	return defined $use_type{$type} if (scalar keys %use_type > 0);
2006cbec18afSJoe Perches
2007cbec18afSJoe Perches	return !defined $ignore_type{$type};
2008000d1cc1SJoe Perches}
2009000d1cc1SJoe Perches
2010f0a594c1SAndy Whitcroftsub report {
2011cbec18afSJoe Perches	my ($level, $type, $msg) = @_;
2012cbec18afSJoe Perches
2013cbec18afSJoe Perches	if (!show_type($type) ||
2014cbec18afSJoe Perches	    (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
2015773647a0SAndy Whitcroft		return 0;
2016773647a0SAndy Whitcroft	}
201757230297SJoe Perches	my $output = '';
2018737c0767SJohn Brooks	if ($color) {
201957230297SJoe Perches		if ($level eq 'ERROR') {
202057230297SJoe Perches			$output .= RED;
202157230297SJoe Perches		} elsif ($level eq 'WARNING') {
202257230297SJoe Perches			$output .= YELLOW;
2023000d1cc1SJoe Perches		} else {
202457230297SJoe Perches			$output .= GREEN;
2025000d1cc1SJoe Perches		}
202657230297SJoe Perches	}
202757230297SJoe Perches	$output .= $prefix . $level . ':';
202857230297SJoe Perches	if ($show_types) {
2029737c0767SJohn Brooks		$output .= BLUE if ($color);
203057230297SJoe Perches		$output .= "$type:";
203157230297SJoe Perches	}
2032737c0767SJohn Brooks	$output .= RESET if ($color);
203357230297SJoe Perches	$output .= ' ' . $msg . "\n";
203434d8815fSJoe Perches
203534d8815fSJoe Perches	if ($showfile) {
203634d8815fSJoe Perches		my @lines = split("\n", $output, -1);
203734d8815fSJoe Perches		splice(@lines, 1, 1);
203834d8815fSJoe Perches		$output = join("\n", @lines);
203934d8815fSJoe Perches	}
204057230297SJoe Perches	$output = (split('\n', $output))[0] . "\n" if ($terse);
20418905a67cSAndy Whitcroft
204257230297SJoe Perches	push(our @report, $output);
2043773647a0SAndy Whitcroft
2044773647a0SAndy Whitcroft	return 1;
2045f0a594c1SAndy Whitcroft}
2046cbec18afSJoe Perches
2047f0a594c1SAndy Whitcroftsub report_dump {
204813214adfSAndy Whitcroft	our @report;
2049f0a594c1SAndy Whitcroft}
2050000d1cc1SJoe Perches
2051d752fcc8SJoe Perchessub fixup_current_range {
2052d752fcc8SJoe Perches	my ($lineRef, $offset, $length) = @_;
2053d752fcc8SJoe Perches
2054d752fcc8SJoe Perches	if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
2055d752fcc8SJoe Perches		my $o = $1;
2056d752fcc8SJoe Perches		my $l = $2;
2057d752fcc8SJoe Perches		my $no = $o + $offset;
2058d752fcc8SJoe Perches		my $nl = $l + $length;
2059d752fcc8SJoe Perches		$$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
2060d752fcc8SJoe Perches	}
2061d752fcc8SJoe Perches}
2062d752fcc8SJoe Perches
2063d752fcc8SJoe Perchessub fix_inserted_deleted_lines {
2064d752fcc8SJoe Perches	my ($linesRef, $insertedRef, $deletedRef) = @_;
2065d752fcc8SJoe Perches
2066d752fcc8SJoe Perches	my $range_last_linenr = 0;
2067d752fcc8SJoe Perches	my $delta_offset = 0;
2068d752fcc8SJoe Perches
2069d752fcc8SJoe Perches	my $old_linenr = 0;
2070d752fcc8SJoe Perches	my $new_linenr = 0;
2071d752fcc8SJoe Perches
2072d752fcc8SJoe Perches	my $next_insert = 0;
2073d752fcc8SJoe Perches	my $next_delete = 0;
2074d752fcc8SJoe Perches
2075d752fcc8SJoe Perches	my @lines = ();
2076d752fcc8SJoe Perches
2077d752fcc8SJoe Perches	my $inserted = @{$insertedRef}[$next_insert++];
2078d752fcc8SJoe Perches	my $deleted = @{$deletedRef}[$next_delete++];
2079d752fcc8SJoe Perches
2080d752fcc8SJoe Perches	foreach my $old_line (@{$linesRef}) {
2081d752fcc8SJoe Perches		my $save_line = 1;
2082d752fcc8SJoe Perches		my $line = $old_line;	#don't modify the array
2083323b267fSJoe Perches		if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) {	#new filename
2084d752fcc8SJoe Perches			$delta_offset = 0;
2085d752fcc8SJoe Perches		} elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) {	#new hunk
2086d752fcc8SJoe Perches			$range_last_linenr = $new_linenr;
2087d752fcc8SJoe Perches			fixup_current_range(\$line, $delta_offset, 0);
2088d752fcc8SJoe Perches		}
2089d752fcc8SJoe Perches
2090d752fcc8SJoe Perches		while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
2091d752fcc8SJoe Perches			$deleted = @{$deletedRef}[$next_delete++];
2092d752fcc8SJoe Perches			$save_line = 0;
2093d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
2094d752fcc8SJoe Perches		}
2095d752fcc8SJoe Perches
2096d752fcc8SJoe Perches		while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
2097d752fcc8SJoe Perches			push(@lines, ${$inserted}{'LINE'});
2098d752fcc8SJoe Perches			$inserted = @{$insertedRef}[$next_insert++];
2099d752fcc8SJoe Perches			$new_linenr++;
2100d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
2101d752fcc8SJoe Perches		}
2102d752fcc8SJoe Perches
2103d752fcc8SJoe Perches		if ($save_line) {
2104d752fcc8SJoe Perches			push(@lines, $line);
2105d752fcc8SJoe Perches			$new_linenr++;
2106d752fcc8SJoe Perches		}
2107d752fcc8SJoe Perches
2108d752fcc8SJoe Perches		$old_linenr++;
2109d752fcc8SJoe Perches	}
2110d752fcc8SJoe Perches
2111d752fcc8SJoe Perches	return @lines;
2112d752fcc8SJoe Perches}
2113d752fcc8SJoe Perches
2114f2d7e4d4SJoe Perchessub fix_insert_line {
2115f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
2116f2d7e4d4SJoe Perches
2117f2d7e4d4SJoe Perches	my $inserted = {
2118f2d7e4d4SJoe Perches		LINENR => $linenr,
2119f2d7e4d4SJoe Perches		LINE => $line,
2120f2d7e4d4SJoe Perches	};
2121f2d7e4d4SJoe Perches	push(@fixed_inserted, $inserted);
2122f2d7e4d4SJoe Perches}
2123f2d7e4d4SJoe Perches
2124f2d7e4d4SJoe Perchessub fix_delete_line {
2125f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
2126f2d7e4d4SJoe Perches
2127f2d7e4d4SJoe Perches	my $deleted = {
2128f2d7e4d4SJoe Perches		LINENR => $linenr,
2129f2d7e4d4SJoe Perches		LINE => $line,
2130f2d7e4d4SJoe Perches	};
2131f2d7e4d4SJoe Perches
2132f2d7e4d4SJoe Perches	push(@fixed_deleted, $deleted);
2133f2d7e4d4SJoe Perches}
2134f2d7e4d4SJoe Perches
2135de7d4f0eSAndy Whitcroftsub ERROR {
2136cbec18afSJoe Perches	my ($type, $msg) = @_;
2137cbec18afSJoe Perches
2138cbec18afSJoe Perches	if (report("ERROR", $type, $msg)) {
2139de7d4f0eSAndy Whitcroft		our $clean = 0;
21406c72ffaaSAndy Whitcroft		our $cnt_error++;
21413705ce5bSJoe Perches		return 1;
2142de7d4f0eSAndy Whitcroft	}
21433705ce5bSJoe Perches	return 0;
2144773647a0SAndy Whitcroft}
2145de7d4f0eSAndy Whitcroftsub WARN {
2146cbec18afSJoe Perches	my ($type, $msg) = @_;
2147cbec18afSJoe Perches
2148cbec18afSJoe Perches	if (report("WARNING", $type, $msg)) {
2149de7d4f0eSAndy Whitcroft		our $clean = 0;
21506c72ffaaSAndy Whitcroft		our $cnt_warn++;
21513705ce5bSJoe Perches		return 1;
2152de7d4f0eSAndy Whitcroft	}
21533705ce5bSJoe Perches	return 0;
2154773647a0SAndy Whitcroft}
2155de7d4f0eSAndy Whitcroftsub CHK {
2156cbec18afSJoe Perches	my ($type, $msg) = @_;
2157cbec18afSJoe Perches
2158cbec18afSJoe Perches	if ($check && report("CHECK", $type, $msg)) {
2159de7d4f0eSAndy Whitcroft		our $clean = 0;
21606c72ffaaSAndy Whitcroft		our $cnt_chk++;
21613705ce5bSJoe Perches		return 1;
21626c72ffaaSAndy Whitcroft	}
21633705ce5bSJoe Perches	return 0;
2164de7d4f0eSAndy Whitcroft}
2165de7d4f0eSAndy Whitcroft
21666ecd9674SAndy Whitcroftsub check_absolute_file {
21676ecd9674SAndy Whitcroft	my ($absolute, $herecurr) = @_;
21686ecd9674SAndy Whitcroft	my $file = $absolute;
21696ecd9674SAndy Whitcroft
21706ecd9674SAndy Whitcroft	##print "absolute<$absolute>\n";
21716ecd9674SAndy Whitcroft
21726ecd9674SAndy Whitcroft	# See if any suffix of this path is a path within the tree.
21736ecd9674SAndy Whitcroft	while ($file =~ s@^[^/]*/@@) {
21746ecd9674SAndy Whitcroft		if (-f "$root/$file") {
21756ecd9674SAndy Whitcroft			##print "file<$file>\n";
21766ecd9674SAndy Whitcroft			last;
21776ecd9674SAndy Whitcroft		}
21786ecd9674SAndy Whitcroft	}
21796ecd9674SAndy Whitcroft	if (! -f _)  {
21806ecd9674SAndy Whitcroft		return 0;
21816ecd9674SAndy Whitcroft	}
21826ecd9674SAndy Whitcroft
21836ecd9674SAndy Whitcroft	# It is, so see if the prefix is acceptable.
21846ecd9674SAndy Whitcroft	my $prefix = $absolute;
21856ecd9674SAndy Whitcroft	substr($prefix, -length($file)) = '';
21866ecd9674SAndy Whitcroft
21876ecd9674SAndy Whitcroft	##print "prefix<$prefix>\n";
21886ecd9674SAndy Whitcroft	if ($prefix ne ".../") {
2189000d1cc1SJoe Perches		WARN("USE_RELATIVE_PATH",
2190000d1cc1SJoe Perches		     "use relative pathname instead of absolute in changelog text\n" . $herecurr);
21916ecd9674SAndy Whitcroft	}
21926ecd9674SAndy Whitcroft}
21936ecd9674SAndy Whitcroft
21943705ce5bSJoe Perchessub trim {
21953705ce5bSJoe Perches	my ($string) = @_;
21963705ce5bSJoe Perches
2197b34c648bSJoe Perches	$string =~ s/^\s+|\s+$//g;
2198b34c648bSJoe Perches
2199b34c648bSJoe Perches	return $string;
2200b34c648bSJoe Perches}
2201b34c648bSJoe Perches
2202b34c648bSJoe Perchessub ltrim {
2203b34c648bSJoe Perches	my ($string) = @_;
2204b34c648bSJoe Perches
2205b34c648bSJoe Perches	$string =~ s/^\s+//;
2206b34c648bSJoe Perches
2207b34c648bSJoe Perches	return $string;
2208b34c648bSJoe Perches}
2209b34c648bSJoe Perches
2210b34c648bSJoe Perchessub rtrim {
2211b34c648bSJoe Perches	my ($string) = @_;
2212b34c648bSJoe Perches
2213b34c648bSJoe Perches	$string =~ s/\s+$//;
22143705ce5bSJoe Perches
22153705ce5bSJoe Perches	return $string;
22163705ce5bSJoe Perches}
22173705ce5bSJoe Perches
221852ea8506SJoe Perchessub string_find_replace {
221952ea8506SJoe Perches	my ($string, $find, $replace) = @_;
222052ea8506SJoe Perches
222152ea8506SJoe Perches	$string =~ s/$find/$replace/g;
222252ea8506SJoe Perches
222352ea8506SJoe Perches	return $string;
222452ea8506SJoe Perches}
222552ea8506SJoe Perches
22263705ce5bSJoe Perchessub tabify {
22273705ce5bSJoe Perches	my ($leading) = @_;
22283705ce5bSJoe Perches
22293705ce5bSJoe Perches	my $source_indent = 8;
22303705ce5bSJoe Perches	my $max_spaces_before_tab = $source_indent - 1;
22313705ce5bSJoe Perches	my $spaces_to_tab = " " x $source_indent;
22323705ce5bSJoe Perches
22333705ce5bSJoe Perches	#convert leading spaces to tabs
22343705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
22353705ce5bSJoe Perches	#Remove spaces before a tab
22363705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
22373705ce5bSJoe Perches
22383705ce5bSJoe Perches	return "$leading";
22393705ce5bSJoe Perches}
22403705ce5bSJoe Perches
2241d1fe9c09SJoe Perchessub pos_last_openparen {
2242d1fe9c09SJoe Perches	my ($line) = @_;
2243d1fe9c09SJoe Perches
2244d1fe9c09SJoe Perches	my $pos = 0;
2245d1fe9c09SJoe Perches
2246d1fe9c09SJoe Perches	my $opens = $line =~ tr/\(/\(/;
2247d1fe9c09SJoe Perches	my $closes = $line =~ tr/\)/\)/;
2248d1fe9c09SJoe Perches
2249d1fe9c09SJoe Perches	my $last_openparen = 0;
2250d1fe9c09SJoe Perches
2251d1fe9c09SJoe Perches	if (($opens == 0) || ($closes >= $opens)) {
2252d1fe9c09SJoe Perches		return -1;
2253d1fe9c09SJoe Perches	}
2254d1fe9c09SJoe Perches
2255d1fe9c09SJoe Perches	my $len = length($line);
2256d1fe9c09SJoe Perches
2257d1fe9c09SJoe Perches	for ($pos = 0; $pos < $len; $pos++) {
2258d1fe9c09SJoe Perches		my $string = substr($line, $pos);
2259d1fe9c09SJoe Perches		if ($string =~ /^($FuncArg|$balanced_parens)/) {
2260d1fe9c09SJoe Perches			$pos += length($1) - 1;
2261d1fe9c09SJoe Perches		} elsif (substr($line, $pos, 1) eq '(') {
2262d1fe9c09SJoe Perches			$last_openparen = $pos;
2263d1fe9c09SJoe Perches		} elsif (index($string, '(') == -1) {
2264d1fe9c09SJoe Perches			last;
2265d1fe9c09SJoe Perches		}
2266d1fe9c09SJoe Perches	}
2267d1fe9c09SJoe Perches
226891cb5195SJoe Perches	return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
2269d1fe9c09SJoe Perches}
2270d1fe9c09SJoe Perches
22710a920b5bSAndy Whitcroftsub process {
22720a920b5bSAndy Whitcroft	my $filename = shift;
22730a920b5bSAndy Whitcroft
22740a920b5bSAndy Whitcroft	my $linenr=0;
22750a920b5bSAndy Whitcroft	my $prevline="";
2276c2fdda0dSAndy Whitcroft	my $prevrawline="";
22770a920b5bSAndy Whitcroft	my $stashline="";
2278c2fdda0dSAndy Whitcroft	my $stashrawline="";
22790a920b5bSAndy Whitcroft
22804a0df2efSAndy Whitcroft	my $length;
22810a920b5bSAndy Whitcroft	my $indent;
22820a920b5bSAndy Whitcroft	my $previndent=0;
22830a920b5bSAndy Whitcroft	my $stashindent=0;
22840a920b5bSAndy Whitcroft
2285de7d4f0eSAndy Whitcroft	our $clean = 1;
22860a920b5bSAndy Whitcroft	my $signoff = 0;
2287cd261496SGeert Uytterhoeven	my $author = '';
2288cd261496SGeert Uytterhoeven	my $authorsignoff = 0;
22890a920b5bSAndy Whitcroft	my $is_patch = 0;
2290133712a2SRob Herring	my $is_binding_patch = -1;
229129ee1b0cSJoe Perches	my $in_header_lines = $file ? 0 : 1;
229215662b3eSJoe Perches	my $in_commit_log = 0;		#Scanning lines before patch
2293ed43c4e5SAllen Hubbe	my $has_commit_log = 0;		#Encountered lines before patch
2294490b292cSJoe Perches	my $commit_log_lines = 0;	#Number of commit log lines
2295bf4daf12SJoe Perches	my $commit_log_possible_stack_dump = 0;
22962a076f40SJoe Perches	my $commit_log_long_line = 0;
2297e518e9a5SJoe Perches	my $commit_log_has_diff = 0;
229813f1937eSJoe Perches	my $reported_maintainer_file = 0;
2299fa64205dSPasi Savanainen	my $non_utf8_charset = 0;
2300fa64205dSPasi Savanainen
2301365dd4eaSJoe Perches	my $last_blank_line = 0;
23025e4f6ba5SJoe Perches	my $last_coalesced_string_linenr = -1;
2303365dd4eaSJoe Perches
230413214adfSAndy Whitcroft	our @report = ();
23056c72ffaaSAndy Whitcroft	our $cnt_lines = 0;
23066c72ffaaSAndy Whitcroft	our $cnt_error = 0;
23076c72ffaaSAndy Whitcroft	our $cnt_warn = 0;
23086c72ffaaSAndy Whitcroft	our $cnt_chk = 0;
23096c72ffaaSAndy Whitcroft
23100a920b5bSAndy Whitcroft	# Trace the real file/line as we go.
23110a920b5bSAndy Whitcroft	my $realfile = '';
23120a920b5bSAndy Whitcroft	my $realline = 0;
23130a920b5bSAndy Whitcroft	my $realcnt = 0;
23140a920b5bSAndy Whitcroft	my $here = '';
231577cb8546SJoe Perches	my $context_function;		#undef'd unless there's a known function
23160a920b5bSAndy Whitcroft	my $in_comment = 0;
2317c2fdda0dSAndy Whitcroft	my $comment_edge = 0;
23180a920b5bSAndy Whitcroft	my $first_line = 0;
23191e855726SWolfram Sang	my $p1_prefix = '';
23200a920b5bSAndy Whitcroft
232113214adfSAndy Whitcroft	my $prev_values = 'E';
232213214adfSAndy Whitcroft
232313214adfSAndy Whitcroft	# suppression flags
2324773647a0SAndy Whitcroft	my %suppress_ifbraces;
2325170d3a22SAndy Whitcroft	my %suppress_whiletrailers;
23262b474a1aSAndy Whitcroft	my %suppress_export;
23273e469cdcSAndy Whitcroft	my $suppress_statement = 0;
2328653d4876SAndy Whitcroft
23297e51f197SJoe Perches	my %signatures = ();
2330323c1260SJoe Perches
2331c2fdda0dSAndy Whitcroft	# Pre-scan the patch sanitizing the lines.
2332de7d4f0eSAndy Whitcroft	# Pre-scan the patch looking for any __setup documentation.
2333c2fdda0dSAndy Whitcroft	#
2334de7d4f0eSAndy Whitcroft	my @setup_docs = ();
2335de7d4f0eSAndy Whitcroft	my $setup_docs = 0;
2336773647a0SAndy Whitcroft
2337d8b07710SJoe Perches	my $camelcase_file_seeded = 0;
2338d8b07710SJoe Perches
23399f3a8992SRob Herring	my $checklicenseline = 1;
23409f3a8992SRob Herring
2341773647a0SAndy Whitcroft	sanitise_line_reset();
2342c2fdda0dSAndy Whitcroft	my $line;
2343c2fdda0dSAndy Whitcroft	foreach my $rawline (@rawlines) {
2344773647a0SAndy Whitcroft		$linenr++;
2345773647a0SAndy Whitcroft		$line = $rawline;
2346c2fdda0dSAndy Whitcroft
23473705ce5bSJoe Perches		push(@fixed, $rawline) if ($fix);
23483705ce5bSJoe Perches
2349773647a0SAndy Whitcroft		if ($rawline=~/^\+\+\+\s+(\S+)/) {
2350de7d4f0eSAndy Whitcroft			$setup_docs = 0;
23518c27ceffSMauro Carvalho Chehab			if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) {
2352de7d4f0eSAndy Whitcroft				$setup_docs = 1;
2353de7d4f0eSAndy Whitcroft			}
2354773647a0SAndy Whitcroft			#next;
2355de7d4f0eSAndy Whitcroft		}
235674fd4f34SJoe Perches		if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
2357773647a0SAndy Whitcroft			$realline=$1-1;
2358773647a0SAndy Whitcroft			if (defined $2) {
2359773647a0SAndy Whitcroft				$realcnt=$3+1;
2360773647a0SAndy Whitcroft			} else {
2361773647a0SAndy Whitcroft				$realcnt=1+1;
2362773647a0SAndy Whitcroft			}
2363c45dcabdSAndy Whitcroft			$in_comment = 0;
2364773647a0SAndy Whitcroft
2365773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  Run
2366773647a0SAndy Whitcroft			# the context looking for a comment "edge".  If this
2367773647a0SAndy Whitcroft			# edge is a close comment then we must be in a comment
2368773647a0SAndy Whitcroft			# at context start.
2369773647a0SAndy Whitcroft			my $edge;
237001fa9147SAndy Whitcroft			my $cnt = $realcnt;
237101fa9147SAndy Whitcroft			for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
237201fa9147SAndy Whitcroft				next if (defined $rawlines[$ln - 1] &&
237301fa9147SAndy Whitcroft					 $rawlines[$ln - 1] =~ /^-/);
237401fa9147SAndy Whitcroft				$cnt--;
237501fa9147SAndy Whitcroft				#print "RAW<$rawlines[$ln - 1]>\n";
2376721c1cb6SAndy Whitcroft				last if (!defined $rawlines[$ln - 1]);
2377fae17daeSAndy Whitcroft				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
2378fae17daeSAndy Whitcroft				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
2379fae17daeSAndy Whitcroft					($edge) = $1;
2380fae17daeSAndy Whitcroft					last;
2381fae17daeSAndy Whitcroft				}
2382773647a0SAndy Whitcroft			}
2383773647a0SAndy Whitcroft			if (defined $edge && $edge eq '*/') {
2384773647a0SAndy Whitcroft				$in_comment = 1;
2385773647a0SAndy Whitcroft			}
2386773647a0SAndy Whitcroft
2387773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  If this
2388773647a0SAndy Whitcroft			# is the start of a diff block and this line starts
2389773647a0SAndy Whitcroft			# ' *' then it is very likely a comment.
2390773647a0SAndy Whitcroft			if (!defined $edge &&
239183242e0cSAndy Whitcroft			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
2392773647a0SAndy Whitcroft			{
2393773647a0SAndy Whitcroft				$in_comment = 1;
2394773647a0SAndy Whitcroft			}
2395773647a0SAndy Whitcroft
2396773647a0SAndy Whitcroft			##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2397773647a0SAndy Whitcroft			sanitise_line_reset($in_comment);
2398773647a0SAndy Whitcroft
2399171ae1a4SAndy Whitcroft		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
2400773647a0SAndy Whitcroft			# Standardise the strings and chars within the input to
2401171ae1a4SAndy Whitcroft			# simplify matching -- only bother with positive lines.
2402773647a0SAndy Whitcroft			$line = sanitise_line($rawline);
2403773647a0SAndy Whitcroft		}
2404773647a0SAndy Whitcroft		push(@lines, $line);
2405773647a0SAndy Whitcroft
2406773647a0SAndy Whitcroft		if ($realcnt > 1) {
2407773647a0SAndy Whitcroft			$realcnt-- if ($line =~ /^(?:\+| |$)/);
2408773647a0SAndy Whitcroft		} else {
2409773647a0SAndy Whitcroft			$realcnt = 0;
2410773647a0SAndy Whitcroft		}
2411773647a0SAndy Whitcroft
2412773647a0SAndy Whitcroft		#print "==>$rawline\n";
2413773647a0SAndy Whitcroft		#print "-->$line\n";
2414de7d4f0eSAndy Whitcroft
2415de7d4f0eSAndy Whitcroft		if ($setup_docs && $line =~ /^\+/) {
2416de7d4f0eSAndy Whitcroft			push(@setup_docs, $line);
2417de7d4f0eSAndy Whitcroft		}
2418de7d4f0eSAndy Whitcroft	}
2419de7d4f0eSAndy Whitcroft
24206c72ffaaSAndy Whitcroft	$prefix = '';
24216c72ffaaSAndy Whitcroft
2422773647a0SAndy Whitcroft	$realcnt = 0;
2423773647a0SAndy Whitcroft	$linenr = 0;
2424194f66fcSJoe Perches	$fixlinenr = -1;
24250a920b5bSAndy Whitcroft	foreach my $line (@lines) {
24260a920b5bSAndy Whitcroft		$linenr++;
2427194f66fcSJoe Perches		$fixlinenr++;
24281b5539b1SJoe Perches		my $sline = $line;	#copy of $line
24291b5539b1SJoe Perches		$sline =~ s/$;/ /g;	#with comments as spaces
24300a920b5bSAndy Whitcroft
2431c2fdda0dSAndy Whitcroft		my $rawline = $rawlines[$linenr - 1];
24326c72ffaaSAndy Whitcroft
243312c253abSJoe Perches# check if it's a mode change, rename or start of a patch
243412c253abSJoe Perches		if (!$in_commit_log &&
243512c253abSJoe Perches		    ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ ||
243612c253abSJoe Perches		    ($line =~ /^rename (?:from|to) \S+\s*$/ ||
243712c253abSJoe Perches		     $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) {
243812c253abSJoe Perches			$is_patch = 1;
243912c253abSJoe Perches		}
244012c253abSJoe Perches
24410a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied
2442e518e9a5SJoe Perches		if (!$in_commit_log &&
244374fd4f34SJoe Perches		    $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
244474fd4f34SJoe Perches			my $context = $4;
24450a920b5bSAndy Whitcroft			$is_patch = 1;
24464a0df2efSAndy Whitcroft			$first_line = $linenr + 1;
24470a920b5bSAndy Whitcroft			$realline=$1-1;
24480a920b5bSAndy Whitcroft			if (defined $2) {
24490a920b5bSAndy Whitcroft				$realcnt=$3+1;
24500a920b5bSAndy Whitcroft			} else {
24510a920b5bSAndy Whitcroft				$realcnt=1+1;
24520a920b5bSAndy Whitcroft			}
2453c2fdda0dSAndy Whitcroft			annotate_reset();
245413214adfSAndy Whitcroft			$prev_values = 'E';
245513214adfSAndy Whitcroft
2456773647a0SAndy Whitcroft			%suppress_ifbraces = ();
2457170d3a22SAndy Whitcroft			%suppress_whiletrailers = ();
24582b474a1aSAndy Whitcroft			%suppress_export = ();
24593e469cdcSAndy Whitcroft			$suppress_statement = 0;
246074fd4f34SJoe Perches			if ($context =~ /\b(\w+)\s*\(/) {
246174fd4f34SJoe Perches				$context_function = $1;
246274fd4f34SJoe Perches			} else {
246374fd4f34SJoe Perches				undef $context_function;
246474fd4f34SJoe Perches			}
24650a920b5bSAndy Whitcroft			next;
24660a920b5bSAndy Whitcroft
24674a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that
24684a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely
24694a0df2efSAndy Whitcroft# blank context lines so we need to count that too.
2470773647a0SAndy Whitcroft		} elsif ($line =~ /^( |\+|$)/) {
24710a920b5bSAndy Whitcroft			$realline++;
2472d8aaf121SAndy Whitcroft			$realcnt-- if ($realcnt != 0);
24730a920b5bSAndy Whitcroft
24744a0df2efSAndy Whitcroft			# Measure the line length and indent.
2475c2fdda0dSAndy Whitcroft			($length, $indent) = line_stats($rawline);
24760a920b5bSAndy Whitcroft
24770a920b5bSAndy Whitcroft			# Track the previous line.
24780a920b5bSAndy Whitcroft			($prevline, $stashline) = ($stashline, $line);
24790a920b5bSAndy Whitcroft			($previndent, $stashindent) = ($stashindent, $indent);
2480c2fdda0dSAndy Whitcroft			($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2481c2fdda0dSAndy Whitcroft
2482773647a0SAndy Whitcroft			#warn "line<$line>\n";
24836c72ffaaSAndy Whitcroft
2484d8aaf121SAndy Whitcroft		} elsif ($realcnt == 1) {
2485d8aaf121SAndy Whitcroft			$realcnt--;
24860a920b5bSAndy Whitcroft		}
24870a920b5bSAndy Whitcroft
2488cc77cdcaSAndy Whitcroft		my $hunk_line = ($realcnt != 0);
2489cc77cdcaSAndy Whitcroft
24906c72ffaaSAndy Whitcroft		$here = "#$linenr: " if (!$file);
24916c72ffaaSAndy Whitcroft		$here = "#$realline: " if ($file);
2492773647a0SAndy Whitcroft
24932ac73b4fSJoe Perches		my $found_file = 0;
2494773647a0SAndy Whitcroft		# extract the filename as it passes
24953bf9a009SRabin Vincent		if ($line =~ /^diff --git.*?(\S+)$/) {
24963bf9a009SRabin Vincent			$realfile = $1;
24972b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2498270c49a0SJoe Perches			$in_commit_log = 0;
24992ac73b4fSJoe Perches			$found_file = 1;
25003bf9a009SRabin Vincent		} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
2501773647a0SAndy Whitcroft			$realfile = $1;
25022b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2503270c49a0SJoe Perches			$in_commit_log = 0;
25041e855726SWolfram Sang
25051e855726SWolfram Sang			$p1_prefix = $1;
2506e2f7aa4bSAndy Whitcroft			if (!$file && $tree && $p1_prefix ne '' &&
2507e2f7aa4bSAndy Whitcroft			    -e "$root/$p1_prefix") {
2508000d1cc1SJoe Perches				WARN("PATCH_PREFIX",
2509000d1cc1SJoe Perches				     "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
25101e855726SWolfram Sang			}
2511773647a0SAndy Whitcroft
2512c1ab3326SAndy Whitcroft			if ($realfile =~ m@^include/asm/@) {
2513000d1cc1SJoe Perches				ERROR("MODIFIED_INCLUDE_ASM",
2514000d1cc1SJoe Perches				      "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
2515773647a0SAndy Whitcroft			}
25162ac73b4fSJoe Perches			$found_file = 1;
25172ac73b4fSJoe Perches		}
25182ac73b4fSJoe Perches
251934d8815fSJoe Perches#make up the handle for any error we report on this line
252034d8815fSJoe Perches		if ($showfile) {
252134d8815fSJoe Perches			$prefix = "$realfile:$realline: "
252234d8815fSJoe Perches		} elsif ($emacs) {
25237d3a9f67SJoe Perches			if ($file) {
25247d3a9f67SJoe Perches				$prefix = "$filename:$realline: ";
25257d3a9f67SJoe Perches			} else {
252634d8815fSJoe Perches				$prefix = "$filename:$linenr: ";
252734d8815fSJoe Perches			}
25287d3a9f67SJoe Perches		}
252934d8815fSJoe Perches
25302ac73b4fSJoe Perches		if ($found_file) {
253185b0ee18SJoe Perches			if (is_maintained_obsolete($realfile)) {
253285b0ee18SJoe Perches				WARN("OBSOLETE",
253385b0ee18SJoe Perches				     "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.\n");
253485b0ee18SJoe Perches			}
25357bd7e483SJoe Perches			if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
25362ac73b4fSJoe Perches				$check = 1;
25372ac73b4fSJoe Perches			} else {
25382ac73b4fSJoe Perches				$check = $check_orig;
25392ac73b4fSJoe Perches			}
25409f3a8992SRob Herring			$checklicenseline = 1;
2541133712a2SRob Herring
2542133712a2SRob Herring			if ($realfile !~ /^MAINTAINERS/) {
2543133712a2SRob Herring				my $last_binding_patch = $is_binding_patch;
2544133712a2SRob Herring
2545133712a2SRob Herring				$is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;
2546133712a2SRob Herring
2547133712a2SRob Herring				if (($last_binding_patch != -1) &&
2548133712a2SRob Herring				    ($last_binding_patch ^ $is_binding_patch)) {
2549133712a2SRob Herring					WARN("DT_SPLIT_BINDING_PATCH",
2550133712a2SRob Herring					     "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.txt\n");
2551133712a2SRob Herring				}
2552133712a2SRob Herring			}
2553133712a2SRob Herring
2554773647a0SAndy Whitcroft			next;
2555773647a0SAndy Whitcroft		}
2556773647a0SAndy Whitcroft
2557389834b6SRandy Dunlap		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
25580a920b5bSAndy Whitcroft
2559c2fdda0dSAndy Whitcroft		my $hereline = "$here\n$rawline\n";
2560c2fdda0dSAndy Whitcroft		my $herecurr = "$here\n$rawline\n";
2561c2fdda0dSAndy Whitcroft		my $hereprev = "$here\n$prevrawline\n$rawline\n";
25620a920b5bSAndy Whitcroft
25636c72ffaaSAndy Whitcroft		$cnt_lines++ if ($realcnt != 0);
25646c72ffaaSAndy Whitcroft
2565490b292cSJoe Perches# Verify the existence of a commit log if appropriate
2566490b292cSJoe Perches# 2 is used because a $signature is counted in $commit_log_lines
2567490b292cSJoe Perches		if ($in_commit_log) {
2568490b292cSJoe Perches			if ($line !~ /^\s*$/) {
2569490b292cSJoe Perches				$commit_log_lines++;	#could be a $signature
2570490b292cSJoe Perches			}
2571490b292cSJoe Perches		} elsif ($has_commit_log && $commit_log_lines < 2) {
2572490b292cSJoe Perches			WARN("COMMIT_MESSAGE",
2573490b292cSJoe Perches			     "Missing commit description - Add an appropriate one\n");
2574490b292cSJoe Perches			$commit_log_lines = 2;	#warn only once
2575490b292cSJoe Perches		}
2576490b292cSJoe Perches
2577e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch
2578e518e9a5SJoe Perches		if ($in_commit_log && !$commit_log_has_diff &&
2579e518e9a5SJoe Perches		    (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&
2580e518e9a5SJoe Perches		      $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||
2581e518e9a5SJoe Perches		     $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
2582e518e9a5SJoe Perches		     $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
2583e518e9a5SJoe Perches			ERROR("DIFF_IN_COMMIT_MSG",
2584e518e9a5SJoe Perches			      "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
2585e518e9a5SJoe Perches			$commit_log_has_diff = 1;
2586e518e9a5SJoe Perches		}
2587e518e9a5SJoe Perches
25883bf9a009SRabin Vincent# Check for incorrect file permissions
25893bf9a009SRabin Vincent		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
25903bf9a009SRabin Vincent			my $permhere = $here . "FILE: $realfile\n";
259104db4d25SJoe Perches			if ($realfile !~ m@scripts/@ &&
259204db4d25SJoe Perches			    $realfile !~ /\.(py|pl|awk|sh)$/) {
2593000d1cc1SJoe Perches				ERROR("EXECUTE_PERMISSIONS",
2594000d1cc1SJoe Perches				      "do not set execute permissions for source files\n" . $permhere);
25953bf9a009SRabin Vincent			}
25963bf9a009SRabin Vincent		}
25973bf9a009SRabin Vincent
2598cd261496SGeert Uytterhoeven# Check the patch for a From:
2599cd261496SGeert Uytterhoeven		if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
2600cd261496SGeert Uytterhoeven			$author = $1;
2601cd261496SGeert Uytterhoeven			$author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
2602cd261496SGeert Uytterhoeven			$author =~ s/"//g;
2603cd261496SGeert Uytterhoeven		}
2604cd261496SGeert Uytterhoeven
260520112475SJoe Perches# Check the patch for a signoff:
2606d8aaf121SAndy Whitcroft		if ($line =~ /^\s*signed-off-by:/i) {
26074a0df2efSAndy Whitcroft			$signoff++;
260815662b3eSJoe Perches			$in_commit_log = 0;
2609cd261496SGeert Uytterhoeven			if ($author ne '') {
2610cd261496SGeert Uytterhoeven				my $l = $line;
2611cd261496SGeert Uytterhoeven				$l =~ s/"//g;
2612cd261496SGeert Uytterhoeven				if ($l =~ /^\s*signed-off-by:\s*\Q$author\E/i) {
2613cd261496SGeert Uytterhoeven				    $authorsignoff = 1;
2614cd261496SGeert Uytterhoeven				}
2615cd261496SGeert Uytterhoeven			}
26160a920b5bSAndy Whitcroft		}
261720112475SJoe Perches
2618e0d975b1SJoe Perches# Check if MAINTAINERS is being updated.  If so, there's probably no need to
2619e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete
2620e0d975b1SJoe Perches		if ($line =~ /^\s*MAINTAINERS\s*\|/) {
2621e0d975b1SJoe Perches			$reported_maintainer_file = 1;
2622e0d975b1SJoe Perches		}
2623e0d975b1SJoe Perches
262420112475SJoe Perches# Check signature styles
2625270c49a0SJoe Perches		if (!$in_header_lines &&
2626ce0338dfSJoe Perches		    $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
262720112475SJoe Perches			my $space_before = $1;
262820112475SJoe Perches			my $sign_off = $2;
262920112475SJoe Perches			my $space_after = $3;
263020112475SJoe Perches			my $email = $4;
263120112475SJoe Perches			my $ucfirst_sign_off = ucfirst(lc($sign_off));
263220112475SJoe Perches
2633ce0338dfSJoe Perches			if ($sign_off !~ /$signature_tags/) {
2634ce0338dfSJoe Perches				WARN("BAD_SIGN_OFF",
2635ce0338dfSJoe Perches				     "Non-standard signature: $sign_off\n" . $herecurr);
2636ce0338dfSJoe Perches			}
263720112475SJoe Perches			if (defined $space_before && $space_before ne "") {
26383705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
26393705ce5bSJoe Perches					 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
26403705ce5bSJoe Perches				    $fix) {
2641194f66fcSJoe Perches					$fixed[$fixlinenr] =
26423705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
26433705ce5bSJoe Perches				}
264420112475SJoe Perches			}
264520112475SJoe Perches			if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
26463705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
26473705ce5bSJoe Perches					 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
26483705ce5bSJoe Perches				    $fix) {
2649194f66fcSJoe Perches					$fixed[$fixlinenr] =
26503705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
26513705ce5bSJoe Perches				}
26523705ce5bSJoe Perches
265320112475SJoe Perches			}
265420112475SJoe Perches			if (!defined $space_after || $space_after ne " ") {
26553705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
26563705ce5bSJoe Perches					 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
26573705ce5bSJoe Perches				    $fix) {
2658194f66fcSJoe Perches					$fixed[$fixlinenr] =
26593705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
26603705ce5bSJoe Perches				}
266120112475SJoe Perches			}
266220112475SJoe Perches
266320112475SJoe Perches			my ($email_name, $email_address, $comment) = parse_email($email);
266420112475SJoe Perches			my $suggested_email = format_email(($email_name, $email_address));
266520112475SJoe Perches			if ($suggested_email eq "") {
2666000d1cc1SJoe Perches				ERROR("BAD_SIGN_OFF",
2667000d1cc1SJoe Perches				      "Unrecognized email address: '$email'\n" . $herecurr);
266820112475SJoe Perches			} else {
266920112475SJoe Perches				my $dequoted = $suggested_email;
267020112475SJoe Perches				$dequoted =~ s/^"//;
267120112475SJoe Perches				$dequoted =~ s/" </ </;
267220112475SJoe Perches				# Don't force email to have quotes
267320112475SJoe Perches				# Allow just an angle bracketed address
267420112475SJoe Perches				if ("$dequoted$comment" ne $email &&
267520112475SJoe Perches				    "<$email_address>$comment" ne $email &&
267620112475SJoe Perches				    "$suggested_email$comment" ne $email) {
2677000d1cc1SJoe Perches					WARN("BAD_SIGN_OFF",
2678000d1cc1SJoe Perches					     "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
267920112475SJoe Perches				}
26800a920b5bSAndy Whitcroft			}
26817e51f197SJoe Perches
26827e51f197SJoe Perches# Check for duplicate signatures
26837e51f197SJoe Perches			my $sig_nospace = $line;
26847e51f197SJoe Perches			$sig_nospace =~ s/\s//g;
26857e51f197SJoe Perches			$sig_nospace = lc($sig_nospace);
26867e51f197SJoe Perches			if (defined $signatures{$sig_nospace}) {
26877e51f197SJoe Perches				WARN("BAD_SIGN_OFF",
26887e51f197SJoe Perches				     "Duplicate signature\n" . $herecurr);
26897e51f197SJoe Perches			} else {
26907e51f197SJoe Perches				$signatures{$sig_nospace} = 1;
26917e51f197SJoe Perches			}
26926c5d24eeSSean Christopherson
26936c5d24eeSSean Christopherson# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email
26946c5d24eeSSean Christopherson			if ($sign_off =~ /^co-developed-by:$/i) {
26956c5d24eeSSean Christopherson				if ($email eq $author) {
26966c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
26976c5d24eeSSean Christopherson					      "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline);
26986c5d24eeSSean Christopherson				}
26996c5d24eeSSean Christopherson				if (!defined $lines[$linenr]) {
27006c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
27016c5d24eeSSean Christopherson                                             "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline);
27026c5d24eeSSean Christopherson				} elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) {
27036c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
27046c5d24eeSSean Christopherson					     "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
27056c5d24eeSSean Christopherson				} elsif ($1 ne $email) {
27066c5d24eeSSean Christopherson					WARN("BAD_SIGN_OFF",
27076c5d24eeSSean Christopherson					     "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]);
27086c5d24eeSSean Christopherson				}
27096c5d24eeSSean Christopherson			}
27100a920b5bSAndy Whitcroft		}
27110a920b5bSAndy Whitcroft
2712a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned
2713a2fe16b9SJoe Perches		if ($in_header_lines &&
2714a2fe16b9SJoe Perches		    $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
2715a2fe16b9SJoe Perches			WARN("EMAIL_SUBJECT",
2716a2fe16b9SJoe Perches			     "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
2717a2fe16b9SJoe Perches		}
2718a2fe16b9SJoe Perches
27197ebd05efSChristopher Covington# Check for unwanted Gerrit info
27207ebd05efSChristopher Covington		if ($in_commit_log && $line =~ /^\s*change-id:/i) {
27217ebd05efSChristopher Covington			ERROR("GERRIT_CHANGE_ID",
27227ebd05efSChristopher Covington			      "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr);
27237ebd05efSChristopher Covington		}
27247ebd05efSChristopher Covington
2725369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump
2726369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
2727369c8dd3SJoe Perches		    ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
2728369c8dd3SJoe Perches		     $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
2729369c8dd3SJoe Perches					# timestamp
2730634cffccSJoe Perches		     $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) ||
2731634cffccSJoe Perches		     $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ ||
2732634cffccSJoe Perches		     $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) {
2733634cffccSJoe Perches					# stack dump address styles
2734369c8dd3SJoe Perches			$commit_log_possible_stack_dump = 1;
2735369c8dd3SJoe Perches		}
2736369c8dd3SJoe Perches
27372a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once
27382a076f40SJoe Perches		if ($in_commit_log && !$commit_log_long_line &&
2739bf4daf12SJoe Perches		    length($line) > 75 &&
2740bf4daf12SJoe Perches		    !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
2741bf4daf12SJoe Perches					# file delta changes
2742bf4daf12SJoe Perches		      $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||
2743bf4daf12SJoe Perches					# filename then :
2744bf4daf12SJoe Perches		      $line =~ /^\s*(?:Fixes:|Link:)/i ||
2745bf4daf12SJoe Perches					# A Fixes: or Link: line
2746bf4daf12SJoe Perches		      $commit_log_possible_stack_dump)) {
27472a076f40SJoe Perches			WARN("COMMIT_LOG_LONG_LINE",
27482a076f40SJoe Perches			     "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
27492a076f40SJoe Perches			$commit_log_long_line = 1;
27502a076f40SJoe Perches		}
27512a076f40SJoe Perches
2752bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found
2753bf4daf12SJoe Perches		if ($in_commit_log && $commit_log_possible_stack_dump &&
2754bf4daf12SJoe Perches		    $line =~ /^\s*$/) {
2755bf4daf12SJoe Perches			$commit_log_possible_stack_dump = 0;
2756bf4daf12SJoe Perches		}
2757bf4daf12SJoe Perches
27580d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions
2759369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
2760aab38f51SJoe Perches		    $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i &&
2761e882dbfcSWei Wang		    $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
2762fe043ea1SJoe Perches		    ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
2763aab38f51SJoe Perches		     ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
2764369c8dd3SJoe Perches		      $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
2765bf4daf12SJoe Perches		      $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
2766fe043ea1SJoe Perches			my $init_char = "c";
2767fe043ea1SJoe Perches			my $orig_commit = "";
27680d7835fcSJoe Perches			my $short = 1;
27690d7835fcSJoe Perches			my $long = 0;
27700d7835fcSJoe Perches			my $case = 1;
27710d7835fcSJoe Perches			my $space = 1;
27720d7835fcSJoe Perches			my $hasdesc = 0;
277319c146a6SJoe Perches			my $hasparens = 0;
27740d7835fcSJoe Perches			my $id = '0123456789ab';
27750d7835fcSJoe Perches			my $orig_desc = "commit description";
27760d7835fcSJoe Perches			my $description = "";
27770d7835fcSJoe Perches
2778fe043ea1SJoe Perches			if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
2779fe043ea1SJoe Perches				$init_char = $1;
2780fe043ea1SJoe Perches				$orig_commit = lc($2);
2781fe043ea1SJoe Perches			} elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {
2782fe043ea1SJoe Perches				$orig_commit = lc($1);
2783fe043ea1SJoe Perches			}
2784fe043ea1SJoe Perches
27850d7835fcSJoe Perches			$short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);
27860d7835fcSJoe Perches			$long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);
27870d7835fcSJoe Perches			$space = 0 if ($line =~ /\bcommit [0-9a-f]/i);
27880d7835fcSJoe Perches			$case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
27890d7835fcSJoe Perches			if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) {
27900d7835fcSJoe Perches				$orig_desc = $1;
279119c146a6SJoe Perches				$hasparens = 1;
27920d7835fcSJoe Perches			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i &&
27930d7835fcSJoe Perches				 defined $rawlines[$linenr] &&
27940d7835fcSJoe Perches				 $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) {
27950d7835fcSJoe Perches				$orig_desc = $1;
279619c146a6SJoe Perches				$hasparens = 1;
2797b671fde0SJoe Perches			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i &&
2798b671fde0SJoe Perches				 defined $rawlines[$linenr] &&
2799b671fde0SJoe Perches				 $rawlines[$linenr] =~ /^\s*[^"]+"\)/) {
2800b671fde0SJoe Perches				$line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i;
2801b671fde0SJoe Perches				$orig_desc = $1;
2802b671fde0SJoe Perches				$rawlines[$linenr] =~ /^\s*([^"]+)"\)/;
2803b671fde0SJoe Perches				$orig_desc .= " " . $1;
280419c146a6SJoe Perches				$hasparens = 1;
28050d7835fcSJoe Perches			}
28060d7835fcSJoe Perches
28070d7835fcSJoe Perches			($id, $description) = git_commit_info($orig_commit,
28080d7835fcSJoe Perches							      $id, $orig_desc);
28090d7835fcSJoe Perches
2810948b133aSHeinrich Schuchardt			if (defined($id) &&
2811948b133aSHeinrich Schuchardt			   ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) {
2812d311cd44SJoe Perches				ERROR("GIT_COMMIT_ID",
28130d7835fcSJoe Perches				      "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);
28140d7835fcSJoe Perches			}
2815d311cd44SJoe Perches		}
2816d311cd44SJoe Perches
281713f1937eSJoe Perches# Check for added, moved or deleted files
281813f1937eSJoe Perches		if (!$reported_maintainer_file && !$in_commit_log &&
281913f1937eSJoe Perches		    ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
282013f1937eSJoe Perches		     $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
282113f1937eSJoe Perches		     ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
282213f1937eSJoe Perches		      (defined($1) || defined($2))))) {
2823a82603a8SAndrew Jeffery			$is_patch = 1;
282413f1937eSJoe Perches			$reported_maintainer_file = 1;
282513f1937eSJoe Perches			WARN("FILE_PATH_CHANGES",
282613f1937eSJoe Perches			     "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
282713f1937eSJoe Perches		}
282813f1937eSJoe Perches
282900df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file
28308905a67cSAndy Whitcroft		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
2831000d1cc1SJoe Perches			ERROR("CORRUPTED_PATCH",
2832000d1cc1SJoe Perches			      "patch seems to be corrupt (line wrapped?)\n" .
28336c72ffaaSAndy Whitcroft				$herecurr) if (!$emitted_corrupt++);
2834de7d4f0eSAndy Whitcroft		}
2835de7d4f0eSAndy Whitcroft
2836de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
2837de7d4f0eSAndy Whitcroft		if (($realfile =~ /^$/ || $line =~ /^\+/) &&
2838171ae1a4SAndy Whitcroft		    $rawline !~ m/^$UTF8*$/) {
2839171ae1a4SAndy Whitcroft			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
2840171ae1a4SAndy Whitcroft
2841171ae1a4SAndy Whitcroft			my $blank = copy_spacing($rawline);
2842171ae1a4SAndy Whitcroft			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
2843171ae1a4SAndy Whitcroft			my $hereptr = "$hereline$ptr\n";
2844171ae1a4SAndy Whitcroft
284534d99219SJoe Perches			CHK("INVALID_UTF8",
2846000d1cc1SJoe Perches			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
284700df344fSAndy Whitcroft		}
28480a920b5bSAndy Whitcroft
284915662b3eSJoe Perches# Check if it's the start of a commit log
285015662b3eSJoe Perches# (not a header line and we haven't seen the patch filename)
285115662b3eSJoe Perches		if ($in_header_lines && $realfile =~ /^$/ &&
2852eb3a58deSJoe Perches		    !($rawline =~ /^\s+(?:\S|$)/ ||
2853eb3a58deSJoe Perches		      $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
285415662b3eSJoe Perches			$in_header_lines = 0;
285515662b3eSJoe Perches			$in_commit_log = 1;
2856ed43c4e5SAllen Hubbe			$has_commit_log = 1;
285715662b3eSJoe Perches		}
285815662b3eSJoe Perches
2859fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly
2860fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing.
2861fa64205dSPasi Savanainen		if ($in_header_lines &&
2862fa64205dSPasi Savanainen		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
2863fa64205dSPasi Savanainen		    $1 !~ /utf-8/i) {
2864fa64205dSPasi Savanainen			$non_utf8_charset = 1;
2865fa64205dSPasi Savanainen		}
2866fa64205dSPasi Savanainen
2867fa64205dSPasi Savanainen		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
286815662b3eSJoe Perches		    $rawline =~ /$NON_ASCII_UTF8/) {
2869fa64205dSPasi Savanainen			WARN("UTF8_BEFORE_PATCH",
287015662b3eSJoe Perches			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);
287115662b3eSJoe Perches		}
287215662b3eSJoe Perches
2873d6430f71SJoe Perches# Check for absolute kernel paths in commit message
2874d6430f71SJoe Perches		if ($tree && $in_commit_log) {
2875d6430f71SJoe Perches			while ($line =~ m{(?:^|\s)(/\S*)}g) {
2876d6430f71SJoe Perches				my $file = $1;
2877d6430f71SJoe Perches
2878d6430f71SJoe Perches				if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
2879d6430f71SJoe Perches				    check_absolute_file($1, $herecurr)) {
2880d6430f71SJoe Perches					#
2881d6430f71SJoe Perches				} else {
2882d6430f71SJoe Perches					check_absolute_file($file, $herecurr);
2883d6430f71SJoe Perches				}
2884d6430f71SJoe Perches			}
2885d6430f71SJoe Perches		}
2886d6430f71SJoe Perches
288766b47b4aSKees Cook# Check for various typo / spelling mistakes
288866d7a382SJoe Perches		if (defined($misspellings) &&
288966d7a382SJoe Perches		    ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
2890ebfd7d62SJoe Perches			while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) {
289166b47b4aSKees Cook				my $typo = $1;
289266b47b4aSKees Cook				my $typo_fix = $spelling_fix{lc($typo)};
289366b47b4aSKees Cook				$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
289466b47b4aSKees Cook				$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
28950675a8fbSJean Delvare				my $msg_level = \&WARN;
28960675a8fbSJean Delvare				$msg_level = \&CHK if ($file);
28970675a8fbSJean Delvare				if (&{$msg_level}("TYPO_SPELLING",
289866b47b4aSKees Cook						  "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) &&
289966b47b4aSKees Cook				    $fix) {
290066b47b4aSKees Cook					$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
290166b47b4aSKees Cook				}
290266b47b4aSKees Cook			}
290366b47b4aSKees Cook		}
290466b47b4aSKees Cook
2905a8dd86bfSMatteo Croce# check for invalid commit id
2906a8dd86bfSMatteo Croce		if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) {
2907a8dd86bfSMatteo Croce			my $id;
2908a8dd86bfSMatteo Croce			my $description;
2909a8dd86bfSMatteo Croce			($id, $description) = git_commit_info($2, undef, undef);
2910a8dd86bfSMatteo Croce			if (!defined($id)) {
2911a8dd86bfSMatteo Croce				WARN("UNKNOWN_COMMIT_ID",
2912a8dd86bfSMatteo Croce				     "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr);
2913a8dd86bfSMatteo Croce			}
2914a8dd86bfSMatteo Croce		}
2915a8dd86bfSMatteo Croce
291630670854SAndy Whitcroft# ignore non-hunk lines and lines being removed
291730670854SAndy Whitcroft		next if (!$hunk_line || $line =~ /^-/);
291800df344fSAndy Whitcroft
29190a920b5bSAndy Whitcroft#trailing whitespace
29209c0ca6f9SAndy Whitcroft		if ($line =~ /^\+.*\015/) {
2921c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2922d5e616fcSJoe Perches			if (ERROR("DOS_LINE_ENDINGS",
2923d5e616fcSJoe Perches				  "DOS line endings\n" . $herevet) &&
2924d5e616fcSJoe Perches			    $fix) {
2925194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/[\s\015]+$//;
2926d5e616fcSJoe Perches			}
2927c2fdda0dSAndy Whitcroft		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
2928c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
29293705ce5bSJoe Perches			if (ERROR("TRAILING_WHITESPACE",
29303705ce5bSJoe Perches				  "trailing whitespace\n" . $herevet) &&
29313705ce5bSJoe Perches			    $fix) {
2932194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
29333705ce5bSJoe Perches			}
29343705ce5bSJoe Perches
2935d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
29360a920b5bSAndy Whitcroft		}
29375368df20SAndy Whitcroft
29384783f894SJosh Triplett# Check for FSF mailing addresses.
2939109d8cb2SAlexander Duyck		if ($rawline =~ /\bwrite to the Free/i ||
29401bde561eSMatthew Wilcox		    $rawline =~ /\b675\s+Mass\s+Ave/i ||
29413e2232f2SJoe Perches		    $rawline =~ /\b59\s+Temple\s+Pl/i ||
29423e2232f2SJoe Perches		    $rawline =~ /\b51\s+Franklin\s+St/i) {
29434783f894SJosh Triplett			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
29440675a8fbSJean Delvare			my $msg_level = \&ERROR;
29450675a8fbSJean Delvare			$msg_level = \&CHK if ($file);
29460675a8fbSJean Delvare			&{$msg_level}("FSF_MAILING_ADDRESS",
29474783f894SJosh 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)
29484783f894SJosh Triplett		}
29494783f894SJosh Triplett
29503354957aSAndi Kleen# check for Kconfig help text having a real description
29519fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have
29529fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough.
29533354957aSAndi Kleen		if ($realfile =~ /Kconfig/ &&
2954678ae162SUlf Magnusson		    # 'choice' is usually the last thing on the line (though
2955678ae162SUlf Magnusson		    # Kconfig supports named choices), so use a word boundary
2956678ae162SUlf Magnusson		    # (\b) rather than a whitespace character (\s)
2957678ae162SUlf Magnusson		    $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
29583354957aSAndi Kleen			my $length = 0;
29599fe287d7SAndy Whitcroft			my $cnt = $realcnt;
29609fe287d7SAndy Whitcroft			my $ln = $linenr + 1;
29619fe287d7SAndy Whitcroft			my $f;
2962a1385803SAndy Whitcroft			my $is_start = 0;
29639fe287d7SAndy Whitcroft			my $is_end = 0;
2964a1385803SAndy Whitcroft			for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
29659fe287d7SAndy Whitcroft				$f = $lines[$ln - 1];
29669fe287d7SAndy Whitcroft				$cnt-- if ($lines[$ln - 1] !~ /^-/);
29679fe287d7SAndy Whitcroft				$is_end = $lines[$ln - 1] =~ /^\+/;
29689fe287d7SAndy Whitcroft
29699fe287d7SAndy Whitcroft				next if ($f =~ /^-/);
29708d73e0e7SJoe Perches				last if (!$file && $f =~ /^\@\@/);
2971a1385803SAndy Whitcroft
297286adf1a0SUlf Magnusson				if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
2973a1385803SAndy Whitcroft					$is_start = 1;
297484af7a61SUlf Magnusson				} elsif ($lines[$ln - 1] =~ /^\+\s*(?:help|---help---)\s*$/) {
297584af7a61SUlf Magnusson					if ($lines[$ln - 1] =~ "---help---") {
297684af7a61SUlf Magnusson						WARN("CONFIG_DESCRIPTION",
297784af7a61SUlf Magnusson						     "prefer 'help' over '---help---' for new help texts\n" . $herecurr);
297884af7a61SUlf Magnusson					}
2979a1385803SAndy Whitcroft					$length = -1;
2980a1385803SAndy Whitcroft				}
2981a1385803SAndy Whitcroft
29829fe287d7SAndy Whitcroft				$f =~ s/^.//;
29833354957aSAndi Kleen				$f =~ s/#.*//;
29843354957aSAndi Kleen				$f =~ s/^\s+//;
29853354957aSAndi Kleen				next if ($f =~ /^$/);
2986678ae162SUlf Magnusson
2987678ae162SUlf Magnusson				# This only checks context lines in the patch
2988678ae162SUlf Magnusson				# and so hopefully shouldn't trigger false
2989678ae162SUlf Magnusson				# positives, even though some of these are
2990678ae162SUlf Magnusson				# common words in help texts
2991678ae162SUlf Magnusson				if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice|
2992678ae162SUlf Magnusson						  if|endif|menu|endmenu|source)\b/x) {
29939fe287d7SAndy Whitcroft					$is_end = 1;
29949fe287d7SAndy Whitcroft					last;
29959fe287d7SAndy Whitcroft				}
29963354957aSAndi Kleen				$length++;
29973354957aSAndi Kleen			}
299856193274SVadim Bendebury			if ($is_start && $is_end && $length < $min_conf_desc_length) {
2999000d1cc1SJoe Perches				WARN("CONFIG_DESCRIPTION",
300056193274SVadim Bendebury				     "please write a paragraph that describes the config symbol fully\n" . $herecurr);
300156193274SVadim Bendebury			}
3002a1385803SAndy Whitcroft			#print "is_start<$is_start> is_end<$is_end> length<$length>\n";
30033354957aSAndi Kleen		}
30043354957aSAndi Kleen
3005628f91a2SJoe Perches# check for MAINTAINERS entries that don't have the right form
3006628f91a2SJoe Perches		if ($realfile =~ /^MAINTAINERS$/ &&
3007628f91a2SJoe Perches		    $rawline =~ /^\+[A-Z]:/ &&
3008628f91a2SJoe Perches		    $rawline !~ /^\+[A-Z]:\t\S/) {
3009628f91a2SJoe Perches			if (WARN("MAINTAINERS_STYLE",
3010628f91a2SJoe Perches				 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
3011628f91a2SJoe Perches			    $fix) {
3012628f91a2SJoe Perches				$fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
3013628f91a2SJoe Perches			}
3014628f91a2SJoe Perches		}
3015628f91a2SJoe Perches
3016327953e9SChristoph Jaeger# discourage the use of boolean for type definition attributes of Kconfig options
3017327953e9SChristoph Jaeger		if ($realfile =~ /Kconfig/ &&
3018327953e9SChristoph Jaeger		    $line =~ /^\+\s*\bboolean\b/) {
3019327953e9SChristoph Jaeger			WARN("CONFIG_TYPE_BOOLEAN",
3020327953e9SChristoph Jaeger			     "Use of boolean is deprecated, please use bool instead.\n" . $herecurr);
3021327953e9SChristoph Jaeger		}
3022327953e9SChristoph Jaeger
3023c68e5878SArnaud Lacombe		if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
3024c68e5878SArnaud Lacombe		    ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
3025c68e5878SArnaud Lacombe			my $flag = $1;
3026c68e5878SArnaud Lacombe			my $replacement = {
3027c68e5878SArnaud Lacombe				'EXTRA_AFLAGS' =>   'asflags-y',
3028c68e5878SArnaud Lacombe				'EXTRA_CFLAGS' =>   'ccflags-y',
3029c68e5878SArnaud Lacombe				'EXTRA_CPPFLAGS' => 'cppflags-y',
3030c68e5878SArnaud Lacombe				'EXTRA_LDFLAGS' =>  'ldflags-y',
3031c68e5878SArnaud Lacombe			};
3032c68e5878SArnaud Lacombe
3033c68e5878SArnaud Lacombe			WARN("DEPRECATED_VARIABLE",
3034c68e5878SArnaud Lacombe			     "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
3035c68e5878SArnaud Lacombe		}
3036c68e5878SArnaud Lacombe
3037bff5da43SRob Herring# check for DT compatible documentation
30387dd05b38SFlorian Vaussard		if (defined $root &&
30397dd05b38SFlorian Vaussard			(($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
30407dd05b38SFlorian Vaussard			 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
30417dd05b38SFlorian Vaussard
3042bff5da43SRob Herring			my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
3043bff5da43SRob Herring
3044cc93319bSFlorian Vaussard			my $dt_path = $root . "/Documentation/devicetree/bindings/";
3045852d095dSRob Herring			my $vp_file = $dt_path . "vendor-prefixes.yaml";
3046cc93319bSFlorian Vaussard
3047bff5da43SRob Herring			foreach my $compat (@compats) {
3048bff5da43SRob Herring				my $compat2 = $compat;
3049185d566bSRob Herring				$compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
3050185d566bSRob Herring				my $compat3 = $compat;
3051185d566bSRob Herring				$compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
3052185d566bSRob Herring				`grep -Erq "$compat|$compat2|$compat3" $dt_path`;
3053bff5da43SRob Herring				if ( $? >> 8 ) {
3054bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
3055bff5da43SRob Herring					     "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
3056bff5da43SRob Herring				}
3057bff5da43SRob Herring
30584fbf32a6SFlorian Vaussard				next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
30594fbf32a6SFlorian Vaussard				my $vendor = $1;
3060852d095dSRob Herring				`grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`;
3061bff5da43SRob Herring				if ( $? >> 8 ) {
3062bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
3063cc93319bSFlorian Vaussard					     "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
3064bff5da43SRob Herring				}
3065bff5da43SRob Herring			}
3066bff5da43SRob Herring		}
3067bff5da43SRob Herring
30689f3a8992SRob Herring# check for using SPDX license tag at beginning of files
30699f3a8992SRob Herring		if ($realline == $checklicenseline) {
30709f3a8992SRob Herring			if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {
30719f3a8992SRob Herring				$checklicenseline = 2;
30729f3a8992SRob Herring			} elsif ($rawline =~ /^\+/) {
30739f3a8992SRob Herring				my $comment = "";
30749f3a8992SRob Herring				if ($realfile =~ /\.(h|s|S)$/) {
30759f3a8992SRob Herring					$comment = '/*';
30769f3a8992SRob Herring				} elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
30779f3a8992SRob Herring					$comment = '//';
30789f3a8992SRob Herring				} elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc)$/) {
30799f3a8992SRob Herring					$comment = '#';
30809f3a8992SRob Herring				} elsif ($realfile =~ /\.rst$/) {
30819f3a8992SRob Herring					$comment = '..';
30829f3a8992SRob Herring				}
30839f3a8992SRob Herring
3084fdf13693SJoe Perches# check SPDX comment style for .[chsS] files
3085fdf13693SJoe Perches				if ($realfile =~ /\.[chsS]$/ &&
3086fdf13693SJoe Perches				    $rawline =~ /SPDX-License-Identifier:/ &&
3087ffbce897SJoe Perches				    $rawline !~ m@^\+\s*\Q$comment\E\s*@) {
3088fdf13693SJoe Perches					WARN("SPDX_LICENSE_TAG",
3089fdf13693SJoe Perches					     "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);
3090fdf13693SJoe Perches				}
3091fdf13693SJoe Perches
30929f3a8992SRob Herring				if ($comment !~ /^$/ &&
3093ffbce897SJoe Perches				    $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) {
30949f3a8992SRob Herring					WARN("SPDX_LICENSE_TAG",
30959f3a8992SRob Herring					     "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
30963b6e8ac9SJoe Perches				} elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
30973b6e8ac9SJoe Perches					my $spdx_license = $1;
30983b6e8ac9SJoe Perches					if (!is_SPDX_License_valid($spdx_license)) {
30993b6e8ac9SJoe Perches						WARN("SPDX_LICENSE_TAG",
31003b6e8ac9SJoe Perches						     "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
31013b6e8ac9SJoe Perches					}
31029f3a8992SRob Herring				}
31039f3a8992SRob Herring			}
31049f3a8992SRob Herring		}
31059f3a8992SRob Herring
31065368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk
3107d6430f71SJoe Perches		next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
31085368df20SAndy Whitcroft
3109a8da38a9SJoe Perches# check for using SPDX-License-Identifier on the wrong line number
3110a8da38a9SJoe Perches		if ($realline != $checklicenseline &&
3111a8da38a9SJoe Perches		    $rawline =~ /\bSPDX-License-Identifier:/ &&
3112a8da38a9SJoe Perches		    substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {
3113a8da38a9SJoe Perches			WARN("SPDX_LICENSE_TAG",
3114a8da38a9SJoe Perches			     "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);
3115a8da38a9SJoe Perches		}
3116a8da38a9SJoe Perches
311747e0c88bSJoe Perches# line length limit (with some exclusions)
311847e0c88bSJoe Perches#
311947e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length:
312047e0c88bSJoe Perches#	logging functions like pr_info that end in a string
312147e0c88bSJoe Perches#	lines with a single string
312247e0c88bSJoe Perches#	#defines that are a single string
31232e4bbbc5SAndreas Brauchli#	lines with an RFC3986 like URL
312447e0c88bSJoe Perches#
312547e0c88bSJoe Perches# There are 3 different line length message types:
3126ab1ecabfSJean Delvare# LONG_LINE_COMMENT	a comment starts before but extends beyond $max_line_length
312747e0c88bSJoe Perches# LONG_LINE_STRING	a string starts before but extends beyond $max_line_length
312847e0c88bSJoe Perches# LONG_LINE		all other lines longer than $max_line_length
312947e0c88bSJoe Perches#
313047e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored
313147e0c88bSJoe Perches#
313247e0c88bSJoe Perches
3133b4749e96SJoe Perches		if ($line =~ /^\+/ && $length > $max_line_length) {
313447e0c88bSJoe Perches			my $msg_type = "LONG_LINE";
313547e0c88bSJoe Perches
313647e0c88bSJoe Perches			# Check the allowed long line types first
313747e0c88bSJoe Perches
313847e0c88bSJoe Perches			# logging functions that end in a string that starts
313947e0c88bSJoe Perches			# before $max_line_length
314047e0c88bSJoe Perches			if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
314147e0c88bSJoe Perches			    length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
314247e0c88bSJoe Perches				$msg_type = "";
314347e0c88bSJoe Perches
314447e0c88bSJoe Perches			# lines with only strings (w/ possible termination)
314547e0c88bSJoe Perches			# #defines with only strings
314647e0c88bSJoe Perches			} elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
314747e0c88bSJoe Perches				 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
314847e0c88bSJoe Perches				$msg_type = "";
314947e0c88bSJoe Perches
3150cc147506SJoe Perches			# More special cases
3151cc147506SJoe Perches			} elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ ||
3152cc147506SJoe Perches				 $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
3153d560a5f8SJoe Perches				$msg_type = "";
3154d560a5f8SJoe Perches
31552e4bbbc5SAndreas Brauchli			# URL ($rawline is used in case the URL is in a comment)
31562e4bbbc5SAndreas Brauchli			} elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
31572e4bbbc5SAndreas Brauchli				$msg_type = "";
31582e4bbbc5SAndreas Brauchli
315947e0c88bSJoe Perches			# Otherwise set the alternate message types
316047e0c88bSJoe Perches
316147e0c88bSJoe Perches			# a comment starts before $max_line_length
316247e0c88bSJoe Perches			} elsif ($line =~ /($;[\s$;]*)$/ &&
316347e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
316447e0c88bSJoe Perches				$msg_type = "LONG_LINE_COMMENT"
316547e0c88bSJoe Perches
316647e0c88bSJoe Perches			# a quoted string starts before $max_line_length
316747e0c88bSJoe Perches			} elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
316847e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
316947e0c88bSJoe Perches				$msg_type = "LONG_LINE_STRING"
317047e0c88bSJoe Perches			}
317147e0c88bSJoe Perches
317247e0c88bSJoe Perches			if ($msg_type ne "" &&
317347e0c88bSJoe Perches			    (show_type("LONG_LINE") || show_type($msg_type))) {
317447e0c88bSJoe Perches				WARN($msg_type,
31756cd7f386SJoe Perches				     "line over $max_line_length characters\n" . $herecurr);
31760a920b5bSAndy Whitcroft			}
317747e0c88bSJoe Perches		}
31780a920b5bSAndy Whitcroft
31798905a67cSAndy Whitcroft# check for adding lines without a newline.
31808905a67cSAndy Whitcroft		if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
3181000d1cc1SJoe Perches			WARN("MISSING_EOF_NEWLINE",
3182000d1cc1SJoe Perches			     "adding a line without newline at end of file\n" . $herecurr);
31838905a67cSAndy Whitcroft		}
31848905a67cSAndy Whitcroft
3185b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk
3186de4c924cSGeert Uytterhoeven		next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
31870a920b5bSAndy Whitcroft
31880a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything
31890a920b5bSAndy Whitcroft# more than 8 must use tabs.
3190c2fdda0dSAndy Whitcroft		if ($rawline =~ /^\+\s* \t\s*\S/ ||
3191c2fdda0dSAndy Whitcroft		    $rawline =~ /^\+\s*        \s*/) {
3192c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3193d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
31943705ce5bSJoe Perches			if (ERROR("CODE_INDENT",
31953705ce5bSJoe Perches				  "code indent should use tabs where possible\n" . $herevet) &&
31963705ce5bSJoe Perches			    $fix) {
3197194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
31983705ce5bSJoe Perches			}
31990a920b5bSAndy Whitcroft		}
32000a920b5bSAndy Whitcroft
320108e44365SAlberto Panizzo# check for space before tabs.
320208e44365SAlberto Panizzo		if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
320308e44365SAlberto Panizzo			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
32043705ce5bSJoe Perches			if (WARN("SPACE_BEFORE_TAB",
32053705ce5bSJoe Perches				"please, no space before tabs\n" . $herevet) &&
32063705ce5bSJoe Perches			    $fix) {
3207194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
3208d2207ccbSJoe Perches					   s/(^\+.*) {8,8}\t/$1\t\t/) {}
3209194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
3210c76f4cb3SJoe Perches					   s/(^\+.*) +\t/$1\t/) {}
32113705ce5bSJoe Perches			}
321208e44365SAlberto Panizzo		}
321308e44365SAlberto Panizzo
32146a487211SJoe Perches# check for assignments on the start of a line
32156a487211SJoe Perches		if ($sline =~ /^\+\s+($Assignment)[^=]/) {
32166a487211SJoe Perches			CHK("ASSIGNMENT_CONTINUATIONS",
32176a487211SJoe Perches			    "Assignment operator '$1' should be on the previous line\n" . $hereprev);
32186a487211SJoe Perches		}
32196a487211SJoe Perches
3220d1fe9c09SJoe Perches# check for && or || at the start of a line
3221d1fe9c09SJoe Perches		if ($rawline =~ /^\+\s*(&&|\|\|)/) {
3222d1fe9c09SJoe Perches			CHK("LOGICAL_CONTINUATIONS",
3223d1fe9c09SJoe Perches			    "Logical continuations should be on the previous line\n" . $hereprev);
3224d1fe9c09SJoe Perches		}
3225d1fe9c09SJoe Perches
3226a91e8994SJoe Perches# check indentation starts on a tab stop
32275b57980dSJoe Perches		if ($perl_version_ok &&
3228bd49111fSJoe Perches		    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) {
3229a91e8994SJoe Perches			my $indent = length($1);
3230a91e8994SJoe Perches			if ($indent % 8) {
3231a91e8994SJoe Perches				if (WARN("TABSTOP",
3232a91e8994SJoe Perches					 "Statements should start on a tabstop\n" . $herecurr) &&
3233a91e8994SJoe Perches				    $fix) {
3234a91e8994SJoe Perches					$fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e;
3235a91e8994SJoe Perches				}
3236a91e8994SJoe Perches			}
3237a91e8994SJoe Perches		}
3238a91e8994SJoe Perches
3239d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line
32405b57980dSJoe Perches		if ($perl_version_ok &&
3241fd71f632SJoe Perches		    $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
3242d1fe9c09SJoe Perches			$prevline =~ /^\+(\t*)(.*)$/;
3243d1fe9c09SJoe Perches			my $oldindent = $1;
3244d1fe9c09SJoe Perches			my $rest = $2;
3245d1fe9c09SJoe Perches
3246d1fe9c09SJoe Perches			my $pos = pos_last_openparen($rest);
3247d1fe9c09SJoe Perches			if ($pos >= 0) {
3248b34a26f3SJoe Perches				$line =~ /^(\+| )([ \t]*)/;
3249b34a26f3SJoe Perches				my $newindent = $2;
3250d1fe9c09SJoe Perches
3251d1fe9c09SJoe Perches				my $goodtabindent = $oldindent .
3252d1fe9c09SJoe Perches					"\t" x ($pos / 8) .
3253d1fe9c09SJoe Perches					" "  x ($pos % 8);
3254d1fe9c09SJoe Perches				my $goodspaceindent = $oldindent . " "  x $pos;
3255d1fe9c09SJoe Perches
3256d1fe9c09SJoe Perches				if ($newindent ne $goodtabindent &&
3257d1fe9c09SJoe Perches				    $newindent ne $goodspaceindent) {
32583705ce5bSJoe Perches
32593705ce5bSJoe Perches					if (CHK("PARENTHESIS_ALIGNMENT",
32603705ce5bSJoe Perches						"Alignment should match open parenthesis\n" . $hereprev) &&
32613705ce5bSJoe Perches					    $fix && $line =~ /^\+/) {
3262194f66fcSJoe Perches						$fixed[$fixlinenr] =~
32633705ce5bSJoe Perches						    s/^\+[ \t]*/\+$goodtabindent/;
32643705ce5bSJoe Perches					}
3265d1fe9c09SJoe Perches				}
3266d1fe9c09SJoe Perches			}
3267d1fe9c09SJoe Perches		}
3268d1fe9c09SJoe Perches
32696ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar"
32706ab3a970SJoe Perches# avoid checking a few false positives:
32716ab3a970SJoe Perches#   "sizeof(<type>)" or "__alignof__(<type>)"
32726ab3a970SJoe Perches#   function pointer declarations like "(*foo)(int) = bar;"
32736ab3a970SJoe Perches#   structure definitions like "(struct foo) { 0 };"
32746ab3a970SJoe Perches#   multiline macros that define functions
32756ab3a970SJoe Perches#   known attributes or the __attribute__ keyword
32766ab3a970SJoe Perches		if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
32776ab3a970SJoe Perches		    (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
32783705ce5bSJoe Perches			if (CHK("SPACING",
3279f27c95dbSJoe Perches				"No space is necessary after a cast\n" . $herecurr) &&
32803705ce5bSJoe Perches			    $fix) {
3281194f66fcSJoe Perches				$fixed[$fixlinenr] =~
3282f27c95dbSJoe Perches				    s/(\(\s*$Type\s*\))[ \t]+/$1/;
32833705ce5bSJoe Perches			}
3284aad4f614SJoe Perches		}
3285aad4f614SJoe Perches
328686406b1cSJoe Perches# Block comment styles
328786406b1cSJoe Perches# Networking with an initial /*
328805880600SJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
3289fdb4bcd6SJoe Perches		    $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
329085ad978cSJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&
329185ad978cSJoe Perches		    $realline > 2) {
329205880600SJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
329305880600SJoe Perches			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
329405880600SJoe Perches		}
329505880600SJoe Perches
329686406b1cSJoe Perches# Block comments use * on subsequent lines
329786406b1cSJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
329886406b1cSJoe Perches		    $prevrawline =~ /^\+.*?\/\*/ &&		#starting /*
3299a605e32eSJoe Perches		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */
330061135e96SJoe Perches		    $rawline =~ /^\+/ &&			#line is new
3301a605e32eSJoe Perches		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *
330286406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
330386406b1cSJoe Perches			     "Block comments use * on subsequent lines\n" . $hereprev);
3304a605e32eSJoe Perches		}
3305a605e32eSJoe Perches
330686406b1cSJoe Perches# Block comments use */ on trailing lines
330786406b1cSJoe Perches		if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
3308c24f9f19SJoe Perches		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/
3309c24f9f19SJoe Perches		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/
3310c24f9f19SJoe Perches		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */
331186406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
331286406b1cSJoe Perches			     "Block comments use a trailing */ on a separate line\n" . $herecurr);
331305880600SJoe Perches		}
331405880600SJoe Perches
331508eb9b80SJoe Perches# Block comment * alignment
331608eb9b80SJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
3317af207524SJoe Perches		    $line =~ /^\+[ \t]*$;/ &&			#leading comment
3318af207524SJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&		#leading *
3319af207524SJoe Perches		    (($prevrawline =~ /^\+.*?\/\*/ &&		#leading /*
332008eb9b80SJoe Perches		      $prevrawline !~ /\*\/[ \t]*$/) ||		#no trailing */
3321af207524SJoe Perches		     $prevrawline =~ /^\+[ \t]*\*/)) {		#leading *
3322af207524SJoe Perches			my $oldindent;
332308eb9b80SJoe Perches			$prevrawline =~ m@^\+([ \t]*/?)\*@;
3324af207524SJoe Perches			if (defined($1)) {
3325af207524SJoe Perches				$oldindent = expand_tabs($1);
3326af207524SJoe Perches			} else {
3327af207524SJoe Perches				$prevrawline =~ m@^\+(.*/?)\*@;
3328af207524SJoe Perches				$oldindent = expand_tabs($1);
3329af207524SJoe Perches			}
333008eb9b80SJoe Perches			$rawline =~ m@^\+([ \t]*)\*@;
333108eb9b80SJoe Perches			my $newindent = $1;
333208eb9b80SJoe Perches			$newindent = expand_tabs($newindent);
3333af207524SJoe Perches			if (length($oldindent) ne length($newindent)) {
333408eb9b80SJoe Perches				WARN("BLOCK_COMMENT_STYLE",
333508eb9b80SJoe Perches				     "Block comments should align the * on each line\n" . $hereprev);
333608eb9b80SJoe Perches			}
333708eb9b80SJoe Perches		}
333808eb9b80SJoe Perches
33397f619191SJoe Perches# check for missing blank lines after struct/union declarations
33407f619191SJoe Perches# with exceptions for various attributes and macros
33417f619191SJoe Perches		if ($prevline =~ /^[\+ ]};?\s*$/ &&
33427f619191SJoe Perches		    $line =~ /^\+/ &&
33437f619191SJoe Perches		    !($line =~ /^\+\s*$/ ||
33447f619191SJoe Perches		      $line =~ /^\+\s*EXPORT_SYMBOL/ ||
33457f619191SJoe Perches		      $line =~ /^\+\s*MODULE_/i ||
33467f619191SJoe Perches		      $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
33477f619191SJoe Perches		      $line =~ /^\+[a-z_]*init/ ||
33487f619191SJoe Perches		      $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
33497f619191SJoe Perches		      $line =~ /^\+\s*DECLARE/ ||
33500bc989ffSMasahiro Yamada		      $line =~ /^\+\s*builtin_[\w_]*driver/ ||
33517f619191SJoe Perches		      $line =~ /^\+\s*__setup/)) {
3352d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
3353d752fcc8SJoe Perches				"Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
3354d752fcc8SJoe Perches			    $fix) {
3355f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, "\+");
3356d752fcc8SJoe Perches			}
33577f619191SJoe Perches		}
33587f619191SJoe Perches
3359365dd4eaSJoe Perches# check for multiple consecutive blank lines
3360365dd4eaSJoe Perches		if ($prevline =~ /^[\+ ]\s*$/ &&
3361365dd4eaSJoe Perches		    $line =~ /^\+\s*$/ &&
3362365dd4eaSJoe Perches		    $last_blank_line != ($linenr - 1)) {
3363d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
3364d752fcc8SJoe Perches				"Please don't use multiple blank lines\n" . $hereprev) &&
3365d752fcc8SJoe Perches			    $fix) {
3366f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
3367d752fcc8SJoe Perches			}
3368d752fcc8SJoe Perches
3369365dd4eaSJoe Perches			$last_blank_line = $linenr;
3370365dd4eaSJoe Perches		}
3371365dd4eaSJoe Perches
33723b617e3bSJoe Perches# check for missing blank lines after declarations
33733f7bac03SJoe Perches		if ($sline =~ /^\+\s+\S/ &&			#Not at char 1
33743f7bac03SJoe Perches			# actual declarations
33753f7bac03SJoe Perches		    ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
33765a4e1fd3SJoe Perches			# function pointer declarations
33775a4e1fd3SJoe Perches		     $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
33783f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
33793f7bac03SJoe Perches		     $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
33803f7bac03SJoe Perches			# known declaration macros
33813f7bac03SJoe Perches		     $prevline =~ /^\+\s+$declaration_macros/) &&
33823f7bac03SJoe Perches			# for "else if" which can look like "$Ident $Ident"
33833f7bac03SJoe Perches		    !($prevline =~ /^\+\s+$c90_Keywords\b/ ||
33843f7bac03SJoe Perches			# other possible extensions of declaration lines
33853f7bac03SJoe Perches		      $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
33863f7bac03SJoe Perches			# not starting a section or a macro "\" extended line
33873f7bac03SJoe Perches		      $prevline =~ /(?:\{\s*|\\)$/) &&
33883f7bac03SJoe Perches			# looks like a declaration
33893f7bac03SJoe Perches		    !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
33905a4e1fd3SJoe Perches			# function pointer declarations
33915a4e1fd3SJoe Perches		      $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
33923f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
33933f7bac03SJoe Perches		      $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
33943f7bac03SJoe Perches			# known declaration macros
33953f7bac03SJoe Perches		      $sline =~ /^\+\s+$declaration_macros/ ||
33963f7bac03SJoe Perches			# start of struct or union or enum
3397328b5f41SJoe Perches		      $sline =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ ||
33983f7bac03SJoe Perches			# start or end of block or continuation of declaration
33993f7bac03SJoe Perches		      $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
34003f7bac03SJoe Perches			# bitfield continuation
34013f7bac03SJoe Perches		      $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
34023f7bac03SJoe Perches			# other possible extensions of declaration lines
34033f7bac03SJoe Perches		      $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) &&
34043f7bac03SJoe Perches			# indentation of previous and current line are the same
34053f7bac03SJoe Perches		    (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) {
3406d752fcc8SJoe Perches			if (WARN("LINE_SPACING",
3407d752fcc8SJoe Perches				 "Missing a blank line after declarations\n" . $hereprev) &&
3408d752fcc8SJoe Perches			    $fix) {
3409f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, "\+");
3410d752fcc8SJoe Perches			}
34113b617e3bSJoe Perches		}
34123b617e3bSJoe Perches
34135f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line.
34146b4c5bebSAndy Whitcroft# Exceptions:
34156b4c5bebSAndy Whitcroft#  1) within comments
34166b4c5bebSAndy Whitcroft#  2) indented preprocessor commands
34176b4c5bebSAndy Whitcroft#  3) hanging labels
34183705ce5bSJoe Perches		if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/)  {
34195f7ddae6SRaffaele Recalcati			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
34203705ce5bSJoe Perches			if (WARN("LEADING_SPACE",
34213705ce5bSJoe Perches				 "please, no spaces at the start of a line\n" . $herevet) &&
34223705ce5bSJoe Perches			    $fix) {
3423194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
34243705ce5bSJoe Perches			}
34255f7ddae6SRaffaele Recalcati		}
34265f7ddae6SRaffaele Recalcati
3427b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk
3428b9ea10d6SAndy Whitcroft		next if ($realfile !~ /\.(h|c)$/);
3429b9ea10d6SAndy Whitcroft
34305751a24eSJoe Perches# check for unusual line ending [ or (
34315751a24eSJoe Perches		if ($line =~ /^\+.*([\[\(])\s*$/) {
34325751a24eSJoe Perches			CHK("OPEN_ENDED_LINE",
34335751a24eSJoe Perches			    "Lines should not end with a '$1'\n" . $herecurr);
34345751a24eSJoe Perches		}
34355751a24eSJoe Perches
34364dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name
34374dbed76fSJoe Perches		if ($sline =~ /^\+\{\s*$/ &&
34384dbed76fSJoe Perches		    $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
34394dbed76fSJoe Perches			$context_function = $1;
34404dbed76fSJoe Perches		}
34414dbed76fSJoe Perches
34424dbed76fSJoe Perches# check if this appears to be the end of function declaration
34434dbed76fSJoe Perches		if ($sline =~ /^\+\}\s*$/) {
34444dbed76fSJoe Perches			undef $context_function;
34454dbed76fSJoe Perches		}
34464dbed76fSJoe Perches
3447032a4c0fSJoe Perches# check indentation of any line with a bare else
3448840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;")
3449032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more...
3450032a4c0fSJoe Perches		if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
3451032a4c0fSJoe Perches			my $tabs = length($1) + 1;
3452840080a0SJoe Perches			if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
3453840080a0SJoe Perches			    ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
3454840080a0SJoe Perches			     defined $lines[$linenr] &&
3455840080a0SJoe Perches			     $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
3456032a4c0fSJoe Perches				WARN("UNNECESSARY_ELSE",
3457032a4c0fSJoe Perches				     "else is not generally useful after a break or return\n" . $hereprev);
3458032a4c0fSJoe Perches			}
3459032a4c0fSJoe Perches		}
3460032a4c0fSJoe Perches
3461c00df19aSJoe Perches# check indentation of a line with a break;
3462c00df19aSJoe Perches# if the previous line is a goto or return and is indented the same # of tabs
3463c00df19aSJoe Perches		if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
3464c00df19aSJoe Perches			my $tabs = $1;
3465c00df19aSJoe Perches			if ($prevline =~ /^\+$tabs(?:goto|return)\b/) {
3466c00df19aSJoe Perches				WARN("UNNECESSARY_BREAK",
3467c00df19aSJoe Perches				     "break is not useful after a goto or return\n" . $hereprev);
3468c00df19aSJoe Perches			}
3469c00df19aSJoe Perches		}
3470c00df19aSJoe Perches
3471c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers
3472cf655043SAndy Whitcroft		if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
3473000d1cc1SJoe Perches			WARN("CVS_KEYWORD",
3474000d1cc1SJoe Perches			     "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
3475c2fdda0dSAndy Whitcroft		}
347622f2a2efSAndy Whitcroft
347756e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings
347856e77d70SJoe Perches		if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
347956e77d70SJoe Perches			WARN("HOTPLUG_SECTION",
348056e77d70SJoe Perches			     "Using $1 is unnecessary\n" . $herecurr);
348156e77d70SJoe Perches		}
348256e77d70SJoe Perches
34839c0ca6f9SAndy Whitcroft# Check for potential 'bare' types
34842b474a1aSAndy Whitcroft		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
34852b474a1aSAndy Whitcroft		    $realline_next);
34863e469cdcSAndy Whitcroft#print "LINE<$line>\n";
3487ca819864SJoe Perches		if ($linenr > $suppress_statement &&
34881b5539b1SJoe Perches		    $realcnt && $sline =~ /.\s*\S/) {
3489170d3a22SAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
3490f5fe35ddSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
3491171ae1a4SAndy Whitcroft			$stat =~ s/\n./\n /g;
3492171ae1a4SAndy Whitcroft			$cond =~ s/\n./\n /g;
3493171ae1a4SAndy Whitcroft
34943e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n";
34953e469cdcSAndy Whitcroft			# If this statement has no statement boundaries within
34963e469cdcSAndy Whitcroft			# it there is no point in retrying a statement scan
34973e469cdcSAndy Whitcroft			# until we hit end of it.
34983e469cdcSAndy Whitcroft			my $frag = $stat; $frag =~ s/;+\s*$//;
34993e469cdcSAndy Whitcroft			if ($frag !~ /(?:{|;)/) {
35003e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n";
35013e469cdcSAndy Whitcroft				$suppress_statement = $line_nr_next;
35023e469cdcSAndy Whitcroft			}
3503f74bd194SAndy Whitcroft
35042b474a1aSAndy Whitcroft			# Find the real next line.
35052b474a1aSAndy Whitcroft			$realline_next = $line_nr_next;
35062b474a1aSAndy Whitcroft			if (defined $realline_next &&
35072b474a1aSAndy Whitcroft			    (!defined $lines[$realline_next - 1] ||
35082b474a1aSAndy Whitcroft			     substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
35092b474a1aSAndy Whitcroft				$realline_next++;
35102b474a1aSAndy Whitcroft			}
35112b474a1aSAndy Whitcroft
3512171ae1a4SAndy Whitcroft			my $s = $stat;
3513171ae1a4SAndy Whitcroft			$s =~ s/{.*$//s;
3514cf655043SAndy Whitcroft
3515c2fdda0dSAndy Whitcroft			# Ignore goto labels.
3516171ae1a4SAndy Whitcroft			if ($s =~ /$Ident:\*$/s) {
3517c2fdda0dSAndy Whitcroft
3518c2fdda0dSAndy Whitcroft			# Ignore functions being called
3519171ae1a4SAndy Whitcroft			} elsif ($s =~ /^.\s*$Ident\s*\(/s) {
3520c2fdda0dSAndy Whitcroft
3521463f2864SAndy Whitcroft			} elsif ($s =~ /^.\s*else\b/s) {
3522463f2864SAndy Whitcroft
3523c45dcabdSAndy Whitcroft			# declarations always start with types
3524d2506586SAndy 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) {
3525c45dcabdSAndy Whitcroft				my $type = $1;
3526c45dcabdSAndy Whitcroft				$type =~ s/\s+/ /g;
3527c45dcabdSAndy Whitcroft				possible($type, "A:" . $s);
3528c45dcabdSAndy Whitcroft
35296c72ffaaSAndy Whitcroft			# definitions in global scope can only start with types
3530a6a84062SAndy Whitcroft			} elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
3531c45dcabdSAndy Whitcroft				possible($1, "B:" . $s);
3532c2fdda0dSAndy Whitcroft			}
35338905a67cSAndy Whitcroft
35346c72ffaaSAndy Whitcroft			# any (foo ... *) is a pointer cast, and foo is a type
353565863862SAndy Whitcroft			while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
3536c45dcabdSAndy Whitcroft				possible($1, "C:" . $s);
35379c0ca6f9SAndy Whitcroft			}
35388905a67cSAndy Whitcroft
35398905a67cSAndy Whitcroft			# Check for any sort of function declaration.
35408905a67cSAndy Whitcroft			# int foo(something bar, other baz);
35418905a67cSAndy Whitcroft			# void (*store_gdt)(x86_descr_ptr *);
3542171ae1a4SAndy Whitcroft			if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
35438905a67cSAndy Whitcroft				my ($name_len) = length($1);
35448905a67cSAndy Whitcroft
3545cf655043SAndy Whitcroft				my $ctx = $s;
3546773647a0SAndy Whitcroft				substr($ctx, 0, $name_len + 1, '');
35478905a67cSAndy Whitcroft				$ctx =~ s/\)[^\)]*$//;
3548cf655043SAndy Whitcroft
35498905a67cSAndy Whitcroft				for my $arg (split(/\s*,\s*/, $ctx)) {
3550c45dcabdSAndy Whitcroft					if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
35518905a67cSAndy Whitcroft
3552c45dcabdSAndy Whitcroft						possible($1, "D:" . $s);
35538905a67cSAndy Whitcroft					}
35548905a67cSAndy Whitcroft				}
35558905a67cSAndy Whitcroft			}
35568905a67cSAndy Whitcroft
35579c0ca6f9SAndy Whitcroft		}
35589c0ca6f9SAndy Whitcroft
355900df344fSAndy Whitcroft#
356000df344fSAndy Whitcroft# Checks which may be anchored in the context.
356100df344fSAndy Whitcroft#
356200df344fSAndy Whitcroft
356300df344fSAndy Whitcroft# Check for switch () and associated case and default
356400df344fSAndy Whitcroft# statements should be at the same indent.
356500df344fSAndy Whitcroft		if ($line=~/\bswitch\s*\(.*\)/) {
356600df344fSAndy Whitcroft			my $err = '';
356700df344fSAndy Whitcroft			my $sep = '';
356800df344fSAndy Whitcroft			my @ctx = ctx_block_outer($linenr, $realcnt);
356900df344fSAndy Whitcroft			shift(@ctx);
357000df344fSAndy Whitcroft			for my $ctx (@ctx) {
357100df344fSAndy Whitcroft				my ($clen, $cindent) = line_stats($ctx);
357200df344fSAndy Whitcroft				if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
357300df344fSAndy Whitcroft							$indent != $cindent) {
357400df344fSAndy Whitcroft					$err .= "$sep$ctx\n";
357500df344fSAndy Whitcroft					$sep = '';
357600df344fSAndy Whitcroft				} else {
357700df344fSAndy Whitcroft					$sep = "[...]\n";
357800df344fSAndy Whitcroft				}
357900df344fSAndy Whitcroft			}
358000df344fSAndy Whitcroft			if ($err ne '') {
3581000d1cc1SJoe Perches				ERROR("SWITCH_CASE_INDENT_LEVEL",
3582000d1cc1SJoe Perches				      "switch and case should be at the same indent\n$hereline$err");
3583de7d4f0eSAndy Whitcroft			}
3584de7d4f0eSAndy Whitcroft		}
3585de7d4f0eSAndy Whitcroft
3586de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop,
3587de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else
35880fe3dc2bSJoe Perches		if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
3589773647a0SAndy Whitcroft			my $pre_ctx = "$1$2";
3590773647a0SAndy Whitcroft
35919c0ca6f9SAndy Whitcroft			my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
35928eef05ddSJoe Perches
35938eef05ddSJoe Perches			if ($line =~ /^\+\t{6,}/) {
35948eef05ddSJoe Perches				WARN("DEEP_INDENTATION",
35958eef05ddSJoe Perches				     "Too many leading tabs - consider code refactoring\n" . $herecurr);
35968eef05ddSJoe Perches			}
35978eef05ddSJoe Perches
3598de7d4f0eSAndy Whitcroft			my $ctx_cnt = $realcnt - $#ctx - 1;
3599de7d4f0eSAndy Whitcroft			my $ctx = join("\n", @ctx);
3600de7d4f0eSAndy Whitcroft
3601548596d5SAndy Whitcroft			my $ctx_ln = $linenr;
3602548596d5SAndy Whitcroft			my $ctx_skip = $realcnt;
3603de7d4f0eSAndy Whitcroft
3604548596d5SAndy Whitcroft			while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
3605548596d5SAndy Whitcroft					defined $lines[$ctx_ln - 1] &&
3606548596d5SAndy Whitcroft					$lines[$ctx_ln - 1] =~ /^-/)) {
3607548596d5SAndy Whitcroft				##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
3608548596d5SAndy Whitcroft				$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
3609773647a0SAndy Whitcroft				$ctx_ln++;
3610773647a0SAndy Whitcroft			}
3611548596d5SAndy Whitcroft
361253210168SAndy Whitcroft			#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
361353210168SAndy Whitcroft			#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
3614773647a0SAndy Whitcroft
3615773647a0SAndy Whitcroft			if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
3616000d1cc1SJoe Perches				ERROR("OPEN_BRACE",
3617000d1cc1SJoe Perches				      "that open brace { should be on the previous line\n" .
361801464f30SAndy Whitcroft					"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
361900df344fSAndy Whitcroft			}
3620773647a0SAndy Whitcroft			if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
3621773647a0SAndy Whitcroft			    $ctx =~ /\)\s*\;\s*$/ &&
3622773647a0SAndy Whitcroft			    defined $lines[$ctx_ln - 1])
3623773647a0SAndy Whitcroft			{
36249c0ca6f9SAndy Whitcroft				my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
36259c0ca6f9SAndy Whitcroft				if ($nindent > $indent) {
3626000d1cc1SJoe Perches					WARN("TRAILING_SEMICOLON",
3627000d1cc1SJoe Perches					     "trailing semicolon indicates no statements, indent implies otherwise\n" .
362801464f30SAndy Whitcroft						"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
36299c0ca6f9SAndy Whitcroft				}
36309c0ca6f9SAndy Whitcroft			}
363100df344fSAndy Whitcroft		}
363200df344fSAndy Whitcroft
36334d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks.
3634f6950a73SJoe Perches		if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
36353e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
36363e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
36373e469cdcSAndy Whitcroft					if (!defined $stat);
36384d001e4dSAndy Whitcroft			my ($s, $c) = ($stat, $cond);
36394d001e4dSAndy Whitcroft
36404d001e4dSAndy Whitcroft			substr($s, 0, length($c), '');
36414d001e4dSAndy Whitcroft
36429f5af480SJoe Perches			# remove inline comments
36439f5af480SJoe Perches			$s =~ s/$;/ /g;
36449f5af480SJoe Perches			$c =~ s/$;/ /g;
36454d001e4dSAndy Whitcroft
36464d001e4dSAndy Whitcroft			# Find out how long the conditional actually is.
36476f779c18SAndy Whitcroft			my @newlines = ($c =~ /\n/gs);
36486f779c18SAndy Whitcroft			my $cond_lines = 1 + $#newlines;
36494d001e4dSAndy Whitcroft
36509f5af480SJoe Perches			# Make sure we remove the line prefixes as we have
36519f5af480SJoe Perches			# none on the first line, and are going to readd them
36529f5af480SJoe Perches			# where necessary.
36539f5af480SJoe Perches			$s =~ s/\n./\n/gs;
36549f5af480SJoe Perches			while ($s =~ /\n\s+\\\n/) {
36559f5af480SJoe Perches				$cond_lines += $s =~ s/\n\s+\\\n/\n/g;
36569f5af480SJoe Perches			}
36579f5af480SJoe Perches
36584d001e4dSAndy Whitcroft			# We want to check the first line inside the block
36594d001e4dSAndy Whitcroft			# starting at the end of the conditional, so remove:
36604d001e4dSAndy Whitcroft			#  1) any blank line termination
36614d001e4dSAndy Whitcroft			#  2) any opening brace { on end of the line
36624d001e4dSAndy Whitcroft			#  3) any do (...) {
36634d001e4dSAndy Whitcroft			my $continuation = 0;
36644d001e4dSAndy Whitcroft			my $check = 0;
36654d001e4dSAndy Whitcroft			$s =~ s/^.*\bdo\b//;
36664d001e4dSAndy Whitcroft			$s =~ s/^\s*{//;
36674d001e4dSAndy Whitcroft			if ($s =~ s/^\s*\\//) {
36684d001e4dSAndy Whitcroft				$continuation = 1;
36694d001e4dSAndy Whitcroft			}
36709bd49efeSAndy Whitcroft			if ($s =~ s/^\s*?\n//) {
36714d001e4dSAndy Whitcroft				$check = 1;
36724d001e4dSAndy Whitcroft				$cond_lines++;
36734d001e4dSAndy Whitcroft			}
36744d001e4dSAndy Whitcroft
36754d001e4dSAndy Whitcroft			# Also ignore a loop construct at the end of a
36764d001e4dSAndy Whitcroft			# preprocessor statement.
36774d001e4dSAndy Whitcroft			if (($prevline =~ /^.\s*#\s*define\s/ ||
36784d001e4dSAndy Whitcroft			    $prevline =~ /\\\s*$/) && $continuation == 0) {
36794d001e4dSAndy Whitcroft				$check = 0;
36804d001e4dSAndy Whitcroft			}
36814d001e4dSAndy Whitcroft
36829bd49efeSAndy Whitcroft			my $cond_ptr = -1;
3683740504c6SAndy Whitcroft			$continuation = 0;
36849bd49efeSAndy Whitcroft			while ($cond_ptr != $cond_lines) {
36859bd49efeSAndy Whitcroft				$cond_ptr = $cond_lines;
36864d001e4dSAndy Whitcroft
3687f16fa28fSAndy Whitcroft				# If we see an #else/#elif then the code
3688f16fa28fSAndy Whitcroft				# is not linear.
3689f16fa28fSAndy Whitcroft				if ($s =~ /^\s*\#\s*(?:else|elif)/) {
3690f16fa28fSAndy Whitcroft					$check = 0;
3691f16fa28fSAndy Whitcroft				}
3692f16fa28fSAndy Whitcroft
36939bd49efeSAndy Whitcroft				# Ignore:
36949bd49efeSAndy Whitcroft				#  1) blank lines, they should be at 0,
36959bd49efeSAndy Whitcroft				#  2) preprocessor lines, and
36969bd49efeSAndy Whitcroft				#  3) labels.
3697740504c6SAndy Whitcroft				if ($continuation ||
3698740504c6SAndy Whitcroft				    $s =~ /^\s*?\n/ ||
36999bd49efeSAndy Whitcroft				    $s =~ /^\s*#\s*?/ ||
37009bd49efeSAndy Whitcroft				    $s =~ /^\s*$Ident\s*:/) {
3701740504c6SAndy Whitcroft					$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
370230dad6ebSAndy Whitcroft					if ($s =~ s/^.*?\n//) {
37039bd49efeSAndy Whitcroft						$cond_lines++;
37049bd49efeSAndy Whitcroft					}
37054d001e4dSAndy Whitcroft				}
370630dad6ebSAndy Whitcroft			}
37074d001e4dSAndy Whitcroft
37084d001e4dSAndy Whitcroft			my (undef, $sindent) = line_stats("+" . $s);
37094d001e4dSAndy Whitcroft			my $stat_real = raw_line($linenr, $cond_lines);
37104d001e4dSAndy Whitcroft
37114d001e4dSAndy Whitcroft			# Check if either of these lines are modified, else
37124d001e4dSAndy Whitcroft			# this is not this patch's fault.
37134d001e4dSAndy Whitcroft			if (!defined($stat_real) ||
37144d001e4dSAndy Whitcroft			    $stat !~ /^\+/ && $stat_real !~ /^\+/) {
37154d001e4dSAndy Whitcroft				$check = 0;
37164d001e4dSAndy Whitcroft			}
37174d001e4dSAndy Whitcroft			if (defined($stat_real) && $cond_lines > 1) {
37184d001e4dSAndy Whitcroft				$stat_real = "[...]\n$stat_real";
37194d001e4dSAndy Whitcroft			}
37204d001e4dSAndy Whitcroft
37219bd49efeSAndy 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";
37224d001e4dSAndy Whitcroft
37239f5af480SJoe Perches			if ($check && $s ne '' &&
37249f5af480SJoe Perches			    (($sindent % 8) != 0 ||
37259f5af480SJoe Perches			     ($sindent < $indent) ||
3726f6950a73SJoe Perches			     ($sindent == $indent &&
3727f6950a73SJoe Perches			      ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
37289f5af480SJoe Perches			     ($sindent > $indent + 8))) {
3729000d1cc1SJoe Perches				WARN("SUSPECT_CODE_INDENT",
3730000d1cc1SJoe Perches				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
37314d001e4dSAndy Whitcroft			}
37324d001e4dSAndy Whitcroft		}
37334d001e4dSAndy Whitcroft
37346c72ffaaSAndy Whitcroft		# Track the 'values' across context and added lines.
37356c72ffaaSAndy Whitcroft		my $opline = $line; $opline =~ s/^./ /;
37361f65f947SAndy Whitcroft		my ($curr_values, $curr_vars) =
37371f65f947SAndy Whitcroft				annotate_values($opline . "\n", $prev_values);
37386c72ffaaSAndy Whitcroft		$curr_values = $prev_values . $curr_values;
3739c2fdda0dSAndy Whitcroft		if ($dbg_values) {
3740c2fdda0dSAndy Whitcroft			my $outline = $opline; $outline =~ s/\t/ /g;
3741cf655043SAndy Whitcroft			print "$linenr > .$outline\n";
3742cf655043SAndy Whitcroft			print "$linenr > $curr_values\n";
37431f65f947SAndy Whitcroft			print "$linenr >  $curr_vars\n";
3744c2fdda0dSAndy Whitcroft		}
37456c72ffaaSAndy Whitcroft		$prev_values = substr($curr_values, -1);
37466c72ffaaSAndy Whitcroft
374700df344fSAndy Whitcroft#ignore lines not being added
37483705ce5bSJoe Perches		next if ($line =~ /^[^\+]/);
374900df344fSAndy Whitcroft
375011ca40a0SJoe Perches# check for dereferences that span multiple lines
375111ca40a0SJoe Perches		if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
375211ca40a0SJoe Perches		    $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
375311ca40a0SJoe Perches			$prevline =~ /($Lval\s*(?:\.|->))\s*$/;
375411ca40a0SJoe Perches			my $ref = $1;
375511ca40a0SJoe Perches			$line =~ /^.\s*($Lval)/;
375611ca40a0SJoe Perches			$ref .= $1;
375711ca40a0SJoe Perches			$ref =~ s/\s//g;
375811ca40a0SJoe Perches			WARN("MULTILINE_DEREFERENCE",
375911ca40a0SJoe Perches			     "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
376011ca40a0SJoe Perches		}
376111ca40a0SJoe Perches
3762a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int
3763c8447115SJoe Perches		while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
3764a1ce18e4SJoe Perches			my $type = $1;
3765a1ce18e4SJoe Perches			my $var = $2;
3766207a8e84SJoe Perches			$var = "" if (!defined $var);
3767207a8e84SJoe Perches			if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
3768a1ce18e4SJoe Perches				my $sign = $1;
3769a1ce18e4SJoe Perches				my $pointer = $2;
3770a1ce18e4SJoe Perches
3771a1ce18e4SJoe Perches				$pointer = "" if (!defined $pointer);
3772a1ce18e4SJoe Perches
3773a1ce18e4SJoe Perches				if (WARN("UNSPECIFIED_INT",
3774a1ce18e4SJoe Perches					 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
3775a1ce18e4SJoe Perches				    $fix) {
3776a1ce18e4SJoe Perches					my $decl = trim($sign) . " int ";
3777207a8e84SJoe Perches					my $comp_pointer = $pointer;
3778207a8e84SJoe Perches					$comp_pointer =~ s/\s//g;
3779207a8e84SJoe Perches					$decl .= $comp_pointer;
3780207a8e84SJoe Perches					$decl = rtrim($decl) if ($var eq "");
3781207a8e84SJoe Perches					$fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
3782a1ce18e4SJoe Perches				}
3783a1ce18e4SJoe Perches			}
3784a1ce18e4SJoe Perches		}
3785a1ce18e4SJoe Perches
3786653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher.
37877429c690SAndy Whitcroft		if ($dbg_type) {
37887429c690SAndy Whitcroft			if ($line =~ /^.\s*$Declare\s*$/) {
3789000d1cc1SJoe Perches				ERROR("TEST_TYPE",
3790000d1cc1SJoe Perches				      "TEST: is type\n" . $herecurr);
37917429c690SAndy Whitcroft			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
3792000d1cc1SJoe Perches				ERROR("TEST_NOT_TYPE",
3793000d1cc1SJoe Perches				      "TEST: is not type ($1 is)\n". $herecurr);
37947429c690SAndy Whitcroft			}
3795653d4876SAndy Whitcroft			next;
3796653d4876SAndy Whitcroft		}
3797a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher.
3798a1ef277eSAndy Whitcroft		if ($dbg_attr) {
37999360b0e5SAndy Whitcroft			if ($line =~ /^.\s*$Modifier\s*$/) {
3800000d1cc1SJoe Perches				ERROR("TEST_ATTR",
3801000d1cc1SJoe Perches				      "TEST: is attr\n" . $herecurr);
38029360b0e5SAndy Whitcroft			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
3803000d1cc1SJoe Perches				ERROR("TEST_NOT_ATTR",
3804000d1cc1SJoe Perches				      "TEST: is not attr ($1 is)\n". $herecurr);
3805a1ef277eSAndy Whitcroft			}
3806a1ef277eSAndy Whitcroft			next;
3807a1ef277eSAndy Whitcroft		}
3808653d4876SAndy Whitcroft
3809f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line
381099423c20SAndy Whitcroft		if ($line =~ /^.\s*{/ &&
381199423c20SAndy Whitcroft		    $prevline =~ /(?:^|[^=])=\s*$/) {
3812d752fcc8SJoe Perches			if (ERROR("OPEN_BRACE",
3813d752fcc8SJoe Perches				  "that open brace { should be on the previous line\n" . $hereprev) &&
3814f2d7e4d4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
3815f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
3816f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
3817d752fcc8SJoe Perches				my $fixedline = $prevrawline;
3818d752fcc8SJoe Perches				$fixedline =~ s/\s*=\s*$/ = {/;
3819f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
3820d752fcc8SJoe Perches				$fixedline = $line;
38218d81ae05SCyril Bur				$fixedline =~ s/^(.\s*)\{\s*/$1/;
3822f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
3823d752fcc8SJoe Perches			}
3824f0a594c1SAndy Whitcroft		}
3825f0a594c1SAndy Whitcroft
382600df344fSAndy Whitcroft#
382700df344fSAndy Whitcroft# Checks which are anchored on the added line.
382800df344fSAndy Whitcroft#
382900df344fSAndy Whitcroft
3830653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line)
3831c45dcabdSAndy Whitcroft		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
3832653d4876SAndy Whitcroft			my $path = $1;
3833653d4876SAndy Whitcroft			if ($path =~ m{//}) {
3834000d1cc1SJoe Perches				ERROR("MALFORMED_INCLUDE",
3835495e9d84SJoe Perches				      "malformed #include filename\n" . $herecurr);
3836495e9d84SJoe Perches			}
3837495e9d84SJoe Perches			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
3838495e9d84SJoe Perches				ERROR("UAPI_INCLUDE",
3839495e9d84SJoe Perches				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
3840653d4876SAndy Whitcroft			}
3841653d4876SAndy Whitcroft		}
3842653d4876SAndy Whitcroft
384300df344fSAndy Whitcroft# no C99 // comments
384400df344fSAndy Whitcroft		if ($line =~ m{//}) {
38453705ce5bSJoe Perches			if (ERROR("C99_COMMENTS",
38463705ce5bSJoe Perches				  "do not use C99 // comments\n" . $herecurr) &&
38473705ce5bSJoe Perches			    $fix) {
3848194f66fcSJoe Perches				my $line = $fixed[$fixlinenr];
38493705ce5bSJoe Perches				if ($line =~ /\/\/(.*)$/) {
38503705ce5bSJoe Perches					my $comment = trim($1);
3851194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
38523705ce5bSJoe Perches				}
38533705ce5bSJoe Perches			}
385400df344fSAndy Whitcroft		}
385500df344fSAndy Whitcroft		# Remove C99 comments.
38560a920b5bSAndy Whitcroft		$line =~ s@//.*@@;
38576c72ffaaSAndy Whitcroft		$opline =~ s@//.*@@;
38580a920b5bSAndy Whitcroft
38592b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
38602b474a1aSAndy Whitcroft# the whole statement.
38612b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n";
38622b474a1aSAndy Whitcroft		if (defined $realline_next &&
38632b474a1aSAndy Whitcroft		    exists $lines[$realline_next - 1] &&
38642b474a1aSAndy Whitcroft		    !defined $suppress_export{$realline_next} &&
38652b474a1aSAndy Whitcroft		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
38662b474a1aSAndy Whitcroft		     $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
38673cbf62dfSAndy Whitcroft			# Handle definitions which produce identifiers with
38683cbf62dfSAndy Whitcroft			# a prefix:
38693cbf62dfSAndy Whitcroft			#   XXX(foo);
38703cbf62dfSAndy Whitcroft			#   EXPORT_SYMBOL(something_foo);
3871653d4876SAndy Whitcroft			my $name = $1;
387287a53877SAndy Whitcroft			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
38733cbf62dfSAndy Whitcroft			    $name =~ /^${Ident}_$2/) {
38743cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n";
38753cbf62dfSAndy Whitcroft				$suppress_export{$realline_next} = 1;
38763cbf62dfSAndy Whitcroft
38773cbf62dfSAndy Whitcroft			} elsif ($stat !~ /(?:
38782b474a1aSAndy Whitcroft				\n.}\s*$|
387948012058SAndy Whitcroft				^.DEFINE_$Ident\(\Q$name\E\)|
388048012058SAndy Whitcroft				^.DECLARE_$Ident\(\Q$name\E\)|
388148012058SAndy Whitcroft				^.LIST_HEAD\(\Q$name\E\)|
38822b474a1aSAndy Whitcroft				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
38832b474a1aSAndy Whitcroft				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
388448012058SAndy Whitcroft			    )/x) {
38852b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
38862b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 2;
38872b474a1aSAndy Whitcroft			} else {
38882b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 1;
38890a920b5bSAndy Whitcroft			}
38900a920b5bSAndy Whitcroft		}
38912b474a1aSAndy Whitcroft		if (!defined $suppress_export{$linenr} &&
38922b474a1aSAndy Whitcroft		    $prevline =~ /^.\s*$/ &&
38932b474a1aSAndy Whitcroft		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
38942b474a1aSAndy Whitcroft		     $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
38952b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n";
38962b474a1aSAndy Whitcroft			$suppress_export{$linenr} = 2;
38972b474a1aSAndy Whitcroft		}
38982b474a1aSAndy Whitcroft		if (defined $suppress_export{$linenr} &&
38992b474a1aSAndy Whitcroft		    $suppress_export{$linenr} == 2) {
3900000d1cc1SJoe Perches			WARN("EXPORT_SYMBOL",
3901000d1cc1SJoe Perches			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
39022b474a1aSAndy Whitcroft		}
39030a920b5bSAndy Whitcroft
39045150bda4SJoe Eloff# check for global initialisers.
39056d32f7a3SJoe Perches		if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) {
3906d5e616fcSJoe Perches			if (ERROR("GLOBAL_INITIALISERS",
39076d32f7a3SJoe Perches				  "do not initialise globals to $1\n" . $herecurr) &&
3908d5e616fcSJoe Perches			    $fix) {
39096d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
3910d5e616fcSJoe Perches			}
3911f0a594c1SAndy Whitcroft		}
39120a920b5bSAndy Whitcroft# check for static initialisers.
39136d32f7a3SJoe Perches		if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
3914d5e616fcSJoe Perches			if (ERROR("INITIALISED_STATIC",
39156d32f7a3SJoe Perches				  "do not initialise statics to $1\n" .
3916d5e616fcSJoe Perches				      $herecurr) &&
3917d5e616fcSJoe Perches			    $fix) {
39186d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
3919d5e616fcSJoe Perches			}
39200a920b5bSAndy Whitcroft		}
39210a920b5bSAndy Whitcroft
39221813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned
39231813087dSJoe Perches		while ($sline =~ m{(\b$TypeMisordered\b)}g) {
39241813087dSJoe Perches			my $tmp = trim($1);
39251813087dSJoe Perches			WARN("MISORDERED_TYPE",
39261813087dSJoe Perches			     "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
39271813087dSJoe Perches		}
39281813087dSJoe Perches
3929809e082eSJoe Perches# check for unnecessary <signed> int declarations of short/long/long long
3930809e082eSJoe Perches		while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) {
3931809e082eSJoe Perches			my $type = trim($1);
3932809e082eSJoe Perches			next if ($type !~ /\bint\b/);
3933809e082eSJoe Perches			next if ($type !~ /\b(?:short|long\s+long|long)\b/);
3934809e082eSJoe Perches			my $new_type = $type;
3935809e082eSJoe Perches			$new_type =~ s/\b\s*int\s*\b/ /;
3936809e082eSJoe Perches			$new_type =~ s/\b\s*(?:un)?signed\b\s*/ /;
3937809e082eSJoe Perches			$new_type =~ s/^const\s+//;
3938809e082eSJoe Perches			$new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/);
3939809e082eSJoe Perches			$new_type = "const $new_type" if ($type =~ /^const\b/);
3940809e082eSJoe Perches			$new_type =~ s/\s+/ /g;
3941809e082eSJoe Perches			$new_type = trim($new_type);
3942809e082eSJoe Perches			if (WARN("UNNECESSARY_INT",
3943809e082eSJoe Perches				 "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) &&
3944809e082eSJoe Perches			    $fix) {
3945809e082eSJoe Perches				$fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/;
3946809e082eSJoe Perches			}
3947809e082eSJoe Perches		}
3948809e082eSJoe Perches
3949cb710ecaSJoe Perches# check for static const char * arrays.
3950cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
3951000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
3952000d1cc1SJoe Perches			     "static const char * array should probably be static const char * const\n" .
3953cb710ecaSJoe Perches				$herecurr);
3954cb710ecaSJoe Perches		}
3955cb710ecaSJoe Perches
395677b8c0a8SJoe Perches# check for initialized const char arrays that should be static const
395777b8c0a8SJoe Perches		if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) {
395877b8c0a8SJoe Perches			if (WARN("STATIC_CONST_CHAR_ARRAY",
395977b8c0a8SJoe Perches				 "const array should probably be static const\n" . $herecurr) &&
396077b8c0a8SJoe Perches			    $fix) {
396177b8c0a8SJoe Perches				$fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/;
396277b8c0a8SJoe Perches			}
396377b8c0a8SJoe Perches		}
396477b8c0a8SJoe Perches
3965cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations.
3966cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
3967000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
3968000d1cc1SJoe Perches			     "static char array declaration should probably be static const char\n" .
3969cb710ecaSJoe Perches				$herecurr);
3970cb710ecaSJoe Perches		}
3971cb710ecaSJoe Perches
3972ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type
3973ab7e23f3SJoe Perches		if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
3974ab7e23f3SJoe Perches			my $found = $1;
3975ab7e23f3SJoe Perches			if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
3976ab7e23f3SJoe Perches				WARN("CONST_CONST",
3977ab7e23f3SJoe Perches				     "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
3978ab7e23f3SJoe Perches			} elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
3979ab7e23f3SJoe Perches				WARN("CONST_CONST",
3980ab7e23f3SJoe Perches				     "'const $found const' should probably be 'const $found'\n" . $herecurr);
3981ab7e23f3SJoe Perches			}
3982ab7e23f3SJoe Perches		}
3983ab7e23f3SJoe Perches
39849b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations.
39859b0fa60dSJoe Perches		if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
39869b0fa60dSJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
39879b0fa60dSJoe Perches			     "char * array declaration might be better as static const\n" .
39889b0fa60dSJoe Perches				$herecurr);
39899b0fa60dSJoe Perches               }
39909b0fa60dSJoe Perches
3991b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
3992b598b670SJoe Perches		if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
3993b598b670SJoe Perches			my $array = $1;
3994b598b670SJoe 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*\))@) {
3995b598b670SJoe Perches				my $array_div = $1;
3996b598b670SJoe Perches				if (WARN("ARRAY_SIZE",
3997b598b670SJoe Perches					 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
3998b598b670SJoe Perches				    $fix) {
3999b598b670SJoe Perches					$fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
4000b598b670SJoe Perches				}
4001b598b670SJoe Perches			}
4002b598b670SJoe Perches		}
4003b598b670SJoe Perches
4004b36190c5SJoe Perches# check for function declarations without arguments like "int foo()"
4005b36190c5SJoe Perches		if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) {
4006b36190c5SJoe Perches			if (ERROR("FUNCTION_WITHOUT_ARGS",
4007b36190c5SJoe Perches				  "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
4008b36190c5SJoe Perches			    $fix) {
4009194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
4010b36190c5SJoe Perches			}
4011b36190c5SJoe Perches		}
4012b36190c5SJoe Perches
4013653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations
4014653d4876SAndy Whitcroft# make sense.
4015653d4876SAndy Whitcroft		if ($line =~ /\btypedef\s/ &&
40168054576dSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
4017c45dcabdSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
40188ed22cadSAndy Whitcroft		    $line !~ /\b$typeTypedefs\b/ &&
401946d832f5SMichael S. Tsirkin		    $line !~ /\b__bitwise\b/) {
4020000d1cc1SJoe Perches			WARN("NEW_TYPEDEFS",
4021000d1cc1SJoe Perches			     "do not add new typedefs\n" . $herecurr);
40220a920b5bSAndy Whitcroft		}
40230a920b5bSAndy Whitcroft
40240a920b5bSAndy Whitcroft# * goes on variable not on type
402565863862SAndy Whitcroft		# (char*[ const])
4026bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
4027bfcb2cc7SAndy Whitcroft			#print "AA<$1>\n";
40283705ce5bSJoe Perches			my ($ident, $from, $to) = ($1, $2, $2);
4029d8aaf121SAndy Whitcroft
403065863862SAndy Whitcroft			# Should start with a space.
403165863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
403265863862SAndy Whitcroft			# Should not end with a space.
403365863862SAndy Whitcroft			$to =~ s/\s+$//;
403465863862SAndy Whitcroft			# '*'s should not have spaces between.
4035f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
403665863862SAndy Whitcroft			}
4037d8aaf121SAndy Whitcroft
40383705ce5bSJoe Perches##			print "1: from<$from> to<$to> ident<$ident>\n";
403965863862SAndy Whitcroft			if ($from ne $to) {
40403705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
40413705ce5bSJoe Perches					  "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
40423705ce5bSJoe Perches				    $fix) {
40433705ce5bSJoe Perches					my $sub_from = $ident;
40443705ce5bSJoe Perches					my $sub_to = $ident;
40453705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
4046194f66fcSJoe Perches					$fixed[$fixlinenr] =~
40473705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
40483705ce5bSJoe Perches				}
404965863862SAndy Whitcroft			}
4050bfcb2cc7SAndy Whitcroft		}
4051bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
4052bfcb2cc7SAndy Whitcroft			#print "BB<$1>\n";
40533705ce5bSJoe Perches			my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
4054d8aaf121SAndy Whitcroft
405565863862SAndy Whitcroft			# Should start with a space.
405665863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
405765863862SAndy Whitcroft			# Should not end with a space.
405865863862SAndy Whitcroft			$to =~ s/\s+$//;
405965863862SAndy Whitcroft			# '*'s should not have spaces between.
4060f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
406165863862SAndy Whitcroft			}
406265863862SAndy Whitcroft			# Modifiers should have spaces.
406365863862SAndy Whitcroft			$to =~ s/(\b$Modifier$)/$1 /;
406465863862SAndy Whitcroft
40653705ce5bSJoe Perches##			print "2: from<$from> to<$to> ident<$ident>\n";
4066667026e7SAndy Whitcroft			if ($from ne $to && $ident !~ /^$Modifier$/) {
40673705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
40683705ce5bSJoe Perches					  "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
40693705ce5bSJoe Perches				    $fix) {
40703705ce5bSJoe Perches
40713705ce5bSJoe Perches					my $sub_from = $match;
40723705ce5bSJoe Perches					my $sub_to = $match;
40733705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
4074194f66fcSJoe Perches					$fixed[$fixlinenr] =~
40753705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
40763705ce5bSJoe Perches				}
407765863862SAndy Whitcroft			}
40780a920b5bSAndy Whitcroft		}
40790a920b5bSAndy Whitcroft
40809d3e3c70SJoe Perches# avoid BUG() or BUG_ON()
40819d3e3c70SJoe Perches		if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
40820675a8fbSJean Delvare			my $msg_level = \&WARN;
40830675a8fbSJean Delvare			$msg_level = \&CHK if ($file);
40840675a8fbSJean Delvare			&{$msg_level}("AVOID_BUG",
40859d3e3c70SJoe Perches				      "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
40869d3e3c70SJoe Perches		}
40870a920b5bSAndy Whitcroft
40889d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE
40898905a67cSAndy Whitcroft		if ($line =~ /\bLINUX_VERSION_CODE\b/) {
4090000d1cc1SJoe Perches			WARN("LINUX_VERSION_CODE",
4091000d1cc1SJoe Perches			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
40928905a67cSAndy Whitcroft		}
40938905a67cSAndy Whitcroft
409417441227SJoe Perches# check for uses of printk_ratelimit
409517441227SJoe Perches		if ($line =~ /\bprintk_ratelimit\s*\(/) {
4096000d1cc1SJoe Perches			WARN("PRINTK_RATELIMITED",
4097000d1cc1SJoe Perches			     "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
409817441227SJoe Perches		}
409917441227SJoe Perches
4100eeef5733SJoe Perches# printk should use KERN_* levels
4101eeef5733SJoe Perches		if ($line =~ /\bprintk\s*\(\s*(?!KERN_[A-Z]+\b)/) {
4102000d1cc1SJoe Perches			WARN("PRINTK_WITHOUT_KERN_LEVEL",
4103eeef5733SJoe Perches			     "printk() should include KERN_<LEVEL> facility level\n" . $herecurr);
410400df344fSAndy Whitcroft		}
41050a920b5bSAndy Whitcroft
4106243f3803SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) {
4107243f3803SJoe Perches			my $orig = $1;
4108243f3803SJoe Perches			my $level = lc($orig);
4109243f3803SJoe Perches			$level = "warn" if ($level eq "warning");
41108f26b837SJoe Perches			my $level2 = $level;
41118f26b837SJoe Perches			$level2 = "dbg" if ($level eq "debug");
4112243f3803SJoe Perches			WARN("PREFER_PR_LEVEL",
4113daa8b059SYogesh Chaudhari			     "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(...  to printk(KERN_$orig ...\n" . $herecurr);
4114243f3803SJoe Perches		}
4115243f3803SJoe Perches
4116243f3803SJoe Perches		if ($line =~ /\bpr_warning\s*\(/) {
4117d5e616fcSJoe Perches			if (WARN("PREFER_PR_LEVEL",
4118d5e616fcSJoe Perches				 "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) &&
4119d5e616fcSJoe Perches			    $fix) {
4120194f66fcSJoe Perches				$fixed[$fixlinenr] =~
4121d5e616fcSJoe Perches				    s/\bpr_warning\b/pr_warn/;
4122d5e616fcSJoe Perches			}
4123243f3803SJoe Perches		}
4124243f3803SJoe Perches
4125dc139313SJoe Perches		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
4126dc139313SJoe Perches			my $orig = $1;
4127dc139313SJoe Perches			my $level = lc($orig);
4128dc139313SJoe Perches			$level = "warn" if ($level eq "warning");
4129dc139313SJoe Perches			$level = "dbg" if ($level eq "debug");
4130dc139313SJoe Perches			WARN("PREFER_DEV_LEVEL",
4131dc139313SJoe Perches			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
4132dc139313SJoe Perches		}
4133dc139313SJoe Perches
413491c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else.  This will have a small
413591c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at
413691c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning.
413791c9afafSAndy Lutomirski		if ($line =~ /\bENOSYS\b/) {
413891c9afafSAndy Lutomirski			WARN("ENOSYS",
413991c9afafSAndy Lutomirski			     "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
414091c9afafSAndy Lutomirski		}
414191c9afafSAndy Lutomirski
4142653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while,
4143653d4876SAndy Whitcroft# or if closed on same line
41445b57980dSJoe Perches		if ($perl_version_ok &&
41452d453e3bSJoe Perches		    $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ &&
41462d453e3bSJoe Perches		    $sline !~ /\#\s*define\b.*do\s*\{/ &&
41472d453e3bSJoe Perches		    $sline !~ /}/) {
41488d182478SJoe Perches			if (ERROR("OPEN_BRACE",
41492d453e3bSJoe Perches				  "open brace '{' following function definitions go on the next line\n" . $herecurr) &&
41508d182478SJoe Perches			    $fix) {
41518d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
41528d182478SJoe Perches				my $fixed_line = $rawline;
41538d182478SJoe Perches				$fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/;
41548d182478SJoe Perches				my $line1 = $1;
41558d182478SJoe Perches				my $line2 = $2;
41568d182478SJoe Perches				fix_insert_line($fixlinenr, ltrim($line1));
41578d182478SJoe Perches				fix_insert_line($fixlinenr, "\+{");
41588d182478SJoe Perches				if ($line2 !~ /^\s*$/) {
41598d182478SJoe Perches					fix_insert_line($fixlinenr, "\+\t" . trim($line2));
41608d182478SJoe Perches				}
41618d182478SJoe Perches			}
41620a920b5bSAndy Whitcroft		}
4163653d4876SAndy Whitcroft
41648905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line.
41658905a67cSAndy Whitcroft		if ($line =~ /^.\s*{/ &&
41668905a67cSAndy Whitcroft		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
41678d182478SJoe Perches			if (ERROR("OPEN_BRACE",
41688d182478SJoe Perches				  "open brace '{' following $1 go on the same line\n" . $hereprev) &&
41698d182478SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
41708d182478SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
41718d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
41728d182478SJoe Perches				my $fixedline = rtrim($prevrawline) . " {";
41738d182478SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
41748d182478SJoe Perches				$fixedline = $rawline;
41758d81ae05SCyril Bur				$fixedline =~ s/^(.\s*)\{\s*/$1\t/;
41768d182478SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
41778d182478SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
41788d182478SJoe Perches				}
41798d182478SJoe Perches			}
41808905a67cSAndy Whitcroft		}
41818905a67cSAndy Whitcroft
41820c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition
41833705ce5bSJoe Perches		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
41843705ce5bSJoe Perches			if (WARN("SPACING",
41853705ce5bSJoe Perches				 "missing space after $1 definition\n" . $herecurr) &&
41863705ce5bSJoe Perches			    $fix) {
4187194f66fcSJoe Perches				$fixed[$fixlinenr] =~
41883705ce5bSJoe Perches				    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
41893705ce5bSJoe Perches			}
41900c73b4ebSAndy Whitcroft		}
41910c73b4ebSAndy Whitcroft
419231070b5dSJoe Perches# Function pointer declarations
419331070b5dSJoe Perches# check spacing between type, funcptr, and args
419431070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)"
419591f72e9cSJoe Perches		if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
419631070b5dSJoe Perches			my $declare = $1;
419731070b5dSJoe Perches			my $pre_pointer_space = $2;
419831070b5dSJoe Perches			my $post_pointer_space = $3;
419931070b5dSJoe Perches			my $funcname = $4;
420031070b5dSJoe Perches			my $post_funcname_space = $5;
420131070b5dSJoe Perches			my $pre_args_space = $6;
420231070b5dSJoe Perches
420391f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type
420491f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types
420591f72e9cSJoe Perches# don't need a space so don't warn for those.
420691f72e9cSJoe Perches			my $post_declare_space = "";
420791f72e9cSJoe Perches			if ($declare =~ /(\s+)$/) {
420891f72e9cSJoe Perches				$post_declare_space = $1;
420991f72e9cSJoe Perches				$declare = rtrim($declare);
421091f72e9cSJoe Perches			}
421191f72e9cSJoe Perches			if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
421231070b5dSJoe Perches				WARN("SPACING",
421331070b5dSJoe Perches				     "missing space after return type\n" . $herecurr);
421491f72e9cSJoe Perches				$post_declare_space = " ";
421531070b5dSJoe Perches			}
421631070b5dSJoe Perches
421731070b5dSJoe Perches# unnecessary space "type  (*funcptr)(args...)"
421891f72e9cSJoe Perches# This test is not currently implemented because these declarations are
421991f72e9cSJoe Perches# equivalent to
422091f72e9cSJoe Perches#	int  foo(int bar, ...)
422191f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning.
422291f72e9cSJoe Perches#
422391f72e9cSJoe Perches#			elsif ($declare =~ /\s{2,}$/) {
422491f72e9cSJoe Perches#				WARN("SPACING",
422591f72e9cSJoe Perches#				     "Multiple spaces after return type\n" . $herecurr);
422691f72e9cSJoe Perches#			}
422731070b5dSJoe Perches
422831070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)"
422931070b5dSJoe Perches			if (defined $pre_pointer_space &&
423031070b5dSJoe Perches			    $pre_pointer_space =~ /^\s/) {
423131070b5dSJoe Perches				WARN("SPACING",
423231070b5dSJoe Perches				     "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
423331070b5dSJoe Perches			}
423431070b5dSJoe Perches
423531070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)"
423631070b5dSJoe Perches			if (defined $post_pointer_space &&
423731070b5dSJoe Perches			    $post_pointer_space =~ /^\s/) {
423831070b5dSJoe Perches				WARN("SPACING",
423931070b5dSJoe Perches				     "Unnecessary space before function pointer name\n" . $herecurr);
424031070b5dSJoe Perches			}
424131070b5dSJoe Perches
424231070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)"
424331070b5dSJoe Perches			if (defined $post_funcname_space &&
424431070b5dSJoe Perches			    $post_funcname_space =~ /^\s/) {
424531070b5dSJoe Perches				WARN("SPACING",
424631070b5dSJoe Perches				     "Unnecessary space after function pointer name\n" . $herecurr);
424731070b5dSJoe Perches			}
424831070b5dSJoe Perches
424931070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)"
425031070b5dSJoe Perches			if (defined $pre_args_space &&
425131070b5dSJoe Perches			    $pre_args_space =~ /^\s/) {
425231070b5dSJoe Perches				WARN("SPACING",
425331070b5dSJoe Perches				     "Unnecessary space before function pointer arguments\n" . $herecurr);
425431070b5dSJoe Perches			}
425531070b5dSJoe Perches
425631070b5dSJoe Perches			if (show_type("SPACING") && $fix) {
4257194f66fcSJoe Perches				$fixed[$fixlinenr] =~
425891f72e9cSJoe Perches				    s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
425931070b5dSJoe Perches			}
426031070b5dSJoe Perches		}
426131070b5dSJoe Perches
42628d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed:
42638d31cfceSAndy Whitcroft#  1. with a type on the left -- int [] a;
4264fe2a7dbcSAndy Whitcroft#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
4265fe2a7dbcSAndy Whitcroft#  3. inside a curly brace -- = { [0...10] = 5 }
42668d31cfceSAndy Whitcroft		while ($line =~ /(.*?\s)\[/g) {
42678d31cfceSAndy Whitcroft			my ($where, $prefix) = ($-[1], $1);
42688d31cfceSAndy Whitcroft			if ($prefix !~ /$Type\s+$/ &&
4269fe2a7dbcSAndy Whitcroft			    ($where != 0 || $prefix !~ /^.\s+$/) &&
427038dca988SHeinrich Schuchardt			    $prefix !~ /[{,:]\s+$/) {
42713705ce5bSJoe Perches				if (ERROR("BRACKET_SPACE",
42723705ce5bSJoe Perches					  "space prohibited before open square bracket '['\n" . $herecurr) &&
42733705ce5bSJoe Perches				    $fix) {
4274194f66fcSJoe Perches				    $fixed[$fixlinenr] =~
42753705ce5bSJoe Perches					s/^(\+.*?)\s+\[/$1\[/;
42763705ce5bSJoe Perches				}
42778d31cfceSAndy Whitcroft			}
42788d31cfceSAndy Whitcroft		}
42798d31cfceSAndy Whitcroft
4280f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses.
42816c72ffaaSAndy Whitcroft		while ($line =~ /($Ident)\s+\(/g) {
4282c2fdda0dSAndy Whitcroft			my $name = $1;
4283773647a0SAndy Whitcroft			my $ctx_before = substr($line, 0, $-[1]);
4284773647a0SAndy Whitcroft			my $ctx = "$ctx_before$name";
4285c2fdda0dSAndy Whitcroft
4286c2fdda0dSAndy Whitcroft			# Ignore those directives where spaces _are_ permitted.
4287773647a0SAndy Whitcroft			if ($name =~ /^(?:
4288773647a0SAndy Whitcroft				if|for|while|switch|return|case|
4289773647a0SAndy Whitcroft				volatile|__volatile__|
4290773647a0SAndy Whitcroft				__attribute__|format|__extension__|
4291773647a0SAndy Whitcroft				asm|__asm__)$/x)
4292773647a0SAndy Whitcroft			{
4293c2fdda0dSAndy Whitcroft			# cpp #define statements have non-optional spaces, ie
4294c2fdda0dSAndy Whitcroft			# if there is a space between the name and the open
4295c2fdda0dSAndy Whitcroft			# parenthesis it is simply not a parameter group.
4296c45dcabdSAndy Whitcroft			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
4297773647a0SAndy Whitcroft
4298773647a0SAndy Whitcroft			# cpp #elif statement condition may start with a (
4299c45dcabdSAndy Whitcroft			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
4300c2fdda0dSAndy Whitcroft
4301c2fdda0dSAndy Whitcroft			# If this whole things ends with a type its most
4302c2fdda0dSAndy Whitcroft			# likely a typedef for a function.
4303773647a0SAndy Whitcroft			} elsif ($ctx =~ /$Type$/) {
4304c2fdda0dSAndy Whitcroft
4305c2fdda0dSAndy Whitcroft			} else {
43063705ce5bSJoe Perches				if (WARN("SPACING",
43073705ce5bSJoe Perches					 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
43083705ce5bSJoe Perches					     $fix) {
4309194f66fcSJoe Perches					$fixed[$fixlinenr] =~
43103705ce5bSJoe Perches					    s/\b$name\s+\(/$name\(/;
43113705ce5bSJoe Perches				}
4312f0a594c1SAndy Whitcroft			}
43136c72ffaaSAndy Whitcroft		}
43149a4cad4eSEric Nelson
4315653d4876SAndy Whitcroft# Check operator spacing.
43160a920b5bSAndy Whitcroft		if (!($line=~/\#\s*include/)) {
43173705ce5bSJoe Perches			my $fixed_line = "";
43183705ce5bSJoe Perches			my $line_fixed = 0;
43193705ce5bSJoe Perches
43209c0ca6f9SAndy Whitcroft			my $ops = qr{
43219c0ca6f9SAndy Whitcroft				<<=|>>=|<=|>=|==|!=|
43229c0ca6f9SAndy Whitcroft				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
43239c0ca6f9SAndy Whitcroft				=>|->|<<|>>|<|>|=|!|~|
43241f65f947SAndy Whitcroft				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
432584731623SJoe Perches				\?:|\?|:
43269c0ca6f9SAndy Whitcroft			}x;
4327cf655043SAndy Whitcroft			my @elements = split(/($ops|;)/, $opline);
43283705ce5bSJoe Perches
43293705ce5bSJoe Perches##			print("element count: <" . $#elements . ">\n");
43303705ce5bSJoe Perches##			foreach my $el (@elements) {
43313705ce5bSJoe Perches##				print("el: <$el>\n");
43323705ce5bSJoe Perches##			}
43333705ce5bSJoe Perches
43343705ce5bSJoe Perches			my @fix_elements = ();
433500df344fSAndy Whitcroft			my $off = 0;
43366c72ffaaSAndy Whitcroft
43373705ce5bSJoe Perches			foreach my $el (@elements) {
43383705ce5bSJoe Perches				push(@fix_elements, substr($rawline, $off, length($el)));
43393705ce5bSJoe Perches				$off += length($el);
43403705ce5bSJoe Perches			}
43413705ce5bSJoe Perches
43423705ce5bSJoe Perches			$off = 0;
43433705ce5bSJoe Perches
43446c72ffaaSAndy Whitcroft			my $blank = copy_spacing($opline);
4345b34c648bSJoe Perches			my $last_after = -1;
43466c72ffaaSAndy Whitcroft
43470a920b5bSAndy Whitcroft			for (my $n = 0; $n < $#elements; $n += 2) {
43483705ce5bSJoe Perches
43493705ce5bSJoe Perches				my $good = $fix_elements[$n] . $fix_elements[$n + 1];
43503705ce5bSJoe Perches
43513705ce5bSJoe Perches##				print("n: <$n> good: <$good>\n");
43523705ce5bSJoe Perches
43534a0df2efSAndy Whitcroft				$off += length($elements[$n]);
43544a0df2efSAndy Whitcroft
435525985edcSLucas De Marchi				# Pick up the preceding and succeeding characters.
4356773647a0SAndy Whitcroft				my $ca = substr($opline, 0, $off);
4357773647a0SAndy Whitcroft				my $cc = '';
4358773647a0SAndy Whitcroft				if (length($opline) >= ($off + length($elements[$n + 1]))) {
4359773647a0SAndy Whitcroft					$cc = substr($opline, $off + length($elements[$n + 1]));
4360773647a0SAndy Whitcroft				}
4361773647a0SAndy Whitcroft				my $cb = "$ca$;$cc";
4362773647a0SAndy Whitcroft
43634a0df2efSAndy Whitcroft				my $a = '';
43644a0df2efSAndy Whitcroft				$a = 'V' if ($elements[$n] ne '');
43654a0df2efSAndy Whitcroft				$a = 'W' if ($elements[$n] =~ /\s$/);
4366cf655043SAndy Whitcroft				$a = 'C' if ($elements[$n] =~ /$;$/);
43674a0df2efSAndy Whitcroft				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
43684a0df2efSAndy Whitcroft				$a = 'O' if ($elements[$n] eq '');
4369773647a0SAndy Whitcroft				$a = 'E' if ($ca =~ /^\s*$/);
43704a0df2efSAndy Whitcroft
43710a920b5bSAndy Whitcroft				my $op = $elements[$n + 1];
43724a0df2efSAndy Whitcroft
43734a0df2efSAndy Whitcroft				my $c = '';
43740a920b5bSAndy Whitcroft				if (defined $elements[$n + 2]) {
43754a0df2efSAndy Whitcroft					$c = 'V' if ($elements[$n + 2] ne '');
43764a0df2efSAndy Whitcroft					$c = 'W' if ($elements[$n + 2] =~ /^\s/);
4377cf655043SAndy Whitcroft					$c = 'C' if ($elements[$n + 2] =~ /^$;/);
43784a0df2efSAndy Whitcroft					$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
43794a0df2efSAndy Whitcroft					$c = 'O' if ($elements[$n + 2] eq '');
43808b1b3378SAndy Whitcroft					$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
43814a0df2efSAndy Whitcroft				} else {
43824a0df2efSAndy Whitcroft					$c = 'E';
43830a920b5bSAndy Whitcroft				}
43840a920b5bSAndy Whitcroft
43854a0df2efSAndy Whitcroft				my $ctx = "${a}x${c}";
43864a0df2efSAndy Whitcroft
43874a0df2efSAndy Whitcroft				my $at = "(ctx:$ctx)";
43884a0df2efSAndy Whitcroft
43896c72ffaaSAndy Whitcroft				my $ptr = substr($blank, 0, $off) . "^";
4390de7d4f0eSAndy Whitcroft				my $hereptr = "$hereline$ptr\n";
43910a920b5bSAndy Whitcroft
439274048ed8SAndy Whitcroft				# Pull out the value of this operator.
43936c72ffaaSAndy Whitcroft				my $op_type = substr($curr_values, $off + 1, 1);
43940a920b5bSAndy Whitcroft
43951f65f947SAndy Whitcroft				# Get the full operator variant.
43961f65f947SAndy Whitcroft				my $opv = $op . substr($curr_vars, $off, 1);
43971f65f947SAndy Whitcroft
439813214adfSAndy Whitcroft				# Ignore operators passed as parameters.
439913214adfSAndy Whitcroft				if ($op_type ne 'V' &&
4400d7fe8065SSam Bobroff				    $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
440113214adfSAndy Whitcroft
4402cf655043SAndy Whitcroft#				# Ignore comments
4403cf655043SAndy Whitcroft#				} elsif ($op =~ /^$;+$/) {
440413214adfSAndy Whitcroft
4405d8aaf121SAndy Whitcroft				# ; should have either the end of line or a space or \ after it
440613214adfSAndy Whitcroft				} elsif ($op eq ';') {
4407cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEBC]/ &&
4408cf655043SAndy Whitcroft					    $cc !~ /^\\/ && $cc !~ /^;/) {
44093705ce5bSJoe Perches						if (ERROR("SPACING",
44103705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
4411b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
44123705ce5bSJoe Perches							$line_fixed = 1;
44133705ce5bSJoe Perches						}
4414d8aaf121SAndy Whitcroft					}
4415d8aaf121SAndy Whitcroft
4416d8aaf121SAndy Whitcroft				# // is a comment
4417d8aaf121SAndy Whitcroft				} elsif ($op eq '//') {
44180a920b5bSAndy Whitcroft
4419b00e4814SJoe Perches				#   :   when part of a bitfield
4420b00e4814SJoe Perches				} elsif ($opv eq ':B') {
4421b00e4814SJoe Perches					# skip the bitfield test for now
4422b00e4814SJoe Perches
44231f65f947SAndy Whitcroft				# No spaces for:
44241f65f947SAndy Whitcroft				#   ->
4425b00e4814SJoe Perches				} elsif ($op eq '->') {
44264a0df2efSAndy Whitcroft					if ($ctx =~ /Wx.|.xW/) {
44273705ce5bSJoe Perches						if (ERROR("SPACING",
44283705ce5bSJoe Perches							  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
4429b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
44303705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
44313705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
44323705ce5bSJoe Perches							}
4433b34c648bSJoe Perches							$line_fixed = 1;
44343705ce5bSJoe Perches						}
44350a920b5bSAndy Whitcroft					}
44360a920b5bSAndy Whitcroft
44372381097bSJoe Perches				# , must not have a space before and must have a space on the right.
44380a920b5bSAndy Whitcroft				} elsif ($op eq ',') {
44392381097bSJoe Perches					my $rtrim_before = 0;
44402381097bSJoe Perches					my $space_after = 0;
44412381097bSJoe Perches					if ($ctx =~ /Wx./) {
44422381097bSJoe Perches						if (ERROR("SPACING",
44432381097bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
44442381097bSJoe Perches							$line_fixed = 1;
44452381097bSJoe Perches							$rtrim_before = 1;
44462381097bSJoe Perches						}
44472381097bSJoe Perches					}
4448cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
44493705ce5bSJoe Perches						if (ERROR("SPACING",
44503705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
44513705ce5bSJoe Perches							$line_fixed = 1;
4452b34c648bSJoe Perches							$last_after = $n;
44532381097bSJoe Perches							$space_after = 1;
44542381097bSJoe Perches						}
44552381097bSJoe Perches					}
44562381097bSJoe Perches					if ($rtrim_before || $space_after) {
44572381097bSJoe Perches						if ($rtrim_before) {
44582381097bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
44592381097bSJoe Perches						} else {
44602381097bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
44612381097bSJoe Perches						}
44622381097bSJoe Perches						if ($space_after) {
44632381097bSJoe Perches							$good .= " ";
44643705ce5bSJoe Perches						}
44650a920b5bSAndy Whitcroft					}
44660a920b5bSAndy Whitcroft
44679c0ca6f9SAndy Whitcroft				# '*' as part of a type definition -- reported already.
446874048ed8SAndy Whitcroft				} elsif ($opv eq '*_') {
44699c0ca6f9SAndy Whitcroft					#warn "'*' is part of type\n";
44709c0ca6f9SAndy Whitcroft
44719c0ca6f9SAndy Whitcroft				# unary operators should have a space before and
44729c0ca6f9SAndy Whitcroft				# none after.  May be left adjacent to another
44739c0ca6f9SAndy Whitcroft				# unary operator, or a cast
44749c0ca6f9SAndy Whitcroft				} elsif ($op eq '!' || $op eq '~' ||
447574048ed8SAndy Whitcroft					 $opv eq '*U' || $opv eq '-U' ||
44760d413866SAndy Whitcroft					 $opv eq '&U' || $opv eq '&&U') {
4477cf655043SAndy Whitcroft					if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
44783705ce5bSJoe Perches						if (ERROR("SPACING",
44793705ce5bSJoe Perches							  "space required before that '$op' $at\n" . $hereptr)) {
4480b34c648bSJoe Perches							if ($n != $last_after + 2) {
4481b34c648bSJoe Perches								$good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
44823705ce5bSJoe Perches								$line_fixed = 1;
44833705ce5bSJoe Perches							}
44840a920b5bSAndy Whitcroft						}
4485b34c648bSJoe Perches					}
4486a3340b35SAndy Whitcroft					if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
4487171ae1a4SAndy Whitcroft						# A unary '*' may be const
4488171ae1a4SAndy Whitcroft
4489171ae1a4SAndy Whitcroft					} elsif ($ctx =~ /.xW/) {
44903705ce5bSJoe Perches						if (ERROR("SPACING",
44913705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
4492b34c648bSJoe Perches							$good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
44933705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
44943705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
44953705ce5bSJoe Perches							}
4496b34c648bSJoe Perches							$line_fixed = 1;
44973705ce5bSJoe Perches						}
44980a920b5bSAndy Whitcroft					}
44990a920b5bSAndy Whitcroft
45000a920b5bSAndy Whitcroft				# unary ++ and unary -- are allowed no space on one side.
45010a920b5bSAndy Whitcroft				} elsif ($op eq '++' or $op eq '--') {
4502773647a0SAndy Whitcroft					if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
45033705ce5bSJoe Perches						if (ERROR("SPACING",
45043705ce5bSJoe Perches							  "space required one side of that '$op' $at\n" . $hereptr)) {
4505b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
45063705ce5bSJoe Perches							$line_fixed = 1;
45073705ce5bSJoe Perches						}
45080a920b5bSAndy Whitcroft					}
4509773647a0SAndy Whitcroft					if ($ctx =~ /Wx[BE]/ ||
4510773647a0SAndy Whitcroft					    ($ctx =~ /Wx./ && $cc =~ /^;/)) {
45113705ce5bSJoe Perches						if (ERROR("SPACING",
45123705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
4513b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
45143705ce5bSJoe Perches							$line_fixed = 1;
45153705ce5bSJoe Perches						}
4516653d4876SAndy Whitcroft					}
4517773647a0SAndy Whitcroft					if ($ctx =~ /ExW/) {
45183705ce5bSJoe Perches						if (ERROR("SPACING",
45193705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
4520b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
45213705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
45223705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4523773647a0SAndy Whitcroft							}
4524b34c648bSJoe Perches							$line_fixed = 1;
45253705ce5bSJoe Perches						}
45263705ce5bSJoe Perches					}
45270a920b5bSAndy Whitcroft
45280a920b5bSAndy Whitcroft				# << and >> may either have or not have spaces both sides
45299c0ca6f9SAndy Whitcroft				} elsif ($op eq '<<' or $op eq '>>' or
45309c0ca6f9SAndy Whitcroft					 $op eq '&' or $op eq '^' or $op eq '|' or
45319c0ca6f9SAndy Whitcroft					 $op eq '+' or $op eq '-' or
4532c2fdda0dSAndy Whitcroft					 $op eq '*' or $op eq '/' or
4533c2fdda0dSAndy Whitcroft					 $op eq '%')
45340a920b5bSAndy Whitcroft				{
4535d2e025f3SJoe Perches					if ($check) {
4536d2e025f3SJoe Perches						if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
4537d2e025f3SJoe Perches							if (CHK("SPACING",
4538d2e025f3SJoe Perches								"spaces preferred around that '$op' $at\n" . $hereptr)) {
4539d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4540d2e025f3SJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4541d2e025f3SJoe Perches								$line_fixed = 1;
4542d2e025f3SJoe Perches							}
4543d2e025f3SJoe Perches						} elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
4544d2e025f3SJoe Perches							if (CHK("SPACING",
4545d2e025f3SJoe Perches								"space preferred before that '$op' $at\n" . $hereptr)) {
4546d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
4547d2e025f3SJoe Perches								$line_fixed = 1;
4548d2e025f3SJoe Perches							}
4549d2e025f3SJoe Perches						}
4550d2e025f3SJoe Perches					} elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
45513705ce5bSJoe Perches						if (ERROR("SPACING",
45523705ce5bSJoe Perches							  "need consistent spacing around '$op' $at\n" . $hereptr)) {
4553b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4554b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
4555b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4556b34c648bSJoe Perches							}
45573705ce5bSJoe Perches							$line_fixed = 1;
45583705ce5bSJoe Perches						}
45590a920b5bSAndy Whitcroft					}
45600a920b5bSAndy Whitcroft
45611f65f947SAndy Whitcroft				# A colon needs no spaces before when it is
45621f65f947SAndy Whitcroft				# terminating a case value or a label.
45631f65f947SAndy Whitcroft				} elsif ($opv eq ':C' || $opv eq ':L') {
45641f65f947SAndy Whitcroft					if ($ctx =~ /Wx./) {
45653705ce5bSJoe Perches						if (ERROR("SPACING",
45663705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
4567b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
45683705ce5bSJoe Perches							$line_fixed = 1;
45693705ce5bSJoe Perches						}
45701f65f947SAndy Whitcroft					}
45711f65f947SAndy Whitcroft
45720a920b5bSAndy Whitcroft				# All the others need spaces both sides.
4573cf655043SAndy Whitcroft				} elsif ($ctx !~ /[EWC]x[CWE]/) {
45741f65f947SAndy Whitcroft					my $ok = 0;
45751f65f947SAndy Whitcroft
457622f2a2efSAndy Whitcroft					# Ignore email addresses <foo@bar>
45771f65f947SAndy Whitcroft					if (($op eq '<' &&
45781f65f947SAndy Whitcroft					     $cc =~ /^\S+\@\S+>/) ||
45791f65f947SAndy Whitcroft					    ($op eq '>' &&
45801f65f947SAndy Whitcroft					     $ca =~ /<\S+\@\S+$/))
45811f65f947SAndy Whitcroft					{
45821f65f947SAndy Whitcroft					    	$ok = 1;
45831f65f947SAndy Whitcroft					}
45841f65f947SAndy Whitcroft
4585e0df7e1fSJoe Perches					# for asm volatile statements
4586e0df7e1fSJoe Perches					# ignore a colon with another
4587e0df7e1fSJoe Perches					# colon immediately before or after
4588e0df7e1fSJoe Perches					if (($op eq ':') &&
4589e0df7e1fSJoe Perches					    ($ca =~ /:$/ || $cc =~ /^:/)) {
4590e0df7e1fSJoe Perches						$ok = 1;
4591e0df7e1fSJoe Perches					}
4592e0df7e1fSJoe Perches
459384731623SJoe Perches					# messages are ERROR, but ?: are CHK
45941f65f947SAndy Whitcroft					if ($ok == 0) {
45950675a8fbSJean Delvare						my $msg_level = \&ERROR;
45960675a8fbSJean Delvare						$msg_level = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
459784731623SJoe Perches
45980675a8fbSJean Delvare						if (&{$msg_level}("SPACING",
45993705ce5bSJoe Perches								  "spaces required around that '$op' $at\n" . $hereptr)) {
4600b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4601b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
4602b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4603b34c648bSJoe Perches							}
46043705ce5bSJoe Perches							$line_fixed = 1;
46053705ce5bSJoe Perches						}
46060a920b5bSAndy Whitcroft					}
460722f2a2efSAndy Whitcroft				}
46084a0df2efSAndy Whitcroft				$off += length($elements[$n + 1]);
46093705ce5bSJoe Perches
46103705ce5bSJoe Perches##				print("n: <$n> GOOD: <$good>\n");
46113705ce5bSJoe Perches
46123705ce5bSJoe Perches				$fixed_line = $fixed_line . $good;
46130a920b5bSAndy Whitcroft			}
46143705ce5bSJoe Perches
46153705ce5bSJoe Perches			if (($#elements % 2) == 0) {
46163705ce5bSJoe Perches				$fixed_line = $fixed_line . $fix_elements[$#elements];
46173705ce5bSJoe Perches			}
46183705ce5bSJoe Perches
4619194f66fcSJoe Perches			if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
4620194f66fcSJoe Perches				$fixed[$fixlinenr] = $fixed_line;
46213705ce5bSJoe Perches			}
46223705ce5bSJoe Perches
46233705ce5bSJoe Perches
46240a920b5bSAndy Whitcroft		}
46250a920b5bSAndy Whitcroft
4626786b6326SJoe Perches# check for whitespace before a non-naked semicolon
4627d2e248e7SJoe Perches		if ($line =~ /^\+.*\S\s+;\s*$/) {
4628786b6326SJoe Perches			if (WARN("SPACING",
4629786b6326SJoe Perches				 "space prohibited before semicolon\n" . $herecurr) &&
4630786b6326SJoe Perches			    $fix) {
4631194f66fcSJoe Perches				1 while $fixed[$fixlinenr] =~
4632786b6326SJoe Perches				    s/^(\+.*\S)\s+;/$1;/;
4633786b6326SJoe Perches			}
4634786b6326SJoe Perches		}
4635786b6326SJoe Perches
4636f0a594c1SAndy Whitcroft# check for multiple assignments
4637f0a594c1SAndy Whitcroft		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
4638000d1cc1SJoe Perches			CHK("MULTIPLE_ASSIGNMENTS",
4639000d1cc1SJoe Perches			    "multiple assignments should be avoided\n" . $herecurr);
4640f0a594c1SAndy Whitcroft		}
4641f0a594c1SAndy Whitcroft
464222f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration
464322f2a2efSAndy Whitcroft## # continuation.
464422f2a2efSAndy Whitcroft## 		if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
464522f2a2efSAndy Whitcroft## 		    $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
464622f2a2efSAndy Whitcroft##
464722f2a2efSAndy Whitcroft## 			# Remove any bracketed sections to ensure we do not
464822f2a2efSAndy Whitcroft## 			# falsly report the parameters of functions.
464922f2a2efSAndy Whitcroft## 			my $ln = $line;
465022f2a2efSAndy Whitcroft## 			while ($ln =~ s/\([^\(\)]*\)//g) {
465122f2a2efSAndy Whitcroft## 			}
465222f2a2efSAndy Whitcroft## 			if ($ln =~ /,/) {
4653000d1cc1SJoe Perches## 				WARN("MULTIPLE_DECLARATION",
4654000d1cc1SJoe Perches##				     "declaring multiple variables together should be avoided\n" . $herecurr);
465522f2a2efSAndy Whitcroft## 			}
465622f2a2efSAndy Whitcroft## 		}
4657f0a594c1SAndy Whitcroft
46580a920b5bSAndy Whitcroft#need space before brace following if, while, etc
46596b8c69e4SGeyslan G. Bem		if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
46606ad724e2SMichal Zylowski		    $line =~ /\b(?:else|do)\{/) {
46613705ce5bSJoe Perches			if (ERROR("SPACING",
46623705ce5bSJoe Perches				  "space required before the open brace '{'\n" . $herecurr) &&
46633705ce5bSJoe Perches			    $fix) {
46646ad724e2SMichal Zylowski				$fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/;
46653705ce5bSJoe Perches			}
4666de7d4f0eSAndy Whitcroft		}
4667de7d4f0eSAndy Whitcroft
4668c4a62ef9SJoe Perches## # check for blank lines before declarations
4669c4a62ef9SJoe Perches##		if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
4670c4a62ef9SJoe Perches##		    $prevrawline =~ /^.\s*$/) {
4671c4a62ef9SJoe Perches##			WARN("SPACING",
4672c4a62ef9SJoe Perches##			     "No blank lines before declarations\n" . $hereprev);
4673c4a62ef9SJoe Perches##		}
4674c4a62ef9SJoe Perches##
4675c4a62ef9SJoe Perches
4676de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything
4677de7d4f0eSAndy Whitcroft# on the line
467894fb9845SJoe Perches		if ($line =~ /}(?!(?:,|;|\)|\}))\S/) {
4679d5e616fcSJoe Perches			if (ERROR("SPACING",
4680d5e616fcSJoe Perches				  "space required after that close brace '}'\n" . $herecurr) &&
4681d5e616fcSJoe Perches			    $fix) {
4682194f66fcSJoe Perches				$fixed[$fixlinenr] =~
4683d5e616fcSJoe Perches				    s/}((?!(?:,|;|\)))\S)/} $1/;
4684d5e616fcSJoe Perches			}
46850a920b5bSAndy Whitcroft		}
46860a920b5bSAndy Whitcroft
468722f2a2efSAndy Whitcroft# check spacing on square brackets
468822f2a2efSAndy Whitcroft		if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
46893705ce5bSJoe Perches			if (ERROR("SPACING",
46903705ce5bSJoe Perches				  "space prohibited after that open square bracket '['\n" . $herecurr) &&
46913705ce5bSJoe Perches			    $fix) {
4692194f66fcSJoe Perches				$fixed[$fixlinenr] =~
46933705ce5bSJoe Perches				    s/\[\s+/\[/;
46943705ce5bSJoe Perches			}
469522f2a2efSAndy Whitcroft		}
469622f2a2efSAndy Whitcroft		if ($line =~ /\s\]/) {
46973705ce5bSJoe Perches			if (ERROR("SPACING",
46983705ce5bSJoe Perches				  "space prohibited before that close square bracket ']'\n" . $herecurr) &&
46993705ce5bSJoe Perches			    $fix) {
4700194f66fcSJoe Perches				$fixed[$fixlinenr] =~
47013705ce5bSJoe Perches				    s/\s+\]/\]/;
47023705ce5bSJoe Perches			}
470322f2a2efSAndy Whitcroft		}
470422f2a2efSAndy Whitcroft
4705c45dcabdSAndy Whitcroft# check spacing on parentheses
47069c0ca6f9SAndy Whitcroft		if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
47079c0ca6f9SAndy Whitcroft		    $line !~ /for\s*\(\s+;/) {
47083705ce5bSJoe Perches			if (ERROR("SPACING",
47093705ce5bSJoe Perches				  "space prohibited after that open parenthesis '('\n" . $herecurr) &&
47103705ce5bSJoe Perches			    $fix) {
4711194f66fcSJoe Perches				$fixed[$fixlinenr] =~
47123705ce5bSJoe Perches				    s/\(\s+/\(/;
47133705ce5bSJoe Perches			}
471422f2a2efSAndy Whitcroft		}
471513214adfSAndy Whitcroft		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
4716c45dcabdSAndy Whitcroft		    $line !~ /for\s*\(.*;\s+\)/ &&
4717c45dcabdSAndy Whitcroft		    $line !~ /:\s+\)/) {
47183705ce5bSJoe Perches			if (ERROR("SPACING",
47193705ce5bSJoe Perches				  "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
47203705ce5bSJoe Perches			    $fix) {
4721194f66fcSJoe Perches				$fixed[$fixlinenr] =~
47223705ce5bSJoe Perches				    s/\s+\)/\)/;
47233705ce5bSJoe Perches			}
472422f2a2efSAndy Whitcroft		}
472522f2a2efSAndy Whitcroft
4726e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals
4727e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
4728e2826fd0SJoe Perches
4729e2826fd0SJoe Perches		while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
4730ea4acbb1SJoe Perches			my $var = $1;
4731ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
4732ea4acbb1SJoe Perches				"Unnecessary parentheses around $var\n" . $herecurr) &&
4733ea4acbb1SJoe Perches			    $fix) {
4734ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
4735ea4acbb1SJoe Perches			}
4736ea4acbb1SJoe Perches		}
4737ea4acbb1SJoe Perches
4738ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses
4739ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar();
4740ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives
4741ea4acbb1SJoe Perches		if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
4742ea4acbb1SJoe Perches			my $var = $2;
4743ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
4744ea4acbb1SJoe Perches				"Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
4745ea4acbb1SJoe Perches			    $fix) {
4746ea4acbb1SJoe Perches				my $var2 = deparenthesize($var);
4747ea4acbb1SJoe Perches				$var2 =~ s/\s//g;
4748ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
4749ea4acbb1SJoe Perches			}
4750e2826fd0SJoe Perches		}
4751e2826fd0SJoe Perches
475263b7c73eSJoe Perches# check for unnecessary parentheses around comparisons in if uses
4753a032aa4cSJoe Perches# when !drivers/staging or command-line uses --strict
4754a032aa4cSJoe Perches		if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) &&
47555b57980dSJoe Perches		    $perl_version_ok && defined($stat) &&
475663b7c73eSJoe Perches		    $stat =~ /(^.\s*if\s*($balanced_parens))/) {
475763b7c73eSJoe Perches			my $if_stat = $1;
475863b7c73eSJoe Perches			my $test = substr($2, 1, -1);
475963b7c73eSJoe Perches			my $herectx;
476063b7c73eSJoe Perches			while ($test =~ /(?:^|[^\w\&\!\~])+\s*\(\s*([\&\!\~]?\s*$Lval\s*(?:$Compare\s*$FuncArg)?)\s*\)/g) {
476163b7c73eSJoe Perches				my $match = $1;
476263b7c73eSJoe Perches				# avoid parentheses around potential macro args
476363b7c73eSJoe Perches				next if ($match =~ /^\s*\w+\s*$/);
476463b7c73eSJoe Perches				if (!defined($herectx)) {
476563b7c73eSJoe Perches					$herectx = $here . "\n";
476663b7c73eSJoe Perches					my $cnt = statement_rawlines($if_stat);
476763b7c73eSJoe Perches					for (my $n = 0; $n < $cnt; $n++) {
476863b7c73eSJoe Perches						my $rl = raw_line($linenr, $n);
476963b7c73eSJoe Perches						$herectx .=  $rl . "\n";
477063b7c73eSJoe Perches						last if $rl =~ /^[ \+].*\{/;
477163b7c73eSJoe Perches					}
477263b7c73eSJoe Perches				}
477363b7c73eSJoe Perches				CHK("UNNECESSARY_PARENTHESES",
477463b7c73eSJoe Perches				    "Unnecessary parentheses around '$match'\n" . $herectx);
477563b7c73eSJoe Perches			}
477663b7c73eSJoe Perches		}
477763b7c73eSJoe Perches
47780a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however
47794a0df2efSAndy Whitcroft		if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
47800a920b5bSAndy Whitcroft		   !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
47813705ce5bSJoe Perches			if (WARN("INDENTED_LABEL",
47823705ce5bSJoe Perches				 "labels should not be indented\n" . $herecurr) &&
47833705ce5bSJoe Perches			    $fix) {
4784194f66fcSJoe Perches				$fixed[$fixlinenr] =~
47853705ce5bSJoe Perches				    s/^(.)\s+/$1/;
47863705ce5bSJoe Perches			}
47870a920b5bSAndy Whitcroft		}
47880a920b5bSAndy Whitcroft
47895b9553abSJoe Perches# return is not a function
4790507e5141SJoe Perches		if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
4791c45dcabdSAndy Whitcroft			my $spacing = $1;
47925b57980dSJoe Perches			if ($perl_version_ok &&
47935b9553abSJoe Perches			    $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
47945b9553abSJoe Perches				my $value = $1;
47955b9553abSJoe Perches				$value = deparenthesize($value);
47965b9553abSJoe Perches				if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
4797000d1cc1SJoe Perches					ERROR("RETURN_PARENTHESES",
4798000d1cc1SJoe Perches					      "return is not a function, parentheses are not required\n" . $herecurr);
47995b9553abSJoe Perches				}
4800c45dcabdSAndy Whitcroft			} elsif ($spacing !~ /\s+/) {
4801000d1cc1SJoe Perches				ERROR("SPACING",
4802000d1cc1SJoe Perches				      "space required before the open parenthesis '('\n" . $herecurr);
4803c45dcabdSAndy Whitcroft			}
4804c45dcabdSAndy Whitcroft		}
4805507e5141SJoe Perches
4806b43ae21bSJoe Perches# unnecessary return in a void function
4807b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return;
4808b43ae21bSJoe Perches# and the line before that not a goto label target like "out:"
4809b43ae21bSJoe Perches		if ($sline =~ /^[ \+]}\s*$/ &&
4810b43ae21bSJoe Perches		    $prevline =~ /^\+\treturn\s*;\s*$/ &&
4811b43ae21bSJoe Perches		    $linenr >= 3 &&
4812b43ae21bSJoe Perches		    $lines[$linenr - 3] =~ /^[ +]/ &&
4813b43ae21bSJoe Perches		    $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
48149819cf25SJoe Perches			WARN("RETURN_VOID",
4815b43ae21bSJoe Perches			     "void function return statements are not generally useful\n" . $hereprev);
48169819cf25SJoe Perches               }
48179819cf25SJoe Perches
4818189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar))
48195b57980dSJoe Perches		if ($perl_version_ok &&
4820189248d8SJoe Perches		    $line =~ /\bif\s*((?:\(\s*){2,})/) {
4821189248d8SJoe Perches			my $openparens = $1;
4822189248d8SJoe Perches			my $count = $openparens =~ tr@\(@\(@;
4823189248d8SJoe Perches			my $msg = "";
4824189248d8SJoe Perches			if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
4825189248d8SJoe Perches				my $comp = $4;	#Not $1 because of $LvalOrFunc
4826189248d8SJoe Perches				$msg = " - maybe == should be = ?" if ($comp eq "==");
4827189248d8SJoe Perches				WARN("UNNECESSARY_PARENTHESES",
4828189248d8SJoe Perches				     "Unnecessary parentheses$msg\n" . $herecurr);
4829189248d8SJoe Perches			}
4830189248d8SJoe Perches		}
4831189248d8SJoe Perches
4832c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left
4833c5595fa2SJoe Perches#	avoid cases like "foo + BAR < baz"
4834c5595fa2SJoe Perches#	only fix matches surrounded by parentheses to avoid incorrect
4835c5595fa2SJoe Perches#	conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
48365b57980dSJoe Perches		if ($perl_version_ok &&
4837c5595fa2SJoe Perches		    $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
4838c5595fa2SJoe Perches			my $lead = $1;
4839c5595fa2SJoe Perches			my $const = $2;
4840c5595fa2SJoe Perches			my $comp = $3;
4841c5595fa2SJoe Perches			my $to = $4;
4842c5595fa2SJoe Perches			my $newcomp = $comp;
4843f39e1769SJoe Perches			if ($lead !~ /(?:$Operators|\.)\s*$/ &&
4844c5595fa2SJoe Perches			    $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
4845c5595fa2SJoe Perches			    WARN("CONSTANT_COMPARISON",
4846c5595fa2SJoe Perches				 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
4847c5595fa2SJoe Perches			    $fix) {
4848c5595fa2SJoe Perches				if ($comp eq "<") {
4849c5595fa2SJoe Perches					$newcomp = ">";
4850c5595fa2SJoe Perches				} elsif ($comp eq "<=") {
4851c5595fa2SJoe Perches					$newcomp = ">=";
4852c5595fa2SJoe Perches				} elsif ($comp eq ">") {
4853c5595fa2SJoe Perches					$newcomp = "<";
4854c5595fa2SJoe Perches				} elsif ($comp eq ">=") {
4855c5595fa2SJoe Perches					$newcomp = "<=";
4856c5595fa2SJoe Perches				}
4857c5595fa2SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
4858c5595fa2SJoe Perches			}
4859c5595fa2SJoe Perches		}
4860c5595fa2SJoe Perches
4861f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative
4862f34e4a4fSJoe Perches		if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
486353a3c448SAndy Whitcroft			my $name = $1;
486453a3c448SAndy Whitcroft			if ($name ne 'EOF' && $name ne 'ERROR') {
4865000d1cc1SJoe Perches				WARN("USE_NEGATIVE_ERRNO",
4866f34e4a4fSJoe Perches				     "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
486753a3c448SAndy Whitcroft			}
486853a3c448SAndy Whitcroft		}
4869c45dcabdSAndy Whitcroft
48700a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc
48714a0df2efSAndy Whitcroft		if ($line =~ /\b(if|while|for|switch)\(/) {
48723705ce5bSJoe Perches			if (ERROR("SPACING",
48733705ce5bSJoe Perches				  "space required before the open parenthesis '('\n" . $herecurr) &&
48743705ce5bSJoe Perches			    $fix) {
4875194f66fcSJoe Perches				$fixed[$fixlinenr] =~
48763705ce5bSJoe Perches				    s/\b(if|while|for|switch)\(/$1 \(/;
48773705ce5bSJoe Perches			}
48780a920b5bSAndy Whitcroft		}
48790a920b5bSAndy Whitcroft
4880f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing
4881f5fe35ddSAndy Whitcroft# statements after the conditional.
4882170d3a22SAndy Whitcroft		if ($line =~ /do\s*(?!{)/) {
48833e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
48843e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
48853e469cdcSAndy Whitcroft					if (!defined $stat);
4886170d3a22SAndy Whitcroft			my ($stat_next) = ctx_statement_block($line_nr_next,
4887170d3a22SAndy Whitcroft						$remain_next, $off_next);
4888170d3a22SAndy Whitcroft			$stat_next =~ s/\n./\n /g;
4889170d3a22SAndy Whitcroft			##print "stat<$stat> stat_next<$stat_next>\n";
4890170d3a22SAndy Whitcroft
4891170d3a22SAndy Whitcroft			if ($stat_next =~ /^\s*while\b/) {
4892170d3a22SAndy Whitcroft				# If the statement carries leading newlines,
4893170d3a22SAndy Whitcroft				# then count those as offsets.
4894170d3a22SAndy Whitcroft				my ($whitespace) =
4895170d3a22SAndy Whitcroft					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
4896170d3a22SAndy Whitcroft				my $offset =
4897170d3a22SAndy Whitcroft					statement_rawlines($whitespace) - 1;
4898170d3a22SAndy Whitcroft
4899170d3a22SAndy Whitcroft				$suppress_whiletrailers{$line_nr_next +
4900170d3a22SAndy Whitcroft								$offset} = 1;
4901170d3a22SAndy Whitcroft			}
4902170d3a22SAndy Whitcroft		}
4903170d3a22SAndy Whitcroft		if (!defined $suppress_whiletrailers{$linenr} &&
4904c11230f4SJoe Perches		    defined($stat) && defined($cond) &&
4905170d3a22SAndy Whitcroft		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
4906171ae1a4SAndy Whitcroft			my ($s, $c) = ($stat, $cond);
49078905a67cSAndy Whitcroft
4908b53c8e10SAndy Whitcroft			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
4909000d1cc1SJoe Perches				ERROR("ASSIGN_IN_IF",
4910000d1cc1SJoe Perches				      "do not use assignment in if condition\n" . $herecurr);
49118905a67cSAndy Whitcroft			}
49128905a67cSAndy Whitcroft
49138905a67cSAndy Whitcroft			# Find out what is on the end of the line after the
49148905a67cSAndy Whitcroft			# conditional.
4915773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
49168905a67cSAndy Whitcroft			$s =~ s/\n.*//g;
491713214adfSAndy Whitcroft			$s =~ s/$;//g; 	# Remove any comments
491853210168SAndy Whitcroft			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
491953210168SAndy Whitcroft			    $c !~ /}\s*while\s*/)
4920773647a0SAndy Whitcroft			{
4921bb44ad39SAndy Whitcroft				# Find out how long the conditional actually is.
4922bb44ad39SAndy Whitcroft				my @newlines = ($c =~ /\n/gs);
4923bb44ad39SAndy Whitcroft				my $cond_lines = 1 + $#newlines;
492442bdf74cSHidetoshi Seto				my $stat_real = '';
4925bb44ad39SAndy Whitcroft
492642bdf74cSHidetoshi Seto				$stat_real = raw_line($linenr, $cond_lines)
492742bdf74cSHidetoshi Seto							. "\n" if ($cond_lines);
4928bb44ad39SAndy Whitcroft				if (defined($stat_real) && $cond_lines > 1) {
4929bb44ad39SAndy Whitcroft					$stat_real = "[...]\n$stat_real";
4930bb44ad39SAndy Whitcroft				}
4931bb44ad39SAndy Whitcroft
4932000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
4933000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr . $stat_real);
49348905a67cSAndy Whitcroft			}
49358905a67cSAndy Whitcroft		}
49368905a67cSAndy Whitcroft
493713214adfSAndy Whitcroft# Check for bitwise tests written as boolean
493813214adfSAndy Whitcroft		if ($line =~ /
493913214adfSAndy Whitcroft			(?:
494013214adfSAndy Whitcroft				(?:\[|\(|\&\&|\|\|)
494113214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
494213214adfSAndy Whitcroft				(?:\&\&|\|\|)
494313214adfSAndy Whitcroft			|
494413214adfSAndy Whitcroft				(?:\&\&|\|\|)
494513214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
494613214adfSAndy Whitcroft				(?:\&\&|\|\||\)|\])
494713214adfSAndy Whitcroft			)/x)
494813214adfSAndy Whitcroft		{
4949000d1cc1SJoe Perches			WARN("HEXADECIMAL_BOOLEAN_TEST",
4950000d1cc1SJoe Perches			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
495113214adfSAndy Whitcroft		}
495213214adfSAndy Whitcroft
49538905a67cSAndy Whitcroft# if and else should not have general statements after it
495413214adfSAndy Whitcroft		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
495513214adfSAndy Whitcroft			my $s = $1;
495613214adfSAndy Whitcroft			$s =~ s/$;//g; 	# Remove any comments
495713214adfSAndy Whitcroft			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
4958000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
4959000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr);
49600a920b5bSAndy Whitcroft			}
496113214adfSAndy Whitcroft		}
496239667782SAndy Whitcroft# if should not continue a brace
496339667782SAndy Whitcroft		if ($line =~ /}\s*if\b/) {
4964000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
4965048b123fSRasmus Villemoes			      "trailing statements should be on next line (or did you mean 'else if'?)\n" .
496639667782SAndy Whitcroft				$herecurr);
496739667782SAndy Whitcroft		}
4968a1080bf8SAndy Whitcroft# case and default should not have general statements after them
4969a1080bf8SAndy Whitcroft		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
4970a1080bf8SAndy Whitcroft		    $line !~ /\G(?:
49713fef12d6SAndy Whitcroft			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
4972a1080bf8SAndy Whitcroft			\s*return\s+
4973a1080bf8SAndy Whitcroft		    )/xg)
4974a1080bf8SAndy Whitcroft		{
4975000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
4976000d1cc1SJoe Perches			      "trailing statements should be on next line\n" . $herecurr);
4977a1080bf8SAndy Whitcroft		}
49780a920b5bSAndy Whitcroft
49790a920b5bSAndy Whitcroft		# Check for }<nl>else {, these must be at the same
49800a920b5bSAndy Whitcroft		# indent level to be relevant to each other.
49818b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
49820a920b5bSAndy Whitcroft		    $previndent == $indent) {
49838b8856f4SJoe Perches			if (ERROR("ELSE_AFTER_BRACE",
49848b8856f4SJoe Perches				  "else should follow close brace '}'\n" . $hereprev) &&
49858b8856f4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
49868b8856f4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
49878b8856f4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
49888b8856f4SJoe Perches				my $fixedline = $prevrawline;
49898b8856f4SJoe Perches				$fixedline =~ s/}\s*$//;
49908b8856f4SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
49918b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
49928b8856f4SJoe Perches				}
49938b8856f4SJoe Perches				$fixedline = $rawline;
49948b8856f4SJoe Perches				$fixedline =~ s/^(.\s*)else/$1} else/;
49958b8856f4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
49968b8856f4SJoe Perches			}
49970a920b5bSAndy Whitcroft		}
49980a920b5bSAndy Whitcroft
49998b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
5000c2fdda0dSAndy Whitcroft		    $previndent == $indent) {
5001c2fdda0dSAndy Whitcroft			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
5002c2fdda0dSAndy Whitcroft
5003c2fdda0dSAndy Whitcroft			# Find out what is on the end of the line after the
5004c2fdda0dSAndy Whitcroft			# conditional.
5005773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
5006c2fdda0dSAndy Whitcroft			$s =~ s/\n.*//g;
5007c2fdda0dSAndy Whitcroft
5008c2fdda0dSAndy Whitcroft			if ($s =~ /^\s*;/) {
50098b8856f4SJoe Perches				if (ERROR("WHILE_AFTER_BRACE",
50108b8856f4SJoe Perches					  "while should follow close brace '}'\n" . $hereprev) &&
50118b8856f4SJoe Perches				    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
50128b8856f4SJoe Perches					fix_delete_line($fixlinenr - 1, $prevrawline);
50138b8856f4SJoe Perches					fix_delete_line($fixlinenr, $rawline);
50148b8856f4SJoe Perches					my $fixedline = $prevrawline;
50158b8856f4SJoe Perches					my $trailing = $rawline;
50168b8856f4SJoe Perches					$trailing =~ s/^\+//;
50178b8856f4SJoe Perches					$trailing = trim($trailing);
50188b8856f4SJoe Perches					$fixedline =~ s/}\s*$/} $trailing/;
50198b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
50208b8856f4SJoe Perches				}
5021c2fdda0dSAndy Whitcroft			}
5022c2fdda0dSAndy Whitcroft		}
5023c2fdda0dSAndy Whitcroft
502495e2c602SJoe Perches#Specific variable tests
5025323c1260SJoe Perches		while ($line =~ m{($Constant|$Lval)}g) {
5026323c1260SJoe Perches			my $var = $1;
502795e2c602SJoe Perches
502895e2c602SJoe Perches#CamelCase
5029807bd26cSJoe Perches			if ($var !~ /^$Constant$/ &&
5030be79794bSJoe Perches			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
503122735ce8SJoe Perches#Ignore Page<foo> variants
5032807bd26cSJoe Perches			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
503322735ce8SJoe Perches#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show)
5034f5123576SJulius Werner			    $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ &&
5035f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz
5036f5123576SJulius Werner			    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
50377e781f67SJoe Perches				while ($var =~ m{($Ident)}g) {
50387e781f67SJoe Perches					my $word = $1;
50397e781f67SJoe Perches					next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
5040d8b07710SJoe Perches					if ($check) {
5041d8b07710SJoe Perches						seed_camelcase_includes();
5042d8b07710SJoe Perches						if (!$file && !$camelcase_file_seeded) {
5043d8b07710SJoe Perches							seed_camelcase_file($realfile);
5044d8b07710SJoe Perches							$camelcase_file_seeded = 1;
5045d8b07710SJoe Perches						}
5046d8b07710SJoe Perches					}
50477e781f67SJoe Perches					if (!defined $camelcase{$word}) {
50487e781f67SJoe Perches						$camelcase{$word} = 1;
5049be79794bSJoe Perches						CHK("CAMELCASE",
50507e781f67SJoe Perches						    "Avoid CamelCase: <$word>\n" . $herecurr);
50517e781f67SJoe Perches					}
5052323c1260SJoe Perches				}
5053323c1260SJoe Perches			}
50543445686aSJoe Perches		}
50550a920b5bSAndy Whitcroft
50560a920b5bSAndy Whitcroft#no spaces allowed after \ in define
5057d5e616fcSJoe Perches		if ($line =~ /\#\s*define.*\\\s+$/) {
5058d5e616fcSJoe Perches			if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
5059d5e616fcSJoe Perches				 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
5060d5e616fcSJoe Perches			    $fix) {
5061194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
5062d5e616fcSJoe Perches			}
50630a920b5bSAndy Whitcroft		}
50640a920b5bSAndy Whitcroft
50650e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
50660e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line)
5067c45dcabdSAndy Whitcroft		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
5068e09dec48SAndy Whitcroft			my $file = "$1.h";
5069e09dec48SAndy Whitcroft			my $checkfile = "include/linux/$file";
5070e09dec48SAndy Whitcroft			if (-f "$root/$checkfile" &&
5071e09dec48SAndy Whitcroft			    $realfile ne $checkfile &&
50727840a94cSWolfram Sang			    $1 !~ /$allowed_asm_includes/)
5073c45dcabdSAndy Whitcroft			{
50740e212e0aSFabian Frederick				my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
50750e212e0aSFabian Frederick				if ($asminclude > 0) {
5076e09dec48SAndy Whitcroft					if ($realfile =~ m{^arch/}) {
5077000d1cc1SJoe Perches						CHK("ARCH_INCLUDE_LINUX",
5078000d1cc1SJoe Perches						    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5079e09dec48SAndy Whitcroft					} else {
5080000d1cc1SJoe Perches						WARN("INCLUDE_LINUX",
5081000d1cc1SJoe Perches						     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
5082e09dec48SAndy Whitcroft					}
50830a920b5bSAndy Whitcroft				}
50840a920b5bSAndy Whitcroft			}
50850e212e0aSFabian Frederick		}
50860a920b5bSAndy Whitcroft
5087653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the
5088653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed
5089cf655043SAndy Whitcroft# in a known good container
5090b8f96a31SAndy Whitcroft		if ($realfile !~ m@/vmlinux.lds.h$@ &&
5091b8f96a31SAndy Whitcroft		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
5092d8aaf121SAndy Whitcroft			my $ln = $linenr;
5093d8aaf121SAndy Whitcroft			my $cnt = $realcnt;
5094c45dcabdSAndy Whitcroft			my ($off, $dstat, $dcond, $rest);
5095c45dcabdSAndy Whitcroft			my $ctx = '';
509608a2843eSJoe Perches			my $has_flow_statement = 0;
509708a2843eSJoe Perches			my $has_arg_concat = 0;
5098c45dcabdSAndy Whitcroft			($dstat, $dcond, $ln, $cnt, $off) =
5099f74bd194SAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
5100f74bd194SAndy Whitcroft			$ctx = $dstat;
5101c45dcabdSAndy Whitcroft			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
5102a3bb97a7SAndy Whitcroft			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
5103c45dcabdSAndy Whitcroft
510408a2843eSJoe Perches			$has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
510562e15a6dSJoe Perches			$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
510608a2843eSJoe Perches
5107f59b64bfSJoe Perches			$dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
5108f59b64bfSJoe Perches			my $define_args = $1;
5109f59b64bfSJoe Perches			my $define_stmt = $dstat;
5110f59b64bfSJoe Perches			my @def_args = ();
5111f59b64bfSJoe Perches
5112f59b64bfSJoe Perches			if (defined $define_args && $define_args ne "") {
5113f59b64bfSJoe Perches				$define_args = substr($define_args, 1, length($define_args) - 2);
5114f59b64bfSJoe Perches				$define_args =~ s/\s*//g;
51158c8c45cfSJoe Perches				$define_args =~ s/\\\+?//g;
5116f59b64bfSJoe Perches				@def_args = split(",", $define_args);
5117f59b64bfSJoe Perches			}
5118f59b64bfSJoe Perches
5119292f1a9bSAndy Whitcroft			$dstat =~ s/$;//g;
5120c45dcabdSAndy Whitcroft			$dstat =~ s/\\\n.//g;
5121c45dcabdSAndy Whitcroft			$dstat =~ s/^\s*//s;
5122c45dcabdSAndy Whitcroft			$dstat =~ s/\s*$//s;
5123c45dcabdSAndy Whitcroft
5124c45dcabdSAndy Whitcroft			# Flatten any parentheses and braces
5125bf30d6edSAndy Whitcroft			while ($dstat =~ s/\([^\(\)]*\)/1/ ||
5126bf30d6edSAndy Whitcroft			       $dstat =~ s/\{[^\{\}]*\}/1/ ||
51276b10df42SVladimir Zapolskiy			       $dstat =~ s/.\[[^\[\]]*\]/1/)
5128bf30d6edSAndy Whitcroft			{
5129c45dcabdSAndy Whitcroft			}
5130c45dcabdSAndy Whitcroft
5131e45bab8eSAndy Whitcroft			# Flatten any obvious string concatentation.
513233acb54aSJoe Perches			while ($dstat =~ s/($String)\s*$Ident/$1/ ||
513333acb54aSJoe Perches			       $dstat =~ s/$Ident\s*($String)/$1/)
5134e45bab8eSAndy Whitcroft			{
5135e45bab8eSAndy Whitcroft			}
5136e45bab8eSAndy Whitcroft
513742e15293SJoe Perches			# Make asm volatile uses seem like a generic function
513842e15293SJoe Perches			$dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
513942e15293SJoe Perches
5140c45dcabdSAndy Whitcroft			my $exceptions = qr{
5141c45dcabdSAndy Whitcroft				$Declare|
5142c45dcabdSAndy Whitcroft				module_param_named|
5143a0a0a7a9SKees Cook				MODULE_PARM_DESC|
5144c45dcabdSAndy Whitcroft				DECLARE_PER_CPU|
5145c45dcabdSAndy Whitcroft				DEFINE_PER_CPU|
5146383099fdSAndy Whitcroft				__typeof__\(|
514722fd2d3eSStefani Seibold				union|
514822fd2d3eSStefani Seibold				struct|
5149ea71a0a0SAndy Whitcroft				\.$Ident\s*=\s*|
51506b10df42SVladimir Zapolskiy				^\"|\"$|
51516b10df42SVladimir Zapolskiy				^\[
5152c45dcabdSAndy Whitcroft			}x;
51535eaa20b9SAndy Whitcroft			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
5154f59b64bfSJoe Perches
5155f59b64bfSJoe Perches			$ctx =~ s/\n*$//;
5156f59b64bfSJoe Perches			my $stmt_cnt = statement_rawlines($ctx);
5157e3d95a2aSTobin C. Harding			my $herectx = get_stat_here($linenr, $stmt_cnt, $here);
5158f59b64bfSJoe Perches
5159f74bd194SAndy Whitcroft			if ($dstat ne '' &&
5160f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),
5161f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();
51623cc4b1c3SJoe Perches			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
5163356fd398SJoe Perches			    $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ &&			# character constants
5164f74bd194SAndy Whitcroft			    $dstat !~ /$exceptions/ &&
5165f74bd194SAndy Whitcroft			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
5166e942e2c3SJoe Perches			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #foo
516772f115f9SAndy Whitcroft			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
5168f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
5169f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
5170f74bd194SAndy Whitcroft			    $dstat !~ /^do\s*{/ &&					# do {...
51714e5d56bdSEddie Kovsky			    $dstat !~ /^\(\{/ &&						# ({...
5172f95a7e6aSJoe Perches			    $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
5173c45dcabdSAndy Whitcroft			{
5174e795556aSJoe Perches				if ($dstat =~ /^\s*if\b/) {
5175e795556aSJoe Perches					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5176e795556aSJoe Perches					      "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
5177e795556aSJoe Perches				} elsif ($dstat =~ /;/) {
5178f74bd194SAndy Whitcroft					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
5179f74bd194SAndy Whitcroft					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
5180f74bd194SAndy Whitcroft				} else {
5181000d1cc1SJoe Perches					ERROR("COMPLEX_MACRO",
5182388982b5SAndrew Morton					      "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
5183d8aaf121SAndy Whitcroft				}
5184f59b64bfSJoe Perches
5185f59b64bfSJoe Perches			}
51865207649bSJoe Perches
51875207649bSJoe Perches			# Make $define_stmt single line, comment-free, etc
51885207649bSJoe Perches			my @stmt_array = split('\n', $define_stmt);
51895207649bSJoe Perches			my $first = 1;
51905207649bSJoe Perches			$define_stmt = "";
51915207649bSJoe Perches			foreach my $l (@stmt_array) {
51925207649bSJoe Perches				$l =~ s/\\$//;
51935207649bSJoe Perches				if ($first) {
51945207649bSJoe Perches					$define_stmt = $l;
51955207649bSJoe Perches					$first = 0;
51965207649bSJoe Perches				} elsif ($l =~ /^[\+ ]/) {
51975207649bSJoe Perches					$define_stmt .= substr($l, 1);
51985207649bSJoe Perches				}
51995207649bSJoe Perches			}
52005207649bSJoe Perches			$define_stmt =~ s/$;//g;
52015207649bSJoe Perches			$define_stmt =~ s/\s+/ /g;
52025207649bSJoe Perches			$define_stmt = trim($define_stmt);
52035207649bSJoe Perches
5204f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type')
5205f59b64bfSJoe Perches			foreach my $arg (@def_args) {
5206f59b64bfSJoe Perches			        next if ($arg =~ /\.\.\./);
52079192d41aSJoe Perches			        next if ($arg =~ /^type$/i);
52087fe528a2SJoe Perches				my $tmp_stmt = $define_stmt;
52096dba824eSBrendan Jackman				$tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
52107fe528a2SJoe Perches				$tmp_stmt =~ s/\#+\s*$arg\b//g;
52117fe528a2SJoe Perches				$tmp_stmt =~ s/\b$arg\s*\#\#//g;
5212d41362edSJoe Perches				my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g;
5213f59b64bfSJoe Perches				if ($use_cnt > 1) {
5214f59b64bfSJoe Perches					CHK("MACRO_ARG_REUSE",
5215f59b64bfSJoe Perches					    "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
5216f59b64bfSJoe Perches				    }
52179192d41aSJoe Perches# check if any macro arguments may have other precedence issues
52187fe528a2SJoe Perches				if ($tmp_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
52199192d41aSJoe Perches				    ((defined($1) && $1 ne ',') ||
52209192d41aSJoe Perches				     (defined($2) && $2 ne ','))) {
52219192d41aSJoe Perches					CHK("MACRO_ARG_PRECEDENCE",
52229192d41aSJoe Perches					    "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
52239192d41aSJoe Perches				}
52240a920b5bSAndy Whitcroft			}
52255023d347SJoe Perches
522608a2843eSJoe Perches# check for macros with flow control, but without ## concatenation
522708a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those
522808a2843eSJoe Perches			if ($has_flow_statement && !$has_arg_concat) {
522908a2843eSJoe Perches				my $cnt = statement_rawlines($ctx);
5230e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
523108a2843eSJoe Perches
523208a2843eSJoe Perches				WARN("MACRO_WITH_FLOW_CONTROL",
523308a2843eSJoe Perches				     "Macros with flow control statements should be avoided\n" . "$herectx");
523408a2843eSJoe Perches			}
523508a2843eSJoe Perches
5236481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm
52375023d347SJoe Perches
52385023d347SJoe Perches		} else {
52395023d347SJoe Perches			if ($prevline !~ /^..*\\$/ &&
5240481eb486SJoe Perches			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
5241481eb486SJoe Perches			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
52425023d347SJoe Perches			    $line =~ /^\+.*\\$/) {
52435023d347SJoe Perches				WARN("LINE_CONTINUATIONS",
52445023d347SJoe Perches				     "Avoid unnecessary line continuations\n" . $herecurr);
52455023d347SJoe Perches			}
5246653d4876SAndy Whitcroft		}
52470a920b5bSAndy Whitcroft
5248b13edf7fSJoe Perches# do {} while (0) macro tests:
5249b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop,
5250b13edf7fSJoe Perches# macro should not end with a semicolon
52515b57980dSJoe Perches		if ($perl_version_ok &&
5252b13edf7fSJoe Perches		    $realfile !~ m@/vmlinux.lds.h$@ &&
5253b13edf7fSJoe Perches		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
5254b13edf7fSJoe Perches			my $ln = $linenr;
5255b13edf7fSJoe Perches			my $cnt = $realcnt;
5256b13edf7fSJoe Perches			my ($off, $dstat, $dcond, $rest);
5257b13edf7fSJoe Perches			my $ctx = '';
5258b13edf7fSJoe Perches			($dstat, $dcond, $ln, $cnt, $off) =
5259b13edf7fSJoe Perches				ctx_statement_block($linenr, $realcnt, 0);
5260b13edf7fSJoe Perches			$ctx = $dstat;
5261b13edf7fSJoe Perches
5262b13edf7fSJoe Perches			$dstat =~ s/\\\n.//g;
52631b36b201SJoe Perches			$dstat =~ s/$;/ /g;
5264b13edf7fSJoe Perches
5265b13edf7fSJoe Perches			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
5266b13edf7fSJoe Perches				my $stmts = $2;
5267b13edf7fSJoe Perches				my $semis = $3;
5268b13edf7fSJoe Perches
5269b13edf7fSJoe Perches				$ctx =~ s/\n*$//;
5270b13edf7fSJoe Perches				my $cnt = statement_rawlines($ctx);
5271e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
5272b13edf7fSJoe Perches
5273ac8e97f8SJoe Perches				if (($stmts =~ tr/;/;/) == 1 &&
5274ac8e97f8SJoe Perches				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
5275b13edf7fSJoe Perches					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
5276b13edf7fSJoe Perches					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
5277b13edf7fSJoe Perches				}
5278b13edf7fSJoe Perches				if (defined $semis && $semis ne "") {
5279b13edf7fSJoe Perches					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
5280b13edf7fSJoe Perches					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
5281b13edf7fSJoe Perches				}
5282f5ef95b1SJoe Perches			} elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
5283f5ef95b1SJoe Perches				$ctx =~ s/\n*$//;
5284f5ef95b1SJoe Perches				my $cnt = statement_rawlines($ctx);
5285e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
5286f5ef95b1SJoe Perches
5287f5ef95b1SJoe Perches				WARN("TRAILING_SEMICOLON",
5288f5ef95b1SJoe Perches				     "macros should not use a trailing semicolon\n" . "$herectx");
5289b13edf7fSJoe Perches			}
5290b13edf7fSJoe Perches		}
5291b13edf7fSJoe Perches
5292f0a594c1SAndy Whitcroft# check for redundant bracing round if etc
529313214adfSAndy Whitcroft		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
529413214adfSAndy Whitcroft			my ($level, $endln, @chunks) =
5295cf655043SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, 1);
529613214adfSAndy Whitcroft			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
5297cf655043SAndy Whitcroft			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
5298cf655043SAndy Whitcroft			if ($#chunks > 0 && $level == 0) {
5299aad4f614SJoe Perches				my @allowed = ();
5300aad4f614SJoe Perches				my $allow = 0;
530113214adfSAndy Whitcroft				my $seen = 0;
5302773647a0SAndy Whitcroft				my $herectx = $here . "\n";
5303cf655043SAndy Whitcroft				my $ln = $linenr - 1;
530413214adfSAndy Whitcroft				for my $chunk (@chunks) {
530513214adfSAndy Whitcroft					my ($cond, $block) = @{$chunk};
530613214adfSAndy Whitcroft
5307773647a0SAndy Whitcroft					# If the condition carries leading newlines, then count those as offsets.
5308773647a0SAndy Whitcroft					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
5309773647a0SAndy Whitcroft					my $offset = statement_rawlines($whitespace) - 1;
5310773647a0SAndy Whitcroft
5311aad4f614SJoe Perches					$allowed[$allow] = 0;
5312773647a0SAndy Whitcroft					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
5313773647a0SAndy Whitcroft
5314773647a0SAndy Whitcroft					# We have looked at and allowed this specific line.
5315773647a0SAndy Whitcroft					$suppress_ifbraces{$ln + $offset} = 1;
5316773647a0SAndy Whitcroft
5317773647a0SAndy Whitcroft					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
5318cf655043SAndy Whitcroft					$ln += statement_rawlines($block) - 1;
5319cf655043SAndy Whitcroft
5320773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
532113214adfSAndy Whitcroft
532213214adfSAndy Whitcroft					$seen++ if ($block =~ /^\s*{/);
532313214adfSAndy Whitcroft
5324aad4f614SJoe Perches					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
5325cf655043SAndy Whitcroft					if (statement_lines($cond) > 1) {
5326cf655043SAndy Whitcroft						#print "APW: ALLOWED: cond<$cond>\n";
5327aad4f614SJoe Perches						$allowed[$allow] = 1;
532813214adfSAndy Whitcroft					}
532913214adfSAndy Whitcroft					if ($block =~/\b(?:if|for|while)\b/) {
5330cf655043SAndy Whitcroft						#print "APW: ALLOWED: block<$block>\n";
5331aad4f614SJoe Perches						$allowed[$allow] = 1;
533213214adfSAndy Whitcroft					}
5333cf655043SAndy Whitcroft					if (statement_block_size($block) > 1) {
5334cf655043SAndy Whitcroft						#print "APW: ALLOWED: lines block<$block>\n";
5335aad4f614SJoe Perches						$allowed[$allow] = 1;
533613214adfSAndy Whitcroft					}
5337aad4f614SJoe Perches					$allow++;
533813214adfSAndy Whitcroft				}
5339aad4f614SJoe Perches				if ($seen) {
5340aad4f614SJoe Perches					my $sum_allowed = 0;
5341aad4f614SJoe Perches					foreach (@allowed) {
5342aad4f614SJoe Perches						$sum_allowed += $_;
5343aad4f614SJoe Perches					}
5344aad4f614SJoe Perches					if ($sum_allowed == 0) {
5345000d1cc1SJoe Perches						WARN("BRACES",
5346000d1cc1SJoe Perches						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
5347aad4f614SJoe Perches					} elsif ($sum_allowed != $allow &&
5348aad4f614SJoe Perches						 $seen != $allow) {
5349aad4f614SJoe Perches						CHK("BRACES",
5350aad4f614SJoe Perches						    "braces {} should be used on all arms of this statement\n" . $herectx);
5351aad4f614SJoe Perches					}
535213214adfSAndy Whitcroft				}
535313214adfSAndy Whitcroft			}
535413214adfSAndy Whitcroft		}
5355773647a0SAndy Whitcroft		if (!defined $suppress_ifbraces{$linenr - 1} &&
535613214adfSAndy Whitcroft					$line =~ /\b(if|while|for|else)\b/) {
5357cf655043SAndy Whitcroft			my $allowed = 0;
5358f0a594c1SAndy Whitcroft
5359cf655043SAndy Whitcroft			# Check the pre-context.
5360cf655043SAndy Whitcroft			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
5361cf655043SAndy Whitcroft				#print "APW: ALLOWED: pre<$1>\n";
5362cf655043SAndy Whitcroft				$allowed = 1;
5363f0a594c1SAndy Whitcroft			}
5364773647a0SAndy Whitcroft
5365773647a0SAndy Whitcroft			my ($level, $endln, @chunks) =
5366773647a0SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, $-[0]);
5367773647a0SAndy Whitcroft
5368cf655043SAndy Whitcroft			# Check the condition.
5369cf655043SAndy Whitcroft			my ($cond, $block) = @{$chunks[0]};
5370773647a0SAndy Whitcroft			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
5371cf655043SAndy Whitcroft			if (defined $cond) {
5372773647a0SAndy Whitcroft				substr($block, 0, length($cond), '');
5373cf655043SAndy Whitcroft			}
5374cf655043SAndy Whitcroft			if (statement_lines($cond) > 1) {
5375cf655043SAndy Whitcroft				#print "APW: ALLOWED: cond<$cond>\n";
5376cf655043SAndy Whitcroft				$allowed = 1;
5377cf655043SAndy Whitcroft			}
5378cf655043SAndy Whitcroft			if ($block =~/\b(?:if|for|while)\b/) {
5379cf655043SAndy Whitcroft				#print "APW: ALLOWED: block<$block>\n";
5380cf655043SAndy Whitcroft				$allowed = 1;
5381cf655043SAndy Whitcroft			}
5382cf655043SAndy Whitcroft			if (statement_block_size($block) > 1) {
5383cf655043SAndy Whitcroft				#print "APW: ALLOWED: lines block<$block>\n";
5384cf655043SAndy Whitcroft				$allowed = 1;
5385cf655043SAndy Whitcroft			}
5386cf655043SAndy Whitcroft			# Check the post-context.
5387cf655043SAndy Whitcroft			if (defined $chunks[1]) {
5388cf655043SAndy Whitcroft				my ($cond, $block) = @{$chunks[1]};
5389cf655043SAndy Whitcroft				if (defined $cond) {
5390773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
5391cf655043SAndy Whitcroft				}
5392cf655043SAndy Whitcroft				if ($block =~ /^\s*\{/) {
5393cf655043SAndy Whitcroft					#print "APW: ALLOWED: chunk-1 block<$block>\n";
5394cf655043SAndy Whitcroft					$allowed = 1;
5395cf655043SAndy Whitcroft				}
5396cf655043SAndy Whitcroft			}
5397cf655043SAndy Whitcroft			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
5398f055663cSAndy Whitcroft				my $cnt = statement_rawlines($block);
5399e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
5400cf655043SAndy Whitcroft
5401000d1cc1SJoe Perches				WARN("BRACES",
5402000d1cc1SJoe Perches				     "braces {} are not necessary for single statement blocks\n" . $herectx);
5403f0a594c1SAndy Whitcroft			}
5404f0a594c1SAndy Whitcroft		}
5405f0a594c1SAndy Whitcroft
5406e4c5babdSJoe Perches# check for single line unbalanced braces
540795330473SSven Eckelmann		if ($sline =~ /^.\s*\}\s*else\s*$/ ||
540895330473SSven Eckelmann		    $sline =~ /^.\s*else\s*\{\s*$/) {
5409e4c5babdSJoe Perches			CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
5410e4c5babdSJoe Perches		}
5411e4c5babdSJoe Perches
54120979ae66SJoe Perches# check for unnecessary blank lines around braces
541377b9a53aSJoe Perches		if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
5414f8e58219SJoe Perches			if (CHK("BRACES",
5415f8e58219SJoe Perches				"Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
5416f8e58219SJoe Perches			    $fix && $prevrawline =~ /^\+/) {
5417f8e58219SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
5418f8e58219SJoe Perches			}
54190979ae66SJoe Perches		}
542077b9a53aSJoe Perches		if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
5421f8e58219SJoe Perches			if (CHK("BRACES",
5422f8e58219SJoe Perches				"Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
5423f8e58219SJoe Perches			    $fix) {
5424f8e58219SJoe Perches				fix_delete_line($fixlinenr, $rawline);
5425f8e58219SJoe Perches			}
54260979ae66SJoe Perches		}
54270979ae66SJoe Perches
54284a0df2efSAndy Whitcroft# no volatiles please
54296c72ffaaSAndy Whitcroft		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
54306c72ffaaSAndy Whitcroft		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
5431000d1cc1SJoe Perches			WARN("VOLATILE",
54328c27ceffSMauro Carvalho Chehab			     "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
54334a0df2efSAndy Whitcroft		}
54344a0df2efSAndy Whitcroft
54355e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability
54365e4f6ba5SJoe Perches# to grep for the string.  Make exceptions when the previous string ends in a
54375e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
54385e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
543933acb54aSJoe Perches		if ($line =~ /^\+\s*$String/ &&
54405e4f6ba5SJoe Perches		    $prevline =~ /"\s*$/ &&
54415e4f6ba5SJoe Perches		    $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
54425e4f6ba5SJoe Perches			if (WARN("SPLIT_STRING",
54435e4f6ba5SJoe Perches				 "quoted string split across lines\n" . $hereprev) &&
54445e4f6ba5SJoe Perches				     $fix &&
54455e4f6ba5SJoe Perches				     $prevrawline =~ /^\+.*"\s*$/ &&
54465e4f6ba5SJoe Perches				     $last_coalesced_string_linenr != $linenr - 1) {
54475e4f6ba5SJoe Perches				my $extracted_string = get_quoted_string($line, $rawline);
54485e4f6ba5SJoe Perches				my $comma_close = "";
54495e4f6ba5SJoe Perches				if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
54505e4f6ba5SJoe Perches					$comma_close = $1;
54515e4f6ba5SJoe Perches				}
54525e4f6ba5SJoe Perches
54535e4f6ba5SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
54545e4f6ba5SJoe Perches				fix_delete_line($fixlinenr, $rawline);
54555e4f6ba5SJoe Perches				my $fixedline = $prevrawline;
54565e4f6ba5SJoe Perches				$fixedline =~ s/"\s*$//;
54575e4f6ba5SJoe Perches				$fixedline .= substr($extracted_string, 1) . trim($comma_close);
54585e4f6ba5SJoe Perches				fix_insert_line($fixlinenr - 1, $fixedline);
54595e4f6ba5SJoe Perches				$fixedline = $rawline;
54605e4f6ba5SJoe Perches				$fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
54615e4f6ba5SJoe Perches				if ($fixedline !~ /\+\s*$/) {
54625e4f6ba5SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
54635e4f6ba5SJoe Perches				}
54645e4f6ba5SJoe Perches				$last_coalesced_string_linenr = $linenr;
54655e4f6ba5SJoe Perches			}
54665e4f6ba5SJoe Perches		}
54675e4f6ba5SJoe Perches
54685e4f6ba5SJoe Perches# check for missing a space in a string concatenation
54695e4f6ba5SJoe Perches		if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
54705e4f6ba5SJoe Perches			WARN('MISSING_SPACE',
54715e4f6ba5SJoe Perches			     "break quoted strings at a space character\n" . $hereprev);
54725e4f6ba5SJoe Perches		}
54735e4f6ba5SJoe Perches
547477cb8546SJoe Perches# check for an embedded function name in a string when the function is known
5475e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch
5476e4b7d309SJoe Perches# context providing the function name or a single line form for in-file
5477e4b7d309SJoe Perches# function declarations
547877cb8546SJoe Perches		if ($line =~ /^\+.*$String/ &&
547977cb8546SJoe Perches		    defined($context_function) &&
5480e4b7d309SJoe Perches		    get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
5481e4b7d309SJoe Perches		    length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
548277cb8546SJoe Perches			WARN("EMBEDDED_FUNCTION_NAME",
5483e4b7d309SJoe Perches			     "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
548477cb8546SJoe Perches		}
548577cb8546SJoe Perches
54865e4f6ba5SJoe Perches# check for spaces before a quoted newline
54875e4f6ba5SJoe Perches		if ($rawline =~ /^.*\".*\s\\n/) {
54885e4f6ba5SJoe Perches			if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
54895e4f6ba5SJoe Perches				 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
54905e4f6ba5SJoe Perches			    $fix) {
54915e4f6ba5SJoe Perches				$fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
54925e4f6ba5SJoe Perches			}
54935e4f6ba5SJoe Perches
54945e4f6ba5SJoe Perches		}
54955e4f6ba5SJoe Perches
5496f17dba4fSJoe Perches# concatenated string without spaces between elements
549779682c0cSJoe Perches		if ($line =~ /$String[A-Za-z0-9_]/ || $line =~ /[A-Za-z0-9_]$String/) {
549879682c0cSJoe Perches			if (CHK("CONCATENATED_STRING",
549979682c0cSJoe Perches				"Concatenated strings should use spaces between elements\n" . $herecurr) &&
550079682c0cSJoe Perches			    $fix) {
550179682c0cSJoe Perches				while ($line =~ /($String)/g) {
550279682c0cSJoe Perches					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
550379682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/;
550479682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/;
550579682c0cSJoe Perches				}
550679682c0cSJoe Perches			}
5507f17dba4fSJoe Perches		}
5508f17dba4fSJoe Perches
550990ad30e5SJoe Perches# uncoalesced string fragments
551033acb54aSJoe Perches		if ($line =~ /$String\s*"/) {
551179682c0cSJoe Perches			if (WARN("STRING_FRAGMENTS",
551279682c0cSJoe Perches				 "Consecutive strings are generally better as a single string\n" . $herecurr) &&
551379682c0cSJoe Perches			    $fix) {
551479682c0cSJoe Perches				while ($line =~ /($String)(?=\s*")/g) {
551579682c0cSJoe Perches					my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]);
551679682c0cSJoe Perches					$fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e;
551779682c0cSJoe Perches				}
551879682c0cSJoe Perches			}
551990ad30e5SJoe Perches		}
552090ad30e5SJoe Perches
5521522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats
5522522b837cSAlexey Dobriyan		my $show_L = 1;	#don't show the same defect twice
5523522b837cSAlexey Dobriyan		my $show_Z = 1;
55245e4f6ba5SJoe Perches		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
5525522b837cSAlexey Dobriyan			my $string = substr($rawline, $-[1], $+[1] - $-[1]);
55265e4f6ba5SJoe Perches			$string =~ s/%%/__/g;
5527522b837cSAlexey Dobriyan			# check for %L
5528522b837cSAlexey Dobriyan			if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
55295e4f6ba5SJoe Perches				WARN("PRINTF_L",
5530522b837cSAlexey Dobriyan				     "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
5531522b837cSAlexey Dobriyan				$show_L = 0;
55325e4f6ba5SJoe Perches			}
5533522b837cSAlexey Dobriyan			# check for %Z
5534522b837cSAlexey Dobriyan			if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
5535522b837cSAlexey Dobriyan				WARN("PRINTF_Z",
5536522b837cSAlexey Dobriyan				     "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
5537522b837cSAlexey Dobriyan				$show_Z = 0;
5538522b837cSAlexey Dobriyan			}
5539522b837cSAlexey Dobriyan			# check for 0x<decimal>
5540522b837cSAlexey Dobriyan			if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
5541522b837cSAlexey Dobriyan				ERROR("PRINTF_0XDECIMAL",
55426e300757SJoe Perches				      "Prefixing 0x with decimal output is defective\n" . $herecurr);
55436e300757SJoe Perches			}
55445e4f6ba5SJoe Perches		}
55455e4f6ba5SJoe Perches
55465e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of "
55473f7f335dSJoe Perches		if ($rawline =~ /\\$/ && $sline =~ tr/"/"/ % 2) {
55485e4f6ba5SJoe Perches			WARN("LINE_CONTINUATIONS",
55495e4f6ba5SJoe Perches			     "Avoid line continuations in quoted strings\n" . $herecurr);
55505e4f6ba5SJoe Perches		}
55515e4f6ba5SJoe Perches
555200df344fSAndy Whitcroft# warn about #if 0
5553c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
555460f89010SPrakruthi Deepak Heragu			WARN("IF_0",
555560f89010SPrakruthi Deepak Heragu			     "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr);
555660f89010SPrakruthi Deepak Heragu		}
555760f89010SPrakruthi Deepak Heragu
555860f89010SPrakruthi Deepak Heragu# warn about #if 1
555960f89010SPrakruthi Deepak Heragu		if ($line =~ /^.\s*\#\s*if\s+1\b/) {
556060f89010SPrakruthi Deepak Heragu			WARN("IF_1",
556160f89010SPrakruthi Deepak Heragu			     "Consider removing the #if 1 and its #endif\n" . $herecurr);
55624a0df2efSAndy Whitcroft		}
55634a0df2efSAndy Whitcroft
556403df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses
556503df4b51SAndy Whitcroft		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
5566100425deSJoe Perches			my $tested = quotemeta($1);
5567100425deSJoe Perches			my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
5568100425deSJoe Perches			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
5569100425deSJoe Perches				my $func = $1;
5570100425deSJoe Perches				if (WARN('NEEDLESS_IF',
5571100425deSJoe Perches					 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
5572100425deSJoe Perches				    $fix) {
5573100425deSJoe Perches					my $do_fix = 1;
5574100425deSJoe Perches					my $leading_tabs = "";
5575100425deSJoe Perches					my $new_leading_tabs = "";
5576100425deSJoe Perches					if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
5577100425deSJoe Perches						$leading_tabs = $1;
5578100425deSJoe Perches					} else {
5579100425deSJoe Perches						$do_fix = 0;
5580100425deSJoe Perches					}
5581100425deSJoe Perches					if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
5582100425deSJoe Perches						$new_leading_tabs = $1;
5583100425deSJoe Perches						if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
5584100425deSJoe Perches							$do_fix = 0;
5585100425deSJoe Perches						}
5586100425deSJoe Perches					} else {
5587100425deSJoe Perches						$do_fix = 0;
5588100425deSJoe Perches					}
5589100425deSJoe Perches					if ($do_fix) {
5590100425deSJoe Perches						fix_delete_line($fixlinenr - 1, $prevrawline);
5591100425deSJoe Perches						$fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
5592100425deSJoe Perches					}
5593100425deSJoe Perches				}
55944c432a8fSGreg Kroah-Hartman			}
55954c432a8fSGreg Kroah-Hartman		}
5596f0a594c1SAndy Whitcroft
5597ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages
5598ebfdc409SJoe Perches		if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
5599ebfdc409SJoe Perches		    $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
5600ebfdc409SJoe Perches		    (defined $1 || defined $3) &&
5601ebfdc409SJoe Perches		    $linenr > 3) {
5602ebfdc409SJoe Perches			my $testval = $2;
5603ebfdc409SJoe Perches			my $testline = $lines[$linenr - 3];
5604ebfdc409SJoe Perches
5605ebfdc409SJoe Perches			my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
5606ebfdc409SJoe Perches#			print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
5607ebfdc409SJoe Perches
5608e29a70f1SJoe Perches			if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ &&
5609e29a70f1SJoe Perches			    $s !~ /\b__GFP_NOWARN\b/ ) {
5610ebfdc409SJoe Perches				WARN("OOM_MESSAGE",
5611ebfdc409SJoe Perches				     "Possible unnecessary 'out of memory' message\n" . $hereprev);
5612ebfdc409SJoe Perches			}
5613ebfdc409SJoe Perches		}
5614ebfdc409SJoe Perches
5615f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL>
5616dcaf1123SPaolo Bonzini		if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
5617f78d98f6SJoe Perches		    $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
5618f78d98f6SJoe Perches			my $level = $1;
5619f78d98f6SJoe Perches			if (WARN("UNNECESSARY_KERN_LEVEL",
5620f78d98f6SJoe Perches				 "Possible unnecessary $level\n" . $herecurr) &&
5621f78d98f6SJoe Perches			    $fix) {
5622f78d98f6SJoe Perches				$fixed[$fixlinenr] =~ s/\s*$level\s*//;
5623f78d98f6SJoe Perches			}
5624f78d98f6SJoe Perches		}
5625f78d98f6SJoe Perches
562645c55e92SJoe Perches# check for logging continuations
562745c55e92SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
562845c55e92SJoe Perches			WARN("LOGGING_CONTINUATION",
562945c55e92SJoe Perches			     "Avoid logging continuation uses where feasible\n" . $herecurr);
563045c55e92SJoe Perches		}
563145c55e92SJoe Perches
5632abb08a53SJoe Perches# check for mask then right shift without a parentheses
56335b57980dSJoe Perches		if ($perl_version_ok &&
5634abb08a53SJoe Perches		    $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
5635abb08a53SJoe Perches		    $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
5636abb08a53SJoe Perches			WARN("MASK_THEN_SHIFT",
5637abb08a53SJoe Perches			     "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
5638abb08a53SJoe Perches		}
5639abb08a53SJoe Perches
5640b75ac618SJoe Perches# check for pointer comparisons to NULL
56415b57980dSJoe Perches		if ($perl_version_ok) {
5642b75ac618SJoe Perches			while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
5643b75ac618SJoe Perches				my $val = $1;
5644b75ac618SJoe Perches				my $equal = "!";
5645b75ac618SJoe Perches				$equal = "" if ($4 eq "!=");
5646b75ac618SJoe Perches				if (CHK("COMPARISON_TO_NULL",
5647b75ac618SJoe Perches					"Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
5648b75ac618SJoe Perches					    $fix) {
5649b75ac618SJoe Perches					$fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
5650b75ac618SJoe Perches				}
5651b75ac618SJoe Perches			}
5652b75ac618SJoe Perches		}
5653b75ac618SJoe Perches
56548716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata)
56558716de38SJoe Perches		if ($line =~ /(\b$InitAttribute\b)/) {
56568716de38SJoe Perches			my $attr = $1;
56578716de38SJoe Perches			if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
56588716de38SJoe Perches				my $ptr = $1;
56598716de38SJoe Perches				my $var = $2;
56608716de38SJoe Perches				if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
56618716de38SJoe Perches				      ERROR("MISPLACED_INIT",
56628716de38SJoe Perches					    "$attr should be placed after $var\n" . $herecurr)) ||
56638716de38SJoe Perches				     ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
56648716de38SJoe Perches				      WARN("MISPLACED_INIT",
56658716de38SJoe Perches					   "$attr should be placed after $var\n" . $herecurr))) &&
56668716de38SJoe Perches				    $fix) {
5667194f66fcSJoe 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;
56688716de38SJoe Perches				}
56698716de38SJoe Perches			}
56708716de38SJoe Perches		}
56718716de38SJoe Perches
5672e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const
5673e970b884SJoe Perches		if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
5674e970b884SJoe Perches			my $attr = $1;
5675e970b884SJoe Perches			$attr =~ /($InitAttributePrefix)(.*)/;
5676e970b884SJoe Perches			my $attr_prefix = $1;
5677e970b884SJoe Perches			my $attr_type = $2;
5678e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
5679e970b884SJoe Perches				  "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
5680e970b884SJoe Perches			    $fix) {
5681194f66fcSJoe Perches				$fixed[$fixlinenr] =~
5682e970b884SJoe Perches				    s/$InitAttributeData/${attr_prefix}initconst/;
5683e970b884SJoe Perches			}
5684e970b884SJoe Perches		}
5685e970b884SJoe Perches
5686e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const
5687e970b884SJoe Perches		if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
5688e970b884SJoe Perches			my $attr = $1;
5689e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
5690e970b884SJoe Perches				  "Use of $attr requires a separate use of const\n" . $herecurr) &&
5691e970b884SJoe Perches			    $fix) {
5692194f66fcSJoe Perches				my $lead = $fixed[$fixlinenr] =~
5693e970b884SJoe Perches				    /(^\+\s*(?:static\s+))/;
5694e970b884SJoe Perches				$lead = rtrim($1);
5695e970b884SJoe Perches				$lead = "$lead " if ($lead !~ /^\+$/);
5696e970b884SJoe Perches				$lead = "${lead}const ";
5697194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
5698e970b884SJoe Perches			}
5699e970b884SJoe Perches		}
5700e970b884SJoe Perches
5701c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const)
5702c17893c7SJoe Perches		if ($line =~ /\b__read_mostly\b/ &&
5703c17893c7SJoe Perches		    $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
5704c17893c7SJoe Perches			if (ERROR("CONST_READ_MOSTLY",
5705c17893c7SJoe Perches				  "Invalid use of __read_mostly with const type\n" . $herecurr) &&
5706c17893c7SJoe Perches			    $fix) {
5707c17893c7SJoe Perches				$fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
5708c17893c7SJoe Perches			}
5709c17893c7SJoe Perches		}
5710c17893c7SJoe Perches
5711fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/
5712fbdb8138SJoe Perches		if ($realfile !~ m@^include/uapi/@ &&
5713fbdb8138SJoe Perches		    $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
5714fbdb8138SJoe Perches			my $constant_func = $1;
5715fbdb8138SJoe Perches			my $func = $constant_func;
5716fbdb8138SJoe Perches			$func =~ s/^__constant_//;
5717fbdb8138SJoe Perches			if (WARN("CONSTANT_CONVERSION",
5718fbdb8138SJoe Perches				 "$constant_func should be $func\n" . $herecurr) &&
5719fbdb8138SJoe Perches			    $fix) {
5720194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
5721fbdb8138SJoe Perches			}
5722fbdb8138SJoe Perches		}
5723fbdb8138SJoe Perches
57241a15a250SPatrick Pannuto# prefer usleep_range over udelay
572537581c28SBruce Allan		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
572643c1d77cSJoe Perches			my $delay = $1;
57271a15a250SPatrick Pannuto			# ignore udelay's < 10, however
572843c1d77cSJoe Perches			if (! ($delay < 10) ) {
5729000d1cc1SJoe Perches				CHK("USLEEP_RANGE",
5730458f69efSMauro Carvalho Chehab				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr);
573143c1d77cSJoe Perches			}
573243c1d77cSJoe Perches			if ($delay > 2000) {
573343c1d77cSJoe Perches				WARN("LONG_UDELAY",
573443c1d77cSJoe Perches				     "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
57351a15a250SPatrick Pannuto			}
57361a15a250SPatrick Pannuto		}
57371a15a250SPatrick Pannuto
573809ef8725SPatrick Pannuto# warn about unexpectedly long msleep's
573909ef8725SPatrick Pannuto		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
574009ef8725SPatrick Pannuto			if ($1 < 20) {
5741000d1cc1SJoe Perches				WARN("MSLEEP",
5742458f69efSMauro Carvalho Chehab				     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr);
574309ef8725SPatrick Pannuto			}
574409ef8725SPatrick Pannuto		}
574509ef8725SPatrick Pannuto
574636ec1939SJoe Perches# check for comparisons of jiffies
574736ec1939SJoe Perches		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
574836ec1939SJoe Perches			WARN("JIFFIES_COMPARISON",
574936ec1939SJoe Perches			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
575036ec1939SJoe Perches		}
575136ec1939SJoe Perches
57529d7a34a5SJoe Perches# check for comparisons of get_jiffies_64()
57539d7a34a5SJoe Perches		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
57549d7a34a5SJoe Perches			WARN("JIFFIES_COMPARISON",
57559d7a34a5SJoe Perches			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
57569d7a34a5SJoe Perches		}
57579d7a34a5SJoe Perches
575800df344fSAndy Whitcroft# warn about #ifdefs in C files
5759c45dcabdSAndy Whitcroft#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
576000df344fSAndy Whitcroft#			print "#ifdef in C files should be avoided\n";
576100df344fSAndy Whitcroft#			print "$herecurr";
576200df344fSAndy Whitcroft#			$clean = 0;
576300df344fSAndy Whitcroft#		}
576400df344fSAndy Whitcroft
576522f2a2efSAndy Whitcroft# warn about spacing in #ifdefs
5766c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
57673705ce5bSJoe Perches			if (ERROR("SPACING",
57683705ce5bSJoe Perches				  "exactly one space required after that #$1\n" . $herecurr) &&
57693705ce5bSJoe Perches			    $fix) {
5770194f66fcSJoe Perches				$fixed[$fixlinenr] =~
57713705ce5bSJoe Perches				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
57723705ce5bSJoe Perches			}
57733705ce5bSJoe Perches
577422f2a2efSAndy Whitcroft		}
577522f2a2efSAndy Whitcroft
57764a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment.
5777171ae1a4SAndy Whitcroft		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
5778171ae1a4SAndy Whitcroft		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
57794a0df2efSAndy Whitcroft			my $which = $1;
57804a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
5781000d1cc1SJoe Perches				CHK("UNCOMMENTED_DEFINITION",
5782000d1cc1SJoe Perches				    "$1 definition without comment\n" . $herecurr);
57834a0df2efSAndy Whitcroft			}
57844a0df2efSAndy Whitcroft		}
57854a0df2efSAndy Whitcroft# check for memory barriers without a comment.
5786402c2553SMichael S. Tsirkin
5787402c2553SMichael S. Tsirkin		my $barriers = qr{
5788402c2553SMichael S. Tsirkin			mb|
5789402c2553SMichael S. Tsirkin			rmb|
5790402c2553SMichael S. Tsirkin			wmb|
5791402c2553SMichael S. Tsirkin			read_barrier_depends
5792402c2553SMichael S. Tsirkin		}x;
5793402c2553SMichael S. Tsirkin		my $barrier_stems = qr{
5794402c2553SMichael S. Tsirkin			mb__before_atomic|
5795402c2553SMichael S. Tsirkin			mb__after_atomic|
5796402c2553SMichael S. Tsirkin			store_release|
5797402c2553SMichael S. Tsirkin			load_acquire|
5798402c2553SMichael S. Tsirkin			store_mb|
5799402c2553SMichael S. Tsirkin			(?:$barriers)
5800402c2553SMichael S. Tsirkin		}x;
5801402c2553SMichael S. Tsirkin		my $all_barriers = qr{
5802402c2553SMichael S. Tsirkin			(?:$barriers)|
580343e361f2SMichael S. Tsirkin			smp_(?:$barrier_stems)|
580443e361f2SMichael S. Tsirkin			virt_(?:$barrier_stems)
5805402c2553SMichael S. Tsirkin		}x;
5806402c2553SMichael S. Tsirkin
5807402c2553SMichael S. Tsirkin		if ($line =~ /\b(?:$all_barriers)\s*\(/) {
58084a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
5809c1fd7bb9SJoe Perches				WARN("MEMORY_BARRIER",
5810000d1cc1SJoe Perches				     "memory barrier without comment\n" . $herecurr);
58114a0df2efSAndy Whitcroft			}
58124a0df2efSAndy Whitcroft		}
58133ad81779SPaul E. McKenney
5814f4073b0fSMichael S. Tsirkin		my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
5815f4073b0fSMichael S. Tsirkin
5816f4073b0fSMichael S. Tsirkin		if ($realfile !~ m@^include/asm-generic/@ &&
5817f4073b0fSMichael S. Tsirkin		    $realfile !~ m@/barrier\.h$@ &&
5818f4073b0fSMichael S. Tsirkin		    $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
5819f4073b0fSMichael S. Tsirkin		    $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
5820f4073b0fSMichael S. Tsirkin			WARN("MEMORY_BARRIER",
5821f4073b0fSMichael S. Tsirkin			     "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
5822f4073b0fSMichael S. Tsirkin		}
5823f4073b0fSMichael S. Tsirkin
5824cb426e99SJoe Perches# check for waitqueue_active without a comment.
5825cb426e99SJoe Perches		if ($line =~ /\bwaitqueue_active\s*\(/) {
5826cb426e99SJoe Perches			if (!ctx_has_comment($first_line, $linenr)) {
5827cb426e99SJoe Perches				WARN("WAITQUEUE_ACTIVE",
5828cb426e99SJoe Perches				     "waitqueue_active without comment\n" . $herecurr);
5829cb426e99SJoe Perches			}
5830cb426e99SJoe Perches		}
58313ad81779SPaul E. McKenney
583291db2592SPaul E. McKenney# check for smp_read_barrier_depends and read_barrier_depends
583391db2592SPaul E. McKenney		if (!$file && $line =~ /\b(smp_|)read_barrier_depends\s*\(/) {
583491db2592SPaul E. McKenney			WARN("READ_BARRIER_DEPENDS",
583591db2592SPaul E. McKenney			     "$1read_barrier_depends should only be used in READ_ONCE or DEC Alpha code\n" . $herecurr);
583691db2592SPaul E. McKenney		}
583791db2592SPaul E. McKenney
58384a0df2efSAndy Whitcroft# check of hardware specific defines
5839c45dcabdSAndy Whitcroft		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
5840000d1cc1SJoe Perches			CHK("ARCH_DEFINES",
5841000d1cc1SJoe Perches			    "architecture specific defines should be avoided\n" .  $herecurr);
58420a920b5bSAndy Whitcroft		}
5843653d4876SAndy Whitcroft
5844596ed45bSJoe Perches# check that the storage class is not after a type
5845596ed45bSJoe Perches		if ($line =~ /\b($Type)\s+($Storage)\b/) {
5846000d1cc1SJoe Perches			WARN("STORAGE_CLASS",
5847596ed45bSJoe Perches			     "storage class '$2' should be located before type '$1'\n" . $herecurr);
5848596ed45bSJoe Perches		}
5849596ed45bSJoe Perches# Check that the storage class is at the beginning of a declaration
5850596ed45bSJoe Perches		if ($line =~ /\b$Storage\b/ &&
5851596ed45bSJoe Perches		    $line !~ /^.\s*$Storage/ &&
5852596ed45bSJoe Perches		    $line =~ /^.\s*(.+?)\$Storage\s/ &&
5853596ed45bSJoe Perches		    $1 !~ /[\,\)]\s*$/) {
5854596ed45bSJoe Perches			WARN("STORAGE_CLASS",
5855596ed45bSJoe Perches			     "storage class should be at the beginning of the declaration\n" . $herecurr);
5856d4977c78STobias Klauser		}
5857d4977c78STobias Klauser
5858de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between
5859de7d4f0eSAndy Whitcroft# storage class and type.
58609c0ca6f9SAndy Whitcroft		if ($line =~ /\b$Type\s+$Inline\b/ ||
58619c0ca6f9SAndy Whitcroft		    $line =~ /\b$Inline\s+$Storage\b/) {
5862000d1cc1SJoe Perches			ERROR("INLINE_LOCATION",
5863000d1cc1SJoe Perches			      "inline keyword should sit between storage class and type\n" . $herecurr);
5864de7d4f0eSAndy Whitcroft		}
5865de7d4f0eSAndy Whitcroft
58668905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline
58672b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
58682b7ab453SJoe Perches		    $line =~ /\b(__inline__|__inline)\b/) {
5869d5e616fcSJoe Perches			if (WARN("INLINE",
5870d5e616fcSJoe Perches				 "plain inline is preferred over $1\n" . $herecurr) &&
5871d5e616fcSJoe Perches			    $fix) {
5872194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
5873d5e616fcSJoe Perches
5874d5e616fcSJoe Perches			}
58758905a67cSAndy Whitcroft		}
58768905a67cSAndy Whitcroft
58773d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed
58782b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
58792b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
5880000d1cc1SJoe Perches			WARN("PREFER_PACKED",
5881000d1cc1SJoe Perches			     "__packed is preferred over __attribute__((packed))\n" . $herecurr);
58823d130fd0SJoe Perches		}
58833d130fd0SJoe Perches
588439b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned
58852b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
58862b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
5887000d1cc1SJoe Perches			WARN("PREFER_ALIGNED",
5888000d1cc1SJoe Perches			     "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
588939b7e287SJoe Perches		}
589039b7e287SJoe Perches
5891462811d9SJoe Perches# Check for __attribute__ section, prefer __section
5892462811d9SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
5893462811d9SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(.*_*section_*\s*\(\s*("[^"]*")/) {
5894462811d9SJoe Perches			my $old = substr($rawline, $-[1], $+[1] - $-[1]);
5895462811d9SJoe Perches			my $new = substr($old, 1, -1);
5896462811d9SJoe Perches			if (WARN("PREFER_SECTION",
5897462811d9SJoe Perches				 "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) &&
5898462811d9SJoe Perches			    $fix) {
5899462811d9SJoe Perches				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/;
5900462811d9SJoe Perches			}
5901462811d9SJoe Perches		}
5902462811d9SJoe Perches
59035f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf
59042b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
59052b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
5906d5e616fcSJoe Perches			if (WARN("PREFER_PRINTF",
5907d5e616fcSJoe Perches				 "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
5908d5e616fcSJoe Perches			    $fix) {
5909194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
5910d5e616fcSJoe Perches
5911d5e616fcSJoe Perches			}
59125f14d3bdSJoe Perches		}
59135f14d3bdSJoe Perches
59146061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf
59152b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
59162b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
5917d5e616fcSJoe Perches			if (WARN("PREFER_SCANF",
5918d5e616fcSJoe Perches				 "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
5919d5e616fcSJoe Perches			    $fix) {
5920194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
5921d5e616fcSJoe Perches			}
59226061d949SJoe Perches		}
59236061d949SJoe Perches
5924619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues)
59255b57980dSJoe Perches		if ($perl_version_ok &&
5926619a908aSJoe Perches		    $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
5927619a908aSJoe Perches		    ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
5928619a908aSJoe Perches		     $line =~ /\b__weak\b/)) {
5929619a908aSJoe Perches			ERROR("WEAK_DECLARATION",
5930619a908aSJoe Perches			      "Using weak declarations can have unintended link defects\n" . $herecurr);
5931619a908aSJoe Perches		}
5932619a908aSJoe Perches
5933fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/
5934e6176fa4SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
5935fd39f904STomas Winkler		    $realfile !~ m@\btools/@ &&
5936e6176fa4SJoe Perches		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
5937e6176fa4SJoe Perches			my $type = $1;
5938e6176fa4SJoe Perches			if ($type =~ /\b($typeC99Typedefs)\b/) {
5939e6176fa4SJoe Perches				$type = $1;
5940e6176fa4SJoe Perches				my $kernel_type = 'u';
5941e6176fa4SJoe Perches				$kernel_type = 's' if ($type =~ /^_*[si]/);
5942e6176fa4SJoe Perches				$type =~ /(\d+)/;
5943e6176fa4SJoe Perches				$kernel_type .= $1;
5944e6176fa4SJoe Perches				if (CHK("PREFER_KERNEL_TYPES",
5945e6176fa4SJoe Perches					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
5946e6176fa4SJoe Perches				    $fix) {
5947e6176fa4SJoe Perches					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
5948e6176fa4SJoe Perches				}
5949e6176fa4SJoe Perches			}
5950e6176fa4SJoe Perches		}
5951e6176fa4SJoe Perches
5952938224b5SJoe Perches# check for cast of C90 native int or longer types constants
5953938224b5SJoe Perches		if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
5954938224b5SJoe Perches			my $cast = $1;
5955938224b5SJoe Perches			my $const = $2;
5956938224b5SJoe Perches			if (WARN("TYPECAST_INT_CONSTANT",
5957938224b5SJoe Perches				 "Unnecessary typecast of c90 int constant\n" . $herecurr) &&
5958938224b5SJoe Perches			    $fix) {
5959938224b5SJoe Perches				my $suffix = "";
5960938224b5SJoe Perches				my $newconst = $const;
5961938224b5SJoe Perches				$newconst =~ s/${Int_type}$//;
5962938224b5SJoe Perches				$suffix .= 'U' if ($cast =~ /\bunsigned\b/);
5963938224b5SJoe Perches				if ($cast =~ /\blong\s+long\b/) {
5964938224b5SJoe Perches					$suffix .= 'LL';
5965938224b5SJoe Perches				} elsif ($cast =~ /\blong\b/) {
5966938224b5SJoe Perches					$suffix .= 'L';
5967938224b5SJoe Perches				}
5968938224b5SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
5969938224b5SJoe Perches			}
5970938224b5SJoe Perches		}
5971938224b5SJoe Perches
59728f53a9b8SJoe Perches# check for sizeof(&)
59738f53a9b8SJoe Perches		if ($line =~ /\bsizeof\s*\(\s*\&/) {
5974000d1cc1SJoe Perches			WARN("SIZEOF_ADDRESS",
5975000d1cc1SJoe Perches			     "sizeof(& should be avoided\n" . $herecurr);
59768f53a9b8SJoe Perches		}
59778f53a9b8SJoe Perches
597866c80b60SJoe Perches# check for sizeof without parenthesis
597966c80b60SJoe Perches		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
5980d5e616fcSJoe Perches			if (WARN("SIZEOF_PARENTHESIS",
5981d5e616fcSJoe Perches				 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
5982d5e616fcSJoe Perches			    $fix) {
5983194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
5984d5e616fcSJoe Perches			}
598566c80b60SJoe Perches		}
598666c80b60SJoe Perches
598788982feaSJoe Perches# check for struct spinlock declarations
598888982feaSJoe Perches		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
598988982feaSJoe Perches			WARN("USE_SPINLOCK_T",
599088982feaSJoe Perches			     "struct spinlock should be spinlock_t\n" . $herecurr);
599188982feaSJoe Perches		}
599288982feaSJoe Perches
5993a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts
599406668727SJoe Perches		if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
5995a6962d72SJoe Perches			my $fmt = get_quoted_string($line, $rawline);
5996caac1d5fSHeba Aamer			$fmt =~ s/%%//g;
5997caac1d5fSHeba Aamer			if ($fmt !~ /%/) {
5998d5e616fcSJoe Perches				if (WARN("PREFER_SEQ_PUTS",
5999d5e616fcSJoe Perches					 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
6000d5e616fcSJoe Perches				    $fix) {
6001194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
6002d5e616fcSJoe Perches				}
6003a6962d72SJoe Perches			}
6004a6962d72SJoe Perches		}
6005a6962d72SJoe Perches
60060b523769SJoe Perches# check for vsprintf extension %p<foo> misuses
60075b57980dSJoe Perches		if ($perl_version_ok &&
60080b523769SJoe Perches		    defined $stat &&
60090b523769SJoe Perches		    $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
60100b523769SJoe Perches		    $1 !~ /^_*volatile_*$/) {
6011e3c6bc95STobin C. Harding			my $stat_real;
6012e3c6bc95STobin C. Harding
60130b523769SJoe Perches			my $lc = $stat =~ tr@\n@@;
60140b523769SJoe Perches			$lc = $lc + $linenr;
60150b523769SJoe Perches		        for (my $count = $linenr; $count <= $lc; $count++) {
6016ffe07513SJoe Perches				my $specifier;
6017ffe07513SJoe Perches				my $extension;
6018ffe07513SJoe Perches				my $bad_specifier = "";
60190b523769SJoe Perches				my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
60200b523769SJoe Perches				$fmt =~ s/%%//g;
6021e3c6bc95STobin C. Harding
6022e3c6bc95STobin C. Harding				while ($fmt =~ /(\%[\*\d\.]*p(\w))/g) {
6023e3c6bc95STobin C. Harding					$specifier = $1;
6024e3c6bc95STobin C. Harding					$extension = $2;
60254462996eSAlexandre Belloni					if ($extension !~ /[SsBKRraEhMmIiUDdgVCbGNOxt]/) {
6026e3c6bc95STobin C. Harding						$bad_specifier = $specifier;
60270b523769SJoe Perches						last;
60280b523769SJoe Perches					}
6029e3c6bc95STobin C. Harding					if ($extension eq "x" && !defined($stat_real)) {
6030e3c6bc95STobin C. Harding						if (!defined($stat_real)) {
6031e3c6bc95STobin C. Harding							$stat_real = get_stat_real($linenr, $lc);
60320b523769SJoe Perches						}
6033e3c6bc95STobin C. Harding						WARN("VSPRINTF_SPECIFIER_PX",
6034e3c6bc95STobin 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");
6035e3c6bc95STobin C. Harding					}
6036e3c6bc95STobin C. Harding				}
6037e3c6bc95STobin C. Harding				if ($bad_specifier ne "") {
60382a9f9d85STobin C. Harding					my $stat_real = get_stat_real($linenr, $lc);
60391df7338aSSergey Senozhatsky					my $ext_type = "Invalid";
60401df7338aSSergey Senozhatsky					my $use = "";
6041e3c6bc95STobin C. Harding					if ($bad_specifier =~ /p[Ff]/) {
60421df7338aSSergey Senozhatsky						$ext_type = "Deprecated";
60431df7338aSSergey Senozhatsky						$use = " - use %pS instead";
6044e3c6bc95STobin C. Harding						$use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);
60451df7338aSSergey Senozhatsky					}
60462a9f9d85STobin C. Harding
60470b523769SJoe Perches					WARN("VSPRINTF_POINTER_EXTENSION",
6048e3c6bc95STobin C. Harding					     "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");
6049e3c6bc95STobin C. Harding				}
60500b523769SJoe Perches			}
60510b523769SJoe Perches		}
60520b523769SJoe Perches
6053554e165cSAndy Whitcroft# Check for misused memsets
60545b57980dSJoe Perches		if ($perl_version_ok &&
6055d1fe9c09SJoe Perches		    defined $stat &&
60569e20a853SMateusz Kulikowski		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
6057554e165cSAndy Whitcroft
6058d7c76ba7SJoe Perches			my $ms_addr = $2;
6059d1fe9c09SJoe Perches			my $ms_val = $7;
6060d1fe9c09SJoe Perches			my $ms_size = $12;
6061d7c76ba7SJoe Perches
6062554e165cSAndy Whitcroft			if ($ms_size =~ /^(0x|)0$/i) {
6063554e165cSAndy Whitcroft				ERROR("MEMSET",
6064d7c76ba7SJoe Perches				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
6065554e165cSAndy Whitcroft			} elsif ($ms_size =~ /^(0x|)1$/i) {
6066554e165cSAndy Whitcroft				WARN("MEMSET",
6067d7c76ba7SJoe Perches				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
6068d7c76ba7SJoe Perches			}
6069d7c76ba7SJoe Perches		}
6070d7c76ba7SJoe Perches
607198a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
60725b57980dSJoe Perches#		if ($perl_version_ok &&
6073f333195dSJoe Perches#		    defined $stat &&
6074f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6075f333195dSJoe Perches#			if (WARN("PREFER_ETHER_ADDR_COPY",
6076f333195dSJoe Perches#				 "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
6077f333195dSJoe Perches#			    $fix) {
6078f333195dSJoe Perches#				$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
6079f333195dSJoe Perches#			}
6080f333195dSJoe Perches#		}
608198a9bba5SJoe Perches
6082b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
60835b57980dSJoe Perches#		if ($perl_version_ok &&
6084f333195dSJoe Perches#		    defined $stat &&
6085f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6086f333195dSJoe Perches#			WARN("PREFER_ETHER_ADDR_EQUAL",
6087f333195dSJoe Perches#			     "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
6088f333195dSJoe Perches#		}
6089b6117d17SMateusz Kulikowski
60908617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
60918617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
60925b57980dSJoe Perches#		if ($perl_version_ok &&
6093f333195dSJoe Perches#		    defined $stat &&
6094f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
6095f333195dSJoe Perches#
6096f333195dSJoe Perches#			my $ms_val = $7;
6097f333195dSJoe Perches#
6098f333195dSJoe Perches#			if ($ms_val =~ /^(?:0x|)0+$/i) {
6099f333195dSJoe Perches#				if (WARN("PREFER_ETH_ZERO_ADDR",
6100f333195dSJoe Perches#					 "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
6101f333195dSJoe Perches#				    $fix) {
6102f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
6103f333195dSJoe Perches#				}
6104f333195dSJoe Perches#			} elsif ($ms_val =~ /^(?:0xff|255)$/i) {
6105f333195dSJoe Perches#				if (WARN("PREFER_ETH_BROADCAST_ADDR",
6106f333195dSJoe Perches#					 "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
6107f333195dSJoe Perches#				    $fix) {
6108f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
6109f333195dSJoe Perches#				}
6110f333195dSJoe Perches#			}
6111f333195dSJoe Perches#		}
61128617cd09SMateusz Kulikowski
6113d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t
61145b57980dSJoe Perches		if ($perl_version_ok &&
6115d1fe9c09SJoe Perches		    defined $stat &&
6116d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
6117d1fe9c09SJoe Perches			if (defined $2 || defined $7) {
6118d7c76ba7SJoe Perches				my $call = $1;
6119d7c76ba7SJoe Perches				my $cast1 = deparenthesize($2);
6120d7c76ba7SJoe Perches				my $arg1 = $3;
6121d1fe9c09SJoe Perches				my $cast2 = deparenthesize($7);
6122d1fe9c09SJoe Perches				my $arg2 = $8;
6123d7c76ba7SJoe Perches				my $cast;
6124d7c76ba7SJoe Perches
6125d1fe9c09SJoe Perches				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
6126d7c76ba7SJoe Perches					$cast = "$cast1 or $cast2";
6127d7c76ba7SJoe Perches				} elsif ($cast1 ne "") {
6128d7c76ba7SJoe Perches					$cast = $cast1;
6129d7c76ba7SJoe Perches				} else {
6130d7c76ba7SJoe Perches					$cast = $cast2;
6131d7c76ba7SJoe Perches				}
6132d7c76ba7SJoe Perches				WARN("MINMAX",
6133d7c76ba7SJoe Perches				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
6134554e165cSAndy Whitcroft			}
6135554e165cSAndy Whitcroft		}
6136554e165cSAndy Whitcroft
61374a273195SJoe Perches# check usleep_range arguments
61385b57980dSJoe Perches		if ($perl_version_ok &&
61394a273195SJoe Perches		    defined $stat &&
61404a273195SJoe Perches		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
61414a273195SJoe Perches			my $min = $1;
61424a273195SJoe Perches			my $max = $7;
61434a273195SJoe Perches			if ($min eq $max) {
61444a273195SJoe Perches				WARN("USLEEP_RANGE",
6145458f69efSMauro Carvalho Chehab				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
61464a273195SJoe Perches			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
61474a273195SJoe Perches				 $min > $max) {
61484a273195SJoe Perches				WARN("USLEEP_RANGE",
6149458f69efSMauro Carvalho Chehab				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");
61504a273195SJoe Perches			}
61514a273195SJoe Perches		}
61524a273195SJoe Perches
6153823b794cSJoe Perches# check for naked sscanf
61545b57980dSJoe Perches		if ($perl_version_ok &&
6155823b794cSJoe Perches		    defined $stat &&
61566c8bd707SJoe Perches		    $line =~ /\bsscanf\b/ &&
6157823b794cSJoe Perches		    ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
6158823b794cSJoe Perches		     $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
6159823b794cSJoe Perches		     $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
6160823b794cSJoe Perches			my $lc = $stat =~ tr@\n@@;
6161823b794cSJoe Perches			$lc = $lc + $linenr;
61622a9f9d85STobin C. Harding			my $stat_real = get_stat_real($linenr, $lc);
6163823b794cSJoe Perches			WARN("NAKED_SSCANF",
6164823b794cSJoe Perches			     "unchecked sscanf return value\n" . "$here\n$stat_real\n");
6165823b794cSJoe Perches		}
6166823b794cSJoe Perches
6167afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo>
61685b57980dSJoe Perches		if ($perl_version_ok &&
6169afc819abSJoe Perches		    defined $stat &&
6170afc819abSJoe Perches		    $line =~ /\bsscanf\b/) {
6171afc819abSJoe Perches			my $lc = $stat =~ tr@\n@@;
6172afc819abSJoe Perches			$lc = $lc + $linenr;
61732a9f9d85STobin C. Harding			my $stat_real = get_stat_real($linenr, $lc);
6174afc819abSJoe Perches			if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
6175afc819abSJoe Perches				my $format = $6;
6176afc819abSJoe Perches				my $count = $format =~ tr@%@%@;
6177afc819abSJoe Perches				if ($count == 1 &&
6178afc819abSJoe Perches				    $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
6179afc819abSJoe Perches					WARN("SSCANF_TO_KSTRTO",
6180afc819abSJoe Perches					     "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
6181afc819abSJoe Perches				}
6182afc819abSJoe Perches			}
6183afc819abSJoe Perches		}
6184afc819abSJoe Perches
618570dc8a48SJoe Perches# check for new externs in .h files.
618670dc8a48SJoe Perches		if ($realfile =~ /\.h$/ &&
618770dc8a48SJoe Perches		    $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
6188d1d85780SJoe Perches			if (CHK("AVOID_EXTERNS",
618970dc8a48SJoe Perches				"extern prototypes should be avoided in .h files\n" . $herecurr) &&
619070dc8a48SJoe Perches			    $fix) {
6191194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
619270dc8a48SJoe Perches			}
619370dc8a48SJoe Perches		}
619470dc8a48SJoe Perches
6195de7d4f0eSAndy Whitcroft# check for new externs in .c files.
6196171ae1a4SAndy Whitcroft		if ($realfile =~ /\.c$/ && defined $stat &&
6197c45dcabdSAndy Whitcroft		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
6198171ae1a4SAndy Whitcroft		{
6199c45dcabdSAndy Whitcroft			my $function_name = $1;
6200c45dcabdSAndy Whitcroft			my $paren_space = $2;
6201171ae1a4SAndy Whitcroft
6202171ae1a4SAndy Whitcroft			my $s = $stat;
6203171ae1a4SAndy Whitcroft			if (defined $cond) {
6204171ae1a4SAndy Whitcroft				substr($s, 0, length($cond), '');
6205171ae1a4SAndy Whitcroft			}
6206c45dcabdSAndy Whitcroft			if ($s =~ /^\s*;/ &&
6207c45dcabdSAndy Whitcroft			    $function_name ne 'uninitialized_var')
6208c45dcabdSAndy Whitcroft			{
6209000d1cc1SJoe Perches				WARN("AVOID_EXTERNS",
6210000d1cc1SJoe Perches				     "externs should be avoided in .c files\n" .  $herecurr);
6211de7d4f0eSAndy Whitcroft			}
6212de7d4f0eSAndy Whitcroft
6213171ae1a4SAndy Whitcroft			if ($paren_space =~ /\n/) {
6214000d1cc1SJoe Perches				WARN("FUNCTION_ARGUMENTS",
6215000d1cc1SJoe Perches				     "arguments for function declarations should follow identifier\n" . $herecurr);
6216171ae1a4SAndy Whitcroft			}
62179c9ba34eSAndy Whitcroft
62189c9ba34eSAndy Whitcroft		} elsif ($realfile =~ /\.c$/ && defined $stat &&
62199c9ba34eSAndy Whitcroft		    $stat =~ /^.\s*extern\s+/)
62209c9ba34eSAndy Whitcroft		{
6221000d1cc1SJoe Perches			WARN("AVOID_EXTERNS",
6222000d1cc1SJoe Perches			     "externs should be avoided in .c files\n" .  $herecurr);
6223171ae1a4SAndy Whitcroft		}
6224171ae1a4SAndy Whitcroft
6225a0ad7596SJoe Perches# check for function declarations that have arguments without identifier names
6226a0ad7596SJoe Perches		if (defined $stat &&
622725bdda2bSMiles Chen		    $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&
6228ca0d8929SJoe Perches		    $1 ne "void") {
6229ca0d8929SJoe Perches			my $args = trim($1);
6230ca0d8929SJoe Perches			while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
6231ca0d8929SJoe Perches				my $arg = trim($1);
6232ca0d8929SJoe Perches				if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
6233ca0d8929SJoe Perches					WARN("FUNCTION_ARGUMENTS",
6234ca0d8929SJoe Perches					     "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
6235ca0d8929SJoe Perches				}
6236ca0d8929SJoe Perches			}
6237ca0d8929SJoe Perches		}
6238ca0d8929SJoe Perches
6239a0ad7596SJoe Perches# check for function definitions
62405b57980dSJoe Perches		if ($perl_version_ok &&
6241a0ad7596SJoe Perches		    defined $stat &&
6242a0ad7596SJoe Perches		    $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
6243a0ad7596SJoe Perches			$context_function = $1;
6244a0ad7596SJoe Perches
6245a0ad7596SJoe Perches# check for multiline function definition with misplaced open brace
6246a0ad7596SJoe Perches			my $ok = 0;
6247a0ad7596SJoe Perches			my $cnt = statement_rawlines($stat);
6248a0ad7596SJoe Perches			my $herectx = $here . "\n";
6249a0ad7596SJoe Perches			for (my $n = 0; $n < $cnt; $n++) {
6250a0ad7596SJoe Perches				my $rl = raw_line($linenr, $n);
6251a0ad7596SJoe Perches				$herectx .=  $rl . "\n";
6252a0ad7596SJoe Perches				$ok = 1 if ($rl =~ /^[ \+]\{/);
6253a0ad7596SJoe Perches				$ok = 1 if ($rl =~ /\{/ && $n == 0);
6254a0ad7596SJoe Perches				last if $rl =~ /^[ \+].*\{/;
6255a0ad7596SJoe Perches			}
6256a0ad7596SJoe Perches			if (!$ok) {
6257a0ad7596SJoe Perches				ERROR("OPEN_BRACE",
6258a0ad7596SJoe Perches				      "open brace '{' following function definitions go on the next line\n" . $herectx);
6259a0ad7596SJoe Perches			}
6260a0ad7596SJoe Perches		}
6261a0ad7596SJoe Perches
6262de7d4f0eSAndy Whitcroft# checks for new __setup's
6263de7d4f0eSAndy Whitcroft		if ($rawline =~ /\b__setup\("([^"]*)"/) {
6264de7d4f0eSAndy Whitcroft			my $name = $1;
6265de7d4f0eSAndy Whitcroft
6266de7d4f0eSAndy Whitcroft			if (!grep(/$name/, @setup_docs)) {
6267000d1cc1SJoe Perches				CHK("UNDOCUMENTED_SETUP",
62688c27ceffSMauro Carvalho Chehab				    "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr);
6269de7d4f0eSAndy Whitcroft			}
6270653d4876SAndy Whitcroft		}
62719c0ca6f9SAndy Whitcroft
6272e29a70f1SJoe Perches# check for pointless casting of alloc functions
6273e29a70f1SJoe Perches		if ($line =~ /\*\s*\)\s*$allocFunctions\b/) {
6274000d1cc1SJoe Perches			WARN("UNNECESSARY_CASTS",
6275000d1cc1SJoe Perches			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
62769c0ca6f9SAndy Whitcroft		}
627713214adfSAndy Whitcroft
6278a640d25cSJoe Perches# alloc style
6279a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
62805b57980dSJoe Perches		if ($perl_version_ok &&
6281e29a70f1SJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
6282a640d25cSJoe Perches			CHK("ALLOC_SIZEOF_STRUCT",
6283a640d25cSJoe Perches			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
6284a640d25cSJoe Perches		}
6285a640d25cSJoe Perches
628660a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
62875b57980dSJoe Perches		if ($perl_version_ok &&
62881b4a2ed4SJoe Perches		    defined $stat &&
62891b4a2ed4SJoe Perches		    $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
629060a55369SJoe Perches			my $oldfunc = $3;
629160a55369SJoe Perches			my $a1 = $4;
629260a55369SJoe Perches			my $a2 = $10;
629360a55369SJoe Perches			my $newfunc = "kmalloc_array";
629460a55369SJoe Perches			$newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
629560a55369SJoe Perches			my $r1 = $a1;
629660a55369SJoe Perches			my $r2 = $a2;
629760a55369SJoe Perches			if ($a1 =~ /^sizeof\s*\S/) {
629860a55369SJoe Perches				$r1 = $a2;
629960a55369SJoe Perches				$r2 = $a1;
630060a55369SJoe Perches			}
6301e367455aSJoe Perches			if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
6302e367455aSJoe Perches			    !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
63031b4a2ed4SJoe Perches				my $cnt = statement_rawlines($stat);
6304e3d95a2aSTobin C. Harding				my $herectx = get_stat_here($linenr, $cnt, $here);
6305e3d95a2aSTobin C. Harding
6306e367455aSJoe Perches				if (WARN("ALLOC_WITH_MULTIPLY",
63071b4a2ed4SJoe Perches					 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
63081b4a2ed4SJoe Perches				    $cnt == 1 &&
6309e367455aSJoe Perches				    $fix) {
6310194f66fcSJoe 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;
631160a55369SJoe Perches				}
631260a55369SJoe Perches			}
631360a55369SJoe Perches		}
631460a55369SJoe Perches
6315972fdea2SJoe Perches# check for krealloc arg reuse
63165b57980dSJoe Perches		if ($perl_version_ok &&
63174cab63ceSJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ &&
63184cab63ceSJoe Perches		    $1 eq $3) {
6319972fdea2SJoe Perches			WARN("KREALLOC_ARG_REUSE",
6320972fdea2SJoe Perches			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
6321972fdea2SJoe Perches		}
6322972fdea2SJoe Perches
63235ce59ae0SJoe Perches# check for alloc argument mismatch
63245ce59ae0SJoe Perches		if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
63255ce59ae0SJoe Perches			WARN("ALLOC_ARRAY_ARGS",
63265ce59ae0SJoe Perches			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
63275ce59ae0SJoe Perches		}
63285ce59ae0SJoe Perches
6329caf2a54fSJoe Perches# check for multiple semicolons
6330caf2a54fSJoe Perches		if ($line =~ /;\s*;\s*$/) {
6331d5e616fcSJoe Perches			if (WARN("ONE_SEMICOLON",
6332d5e616fcSJoe Perches				 "Statements terminations use 1 semicolon\n" . $herecurr) &&
6333d5e616fcSJoe Perches			    $fix) {
6334194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
6335d5e616fcSJoe Perches			}
6336d1e2ad07SJoe Perches		}
6337d1e2ad07SJoe Perches
6338cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
6339cec3aaa5STomas Winkler		if ($realfile !~ m@^include/uapi/@ &&
6340cec3aaa5STomas Winkler		    $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
63410ab90191SJoe Perches			my $ull = "";
63420ab90191SJoe Perches			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
63430ab90191SJoe Perches			if (CHK("BIT_MACRO",
63440ab90191SJoe Perches				"Prefer using the BIT$ull macro\n" . $herecurr) &&
63450ab90191SJoe Perches			    $fix) {
63460ab90191SJoe Perches				$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
63470ab90191SJoe Perches			}
63480ab90191SJoe Perches		}
63490ab90191SJoe Perches
63502d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
63512d632745SJoe 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*$/) {
63522d632745SJoe Perches			my $config = $1;
63532d632745SJoe Perches			if (WARN("PREFER_IS_ENABLED",
63542d632745SJoe Perches				 "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) &&
63552d632745SJoe Perches			    $fix) {
63562d632745SJoe Perches				$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
63572d632745SJoe Perches			}
63582d632745SJoe Perches		}
63592d632745SJoe Perches
6360e81f239bSJoe Perches# check for case / default statements not preceded by break/fallthrough/switch
6361c34c09a8SJoe Perches		if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
6362c34c09a8SJoe Perches			my $has_break = 0;
6363c34c09a8SJoe Perches			my $has_statement = 0;
6364c34c09a8SJoe Perches			my $count = 0;
6365c34c09a8SJoe Perches			my $prevline = $linenr;
6366e81f239bSJoe Perches			while ($prevline > 1 && ($file || $count < 3) && !$has_break) {
6367c34c09a8SJoe Perches				$prevline--;
6368c34c09a8SJoe Perches				my $rline = $rawlines[$prevline - 1];
6369c34c09a8SJoe Perches				my $fline = $lines[$prevline - 1];
6370c34c09a8SJoe Perches				last if ($fline =~ /^\@\@/);
6371c34c09a8SJoe Perches				next if ($fline =~ /^\-/);
6372c34c09a8SJoe Perches				next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/);
6373c34c09a8SJoe Perches				$has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i);
6374c34c09a8SJoe Perches				next if ($fline =~ /^.[\s$;]*$/);
6375c34c09a8SJoe Perches				$has_statement = 1;
6376c34c09a8SJoe Perches				$count++;
6377258f79d5SHeinrich Schuchardt				$has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|exit\s*\(\b|return\b|goto\b|continue\b)/);
6378c34c09a8SJoe Perches			}
6379c34c09a8SJoe Perches			if (!$has_break && $has_statement) {
6380c34c09a8SJoe Perches				WARN("MISSING_BREAK",
6381224236d9SAndrew Morton				     "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr);
6382c34c09a8SJoe Perches			}
6383c34c09a8SJoe Perches		}
6384c34c09a8SJoe Perches
6385d1e2ad07SJoe Perches# check for switch/default statements without a break;
63865b57980dSJoe Perches		if ($perl_version_ok &&
6387d1e2ad07SJoe Perches		    defined $stat &&
6388d1e2ad07SJoe Perches		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
6389d1e2ad07SJoe Perches			my $cnt = statement_rawlines($stat);
6390e3d95a2aSTobin C. Harding			my $herectx = get_stat_here($linenr, $cnt, $here);
6391e3d95a2aSTobin C. Harding
6392d1e2ad07SJoe Perches			WARN("DEFAULT_NO_BREAK",
6393d1e2ad07SJoe Perches			     "switch default: should use break\n" . $herectx);
6394caf2a54fSJoe Perches		}
6395caf2a54fSJoe Perches
639613214adfSAndy Whitcroft# check for gcc specific __FUNCTION__
6397d5e616fcSJoe Perches		if ($line =~ /\b__FUNCTION__\b/) {
6398d5e616fcSJoe Perches			if (WARN("USE_FUNC",
6399d5e616fcSJoe Perches				 "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr) &&
6400d5e616fcSJoe Perches			    $fix) {
6401194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
6402d5e616fcSJoe Perches			}
640313214adfSAndy Whitcroft		}
6404773647a0SAndy Whitcroft
640562ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__
640662ec818fSJoe Perches		while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
640762ec818fSJoe Perches			ERROR("DATE_TIME",
640862ec818fSJoe Perches			      "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
640962ec818fSJoe Perches		}
641062ec818fSJoe Perches
64112c92488aSJoe Perches# check for use of yield()
64122c92488aSJoe Perches		if ($line =~ /\byield\s*\(\s*\)/) {
64132c92488aSJoe Perches			WARN("YIELD",
64142c92488aSJoe Perches			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
64152c92488aSJoe Perches		}
64162c92488aSJoe Perches
6417179f8f40SJoe Perches# check for comparisons against true and false
6418179f8f40SJoe Perches		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
6419179f8f40SJoe Perches			my $lead = $1;
6420179f8f40SJoe Perches			my $arg = $2;
6421179f8f40SJoe Perches			my $test = $3;
6422179f8f40SJoe Perches			my $otype = $4;
6423179f8f40SJoe Perches			my $trail = $5;
6424179f8f40SJoe Perches			my $op = "!";
6425179f8f40SJoe Perches
6426179f8f40SJoe Perches			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
6427179f8f40SJoe Perches
6428179f8f40SJoe Perches			my $type = lc($otype);
6429179f8f40SJoe Perches			if ($type =~ /^(?:true|false)$/) {
6430179f8f40SJoe Perches				if (("$test" eq "==" && "$type" eq "true") ||
6431179f8f40SJoe Perches				    ("$test" eq "!=" && "$type" eq "false")) {
6432179f8f40SJoe Perches					$op = "";
6433179f8f40SJoe Perches				}
6434179f8f40SJoe Perches
6435179f8f40SJoe Perches				CHK("BOOL_COMPARISON",
6436179f8f40SJoe Perches				    "Using comparison to $otype is error prone\n" . $herecurr);
6437179f8f40SJoe Perches
6438179f8f40SJoe Perches## maybe suggesting a correct construct would better
6439179f8f40SJoe Perches##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
6440179f8f40SJoe Perches
6441179f8f40SJoe Perches			}
6442179f8f40SJoe Perches		}
6443179f8f40SJoe Perches
64444882720bSThomas Gleixner# check for semaphores initialized locked
64454882720bSThomas Gleixner		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
6446000d1cc1SJoe Perches			WARN("CONSIDER_COMPLETION",
6447000d1cc1SJoe Perches			     "consider using a completion\n" . $herecurr);
6448773647a0SAndy Whitcroft		}
64496712d858SJoe Perches
645067d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto*
645167d0a075SJoe Perches		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
6452000d1cc1SJoe Perches			WARN("CONSIDER_KSTRTO",
645367d0a075SJoe Perches			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
6454773647a0SAndy Whitcroft		}
64556712d858SJoe Perches
6456ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please
6457f3db6639SMichael Ellerman		if ($line =~ /^.\s*__initcall\s*\(/) {
6458000d1cc1SJoe Perches			WARN("USE_DEVICE_INITCALL",
6459ae3ccc46SFabian Frederick			     "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
6460f3db6639SMichael Ellerman		}
64616712d858SJoe Perches
64623d709ab5SPaul E. McKenney# check for spin_is_locked(), suggest lockdep instead
64633d709ab5SPaul E. McKenney		if ($line =~ /\bspin_is_locked\(/) {
64643d709ab5SPaul E. McKenney			WARN("USE_LOCKDEP",
64653d709ab5SPaul E. McKenney			     "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr);
64663d709ab5SPaul E. McKenney		}
64673d709ab5SPaul E. McKenney
64689189c7e7SJoe Perches# check for deprecated apis
64699189c7e7SJoe Perches		if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) {
64709189c7e7SJoe Perches			my $deprecated_api = $1;
64719189c7e7SJoe Perches			my $new_api = $deprecated_apis{$deprecated_api};
64729189c7e7SJoe Perches			WARN("DEPRECATED_API",
64739189c7e7SJoe Perches			     "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr);
64749189c7e7SJoe Perches		}
64759189c7e7SJoe Perches
64760f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree)
6477d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {'
64786903ffb2SAndy Whitcroft		if ($line !~ /\bconst\b/ &&
6479d9190e4eSJoe Perches		    $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
6480000d1cc1SJoe Perches			WARN("CONST_STRUCT",
6481d9190e4eSJoe Perches			     "struct $1 should normally be const\n" . $herecurr);
64822b6db5cbSAndy Whitcroft		}
6483773647a0SAndy Whitcroft
6484773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong
6485773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right
6486773647a0SAndy Whitcroft		if ($line =~ /\bNR_CPUS\b/ &&
6487c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
6488c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
6489171ae1a4SAndy Whitcroft		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
6490171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
6491171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/)
6492773647a0SAndy Whitcroft		{
6493000d1cc1SJoe Perches			WARN("NR_CPUS",
6494000d1cc1SJoe Perches			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
6495773647a0SAndy Whitcroft		}
64969c9ba34eSAndy Whitcroft
649752ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
649852ea8506SJoe Perches		if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
649952ea8506SJoe Perches			ERROR("DEFINE_ARCH_HAS",
650052ea8506SJoe Perches			      "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
650152ea8506SJoe Perches		}
650252ea8506SJoe Perches
6503acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)"
65045b57980dSJoe Perches		if ($perl_version_ok &&
6505acd9362cSJoe Perches		    $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
6506acd9362cSJoe Perches			WARN("LIKELY_MISUSE",
6507acd9362cSJoe Perches			     "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
6508acd9362cSJoe Perches		}
6509acd9362cSJoe Perches
6510691d77b6SAndy Whitcroft# whine mightly about in_atomic
6511691d77b6SAndy Whitcroft		if ($line =~ /\bin_atomic\s*\(/) {
6512691d77b6SAndy Whitcroft			if ($realfile =~ m@^drivers/@) {
6513000d1cc1SJoe Perches				ERROR("IN_ATOMIC",
6514000d1cc1SJoe Perches				      "do not use in_atomic in drivers\n" . $herecurr);
6515f4a87736SAndy Whitcroft			} elsif ($realfile !~ m@^kernel/@) {
6516000d1cc1SJoe Perches				WARN("IN_ATOMIC",
6517000d1cc1SJoe Perches				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
6518691d77b6SAndy Whitcroft			}
6519691d77b6SAndy Whitcroft		}
65201704f47bSPeter Zijlstra
65210f5225b0SPeter Zijlstra# check for mutex_trylock_recursive usage
65220f5225b0SPeter Zijlstra		if ($line =~ /mutex_trylock_recursive/) {
65230f5225b0SPeter Zijlstra			ERROR("LOCKING",
65240f5225b0SPeter Zijlstra			      "recursive locking is bad, do not use this ever.\n" . $herecurr);
65250f5225b0SPeter Zijlstra		}
65260f5225b0SPeter Zijlstra
65271704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class
65281704f47bSPeter Zijlstra		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
65291704f47bSPeter Zijlstra		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
65301704f47bSPeter Zijlstra			if ($realfile !~ m@^kernel/lockdep@ &&
65311704f47bSPeter Zijlstra			    $realfile !~ m@^include/linux/lockdep@ &&
65321704f47bSPeter Zijlstra			    $realfile !~ m@^drivers/base/core@) {
6533000d1cc1SJoe Perches				ERROR("LOCKDEP",
6534000d1cc1SJoe Perches				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
65351704f47bSPeter Zijlstra			}
65361704f47bSPeter Zijlstra		}
653788f8831cSDave Jones
6538b392c64fSJoe Perches		if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
6539b392c64fSJoe Perches		    $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
6540000d1cc1SJoe Perches			WARN("EXPORTED_WORLD_WRITABLE",
6541000d1cc1SJoe Perches			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
654288f8831cSDave Jones		}
65432435880fSJoe Perches
654400180468SJoe Perches# check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO>
654500180468SJoe Perches# and whether or not function naming is typical and if
654600180468SJoe Perches# DEVICE_ATTR permissions uses are unusual too
65475b57980dSJoe Perches		if ($perl_version_ok &&
654800180468SJoe Perches		    defined $stat &&
654900180468SJoe 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*\)/) {
655000180468SJoe Perches			my $var = $1;
655100180468SJoe Perches			my $perms = $2;
655200180468SJoe Perches			my $show = $3;
655300180468SJoe Perches			my $store = $4;
655400180468SJoe Perches			my $octal_perms = perms_to_octal($perms);
655500180468SJoe Perches			if ($show =~ /^${var}_show$/ &&
655600180468SJoe Perches			    $store =~ /^${var}_store$/ &&
655700180468SJoe Perches			    $octal_perms eq "0644") {
655800180468SJoe Perches				if (WARN("DEVICE_ATTR_RW",
655900180468SJoe Perches					 "Use DEVICE_ATTR_RW\n" . $herecurr) &&
656000180468SJoe Perches				    $fix) {
656100180468SJoe 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})/;
656200180468SJoe Perches				}
656300180468SJoe Perches			} elsif ($show =~ /^${var}_show$/ &&
656400180468SJoe Perches				 $store =~ /^NULL$/ &&
656500180468SJoe Perches				 $octal_perms eq "0444") {
656600180468SJoe Perches				if (WARN("DEVICE_ATTR_RO",
656700180468SJoe Perches					 "Use DEVICE_ATTR_RO\n" . $herecurr) &&
656800180468SJoe Perches				    $fix) {
656900180468SJoe 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})/;
657000180468SJoe Perches				}
657100180468SJoe Perches			} elsif ($show =~ /^NULL$/ &&
657200180468SJoe Perches				 $store =~ /^${var}_store$/ &&
657300180468SJoe Perches				 $octal_perms eq "0200") {
657400180468SJoe Perches				if (WARN("DEVICE_ATTR_WO",
657500180468SJoe Perches					 "Use DEVICE_ATTR_WO\n" . $herecurr) &&
657600180468SJoe Perches				    $fix) {
657700180468SJoe 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})/;
657800180468SJoe Perches				}
657900180468SJoe Perches			} elsif ($octal_perms eq "0644" ||
658000180468SJoe Perches				 $octal_perms eq "0444" ||
658100180468SJoe Perches				 $octal_perms eq "0200") {
658200180468SJoe Perches				my $newshow = "$show";
658300180468SJoe Perches				$newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");
658400180468SJoe Perches				my $newstore = $store;
658500180468SJoe Perches				$newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");
658600180468SJoe Perches				my $rename = "";
658700180468SJoe Perches				if ($show ne $newshow) {
658800180468SJoe Perches					$rename .= " '$show' to '$newshow'";
658900180468SJoe Perches				}
659000180468SJoe Perches				if ($store ne $newstore) {
659100180468SJoe Perches					$rename .= " '$store' to '$newstore'";
659200180468SJoe Perches				}
659300180468SJoe Perches				WARN("DEVICE_ATTR_FUNCTIONS",
659400180468SJoe Perches				     "Consider renaming function(s)$rename\n" . $herecurr);
659500180468SJoe Perches			} else {
659600180468SJoe Perches				WARN("DEVICE_ATTR_PERMS",
659700180468SJoe Perches				     "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);
659800180468SJoe Perches			}
659900180468SJoe Perches		}
660000180468SJoe Perches
6601515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal
6602515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
660373121534SJoe Perches# o Ignore module_param*(...) uses with a decimal 0 permission as that has a
660473121534SJoe Perches#   specific definition of not visible in sysfs.
660573121534SJoe Perches# o Ignore proc_create*(...) uses with a decimal 0 permission as that means
660673121534SJoe Perches#   use the default permissions
66075b57980dSJoe Perches		if ($perl_version_ok &&
6608459cf0aeSJoe Perches		    defined $stat &&
6609515a235eSJoe Perches		    $line =~ /$mode_perms_search/) {
66102435880fSJoe Perches			foreach my $entry (@mode_permission_funcs) {
66112435880fSJoe Perches				my $func = $entry->[0];
66122435880fSJoe Perches				my $arg_pos = $entry->[1];
66132435880fSJoe Perches
6614459cf0aeSJoe Perches				my $lc = $stat =~ tr@\n@@;
6615459cf0aeSJoe Perches				$lc = $lc + $linenr;
66162a9f9d85STobin C. Harding				my $stat_real = get_stat_real($linenr, $lc);
6617459cf0aeSJoe Perches
66182435880fSJoe Perches				my $skip_args = "";
66192435880fSJoe Perches				if ($arg_pos > 1) {
66202435880fSJoe Perches					$arg_pos--;
66212435880fSJoe Perches					$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
66222435880fSJoe Perches				}
6623f90774e1SJoe Perches				my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
6624459cf0aeSJoe Perches				if ($stat =~ /$test/) {
66252435880fSJoe Perches					my $val = $1;
66262435880fSJoe Perches					$val = $6 if ($skip_args ne "");
662773121534SJoe Perches					if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&
662873121534SJoe Perches					    (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
662973121534SJoe Perches					     ($val =~ /^$Octal$/ && length($val) ne 4))) {
66302435880fSJoe Perches						ERROR("NON_OCTAL_PERMISSIONS",
6631459cf0aeSJoe Perches						      "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
6632f90774e1SJoe Perches					}
6633f90774e1SJoe Perches					if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
6634c0a5c898SJoe Perches						ERROR("EXPORTED_WORLD_WRITABLE",
6635459cf0aeSJoe Perches						      "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
66362435880fSJoe Perches					}
6637459cf0aeSJoe Perches				}
6638459cf0aeSJoe Perches			}
6639459cf0aeSJoe Perches		}
6640459cf0aeSJoe Perches
6641459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability
6642bc22d9a7SJoe Perches		while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {
664300180468SJoe Perches			my $oval = $1;
664400180468SJoe Perches			my $octal = perms_to_octal($oval);
6645f90774e1SJoe Perches			if (WARN("SYMBOLIC_PERMS",
6646459cf0aeSJoe Perches				 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
6647f90774e1SJoe Perches			    $fix) {
664800180468SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;
66492435880fSJoe Perches			}
665013214adfSAndy Whitcroft		}
66515a6d20ceSBjorn Andersson
66525a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h
66535a6d20ceSBjorn Andersson		if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
66545a6d20ceSBjorn Andersson			my $extracted_string = get_quoted_string($line, $rawline);
66555a6d20ceSBjorn Andersson			my $valid_licenses = qr{
66565a6d20ceSBjorn Andersson						GPL|
66575a6d20ceSBjorn Andersson						GPL\ v2|
66585a6d20ceSBjorn Andersson						GPL\ and\ additional\ rights|
66595a6d20ceSBjorn Andersson						Dual\ BSD/GPL|
66605a6d20ceSBjorn Andersson						Dual\ MIT/GPL|
66615a6d20ceSBjorn Andersson						Dual\ MPL/GPL|
66625a6d20ceSBjorn Andersson						Proprietary
66635a6d20ceSBjorn Andersson					}x;
66645a6d20ceSBjorn Andersson			if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
66655a6d20ceSBjorn Andersson				WARN("MODULE_LICENSE",
66665a6d20ceSBjorn Andersson				     "unknown module license " . $extracted_string . "\n" . $herecurr);
66675a6d20ceSBjorn Andersson			}
66685a6d20ceSBjorn Andersson		}
66696a8d76cbSMatteo Croce
66706a8d76cbSMatteo Croce# check for sysctl duplicate constants
66716a8d76cbSMatteo Croce		if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) {
66726a8d76cbSMatteo Croce			WARN("DUPLICATED_SYSCTL_CONST",
66736a8d76cbSMatteo Croce				"duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr);
66746a8d76cbSMatteo Croce		}
6675515a235eSJoe Perches	}
667613214adfSAndy Whitcroft
667713214adfSAndy Whitcroft	# If we have no input at all, then there is nothing to report on
667813214adfSAndy Whitcroft	# so just keep quiet.
667913214adfSAndy Whitcroft	if ($#rawlines == -1) {
668013214adfSAndy Whitcroft		exit(0);
66810a920b5bSAndy Whitcroft	}
66820a920b5bSAndy Whitcroft
66838905a67cSAndy Whitcroft	# In mailback mode only produce a report in the negative, for
66848905a67cSAndy Whitcroft	# things that appear to be patches.
66858905a67cSAndy Whitcroft	if ($mailback && ($clean == 1 || !$is_patch)) {
66868905a67cSAndy Whitcroft		exit(0);
66878905a67cSAndy Whitcroft	}
66888905a67cSAndy Whitcroft
66898905a67cSAndy Whitcroft	# This is not a patch, and we are are in 'no-patch' mode so
66908905a67cSAndy Whitcroft	# just keep quiet.
66918905a67cSAndy Whitcroft	if (!$chk_patch && !$is_patch) {
66928905a67cSAndy Whitcroft		exit(0);
66938905a67cSAndy Whitcroft	}
66948905a67cSAndy Whitcroft
6695a08ffbefSStafford Horne	if (!$is_patch && $filename !~ /cover-letter\.patch$/) {
6696000d1cc1SJoe Perches		ERROR("NOT_UNIFIED_DIFF",
6697000d1cc1SJoe Perches		      "Does not appear to be a unified-diff format patch\n");
66980a920b5bSAndy Whitcroft	}
6699cd261496SGeert Uytterhoeven	if ($is_patch && $has_commit_log && $chk_signoff) {
6700cd261496SGeert Uytterhoeven		if ($signoff == 0) {
6701000d1cc1SJoe Perches			ERROR("MISSING_SIGN_OFF",
6702000d1cc1SJoe Perches			      "Missing Signed-off-by: line(s)\n");
6703cd261496SGeert Uytterhoeven		} elsif (!$authorsignoff) {
6704cd261496SGeert Uytterhoeven			WARN("NO_AUTHOR_SIGN_OFF",
6705cd261496SGeert Uytterhoeven			     "Missing Signed-off-by: line by nominal patch author '$author'\n");
6706cd261496SGeert Uytterhoeven		}
67070a920b5bSAndy Whitcroft	}
67080a920b5bSAndy Whitcroft
6709f0a594c1SAndy Whitcroft	print report_dump();
671013214adfSAndy Whitcroft	if ($summary && !($clean == 1 && $quiet == 1)) {
671113214adfSAndy Whitcroft		print "$filename " if ($summary_file);
67126c72ffaaSAndy Whitcroft		print "total: $cnt_error errors, $cnt_warn warnings, " .
67136c72ffaaSAndy Whitcroft			(($check)? "$cnt_chk checks, " : "") .
67146c72ffaaSAndy Whitcroft			"$cnt_lines lines checked\n";
67156c72ffaaSAndy Whitcroft	}
67168905a67cSAndy Whitcroft
6717d2c0a235SAndy Whitcroft	if ($quiet == 0) {
6718ef212196SJoe Perches		# If there were any defects found and not already fixing them
6719ef212196SJoe Perches		if (!$clean and !$fix) {
6720ef212196SJoe Perches			print << "EOM"
6721ef212196SJoe Perches
6722ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to
6723ef212196SJoe Perches      mechanically convert to the typical style using --fix or --fix-inplace.
6724ef212196SJoe PerchesEOM
6725ef212196SJoe Perches		}
6726d2c0a235SAndy Whitcroft		# If there were whitespace errors which cleanpatch can fix
6727d2c0a235SAndy Whitcroft		# then suggest that.
6728d2c0a235SAndy Whitcroft		if ($rpt_cleaners) {
6729b0781216SMike Frysinger			$rpt_cleaners = 0;
6730d8469f16SJoe Perches			print << "EOM"
6731d8469f16SJoe Perches
6732d8469f16SJoe PerchesNOTE: Whitespace errors detected.
6733d8469f16SJoe Perches      You may wish to use scripts/cleanpatch or scripts/cleanfile
6734d8469f16SJoe PerchesEOM
6735d2c0a235SAndy Whitcroft		}
6736d2c0a235SAndy Whitcroft	}
6737d2c0a235SAndy Whitcroft
6738d752fcc8SJoe Perches	if ($clean == 0 && $fix &&
6739d752fcc8SJoe Perches	    ("@rawlines" ne "@fixed" ||
6740d752fcc8SJoe Perches	     $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
67419624b8d6SJoe Perches		my $newfile = $filename;
67429624b8d6SJoe Perches		$newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
67433705ce5bSJoe Perches		my $linecount = 0;
67443705ce5bSJoe Perches		my $f;
67453705ce5bSJoe Perches
6746d752fcc8SJoe Perches		@fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
6747d752fcc8SJoe Perches
67483705ce5bSJoe Perches		open($f, '>', $newfile)
67493705ce5bSJoe Perches		    or die "$P: Can't open $newfile for write\n";
67503705ce5bSJoe Perches		foreach my $fixed_line (@fixed) {
67513705ce5bSJoe Perches			$linecount++;
67523705ce5bSJoe Perches			if ($file) {
67533705ce5bSJoe Perches				if ($linecount > 3) {
67543705ce5bSJoe Perches					$fixed_line =~ s/^\+//;
67553705ce5bSJoe Perches					print $f $fixed_line . "\n";
67563705ce5bSJoe Perches				}
67573705ce5bSJoe Perches			} else {
67583705ce5bSJoe Perches				print $f $fixed_line . "\n";
67593705ce5bSJoe Perches			}
67603705ce5bSJoe Perches		}
67613705ce5bSJoe Perches		close($f);
67623705ce5bSJoe Perches
67633705ce5bSJoe Perches		if (!$quiet) {
67643705ce5bSJoe Perches			print << "EOM";
6765d8469f16SJoe Perches
67663705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile'
67673705ce5bSJoe Perches
67683705ce5bSJoe PerchesDo _NOT_ trust the results written to this file.
67693705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness.
67703705ce5bSJoe Perches
67713705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches.
67723705ce5bSJoe PerchesNo warranties, expressed or implied...
67733705ce5bSJoe PerchesEOM
67743705ce5bSJoe Perches		}
67753705ce5bSJoe Perches	}
67763705ce5bSJoe Perches
6777d8469f16SJoe Perches	if ($quiet == 0) {
6778d8469f16SJoe Perches		print "\n";
6779d8469f16SJoe Perches		if ($clean == 1) {
6780d8469f16SJoe Perches			print "$vname has no obvious style problems and is ready for submission.\n";
6781d8469f16SJoe Perches		} else {
6782d8469f16SJoe Perches			print "$vname has style problems, please review.\n";
67830a920b5bSAndy Whitcroft		}
67840a920b5bSAndy Whitcroft	}
67850a920b5bSAndy Whitcroft	return $clean;
67860a920b5bSAndy Whitcroft}
6787