xref: /linux-6.15/scripts/checkpatch.pl (revision 8d81ae05)
1cb77f0d6SKamil Rytarowski#!/usr/bin/env perl
2dbf004d7SDave Jones# (c) 2001, Dave Jones. (the file handling bit)
300df344fSAndy Whitcroft# (c) 2005, Joel Schopp <[email protected]> (the ugly bit)
42a5a2c25SAndy Whitcroft# (c) 2007,2008, Andy Whitcroft <[email protected]> (new conditions, test suite)
5015830beSAndy Whitcroft# (c) 2008-2010 Andy Whitcroft <[email protected]>
60a920b5bSAndy Whitcroft# Licensed under the terms of the GNU GPL License version 2
70a920b5bSAndy Whitcroft
80a920b5bSAndy Whitcroftuse strict;
9cb77f0d6SKamil Rytarowskiuse warnings;
10c707a81dSJoe Perchesuse POSIX;
1136061e38SJoe Perchesuse File::Basename;
1236061e38SJoe Perchesuse Cwd 'abs_path';
1357230297SJoe Perchesuse Term::ANSIColor qw(:constants);
140a920b5bSAndy Whitcroft
150a920b5bSAndy Whitcroftmy $P = $0;
1636061e38SJoe Perchesmy $D = dirname(abs_path($P));
170a920b5bSAndy Whitcroft
18000d1cc1SJoe Perchesmy $V = '0.32';
190a920b5bSAndy Whitcroft
200a920b5bSAndy Whitcroftuse Getopt::Long qw(:config no_auto_abbrev);
210a920b5bSAndy Whitcroft
220a920b5bSAndy Whitcroftmy $quiet = 0;
230a920b5bSAndy Whitcroftmy $tree = 1;
240a920b5bSAndy Whitcroftmy $chk_signoff = 1;
250a920b5bSAndy Whitcroftmy $chk_patch = 1;
26773647a0SAndy Whitcroftmy $tst_only;
276c72ffaaSAndy Whitcroftmy $emacs = 0;
288905a67cSAndy Whitcroftmy $terse = 0;
2934d8815fSJoe Perchesmy $showfile = 0;
306c72ffaaSAndy Whitcroftmy $file = 0;
314a593c34SDu, Changbinmy $git = 0;
320dea9f1eSJoe Perchesmy %git_commits = ();
336c72ffaaSAndy Whitcroftmy $check = 0;
342ac73b4fSJoe Perchesmy $check_orig = 0;
358905a67cSAndy Whitcroftmy $summary = 1;
368905a67cSAndy Whitcroftmy $mailback = 0;
3713214adfSAndy Whitcroftmy $summary_file = 0;
38000d1cc1SJoe Perchesmy $show_types = 0;
393beb42ecSJoe Perchesmy $list_types = 0;
403705ce5bSJoe Perchesmy $fix = 0;
419624b8d6SJoe Perchesmy $fix_inplace = 0;
426c72ffaaSAndy Whitcroftmy $root;
43c2fdda0dSAndy Whitcroftmy %debug;
443445686aSJoe Perchesmy %camelcase = ();
4591bfe484SJoe Perchesmy %use_type = ();
4691bfe484SJoe Perchesmy @use = ();
4791bfe484SJoe Perchesmy %ignore_type = ();
48000d1cc1SJoe Perchesmy @ignore = ();
4977f5b10aSHannes Edermy $help = 0;
50000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf";
516cd7f386SJoe Perchesmy $max_line_length = 80;
52d62a201fSDave Hansenmy $ignore_perl_version = 0;
53d62a201fSDave Hansenmy $minimum_perl_version = 5.10.0;
5456193274SVadim Bendeburymy $min_conf_desc_length = 4;
5566b47b4aSKees Cookmy $spelling_file = "$D/spelling.txt";
56ebfd7d62SJoe Perchesmy $codespell = 0;
57f1a63678SMaxim Uvarovmy $codespellfile = "/usr/share/codespell/dictionary.txt";
58bf1fa1daSJoe Perchesmy $conststructsfile = "$D/const_structs.checkpatch";
5975ad8c57SJerome Forissiermy $typedefsfile = "";
6057230297SJoe Perchesmy $color = 1;
61dadf680dSJoe Perchesmy $allow_c99_comments = 1;
6277f5b10aSHannes Eder
6377f5b10aSHannes Edersub help {
6477f5b10aSHannes Eder	my ($exitcode) = @_;
6577f5b10aSHannes Eder
6677f5b10aSHannes Eder	print << "EOM";
6777f5b10aSHannes EderUsage: $P [OPTION]... [FILE]...
6877f5b10aSHannes EderVersion: $V
6977f5b10aSHannes Eder
7077f5b10aSHannes EderOptions:
7177f5b10aSHannes Eder  -q, --quiet                quiet
7277f5b10aSHannes Eder  --no-tree                  run without a kernel tree
7377f5b10aSHannes Eder  --no-signoff               do not check for 'Signed-off-by' line
7477f5b10aSHannes Eder  --patch                    treat FILE as patchfile (default)
7577f5b10aSHannes Eder  --emacs                    emacs compile window format
7677f5b10aSHannes Eder  --terse                    one line per report
7734d8815fSJoe Perches  --showfile                 emit diffed file position, not input file position
784a593c34SDu, Changbin  -g, --git                  treat FILE as a single commit or git revision range
794a593c34SDu, Changbin                             single git commit with:
804a593c34SDu, Changbin                               <rev>
814a593c34SDu, Changbin                               <rev>^
824a593c34SDu, Changbin                               <rev>~n
834a593c34SDu, Changbin                             multiple git commits with:
844a593c34SDu, Changbin                               <rev1>..<rev2>
854a593c34SDu, Changbin                               <rev1>...<rev2>
864a593c34SDu, Changbin                               <rev>-<count>
874a593c34SDu, Changbin                             git merges are ignored
8877f5b10aSHannes Eder  -f, --file                 treat FILE as regular source file
8977f5b10aSHannes Eder  --subjective, --strict     enable more subjective tests
903beb42ecSJoe Perches  --list-types               list the possible message types
9191bfe484SJoe Perches  --types TYPE(,TYPE2...)    show only these comma separated message types
92000d1cc1SJoe Perches  --ignore TYPE(,TYPE2...)   ignore various comma separated message types
933beb42ecSJoe Perches  --show-types               show the specific message type in the output
946cd7f386SJoe Perches  --max-line-length=n        set the maximum line length, if exceeded, warn
9556193274SVadim Bendebury  --min-conf-desc-length=n   set the min description length, if shorter, warn
9677f5b10aSHannes Eder  --root=PATH                PATH to the kernel tree root
9777f5b10aSHannes Eder  --no-summary               suppress the per-file summary
9877f5b10aSHannes Eder  --mailback                 only produce a report in case of warnings/errors
9977f5b10aSHannes Eder  --summary-file             include the filename in summary
10077f5b10aSHannes Eder  --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of
10177f5b10aSHannes Eder                             'values', 'possible', 'type', and 'attr' (default
10277f5b10aSHannes Eder                             is all off)
10377f5b10aSHannes Eder  --test-only=WORD           report only warnings/errors containing WORD
10477f5b10aSHannes Eder                             literally
1053705ce5bSJoe Perches  --fix                      EXPERIMENTAL - may create horrible results
1063705ce5bSJoe Perches                             If correctable single-line errors exist, create
1073705ce5bSJoe Perches                             "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
1083705ce5bSJoe Perches                             with potential errors corrected to the preferred
1093705ce5bSJoe Perches                             checkpatch style
1109624b8d6SJoe Perches  --fix-inplace              EXPERIMENTAL - may create horrible results
1119624b8d6SJoe Perches                             Is the same as --fix, but overwrites the input
1129624b8d6SJoe Perches                             file.  It's your fault if there's no backup or git
113d62a201fSDave Hansen  --ignore-perl-version      override checking of perl version.  expect
114d62a201fSDave Hansen                             runtime errors.
115ebfd7d62SJoe Perches  --codespell                Use the codespell dictionary for spelling/typos
116f1a63678SMaxim Uvarov                             (default:/usr/share/codespell/dictionary.txt)
117ebfd7d62SJoe Perches  --codespellfile            Use this codespell dictionary
11875ad8c57SJerome Forissier  --typedefsfile             Read additional types from this file
11957230297SJoe Perches  --color                    Use colors when output is STDOUT (default: on)
12077f5b10aSHannes Eder  -h, --help, --version      display this help and exit
12177f5b10aSHannes Eder
12277f5b10aSHannes EderWhen FILE is - read standard input.
12377f5b10aSHannes EderEOM
12477f5b10aSHannes Eder
12577f5b10aSHannes Eder	exit($exitcode);
12677f5b10aSHannes Eder}
12777f5b10aSHannes Eder
1283beb42ecSJoe Perchessub uniq {
1293beb42ecSJoe Perches	my %seen;
1303beb42ecSJoe Perches	return grep { !$seen{$_}++ } @_;
1313beb42ecSJoe Perches}
1323beb42ecSJoe Perches
1333beb42ecSJoe Perchessub list_types {
1343beb42ecSJoe Perches	my ($exitcode) = @_;
1353beb42ecSJoe Perches
1363beb42ecSJoe Perches	my $count = 0;
1373beb42ecSJoe Perches
1383beb42ecSJoe Perches	local $/ = undef;
1393beb42ecSJoe Perches
1403beb42ecSJoe Perches	open(my $script, '<', abs_path($P)) or
1413beb42ecSJoe Perches	    die "$P: Can't read '$P' $!\n";
1423beb42ecSJoe Perches
1433beb42ecSJoe Perches	my $text = <$script>;
1443beb42ecSJoe Perches	close($script);
1453beb42ecSJoe Perches
1463beb42ecSJoe Perches	my @types = ();
1473beb42ecSJoe Perches	for ($text =~ /\b(?:(?:CHK|WARN|ERROR)\s*\(\s*"([^"]+)")/g) {
1483beb42ecSJoe Perches		push (@types, $_);
1493beb42ecSJoe Perches	}
1503beb42ecSJoe Perches	@types = sort(uniq(@types));
1513beb42ecSJoe Perches	print("#\tMessage type\n\n");
1523beb42ecSJoe Perches	foreach my $type (@types) {
1533beb42ecSJoe Perches		print(++$count . "\t" . $type . "\n");
1543beb42ecSJoe Perches	}
1553beb42ecSJoe Perches
1563beb42ecSJoe Perches	exit($exitcode);
1573beb42ecSJoe Perches}
1583beb42ecSJoe Perches
159000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file);
160000d1cc1SJoe Perchesif (-f $conf) {
161000d1cc1SJoe Perches	my @conf_args;
162000d1cc1SJoe Perches	open(my $conffile, '<', "$conf")
163000d1cc1SJoe Perches	    or warn "$P: Can't find a readable $configuration_file file $!\n";
164000d1cc1SJoe Perches
165000d1cc1SJoe Perches	while (<$conffile>) {
166000d1cc1SJoe Perches		my $line = $_;
167000d1cc1SJoe Perches
168000d1cc1SJoe Perches		$line =~ s/\s*\n?$//g;
169000d1cc1SJoe Perches		$line =~ s/^\s*//g;
170000d1cc1SJoe Perches		$line =~ s/\s+/ /g;
171000d1cc1SJoe Perches
172000d1cc1SJoe Perches		next if ($line =~ m/^\s*#/);
173000d1cc1SJoe Perches		next if ($line =~ m/^\s*$/);
174000d1cc1SJoe Perches
175000d1cc1SJoe Perches		my @words = split(" ", $line);
176000d1cc1SJoe Perches		foreach my $word (@words) {
177000d1cc1SJoe Perches			last if ($word =~ m/^#/);
178000d1cc1SJoe Perches			push (@conf_args, $word);
179000d1cc1SJoe Perches		}
180000d1cc1SJoe Perches	}
181000d1cc1SJoe Perches	close($conffile);
182000d1cc1SJoe Perches	unshift(@ARGV, @conf_args) if @conf_args;
183000d1cc1SJoe Perches}
184000d1cc1SJoe Perches
1850a920b5bSAndy WhitcroftGetOptions(
1866c72ffaaSAndy Whitcroft	'q|quiet+'	=> \$quiet,
1870a920b5bSAndy Whitcroft	'tree!'		=> \$tree,
1880a920b5bSAndy Whitcroft	'signoff!'	=> \$chk_signoff,
1890a920b5bSAndy Whitcroft	'patch!'	=> \$chk_patch,
1906c72ffaaSAndy Whitcroft	'emacs!'	=> \$emacs,
1918905a67cSAndy Whitcroft	'terse!'	=> \$terse,
19234d8815fSJoe Perches	'showfile!'	=> \$showfile,
19377f5b10aSHannes Eder	'f|file!'	=> \$file,
1944a593c34SDu, Changbin	'g|git!'	=> \$git,
1956c72ffaaSAndy Whitcroft	'subjective!'	=> \$check,
1966c72ffaaSAndy Whitcroft	'strict!'	=> \$check,
197000d1cc1SJoe Perches	'ignore=s'	=> \@ignore,
19891bfe484SJoe Perches	'types=s'	=> \@use,
199000d1cc1SJoe Perches	'show-types!'	=> \$show_types,
2003beb42ecSJoe Perches	'list-types!'	=> \$list_types,
2016cd7f386SJoe Perches	'max-line-length=i' => \$max_line_length,
20256193274SVadim Bendebury	'min-conf-desc-length=i' => \$min_conf_desc_length,
2036c72ffaaSAndy Whitcroft	'root=s'	=> \$root,
2048905a67cSAndy Whitcroft	'summary!'	=> \$summary,
2058905a67cSAndy Whitcroft	'mailback!'	=> \$mailback,
20613214adfSAndy Whitcroft	'summary-file!'	=> \$summary_file,
2073705ce5bSJoe Perches	'fix!'		=> \$fix,
2089624b8d6SJoe Perches	'fix-inplace!'	=> \$fix_inplace,
209d62a201fSDave Hansen	'ignore-perl-version!' => \$ignore_perl_version,
210c2fdda0dSAndy Whitcroft	'debug=s'	=> \%debug,
211773647a0SAndy Whitcroft	'test-only=s'	=> \$tst_only,
212ebfd7d62SJoe Perches	'codespell!'	=> \$codespell,
213ebfd7d62SJoe Perches	'codespellfile=s'	=> \$codespellfile,
21475ad8c57SJerome Forissier	'typedefsfile=s'	=> \$typedefsfile,
21557230297SJoe Perches	'color!'	=> \$color,
21677f5b10aSHannes Eder	'h|help'	=> \$help,
21777f5b10aSHannes Eder	'version'	=> \$help
21877f5b10aSHannes Eder) or help(1);
21977f5b10aSHannes Eder
22077f5b10aSHannes Ederhelp(0) if ($help);
2210a920b5bSAndy Whitcroft
2223beb42ecSJoe Percheslist_types(0) if ($list_types);
2233beb42ecSJoe Perches
2249624b8d6SJoe Perches$fix = 1 if ($fix_inplace);
2252ac73b4fSJoe Perches$check_orig = $check;
2269624b8d6SJoe Perches
2270a920b5bSAndy Whitcroftmy $exit = 0;
2280a920b5bSAndy Whitcroft
229d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) {
230d62a201fSDave Hansen	printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
231d62a201fSDave Hansen	if (!$ignore_perl_version) {
232d62a201fSDave Hansen		exit(1);
233d62a201fSDave Hansen	}
234d62a201fSDave Hansen}
235d62a201fSDave Hansen
23645107ff6SAllen Hubbe#if no filenames are given, push '-' to read patch from stdin
2370a920b5bSAndy Whitcroftif ($#ARGV < 0) {
23845107ff6SAllen Hubbe	push(@ARGV, '-');
2390a920b5bSAndy Whitcroft}
2400a920b5bSAndy Whitcroft
24191bfe484SJoe Perchessub hash_save_array_words {
24291bfe484SJoe Perches	my ($hashRef, $arrayRef) = @_;
24391bfe484SJoe Perches
24491bfe484SJoe Perches	my @array = split(/,/, join(',', @$arrayRef));
24591bfe484SJoe Perches	foreach my $word (@array) {
246000d1cc1SJoe Perches		$word =~ s/\s*\n?$//g;
247000d1cc1SJoe Perches		$word =~ s/^\s*//g;
248000d1cc1SJoe Perches		$word =~ s/\s+/ /g;
249000d1cc1SJoe Perches		$word =~ tr/[a-z]/[A-Z]/;
250000d1cc1SJoe Perches
251000d1cc1SJoe Perches		next if ($word =~ m/^\s*#/);
252000d1cc1SJoe Perches		next if ($word =~ m/^\s*$/);
253000d1cc1SJoe Perches
25491bfe484SJoe Perches		$hashRef->{$word}++;
255000d1cc1SJoe Perches	}
25691bfe484SJoe Perches}
25791bfe484SJoe Perches
25891bfe484SJoe Perchessub hash_show_words {
25991bfe484SJoe Perches	my ($hashRef, $prefix) = @_;
26091bfe484SJoe Perches
2613c816e49SJoe Perches	if (keys %$hashRef) {
262d8469f16SJoe Perches		print "\nNOTE: $prefix message types:";
26358cb3cf6SJoe Perches		foreach my $word (sort keys %$hashRef) {
26491bfe484SJoe Perches			print " $word";
26591bfe484SJoe Perches		}
266d8469f16SJoe Perches		print "\n";
26791bfe484SJoe Perches	}
26891bfe484SJoe Perches}
26991bfe484SJoe Perches
27091bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore);
27191bfe484SJoe Percheshash_save_array_words(\%use_type, \@use);
272000d1cc1SJoe Perches
273c2fdda0dSAndy Whitcroftmy $dbg_values = 0;
274c2fdda0dSAndy Whitcroftmy $dbg_possible = 0;
2757429c690SAndy Whitcroftmy $dbg_type = 0;
276a1ef277eSAndy Whitcroftmy $dbg_attr = 0;
277c2fdda0dSAndy Whitcroftfor my $key (keys %debug) {
27821caa13cSAndy Whitcroft	## no critic
27921caa13cSAndy Whitcroft	eval "\${dbg_$key} = '$debug{$key}';";
28021caa13cSAndy Whitcroft	die "$@" if ($@);
281c2fdda0dSAndy Whitcroft}
282c2fdda0dSAndy Whitcroft
283d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0;
284d2c0a235SAndy Whitcroft
2858905a67cSAndy Whitcroftif ($terse) {
2868905a67cSAndy Whitcroft	$emacs = 1;
2878905a67cSAndy Whitcroft	$quiet++;
2888905a67cSAndy Whitcroft}
2898905a67cSAndy Whitcroft
2906c72ffaaSAndy Whitcroftif ($tree) {
2916c72ffaaSAndy Whitcroft	if (defined $root) {
2926c72ffaaSAndy Whitcroft		if (!top_of_kernel_tree($root)) {
2936c72ffaaSAndy Whitcroft			die "$P: $root: --root does not point at a valid tree\n";
2946c72ffaaSAndy Whitcroft		}
2956c72ffaaSAndy Whitcroft	} else {
2966c72ffaaSAndy Whitcroft		if (top_of_kernel_tree('.')) {
2976c72ffaaSAndy Whitcroft			$root = '.';
2986c72ffaaSAndy Whitcroft		} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
2996c72ffaaSAndy Whitcroft						top_of_kernel_tree($1)) {
3006c72ffaaSAndy Whitcroft			$root = $1;
3016c72ffaaSAndy Whitcroft		}
3026c72ffaaSAndy Whitcroft	}
3036c72ffaaSAndy Whitcroft
3046c72ffaaSAndy Whitcroft	if (!defined $root) {
3050a920b5bSAndy Whitcroft		print "Must be run from the top-level dir. of a kernel tree\n";
3060a920b5bSAndy Whitcroft		exit(2);
3070a920b5bSAndy Whitcroft	}
3086c72ffaaSAndy Whitcroft}
3096c72ffaaSAndy Whitcroft
3106c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0;
3116c72ffaaSAndy Whitcroft
3122ceb532bSAndy Whitcroftour $Ident	= qr{
3132ceb532bSAndy Whitcroft			[A-Za-z_][A-Za-z\d_]*
3142ceb532bSAndy Whitcroft			(?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
3152ceb532bSAndy Whitcroft		}x;
3166c72ffaaSAndy Whitcroftour $Storage	= qr{extern|static|asmlinkage};
3176c72ffaaSAndy Whitcroftour $Sparse	= qr{
3186c72ffaaSAndy Whitcroft			__user|
3196c72ffaaSAndy Whitcroft			__kernel|
3206c72ffaaSAndy Whitcroft			__force|
3216c72ffaaSAndy Whitcroft			__iomem|
3226c72ffaaSAndy Whitcroft			__must_check|
3236c72ffaaSAndy Whitcroft			__init_refok|
324417495edSAndy Whitcroft			__kprobes|
325165e72a6SSven Eckelmann			__ref|
326ad315455SBoqun Feng			__rcu|
327ad315455SBoqun Feng			__private
3286c72ffaaSAndy Whitcroft		}x;
329e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
330e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
331e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
332e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
333e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
3348716de38SJoe Perches
33552131292SWolfram Sang# Notes to $Attribute:
33652131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
3376c72ffaaSAndy Whitcroftour $Attribute	= qr{
3386c72ffaaSAndy Whitcroft			const|
33903f1df7dSJoe Perches			__percpu|
34003f1df7dSJoe Perches			__nocast|
34103f1df7dSJoe Perches			__safe|
34246d832f5SMichael S. Tsirkin			__bitwise|
34303f1df7dSJoe Perches			__packed__|
34403f1df7dSJoe Perches			__packed2__|
34503f1df7dSJoe Perches			__naked|
34603f1df7dSJoe Perches			__maybe_unused|
34703f1df7dSJoe Perches			__always_unused|
34803f1df7dSJoe Perches			__noreturn|
34903f1df7dSJoe Perches			__used|
35003f1df7dSJoe Perches			__cold|
351e23ef1f3SJoe Perches			__pure|
35203f1df7dSJoe Perches			__noclone|
35303f1df7dSJoe Perches			__deprecated|
3546c72ffaaSAndy Whitcroft			__read_mostly|
3556c72ffaaSAndy Whitcroft			__kprobes|
3568716de38SJoe Perches			$InitAttribute|
35724e1d81aSAndy Whitcroft			____cacheline_aligned|
35824e1d81aSAndy Whitcroft			____cacheline_aligned_in_smp|
3595fe3af11SAndy Whitcroft			____cacheline_internodealigned_in_smp|
3605fe3af11SAndy Whitcroft			__weak
3616c72ffaaSAndy Whitcroft		  }x;
362c45dcabdSAndy Whitcroftour $Modifier;
36391cb5195SJoe Perchesour $Inline	= qr{inline|__always_inline|noinline|__inline|__inline__};
3646c72ffaaSAndy Whitcroftour $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};
3656c72ffaaSAndy Whitcroftour $Lval	= qr{$Ident(?:$Member)*};
3666c72ffaaSAndy Whitcroft
36795e2c602SJoe Perchesour $Int_type	= qr{(?i)llu|ull|ll|lu|ul|l|u};
36895e2c602SJoe Perchesour $Binary	= qr{(?i)0b[01]+$Int_type?};
36995e2c602SJoe Perchesour $Hex	= qr{(?i)0x[0-9a-f]+$Int_type?};
37095e2c602SJoe Perchesour $Int	= qr{[0-9]+$Int_type?};
3712435880fSJoe Perchesour $Octal	= qr{0[0-7]+$Int_type?};
372c0a5c898SJoe Perchesour $String	= qr{"[X\t]*"};
373326b1ffcSJoe Perchesour $Float_hex	= qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
374326b1ffcSJoe Perchesour $Float_dec	= qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
375326b1ffcSJoe Perchesour $Float_int	= qr{(?i)[0-9]+e-?[0-9]+[fl]?};
37674349bccSJoe Perchesour $Float	= qr{$Float_hex|$Float_dec|$Float_int};
3772435880fSJoe Perchesour $Constant	= qr{$Float|$Binary|$Octal|$Hex|$Int};
378326b1ffcSJoe Perchesour $Assignment	= qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
379447432f3SJoe Perchesour $Compare    = qr{<=|>=|==|!=|<|(?<!-)>};
38023f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%};
3816c72ffaaSAndy Whitcroftour $Operators	= qr{
3826c72ffaaSAndy Whitcroft			<=|>=|==|!=|
3836c72ffaaSAndy Whitcroft			=>|->|<<|>>|<|>|!|~|
38423f780c9SJoe Perches			&&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
3856c72ffaaSAndy Whitcroft		  }x;
3866c72ffaaSAndy Whitcroft
38791cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
38891cb5195SJoe Perches
389ab7e23f3SJoe Perchesour $BasicType;
3908905a67cSAndy Whitcroftour $NonptrType;
3911813087dSJoe Perchesour $NonptrTypeMisordered;
3928716de38SJoe Perchesour $NonptrTypeWithAttr;
3938905a67cSAndy Whitcroftour $Type;
3941813087dSJoe Perchesour $TypeMisordered;
3958905a67cSAndy Whitcroftour $Declare;
3961813087dSJoe Perchesour $DeclareMisordered;
3978905a67cSAndy Whitcroft
39815662b3eSJoe Perchesour $NON_ASCII_UTF8	= qr{
39915662b3eSJoe Perches	[\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte
400171ae1a4SAndy Whitcroft	|  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
401171ae1a4SAndy Whitcroft	| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
402171ae1a4SAndy Whitcroft	|  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
403171ae1a4SAndy Whitcroft	|  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
404171ae1a4SAndy Whitcroft	| [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
405171ae1a4SAndy Whitcroft	|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
406171ae1a4SAndy Whitcroft}x;
407171ae1a4SAndy Whitcroft
40815662b3eSJoe Perchesour $UTF8	= qr{
40915662b3eSJoe Perches	[\x09\x0A\x0D\x20-\x7E]              # ASCII
41015662b3eSJoe Perches	| $NON_ASCII_UTF8
41115662b3eSJoe Perches}x;
41215662b3eSJoe Perches
413e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
414021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x:
415021158b4SJoe Perches	u_(?:char|short|int|long) |          # bsd
416021158b4SJoe Perches	u(?:nchar|short|int|long)            # sysv
417021158b4SJoe Perches)};
418e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x:
419fb9e9096SAndy Whitcroft	(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
4208ed22cadSAndy Whitcroft	atomic_t
4218ed22cadSAndy Whitcroft)};
422e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x:
423e6176fa4SJoe Perches	$typeC99Typedefs\b|
424e6176fa4SJoe Perches	$typeOtherOSTypedefs\b|
425e6176fa4SJoe Perches	$typeKernelTypedefs\b
426e6176fa4SJoe Perches)};
4278ed22cadSAndy Whitcroft
4286d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
4296d32f7a3SJoe Perches
430691e669bSJoe Perchesour $logFunctions = qr{(?x:
431758d7aadSMiles Chen	printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
4327d0b6594SJacob Keller	(?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
4336e60c02eSJoe Perches	WARN(?:_RATELIMIT|_ONCE|)|
434b0531722SJoe Perches	panic|
43506668727SJoe Perches	MODULE_[A-Z_]+|
43606668727SJoe Perches	seq_vprintf|seq_printf|seq_puts
437691e669bSJoe Perches)};
438691e669bSJoe Perches
43920112475SJoe Perchesour $signature_tags = qr{(?xi:
44020112475SJoe Perches	Signed-off-by:|
44120112475SJoe Perches	Acked-by:|
44220112475SJoe Perches	Tested-by:|
44320112475SJoe Perches	Reviewed-by:|
44420112475SJoe Perches	Reported-by:|
4458543ae12SMugunthan V N	Suggested-by:|
44620112475SJoe Perches	To:|
44720112475SJoe Perches	Cc:
44820112475SJoe Perches)};
44920112475SJoe Perches
4501813087dSJoe Perchesour @typeListMisordered = (
4511813087dSJoe Perches	qr{char\s+(?:un)?signed},
4521813087dSJoe Perches	qr{int\s+(?:(?:un)?signed\s+)?short\s},
4531813087dSJoe Perches	qr{int\s+short(?:\s+(?:un)?signed)},
4541813087dSJoe Perches	qr{short\s+int(?:\s+(?:un)?signed)},
4551813087dSJoe Perches	qr{(?:un)?signed\s+int\s+short},
4561813087dSJoe Perches	qr{short\s+(?:un)?signed},
4571813087dSJoe Perches	qr{long\s+int\s+(?:un)?signed},
4581813087dSJoe Perches	qr{int\s+long\s+(?:un)?signed},
4591813087dSJoe Perches	qr{long\s+(?:un)?signed\s+int},
4601813087dSJoe Perches	qr{int\s+(?:un)?signed\s+long},
4611813087dSJoe Perches	qr{int\s+(?:un)?signed},
4621813087dSJoe Perches	qr{int\s+long\s+long\s+(?:un)?signed},
4631813087dSJoe Perches	qr{long\s+long\s+int\s+(?:un)?signed},
4641813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed\s+int},
4651813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed},
4661813087dSJoe Perches	qr{long\s+(?:un)?signed},
4671813087dSJoe Perches);
4681813087dSJoe Perches
4698905a67cSAndy Whitcroftour @typeList = (
4708905a67cSAndy Whitcroft	qr{void},
4710c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?char},
4720c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short\s+int},
4730c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short},
4740c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?int},
4750c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+int},
4760c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
4770c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long},
4780c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long},
4790c773d9dSJoe Perches	qr{(?:un)?signed},
4808905a67cSAndy Whitcroft	qr{float},
4818905a67cSAndy Whitcroft	qr{double},
4828905a67cSAndy Whitcroft	qr{bool},
4838905a67cSAndy Whitcroft	qr{struct\s+$Ident},
4848905a67cSAndy Whitcroft	qr{union\s+$Ident},
4858905a67cSAndy Whitcroft	qr{enum\s+$Ident},
4868905a67cSAndy Whitcroft	qr{${Ident}_t},
4878905a67cSAndy Whitcroft	qr{${Ident}_handler},
4888905a67cSAndy Whitcroft	qr{${Ident}_handler_fn},
4891813087dSJoe Perches	@typeListMisordered,
4908905a67cSAndy Whitcroft);
491938224b5SJoe Perches
492938224b5SJoe Perchesour $C90_int_types = qr{(?x:
493938224b5SJoe Perches	long\s+long\s+int\s+(?:un)?signed|
494938224b5SJoe Perches	long\s+long\s+(?:un)?signed\s+int|
495938224b5SJoe Perches	long\s+long\s+(?:un)?signed|
496938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long\s+int|
497938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long|
498938224b5SJoe Perches	int\s+long\s+long\s+(?:un)?signed|
499938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long\s+long|
500938224b5SJoe Perches
501938224b5SJoe Perches	long\s+int\s+(?:un)?signed|
502938224b5SJoe Perches	long\s+(?:un)?signed\s+int|
503938224b5SJoe Perches	long\s+(?:un)?signed|
504938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+int|
505938224b5SJoe Perches	(?:(?:un)?signed\s+)?long|
506938224b5SJoe Perches	int\s+long\s+(?:un)?signed|
507938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long|
508938224b5SJoe Perches
509938224b5SJoe Perches	int\s+(?:un)?signed|
510938224b5SJoe Perches	(?:(?:un)?signed\s+)?int
511938224b5SJoe Perches)};
512938224b5SJoe Perches
513485ff23eSAlex Dowadour @typeListFile = ();
5148716de38SJoe Perchesour @typeListWithAttr = (
5158716de38SJoe Perches	@typeList,
5168716de38SJoe Perches	qr{struct\s+$InitAttribute\s+$Ident},
5178716de38SJoe Perches	qr{union\s+$InitAttribute\s+$Ident},
5188716de38SJoe Perches);
5198716de38SJoe Perches
520c45dcabdSAndy Whitcroftour @modifierList = (
521c45dcabdSAndy Whitcroft	qr{fastcall},
522c45dcabdSAndy Whitcroft);
523485ff23eSAlex Dowadour @modifierListFile = ();
5248905a67cSAndy Whitcroft
5252435880fSJoe Perchesour @mode_permission_funcs = (
5262435880fSJoe Perches	["module_param", 3],
5272435880fSJoe Perches	["module_param_(?:array|named|string)", 4],
5282435880fSJoe Perches	["module_param_array_named", 5],
5292435880fSJoe Perches	["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
5302435880fSJoe Perches	["proc_create(?:_data|)", 2],
531459cf0aeSJoe Perches	["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
532459cf0aeSJoe Perches	["IIO_DEV_ATTR_[A-Z_]+", 1],
533459cf0aeSJoe Perches	["SENSOR_(?:DEVICE_|)ATTR_2", 2],
534459cf0aeSJoe Perches	["SENSOR_TEMPLATE(?:_2|)", 3],
535459cf0aeSJoe Perches	["__ATTR", 2],
5362435880fSJoe Perches);
5372435880fSJoe Perches
538515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below
539515a235eSJoe Perchesour $mode_perms_search = "";
540515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) {
541515a235eSJoe Perches	$mode_perms_search .= '|' if ($mode_perms_search ne "");
542515a235eSJoe Perches	$mode_perms_search .= $entry->[0];
543515a235eSJoe Perches}
544515a235eSJoe Perches
545b392c64fSJoe Perchesour $mode_perms_world_writable = qr{
546b392c64fSJoe Perches	S_IWUGO		|
547b392c64fSJoe Perches	S_IWOTH		|
548b392c64fSJoe Perches	S_IRWXUGO	|
549b392c64fSJoe Perches	S_IALLUGO	|
550b392c64fSJoe Perches	0[0-7][0-7][2367]
551b392c64fSJoe Perches}x;
552b392c64fSJoe Perches
553f90774e1SJoe Perchesour %mode_permission_string_types = (
554f90774e1SJoe Perches	"S_IRWXU" => 0700,
555f90774e1SJoe Perches	"S_IRUSR" => 0400,
556f90774e1SJoe Perches	"S_IWUSR" => 0200,
557f90774e1SJoe Perches	"S_IXUSR" => 0100,
558f90774e1SJoe Perches	"S_IRWXG" => 0070,
559f90774e1SJoe Perches	"S_IRGRP" => 0040,
560f90774e1SJoe Perches	"S_IWGRP" => 0020,
561f90774e1SJoe Perches	"S_IXGRP" => 0010,
562f90774e1SJoe Perches	"S_IRWXO" => 0007,
563f90774e1SJoe Perches	"S_IROTH" => 0004,
564f90774e1SJoe Perches	"S_IWOTH" => 0002,
565f90774e1SJoe Perches	"S_IXOTH" => 0001,
566f90774e1SJoe Perches	"S_IRWXUGO" => 0777,
567f90774e1SJoe Perches	"S_IRUGO" => 0444,
568f90774e1SJoe Perches	"S_IWUGO" => 0222,
569f90774e1SJoe Perches	"S_IXUGO" => 0111,
570f90774e1SJoe Perches);
571f90774e1SJoe Perches
572f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below
573f90774e1SJoe Perchesour $mode_perms_string_search = "";
574f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) {
575f90774e1SJoe Perches	$mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
576f90774e1SJoe Perches	$mode_perms_string_search .= $entry;
577f90774e1SJoe Perches}
578f90774e1SJoe Perches
5797840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x:
5807840a94cSWolfram Sang	irq|
581cdcee686SSergey Ryazanov	memory|
582cdcee686SSergey Ryazanov	time|
583cdcee686SSergey Ryazanov	reboot
5847840a94cSWolfram Sang)};
5857840a94cSWolfram Sang# memory.h: ARM has a custom one
5867840a94cSWolfram Sang
58766b47b4aSKees Cook# Load common spelling mistakes and build regular expression list.
58866b47b4aSKees Cookmy $misspellings;
58966b47b4aSKees Cookmy %spelling_fix;
59036061e38SJoe Perches
59136061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) {
59266b47b4aSKees Cook	while (<$spelling>) {
59366b47b4aSKees Cook		my $line = $_;
59466b47b4aSKees Cook
59566b47b4aSKees Cook		$line =~ s/\s*\n?$//g;
59666b47b4aSKees Cook		$line =~ s/^\s*//g;
59766b47b4aSKees Cook
59866b47b4aSKees Cook		next if ($line =~ m/^\s*#/);
59966b47b4aSKees Cook		next if ($line =~ m/^\s*$/);
60066b47b4aSKees Cook
60166b47b4aSKees Cook		my ($suspect, $fix) = split(/\|\|/, $line);
60266b47b4aSKees Cook
60366b47b4aSKees Cook		$spelling_fix{$suspect} = $fix;
60466b47b4aSKees Cook	}
60566b47b4aSKees Cook	close($spelling);
60636061e38SJoe Perches} else {
60736061e38SJoe Perches	warn "No typos will be found - file '$spelling_file': $!\n";
60836061e38SJoe Perches}
60966b47b4aSKees Cook
610ebfd7d62SJoe Perchesif ($codespell) {
611ebfd7d62SJoe Perches	if (open(my $spelling, '<', $codespellfile)) {
612ebfd7d62SJoe Perches		while (<$spelling>) {
613ebfd7d62SJoe Perches			my $line = $_;
614ebfd7d62SJoe Perches
615ebfd7d62SJoe Perches			$line =~ s/\s*\n?$//g;
616ebfd7d62SJoe Perches			$line =~ s/^\s*//g;
617ebfd7d62SJoe Perches
618ebfd7d62SJoe Perches			next if ($line =~ m/^\s*#/);
619ebfd7d62SJoe Perches			next if ($line =~ m/^\s*$/);
620ebfd7d62SJoe Perches			next if ($line =~ m/, disabled/i);
621ebfd7d62SJoe Perches
622ebfd7d62SJoe Perches			$line =~ s/,.*$//;
623ebfd7d62SJoe Perches
624ebfd7d62SJoe Perches			my ($suspect, $fix) = split(/->/, $line);
625ebfd7d62SJoe Perches
626ebfd7d62SJoe Perches			$spelling_fix{$suspect} = $fix;
627ebfd7d62SJoe Perches		}
628ebfd7d62SJoe Perches		close($spelling);
629ebfd7d62SJoe Perches	} else {
630ebfd7d62SJoe Perches		warn "No codespell typos will be found - file '$codespellfile': $!\n";
631ebfd7d62SJoe Perches	}
632ebfd7d62SJoe Perches}
633ebfd7d62SJoe Perches
634ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
635ebfd7d62SJoe Perches
63675ad8c57SJerome Forissiersub read_words {
63775ad8c57SJerome Forissier	my ($wordsRef, $file) = @_;
63875ad8c57SJerome Forissier
63975ad8c57SJerome Forissier	if (open(my $words, '<', $file)) {
64075ad8c57SJerome Forissier		while (<$words>) {
641bf1fa1daSJoe Perches			my $line = $_;
642bf1fa1daSJoe Perches
643bf1fa1daSJoe Perches			$line =~ s/\s*\n?$//g;
644bf1fa1daSJoe Perches			$line =~ s/^\s*//g;
645bf1fa1daSJoe Perches
646bf1fa1daSJoe Perches			next if ($line =~ m/^\s*#/);
647bf1fa1daSJoe Perches			next if ($line =~ m/^\s*$/);
648bf1fa1daSJoe Perches			if ($line =~ /\s/) {
64975ad8c57SJerome Forissier				print("$file: '$line' invalid - ignored\n");
650bf1fa1daSJoe Perches				next;
651bf1fa1daSJoe Perches			}
652bf1fa1daSJoe Perches
65375ad8c57SJerome Forissier			$$wordsRef .= '|' if ($$wordsRef ne "");
65475ad8c57SJerome Forissier			$$wordsRef .= $line;
655bf1fa1daSJoe Perches		}
65675ad8c57SJerome Forissier		close($file);
65775ad8c57SJerome Forissier		return 1;
658bf1fa1daSJoe Perches	}
659bf1fa1daSJoe Perches
66075ad8c57SJerome Forissier	return 0;
66175ad8c57SJerome Forissier}
66275ad8c57SJerome Forissier
66375ad8c57SJerome Forissiermy $const_structs = "";
66475ad8c57SJerome Forissierread_words(\$const_structs, $conststructsfile)
66575ad8c57SJerome Forissier    or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
66675ad8c57SJerome Forissier
66775ad8c57SJerome Forissiermy $typeOtherTypedefs = "";
66875ad8c57SJerome Forissierif (length($typedefsfile)) {
66975ad8c57SJerome Forissier	read_words(\$typeOtherTypedefs, $typedefsfile)
67075ad8c57SJerome Forissier	    or warn "No additional types will be considered - file '$typedefsfile': $!\n";
67175ad8c57SJerome Forissier}
67275ad8c57SJerome Forissier$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne "");
67375ad8c57SJerome Forissier
6748905a67cSAndy Whitcroftsub build_types {
675485ff23eSAlex Dowad	my $mods = "(?x:  \n" . join("|\n  ", (@modifierList, @modifierListFile)) . "\n)";
676485ff23eSAlex Dowad	my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile)) . "\n)";
6771813087dSJoe Perches	my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered) . "\n)";
6788716de38SJoe Perches	my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr) . "\n)";
679c8cb2ca3SAndy Whitcroft	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};
680ab7e23f3SJoe Perches	$BasicType	= qr{
681ab7e23f3SJoe Perches				(?:$typeTypedefs\b)|
682ab7e23f3SJoe Perches				(?:${all}\b)
683ab7e23f3SJoe Perches		}x;
6848905a67cSAndy Whitcroft	$NonptrType	= qr{
685d2172eb5SAndy Whitcroft			(?:$Modifier\s+|const\s+)*
686cf655043SAndy Whitcroft			(?:
6876b48db24SAndy Whitcroft				(?:typeof|__typeof__)\s*\([^\)]*\)|
6888ed22cadSAndy Whitcroft				(?:$typeTypedefs\b)|
689c45dcabdSAndy Whitcroft				(?:${all}\b)
690cf655043SAndy Whitcroft			)
691c8cb2ca3SAndy Whitcroft			(?:\s+$Modifier|\s+const)*
6928905a67cSAndy Whitcroft		  }x;
6931813087dSJoe Perches	$NonptrTypeMisordered	= qr{
6941813087dSJoe Perches			(?:$Modifier\s+|const\s+)*
6951813087dSJoe Perches			(?:
6961813087dSJoe Perches				(?:${Misordered}\b)
6971813087dSJoe Perches			)
6981813087dSJoe Perches			(?:\s+$Modifier|\s+const)*
6991813087dSJoe Perches		  }x;
7008716de38SJoe Perches	$NonptrTypeWithAttr	= qr{
7018716de38SJoe Perches			(?:$Modifier\s+|const\s+)*
7028716de38SJoe Perches			(?:
7038716de38SJoe Perches				(?:typeof|__typeof__)\s*\([^\)]*\)|
7048716de38SJoe Perches				(?:$typeTypedefs\b)|
7058716de38SJoe Perches				(?:${allWithAttr}\b)
7068716de38SJoe Perches			)
7078716de38SJoe Perches			(?:\s+$Modifier|\s+const)*
7088716de38SJoe Perches		  }x;
7098905a67cSAndy Whitcroft	$Type	= qr{
710c45dcabdSAndy Whitcroft			$NonptrType
7111574a29fSJoe Perches			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
712c8cb2ca3SAndy Whitcroft			(?:\s+$Inline|\s+$Modifier)*
7138905a67cSAndy Whitcroft		  }x;
7141813087dSJoe Perches	$TypeMisordered	= qr{
7151813087dSJoe Perches			$NonptrTypeMisordered
7161813087dSJoe Perches			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
7171813087dSJoe Perches			(?:\s+$Inline|\s+$Modifier)*
7181813087dSJoe Perches		  }x;
71991cb5195SJoe Perches	$Declare	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
7201813087dSJoe Perches	$DeclareMisordered	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
7218905a67cSAndy Whitcroft}
7228905a67cSAndy Whitcroftbuild_types();
7236c72ffaaSAndy Whitcroft
7247d2367afSJoe Perchesour $Typecast	= qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
725d1fe9c09SJoe Perches
726d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg
727d1fe9c09SJoe Perches# requires at least perl version v5.10.0
728d1fe9c09SJoe Perches# Any use must be runtime checked with $^V
729d1fe9c09SJoe Perches
730d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
7312435880fSJoe Perchesour $LvalOrFunc	= qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
732c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
7337d2367afSJoe Perches
734f8422308SJoe Perchesour $declaration_macros = qr{(?x:
7353e838b6cSJoe Perches	(?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
736fe658f94SSteffen Maier	(?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
737f8422308SJoe Perches	(?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(
738f8422308SJoe Perches)};
739f8422308SJoe Perches
7407d2367afSJoe Perchessub deparenthesize {
7417d2367afSJoe Perches	my ($string) = @_;
7427d2367afSJoe Perches	return "" if (!defined($string));
7435b9553abSJoe Perches
7445b9553abSJoe Perches	while ($string =~ /^\s*\(.*\)\s*$/) {
7455b9553abSJoe Perches		$string =~ s@^\s*\(\s*@@;
7465b9553abSJoe Perches		$string =~ s@\s*\)\s*$@@;
7475b9553abSJoe Perches	}
7485b9553abSJoe Perches
7497d2367afSJoe Perches	$string =~ s@\s+@ @g;
7505b9553abSJoe Perches
7517d2367afSJoe Perches	return $string;
7527d2367afSJoe Perches}
7537d2367afSJoe Perches
7543445686aSJoe Perchessub seed_camelcase_file {
7553445686aSJoe Perches	my ($file) = @_;
7563445686aSJoe Perches
7573445686aSJoe Perches	return if (!(-f $file));
7583445686aSJoe Perches
7593445686aSJoe Perches	local $/;
7603445686aSJoe Perches
7613445686aSJoe Perches	open(my $include_file, '<', "$file")
7623445686aSJoe Perches	    or warn "$P: Can't read '$file' $!\n";
7633445686aSJoe Perches	my $text = <$include_file>;
7643445686aSJoe Perches	close($include_file);
7653445686aSJoe Perches
7663445686aSJoe Perches	my @lines = split('\n', $text);
7673445686aSJoe Perches
7683445686aSJoe Perches	foreach my $line (@lines) {
7693445686aSJoe Perches		next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
7703445686aSJoe Perches		if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
7713445686aSJoe Perches			$camelcase{$1} = 1;
77211ea516aSJoe Perches		} elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
77311ea516aSJoe Perches			$camelcase{$1} = 1;
77411ea516aSJoe Perches		} elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
7753445686aSJoe Perches			$camelcase{$1} = 1;
7763445686aSJoe Perches		}
7773445686aSJoe Perches	}
7783445686aSJoe Perches}
7793445686aSJoe Perches
78085b0ee18SJoe Perchessub is_maintained_obsolete {
78185b0ee18SJoe Perches	my ($filename) = @_;
78285b0ee18SJoe Perches
783f2c19c2fSJerome Forissier	return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
78485b0ee18SJoe Perches
7850616efa4SJoe Perches	my $status = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
78685b0ee18SJoe Perches
78785b0ee18SJoe Perches	return $status =~ /obsolete/i;
78885b0ee18SJoe Perches}
78985b0ee18SJoe Perches
7903445686aSJoe Perchesmy $camelcase_seeded = 0;
7913445686aSJoe Perchessub seed_camelcase_includes {
7923445686aSJoe Perches	return if ($camelcase_seeded);
7933445686aSJoe Perches
7943445686aSJoe Perches	my $files;
795c707a81dSJoe Perches	my $camelcase_cache = "";
796c707a81dSJoe Perches	my @include_files = ();
797c707a81dSJoe Perches
798c707a81dSJoe Perches	$camelcase_seeded = 1;
799351b2a1fSJoe Perches
8003645e328SRichard Genoud	if (-e ".git") {
801351b2a1fSJoe Perches		my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`;
802351b2a1fSJoe Perches		chomp $git_last_include_commit;
803c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
804c707a81dSJoe Perches	} else {
805c707a81dSJoe Perches		my $last_mod_date = 0;
806c707a81dSJoe Perches		$files = `find $root/include -name "*.h"`;
807c707a81dSJoe Perches		@include_files = split('\n', $files);
808c707a81dSJoe Perches		foreach my $file (@include_files) {
809c707a81dSJoe Perches			my $date = POSIX::strftime("%Y%m%d%H%M",
810c707a81dSJoe Perches						   localtime((stat $file)[9]));
811c707a81dSJoe Perches			$last_mod_date = $date if ($last_mod_date < $date);
812c707a81dSJoe Perches		}
813c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
814c707a81dSJoe Perches	}
815c707a81dSJoe Perches
816c707a81dSJoe Perches	if ($camelcase_cache ne "" && -f $camelcase_cache) {
817c707a81dSJoe Perches		open(my $camelcase_file, '<', "$camelcase_cache")
818c707a81dSJoe Perches		    or warn "$P: Can't read '$camelcase_cache' $!\n";
819351b2a1fSJoe Perches		while (<$camelcase_file>) {
820351b2a1fSJoe Perches			chomp;
821351b2a1fSJoe Perches			$camelcase{$_} = 1;
822351b2a1fSJoe Perches		}
823351b2a1fSJoe Perches		close($camelcase_file);
824351b2a1fSJoe Perches
825351b2a1fSJoe Perches		return;
826351b2a1fSJoe Perches	}
827c707a81dSJoe Perches
8283645e328SRichard Genoud	if (-e ".git") {
829c707a81dSJoe Perches		$files = `git ls-files "include/*.h"`;
830c707a81dSJoe Perches		@include_files = split('\n', $files);
8313445686aSJoe Perches	}
832c707a81dSJoe Perches
8333445686aSJoe Perches	foreach my $file (@include_files) {
8343445686aSJoe Perches		seed_camelcase_file($file);
8353445686aSJoe Perches	}
836351b2a1fSJoe Perches
837c707a81dSJoe Perches	if ($camelcase_cache ne "") {
838351b2a1fSJoe Perches		unlink glob ".checkpatch-camelcase.*";
839c707a81dSJoe Perches		open(my $camelcase_file, '>', "$camelcase_cache")
840c707a81dSJoe Perches		    or warn "$P: Can't write '$camelcase_cache' $!\n";
841351b2a1fSJoe Perches		foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
842351b2a1fSJoe Perches			print $camelcase_file ("$_\n");
843351b2a1fSJoe Perches		}
844351b2a1fSJoe Perches		close($camelcase_file);
845351b2a1fSJoe Perches	}
8463445686aSJoe Perches}
8473445686aSJoe Perches
848d311cd44SJoe Perchessub git_commit_info {
849d311cd44SJoe Perches	my ($commit, $id, $desc) = @_;
850d311cd44SJoe Perches
851d311cd44SJoe Perches	return ($id, $desc) if ((which("git") eq "") || !(-e ".git"));
852d311cd44SJoe Perches
853d311cd44SJoe Perches	my $output = `git log --no-color --format='%H %s' -1 $commit 2>&1`;
854d311cd44SJoe Perches	$output =~ s/^\s*//gm;
855d311cd44SJoe Perches	my @lines = split("\n", $output);
856d311cd44SJoe Perches
8570d7835fcSJoe Perches	return ($id, $desc) if ($#lines < 0);
8580d7835fcSJoe Perches
859d311cd44SJoe Perches	if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous\./) {
860d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns
861d311cd44SJoe Perches# all matching commit ids, but it's very slow...
862d311cd44SJoe Perches#
863d311cd44SJoe Perches#		echo "checking commits $1..."
864d311cd44SJoe Perches#		git rev-list --remotes | grep -i "^$1" |
865d311cd44SJoe Perches#		while read line ; do
866d311cd44SJoe Perches#		    git log --format='%H %s' -1 $line |
867d311cd44SJoe Perches#		    echo "commit $(cut -c 1-12,41-)"
868d311cd44SJoe Perches#		done
869d311cd44SJoe Perches	} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) {
870948b133aSHeinrich Schuchardt		$id = undef;
871d311cd44SJoe Perches	} else {
872d311cd44SJoe Perches		$id = substr($lines[0], 0, 12);
873d311cd44SJoe Perches		$desc = substr($lines[0], 41);
874d311cd44SJoe Perches	}
875d311cd44SJoe Perches
876d311cd44SJoe Perches	return ($id, $desc);
877d311cd44SJoe Perches}
878d311cd44SJoe Perches
8796c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file);
8800a920b5bSAndy Whitcroft
88100df344fSAndy Whitcroftmy @rawlines = ();
882c2fdda0dSAndy Whitcroftmy @lines = ();
8833705ce5bSJoe Perchesmy @fixed = ();
884d752fcc8SJoe Perchesmy @fixed_inserted = ();
885d752fcc8SJoe Perchesmy @fixed_deleted = ();
886194f66fcSJoe Perchesmy $fixlinenr = -1;
887194f66fcSJoe Perches
8884a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions.
8894a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
8904a593c34SDu, Changbindie "$P: No git repository found\n" if ($git && !-e ".git");
8914a593c34SDu, Changbin
8924a593c34SDu, Changbinif ($git) {
8934a593c34SDu, Changbin	my @commits = ();
8940dea9f1eSJoe Perches	foreach my $commit_expr (@ARGV) {
8954a593c34SDu, Changbin		my $git_range;
89628898fd1SJoe Perches		if ($commit_expr =~ m/^(.*)-(\d+)$/) {
89728898fd1SJoe Perches			$git_range = "-$2 $1";
8984a593c34SDu, Changbin		} elsif ($commit_expr =~ m/\.\./) {
8994a593c34SDu, Changbin			$git_range = "$commit_expr";
9004a593c34SDu, Changbin		} else {
9010dea9f1eSJoe Perches			$git_range = "-1 $commit_expr";
9020dea9f1eSJoe Perches		}
9030dea9f1eSJoe Perches		my $lines = `git log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
9040dea9f1eSJoe Perches		foreach my $line (split(/\n/, $lines)) {
90528898fd1SJoe Perches			$line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
90628898fd1SJoe Perches			next if (!defined($1) || !defined($2));
9070dea9f1eSJoe Perches			my $sha1 = $1;
9080dea9f1eSJoe Perches			my $subject = $2;
9090dea9f1eSJoe Perches			unshift(@commits, $sha1);
9100dea9f1eSJoe Perches			$git_commits{$sha1} = $subject;
9114a593c34SDu, Changbin		}
9124a593c34SDu, Changbin	}
9134a593c34SDu, Changbin	die "$P: no git commits after extraction!\n" if (@commits == 0);
9144a593c34SDu, Changbin	@ARGV = @commits;
9154a593c34SDu, Changbin}
9164a593c34SDu, Changbin
917c2fdda0dSAndy Whitcroftmy $vname;
9186c72ffaaSAndy Whitcroftfor my $filename (@ARGV) {
91921caa13cSAndy Whitcroft	my $FILE;
9204a593c34SDu, Changbin	if ($git) {
9214a593c34SDu, Changbin		open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
9224a593c34SDu, Changbin			die "$P: $filename: git format-patch failed - $!\n";
9234a593c34SDu, Changbin	} elsif ($file) {
92421caa13cSAndy Whitcroft		open($FILE, '-|', "diff -u /dev/null $filename") ||
9256c72ffaaSAndy Whitcroft			die "$P: $filename: diff failed - $!\n";
92621caa13cSAndy Whitcroft	} elsif ($filename eq '-') {
92721caa13cSAndy Whitcroft		open($FILE, '<&STDIN');
9286c72ffaaSAndy Whitcroft	} else {
92921caa13cSAndy Whitcroft		open($FILE, '<', "$filename") ||
9306c72ffaaSAndy Whitcroft			die "$P: $filename: open failed - $!\n";
9316c72ffaaSAndy Whitcroft	}
932c2fdda0dSAndy Whitcroft	if ($filename eq '-') {
933c2fdda0dSAndy Whitcroft		$vname = 'Your patch';
9344a593c34SDu, Changbin	} elsif ($git) {
9350dea9f1eSJoe Perches		$vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
936c2fdda0dSAndy Whitcroft	} else {
937c2fdda0dSAndy Whitcroft		$vname = $filename;
938c2fdda0dSAndy Whitcroft	}
93921caa13cSAndy Whitcroft	while (<$FILE>) {
9400a920b5bSAndy Whitcroft		chomp;
94100df344fSAndy Whitcroft		push(@rawlines, $_);
9426c72ffaaSAndy Whitcroft	}
94321caa13cSAndy Whitcroft	close($FILE);
944d8469f16SJoe Perches
945d8469f16SJoe Perches	if ($#ARGV > 0 && $quiet == 0) {
946d8469f16SJoe Perches		print '-' x length($vname) . "\n";
947d8469f16SJoe Perches		print "$vname\n";
948d8469f16SJoe Perches		print '-' x length($vname) . "\n";
949d8469f16SJoe Perches	}
950d8469f16SJoe Perches
951c2fdda0dSAndy Whitcroft	if (!process($filename)) {
9520a920b5bSAndy Whitcroft		$exit = 1;
9530a920b5bSAndy Whitcroft	}
95400df344fSAndy Whitcroft	@rawlines = ();
95513214adfSAndy Whitcroft	@lines = ();
9563705ce5bSJoe Perches	@fixed = ();
957d752fcc8SJoe Perches	@fixed_inserted = ();
958d752fcc8SJoe Perches	@fixed_deleted = ();
959194f66fcSJoe Perches	$fixlinenr = -1;
960485ff23eSAlex Dowad	@modifierListFile = ();
961485ff23eSAlex Dowad	@typeListFile = ();
962485ff23eSAlex Dowad	build_types();
9630a920b5bSAndy Whitcroft}
9640a920b5bSAndy Whitcroft
965d8469f16SJoe Perchesif (!$quiet) {
9663c816e49SJoe Perches	hash_show_words(\%use_type, "Used");
9673c816e49SJoe Perches	hash_show_words(\%ignore_type, "Ignored");
9683c816e49SJoe Perches
969d8469f16SJoe Perches	if ($^V lt 5.10.0) {
970d8469f16SJoe Perches		print << "EOM"
971d8469f16SJoe Perches
972d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues.
973d8469f16SJoe Perches      An upgrade to at least perl v5.10.0 is suggested.
974d8469f16SJoe PerchesEOM
975d8469f16SJoe Perches	}
976d8469f16SJoe Perches	if ($exit) {
977d8469f16SJoe Perches		print << "EOM"
978d8469f16SJoe Perches
979d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report
980d8469f16SJoe Perches      them to the maintainer, see CHECKPATCH in MAINTAINERS.
981d8469f16SJoe PerchesEOM
982d8469f16SJoe Perches	}
983d8469f16SJoe Perches}
984d8469f16SJoe Perches
9850a920b5bSAndy Whitcroftexit($exit);
9860a920b5bSAndy Whitcroft
9870a920b5bSAndy Whitcroftsub top_of_kernel_tree {
9886c72ffaaSAndy Whitcroft	my ($root) = @_;
9896c72ffaaSAndy Whitcroft
9906c72ffaaSAndy Whitcroft	my @tree_check = (
9916c72ffaaSAndy Whitcroft		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
9926c72ffaaSAndy Whitcroft		"README", "Documentation", "arch", "include", "drivers",
9936c72ffaaSAndy Whitcroft		"fs", "init", "ipc", "kernel", "lib", "scripts",
9946c72ffaaSAndy Whitcroft	);
9956c72ffaaSAndy Whitcroft
9966c72ffaaSAndy Whitcroft	foreach my $check (@tree_check) {
9976c72ffaaSAndy Whitcroft		if (! -e $root . '/' . $check) {
9980a920b5bSAndy Whitcroft			return 0;
9990a920b5bSAndy Whitcroft		}
10006c72ffaaSAndy Whitcroft	}
10016c72ffaaSAndy Whitcroft	return 1;
10026c72ffaaSAndy Whitcroft}
10030a920b5bSAndy Whitcroft
100420112475SJoe Perchessub parse_email {
100520112475SJoe Perches	my ($formatted_email) = @_;
100620112475SJoe Perches
100720112475SJoe Perches	my $name = "";
100820112475SJoe Perches	my $address = "";
100920112475SJoe Perches	my $comment = "";
101020112475SJoe Perches
101120112475SJoe Perches	if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
101220112475SJoe Perches		$name = $1;
101320112475SJoe Perches		$address = $2;
101420112475SJoe Perches		$comment = $3 if defined $3;
101520112475SJoe Perches	} elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
101620112475SJoe Perches		$address = $1;
101720112475SJoe Perches		$comment = $2 if defined $2;
101820112475SJoe Perches	} elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
101920112475SJoe Perches		$address = $1;
102020112475SJoe Perches		$comment = $2 if defined $2;
102120112475SJoe Perches		$formatted_email =~ s/$address.*$//;
102220112475SJoe Perches		$name = $formatted_email;
10233705ce5bSJoe Perches		$name = trim($name);
102420112475SJoe Perches		$name =~ s/^\"|\"$//g;
102520112475SJoe Perches		# If there's a name left after stripping spaces and
102620112475SJoe Perches		# leading quotes, and the address doesn't have both
102720112475SJoe Perches		# leading and trailing angle brackets, the address
102820112475SJoe Perches		# is invalid. ie:
102920112475SJoe Perches		#   "joe smith [email protected]" bad
103020112475SJoe Perches		#   "joe smith <[email protected]" bad
103120112475SJoe Perches		if ($name ne "" && $address !~ /^<[^>]+>$/) {
103220112475SJoe Perches			$name = "";
103320112475SJoe Perches			$address = "";
103420112475SJoe Perches			$comment = "";
103520112475SJoe Perches		}
103620112475SJoe Perches	}
103720112475SJoe Perches
10383705ce5bSJoe Perches	$name = trim($name);
103920112475SJoe Perches	$name =~ s/^\"|\"$//g;
10403705ce5bSJoe Perches	$address = trim($address);
104120112475SJoe Perches	$address =~ s/^\<|\>$//g;
104220112475SJoe Perches
104320112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
104420112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
104520112475SJoe Perches		$name = "\"$name\"";
104620112475SJoe Perches	}
104720112475SJoe Perches
104820112475SJoe Perches	return ($name, $address, $comment);
104920112475SJoe Perches}
105020112475SJoe Perches
105120112475SJoe Perchessub format_email {
105220112475SJoe Perches	my ($name, $address) = @_;
105320112475SJoe Perches
105420112475SJoe Perches	my $formatted_email;
105520112475SJoe Perches
10563705ce5bSJoe Perches	$name = trim($name);
105720112475SJoe Perches	$name =~ s/^\"|\"$//g;
10583705ce5bSJoe Perches	$address = trim($address);
105920112475SJoe Perches
106020112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
106120112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
106220112475SJoe Perches		$name = "\"$name\"";
106320112475SJoe Perches	}
106420112475SJoe Perches
106520112475SJoe Perches	if ("$name" eq "") {
106620112475SJoe Perches		$formatted_email = "$address";
106720112475SJoe Perches	} else {
106820112475SJoe Perches		$formatted_email = "$name <$address>";
106920112475SJoe Perches	}
107020112475SJoe Perches
107120112475SJoe Perches	return $formatted_email;
107220112475SJoe Perches}
107320112475SJoe Perches
1074d311cd44SJoe Perchessub which {
1075d311cd44SJoe Perches	my ($bin) = @_;
1076d311cd44SJoe Perches
1077d311cd44SJoe Perches	foreach my $path (split(/:/, $ENV{PATH})) {
1078d311cd44SJoe Perches		if (-e "$path/$bin") {
1079d311cd44SJoe Perches			return "$path/$bin";
1080d311cd44SJoe Perches		}
1081d311cd44SJoe Perches	}
1082d311cd44SJoe Perches
1083d311cd44SJoe Perches	return "";
1084d311cd44SJoe Perches}
1085d311cd44SJoe Perches
1086000d1cc1SJoe Perchessub which_conf {
1087000d1cc1SJoe Perches	my ($conf) = @_;
1088000d1cc1SJoe Perches
1089000d1cc1SJoe Perches	foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
1090000d1cc1SJoe Perches		if (-e "$path/$conf") {
1091000d1cc1SJoe Perches			return "$path/$conf";
1092000d1cc1SJoe Perches		}
1093000d1cc1SJoe Perches	}
1094000d1cc1SJoe Perches
1095000d1cc1SJoe Perches	return "";
1096000d1cc1SJoe Perches}
1097000d1cc1SJoe Perches
10980a920b5bSAndy Whitcroftsub expand_tabs {
10990a920b5bSAndy Whitcroft	my ($str) = @_;
11000a920b5bSAndy Whitcroft
11010a920b5bSAndy Whitcroft	my $res = '';
11020a920b5bSAndy Whitcroft	my $n = 0;
11030a920b5bSAndy Whitcroft	for my $c (split(//, $str)) {
11040a920b5bSAndy Whitcroft		if ($c eq "\t") {
11050a920b5bSAndy Whitcroft			$res .= ' ';
11060a920b5bSAndy Whitcroft			$n++;
11070a920b5bSAndy Whitcroft			for (; ($n % 8) != 0; $n++) {
11080a920b5bSAndy Whitcroft				$res .= ' ';
11090a920b5bSAndy Whitcroft			}
11100a920b5bSAndy Whitcroft			next;
11110a920b5bSAndy Whitcroft		}
11120a920b5bSAndy Whitcroft		$res .= $c;
11130a920b5bSAndy Whitcroft		$n++;
11140a920b5bSAndy Whitcroft	}
11150a920b5bSAndy Whitcroft
11160a920b5bSAndy Whitcroft	return $res;
11170a920b5bSAndy Whitcroft}
11186c72ffaaSAndy Whitcroftsub copy_spacing {
1119773647a0SAndy Whitcroft	(my $res = shift) =~ tr/\t/ /c;
11206c72ffaaSAndy Whitcroft	return $res;
11216c72ffaaSAndy Whitcroft}
11220a920b5bSAndy Whitcroft
11234a0df2efSAndy Whitcroftsub line_stats {
11244a0df2efSAndy Whitcroft	my ($line) = @_;
11254a0df2efSAndy Whitcroft
11264a0df2efSAndy Whitcroft	# Drop the diff line leader and expand tabs
11274a0df2efSAndy Whitcroft	$line =~ s/^.//;
11284a0df2efSAndy Whitcroft	$line = expand_tabs($line);
11294a0df2efSAndy Whitcroft
11304a0df2efSAndy Whitcroft	# Pick the indent from the front of the line.
11314a0df2efSAndy Whitcroft	my ($white) = ($line =~ /^(\s*)/);
11324a0df2efSAndy Whitcroft
11334a0df2efSAndy Whitcroft	return (length($line), length($white));
11344a0df2efSAndy Whitcroft}
11354a0df2efSAndy Whitcroft
1136773647a0SAndy Whitcroftmy $sanitise_quote = '';
1137773647a0SAndy Whitcroft
1138773647a0SAndy Whitcroftsub sanitise_line_reset {
1139773647a0SAndy Whitcroft	my ($in_comment) = @_;
1140773647a0SAndy Whitcroft
1141773647a0SAndy Whitcroft	if ($in_comment) {
1142773647a0SAndy Whitcroft		$sanitise_quote = '*/';
1143773647a0SAndy Whitcroft	} else {
1144773647a0SAndy Whitcroft		$sanitise_quote = '';
1145773647a0SAndy Whitcroft	}
1146773647a0SAndy Whitcroft}
114700df344fSAndy Whitcroftsub sanitise_line {
114800df344fSAndy Whitcroft	my ($line) = @_;
114900df344fSAndy Whitcroft
115000df344fSAndy Whitcroft	my $res = '';
115100df344fSAndy Whitcroft	my $l = '';
115200df344fSAndy Whitcroft
1153c2fdda0dSAndy Whitcroft	my $qlen = 0;
1154773647a0SAndy Whitcroft	my $off = 0;
1155773647a0SAndy Whitcroft	my $c;
115600df344fSAndy Whitcroft
1157773647a0SAndy Whitcroft	# Always copy over the diff marker.
1158773647a0SAndy Whitcroft	$res = substr($line, 0, 1);
1159773647a0SAndy Whitcroft
1160773647a0SAndy Whitcroft	for ($off = 1; $off < length($line); $off++) {
1161773647a0SAndy Whitcroft		$c = substr($line, $off, 1);
1162773647a0SAndy Whitcroft
1163773647a0SAndy Whitcroft		# Comments we are wacking completly including the begin
1164773647a0SAndy Whitcroft		# and end, all to $;.
1165773647a0SAndy Whitcroft		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
1166773647a0SAndy Whitcroft			$sanitise_quote = '*/';
1167773647a0SAndy Whitcroft
1168773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1169773647a0SAndy Whitcroft			$off++;
117000df344fSAndy Whitcroft			next;
1171773647a0SAndy Whitcroft		}
117281bc0e02SAndy Whitcroft		if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
1173773647a0SAndy Whitcroft			$sanitise_quote = '';
1174773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1175773647a0SAndy Whitcroft			$off++;
1176773647a0SAndy Whitcroft			next;
1177773647a0SAndy Whitcroft		}
1178113f04a8SDaniel Walker		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
1179113f04a8SDaniel Walker			$sanitise_quote = '//';
1180113f04a8SDaniel Walker
1181113f04a8SDaniel Walker			substr($res, $off, 2, $sanitise_quote);
1182113f04a8SDaniel Walker			$off++;
1183113f04a8SDaniel Walker			next;
1184113f04a8SDaniel Walker		}
1185773647a0SAndy Whitcroft
1186773647a0SAndy Whitcroft		# A \ in a string means ignore the next character.
1187773647a0SAndy Whitcroft		if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
1188773647a0SAndy Whitcroft		    $c eq "\\") {
1189773647a0SAndy Whitcroft			substr($res, $off, 2, 'XX');
1190773647a0SAndy Whitcroft			$off++;
1191773647a0SAndy Whitcroft			next;
1192773647a0SAndy Whitcroft		}
1193773647a0SAndy Whitcroft		# Regular quotes.
1194773647a0SAndy Whitcroft		if ($c eq "'" || $c eq '"') {
1195773647a0SAndy Whitcroft			if ($sanitise_quote eq '') {
1196773647a0SAndy Whitcroft				$sanitise_quote = $c;
1197773647a0SAndy Whitcroft
1198773647a0SAndy Whitcroft				substr($res, $off, 1, $c);
1199773647a0SAndy Whitcroft				next;
1200773647a0SAndy Whitcroft			} elsif ($sanitise_quote eq $c) {
1201773647a0SAndy Whitcroft				$sanitise_quote = '';
120200df344fSAndy Whitcroft			}
120300df344fSAndy Whitcroft		}
1204773647a0SAndy Whitcroft
1205fae17daeSAndy Whitcroft		#print "c<$c> SQ<$sanitise_quote>\n";
1206773647a0SAndy Whitcroft		if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
1207773647a0SAndy Whitcroft			substr($res, $off, 1, $;);
1208113f04a8SDaniel Walker		} elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
1209113f04a8SDaniel Walker			substr($res, $off, 1, $;);
1210773647a0SAndy Whitcroft		} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
1211773647a0SAndy Whitcroft			substr($res, $off, 1, 'X');
121200df344fSAndy Whitcroft		} else {
1213773647a0SAndy Whitcroft			substr($res, $off, 1, $c);
121400df344fSAndy Whitcroft		}
1215c2fdda0dSAndy Whitcroft	}
1216c2fdda0dSAndy Whitcroft
1217113f04a8SDaniel Walker	if ($sanitise_quote eq '//') {
1218113f04a8SDaniel Walker		$sanitise_quote = '';
1219113f04a8SDaniel Walker	}
1220113f04a8SDaniel Walker
1221c2fdda0dSAndy Whitcroft	# The pathname on a #include may be surrounded by '<' and '>'.
1222c45dcabdSAndy Whitcroft	if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
1223c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1224c2fdda0dSAndy Whitcroft		$res =~ s@\<.*\>@<$clean>@;
1225c2fdda0dSAndy Whitcroft
1226c2fdda0dSAndy Whitcroft	# The whole of a #error is a string.
1227c45dcabdSAndy Whitcroft	} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
1228c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1229c45dcabdSAndy Whitcroft		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
1230c2fdda0dSAndy Whitcroft	}
1231c2fdda0dSAndy Whitcroft
1232dadf680dSJoe Perches	if ($allow_c99_comments && $res =~ m@(//.*$)@) {
1233dadf680dSJoe Perches		my $match = $1;
1234dadf680dSJoe Perches		$res =~ s/\Q$match\E/"$;" x length($match)/e;
1235dadf680dSJoe Perches	}
1236dadf680dSJoe Perches
123700df344fSAndy Whitcroft	return $res;
123800df344fSAndy Whitcroft}
123900df344fSAndy Whitcroft
1240a6962d72SJoe Perchessub get_quoted_string {
1241a6962d72SJoe Perches	my ($line, $rawline) = @_;
1242a6962d72SJoe Perches
124333acb54aSJoe Perches	return "" if ($line !~ m/($String)/g);
1244a6962d72SJoe Perches	return substr($rawline, $-[0], $+[0] - $-[0]);
1245a6962d72SJoe Perches}
1246a6962d72SJoe Perches
12478905a67cSAndy Whitcroftsub ctx_statement_block {
12488905a67cSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
12498905a67cSAndy Whitcroft	my $line = $linenr - 1;
12508905a67cSAndy Whitcroft	my $blk = '';
12518905a67cSAndy Whitcroft	my $soff = $off;
12528905a67cSAndy Whitcroft	my $coff = $off - 1;
1253773647a0SAndy Whitcroft	my $coff_set = 0;
12548905a67cSAndy Whitcroft
125513214adfSAndy Whitcroft	my $loff = 0;
125613214adfSAndy Whitcroft
12578905a67cSAndy Whitcroft	my $type = '';
12588905a67cSAndy Whitcroft	my $level = 0;
1259a2750645SAndy Whitcroft	my @stack = ();
1260cf655043SAndy Whitcroft	my $p;
12618905a67cSAndy Whitcroft	my $c;
12628905a67cSAndy Whitcroft	my $len = 0;
126313214adfSAndy Whitcroft
126413214adfSAndy Whitcroft	my $remainder;
12658905a67cSAndy Whitcroft	while (1) {
1266a2750645SAndy Whitcroft		@stack = (['', 0]) if ($#stack == -1);
1267a2750645SAndy Whitcroft
1268773647a0SAndy Whitcroft		#warn "CSB: blk<$blk> remain<$remain>\n";
12698905a67cSAndy Whitcroft		# If we are about to drop off the end, pull in more
12708905a67cSAndy Whitcroft		# context.
12718905a67cSAndy Whitcroft		if ($off >= $len) {
12728905a67cSAndy Whitcroft			for (; $remain > 0; $line++) {
1273dea33496SAndy Whitcroft				last if (!defined $lines[$line]);
1274c2fdda0dSAndy Whitcroft				next if ($lines[$line] =~ /^-/);
12758905a67cSAndy Whitcroft				$remain--;
127613214adfSAndy Whitcroft				$loff = $len;
1277c2fdda0dSAndy Whitcroft				$blk .= $lines[$line] . "\n";
12788905a67cSAndy Whitcroft				$len = length($blk);
12798905a67cSAndy Whitcroft				$line++;
12808905a67cSAndy Whitcroft				last;
12818905a67cSAndy Whitcroft			}
12828905a67cSAndy Whitcroft			# Bail if there is no further context.
12838905a67cSAndy Whitcroft			#warn "CSB: blk<$blk> off<$off> len<$len>\n";
128413214adfSAndy Whitcroft			if ($off >= $len) {
12858905a67cSAndy Whitcroft				last;
12868905a67cSAndy Whitcroft			}
1287f74bd194SAndy Whitcroft			if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
1288f74bd194SAndy Whitcroft				$level++;
1289f74bd194SAndy Whitcroft				$type = '#';
1290f74bd194SAndy Whitcroft			}
12918905a67cSAndy Whitcroft		}
1292cf655043SAndy Whitcroft		$p = $c;
12938905a67cSAndy Whitcroft		$c = substr($blk, $off, 1);
129413214adfSAndy Whitcroft		$remainder = substr($blk, $off);
12958905a67cSAndy Whitcroft
1296773647a0SAndy Whitcroft		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
12974635f4fbSAndy Whitcroft
12984635f4fbSAndy Whitcroft		# Handle nested #if/#else.
12994635f4fbSAndy Whitcroft		if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
13004635f4fbSAndy Whitcroft			push(@stack, [ $type, $level ]);
13014635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
13024635f4fbSAndy Whitcroft			($type, $level) = @{$stack[$#stack - 1]};
13034635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*endif\b/) {
13044635f4fbSAndy Whitcroft			($type, $level) = @{pop(@stack)};
13054635f4fbSAndy Whitcroft		}
13064635f4fbSAndy Whitcroft
13078905a67cSAndy Whitcroft		# Statement ends at the ';' or a close '}' at the
13088905a67cSAndy Whitcroft		# outermost level.
13098905a67cSAndy Whitcroft		if ($level == 0 && $c eq ';') {
13108905a67cSAndy Whitcroft			last;
13118905a67cSAndy Whitcroft		}
13128905a67cSAndy Whitcroft
131313214adfSAndy Whitcroft		# An else is really a conditional as long as its not else if
1314773647a0SAndy Whitcroft		if ($level == 0 && $coff_set == 0 &&
1315773647a0SAndy Whitcroft				(!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
1316773647a0SAndy Whitcroft				$remainder =~ /^(else)(?:\s|{)/ &&
1317773647a0SAndy Whitcroft				$remainder !~ /^else\s+if\b/) {
1318773647a0SAndy Whitcroft			$coff = $off + length($1) - 1;
1319773647a0SAndy Whitcroft			$coff_set = 1;
1320773647a0SAndy Whitcroft			#warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
1321773647a0SAndy Whitcroft			#warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
132213214adfSAndy Whitcroft		}
132313214adfSAndy Whitcroft
13248905a67cSAndy Whitcroft		if (($type eq '' || $type eq '(') && $c eq '(') {
13258905a67cSAndy Whitcroft			$level++;
13268905a67cSAndy Whitcroft			$type = '(';
13278905a67cSAndy Whitcroft		}
13288905a67cSAndy Whitcroft		if ($type eq '(' && $c eq ')') {
13298905a67cSAndy Whitcroft			$level--;
13308905a67cSAndy Whitcroft			$type = ($level != 0)? '(' : '';
13318905a67cSAndy Whitcroft
13328905a67cSAndy Whitcroft			if ($level == 0 && $coff < $soff) {
13338905a67cSAndy Whitcroft				$coff = $off;
1334773647a0SAndy Whitcroft				$coff_set = 1;
1335773647a0SAndy Whitcroft				#warn "CSB: mark coff<$coff>\n";
13368905a67cSAndy Whitcroft			}
13378905a67cSAndy Whitcroft		}
13388905a67cSAndy Whitcroft		if (($type eq '' || $type eq '{') && $c eq '{') {
13398905a67cSAndy Whitcroft			$level++;
13408905a67cSAndy Whitcroft			$type = '{';
13418905a67cSAndy Whitcroft		}
13428905a67cSAndy Whitcroft		if ($type eq '{' && $c eq '}') {
13438905a67cSAndy Whitcroft			$level--;
13448905a67cSAndy Whitcroft			$type = ($level != 0)? '{' : '';
13458905a67cSAndy Whitcroft
13468905a67cSAndy Whitcroft			if ($level == 0) {
1347b998e001SPatrick Pannuto				if (substr($blk, $off + 1, 1) eq ';') {
1348b998e001SPatrick Pannuto					$off++;
1349b998e001SPatrick Pannuto				}
13508905a67cSAndy Whitcroft				last;
13518905a67cSAndy Whitcroft			}
13528905a67cSAndy Whitcroft		}
1353f74bd194SAndy Whitcroft		# Preprocessor commands end at the newline unless escaped.
1354f74bd194SAndy Whitcroft		if ($type eq '#' && $c eq "\n" && $p ne "\\") {
1355f74bd194SAndy Whitcroft			$level--;
1356f74bd194SAndy Whitcroft			$type = '';
1357f74bd194SAndy Whitcroft			$off++;
1358f74bd194SAndy Whitcroft			last;
1359f74bd194SAndy Whitcroft		}
13608905a67cSAndy Whitcroft		$off++;
13618905a67cSAndy Whitcroft	}
1362a3bb97a7SAndy Whitcroft	# We are truly at the end, so shuffle to the next line.
136313214adfSAndy Whitcroft	if ($off == $len) {
1364a3bb97a7SAndy Whitcroft		$loff = $len + 1;
136513214adfSAndy Whitcroft		$line++;
136613214adfSAndy Whitcroft		$remain--;
136713214adfSAndy Whitcroft	}
13688905a67cSAndy Whitcroft
13698905a67cSAndy Whitcroft	my $statement = substr($blk, $soff, $off - $soff + 1);
13708905a67cSAndy Whitcroft	my $condition = substr($blk, $soff, $coff - $soff + 1);
13718905a67cSAndy Whitcroft
13728905a67cSAndy Whitcroft	#warn "STATEMENT<$statement>\n";
13738905a67cSAndy Whitcroft	#warn "CONDITION<$condition>\n";
13748905a67cSAndy Whitcroft
1375773647a0SAndy Whitcroft	#print "coff<$coff> soff<$off> loff<$loff>\n";
137613214adfSAndy Whitcroft
137713214adfSAndy Whitcroft	return ($statement, $condition,
137813214adfSAndy Whitcroft			$line, $remain + 1, $off - $loff + 1, $level);
137913214adfSAndy Whitcroft}
138013214adfSAndy Whitcroft
1381cf655043SAndy Whitcroftsub statement_lines {
1382cf655043SAndy Whitcroft	my ($stmt) = @_;
1383cf655043SAndy Whitcroft
1384cf655043SAndy Whitcroft	# Strip the diff line prefixes and rip blank lines at start and end.
1385cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1386cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1387cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1388cf655043SAndy Whitcroft
1389cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1390cf655043SAndy Whitcroft
1391cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1392cf655043SAndy Whitcroft}
1393cf655043SAndy Whitcroft
1394cf655043SAndy Whitcroftsub statement_rawlines {
1395cf655043SAndy Whitcroft	my ($stmt) = @_;
1396cf655043SAndy Whitcroft
1397cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1398cf655043SAndy Whitcroft
1399cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1400cf655043SAndy Whitcroft}
1401cf655043SAndy Whitcroft
1402cf655043SAndy Whitcroftsub statement_block_size {
1403cf655043SAndy Whitcroft	my ($stmt) = @_;
1404cf655043SAndy Whitcroft
1405cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1406cf655043SAndy Whitcroft	$stmt =~ s/^\s*{//;
1407cf655043SAndy Whitcroft	$stmt =~ s/}\s*$//;
1408cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1409cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1410cf655043SAndy Whitcroft
1411cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1412cf655043SAndy Whitcroft	my @stmt_statements = ($stmt =~ /;/g);
1413cf655043SAndy Whitcroft
1414cf655043SAndy Whitcroft	my $stmt_lines = $#stmt_lines + 2;
1415cf655043SAndy Whitcroft	my $stmt_statements = $#stmt_statements + 1;
1416cf655043SAndy Whitcroft
1417cf655043SAndy Whitcroft	if ($stmt_lines > $stmt_statements) {
1418cf655043SAndy Whitcroft		return $stmt_lines;
1419cf655043SAndy Whitcroft	} else {
1420cf655043SAndy Whitcroft		return $stmt_statements;
1421cf655043SAndy Whitcroft	}
1422cf655043SAndy Whitcroft}
1423cf655043SAndy Whitcroft
142413214adfSAndy Whitcroftsub ctx_statement_full {
142513214adfSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
142613214adfSAndy Whitcroft	my ($statement, $condition, $level);
142713214adfSAndy Whitcroft
142813214adfSAndy Whitcroft	my (@chunks);
142913214adfSAndy Whitcroft
1430cf655043SAndy Whitcroft	# Grab the first conditional/block pair.
143113214adfSAndy Whitcroft	($statement, $condition, $linenr, $remain, $off, $level) =
143213214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1433773647a0SAndy Whitcroft	#print "F: c<$condition> s<$statement> remain<$remain>\n";
143413214adfSAndy Whitcroft	push(@chunks, [ $condition, $statement ]);
1435cf655043SAndy Whitcroft	if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1436cf655043SAndy Whitcroft		return ($level, $linenr, @chunks);
1437cf655043SAndy Whitcroft	}
1438cf655043SAndy Whitcroft
1439cf655043SAndy Whitcroft	# Pull in the following conditional/block pairs and see if they
1440cf655043SAndy Whitcroft	# could continue the statement.
1441cf655043SAndy Whitcroft	for (;;) {
144213214adfSAndy Whitcroft		($statement, $condition, $linenr, $remain, $off, $level) =
144313214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1444cf655043SAndy Whitcroft		#print "C: c<$condition> s<$statement> remain<$remain>\n";
1445773647a0SAndy Whitcroft		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1446cf655043SAndy Whitcroft		#print "C: push\n";
1447cf655043SAndy Whitcroft		push(@chunks, [ $condition, $statement ]);
144813214adfSAndy Whitcroft	}
144913214adfSAndy Whitcroft
145013214adfSAndy Whitcroft	return ($level, $linenr, @chunks);
14518905a67cSAndy Whitcroft}
14528905a67cSAndy Whitcroft
14534a0df2efSAndy Whitcroftsub ctx_block_get {
1454f0a594c1SAndy Whitcroft	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
14554a0df2efSAndy Whitcroft	my $line;
14564a0df2efSAndy Whitcroft	my $start = $linenr - 1;
14574a0df2efSAndy Whitcroft	my $blk = '';
14584a0df2efSAndy Whitcroft	my @o;
14594a0df2efSAndy Whitcroft	my @c;
14604a0df2efSAndy Whitcroft	my @res = ();
14614a0df2efSAndy Whitcroft
1462f0a594c1SAndy Whitcroft	my $level = 0;
14634635f4fbSAndy Whitcroft	my @stack = ($level);
146400df344fSAndy Whitcroft	for ($line = $start; $remain > 0; $line++) {
146500df344fSAndy Whitcroft		next if ($rawlines[$line] =~ /^-/);
146600df344fSAndy Whitcroft		$remain--;
146700df344fSAndy Whitcroft
146800df344fSAndy Whitcroft		$blk .= $rawlines[$line];
14694635f4fbSAndy Whitcroft
14704635f4fbSAndy Whitcroft		# Handle nested #if/#else.
147101464f30SAndy Whitcroft		if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
14724635f4fbSAndy Whitcroft			push(@stack, $level);
147301464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
14744635f4fbSAndy Whitcroft			$level = $stack[$#stack - 1];
147501464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
14764635f4fbSAndy Whitcroft			$level = pop(@stack);
14774635f4fbSAndy Whitcroft		}
14784635f4fbSAndy Whitcroft
147901464f30SAndy Whitcroft		foreach my $c (split(//, $lines[$line])) {
1480f0a594c1SAndy Whitcroft			##print "C<$c>L<$level><$open$close>O<$off>\n";
1481f0a594c1SAndy Whitcroft			if ($off > 0) {
1482f0a594c1SAndy Whitcroft				$off--;
1483f0a594c1SAndy Whitcroft				next;
1484f0a594c1SAndy Whitcroft			}
14854a0df2efSAndy Whitcroft
1486f0a594c1SAndy Whitcroft			if ($c eq $close && $level > 0) {
1487f0a594c1SAndy Whitcroft				$level--;
1488f0a594c1SAndy Whitcroft				last if ($level == 0);
1489f0a594c1SAndy Whitcroft			} elsif ($c eq $open) {
1490f0a594c1SAndy Whitcroft				$level++;
1491f0a594c1SAndy Whitcroft			}
1492f0a594c1SAndy Whitcroft		}
14934a0df2efSAndy Whitcroft
1494f0a594c1SAndy Whitcroft		if (!$outer || $level <= 1) {
149500df344fSAndy Whitcroft			push(@res, $rawlines[$line]);
14964a0df2efSAndy Whitcroft		}
14974a0df2efSAndy Whitcroft
1498f0a594c1SAndy Whitcroft		last if ($level == 0);
14994a0df2efSAndy Whitcroft	}
15004a0df2efSAndy Whitcroft
1501f0a594c1SAndy Whitcroft	return ($level, @res);
15024a0df2efSAndy Whitcroft}
15034a0df2efSAndy Whitcroftsub ctx_block_outer {
15044a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
15054a0df2efSAndy Whitcroft
1506f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1507f0a594c1SAndy Whitcroft	return @r;
15084a0df2efSAndy Whitcroft}
15094a0df2efSAndy Whitcroftsub ctx_block {
15104a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
15114a0df2efSAndy Whitcroft
1512f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1513f0a594c1SAndy Whitcroft	return @r;
1514653d4876SAndy Whitcroft}
1515653d4876SAndy Whitcroftsub ctx_statement {
1516f0a594c1SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
1517f0a594c1SAndy Whitcroft
1518f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1519f0a594c1SAndy Whitcroft	return @r;
1520f0a594c1SAndy Whitcroft}
1521f0a594c1SAndy Whitcroftsub ctx_block_level {
1522653d4876SAndy Whitcroft	my ($linenr, $remain) = @_;
1523653d4876SAndy Whitcroft
1524f0a594c1SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
15254a0df2efSAndy Whitcroft}
15269c0ca6f9SAndy Whitcroftsub ctx_statement_level {
15279c0ca6f9SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
15289c0ca6f9SAndy Whitcroft
15299c0ca6f9SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
15309c0ca6f9SAndy Whitcroft}
15314a0df2efSAndy Whitcroft
15324a0df2efSAndy Whitcroftsub ctx_locate_comment {
15334a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
15344a0df2efSAndy Whitcroft
15354a0df2efSAndy Whitcroft	# Catch a comment on the end of the line itself.
1536beae6332SAndy Whitcroft	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
15374a0df2efSAndy Whitcroft	return $current_comment if (defined $current_comment);
15384a0df2efSAndy Whitcroft
15394a0df2efSAndy Whitcroft	# Look through the context and try and figure out if there is a
15404a0df2efSAndy Whitcroft	# comment.
15414a0df2efSAndy Whitcroft	my $in_comment = 0;
15424a0df2efSAndy Whitcroft	$current_comment = '';
15434a0df2efSAndy Whitcroft	for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
154400df344fSAndy Whitcroft		my $line = $rawlines[$linenr - 1];
154500df344fSAndy Whitcroft		#warn "           $line\n";
15464a0df2efSAndy Whitcroft		if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
15474a0df2efSAndy Whitcroft			$in_comment = 1;
15484a0df2efSAndy Whitcroft		}
15494a0df2efSAndy Whitcroft		if ($line =~ m@/\*@) {
15504a0df2efSAndy Whitcroft			$in_comment = 1;
15514a0df2efSAndy Whitcroft		}
15524a0df2efSAndy Whitcroft		if (!$in_comment && $current_comment ne '') {
15534a0df2efSAndy Whitcroft			$current_comment = '';
15544a0df2efSAndy Whitcroft		}
15554a0df2efSAndy Whitcroft		$current_comment .= $line . "\n" if ($in_comment);
15564a0df2efSAndy Whitcroft		if ($line =~ m@\*/@) {
15574a0df2efSAndy Whitcroft			$in_comment = 0;
15584a0df2efSAndy Whitcroft		}
15594a0df2efSAndy Whitcroft	}
15604a0df2efSAndy Whitcroft
15614a0df2efSAndy Whitcroft	chomp($current_comment);
15624a0df2efSAndy Whitcroft	return($current_comment);
15634a0df2efSAndy Whitcroft}
15644a0df2efSAndy Whitcroftsub ctx_has_comment {
15654a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
15664a0df2efSAndy Whitcroft	my $cmt = ctx_locate_comment($first_line, $end_line);
15674a0df2efSAndy Whitcroft
156800df344fSAndy Whitcroft	##print "LINE: $rawlines[$end_line - 1 ]\n";
15694a0df2efSAndy Whitcroft	##print "CMMT: $cmt\n";
15704a0df2efSAndy Whitcroft
15714a0df2efSAndy Whitcroft	return ($cmt ne '');
15724a0df2efSAndy Whitcroft}
15734a0df2efSAndy Whitcroft
15744d001e4dSAndy Whitcroftsub raw_line {
15754d001e4dSAndy Whitcroft	my ($linenr, $cnt) = @_;
15764d001e4dSAndy Whitcroft
15774d001e4dSAndy Whitcroft	my $offset = $linenr - 1;
15784d001e4dSAndy Whitcroft	$cnt++;
15794d001e4dSAndy Whitcroft
15804d001e4dSAndy Whitcroft	my $line;
15814d001e4dSAndy Whitcroft	while ($cnt) {
15824d001e4dSAndy Whitcroft		$line = $rawlines[$offset++];
15834d001e4dSAndy Whitcroft		next if (defined($line) && $line =~ /^-/);
15844d001e4dSAndy Whitcroft		$cnt--;
15854d001e4dSAndy Whitcroft	}
15864d001e4dSAndy Whitcroft
15874d001e4dSAndy Whitcroft	return $line;
15884d001e4dSAndy Whitcroft}
15894d001e4dSAndy Whitcroft
15900a920b5bSAndy Whitcroftsub cat_vet {
15910a920b5bSAndy Whitcroft	my ($vet) = @_;
15929c0ca6f9SAndy Whitcroft	my ($res, $coded);
15930a920b5bSAndy Whitcroft
15949c0ca6f9SAndy Whitcroft	$res = '';
15956c72ffaaSAndy Whitcroft	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
15966c72ffaaSAndy Whitcroft		$res .= $1;
15976c72ffaaSAndy Whitcroft		if ($2 ne '') {
15989c0ca6f9SAndy Whitcroft			$coded = sprintf("^%c", unpack('C', $2) + 64);
15996c72ffaaSAndy Whitcroft			$res .= $coded;
16006c72ffaaSAndy Whitcroft		}
16019c0ca6f9SAndy Whitcroft	}
16029c0ca6f9SAndy Whitcroft	$res =~ s/$/\$/;
16030a920b5bSAndy Whitcroft
16049c0ca6f9SAndy Whitcroft	return $res;
16050a920b5bSAndy Whitcroft}
16060a920b5bSAndy Whitcroft
1607c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0;
1608cf655043SAndy Whitcroftmy $av_pending;
1609c2fdda0dSAndy Whitcroftmy @av_paren_type;
16101f65f947SAndy Whitcroftmy $av_pend_colon;
1611c2fdda0dSAndy Whitcroft
1612c2fdda0dSAndy Whitcroftsub annotate_reset {
1613c2fdda0dSAndy Whitcroft	$av_preprocessor = 0;
1614cf655043SAndy Whitcroft	$av_pending = '_';
1615cf655043SAndy Whitcroft	@av_paren_type = ('E');
16161f65f947SAndy Whitcroft	$av_pend_colon = 'O';
1617c2fdda0dSAndy Whitcroft}
1618c2fdda0dSAndy Whitcroft
16196c72ffaaSAndy Whitcroftsub annotate_values {
16206c72ffaaSAndy Whitcroft	my ($stream, $type) = @_;
16216c72ffaaSAndy Whitcroft
16226c72ffaaSAndy Whitcroft	my $res;
16231f65f947SAndy Whitcroft	my $var = '_' x length($stream);
16246c72ffaaSAndy Whitcroft	my $cur = $stream;
16256c72ffaaSAndy Whitcroft
1626c2fdda0dSAndy Whitcroft	print "$stream\n" if ($dbg_values > 1);
16276c72ffaaSAndy Whitcroft
16286c72ffaaSAndy Whitcroft	while (length($cur)) {
1629773647a0SAndy Whitcroft		@av_paren_type = ('E') if ($#av_paren_type < 0);
1630cf655043SAndy Whitcroft		print " <" . join('', @av_paren_type) .
1631171ae1a4SAndy Whitcroft				"> <$type> <$av_pending>" if ($dbg_values > 1);
16326c72ffaaSAndy Whitcroft		if ($cur =~ /^(\s+)/o) {
1633c2fdda0dSAndy Whitcroft			print "WS($1)\n" if ($dbg_values > 1);
1634c2fdda0dSAndy Whitcroft			if ($1 =~ /\n/ && $av_preprocessor) {
1635cf655043SAndy Whitcroft				$type = pop(@av_paren_type);
1636c2fdda0dSAndy Whitcroft				$av_preprocessor = 0;
16376c72ffaaSAndy Whitcroft			}
16386c72ffaaSAndy Whitcroft
1639c023e473SFlorian Mickler		} elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
16409446ef56SAndy Whitcroft			print "CAST($1)\n" if ($dbg_values > 1);
16419446ef56SAndy Whitcroft			push(@av_paren_type, $type);
1642addcdceaSAndy Whitcroft			$type = 'c';
16439446ef56SAndy Whitcroft
1644e91b6e26SAndy Whitcroft		} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
1645c2fdda0dSAndy Whitcroft			print "DECLARE($1)\n" if ($dbg_values > 1);
16466c72ffaaSAndy Whitcroft			$type = 'T';
16476c72ffaaSAndy Whitcroft
1648389a2fe5SAndy Whitcroft		} elsif ($cur =~ /^($Modifier)\s*/) {
1649389a2fe5SAndy Whitcroft			print "MODIFIER($1)\n" if ($dbg_values > 1);
1650389a2fe5SAndy Whitcroft			$type = 'T';
1651389a2fe5SAndy Whitcroft
1652c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
1653171ae1a4SAndy Whitcroft			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
1654c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1655171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
1656171ae1a4SAndy Whitcroft			if ($2 ne '') {
1657cf655043SAndy Whitcroft				$av_pending = 'N';
1658171ae1a4SAndy Whitcroft			}
1659171ae1a4SAndy Whitcroft			$type = 'E';
1660171ae1a4SAndy Whitcroft
1661c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
1662171ae1a4SAndy Whitcroft			print "UNDEF($1)\n" if ($dbg_values > 1);
1663171ae1a4SAndy Whitcroft			$av_preprocessor = 1;
1664171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
16656c72ffaaSAndy Whitcroft
1666c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
1667cf655043SAndy Whitcroft			print "PRE_START($1)\n" if ($dbg_values > 1);
1668c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1669cf655043SAndy Whitcroft
1670cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1671cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1672171ae1a4SAndy Whitcroft			$type = 'E';
1673cf655043SAndy Whitcroft
1674c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
1675cf655043SAndy Whitcroft			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
1676cf655043SAndy Whitcroft			$av_preprocessor = 1;
1677cf655043SAndy Whitcroft
1678cf655043SAndy Whitcroft			push(@av_paren_type, $av_paren_type[$#av_paren_type]);
1679cf655043SAndy Whitcroft
1680171ae1a4SAndy Whitcroft			$type = 'E';
1681cf655043SAndy Whitcroft
1682c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
1683cf655043SAndy Whitcroft			print "PRE_END($1)\n" if ($dbg_values > 1);
1684cf655043SAndy Whitcroft
1685cf655043SAndy Whitcroft			$av_preprocessor = 1;
1686cf655043SAndy Whitcroft
1687cf655043SAndy Whitcroft			# Assume all arms of the conditional end as this
1688cf655043SAndy Whitcroft			# one does, and continue as if the #endif was not here.
1689cf655043SAndy Whitcroft			pop(@av_paren_type);
1690cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1691171ae1a4SAndy Whitcroft			$type = 'E';
16926c72ffaaSAndy Whitcroft
16936c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\\\n)/o) {
1694c2fdda0dSAndy Whitcroft			print "PRECONT($1)\n" if ($dbg_values > 1);
16956c72ffaaSAndy Whitcroft
1696171ae1a4SAndy Whitcroft		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
1697171ae1a4SAndy Whitcroft			print "ATTR($1)\n" if ($dbg_values > 1);
1698171ae1a4SAndy Whitcroft			$av_pending = $type;
1699171ae1a4SAndy Whitcroft			$type = 'N';
1700171ae1a4SAndy Whitcroft
17016c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
1702c2fdda0dSAndy Whitcroft			print "SIZEOF($1)\n" if ($dbg_values > 1);
17036c72ffaaSAndy Whitcroft			if (defined $2) {
1704cf655043SAndy Whitcroft				$av_pending = 'V';
17056c72ffaaSAndy Whitcroft			}
17066c72ffaaSAndy Whitcroft			$type = 'N';
17076c72ffaaSAndy Whitcroft
170814b111c1SAndy Whitcroft		} elsif ($cur =~ /^(if|while|for)\b/o) {
1709c2fdda0dSAndy Whitcroft			print "COND($1)\n" if ($dbg_values > 1);
171014b111c1SAndy Whitcroft			$av_pending = 'E';
17116c72ffaaSAndy Whitcroft			$type = 'N';
17126c72ffaaSAndy Whitcroft
17131f65f947SAndy Whitcroft		} elsif ($cur =~/^(case)/o) {
17141f65f947SAndy Whitcroft			print "CASE($1)\n" if ($dbg_values > 1);
17151f65f947SAndy Whitcroft			$av_pend_colon = 'C';
17161f65f947SAndy Whitcroft			$type = 'N';
17171f65f947SAndy Whitcroft
171814b111c1SAndy Whitcroft		} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
1719c2fdda0dSAndy Whitcroft			print "KEYWORD($1)\n" if ($dbg_values > 1);
17206c72ffaaSAndy Whitcroft			$type = 'N';
17216c72ffaaSAndy Whitcroft
17226c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\()/o) {
1723c2fdda0dSAndy Whitcroft			print "PAREN('$1')\n" if ($dbg_values > 1);
1724cf655043SAndy Whitcroft			push(@av_paren_type, $av_pending);
1725cf655043SAndy Whitcroft			$av_pending = '_';
17266c72ffaaSAndy Whitcroft			$type = 'N';
17276c72ffaaSAndy Whitcroft
17286c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\))/o) {
1729cf655043SAndy Whitcroft			my $new_type = pop(@av_paren_type);
1730cf655043SAndy Whitcroft			if ($new_type ne '_') {
1731cf655043SAndy Whitcroft				$type = $new_type;
1732c2fdda0dSAndy Whitcroft				print "PAREN('$1') -> $type\n"
1733c2fdda0dSAndy Whitcroft							if ($dbg_values > 1);
17346c72ffaaSAndy Whitcroft			} else {
1735c2fdda0dSAndy Whitcroft				print "PAREN('$1')\n" if ($dbg_values > 1);
17366c72ffaaSAndy Whitcroft			}
17376c72ffaaSAndy Whitcroft
1738c8cb2ca3SAndy Whitcroft		} elsif ($cur =~ /^($Ident)\s*\(/o) {
1739c2fdda0dSAndy Whitcroft			print "FUNC($1)\n" if ($dbg_values > 1);
1740c8cb2ca3SAndy Whitcroft			$type = 'V';
1741cf655043SAndy Whitcroft			$av_pending = 'V';
17426c72ffaaSAndy Whitcroft
17438e761b04SAndy Whitcroft		} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
17448e761b04SAndy Whitcroft			if (defined $2 && $type eq 'C' || $type eq 'T') {
17451f65f947SAndy Whitcroft				$av_pend_colon = 'B';
17468e761b04SAndy Whitcroft			} elsif ($type eq 'E') {
17478e761b04SAndy Whitcroft				$av_pend_colon = 'L';
17481f65f947SAndy Whitcroft			}
17491f65f947SAndy Whitcroft			print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
17501f65f947SAndy Whitcroft			$type = 'V';
17511f65f947SAndy Whitcroft
17526c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Ident|$Constant)/o) {
1753c2fdda0dSAndy Whitcroft			print "IDENT($1)\n" if ($dbg_values > 1);
17546c72ffaaSAndy Whitcroft			$type = 'V';
17556c72ffaaSAndy Whitcroft
17566c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Assignment)/o) {
1757c2fdda0dSAndy Whitcroft			print "ASSIGN($1)\n" if ($dbg_values > 1);
17586c72ffaaSAndy Whitcroft			$type = 'N';
17596c72ffaaSAndy Whitcroft
1760cf655043SAndy Whitcroft		} elsif ($cur =~/^(;|{|})/) {
1761c2fdda0dSAndy Whitcroft			print "END($1)\n" if ($dbg_values > 1);
176213214adfSAndy Whitcroft			$type = 'E';
17631f65f947SAndy Whitcroft			$av_pend_colon = 'O';
176413214adfSAndy Whitcroft
17658e761b04SAndy Whitcroft		} elsif ($cur =~/^(,)/) {
17668e761b04SAndy Whitcroft			print "COMMA($1)\n" if ($dbg_values > 1);
17678e761b04SAndy Whitcroft			$type = 'C';
17688e761b04SAndy Whitcroft
17691f65f947SAndy Whitcroft		} elsif ($cur =~ /^(\?)/o) {
17701f65f947SAndy Whitcroft			print "QUESTION($1)\n" if ($dbg_values > 1);
17711f65f947SAndy Whitcroft			$type = 'N';
17721f65f947SAndy Whitcroft
17731f65f947SAndy Whitcroft		} elsif ($cur =~ /^(:)/o) {
17741f65f947SAndy Whitcroft			print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
17751f65f947SAndy Whitcroft
17761f65f947SAndy Whitcroft			substr($var, length($res), 1, $av_pend_colon);
17771f65f947SAndy Whitcroft			if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
17781f65f947SAndy Whitcroft				$type = 'E';
17791f65f947SAndy Whitcroft			} else {
17801f65f947SAndy Whitcroft				$type = 'N';
17811f65f947SAndy Whitcroft			}
17821f65f947SAndy Whitcroft			$av_pend_colon = 'O';
17831f65f947SAndy Whitcroft
17848e761b04SAndy Whitcroft		} elsif ($cur =~ /^(\[)/o) {
178513214adfSAndy Whitcroft			print "CLOSE($1)\n" if ($dbg_values > 1);
17866c72ffaaSAndy Whitcroft			$type = 'N';
17876c72ffaaSAndy Whitcroft
17880d413866SAndy Whitcroft		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
178974048ed8SAndy Whitcroft			my $variant;
179074048ed8SAndy Whitcroft
179174048ed8SAndy Whitcroft			print "OPV($1)\n" if ($dbg_values > 1);
179274048ed8SAndy Whitcroft			if ($type eq 'V') {
179374048ed8SAndy Whitcroft				$variant = 'B';
179474048ed8SAndy Whitcroft			} else {
179574048ed8SAndy Whitcroft				$variant = 'U';
179674048ed8SAndy Whitcroft			}
179774048ed8SAndy Whitcroft
179874048ed8SAndy Whitcroft			substr($var, length($res), 1, $variant);
179974048ed8SAndy Whitcroft			$type = 'N';
180074048ed8SAndy Whitcroft
18016c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Operators)/o) {
1802c2fdda0dSAndy Whitcroft			print "OP($1)\n" if ($dbg_values > 1);
18036c72ffaaSAndy Whitcroft			if ($1 ne '++' && $1 ne '--') {
18046c72ffaaSAndy Whitcroft				$type = 'N';
18056c72ffaaSAndy Whitcroft			}
18066c72ffaaSAndy Whitcroft
18076c72ffaaSAndy Whitcroft		} elsif ($cur =~ /(^.)/o) {
1808c2fdda0dSAndy Whitcroft			print "C($1)\n" if ($dbg_values > 1);
18096c72ffaaSAndy Whitcroft		}
18106c72ffaaSAndy Whitcroft		if (defined $1) {
18116c72ffaaSAndy Whitcroft			$cur = substr($cur, length($1));
18126c72ffaaSAndy Whitcroft			$res .= $type x length($1);
18136c72ffaaSAndy Whitcroft		}
18146c72ffaaSAndy Whitcroft	}
18156c72ffaaSAndy Whitcroft
18161f65f947SAndy Whitcroft	return ($res, $var);
18176c72ffaaSAndy Whitcroft}
18186c72ffaaSAndy Whitcroft
18198905a67cSAndy Whitcroftsub possible {
182013214adfSAndy Whitcroft	my ($possible, $line) = @_;
18219a974fdbSAndy Whitcroft	my $notPermitted = qr{(?:
18220776e594SAndy Whitcroft		^(?:
18230776e594SAndy Whitcroft			$Modifier|
18240776e594SAndy Whitcroft			$Storage|
18250776e594SAndy Whitcroft			$Type|
18269a974fdbSAndy Whitcroft			DEFINE_\S+
18279a974fdbSAndy Whitcroft		)$|
18289a974fdbSAndy Whitcroft		^(?:
18290776e594SAndy Whitcroft			goto|
18300776e594SAndy Whitcroft			return|
18310776e594SAndy Whitcroft			case|
18320776e594SAndy Whitcroft			else|
18330776e594SAndy Whitcroft			asm|__asm__|
183489a88353SAndy Whitcroft			do|
183589a88353SAndy Whitcroft			\#|
183689a88353SAndy Whitcroft			\#\#|
18379a974fdbSAndy Whitcroft		)(?:\s|$)|
18380776e594SAndy Whitcroft		^(?:typedef|struct|enum)\b
18399a974fdbSAndy Whitcroft	    )}x;
18409a974fdbSAndy Whitcroft	warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
18419a974fdbSAndy Whitcroft	if ($possible !~ $notPermitted) {
1842c45dcabdSAndy Whitcroft		# Check for modifiers.
1843c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Storage\s*//g;
1844c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Sparse\s*//g;
1845c45dcabdSAndy Whitcroft		if ($possible =~ /^\s*$/) {
1846c45dcabdSAndy Whitcroft
1847c45dcabdSAndy Whitcroft		} elsif ($possible =~ /\s/) {
1848c45dcabdSAndy Whitcroft			$possible =~ s/\s*$Type\s*//g;
1849d2506586SAndy Whitcroft			for my $modifier (split(' ', $possible)) {
18509a974fdbSAndy Whitcroft				if ($modifier !~ $notPermitted) {
1851d2506586SAndy Whitcroft					warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
1852485ff23eSAlex Dowad					push(@modifierListFile, $modifier);
1853d2506586SAndy Whitcroft				}
18549a974fdbSAndy Whitcroft			}
1855c45dcabdSAndy Whitcroft
1856c45dcabdSAndy Whitcroft		} else {
185713214adfSAndy Whitcroft			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
1858485ff23eSAlex Dowad			push(@typeListFile, $possible);
1859c45dcabdSAndy Whitcroft		}
18608905a67cSAndy Whitcroft		build_types();
18610776e594SAndy Whitcroft	} else {
18620776e594SAndy Whitcroft		warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
18638905a67cSAndy Whitcroft	}
18648905a67cSAndy Whitcroft}
18658905a67cSAndy Whitcroft
18666c72ffaaSAndy Whitcroftmy $prefix = '';
18676c72ffaaSAndy Whitcroft
1868000d1cc1SJoe Perchessub show_type {
1869cbec18afSJoe Perches	my ($type) = @_;
187091bfe484SJoe Perches
1871522b837cSAlexey Dobriyan	$type =~ tr/[a-z]/[A-Z]/;
1872522b837cSAlexey Dobriyan
1873cbec18afSJoe Perches	return defined $use_type{$type} if (scalar keys %use_type > 0);
1874cbec18afSJoe Perches
1875cbec18afSJoe Perches	return !defined $ignore_type{$type};
1876000d1cc1SJoe Perches}
1877000d1cc1SJoe Perches
1878f0a594c1SAndy Whitcroftsub report {
1879cbec18afSJoe Perches	my ($level, $type, $msg) = @_;
1880cbec18afSJoe Perches
1881cbec18afSJoe Perches	if (!show_type($type) ||
1882cbec18afSJoe Perches	    (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
1883773647a0SAndy Whitcroft		return 0;
1884773647a0SAndy Whitcroft	}
188557230297SJoe Perches	my $output = '';
188657230297SJoe Perches	if (-t STDOUT && $color) {
188757230297SJoe Perches		if ($level eq 'ERROR') {
188857230297SJoe Perches			$output .= RED;
188957230297SJoe Perches		} elsif ($level eq 'WARNING') {
189057230297SJoe Perches			$output .= YELLOW;
1891000d1cc1SJoe Perches		} else {
189257230297SJoe Perches			$output .= GREEN;
1893000d1cc1SJoe Perches		}
189457230297SJoe Perches	}
189557230297SJoe Perches	$output .= $prefix . $level . ':';
189657230297SJoe Perches	if ($show_types) {
189757230297SJoe Perches		$output .= BLUE if (-t STDOUT && $color);
189857230297SJoe Perches		$output .= "$type:";
189957230297SJoe Perches	}
190057230297SJoe Perches	$output .= RESET if (-t STDOUT && $color);
190157230297SJoe Perches	$output .= ' ' . $msg . "\n";
190234d8815fSJoe Perches
190334d8815fSJoe Perches	if ($showfile) {
190434d8815fSJoe Perches		my @lines = split("\n", $output, -1);
190534d8815fSJoe Perches		splice(@lines, 1, 1);
190634d8815fSJoe Perches		$output = join("\n", @lines);
190734d8815fSJoe Perches	}
190857230297SJoe Perches	$output = (split('\n', $output))[0] . "\n" if ($terse);
19098905a67cSAndy Whitcroft
191057230297SJoe Perches	push(our @report, $output);
1911773647a0SAndy Whitcroft
1912773647a0SAndy Whitcroft	return 1;
1913f0a594c1SAndy Whitcroft}
1914cbec18afSJoe Perches
1915f0a594c1SAndy Whitcroftsub report_dump {
191613214adfSAndy Whitcroft	our @report;
1917f0a594c1SAndy Whitcroft}
1918000d1cc1SJoe Perches
1919d752fcc8SJoe Perchessub fixup_current_range {
1920d752fcc8SJoe Perches	my ($lineRef, $offset, $length) = @_;
1921d752fcc8SJoe Perches
1922d752fcc8SJoe Perches	if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
1923d752fcc8SJoe Perches		my $o = $1;
1924d752fcc8SJoe Perches		my $l = $2;
1925d752fcc8SJoe Perches		my $no = $o + $offset;
1926d752fcc8SJoe Perches		my $nl = $l + $length;
1927d752fcc8SJoe Perches		$$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
1928d752fcc8SJoe Perches	}
1929d752fcc8SJoe Perches}
1930d752fcc8SJoe Perches
1931d752fcc8SJoe Perchessub fix_inserted_deleted_lines {
1932d752fcc8SJoe Perches	my ($linesRef, $insertedRef, $deletedRef) = @_;
1933d752fcc8SJoe Perches
1934d752fcc8SJoe Perches	my $range_last_linenr = 0;
1935d752fcc8SJoe Perches	my $delta_offset = 0;
1936d752fcc8SJoe Perches
1937d752fcc8SJoe Perches	my $old_linenr = 0;
1938d752fcc8SJoe Perches	my $new_linenr = 0;
1939d752fcc8SJoe Perches
1940d752fcc8SJoe Perches	my $next_insert = 0;
1941d752fcc8SJoe Perches	my $next_delete = 0;
1942d752fcc8SJoe Perches
1943d752fcc8SJoe Perches	my @lines = ();
1944d752fcc8SJoe Perches
1945d752fcc8SJoe Perches	my $inserted = @{$insertedRef}[$next_insert++];
1946d752fcc8SJoe Perches	my $deleted = @{$deletedRef}[$next_delete++];
1947d752fcc8SJoe Perches
1948d752fcc8SJoe Perches	foreach my $old_line (@{$linesRef}) {
1949d752fcc8SJoe Perches		my $save_line = 1;
1950d752fcc8SJoe Perches		my $line = $old_line;	#don't modify the array
1951323b267fSJoe Perches		if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) {	#new filename
1952d752fcc8SJoe Perches			$delta_offset = 0;
1953d752fcc8SJoe Perches		} elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) {	#new hunk
1954d752fcc8SJoe Perches			$range_last_linenr = $new_linenr;
1955d752fcc8SJoe Perches			fixup_current_range(\$line, $delta_offset, 0);
1956d752fcc8SJoe Perches		}
1957d752fcc8SJoe Perches
1958d752fcc8SJoe Perches		while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
1959d752fcc8SJoe Perches			$deleted = @{$deletedRef}[$next_delete++];
1960d752fcc8SJoe Perches			$save_line = 0;
1961d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
1962d752fcc8SJoe Perches		}
1963d752fcc8SJoe Perches
1964d752fcc8SJoe Perches		while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
1965d752fcc8SJoe Perches			push(@lines, ${$inserted}{'LINE'});
1966d752fcc8SJoe Perches			$inserted = @{$insertedRef}[$next_insert++];
1967d752fcc8SJoe Perches			$new_linenr++;
1968d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
1969d752fcc8SJoe Perches		}
1970d752fcc8SJoe Perches
1971d752fcc8SJoe Perches		if ($save_line) {
1972d752fcc8SJoe Perches			push(@lines, $line);
1973d752fcc8SJoe Perches			$new_linenr++;
1974d752fcc8SJoe Perches		}
1975d752fcc8SJoe Perches
1976d752fcc8SJoe Perches		$old_linenr++;
1977d752fcc8SJoe Perches	}
1978d752fcc8SJoe Perches
1979d752fcc8SJoe Perches	return @lines;
1980d752fcc8SJoe Perches}
1981d752fcc8SJoe Perches
1982f2d7e4d4SJoe Perchessub fix_insert_line {
1983f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
1984f2d7e4d4SJoe Perches
1985f2d7e4d4SJoe Perches	my $inserted = {
1986f2d7e4d4SJoe Perches		LINENR => $linenr,
1987f2d7e4d4SJoe Perches		LINE => $line,
1988f2d7e4d4SJoe Perches	};
1989f2d7e4d4SJoe Perches	push(@fixed_inserted, $inserted);
1990f2d7e4d4SJoe Perches}
1991f2d7e4d4SJoe Perches
1992f2d7e4d4SJoe Perchessub fix_delete_line {
1993f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
1994f2d7e4d4SJoe Perches
1995f2d7e4d4SJoe Perches	my $deleted = {
1996f2d7e4d4SJoe Perches		LINENR => $linenr,
1997f2d7e4d4SJoe Perches		LINE => $line,
1998f2d7e4d4SJoe Perches	};
1999f2d7e4d4SJoe Perches
2000f2d7e4d4SJoe Perches	push(@fixed_deleted, $deleted);
2001f2d7e4d4SJoe Perches}
2002f2d7e4d4SJoe Perches
2003de7d4f0eSAndy Whitcroftsub ERROR {
2004cbec18afSJoe Perches	my ($type, $msg) = @_;
2005cbec18afSJoe Perches
2006cbec18afSJoe Perches	if (report("ERROR", $type, $msg)) {
2007de7d4f0eSAndy Whitcroft		our $clean = 0;
20086c72ffaaSAndy Whitcroft		our $cnt_error++;
20093705ce5bSJoe Perches		return 1;
2010de7d4f0eSAndy Whitcroft	}
20113705ce5bSJoe Perches	return 0;
2012773647a0SAndy Whitcroft}
2013de7d4f0eSAndy Whitcroftsub WARN {
2014cbec18afSJoe Perches	my ($type, $msg) = @_;
2015cbec18afSJoe Perches
2016cbec18afSJoe Perches	if (report("WARNING", $type, $msg)) {
2017de7d4f0eSAndy Whitcroft		our $clean = 0;
20186c72ffaaSAndy Whitcroft		our $cnt_warn++;
20193705ce5bSJoe Perches		return 1;
2020de7d4f0eSAndy Whitcroft	}
20213705ce5bSJoe Perches	return 0;
2022773647a0SAndy Whitcroft}
2023de7d4f0eSAndy Whitcroftsub CHK {
2024cbec18afSJoe Perches	my ($type, $msg) = @_;
2025cbec18afSJoe Perches
2026cbec18afSJoe Perches	if ($check && report("CHECK", $type, $msg)) {
2027de7d4f0eSAndy Whitcroft		our $clean = 0;
20286c72ffaaSAndy Whitcroft		our $cnt_chk++;
20293705ce5bSJoe Perches		return 1;
20306c72ffaaSAndy Whitcroft	}
20313705ce5bSJoe Perches	return 0;
2032de7d4f0eSAndy Whitcroft}
2033de7d4f0eSAndy Whitcroft
20346ecd9674SAndy Whitcroftsub check_absolute_file {
20356ecd9674SAndy Whitcroft	my ($absolute, $herecurr) = @_;
20366ecd9674SAndy Whitcroft	my $file = $absolute;
20376ecd9674SAndy Whitcroft
20386ecd9674SAndy Whitcroft	##print "absolute<$absolute>\n";
20396ecd9674SAndy Whitcroft
20406ecd9674SAndy Whitcroft	# See if any suffix of this path is a path within the tree.
20416ecd9674SAndy Whitcroft	while ($file =~ s@^[^/]*/@@) {
20426ecd9674SAndy Whitcroft		if (-f "$root/$file") {
20436ecd9674SAndy Whitcroft			##print "file<$file>\n";
20446ecd9674SAndy Whitcroft			last;
20456ecd9674SAndy Whitcroft		}
20466ecd9674SAndy Whitcroft	}
20476ecd9674SAndy Whitcroft	if (! -f _)  {
20486ecd9674SAndy Whitcroft		return 0;
20496ecd9674SAndy Whitcroft	}
20506ecd9674SAndy Whitcroft
20516ecd9674SAndy Whitcroft	# It is, so see if the prefix is acceptable.
20526ecd9674SAndy Whitcroft	my $prefix = $absolute;
20536ecd9674SAndy Whitcroft	substr($prefix, -length($file)) = '';
20546ecd9674SAndy Whitcroft
20556ecd9674SAndy Whitcroft	##print "prefix<$prefix>\n";
20566ecd9674SAndy Whitcroft	if ($prefix ne ".../") {
2057000d1cc1SJoe Perches		WARN("USE_RELATIVE_PATH",
2058000d1cc1SJoe Perches		     "use relative pathname instead of absolute in changelog text\n" . $herecurr);
20596ecd9674SAndy Whitcroft	}
20606ecd9674SAndy Whitcroft}
20616ecd9674SAndy Whitcroft
20623705ce5bSJoe Perchessub trim {
20633705ce5bSJoe Perches	my ($string) = @_;
20643705ce5bSJoe Perches
2065b34c648bSJoe Perches	$string =~ s/^\s+|\s+$//g;
2066b34c648bSJoe Perches
2067b34c648bSJoe Perches	return $string;
2068b34c648bSJoe Perches}
2069b34c648bSJoe Perches
2070b34c648bSJoe Perchessub ltrim {
2071b34c648bSJoe Perches	my ($string) = @_;
2072b34c648bSJoe Perches
2073b34c648bSJoe Perches	$string =~ s/^\s+//;
2074b34c648bSJoe Perches
2075b34c648bSJoe Perches	return $string;
2076b34c648bSJoe Perches}
2077b34c648bSJoe Perches
2078b34c648bSJoe Perchessub rtrim {
2079b34c648bSJoe Perches	my ($string) = @_;
2080b34c648bSJoe Perches
2081b34c648bSJoe Perches	$string =~ s/\s+$//;
20823705ce5bSJoe Perches
20833705ce5bSJoe Perches	return $string;
20843705ce5bSJoe Perches}
20853705ce5bSJoe Perches
208652ea8506SJoe Perchessub string_find_replace {
208752ea8506SJoe Perches	my ($string, $find, $replace) = @_;
208852ea8506SJoe Perches
208952ea8506SJoe Perches	$string =~ s/$find/$replace/g;
209052ea8506SJoe Perches
209152ea8506SJoe Perches	return $string;
209252ea8506SJoe Perches}
209352ea8506SJoe Perches
20943705ce5bSJoe Perchessub tabify {
20953705ce5bSJoe Perches	my ($leading) = @_;
20963705ce5bSJoe Perches
20973705ce5bSJoe Perches	my $source_indent = 8;
20983705ce5bSJoe Perches	my $max_spaces_before_tab = $source_indent - 1;
20993705ce5bSJoe Perches	my $spaces_to_tab = " " x $source_indent;
21003705ce5bSJoe Perches
21013705ce5bSJoe Perches	#convert leading spaces to tabs
21023705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
21033705ce5bSJoe Perches	#Remove spaces before a tab
21043705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
21053705ce5bSJoe Perches
21063705ce5bSJoe Perches	return "$leading";
21073705ce5bSJoe Perches}
21083705ce5bSJoe Perches
2109d1fe9c09SJoe Perchessub pos_last_openparen {
2110d1fe9c09SJoe Perches	my ($line) = @_;
2111d1fe9c09SJoe Perches
2112d1fe9c09SJoe Perches	my $pos = 0;
2113d1fe9c09SJoe Perches
2114d1fe9c09SJoe Perches	my $opens = $line =~ tr/\(/\(/;
2115d1fe9c09SJoe Perches	my $closes = $line =~ tr/\)/\)/;
2116d1fe9c09SJoe Perches
2117d1fe9c09SJoe Perches	my $last_openparen = 0;
2118d1fe9c09SJoe Perches
2119d1fe9c09SJoe Perches	if (($opens == 0) || ($closes >= $opens)) {
2120d1fe9c09SJoe Perches		return -1;
2121d1fe9c09SJoe Perches	}
2122d1fe9c09SJoe Perches
2123d1fe9c09SJoe Perches	my $len = length($line);
2124d1fe9c09SJoe Perches
2125d1fe9c09SJoe Perches	for ($pos = 0; $pos < $len; $pos++) {
2126d1fe9c09SJoe Perches		my $string = substr($line, $pos);
2127d1fe9c09SJoe Perches		if ($string =~ /^($FuncArg|$balanced_parens)/) {
2128d1fe9c09SJoe Perches			$pos += length($1) - 1;
2129d1fe9c09SJoe Perches		} elsif (substr($line, $pos, 1) eq '(') {
2130d1fe9c09SJoe Perches			$last_openparen = $pos;
2131d1fe9c09SJoe Perches		} elsif (index($string, '(') == -1) {
2132d1fe9c09SJoe Perches			last;
2133d1fe9c09SJoe Perches		}
2134d1fe9c09SJoe Perches	}
2135d1fe9c09SJoe Perches
213691cb5195SJoe Perches	return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
2137d1fe9c09SJoe Perches}
2138d1fe9c09SJoe Perches
21390a920b5bSAndy Whitcroftsub process {
21400a920b5bSAndy Whitcroft	my $filename = shift;
21410a920b5bSAndy Whitcroft
21420a920b5bSAndy Whitcroft	my $linenr=0;
21430a920b5bSAndy Whitcroft	my $prevline="";
2144c2fdda0dSAndy Whitcroft	my $prevrawline="";
21450a920b5bSAndy Whitcroft	my $stashline="";
2146c2fdda0dSAndy Whitcroft	my $stashrawline="";
21470a920b5bSAndy Whitcroft
21484a0df2efSAndy Whitcroft	my $length;
21490a920b5bSAndy Whitcroft	my $indent;
21500a920b5bSAndy Whitcroft	my $previndent=0;
21510a920b5bSAndy Whitcroft	my $stashindent=0;
21520a920b5bSAndy Whitcroft
2153de7d4f0eSAndy Whitcroft	our $clean = 1;
21540a920b5bSAndy Whitcroft	my $signoff = 0;
21550a920b5bSAndy Whitcroft	my $is_patch = 0;
215629ee1b0cSJoe Perches	my $in_header_lines = $file ? 0 : 1;
215715662b3eSJoe Perches	my $in_commit_log = 0;		#Scanning lines before patch
2158ed43c4e5SAllen Hubbe	my $has_commit_log = 0;		#Encountered lines before patch
2159bf4daf12SJoe Perches	my $commit_log_possible_stack_dump = 0;
21602a076f40SJoe Perches	my $commit_log_long_line = 0;
2161e518e9a5SJoe Perches	my $commit_log_has_diff = 0;
216213f1937eSJoe Perches	my $reported_maintainer_file = 0;
2163fa64205dSPasi Savanainen	my $non_utf8_charset = 0;
2164fa64205dSPasi Savanainen
2165365dd4eaSJoe Perches	my $last_blank_line = 0;
21665e4f6ba5SJoe Perches	my $last_coalesced_string_linenr = -1;
2167365dd4eaSJoe Perches
216813214adfSAndy Whitcroft	our @report = ();
21696c72ffaaSAndy Whitcroft	our $cnt_lines = 0;
21706c72ffaaSAndy Whitcroft	our $cnt_error = 0;
21716c72ffaaSAndy Whitcroft	our $cnt_warn = 0;
21726c72ffaaSAndy Whitcroft	our $cnt_chk = 0;
21736c72ffaaSAndy Whitcroft
21740a920b5bSAndy Whitcroft	# Trace the real file/line as we go.
21750a920b5bSAndy Whitcroft	my $realfile = '';
21760a920b5bSAndy Whitcroft	my $realline = 0;
21770a920b5bSAndy Whitcroft	my $realcnt = 0;
21780a920b5bSAndy Whitcroft	my $here = '';
217977cb8546SJoe Perches	my $context_function;		#undef'd unless there's a known function
21800a920b5bSAndy Whitcroft	my $in_comment = 0;
2181c2fdda0dSAndy Whitcroft	my $comment_edge = 0;
21820a920b5bSAndy Whitcroft	my $first_line = 0;
21831e855726SWolfram Sang	my $p1_prefix = '';
21840a920b5bSAndy Whitcroft
218513214adfSAndy Whitcroft	my $prev_values = 'E';
218613214adfSAndy Whitcroft
218713214adfSAndy Whitcroft	# suppression flags
2188773647a0SAndy Whitcroft	my %suppress_ifbraces;
2189170d3a22SAndy Whitcroft	my %suppress_whiletrailers;
21902b474a1aSAndy Whitcroft	my %suppress_export;
21913e469cdcSAndy Whitcroft	my $suppress_statement = 0;
2192653d4876SAndy Whitcroft
21937e51f197SJoe Perches	my %signatures = ();
2194323c1260SJoe Perches
2195c2fdda0dSAndy Whitcroft	# Pre-scan the patch sanitizing the lines.
2196de7d4f0eSAndy Whitcroft	# Pre-scan the patch looking for any __setup documentation.
2197c2fdda0dSAndy Whitcroft	#
2198de7d4f0eSAndy Whitcroft	my @setup_docs = ();
2199de7d4f0eSAndy Whitcroft	my $setup_docs = 0;
2200773647a0SAndy Whitcroft
2201d8b07710SJoe Perches	my $camelcase_file_seeded = 0;
2202d8b07710SJoe Perches
2203773647a0SAndy Whitcroft	sanitise_line_reset();
2204c2fdda0dSAndy Whitcroft	my $line;
2205c2fdda0dSAndy Whitcroft	foreach my $rawline (@rawlines) {
2206773647a0SAndy Whitcroft		$linenr++;
2207773647a0SAndy Whitcroft		$line = $rawline;
2208c2fdda0dSAndy Whitcroft
22093705ce5bSJoe Perches		push(@fixed, $rawline) if ($fix);
22103705ce5bSJoe Perches
2211773647a0SAndy Whitcroft		if ($rawline=~/^\+\+\+\s+(\S+)/) {
2212de7d4f0eSAndy Whitcroft			$setup_docs = 0;
22138c27ceffSMauro Carvalho Chehab			if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) {
2214de7d4f0eSAndy Whitcroft				$setup_docs = 1;
2215de7d4f0eSAndy Whitcroft			}
2216773647a0SAndy Whitcroft			#next;
2217de7d4f0eSAndy Whitcroft		}
221874fd4f34SJoe Perches		if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
2219773647a0SAndy Whitcroft			$realline=$1-1;
2220773647a0SAndy Whitcroft			if (defined $2) {
2221773647a0SAndy Whitcroft				$realcnt=$3+1;
2222773647a0SAndy Whitcroft			} else {
2223773647a0SAndy Whitcroft				$realcnt=1+1;
2224773647a0SAndy Whitcroft			}
2225c45dcabdSAndy Whitcroft			$in_comment = 0;
2226773647a0SAndy Whitcroft
2227773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  Run
2228773647a0SAndy Whitcroft			# the context looking for a comment "edge".  If this
2229773647a0SAndy Whitcroft			# edge is a close comment then we must be in a comment
2230773647a0SAndy Whitcroft			# at context start.
2231773647a0SAndy Whitcroft			my $edge;
223201fa9147SAndy Whitcroft			my $cnt = $realcnt;
223301fa9147SAndy Whitcroft			for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
223401fa9147SAndy Whitcroft				next if (defined $rawlines[$ln - 1] &&
223501fa9147SAndy Whitcroft					 $rawlines[$ln - 1] =~ /^-/);
223601fa9147SAndy Whitcroft				$cnt--;
223701fa9147SAndy Whitcroft				#print "RAW<$rawlines[$ln - 1]>\n";
2238721c1cb6SAndy Whitcroft				last if (!defined $rawlines[$ln - 1]);
2239fae17daeSAndy Whitcroft				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
2240fae17daeSAndy Whitcroft				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
2241fae17daeSAndy Whitcroft					($edge) = $1;
2242fae17daeSAndy Whitcroft					last;
2243fae17daeSAndy Whitcroft				}
2244773647a0SAndy Whitcroft			}
2245773647a0SAndy Whitcroft			if (defined $edge && $edge eq '*/') {
2246773647a0SAndy Whitcroft				$in_comment = 1;
2247773647a0SAndy Whitcroft			}
2248773647a0SAndy Whitcroft
2249773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  If this
2250773647a0SAndy Whitcroft			# is the start of a diff block and this line starts
2251773647a0SAndy Whitcroft			# ' *' then it is very likely a comment.
2252773647a0SAndy Whitcroft			if (!defined $edge &&
225383242e0cSAndy Whitcroft			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
2254773647a0SAndy Whitcroft			{
2255773647a0SAndy Whitcroft				$in_comment = 1;
2256773647a0SAndy Whitcroft			}
2257773647a0SAndy Whitcroft
2258773647a0SAndy Whitcroft			##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2259773647a0SAndy Whitcroft			sanitise_line_reset($in_comment);
2260773647a0SAndy Whitcroft
2261171ae1a4SAndy Whitcroft		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
2262773647a0SAndy Whitcroft			# Standardise the strings and chars within the input to
2263171ae1a4SAndy Whitcroft			# simplify matching -- only bother with positive lines.
2264773647a0SAndy Whitcroft			$line = sanitise_line($rawline);
2265773647a0SAndy Whitcroft		}
2266773647a0SAndy Whitcroft		push(@lines, $line);
2267773647a0SAndy Whitcroft
2268773647a0SAndy Whitcroft		if ($realcnt > 1) {
2269773647a0SAndy Whitcroft			$realcnt-- if ($line =~ /^(?:\+| |$)/);
2270773647a0SAndy Whitcroft		} else {
2271773647a0SAndy Whitcroft			$realcnt = 0;
2272773647a0SAndy Whitcroft		}
2273773647a0SAndy Whitcroft
2274773647a0SAndy Whitcroft		#print "==>$rawline\n";
2275773647a0SAndy Whitcroft		#print "-->$line\n";
2276de7d4f0eSAndy Whitcroft
2277de7d4f0eSAndy Whitcroft		if ($setup_docs && $line =~ /^\+/) {
2278de7d4f0eSAndy Whitcroft			push(@setup_docs, $line);
2279de7d4f0eSAndy Whitcroft		}
2280de7d4f0eSAndy Whitcroft	}
2281de7d4f0eSAndy Whitcroft
22826c72ffaaSAndy Whitcroft	$prefix = '';
22836c72ffaaSAndy Whitcroft
2284773647a0SAndy Whitcroft	$realcnt = 0;
2285773647a0SAndy Whitcroft	$linenr = 0;
2286194f66fcSJoe Perches	$fixlinenr = -1;
22870a920b5bSAndy Whitcroft	foreach my $line (@lines) {
22880a920b5bSAndy Whitcroft		$linenr++;
2289194f66fcSJoe Perches		$fixlinenr++;
22901b5539b1SJoe Perches		my $sline = $line;	#copy of $line
22911b5539b1SJoe Perches		$sline =~ s/$;/ /g;	#with comments as spaces
22920a920b5bSAndy Whitcroft
2293c2fdda0dSAndy Whitcroft		my $rawline = $rawlines[$linenr - 1];
22946c72ffaaSAndy Whitcroft
22950a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied
2296e518e9a5SJoe Perches		if (!$in_commit_log &&
229774fd4f34SJoe Perches		    $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
229874fd4f34SJoe Perches			my $context = $4;
22990a920b5bSAndy Whitcroft			$is_patch = 1;
23004a0df2efSAndy Whitcroft			$first_line = $linenr + 1;
23010a920b5bSAndy Whitcroft			$realline=$1-1;
23020a920b5bSAndy Whitcroft			if (defined $2) {
23030a920b5bSAndy Whitcroft				$realcnt=$3+1;
23040a920b5bSAndy Whitcroft			} else {
23050a920b5bSAndy Whitcroft				$realcnt=1+1;
23060a920b5bSAndy Whitcroft			}
2307c2fdda0dSAndy Whitcroft			annotate_reset();
230813214adfSAndy Whitcroft			$prev_values = 'E';
230913214adfSAndy Whitcroft
2310773647a0SAndy Whitcroft			%suppress_ifbraces = ();
2311170d3a22SAndy Whitcroft			%suppress_whiletrailers = ();
23122b474a1aSAndy Whitcroft			%suppress_export = ();
23133e469cdcSAndy Whitcroft			$suppress_statement = 0;
231474fd4f34SJoe Perches			if ($context =~ /\b(\w+)\s*\(/) {
231574fd4f34SJoe Perches				$context_function = $1;
231674fd4f34SJoe Perches			} else {
231774fd4f34SJoe Perches				undef $context_function;
231874fd4f34SJoe Perches			}
23190a920b5bSAndy Whitcroft			next;
23200a920b5bSAndy Whitcroft
23214a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that
23224a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely
23234a0df2efSAndy Whitcroft# blank context lines so we need to count that too.
2324773647a0SAndy Whitcroft		} elsif ($line =~ /^( |\+|$)/) {
23250a920b5bSAndy Whitcroft			$realline++;
2326d8aaf121SAndy Whitcroft			$realcnt-- if ($realcnt != 0);
23270a920b5bSAndy Whitcroft
23284a0df2efSAndy Whitcroft			# Measure the line length and indent.
2329c2fdda0dSAndy Whitcroft			($length, $indent) = line_stats($rawline);
23300a920b5bSAndy Whitcroft
23310a920b5bSAndy Whitcroft			# Track the previous line.
23320a920b5bSAndy Whitcroft			($prevline, $stashline) = ($stashline, $line);
23330a920b5bSAndy Whitcroft			($previndent, $stashindent) = ($stashindent, $indent);
2334c2fdda0dSAndy Whitcroft			($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2335c2fdda0dSAndy Whitcroft
2336773647a0SAndy Whitcroft			#warn "line<$line>\n";
23376c72ffaaSAndy Whitcroft
2338d8aaf121SAndy Whitcroft		} elsif ($realcnt == 1) {
2339d8aaf121SAndy Whitcroft			$realcnt--;
23400a920b5bSAndy Whitcroft		}
23410a920b5bSAndy Whitcroft
2342cc77cdcaSAndy Whitcroft		my $hunk_line = ($realcnt != 0);
2343cc77cdcaSAndy Whitcroft
23446c72ffaaSAndy Whitcroft		$here = "#$linenr: " if (!$file);
23456c72ffaaSAndy Whitcroft		$here = "#$realline: " if ($file);
2346773647a0SAndy Whitcroft
23472ac73b4fSJoe Perches		my $found_file = 0;
2348773647a0SAndy Whitcroft		# extract the filename as it passes
23493bf9a009SRabin Vincent		if ($line =~ /^diff --git.*?(\S+)$/) {
23503bf9a009SRabin Vincent			$realfile = $1;
23512b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2352270c49a0SJoe Perches			$in_commit_log = 0;
23532ac73b4fSJoe Perches			$found_file = 1;
23543bf9a009SRabin Vincent		} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
2355773647a0SAndy Whitcroft			$realfile = $1;
23562b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2357270c49a0SJoe Perches			$in_commit_log = 0;
23581e855726SWolfram Sang
23591e855726SWolfram Sang			$p1_prefix = $1;
2360e2f7aa4bSAndy Whitcroft			if (!$file && $tree && $p1_prefix ne '' &&
2361e2f7aa4bSAndy Whitcroft			    -e "$root/$p1_prefix") {
2362000d1cc1SJoe Perches				WARN("PATCH_PREFIX",
2363000d1cc1SJoe Perches				     "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
23641e855726SWolfram Sang			}
2365773647a0SAndy Whitcroft
2366c1ab3326SAndy Whitcroft			if ($realfile =~ m@^include/asm/@) {
2367000d1cc1SJoe Perches				ERROR("MODIFIED_INCLUDE_ASM",
2368000d1cc1SJoe Perches				      "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
2369773647a0SAndy Whitcroft			}
23702ac73b4fSJoe Perches			$found_file = 1;
23712ac73b4fSJoe Perches		}
23722ac73b4fSJoe Perches
237334d8815fSJoe Perches#make up the handle for any error we report on this line
237434d8815fSJoe Perches		if ($showfile) {
237534d8815fSJoe Perches			$prefix = "$realfile:$realline: "
237634d8815fSJoe Perches		} elsif ($emacs) {
23777d3a9f67SJoe Perches			if ($file) {
23787d3a9f67SJoe Perches				$prefix = "$filename:$realline: ";
23797d3a9f67SJoe Perches			} else {
238034d8815fSJoe Perches				$prefix = "$filename:$linenr: ";
238134d8815fSJoe Perches			}
23827d3a9f67SJoe Perches		}
238334d8815fSJoe Perches
23842ac73b4fSJoe Perches		if ($found_file) {
238585b0ee18SJoe Perches			if (is_maintained_obsolete($realfile)) {
238685b0ee18SJoe Perches				WARN("OBSOLETE",
238785b0ee18SJoe Perches				     "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.\n");
238885b0ee18SJoe Perches			}
23897bd7e483SJoe Perches			if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
23902ac73b4fSJoe Perches				$check = 1;
23912ac73b4fSJoe Perches			} else {
23922ac73b4fSJoe Perches				$check = $check_orig;
23932ac73b4fSJoe Perches			}
2394773647a0SAndy Whitcroft			next;
2395773647a0SAndy Whitcroft		}
2396773647a0SAndy Whitcroft
2397389834b6SRandy Dunlap		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
23980a920b5bSAndy Whitcroft
2399c2fdda0dSAndy Whitcroft		my $hereline = "$here\n$rawline\n";
2400c2fdda0dSAndy Whitcroft		my $herecurr = "$here\n$rawline\n";
2401c2fdda0dSAndy Whitcroft		my $hereprev = "$here\n$prevrawline\n$rawline\n";
24020a920b5bSAndy Whitcroft
24036c72ffaaSAndy Whitcroft		$cnt_lines++ if ($realcnt != 0);
24046c72ffaaSAndy Whitcroft
2405e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch
2406e518e9a5SJoe Perches		if ($in_commit_log && !$commit_log_has_diff &&
2407e518e9a5SJoe Perches		    (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&
2408e518e9a5SJoe Perches		      $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||
2409e518e9a5SJoe Perches		     $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
2410e518e9a5SJoe Perches		     $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
2411e518e9a5SJoe Perches			ERROR("DIFF_IN_COMMIT_MSG",
2412e518e9a5SJoe Perches			      "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
2413e518e9a5SJoe Perches			$commit_log_has_diff = 1;
2414e518e9a5SJoe Perches		}
2415e518e9a5SJoe Perches
24163bf9a009SRabin Vincent# Check for incorrect file permissions
24173bf9a009SRabin Vincent		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
24183bf9a009SRabin Vincent			my $permhere = $here . "FILE: $realfile\n";
241904db4d25SJoe Perches			if ($realfile !~ m@scripts/@ &&
242004db4d25SJoe Perches			    $realfile !~ /\.(py|pl|awk|sh)$/) {
2421000d1cc1SJoe Perches				ERROR("EXECUTE_PERMISSIONS",
2422000d1cc1SJoe Perches				      "do not set execute permissions for source files\n" . $permhere);
24233bf9a009SRabin Vincent			}
24243bf9a009SRabin Vincent		}
24253bf9a009SRabin Vincent
242620112475SJoe Perches# Check the patch for a signoff:
2427d8aaf121SAndy Whitcroft		if ($line =~ /^\s*signed-off-by:/i) {
24284a0df2efSAndy Whitcroft			$signoff++;
242915662b3eSJoe Perches			$in_commit_log = 0;
24300a920b5bSAndy Whitcroft		}
243120112475SJoe Perches
2432e0d975b1SJoe Perches# Check if MAINTAINERS is being updated.  If so, there's probably no need to
2433e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete
2434e0d975b1SJoe Perches		if ($line =~ /^\s*MAINTAINERS\s*\|/) {
2435e0d975b1SJoe Perches			$reported_maintainer_file = 1;
2436e0d975b1SJoe Perches		}
2437e0d975b1SJoe Perches
243820112475SJoe Perches# Check signature styles
2439270c49a0SJoe Perches		if (!$in_header_lines &&
2440ce0338dfSJoe Perches		    $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
244120112475SJoe Perches			my $space_before = $1;
244220112475SJoe Perches			my $sign_off = $2;
244320112475SJoe Perches			my $space_after = $3;
244420112475SJoe Perches			my $email = $4;
244520112475SJoe Perches			my $ucfirst_sign_off = ucfirst(lc($sign_off));
244620112475SJoe Perches
2447ce0338dfSJoe Perches			if ($sign_off !~ /$signature_tags/) {
2448ce0338dfSJoe Perches				WARN("BAD_SIGN_OFF",
2449ce0338dfSJoe Perches				     "Non-standard signature: $sign_off\n" . $herecurr);
2450ce0338dfSJoe Perches			}
245120112475SJoe Perches			if (defined $space_before && $space_before ne "") {
24523705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
24533705ce5bSJoe Perches					 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
24543705ce5bSJoe Perches				    $fix) {
2455194f66fcSJoe Perches					$fixed[$fixlinenr] =
24563705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
24573705ce5bSJoe Perches				}
245820112475SJoe Perches			}
245920112475SJoe Perches			if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
24603705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
24613705ce5bSJoe Perches					 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
24623705ce5bSJoe Perches				    $fix) {
2463194f66fcSJoe Perches					$fixed[$fixlinenr] =
24643705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
24653705ce5bSJoe Perches				}
24663705ce5bSJoe Perches
246720112475SJoe Perches			}
246820112475SJoe Perches			if (!defined $space_after || $space_after ne " ") {
24693705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
24703705ce5bSJoe Perches					 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
24713705ce5bSJoe Perches				    $fix) {
2472194f66fcSJoe Perches					$fixed[$fixlinenr] =
24733705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
24743705ce5bSJoe Perches				}
247520112475SJoe Perches			}
247620112475SJoe Perches
247720112475SJoe Perches			my ($email_name, $email_address, $comment) = parse_email($email);
247820112475SJoe Perches			my $suggested_email = format_email(($email_name, $email_address));
247920112475SJoe Perches			if ($suggested_email eq "") {
2480000d1cc1SJoe Perches				ERROR("BAD_SIGN_OFF",
2481000d1cc1SJoe Perches				      "Unrecognized email address: '$email'\n" . $herecurr);
248220112475SJoe Perches			} else {
248320112475SJoe Perches				my $dequoted = $suggested_email;
248420112475SJoe Perches				$dequoted =~ s/^"//;
248520112475SJoe Perches				$dequoted =~ s/" </ </;
248620112475SJoe Perches				# Don't force email to have quotes
248720112475SJoe Perches				# Allow just an angle bracketed address
248820112475SJoe Perches				if ("$dequoted$comment" ne $email &&
248920112475SJoe Perches				    "<$email_address>$comment" ne $email &&
249020112475SJoe Perches				    "$suggested_email$comment" ne $email) {
2491000d1cc1SJoe Perches					WARN("BAD_SIGN_OFF",
2492000d1cc1SJoe Perches					     "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
249320112475SJoe Perches				}
24940a920b5bSAndy Whitcroft			}
24957e51f197SJoe Perches
24967e51f197SJoe Perches# Check for duplicate signatures
24977e51f197SJoe Perches			my $sig_nospace = $line;
24987e51f197SJoe Perches			$sig_nospace =~ s/\s//g;
24997e51f197SJoe Perches			$sig_nospace = lc($sig_nospace);
25007e51f197SJoe Perches			if (defined $signatures{$sig_nospace}) {
25017e51f197SJoe Perches				WARN("BAD_SIGN_OFF",
25027e51f197SJoe Perches				     "Duplicate signature\n" . $herecurr);
25037e51f197SJoe Perches			} else {
25047e51f197SJoe Perches				$signatures{$sig_nospace} = 1;
25057e51f197SJoe Perches			}
25060a920b5bSAndy Whitcroft		}
25070a920b5bSAndy Whitcroft
2508a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned
2509a2fe16b9SJoe Perches		if ($in_header_lines &&
2510a2fe16b9SJoe Perches		    $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
2511a2fe16b9SJoe Perches			WARN("EMAIL_SUBJECT",
2512a2fe16b9SJoe Perches			     "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
2513a2fe16b9SJoe Perches		}
2514a2fe16b9SJoe Perches
25159b3189ebSJoe Perches# Check for old stable address
25169b3189ebSJoe Perches		if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) {
25179b3189ebSJoe Perches			ERROR("STABLE_ADDRESS",
25189b3189ebSJoe Perches			      "The 'stable' address should be 'stable\@vger.kernel.org'\n" . $herecurr);
25199b3189ebSJoe Perches		}
25209b3189ebSJoe Perches
25217ebd05efSChristopher Covington# Check for unwanted Gerrit info
25227ebd05efSChristopher Covington		if ($in_commit_log && $line =~ /^\s*change-id:/i) {
25237ebd05efSChristopher Covington			ERROR("GERRIT_CHANGE_ID",
25247ebd05efSChristopher Covington			      "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr);
25257ebd05efSChristopher Covington		}
25267ebd05efSChristopher Covington
2527369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump
2528369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
2529369c8dd3SJoe Perches		    ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
2530369c8dd3SJoe Perches		     $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
2531369c8dd3SJoe Perches					# timestamp
2532369c8dd3SJoe Perches		     $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) {
2533369c8dd3SJoe Perches					# stack dump address
2534369c8dd3SJoe Perches			$commit_log_possible_stack_dump = 1;
2535369c8dd3SJoe Perches		}
2536369c8dd3SJoe Perches
25372a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once
25382a076f40SJoe Perches		if ($in_commit_log && !$commit_log_long_line &&
2539bf4daf12SJoe Perches		    length($line) > 75 &&
2540bf4daf12SJoe Perches		    !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
2541bf4daf12SJoe Perches					# file delta changes
2542bf4daf12SJoe Perches		      $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||
2543bf4daf12SJoe Perches					# filename then :
2544bf4daf12SJoe Perches		      $line =~ /^\s*(?:Fixes:|Link:)/i ||
2545bf4daf12SJoe Perches					# A Fixes: or Link: line
2546bf4daf12SJoe Perches		      $commit_log_possible_stack_dump)) {
25472a076f40SJoe Perches			WARN("COMMIT_LOG_LONG_LINE",
25482a076f40SJoe Perches			     "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
25492a076f40SJoe Perches			$commit_log_long_line = 1;
25502a076f40SJoe Perches		}
25512a076f40SJoe Perches
2552bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found
2553bf4daf12SJoe Perches		if ($in_commit_log && $commit_log_possible_stack_dump &&
2554bf4daf12SJoe Perches		    $line =~ /^\s*$/) {
2555bf4daf12SJoe Perches			$commit_log_possible_stack_dump = 0;
2556bf4daf12SJoe Perches		}
2557bf4daf12SJoe Perches
25580d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions
2559369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
2560aab38f51SJoe Perches		    $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i &&
2561e882dbfcSWei Wang		    $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
2562fe043ea1SJoe Perches		    ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
2563aab38f51SJoe Perches		     ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
2564369c8dd3SJoe Perches		      $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
2565bf4daf12SJoe Perches		      $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
2566fe043ea1SJoe Perches			my $init_char = "c";
2567fe043ea1SJoe Perches			my $orig_commit = "";
25680d7835fcSJoe Perches			my $short = 1;
25690d7835fcSJoe Perches			my $long = 0;
25700d7835fcSJoe Perches			my $case = 1;
25710d7835fcSJoe Perches			my $space = 1;
25720d7835fcSJoe Perches			my $hasdesc = 0;
257319c146a6SJoe Perches			my $hasparens = 0;
25740d7835fcSJoe Perches			my $id = '0123456789ab';
25750d7835fcSJoe Perches			my $orig_desc = "commit description";
25760d7835fcSJoe Perches			my $description = "";
25770d7835fcSJoe Perches
2578fe043ea1SJoe Perches			if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
2579fe043ea1SJoe Perches				$init_char = $1;
2580fe043ea1SJoe Perches				$orig_commit = lc($2);
2581fe043ea1SJoe Perches			} elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {
2582fe043ea1SJoe Perches				$orig_commit = lc($1);
2583fe043ea1SJoe Perches			}
2584fe043ea1SJoe Perches
25850d7835fcSJoe Perches			$short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);
25860d7835fcSJoe Perches			$long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);
25870d7835fcSJoe Perches			$space = 0 if ($line =~ /\bcommit [0-9a-f]/i);
25880d7835fcSJoe Perches			$case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
25890d7835fcSJoe Perches			if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) {
25900d7835fcSJoe Perches				$orig_desc = $1;
259119c146a6SJoe Perches				$hasparens = 1;
25920d7835fcSJoe Perches			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i &&
25930d7835fcSJoe Perches				 defined $rawlines[$linenr] &&
25940d7835fcSJoe Perches				 $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) {
25950d7835fcSJoe Perches				$orig_desc = $1;
259619c146a6SJoe Perches				$hasparens = 1;
2597b671fde0SJoe Perches			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i &&
2598b671fde0SJoe Perches				 defined $rawlines[$linenr] &&
2599b671fde0SJoe Perches				 $rawlines[$linenr] =~ /^\s*[^"]+"\)/) {
2600b671fde0SJoe Perches				$line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i;
2601b671fde0SJoe Perches				$orig_desc = $1;
2602b671fde0SJoe Perches				$rawlines[$linenr] =~ /^\s*([^"]+)"\)/;
2603b671fde0SJoe Perches				$orig_desc .= " " . $1;
260419c146a6SJoe Perches				$hasparens = 1;
26050d7835fcSJoe Perches			}
26060d7835fcSJoe Perches
26070d7835fcSJoe Perches			($id, $description) = git_commit_info($orig_commit,
26080d7835fcSJoe Perches							      $id, $orig_desc);
26090d7835fcSJoe Perches
2610948b133aSHeinrich Schuchardt			if (defined($id) &&
2611948b133aSHeinrich Schuchardt			   ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) {
2612d311cd44SJoe Perches				ERROR("GIT_COMMIT_ID",
26130d7835fcSJoe Perches				      "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);
26140d7835fcSJoe Perches			}
2615d311cd44SJoe Perches		}
2616d311cd44SJoe Perches
261713f1937eSJoe Perches# Check for added, moved or deleted files
261813f1937eSJoe Perches		if (!$reported_maintainer_file && !$in_commit_log &&
261913f1937eSJoe Perches		    ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
262013f1937eSJoe Perches		     $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
262113f1937eSJoe Perches		     ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
262213f1937eSJoe Perches		      (defined($1) || defined($2))))) {
2623a82603a8SAndrew Jeffery			$is_patch = 1;
262413f1937eSJoe Perches			$reported_maintainer_file = 1;
262513f1937eSJoe Perches			WARN("FILE_PATH_CHANGES",
262613f1937eSJoe Perches			     "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
262713f1937eSJoe Perches		}
262813f1937eSJoe Perches
262900df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file
26308905a67cSAndy Whitcroft		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
2631000d1cc1SJoe Perches			ERROR("CORRUPTED_PATCH",
2632000d1cc1SJoe Perches			      "patch seems to be corrupt (line wrapped?)\n" .
26336c72ffaaSAndy Whitcroft				$herecurr) if (!$emitted_corrupt++);
2634de7d4f0eSAndy Whitcroft		}
2635de7d4f0eSAndy Whitcroft
2636de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
2637de7d4f0eSAndy Whitcroft		if (($realfile =~ /^$/ || $line =~ /^\+/) &&
2638171ae1a4SAndy Whitcroft		    $rawline !~ m/^$UTF8*$/) {
2639171ae1a4SAndy Whitcroft			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
2640171ae1a4SAndy Whitcroft
2641171ae1a4SAndy Whitcroft			my $blank = copy_spacing($rawline);
2642171ae1a4SAndy Whitcroft			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
2643171ae1a4SAndy Whitcroft			my $hereptr = "$hereline$ptr\n";
2644171ae1a4SAndy Whitcroft
264534d99219SJoe Perches			CHK("INVALID_UTF8",
2646000d1cc1SJoe Perches			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
264700df344fSAndy Whitcroft		}
26480a920b5bSAndy Whitcroft
264915662b3eSJoe Perches# Check if it's the start of a commit log
265015662b3eSJoe Perches# (not a header line and we haven't seen the patch filename)
265115662b3eSJoe Perches		if ($in_header_lines && $realfile =~ /^$/ &&
2652eb3a58deSJoe Perches		    !($rawline =~ /^\s+(?:\S|$)/ ||
2653eb3a58deSJoe Perches		      $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
265415662b3eSJoe Perches			$in_header_lines = 0;
265515662b3eSJoe Perches			$in_commit_log = 1;
2656ed43c4e5SAllen Hubbe			$has_commit_log = 1;
265715662b3eSJoe Perches		}
265815662b3eSJoe Perches
2659fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly
2660fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing.
2661fa64205dSPasi Savanainen		if ($in_header_lines &&
2662fa64205dSPasi Savanainen		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
2663fa64205dSPasi Savanainen		    $1 !~ /utf-8/i) {
2664fa64205dSPasi Savanainen			$non_utf8_charset = 1;
2665fa64205dSPasi Savanainen		}
2666fa64205dSPasi Savanainen
2667fa64205dSPasi Savanainen		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
266815662b3eSJoe Perches		    $rawline =~ /$NON_ASCII_UTF8/) {
2669fa64205dSPasi Savanainen			WARN("UTF8_BEFORE_PATCH",
267015662b3eSJoe Perches			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);
267115662b3eSJoe Perches		}
267215662b3eSJoe Perches
2673d6430f71SJoe Perches# Check for absolute kernel paths in commit message
2674d6430f71SJoe Perches		if ($tree && $in_commit_log) {
2675d6430f71SJoe Perches			while ($line =~ m{(?:^|\s)(/\S*)}g) {
2676d6430f71SJoe Perches				my $file = $1;
2677d6430f71SJoe Perches
2678d6430f71SJoe Perches				if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
2679d6430f71SJoe Perches				    check_absolute_file($1, $herecurr)) {
2680d6430f71SJoe Perches					#
2681d6430f71SJoe Perches				} else {
2682d6430f71SJoe Perches					check_absolute_file($file, $herecurr);
2683d6430f71SJoe Perches				}
2684d6430f71SJoe Perches			}
2685d6430f71SJoe Perches		}
2686d6430f71SJoe Perches
268766b47b4aSKees Cook# Check for various typo / spelling mistakes
268866d7a382SJoe Perches		if (defined($misspellings) &&
268966d7a382SJoe Perches		    ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
2690ebfd7d62SJoe Perches			while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) {
269166b47b4aSKees Cook				my $typo = $1;
269266b47b4aSKees Cook				my $typo_fix = $spelling_fix{lc($typo)};
269366b47b4aSKees Cook				$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
269466b47b4aSKees Cook				$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
269566b47b4aSKees Cook				my $msg_type = \&WARN;
269666b47b4aSKees Cook				$msg_type = \&CHK if ($file);
269766b47b4aSKees Cook				if (&{$msg_type}("TYPO_SPELLING",
269866b47b4aSKees Cook						 "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) &&
269966b47b4aSKees Cook				    $fix) {
270066b47b4aSKees Cook					$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
270166b47b4aSKees Cook				}
270266b47b4aSKees Cook			}
270366b47b4aSKees Cook		}
270466b47b4aSKees Cook
270530670854SAndy Whitcroft# ignore non-hunk lines and lines being removed
270630670854SAndy Whitcroft		next if (!$hunk_line || $line =~ /^-/);
270700df344fSAndy Whitcroft
27080a920b5bSAndy Whitcroft#trailing whitespace
27099c0ca6f9SAndy Whitcroft		if ($line =~ /^\+.*\015/) {
2710c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2711d5e616fcSJoe Perches			if (ERROR("DOS_LINE_ENDINGS",
2712d5e616fcSJoe Perches				  "DOS line endings\n" . $herevet) &&
2713d5e616fcSJoe Perches			    $fix) {
2714194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/[\s\015]+$//;
2715d5e616fcSJoe Perches			}
2716c2fdda0dSAndy Whitcroft		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
2717c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
27183705ce5bSJoe Perches			if (ERROR("TRAILING_WHITESPACE",
27193705ce5bSJoe Perches				  "trailing whitespace\n" . $herevet) &&
27203705ce5bSJoe Perches			    $fix) {
2721194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
27223705ce5bSJoe Perches			}
27233705ce5bSJoe Perches
2724d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
27250a920b5bSAndy Whitcroft		}
27265368df20SAndy Whitcroft
27274783f894SJosh Triplett# Check for FSF mailing addresses.
2728109d8cb2SAlexander Duyck		if ($rawline =~ /\bwrite to the Free/i ||
27291bde561eSMatthew Wilcox		    $rawline =~ /\b675\s+Mass\s+Ave/i ||
27303e2232f2SJoe Perches		    $rawline =~ /\b59\s+Temple\s+Pl/i ||
27313e2232f2SJoe Perches		    $rawline =~ /\b51\s+Franklin\s+St/i) {
27324783f894SJosh Triplett			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
27334783f894SJosh Triplett			my $msg_type = \&ERROR;
27344783f894SJosh Triplett			$msg_type = \&CHK if ($file);
27354783f894SJosh Triplett			&{$msg_type}("FSF_MAILING_ADDRESS",
27364783f894SJosh 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)
27374783f894SJosh Triplett		}
27384783f894SJosh Triplett
27393354957aSAndi Kleen# check for Kconfig help text having a real description
27409fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have
27419fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough.
27423354957aSAndi Kleen		if ($realfile =~ /Kconfig/ &&
27438d73e0e7SJoe Perches		    $line =~ /^\+\s*config\s+/) {
27443354957aSAndi Kleen			my $length = 0;
27459fe287d7SAndy Whitcroft			my $cnt = $realcnt;
27469fe287d7SAndy Whitcroft			my $ln = $linenr + 1;
27479fe287d7SAndy Whitcroft			my $f;
2748a1385803SAndy Whitcroft			my $is_start = 0;
27499fe287d7SAndy Whitcroft			my $is_end = 0;
2750a1385803SAndy Whitcroft			for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
27519fe287d7SAndy Whitcroft				$f = $lines[$ln - 1];
27529fe287d7SAndy Whitcroft				$cnt-- if ($lines[$ln - 1] !~ /^-/);
27539fe287d7SAndy Whitcroft				$is_end = $lines[$ln - 1] =~ /^\+/;
27549fe287d7SAndy Whitcroft
27559fe287d7SAndy Whitcroft				next if ($f =~ /^-/);
27568d73e0e7SJoe Perches				last if (!$file && $f =~ /^\@\@/);
2757a1385803SAndy Whitcroft
27588d73e0e7SJoe Perches				if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate)\s*\"/) {
2759a1385803SAndy Whitcroft					$is_start = 1;
27608d73e0e7SJoe Perches				} elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) {
2761a1385803SAndy Whitcroft					$length = -1;
2762a1385803SAndy Whitcroft				}
2763a1385803SAndy Whitcroft
27649fe287d7SAndy Whitcroft				$f =~ s/^.//;
27653354957aSAndi Kleen				$f =~ s/#.*//;
27663354957aSAndi Kleen				$f =~ s/^\s+//;
27673354957aSAndi Kleen				next if ($f =~ /^$/);
27689fe287d7SAndy Whitcroft				if ($f =~ /^\s*config\s/) {
27699fe287d7SAndy Whitcroft					$is_end = 1;
27709fe287d7SAndy Whitcroft					last;
27719fe287d7SAndy Whitcroft				}
27723354957aSAndi Kleen				$length++;
27733354957aSAndi Kleen			}
277456193274SVadim Bendebury			if ($is_start && $is_end && $length < $min_conf_desc_length) {
2775000d1cc1SJoe Perches				WARN("CONFIG_DESCRIPTION",
277656193274SVadim Bendebury				     "please write a paragraph that describes the config symbol fully\n" . $herecurr);
277756193274SVadim Bendebury			}
2778a1385803SAndy Whitcroft			#print "is_start<$is_start> is_end<$is_end> length<$length>\n";
27793354957aSAndi Kleen		}
27803354957aSAndi Kleen
2781628f91a2SJoe Perches# check for MAINTAINERS entries that don't have the right form
2782628f91a2SJoe Perches		if ($realfile =~ /^MAINTAINERS$/ &&
2783628f91a2SJoe Perches		    $rawline =~ /^\+[A-Z]:/ &&
2784628f91a2SJoe Perches		    $rawline !~ /^\+[A-Z]:\t\S/) {
2785628f91a2SJoe Perches			if (WARN("MAINTAINERS_STYLE",
2786628f91a2SJoe Perches				 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
2787628f91a2SJoe Perches			    $fix) {
2788628f91a2SJoe Perches				$fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
2789628f91a2SJoe Perches			}
2790628f91a2SJoe Perches		}
2791628f91a2SJoe Perches
2792327953e9SChristoph Jaeger# discourage the use of boolean for type definition attributes of Kconfig options
2793327953e9SChristoph Jaeger		if ($realfile =~ /Kconfig/ &&
2794327953e9SChristoph Jaeger		    $line =~ /^\+\s*\bboolean\b/) {
2795327953e9SChristoph Jaeger			WARN("CONFIG_TYPE_BOOLEAN",
2796327953e9SChristoph Jaeger			     "Use of boolean is deprecated, please use bool instead.\n" . $herecurr);
2797327953e9SChristoph Jaeger		}
2798327953e9SChristoph Jaeger
2799c68e5878SArnaud Lacombe		if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
2800c68e5878SArnaud Lacombe		    ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
2801c68e5878SArnaud Lacombe			my $flag = $1;
2802c68e5878SArnaud Lacombe			my $replacement = {
2803c68e5878SArnaud Lacombe				'EXTRA_AFLAGS' =>   'asflags-y',
2804c68e5878SArnaud Lacombe				'EXTRA_CFLAGS' =>   'ccflags-y',
2805c68e5878SArnaud Lacombe				'EXTRA_CPPFLAGS' => 'cppflags-y',
2806c68e5878SArnaud Lacombe				'EXTRA_LDFLAGS' =>  'ldflags-y',
2807c68e5878SArnaud Lacombe			};
2808c68e5878SArnaud Lacombe
2809c68e5878SArnaud Lacombe			WARN("DEPRECATED_VARIABLE",
2810c68e5878SArnaud Lacombe			     "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
2811c68e5878SArnaud Lacombe		}
2812c68e5878SArnaud Lacombe
2813bff5da43SRob Herring# check for DT compatible documentation
28147dd05b38SFlorian Vaussard		if (defined $root &&
28157dd05b38SFlorian Vaussard			(($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
28167dd05b38SFlorian Vaussard			 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
28177dd05b38SFlorian Vaussard
2818bff5da43SRob Herring			my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
2819bff5da43SRob Herring
2820cc93319bSFlorian Vaussard			my $dt_path = $root . "/Documentation/devicetree/bindings/";
2821cc93319bSFlorian Vaussard			my $vp_file = $dt_path . "vendor-prefixes.txt";
2822cc93319bSFlorian Vaussard
2823bff5da43SRob Herring			foreach my $compat (@compats) {
2824bff5da43SRob Herring				my $compat2 = $compat;
2825185d566bSRob Herring				$compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
2826185d566bSRob Herring				my $compat3 = $compat;
2827185d566bSRob Herring				$compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
2828185d566bSRob Herring				`grep -Erq "$compat|$compat2|$compat3" $dt_path`;
2829bff5da43SRob Herring				if ( $? >> 8 ) {
2830bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
2831bff5da43SRob Herring					     "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
2832bff5da43SRob Herring				}
2833bff5da43SRob Herring
28344fbf32a6SFlorian Vaussard				next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
28354fbf32a6SFlorian Vaussard				my $vendor = $1;
2836cc93319bSFlorian Vaussard				`grep -Eq "^$vendor\\b" $vp_file`;
2837bff5da43SRob Herring				if ( $? >> 8 ) {
2838bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
2839cc93319bSFlorian Vaussard					     "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
2840bff5da43SRob Herring				}
2841bff5da43SRob Herring			}
2842bff5da43SRob Herring		}
2843bff5da43SRob Herring
28445368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk
2845d6430f71SJoe Perches		next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
28465368df20SAndy Whitcroft
284747e0c88bSJoe Perches# line length limit (with some exclusions)
284847e0c88bSJoe Perches#
284947e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length:
285047e0c88bSJoe Perches#	logging functions like pr_info that end in a string
285147e0c88bSJoe Perches#	lines with a single string
285247e0c88bSJoe Perches#	#defines that are a single string
285347e0c88bSJoe Perches#
285447e0c88bSJoe Perches# There are 3 different line length message types:
285547e0c88bSJoe Perches# LONG_LINE_COMMENT	a comment starts before but extends beyond $max_linelength
285647e0c88bSJoe Perches# LONG_LINE_STRING	a string starts before but extends beyond $max_line_length
285747e0c88bSJoe Perches# LONG_LINE		all other lines longer than $max_line_length
285847e0c88bSJoe Perches#
285947e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored
286047e0c88bSJoe Perches#
286147e0c88bSJoe Perches
2862b4749e96SJoe Perches		if ($line =~ /^\+/ && $length > $max_line_length) {
286347e0c88bSJoe Perches			my $msg_type = "LONG_LINE";
286447e0c88bSJoe Perches
286547e0c88bSJoe Perches			# Check the allowed long line types first
286647e0c88bSJoe Perches
286747e0c88bSJoe Perches			# logging functions that end in a string that starts
286847e0c88bSJoe Perches			# before $max_line_length
286947e0c88bSJoe Perches			if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
287047e0c88bSJoe Perches			    length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
287147e0c88bSJoe Perches				$msg_type = "";
287247e0c88bSJoe Perches
287347e0c88bSJoe Perches			# lines with only strings (w/ possible termination)
287447e0c88bSJoe Perches			# #defines with only strings
287547e0c88bSJoe Perches			} elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
287647e0c88bSJoe Perches				 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
287747e0c88bSJoe Perches				$msg_type = "";
287847e0c88bSJoe Perches
2879d560a5f8SJoe Perches			# EFI_GUID is another special case
2880d560a5f8SJoe Perches			} elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) {
2881d560a5f8SJoe Perches				$msg_type = "";
2882d560a5f8SJoe Perches
288347e0c88bSJoe Perches			# Otherwise set the alternate message types
288447e0c88bSJoe Perches
288547e0c88bSJoe Perches			# a comment starts before $max_line_length
288647e0c88bSJoe Perches			} elsif ($line =~ /($;[\s$;]*)$/ &&
288747e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
288847e0c88bSJoe Perches				$msg_type = "LONG_LINE_COMMENT"
288947e0c88bSJoe Perches
289047e0c88bSJoe Perches			# a quoted string starts before $max_line_length
289147e0c88bSJoe Perches			} elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
289247e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
289347e0c88bSJoe Perches				$msg_type = "LONG_LINE_STRING"
289447e0c88bSJoe Perches			}
289547e0c88bSJoe Perches
289647e0c88bSJoe Perches			if ($msg_type ne "" &&
289747e0c88bSJoe Perches			    (show_type("LONG_LINE") || show_type($msg_type))) {
289847e0c88bSJoe Perches				WARN($msg_type,
28996cd7f386SJoe Perches				     "line over $max_line_length characters\n" . $herecurr);
29000a920b5bSAndy Whitcroft			}
290147e0c88bSJoe Perches		}
29020a920b5bSAndy Whitcroft
29038905a67cSAndy Whitcroft# check for adding lines without a newline.
29048905a67cSAndy Whitcroft		if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
2905000d1cc1SJoe Perches			WARN("MISSING_EOF_NEWLINE",
2906000d1cc1SJoe Perches			     "adding a line without newline at end of file\n" . $herecurr);
29078905a67cSAndy Whitcroft		}
29088905a67cSAndy Whitcroft
290942e41c54SMike Frysinger# Blackfin: use hi/lo macros
291042e41c54SMike Frysinger		if ($realfile =~ m@arch/blackfin/.*\.S$@) {
291142e41c54SMike Frysinger			if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) {
291242e41c54SMike Frysinger				my $herevet = "$here\n" . cat_vet($line) . "\n";
2913000d1cc1SJoe Perches				ERROR("LO_MACRO",
2914000d1cc1SJoe Perches				      "use the LO() macro, not (... & 0xFFFF)\n" . $herevet);
291542e41c54SMike Frysinger			}
291642e41c54SMike Frysinger			if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) {
291742e41c54SMike Frysinger				my $herevet = "$here\n" . cat_vet($line) . "\n";
2918000d1cc1SJoe Perches				ERROR("HI_MACRO",
2919000d1cc1SJoe Perches				      "use the HI() macro, not (... >> 16)\n" . $herevet);
292042e41c54SMike Frysinger			}
292142e41c54SMike Frysinger		}
292242e41c54SMike Frysinger
2923b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk
2924de4c924cSGeert Uytterhoeven		next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
29250a920b5bSAndy Whitcroft
29260a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything
29270a920b5bSAndy Whitcroft# more than 8 must use tabs.
2928c2fdda0dSAndy Whitcroft		if ($rawline =~ /^\+\s* \t\s*\S/ ||
2929c2fdda0dSAndy Whitcroft		    $rawline =~ /^\+\s*        \s*/) {
2930c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2931d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
29323705ce5bSJoe Perches			if (ERROR("CODE_INDENT",
29333705ce5bSJoe Perches				  "code indent should use tabs where possible\n" . $herevet) &&
29343705ce5bSJoe Perches			    $fix) {
2935194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
29363705ce5bSJoe Perches			}
29370a920b5bSAndy Whitcroft		}
29380a920b5bSAndy Whitcroft
293908e44365SAlberto Panizzo# check for space before tabs.
294008e44365SAlberto Panizzo		if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
294108e44365SAlberto Panizzo			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
29423705ce5bSJoe Perches			if (WARN("SPACE_BEFORE_TAB",
29433705ce5bSJoe Perches				"please, no space before tabs\n" . $herevet) &&
29443705ce5bSJoe Perches			    $fix) {
2945194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
2946d2207ccbSJoe Perches					   s/(^\+.*) {8,8}\t/$1\t\t/) {}
2947194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
2948c76f4cb3SJoe Perches					   s/(^\+.*) +\t/$1\t/) {}
29493705ce5bSJoe Perches			}
295008e44365SAlberto Panizzo		}
295108e44365SAlberto Panizzo
2952d1fe9c09SJoe Perches# check for && or || at the start of a line
2953d1fe9c09SJoe Perches		if ($rawline =~ /^\+\s*(&&|\|\|)/) {
2954d1fe9c09SJoe Perches			CHK("LOGICAL_CONTINUATIONS",
2955d1fe9c09SJoe Perches			    "Logical continuations should be on the previous line\n" . $hereprev);
2956d1fe9c09SJoe Perches		}
2957d1fe9c09SJoe Perches
2958a91e8994SJoe Perches# check indentation starts on a tab stop
2959a91e8994SJoe Perches		if ($^V && $^V ge 5.10.0 &&
2960a91e8994SJoe Perches		    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$))/) {
2961a91e8994SJoe Perches			my $indent = length($1);
2962a91e8994SJoe Perches			if ($indent % 8) {
2963a91e8994SJoe Perches				if (WARN("TABSTOP",
2964a91e8994SJoe Perches					 "Statements should start on a tabstop\n" . $herecurr) &&
2965a91e8994SJoe Perches				    $fix) {
2966a91e8994SJoe Perches					$fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e;
2967a91e8994SJoe Perches				}
2968a91e8994SJoe Perches			}
2969a91e8994SJoe Perches		}
2970a91e8994SJoe Perches
2971d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line
2972d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
297391cb5195SJoe Perches		    $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|$Ident\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
2974d1fe9c09SJoe Perches			$prevline =~ /^\+(\t*)(.*)$/;
2975d1fe9c09SJoe Perches			my $oldindent = $1;
2976d1fe9c09SJoe Perches			my $rest = $2;
2977d1fe9c09SJoe Perches
2978d1fe9c09SJoe Perches			my $pos = pos_last_openparen($rest);
2979d1fe9c09SJoe Perches			if ($pos >= 0) {
2980b34a26f3SJoe Perches				$line =~ /^(\+| )([ \t]*)/;
2981b34a26f3SJoe Perches				my $newindent = $2;
2982d1fe9c09SJoe Perches
2983d1fe9c09SJoe Perches				my $goodtabindent = $oldindent .
2984d1fe9c09SJoe Perches					"\t" x ($pos / 8) .
2985d1fe9c09SJoe Perches					" "  x ($pos % 8);
2986d1fe9c09SJoe Perches				my $goodspaceindent = $oldindent . " "  x $pos;
2987d1fe9c09SJoe Perches
2988d1fe9c09SJoe Perches				if ($newindent ne $goodtabindent &&
2989d1fe9c09SJoe Perches				    $newindent ne $goodspaceindent) {
29903705ce5bSJoe Perches
29913705ce5bSJoe Perches					if (CHK("PARENTHESIS_ALIGNMENT",
29923705ce5bSJoe Perches						"Alignment should match open parenthesis\n" . $hereprev) &&
29933705ce5bSJoe Perches					    $fix && $line =~ /^\+/) {
2994194f66fcSJoe Perches						$fixed[$fixlinenr] =~
29953705ce5bSJoe Perches						    s/^\+[ \t]*/\+$goodtabindent/;
29963705ce5bSJoe Perches					}
2997d1fe9c09SJoe Perches				}
2998d1fe9c09SJoe Perches			}
2999d1fe9c09SJoe Perches		}
3000d1fe9c09SJoe Perches
30016ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar"
30026ab3a970SJoe Perches# avoid checking a few false positives:
30036ab3a970SJoe Perches#   "sizeof(<type>)" or "__alignof__(<type>)"
30046ab3a970SJoe Perches#   function pointer declarations like "(*foo)(int) = bar;"
30056ab3a970SJoe Perches#   structure definitions like "(struct foo) { 0 };"
30066ab3a970SJoe Perches#   multiline macros that define functions
30076ab3a970SJoe Perches#   known attributes or the __attribute__ keyword
30086ab3a970SJoe Perches		if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
30096ab3a970SJoe Perches		    (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
30103705ce5bSJoe Perches			if (CHK("SPACING",
3011f27c95dbSJoe Perches				"No space is necessary after a cast\n" . $herecurr) &&
30123705ce5bSJoe Perches			    $fix) {
3013194f66fcSJoe Perches				$fixed[$fixlinenr] =~
3014f27c95dbSJoe Perches				    s/(\(\s*$Type\s*\))[ \t]+/$1/;
30153705ce5bSJoe Perches			}
3016aad4f614SJoe Perches		}
3017aad4f614SJoe Perches
301886406b1cSJoe Perches# Block comment styles
301986406b1cSJoe Perches# Networking with an initial /*
302005880600SJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
3021fdb4bcd6SJoe Perches		    $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
302285ad978cSJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&
302385ad978cSJoe Perches		    $realline > 2) {
302405880600SJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
302505880600SJoe Perches			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
302605880600SJoe Perches		}
302705880600SJoe Perches
302886406b1cSJoe Perches# Block comments use * on subsequent lines
302986406b1cSJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
303086406b1cSJoe Perches		    $prevrawline =~ /^\+.*?\/\*/ &&		#starting /*
3031a605e32eSJoe Perches		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */
303261135e96SJoe Perches		    $rawline =~ /^\+/ &&			#line is new
3033a605e32eSJoe Perches		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *
303486406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
303586406b1cSJoe Perches			     "Block comments use * on subsequent lines\n" . $hereprev);
3036a605e32eSJoe Perches		}
3037a605e32eSJoe Perches
303886406b1cSJoe Perches# Block comments use */ on trailing lines
303986406b1cSJoe Perches		if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
3040c24f9f19SJoe Perches		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/
3041c24f9f19SJoe Perches		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/
3042c24f9f19SJoe Perches		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */
304386406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
304486406b1cSJoe Perches			     "Block comments use a trailing */ on a separate line\n" . $herecurr);
304505880600SJoe Perches		}
304605880600SJoe Perches
304708eb9b80SJoe Perches# Block comment * alignment
304808eb9b80SJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
3049af207524SJoe Perches		    $line =~ /^\+[ \t]*$;/ &&			#leading comment
3050af207524SJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&		#leading *
3051af207524SJoe Perches		    (($prevrawline =~ /^\+.*?\/\*/ &&		#leading /*
305208eb9b80SJoe Perches		      $prevrawline !~ /\*\/[ \t]*$/) ||		#no trailing */
3053af207524SJoe Perches		     $prevrawline =~ /^\+[ \t]*\*/)) {		#leading *
3054af207524SJoe Perches			my $oldindent;
305508eb9b80SJoe Perches			$prevrawline =~ m@^\+([ \t]*/?)\*@;
3056af207524SJoe Perches			if (defined($1)) {
3057af207524SJoe Perches				$oldindent = expand_tabs($1);
3058af207524SJoe Perches			} else {
3059af207524SJoe Perches				$prevrawline =~ m@^\+(.*/?)\*@;
3060af207524SJoe Perches				$oldindent = expand_tabs($1);
3061af207524SJoe Perches			}
306208eb9b80SJoe Perches			$rawline =~ m@^\+([ \t]*)\*@;
306308eb9b80SJoe Perches			my $newindent = $1;
306408eb9b80SJoe Perches			$newindent = expand_tabs($newindent);
3065af207524SJoe Perches			if (length($oldindent) ne length($newindent)) {
306608eb9b80SJoe Perches				WARN("BLOCK_COMMENT_STYLE",
306708eb9b80SJoe Perches				     "Block comments should align the * on each line\n" . $hereprev);
306808eb9b80SJoe Perches			}
306908eb9b80SJoe Perches		}
307008eb9b80SJoe Perches
30717f619191SJoe Perches# check for missing blank lines after struct/union declarations
30727f619191SJoe Perches# with exceptions for various attributes and macros
30737f619191SJoe Perches		if ($prevline =~ /^[\+ ]};?\s*$/ &&
30747f619191SJoe Perches		    $line =~ /^\+/ &&
30757f619191SJoe Perches		    !($line =~ /^\+\s*$/ ||
30767f619191SJoe Perches		      $line =~ /^\+\s*EXPORT_SYMBOL/ ||
30777f619191SJoe Perches		      $line =~ /^\+\s*MODULE_/i ||
30787f619191SJoe Perches		      $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
30797f619191SJoe Perches		      $line =~ /^\+[a-z_]*init/ ||
30807f619191SJoe Perches		      $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
30817f619191SJoe Perches		      $line =~ /^\+\s*DECLARE/ ||
30827f619191SJoe Perches		      $line =~ /^\+\s*__setup/)) {
3083d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
3084d752fcc8SJoe Perches				"Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
3085d752fcc8SJoe Perches			    $fix) {
3086f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, "\+");
3087d752fcc8SJoe Perches			}
30887f619191SJoe Perches		}
30897f619191SJoe Perches
3090365dd4eaSJoe Perches# check for multiple consecutive blank lines
3091365dd4eaSJoe Perches		if ($prevline =~ /^[\+ ]\s*$/ &&
3092365dd4eaSJoe Perches		    $line =~ /^\+\s*$/ &&
3093365dd4eaSJoe Perches		    $last_blank_line != ($linenr - 1)) {
3094d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
3095d752fcc8SJoe Perches				"Please don't use multiple blank lines\n" . $hereprev) &&
3096d752fcc8SJoe Perches			    $fix) {
3097f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
3098d752fcc8SJoe Perches			}
3099d752fcc8SJoe Perches
3100365dd4eaSJoe Perches			$last_blank_line = $linenr;
3101365dd4eaSJoe Perches		}
3102365dd4eaSJoe Perches
31033b617e3bSJoe Perches# check for missing blank lines after declarations
31043f7bac03SJoe Perches		if ($sline =~ /^\+\s+\S/ &&			#Not at char 1
31053f7bac03SJoe Perches			# actual declarations
31063f7bac03SJoe Perches		    ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
31075a4e1fd3SJoe Perches			# function pointer declarations
31085a4e1fd3SJoe Perches		     $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
31093f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
31103f7bac03SJoe Perches		     $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
31113f7bac03SJoe Perches			# known declaration macros
31123f7bac03SJoe Perches		     $prevline =~ /^\+\s+$declaration_macros/) &&
31133f7bac03SJoe Perches			# for "else if" which can look like "$Ident $Ident"
31143f7bac03SJoe Perches		    !($prevline =~ /^\+\s+$c90_Keywords\b/ ||
31153f7bac03SJoe Perches			# other possible extensions of declaration lines
31163f7bac03SJoe Perches		      $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
31173f7bac03SJoe Perches			# not starting a section or a macro "\" extended line
31183f7bac03SJoe Perches		      $prevline =~ /(?:\{\s*|\\)$/) &&
31193f7bac03SJoe Perches			# looks like a declaration
31203f7bac03SJoe Perches		    !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
31215a4e1fd3SJoe Perches			# function pointer declarations
31225a4e1fd3SJoe Perches		      $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
31233f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
31243f7bac03SJoe Perches		      $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
31253f7bac03SJoe Perches			# known declaration macros
31263f7bac03SJoe Perches		      $sline =~ /^\+\s+$declaration_macros/ ||
31273f7bac03SJoe Perches			# start of struct or union or enum
31283b617e3bSJoe Perches		      $sline =~ /^\+\s+(?:union|struct|enum|typedef)\b/ ||
31293f7bac03SJoe Perches			# start or end of block or continuation of declaration
31303f7bac03SJoe Perches		      $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
31313f7bac03SJoe Perches			# bitfield continuation
31323f7bac03SJoe Perches		      $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
31333f7bac03SJoe Perches			# other possible extensions of declaration lines
31343f7bac03SJoe Perches		      $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) &&
31353f7bac03SJoe Perches			# indentation of previous and current line are the same
31363f7bac03SJoe Perches		    (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) {
3137d752fcc8SJoe Perches			if (WARN("LINE_SPACING",
3138d752fcc8SJoe Perches				 "Missing a blank line after declarations\n" . $hereprev) &&
3139d752fcc8SJoe Perches			    $fix) {
3140f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, "\+");
3141d752fcc8SJoe Perches			}
31423b617e3bSJoe Perches		}
31433b617e3bSJoe Perches
31445f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line.
31456b4c5bebSAndy Whitcroft# Exceptions:
31466b4c5bebSAndy Whitcroft#  1) within comments
31476b4c5bebSAndy Whitcroft#  2) indented preprocessor commands
31486b4c5bebSAndy Whitcroft#  3) hanging labels
31493705ce5bSJoe Perches		if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/)  {
31505f7ddae6SRaffaele Recalcati			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
31513705ce5bSJoe Perches			if (WARN("LEADING_SPACE",
31523705ce5bSJoe Perches				 "please, no spaces at the start of a line\n" . $herevet) &&
31533705ce5bSJoe Perches			    $fix) {
3154194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
31553705ce5bSJoe Perches			}
31565f7ddae6SRaffaele Recalcati		}
31575f7ddae6SRaffaele Recalcati
3158b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk
3159b9ea10d6SAndy Whitcroft		next if ($realfile !~ /\.(h|c)$/);
3160b9ea10d6SAndy Whitcroft
31614dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name
31624dbed76fSJoe Perches		if ($sline =~ /^\+\{\s*$/ &&
31634dbed76fSJoe Perches		    $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
31644dbed76fSJoe Perches			$context_function = $1;
31654dbed76fSJoe Perches		}
31664dbed76fSJoe Perches
31674dbed76fSJoe Perches# check if this appears to be the end of function declaration
31684dbed76fSJoe Perches		if ($sline =~ /^\+\}\s*$/) {
31694dbed76fSJoe Perches			undef $context_function;
31704dbed76fSJoe Perches		}
31714dbed76fSJoe Perches
3172032a4c0fSJoe Perches# check indentation of any line with a bare else
3173840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;")
3174032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more...
3175032a4c0fSJoe Perches		if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
3176032a4c0fSJoe Perches			my $tabs = length($1) + 1;
3177840080a0SJoe Perches			if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
3178840080a0SJoe Perches			    ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
3179840080a0SJoe Perches			     defined $lines[$linenr] &&
3180840080a0SJoe Perches			     $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
3181032a4c0fSJoe Perches				WARN("UNNECESSARY_ELSE",
3182032a4c0fSJoe Perches				     "else is not generally useful after a break or return\n" . $hereprev);
3183032a4c0fSJoe Perches			}
3184032a4c0fSJoe Perches		}
3185032a4c0fSJoe Perches
3186c00df19aSJoe Perches# check indentation of a line with a break;
3187c00df19aSJoe Perches# if the previous line is a goto or return and is indented the same # of tabs
3188c00df19aSJoe Perches		if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
3189c00df19aSJoe Perches			my $tabs = $1;
3190c00df19aSJoe Perches			if ($prevline =~ /^\+$tabs(?:goto|return)\b/) {
3191c00df19aSJoe Perches				WARN("UNNECESSARY_BREAK",
3192c00df19aSJoe Perches				     "break is not useful after a goto or return\n" . $hereprev);
3193c00df19aSJoe Perches			}
3194c00df19aSJoe Perches		}
3195c00df19aSJoe Perches
3196c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers
3197cf655043SAndy Whitcroft		if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
3198000d1cc1SJoe Perches			WARN("CVS_KEYWORD",
3199000d1cc1SJoe Perches			     "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
3200c2fdda0dSAndy Whitcroft		}
320122f2a2efSAndy Whitcroft
320242e41c54SMike Frysinger# Blackfin: don't use __builtin_bfin_[cs]sync
320342e41c54SMike Frysinger		if ($line =~ /__builtin_bfin_csync/) {
320442e41c54SMike Frysinger			my $herevet = "$here\n" . cat_vet($line) . "\n";
3205000d1cc1SJoe Perches			ERROR("CSYNC",
3206000d1cc1SJoe Perches			      "use the CSYNC() macro in asm/blackfin.h\n" . $herevet);
320742e41c54SMike Frysinger		}
320842e41c54SMike Frysinger		if ($line =~ /__builtin_bfin_ssync/) {
320942e41c54SMike Frysinger			my $herevet = "$here\n" . cat_vet($line) . "\n";
3210000d1cc1SJoe Perches			ERROR("SSYNC",
3211000d1cc1SJoe Perches			      "use the SSYNC() macro in asm/blackfin.h\n" . $herevet);
321242e41c54SMike Frysinger		}
321342e41c54SMike Frysinger
321456e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings
321556e77d70SJoe Perches		if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
321656e77d70SJoe Perches			WARN("HOTPLUG_SECTION",
321756e77d70SJoe Perches			     "Using $1 is unnecessary\n" . $herecurr);
321856e77d70SJoe Perches		}
321956e77d70SJoe Perches
32209c0ca6f9SAndy Whitcroft# Check for potential 'bare' types
32212b474a1aSAndy Whitcroft		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
32222b474a1aSAndy Whitcroft		    $realline_next);
32233e469cdcSAndy Whitcroft#print "LINE<$line>\n";
3224ca819864SJoe Perches		if ($linenr > $suppress_statement &&
32251b5539b1SJoe Perches		    $realcnt && $sline =~ /.\s*\S/) {
3226170d3a22SAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
3227f5fe35ddSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
3228171ae1a4SAndy Whitcroft			$stat =~ s/\n./\n /g;
3229171ae1a4SAndy Whitcroft			$cond =~ s/\n./\n /g;
3230171ae1a4SAndy Whitcroft
32313e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n";
32323e469cdcSAndy Whitcroft			# If this statement has no statement boundaries within
32333e469cdcSAndy Whitcroft			# it there is no point in retrying a statement scan
32343e469cdcSAndy Whitcroft			# until we hit end of it.
32353e469cdcSAndy Whitcroft			my $frag = $stat; $frag =~ s/;+\s*$//;
32363e469cdcSAndy Whitcroft			if ($frag !~ /(?:{|;)/) {
32373e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n";
32383e469cdcSAndy Whitcroft				$suppress_statement = $line_nr_next;
32393e469cdcSAndy Whitcroft			}
3240f74bd194SAndy Whitcroft
32412b474a1aSAndy Whitcroft			# Find the real next line.
32422b474a1aSAndy Whitcroft			$realline_next = $line_nr_next;
32432b474a1aSAndy Whitcroft			if (defined $realline_next &&
32442b474a1aSAndy Whitcroft			    (!defined $lines[$realline_next - 1] ||
32452b474a1aSAndy Whitcroft			     substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
32462b474a1aSAndy Whitcroft				$realline_next++;
32472b474a1aSAndy Whitcroft			}
32482b474a1aSAndy Whitcroft
3249171ae1a4SAndy Whitcroft			my $s = $stat;
3250171ae1a4SAndy Whitcroft			$s =~ s/{.*$//s;
3251cf655043SAndy Whitcroft
3252c2fdda0dSAndy Whitcroft			# Ignore goto labels.
3253171ae1a4SAndy Whitcroft			if ($s =~ /$Ident:\*$/s) {
3254c2fdda0dSAndy Whitcroft
3255c2fdda0dSAndy Whitcroft			# Ignore functions being called
3256171ae1a4SAndy Whitcroft			} elsif ($s =~ /^.\s*$Ident\s*\(/s) {
3257c2fdda0dSAndy Whitcroft
3258463f2864SAndy Whitcroft			} elsif ($s =~ /^.\s*else\b/s) {
3259463f2864SAndy Whitcroft
3260c45dcabdSAndy Whitcroft			# declarations always start with types
3261d2506586SAndy 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) {
3262c45dcabdSAndy Whitcroft				my $type = $1;
3263c45dcabdSAndy Whitcroft				$type =~ s/\s+/ /g;
3264c45dcabdSAndy Whitcroft				possible($type, "A:" . $s);
3265c45dcabdSAndy Whitcroft
32666c72ffaaSAndy Whitcroft			# definitions in global scope can only start with types
3267a6a84062SAndy Whitcroft			} elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
3268c45dcabdSAndy Whitcroft				possible($1, "B:" . $s);
3269c2fdda0dSAndy Whitcroft			}
32708905a67cSAndy Whitcroft
32716c72ffaaSAndy Whitcroft			# any (foo ... *) is a pointer cast, and foo is a type
327265863862SAndy Whitcroft			while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
3273c45dcabdSAndy Whitcroft				possible($1, "C:" . $s);
32749c0ca6f9SAndy Whitcroft			}
32758905a67cSAndy Whitcroft
32768905a67cSAndy Whitcroft			# Check for any sort of function declaration.
32778905a67cSAndy Whitcroft			# int foo(something bar, other baz);
32788905a67cSAndy Whitcroft			# void (*store_gdt)(x86_descr_ptr *);
3279171ae1a4SAndy Whitcroft			if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
32808905a67cSAndy Whitcroft				my ($name_len) = length($1);
32818905a67cSAndy Whitcroft
3282cf655043SAndy Whitcroft				my $ctx = $s;
3283773647a0SAndy Whitcroft				substr($ctx, 0, $name_len + 1, '');
32848905a67cSAndy Whitcroft				$ctx =~ s/\)[^\)]*$//;
3285cf655043SAndy Whitcroft
32868905a67cSAndy Whitcroft				for my $arg (split(/\s*,\s*/, $ctx)) {
3287c45dcabdSAndy Whitcroft					if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
32888905a67cSAndy Whitcroft
3289c45dcabdSAndy Whitcroft						possible($1, "D:" . $s);
32908905a67cSAndy Whitcroft					}
32918905a67cSAndy Whitcroft				}
32928905a67cSAndy Whitcroft			}
32938905a67cSAndy Whitcroft
32949c0ca6f9SAndy Whitcroft		}
32959c0ca6f9SAndy Whitcroft
329600df344fSAndy Whitcroft#
329700df344fSAndy Whitcroft# Checks which may be anchored in the context.
329800df344fSAndy Whitcroft#
329900df344fSAndy Whitcroft
330000df344fSAndy Whitcroft# Check for switch () and associated case and default
330100df344fSAndy Whitcroft# statements should be at the same indent.
330200df344fSAndy Whitcroft		if ($line=~/\bswitch\s*\(.*\)/) {
330300df344fSAndy Whitcroft			my $err = '';
330400df344fSAndy Whitcroft			my $sep = '';
330500df344fSAndy Whitcroft			my @ctx = ctx_block_outer($linenr, $realcnt);
330600df344fSAndy Whitcroft			shift(@ctx);
330700df344fSAndy Whitcroft			for my $ctx (@ctx) {
330800df344fSAndy Whitcroft				my ($clen, $cindent) = line_stats($ctx);
330900df344fSAndy Whitcroft				if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
331000df344fSAndy Whitcroft							$indent != $cindent) {
331100df344fSAndy Whitcroft					$err .= "$sep$ctx\n";
331200df344fSAndy Whitcroft					$sep = '';
331300df344fSAndy Whitcroft				} else {
331400df344fSAndy Whitcroft					$sep = "[...]\n";
331500df344fSAndy Whitcroft				}
331600df344fSAndy Whitcroft			}
331700df344fSAndy Whitcroft			if ($err ne '') {
3318000d1cc1SJoe Perches				ERROR("SWITCH_CASE_INDENT_LEVEL",
3319000d1cc1SJoe Perches				      "switch and case should be at the same indent\n$hereline$err");
3320de7d4f0eSAndy Whitcroft			}
3321de7d4f0eSAndy Whitcroft		}
3322de7d4f0eSAndy Whitcroft
3323de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop,
3324de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else
33250fe3dc2bSJoe Perches		if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
3326773647a0SAndy Whitcroft			my $pre_ctx = "$1$2";
3327773647a0SAndy Whitcroft
33289c0ca6f9SAndy Whitcroft			my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
33298eef05ddSJoe Perches
33308eef05ddSJoe Perches			if ($line =~ /^\+\t{6,}/) {
33318eef05ddSJoe Perches				WARN("DEEP_INDENTATION",
33328eef05ddSJoe Perches				     "Too many leading tabs - consider code refactoring\n" . $herecurr);
33338eef05ddSJoe Perches			}
33348eef05ddSJoe Perches
3335de7d4f0eSAndy Whitcroft			my $ctx_cnt = $realcnt - $#ctx - 1;
3336de7d4f0eSAndy Whitcroft			my $ctx = join("\n", @ctx);
3337de7d4f0eSAndy Whitcroft
3338548596d5SAndy Whitcroft			my $ctx_ln = $linenr;
3339548596d5SAndy Whitcroft			my $ctx_skip = $realcnt;
3340de7d4f0eSAndy Whitcroft
3341548596d5SAndy Whitcroft			while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
3342548596d5SAndy Whitcroft					defined $lines[$ctx_ln - 1] &&
3343548596d5SAndy Whitcroft					$lines[$ctx_ln - 1] =~ /^-/)) {
3344548596d5SAndy Whitcroft				##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
3345548596d5SAndy Whitcroft				$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
3346773647a0SAndy Whitcroft				$ctx_ln++;
3347773647a0SAndy Whitcroft			}
3348548596d5SAndy Whitcroft
334953210168SAndy Whitcroft			#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
335053210168SAndy Whitcroft			#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
3351773647a0SAndy Whitcroft
3352773647a0SAndy Whitcroft			if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
3353000d1cc1SJoe Perches				ERROR("OPEN_BRACE",
3354000d1cc1SJoe Perches				      "that open brace { should be on the previous line\n" .
335501464f30SAndy Whitcroft					"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
335600df344fSAndy Whitcroft			}
3357773647a0SAndy Whitcroft			if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
3358773647a0SAndy Whitcroft			    $ctx =~ /\)\s*\;\s*$/ &&
3359773647a0SAndy Whitcroft			    defined $lines[$ctx_ln - 1])
3360773647a0SAndy Whitcroft			{
33619c0ca6f9SAndy Whitcroft				my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
33629c0ca6f9SAndy Whitcroft				if ($nindent > $indent) {
3363000d1cc1SJoe Perches					WARN("TRAILING_SEMICOLON",
3364000d1cc1SJoe Perches					     "trailing semicolon indicates no statements, indent implies otherwise\n" .
336501464f30SAndy Whitcroft						"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
33669c0ca6f9SAndy Whitcroft				}
33679c0ca6f9SAndy Whitcroft			}
336800df344fSAndy Whitcroft		}
336900df344fSAndy Whitcroft
33704d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks.
3371f6950a73SJoe Perches		if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
33723e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
33733e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
33743e469cdcSAndy Whitcroft					if (!defined $stat);
33754d001e4dSAndy Whitcroft			my ($s, $c) = ($stat, $cond);
33764d001e4dSAndy Whitcroft
33774d001e4dSAndy Whitcroft			substr($s, 0, length($c), '');
33784d001e4dSAndy Whitcroft
33799f5af480SJoe Perches			# remove inline comments
33809f5af480SJoe Perches			$s =~ s/$;/ /g;
33819f5af480SJoe Perches			$c =~ s/$;/ /g;
33824d001e4dSAndy Whitcroft
33834d001e4dSAndy Whitcroft			# Find out how long the conditional actually is.
33846f779c18SAndy Whitcroft			my @newlines = ($c =~ /\n/gs);
33856f779c18SAndy Whitcroft			my $cond_lines = 1 + $#newlines;
33864d001e4dSAndy Whitcroft
33879f5af480SJoe Perches			# Make sure we remove the line prefixes as we have
33889f5af480SJoe Perches			# none on the first line, and are going to readd them
33899f5af480SJoe Perches			# where necessary.
33909f5af480SJoe Perches			$s =~ s/\n./\n/gs;
33919f5af480SJoe Perches			while ($s =~ /\n\s+\\\n/) {
33929f5af480SJoe Perches				$cond_lines += $s =~ s/\n\s+\\\n/\n/g;
33939f5af480SJoe Perches			}
33949f5af480SJoe Perches
33954d001e4dSAndy Whitcroft			# We want to check the first line inside the block
33964d001e4dSAndy Whitcroft			# starting at the end of the conditional, so remove:
33974d001e4dSAndy Whitcroft			#  1) any blank line termination
33984d001e4dSAndy Whitcroft			#  2) any opening brace { on end of the line
33994d001e4dSAndy Whitcroft			#  3) any do (...) {
34004d001e4dSAndy Whitcroft			my $continuation = 0;
34014d001e4dSAndy Whitcroft			my $check = 0;
34024d001e4dSAndy Whitcroft			$s =~ s/^.*\bdo\b//;
34034d001e4dSAndy Whitcroft			$s =~ s/^\s*{//;
34044d001e4dSAndy Whitcroft			if ($s =~ s/^\s*\\//) {
34054d001e4dSAndy Whitcroft				$continuation = 1;
34064d001e4dSAndy Whitcroft			}
34079bd49efeSAndy Whitcroft			if ($s =~ s/^\s*?\n//) {
34084d001e4dSAndy Whitcroft				$check = 1;
34094d001e4dSAndy Whitcroft				$cond_lines++;
34104d001e4dSAndy Whitcroft			}
34114d001e4dSAndy Whitcroft
34124d001e4dSAndy Whitcroft			# Also ignore a loop construct at the end of a
34134d001e4dSAndy Whitcroft			# preprocessor statement.
34144d001e4dSAndy Whitcroft			if (($prevline =~ /^.\s*#\s*define\s/ ||
34154d001e4dSAndy Whitcroft			    $prevline =~ /\\\s*$/) && $continuation == 0) {
34164d001e4dSAndy Whitcroft				$check = 0;
34174d001e4dSAndy Whitcroft			}
34184d001e4dSAndy Whitcroft
34199bd49efeSAndy Whitcroft			my $cond_ptr = -1;
3420740504c6SAndy Whitcroft			$continuation = 0;
34219bd49efeSAndy Whitcroft			while ($cond_ptr != $cond_lines) {
34229bd49efeSAndy Whitcroft				$cond_ptr = $cond_lines;
34234d001e4dSAndy Whitcroft
3424f16fa28fSAndy Whitcroft				# If we see an #else/#elif then the code
3425f16fa28fSAndy Whitcroft				# is not linear.
3426f16fa28fSAndy Whitcroft				if ($s =~ /^\s*\#\s*(?:else|elif)/) {
3427f16fa28fSAndy Whitcroft					$check = 0;
3428f16fa28fSAndy Whitcroft				}
3429f16fa28fSAndy Whitcroft
34309bd49efeSAndy Whitcroft				# Ignore:
34319bd49efeSAndy Whitcroft				#  1) blank lines, they should be at 0,
34329bd49efeSAndy Whitcroft				#  2) preprocessor lines, and
34339bd49efeSAndy Whitcroft				#  3) labels.
3434740504c6SAndy Whitcroft				if ($continuation ||
3435740504c6SAndy Whitcroft				    $s =~ /^\s*?\n/ ||
34369bd49efeSAndy Whitcroft				    $s =~ /^\s*#\s*?/ ||
34379bd49efeSAndy Whitcroft				    $s =~ /^\s*$Ident\s*:/) {
3438740504c6SAndy Whitcroft					$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
343930dad6ebSAndy Whitcroft					if ($s =~ s/^.*?\n//) {
34409bd49efeSAndy Whitcroft						$cond_lines++;
34419bd49efeSAndy Whitcroft					}
34424d001e4dSAndy Whitcroft				}
344330dad6ebSAndy Whitcroft			}
34444d001e4dSAndy Whitcroft
34454d001e4dSAndy Whitcroft			my (undef, $sindent) = line_stats("+" . $s);
34464d001e4dSAndy Whitcroft			my $stat_real = raw_line($linenr, $cond_lines);
34474d001e4dSAndy Whitcroft
34484d001e4dSAndy Whitcroft			# Check if either of these lines are modified, else
34494d001e4dSAndy Whitcroft			# this is not this patch's fault.
34504d001e4dSAndy Whitcroft			if (!defined($stat_real) ||
34514d001e4dSAndy Whitcroft			    $stat !~ /^\+/ && $stat_real !~ /^\+/) {
34524d001e4dSAndy Whitcroft				$check = 0;
34534d001e4dSAndy Whitcroft			}
34544d001e4dSAndy Whitcroft			if (defined($stat_real) && $cond_lines > 1) {
34554d001e4dSAndy Whitcroft				$stat_real = "[...]\n$stat_real";
34564d001e4dSAndy Whitcroft			}
34574d001e4dSAndy Whitcroft
34589bd49efeSAndy 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";
34594d001e4dSAndy Whitcroft
34609f5af480SJoe Perches			if ($check && $s ne '' &&
34619f5af480SJoe Perches			    (($sindent % 8) != 0 ||
34629f5af480SJoe Perches			     ($sindent < $indent) ||
3463f6950a73SJoe Perches			     ($sindent == $indent &&
3464f6950a73SJoe Perches			      ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
34659f5af480SJoe Perches			     ($sindent > $indent + 8))) {
3466000d1cc1SJoe Perches				WARN("SUSPECT_CODE_INDENT",
3467000d1cc1SJoe Perches				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
34684d001e4dSAndy Whitcroft			}
34694d001e4dSAndy Whitcroft		}
34704d001e4dSAndy Whitcroft
34716c72ffaaSAndy Whitcroft		# Track the 'values' across context and added lines.
34726c72ffaaSAndy Whitcroft		my $opline = $line; $opline =~ s/^./ /;
34731f65f947SAndy Whitcroft		my ($curr_values, $curr_vars) =
34741f65f947SAndy Whitcroft				annotate_values($opline . "\n", $prev_values);
34756c72ffaaSAndy Whitcroft		$curr_values = $prev_values . $curr_values;
3476c2fdda0dSAndy Whitcroft		if ($dbg_values) {
3477c2fdda0dSAndy Whitcroft			my $outline = $opline; $outline =~ s/\t/ /g;
3478cf655043SAndy Whitcroft			print "$linenr > .$outline\n";
3479cf655043SAndy Whitcroft			print "$linenr > $curr_values\n";
34801f65f947SAndy Whitcroft			print "$linenr >  $curr_vars\n";
3481c2fdda0dSAndy Whitcroft		}
34826c72ffaaSAndy Whitcroft		$prev_values = substr($curr_values, -1);
34836c72ffaaSAndy Whitcroft
348400df344fSAndy Whitcroft#ignore lines not being added
34853705ce5bSJoe Perches		next if ($line =~ /^[^\+]/);
348600df344fSAndy Whitcroft
348711ca40a0SJoe Perches# check for dereferences that span multiple lines
348811ca40a0SJoe Perches		if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
348911ca40a0SJoe Perches		    $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
349011ca40a0SJoe Perches			$prevline =~ /($Lval\s*(?:\.|->))\s*$/;
349111ca40a0SJoe Perches			my $ref = $1;
349211ca40a0SJoe Perches			$line =~ /^.\s*($Lval)/;
349311ca40a0SJoe Perches			$ref .= $1;
349411ca40a0SJoe Perches			$ref =~ s/\s//g;
349511ca40a0SJoe Perches			WARN("MULTILINE_DEREFERENCE",
349611ca40a0SJoe Perches			     "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
349711ca40a0SJoe Perches		}
349811ca40a0SJoe Perches
3499a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int
3500c8447115SJoe Perches		while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
3501a1ce18e4SJoe Perches			my $type = $1;
3502a1ce18e4SJoe Perches			my $var = $2;
3503207a8e84SJoe Perches			$var = "" if (!defined $var);
3504207a8e84SJoe Perches			if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
3505a1ce18e4SJoe Perches				my $sign = $1;
3506a1ce18e4SJoe Perches				my $pointer = $2;
3507a1ce18e4SJoe Perches
3508a1ce18e4SJoe Perches				$pointer = "" if (!defined $pointer);
3509a1ce18e4SJoe Perches
3510a1ce18e4SJoe Perches				if (WARN("UNSPECIFIED_INT",
3511a1ce18e4SJoe Perches					 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
3512a1ce18e4SJoe Perches				    $fix) {
3513a1ce18e4SJoe Perches					my $decl = trim($sign) . " int ";
3514207a8e84SJoe Perches					my $comp_pointer = $pointer;
3515207a8e84SJoe Perches					$comp_pointer =~ s/\s//g;
3516207a8e84SJoe Perches					$decl .= $comp_pointer;
3517207a8e84SJoe Perches					$decl = rtrim($decl) if ($var eq "");
3518207a8e84SJoe Perches					$fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
3519a1ce18e4SJoe Perches				}
3520a1ce18e4SJoe Perches			}
3521a1ce18e4SJoe Perches		}
3522a1ce18e4SJoe Perches
3523653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher.
35247429c690SAndy Whitcroft		if ($dbg_type) {
35257429c690SAndy Whitcroft			if ($line =~ /^.\s*$Declare\s*$/) {
3526000d1cc1SJoe Perches				ERROR("TEST_TYPE",
3527000d1cc1SJoe Perches				      "TEST: is type\n" . $herecurr);
35287429c690SAndy Whitcroft			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
3529000d1cc1SJoe Perches				ERROR("TEST_NOT_TYPE",
3530000d1cc1SJoe Perches				      "TEST: is not type ($1 is)\n". $herecurr);
35317429c690SAndy Whitcroft			}
3532653d4876SAndy Whitcroft			next;
3533653d4876SAndy Whitcroft		}
3534a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher.
3535a1ef277eSAndy Whitcroft		if ($dbg_attr) {
35369360b0e5SAndy Whitcroft			if ($line =~ /^.\s*$Modifier\s*$/) {
3537000d1cc1SJoe Perches				ERROR("TEST_ATTR",
3538000d1cc1SJoe Perches				      "TEST: is attr\n" . $herecurr);
35399360b0e5SAndy Whitcroft			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
3540000d1cc1SJoe Perches				ERROR("TEST_NOT_ATTR",
3541000d1cc1SJoe Perches				      "TEST: is not attr ($1 is)\n". $herecurr);
3542a1ef277eSAndy Whitcroft			}
3543a1ef277eSAndy Whitcroft			next;
3544a1ef277eSAndy Whitcroft		}
3545653d4876SAndy Whitcroft
3546f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line
354799423c20SAndy Whitcroft		if ($line =~ /^.\s*{/ &&
354899423c20SAndy Whitcroft		    $prevline =~ /(?:^|[^=])=\s*$/) {
3549d752fcc8SJoe Perches			if (ERROR("OPEN_BRACE",
3550d752fcc8SJoe Perches				  "that open brace { should be on the previous line\n" . $hereprev) &&
3551f2d7e4d4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
3552f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
3553f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
3554d752fcc8SJoe Perches				my $fixedline = $prevrawline;
3555d752fcc8SJoe Perches				$fixedline =~ s/\s*=\s*$/ = {/;
3556f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
3557d752fcc8SJoe Perches				$fixedline = $line;
3558*8d81ae05SCyril Bur				$fixedline =~ s/^(.\s*)\{\s*/$1/;
3559f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
3560d752fcc8SJoe Perches			}
3561f0a594c1SAndy Whitcroft		}
3562f0a594c1SAndy Whitcroft
356300df344fSAndy Whitcroft#
356400df344fSAndy Whitcroft# Checks which are anchored on the added line.
356500df344fSAndy Whitcroft#
356600df344fSAndy Whitcroft
3567653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line)
3568c45dcabdSAndy Whitcroft		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
3569653d4876SAndy Whitcroft			my $path = $1;
3570653d4876SAndy Whitcroft			if ($path =~ m{//}) {
3571000d1cc1SJoe Perches				ERROR("MALFORMED_INCLUDE",
3572495e9d84SJoe Perches				      "malformed #include filename\n" . $herecurr);
3573495e9d84SJoe Perches			}
3574495e9d84SJoe Perches			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
3575495e9d84SJoe Perches				ERROR("UAPI_INCLUDE",
3576495e9d84SJoe Perches				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
3577653d4876SAndy Whitcroft			}
3578653d4876SAndy Whitcroft		}
3579653d4876SAndy Whitcroft
358000df344fSAndy Whitcroft# no C99 // comments
358100df344fSAndy Whitcroft		if ($line =~ m{//}) {
35823705ce5bSJoe Perches			if (ERROR("C99_COMMENTS",
35833705ce5bSJoe Perches				  "do not use C99 // comments\n" . $herecurr) &&
35843705ce5bSJoe Perches			    $fix) {
3585194f66fcSJoe Perches				my $line = $fixed[$fixlinenr];
35863705ce5bSJoe Perches				if ($line =~ /\/\/(.*)$/) {
35873705ce5bSJoe Perches					my $comment = trim($1);
3588194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
35893705ce5bSJoe Perches				}
35903705ce5bSJoe Perches			}
359100df344fSAndy Whitcroft		}
359200df344fSAndy Whitcroft		# Remove C99 comments.
35930a920b5bSAndy Whitcroft		$line =~ s@//.*@@;
35946c72ffaaSAndy Whitcroft		$opline =~ s@//.*@@;
35950a920b5bSAndy Whitcroft
35962b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
35972b474a1aSAndy Whitcroft# the whole statement.
35982b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n";
35992b474a1aSAndy Whitcroft		if (defined $realline_next &&
36002b474a1aSAndy Whitcroft		    exists $lines[$realline_next - 1] &&
36012b474a1aSAndy Whitcroft		    !defined $suppress_export{$realline_next} &&
36022b474a1aSAndy Whitcroft		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
36032b474a1aSAndy Whitcroft		     $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
36043cbf62dfSAndy Whitcroft			# Handle definitions which produce identifiers with
36053cbf62dfSAndy Whitcroft			# a prefix:
36063cbf62dfSAndy Whitcroft			#   XXX(foo);
36073cbf62dfSAndy Whitcroft			#   EXPORT_SYMBOL(something_foo);
3608653d4876SAndy Whitcroft			my $name = $1;
360987a53877SAndy Whitcroft			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
36103cbf62dfSAndy Whitcroft			    $name =~ /^${Ident}_$2/) {
36113cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n";
36123cbf62dfSAndy Whitcroft				$suppress_export{$realline_next} = 1;
36133cbf62dfSAndy Whitcroft
36143cbf62dfSAndy Whitcroft			} elsif ($stat !~ /(?:
36152b474a1aSAndy Whitcroft				\n.}\s*$|
361648012058SAndy Whitcroft				^.DEFINE_$Ident\(\Q$name\E\)|
361748012058SAndy Whitcroft				^.DECLARE_$Ident\(\Q$name\E\)|
361848012058SAndy Whitcroft				^.LIST_HEAD\(\Q$name\E\)|
36192b474a1aSAndy Whitcroft				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
36202b474a1aSAndy Whitcroft				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
362148012058SAndy Whitcroft			    )/x) {
36222b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
36232b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 2;
36242b474a1aSAndy Whitcroft			} else {
36252b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 1;
36260a920b5bSAndy Whitcroft			}
36270a920b5bSAndy Whitcroft		}
36282b474a1aSAndy Whitcroft		if (!defined $suppress_export{$linenr} &&
36292b474a1aSAndy Whitcroft		    $prevline =~ /^.\s*$/ &&
36302b474a1aSAndy Whitcroft		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
36312b474a1aSAndy Whitcroft		     $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
36322b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n";
36332b474a1aSAndy Whitcroft			$suppress_export{$linenr} = 2;
36342b474a1aSAndy Whitcroft		}
36352b474a1aSAndy Whitcroft		if (defined $suppress_export{$linenr} &&
36362b474a1aSAndy Whitcroft		    $suppress_export{$linenr} == 2) {
3637000d1cc1SJoe Perches			WARN("EXPORT_SYMBOL",
3638000d1cc1SJoe Perches			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
36392b474a1aSAndy Whitcroft		}
36400a920b5bSAndy Whitcroft
36415150bda4SJoe Eloff# check for global initialisers.
36426d32f7a3SJoe Perches		if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) {
3643d5e616fcSJoe Perches			if (ERROR("GLOBAL_INITIALISERS",
36446d32f7a3SJoe Perches				  "do not initialise globals to $1\n" . $herecurr) &&
3645d5e616fcSJoe Perches			    $fix) {
36466d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
3647d5e616fcSJoe Perches			}
3648f0a594c1SAndy Whitcroft		}
36490a920b5bSAndy Whitcroft# check for static initialisers.
36506d32f7a3SJoe Perches		if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
3651d5e616fcSJoe Perches			if (ERROR("INITIALISED_STATIC",
36526d32f7a3SJoe Perches				  "do not initialise statics to $1\n" .
3653d5e616fcSJoe Perches				      $herecurr) &&
3654d5e616fcSJoe Perches			    $fix) {
36556d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
3656d5e616fcSJoe Perches			}
36570a920b5bSAndy Whitcroft		}
36580a920b5bSAndy Whitcroft
36591813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned
36601813087dSJoe Perches		while ($sline =~ m{(\b$TypeMisordered\b)}g) {
36611813087dSJoe Perches			my $tmp = trim($1);
36621813087dSJoe Perches			WARN("MISORDERED_TYPE",
36631813087dSJoe Perches			     "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
36641813087dSJoe Perches		}
36651813087dSJoe Perches
3666cb710ecaSJoe Perches# check for static const char * arrays.
3667cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
3668000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
3669000d1cc1SJoe Perches			     "static const char * array should probably be static const char * const\n" .
3670cb710ecaSJoe Perches				$herecurr);
3671cb710ecaSJoe Perches               }
3672cb710ecaSJoe Perches
3673cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations.
3674cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
3675000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
3676000d1cc1SJoe Perches			     "static char array declaration should probably be static const char\n" .
3677cb710ecaSJoe Perches				$herecurr);
3678cb710ecaSJoe Perches               }
3679cb710ecaSJoe Perches
3680ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type
3681ab7e23f3SJoe Perches		if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
3682ab7e23f3SJoe Perches			my $found = $1;
3683ab7e23f3SJoe Perches			if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
3684ab7e23f3SJoe Perches				WARN("CONST_CONST",
3685ab7e23f3SJoe Perches				     "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
3686ab7e23f3SJoe Perches			} elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
3687ab7e23f3SJoe Perches				WARN("CONST_CONST",
3688ab7e23f3SJoe Perches				     "'const $found const' should probably be 'const $found'\n" . $herecurr);
3689ab7e23f3SJoe Perches			}
3690ab7e23f3SJoe Perches		}
3691ab7e23f3SJoe Perches
36929b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations.
36939b0fa60dSJoe Perches		if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
36949b0fa60dSJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
36959b0fa60dSJoe Perches			     "char * array declaration might be better as static const\n" .
36969b0fa60dSJoe Perches				$herecurr);
36979b0fa60dSJoe Perches               }
36989b0fa60dSJoe Perches
3699b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
3700b598b670SJoe Perches		if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
3701b598b670SJoe Perches			my $array = $1;
3702b598b670SJoe 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*\))@) {
3703b598b670SJoe Perches				my $array_div = $1;
3704b598b670SJoe Perches				if (WARN("ARRAY_SIZE",
3705b598b670SJoe Perches					 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
3706b598b670SJoe Perches				    $fix) {
3707b598b670SJoe Perches					$fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
3708b598b670SJoe Perches				}
3709b598b670SJoe Perches			}
3710b598b670SJoe Perches		}
3711b598b670SJoe Perches
3712b36190c5SJoe Perches# check for function declarations without arguments like "int foo()"
3713b36190c5SJoe Perches		if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) {
3714b36190c5SJoe Perches			if (ERROR("FUNCTION_WITHOUT_ARGS",
3715b36190c5SJoe Perches				  "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
3716b36190c5SJoe Perches			    $fix) {
3717194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
3718b36190c5SJoe Perches			}
3719b36190c5SJoe Perches		}
3720b36190c5SJoe Perches
3721653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations
3722653d4876SAndy Whitcroft# make sense.
3723653d4876SAndy Whitcroft		if ($line =~ /\btypedef\s/ &&
37248054576dSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
3725c45dcabdSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
37268ed22cadSAndy Whitcroft		    $line !~ /\b$typeTypedefs\b/ &&
372746d832f5SMichael S. Tsirkin		    $line !~ /\b__bitwise\b/) {
3728000d1cc1SJoe Perches			WARN("NEW_TYPEDEFS",
3729000d1cc1SJoe Perches			     "do not add new typedefs\n" . $herecurr);
37300a920b5bSAndy Whitcroft		}
37310a920b5bSAndy Whitcroft
37320a920b5bSAndy Whitcroft# * goes on variable not on type
373365863862SAndy Whitcroft		# (char*[ const])
3734bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
3735bfcb2cc7SAndy Whitcroft			#print "AA<$1>\n";
37363705ce5bSJoe Perches			my ($ident, $from, $to) = ($1, $2, $2);
3737d8aaf121SAndy Whitcroft
373865863862SAndy Whitcroft			# Should start with a space.
373965863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
374065863862SAndy Whitcroft			# Should not end with a space.
374165863862SAndy Whitcroft			$to =~ s/\s+$//;
374265863862SAndy Whitcroft			# '*'s should not have spaces between.
3743f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
374465863862SAndy Whitcroft			}
3745d8aaf121SAndy Whitcroft
37463705ce5bSJoe Perches##			print "1: from<$from> to<$to> ident<$ident>\n";
374765863862SAndy Whitcroft			if ($from ne $to) {
37483705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
37493705ce5bSJoe Perches					  "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
37503705ce5bSJoe Perches				    $fix) {
37513705ce5bSJoe Perches					my $sub_from = $ident;
37523705ce5bSJoe Perches					my $sub_to = $ident;
37533705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
3754194f66fcSJoe Perches					$fixed[$fixlinenr] =~
37553705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
37563705ce5bSJoe Perches				}
375765863862SAndy Whitcroft			}
3758bfcb2cc7SAndy Whitcroft		}
3759bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
3760bfcb2cc7SAndy Whitcroft			#print "BB<$1>\n";
37613705ce5bSJoe Perches			my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
3762d8aaf121SAndy Whitcroft
376365863862SAndy Whitcroft			# Should start with a space.
376465863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
376565863862SAndy Whitcroft			# Should not end with a space.
376665863862SAndy Whitcroft			$to =~ s/\s+$//;
376765863862SAndy Whitcroft			# '*'s should not have spaces between.
3768f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
376965863862SAndy Whitcroft			}
377065863862SAndy Whitcroft			# Modifiers should have spaces.
377165863862SAndy Whitcroft			$to =~ s/(\b$Modifier$)/$1 /;
377265863862SAndy Whitcroft
37733705ce5bSJoe Perches##			print "2: from<$from> to<$to> ident<$ident>\n";
3774667026e7SAndy Whitcroft			if ($from ne $to && $ident !~ /^$Modifier$/) {
37753705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
37763705ce5bSJoe Perches					  "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
37773705ce5bSJoe Perches				    $fix) {
37783705ce5bSJoe Perches
37793705ce5bSJoe Perches					my $sub_from = $match;
37803705ce5bSJoe Perches					my $sub_to = $match;
37813705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
3782194f66fcSJoe Perches					$fixed[$fixlinenr] =~
37833705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
37843705ce5bSJoe Perches				}
378565863862SAndy Whitcroft			}
37860a920b5bSAndy Whitcroft		}
37870a920b5bSAndy Whitcroft
37889d3e3c70SJoe Perches# avoid BUG() or BUG_ON()
37899d3e3c70SJoe Perches		if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
37909d3e3c70SJoe Perches			my $msg_type = \&WARN;
37919d3e3c70SJoe Perches			$msg_type = \&CHK if ($file);
37929d3e3c70SJoe Perches			&{$msg_type}("AVOID_BUG",
37939d3e3c70SJoe Perches				     "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
37949d3e3c70SJoe Perches		}
37950a920b5bSAndy Whitcroft
37969d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE
37978905a67cSAndy Whitcroft		if ($line =~ /\bLINUX_VERSION_CODE\b/) {
3798000d1cc1SJoe Perches			WARN("LINUX_VERSION_CODE",
3799000d1cc1SJoe Perches			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
38008905a67cSAndy Whitcroft		}
38018905a67cSAndy Whitcroft
380217441227SJoe Perches# check for uses of printk_ratelimit
380317441227SJoe Perches		if ($line =~ /\bprintk_ratelimit\s*\(/) {
3804000d1cc1SJoe Perches			WARN("PRINTK_RATELIMITED",
3805000d1cc1SJoe Perches			     "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
380617441227SJoe Perches		}
380717441227SJoe Perches
380800df344fSAndy Whitcroft# printk should use KERN_* levels.  Note that follow on printk's on the
380900df344fSAndy Whitcroft# same line do not need a level, so we use the current block context
381000df344fSAndy Whitcroft# to try and find and validate the current printk.  In summary the current
381125985edcSLucas De Marchi# printk includes all preceding printk's which have no newline on the end.
381200df344fSAndy Whitcroft# we assume the first bad printk is the one to report.
3813f0a594c1SAndy Whitcroft		if ($line =~ /\bprintk\((?!KERN_)\s*"/) {
381400df344fSAndy Whitcroft			my $ok = 0;
381500df344fSAndy Whitcroft			for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) {
381600df344fSAndy Whitcroft				#print "CHECK<$lines[$ln - 1]\n";
381725985edcSLucas De Marchi				# we have a preceding printk if it ends
381800df344fSAndy Whitcroft				# with "\n" ignore it, else it is to blame
381900df344fSAndy Whitcroft				if ($lines[$ln - 1] =~ m{\bprintk\(}) {
382000df344fSAndy Whitcroft					if ($rawlines[$ln - 1] !~ m{\\n"}) {
382100df344fSAndy Whitcroft						$ok = 1;
382200df344fSAndy Whitcroft					}
382300df344fSAndy Whitcroft					last;
382400df344fSAndy Whitcroft				}
382500df344fSAndy Whitcroft			}
382600df344fSAndy Whitcroft			if ($ok == 0) {
3827000d1cc1SJoe Perches				WARN("PRINTK_WITHOUT_KERN_LEVEL",
3828000d1cc1SJoe Perches				     "printk() should include KERN_ facility level\n" . $herecurr);
38290a920b5bSAndy Whitcroft			}
383000df344fSAndy Whitcroft		}
38310a920b5bSAndy Whitcroft
3832243f3803SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) {
3833243f3803SJoe Perches			my $orig = $1;
3834243f3803SJoe Perches			my $level = lc($orig);
3835243f3803SJoe Perches			$level = "warn" if ($level eq "warning");
38368f26b837SJoe Perches			my $level2 = $level;
38378f26b837SJoe Perches			$level2 = "dbg" if ($level eq "debug");
3838243f3803SJoe Perches			WARN("PREFER_PR_LEVEL",
3839daa8b059SYogesh Chaudhari			     "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(...  to printk(KERN_$orig ...\n" . $herecurr);
3840243f3803SJoe Perches		}
3841243f3803SJoe Perches
3842243f3803SJoe Perches		if ($line =~ /\bpr_warning\s*\(/) {
3843d5e616fcSJoe Perches			if (WARN("PREFER_PR_LEVEL",
3844d5e616fcSJoe Perches				 "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) &&
3845d5e616fcSJoe Perches			    $fix) {
3846194f66fcSJoe Perches				$fixed[$fixlinenr] =~
3847d5e616fcSJoe Perches				    s/\bpr_warning\b/pr_warn/;
3848d5e616fcSJoe Perches			}
3849243f3803SJoe Perches		}
3850243f3803SJoe Perches
3851dc139313SJoe Perches		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
3852dc139313SJoe Perches			my $orig = $1;
3853dc139313SJoe Perches			my $level = lc($orig);
3854dc139313SJoe Perches			$level = "warn" if ($level eq "warning");
3855dc139313SJoe Perches			$level = "dbg" if ($level eq "debug");
3856dc139313SJoe Perches			WARN("PREFER_DEV_LEVEL",
3857dc139313SJoe Perches			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
3858dc139313SJoe Perches		}
3859dc139313SJoe Perches
386091c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else.  This will have a small
386191c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at
386291c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning.
386391c9afafSAndy Lutomirski		if ($line =~ /\bENOSYS\b/) {
386491c9afafSAndy Lutomirski			WARN("ENOSYS",
386591c9afafSAndy Lutomirski			     "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
386691c9afafSAndy Lutomirski		}
386791c9afafSAndy Lutomirski
3868653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while,
3869653d4876SAndy Whitcroft# or if closed on same line
38708d182478SJoe Perches		if (($line=~/$Type\s*$Ident\(.*\).*\s*{/) and
38714e5d56bdSEddie Kovsky		    !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) {
38728d182478SJoe Perches			if (ERROR("OPEN_BRACE",
38738d182478SJoe Perches				  "open brace '{' following function declarations go on the next line\n" . $herecurr) &&
38748d182478SJoe Perches			    $fix) {
38758d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
38768d182478SJoe Perches				my $fixed_line = $rawline;
38778d182478SJoe Perches				$fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/;
38788d182478SJoe Perches				my $line1 = $1;
38798d182478SJoe Perches				my $line2 = $2;
38808d182478SJoe Perches				fix_insert_line($fixlinenr, ltrim($line1));
38818d182478SJoe Perches				fix_insert_line($fixlinenr, "\+{");
38828d182478SJoe Perches				if ($line2 !~ /^\s*$/) {
38838d182478SJoe Perches					fix_insert_line($fixlinenr, "\+\t" . trim($line2));
38848d182478SJoe Perches				}
38858d182478SJoe Perches			}
38860a920b5bSAndy Whitcroft		}
3887653d4876SAndy Whitcroft
38888905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line.
38898905a67cSAndy Whitcroft		if ($line =~ /^.\s*{/ &&
38908905a67cSAndy Whitcroft		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
38918d182478SJoe Perches			if (ERROR("OPEN_BRACE",
38928d182478SJoe Perches				  "open brace '{' following $1 go on the same line\n" . $hereprev) &&
38938d182478SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
38948d182478SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
38958d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
38968d182478SJoe Perches				my $fixedline = rtrim($prevrawline) . " {";
38978d182478SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
38988d182478SJoe Perches				$fixedline = $rawline;
3899*8d81ae05SCyril Bur				$fixedline =~ s/^(.\s*)\{\s*/$1\t/;
39008d182478SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
39018d182478SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
39028d182478SJoe Perches				}
39038d182478SJoe Perches			}
39048905a67cSAndy Whitcroft		}
39058905a67cSAndy Whitcroft
39060c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition
39073705ce5bSJoe Perches		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
39083705ce5bSJoe Perches			if (WARN("SPACING",
39093705ce5bSJoe Perches				 "missing space after $1 definition\n" . $herecurr) &&
39103705ce5bSJoe Perches			    $fix) {
3911194f66fcSJoe Perches				$fixed[$fixlinenr] =~
39123705ce5bSJoe Perches				    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
39133705ce5bSJoe Perches			}
39140c73b4ebSAndy Whitcroft		}
39150c73b4ebSAndy Whitcroft
391631070b5dSJoe Perches# Function pointer declarations
391731070b5dSJoe Perches# check spacing between type, funcptr, and args
391831070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)"
391991f72e9cSJoe Perches		if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
392031070b5dSJoe Perches			my $declare = $1;
392131070b5dSJoe Perches			my $pre_pointer_space = $2;
392231070b5dSJoe Perches			my $post_pointer_space = $3;
392331070b5dSJoe Perches			my $funcname = $4;
392431070b5dSJoe Perches			my $post_funcname_space = $5;
392531070b5dSJoe Perches			my $pre_args_space = $6;
392631070b5dSJoe Perches
392791f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type
392891f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types
392991f72e9cSJoe Perches# don't need a space so don't warn for those.
393091f72e9cSJoe Perches			my $post_declare_space = "";
393191f72e9cSJoe Perches			if ($declare =~ /(\s+)$/) {
393291f72e9cSJoe Perches				$post_declare_space = $1;
393391f72e9cSJoe Perches				$declare = rtrim($declare);
393491f72e9cSJoe Perches			}
393591f72e9cSJoe Perches			if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
393631070b5dSJoe Perches				WARN("SPACING",
393731070b5dSJoe Perches				     "missing space after return type\n" . $herecurr);
393891f72e9cSJoe Perches				$post_declare_space = " ";
393931070b5dSJoe Perches			}
394031070b5dSJoe Perches
394131070b5dSJoe Perches# unnecessary space "type  (*funcptr)(args...)"
394291f72e9cSJoe Perches# This test is not currently implemented because these declarations are
394391f72e9cSJoe Perches# equivalent to
394491f72e9cSJoe Perches#	int  foo(int bar, ...)
394591f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning.
394691f72e9cSJoe Perches#
394791f72e9cSJoe Perches#			elsif ($declare =~ /\s{2,}$/) {
394891f72e9cSJoe Perches#				WARN("SPACING",
394991f72e9cSJoe Perches#				     "Multiple spaces after return type\n" . $herecurr);
395091f72e9cSJoe Perches#			}
395131070b5dSJoe Perches
395231070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)"
395331070b5dSJoe Perches			if (defined $pre_pointer_space &&
395431070b5dSJoe Perches			    $pre_pointer_space =~ /^\s/) {
395531070b5dSJoe Perches				WARN("SPACING",
395631070b5dSJoe Perches				     "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
395731070b5dSJoe Perches			}
395831070b5dSJoe Perches
395931070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)"
396031070b5dSJoe Perches			if (defined $post_pointer_space &&
396131070b5dSJoe Perches			    $post_pointer_space =~ /^\s/) {
396231070b5dSJoe Perches				WARN("SPACING",
396331070b5dSJoe Perches				     "Unnecessary space before function pointer name\n" . $herecurr);
396431070b5dSJoe Perches			}
396531070b5dSJoe Perches
396631070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)"
396731070b5dSJoe Perches			if (defined $post_funcname_space &&
396831070b5dSJoe Perches			    $post_funcname_space =~ /^\s/) {
396931070b5dSJoe Perches				WARN("SPACING",
397031070b5dSJoe Perches				     "Unnecessary space after function pointer name\n" . $herecurr);
397131070b5dSJoe Perches			}
397231070b5dSJoe Perches
397331070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)"
397431070b5dSJoe Perches			if (defined $pre_args_space &&
397531070b5dSJoe Perches			    $pre_args_space =~ /^\s/) {
397631070b5dSJoe Perches				WARN("SPACING",
397731070b5dSJoe Perches				     "Unnecessary space before function pointer arguments\n" . $herecurr);
397831070b5dSJoe Perches			}
397931070b5dSJoe Perches
398031070b5dSJoe Perches			if (show_type("SPACING") && $fix) {
3981194f66fcSJoe Perches				$fixed[$fixlinenr] =~
398291f72e9cSJoe Perches				    s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
398331070b5dSJoe Perches			}
398431070b5dSJoe Perches		}
398531070b5dSJoe Perches
39868d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed:
39878d31cfceSAndy Whitcroft#  1. with a type on the left -- int [] a;
3988fe2a7dbcSAndy Whitcroft#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
3989fe2a7dbcSAndy Whitcroft#  3. inside a curly brace -- = { [0...10] = 5 }
39908d31cfceSAndy Whitcroft		while ($line =~ /(.*?\s)\[/g) {
39918d31cfceSAndy Whitcroft			my ($where, $prefix) = ($-[1], $1);
39928d31cfceSAndy Whitcroft			if ($prefix !~ /$Type\s+$/ &&
3993fe2a7dbcSAndy Whitcroft			    ($where != 0 || $prefix !~ /^.\s+$/) &&
3994daebc534SAndy Whitcroft			    $prefix !~ /[{,]\s+$/) {
39953705ce5bSJoe Perches				if (ERROR("BRACKET_SPACE",
39963705ce5bSJoe Perches					  "space prohibited before open square bracket '['\n" . $herecurr) &&
39973705ce5bSJoe Perches				    $fix) {
3998194f66fcSJoe Perches				    $fixed[$fixlinenr] =~
39993705ce5bSJoe Perches					s/^(\+.*?)\s+\[/$1\[/;
40003705ce5bSJoe Perches				}
40018d31cfceSAndy Whitcroft			}
40028d31cfceSAndy Whitcroft		}
40038d31cfceSAndy Whitcroft
4004f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses.
40056c72ffaaSAndy Whitcroft		while ($line =~ /($Ident)\s+\(/g) {
4006c2fdda0dSAndy Whitcroft			my $name = $1;
4007773647a0SAndy Whitcroft			my $ctx_before = substr($line, 0, $-[1]);
4008773647a0SAndy Whitcroft			my $ctx = "$ctx_before$name";
4009c2fdda0dSAndy Whitcroft
4010c2fdda0dSAndy Whitcroft			# Ignore those directives where spaces _are_ permitted.
4011773647a0SAndy Whitcroft			if ($name =~ /^(?:
4012773647a0SAndy Whitcroft				if|for|while|switch|return|case|
4013773647a0SAndy Whitcroft				volatile|__volatile__|
4014773647a0SAndy Whitcroft				__attribute__|format|__extension__|
4015773647a0SAndy Whitcroft				asm|__asm__)$/x)
4016773647a0SAndy Whitcroft			{
4017c2fdda0dSAndy Whitcroft			# cpp #define statements have non-optional spaces, ie
4018c2fdda0dSAndy Whitcroft			# if there is a space between the name and the open
4019c2fdda0dSAndy Whitcroft			# parenthesis it is simply not a parameter group.
4020c45dcabdSAndy Whitcroft			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
4021773647a0SAndy Whitcroft
4022773647a0SAndy Whitcroft			# cpp #elif statement condition may start with a (
4023c45dcabdSAndy Whitcroft			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
4024c2fdda0dSAndy Whitcroft
4025c2fdda0dSAndy Whitcroft			# If this whole things ends with a type its most
4026c2fdda0dSAndy Whitcroft			# likely a typedef for a function.
4027773647a0SAndy Whitcroft			} elsif ($ctx =~ /$Type$/) {
4028c2fdda0dSAndy Whitcroft
4029c2fdda0dSAndy Whitcroft			} else {
40303705ce5bSJoe Perches				if (WARN("SPACING",
40313705ce5bSJoe Perches					 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
40323705ce5bSJoe Perches					     $fix) {
4033194f66fcSJoe Perches					$fixed[$fixlinenr] =~
40343705ce5bSJoe Perches					    s/\b$name\s+\(/$name\(/;
40353705ce5bSJoe Perches				}
4036f0a594c1SAndy Whitcroft			}
40376c72ffaaSAndy Whitcroft		}
40389a4cad4eSEric Nelson
4039653d4876SAndy Whitcroft# Check operator spacing.
40400a920b5bSAndy Whitcroft		if (!($line=~/\#\s*include/)) {
40413705ce5bSJoe Perches			my $fixed_line = "";
40423705ce5bSJoe Perches			my $line_fixed = 0;
40433705ce5bSJoe Perches
40449c0ca6f9SAndy Whitcroft			my $ops = qr{
40459c0ca6f9SAndy Whitcroft				<<=|>>=|<=|>=|==|!=|
40469c0ca6f9SAndy Whitcroft				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
40479c0ca6f9SAndy Whitcroft				=>|->|<<|>>|<|>|=|!|~|
40481f65f947SAndy Whitcroft				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
404984731623SJoe Perches				\?:|\?|:
40509c0ca6f9SAndy Whitcroft			}x;
4051cf655043SAndy Whitcroft			my @elements = split(/($ops|;)/, $opline);
40523705ce5bSJoe Perches
40533705ce5bSJoe Perches##			print("element count: <" . $#elements . ">\n");
40543705ce5bSJoe Perches##			foreach my $el (@elements) {
40553705ce5bSJoe Perches##				print("el: <$el>\n");
40563705ce5bSJoe Perches##			}
40573705ce5bSJoe Perches
40583705ce5bSJoe Perches			my @fix_elements = ();
405900df344fSAndy Whitcroft			my $off = 0;
40606c72ffaaSAndy Whitcroft
40613705ce5bSJoe Perches			foreach my $el (@elements) {
40623705ce5bSJoe Perches				push(@fix_elements, substr($rawline, $off, length($el)));
40633705ce5bSJoe Perches				$off += length($el);
40643705ce5bSJoe Perches			}
40653705ce5bSJoe Perches
40663705ce5bSJoe Perches			$off = 0;
40673705ce5bSJoe Perches
40686c72ffaaSAndy Whitcroft			my $blank = copy_spacing($opline);
4069b34c648bSJoe Perches			my $last_after = -1;
40706c72ffaaSAndy Whitcroft
40710a920b5bSAndy Whitcroft			for (my $n = 0; $n < $#elements; $n += 2) {
40723705ce5bSJoe Perches
40733705ce5bSJoe Perches				my $good = $fix_elements[$n] . $fix_elements[$n + 1];
40743705ce5bSJoe Perches
40753705ce5bSJoe Perches##				print("n: <$n> good: <$good>\n");
40763705ce5bSJoe Perches
40774a0df2efSAndy Whitcroft				$off += length($elements[$n]);
40784a0df2efSAndy Whitcroft
407925985edcSLucas De Marchi				# Pick up the preceding and succeeding characters.
4080773647a0SAndy Whitcroft				my $ca = substr($opline, 0, $off);
4081773647a0SAndy Whitcroft				my $cc = '';
4082773647a0SAndy Whitcroft				if (length($opline) >= ($off + length($elements[$n + 1]))) {
4083773647a0SAndy Whitcroft					$cc = substr($opline, $off + length($elements[$n + 1]));
4084773647a0SAndy Whitcroft				}
4085773647a0SAndy Whitcroft				my $cb = "$ca$;$cc";
4086773647a0SAndy Whitcroft
40874a0df2efSAndy Whitcroft				my $a = '';
40884a0df2efSAndy Whitcroft				$a = 'V' if ($elements[$n] ne '');
40894a0df2efSAndy Whitcroft				$a = 'W' if ($elements[$n] =~ /\s$/);
4090cf655043SAndy Whitcroft				$a = 'C' if ($elements[$n] =~ /$;$/);
40914a0df2efSAndy Whitcroft				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
40924a0df2efSAndy Whitcroft				$a = 'O' if ($elements[$n] eq '');
4093773647a0SAndy Whitcroft				$a = 'E' if ($ca =~ /^\s*$/);
40944a0df2efSAndy Whitcroft
40950a920b5bSAndy Whitcroft				my $op = $elements[$n + 1];
40964a0df2efSAndy Whitcroft
40974a0df2efSAndy Whitcroft				my $c = '';
40980a920b5bSAndy Whitcroft				if (defined $elements[$n + 2]) {
40994a0df2efSAndy Whitcroft					$c = 'V' if ($elements[$n + 2] ne '');
41004a0df2efSAndy Whitcroft					$c = 'W' if ($elements[$n + 2] =~ /^\s/);
4101cf655043SAndy Whitcroft					$c = 'C' if ($elements[$n + 2] =~ /^$;/);
41024a0df2efSAndy Whitcroft					$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
41034a0df2efSAndy Whitcroft					$c = 'O' if ($elements[$n + 2] eq '');
41048b1b3378SAndy Whitcroft					$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
41054a0df2efSAndy Whitcroft				} else {
41064a0df2efSAndy Whitcroft					$c = 'E';
41070a920b5bSAndy Whitcroft				}
41080a920b5bSAndy Whitcroft
41094a0df2efSAndy Whitcroft				my $ctx = "${a}x${c}";
41104a0df2efSAndy Whitcroft
41114a0df2efSAndy Whitcroft				my $at = "(ctx:$ctx)";
41124a0df2efSAndy Whitcroft
41136c72ffaaSAndy Whitcroft				my $ptr = substr($blank, 0, $off) . "^";
4114de7d4f0eSAndy Whitcroft				my $hereptr = "$hereline$ptr\n";
41150a920b5bSAndy Whitcroft
411674048ed8SAndy Whitcroft				# Pull out the value of this operator.
41176c72ffaaSAndy Whitcroft				my $op_type = substr($curr_values, $off + 1, 1);
41180a920b5bSAndy Whitcroft
41191f65f947SAndy Whitcroft				# Get the full operator variant.
41201f65f947SAndy Whitcroft				my $opv = $op . substr($curr_vars, $off, 1);
41211f65f947SAndy Whitcroft
412213214adfSAndy Whitcroft				# Ignore operators passed as parameters.
412313214adfSAndy Whitcroft				if ($op_type ne 'V' &&
4124d7fe8065SSam Bobroff				    $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
412513214adfSAndy Whitcroft
4126cf655043SAndy Whitcroft#				# Ignore comments
4127cf655043SAndy Whitcroft#				} elsif ($op =~ /^$;+$/) {
412813214adfSAndy Whitcroft
4129d8aaf121SAndy Whitcroft				# ; should have either the end of line or a space or \ after it
413013214adfSAndy Whitcroft				} elsif ($op eq ';') {
4131cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEBC]/ &&
4132cf655043SAndy Whitcroft					    $cc !~ /^\\/ && $cc !~ /^;/) {
41333705ce5bSJoe Perches						if (ERROR("SPACING",
41343705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
4135b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
41363705ce5bSJoe Perches							$line_fixed = 1;
41373705ce5bSJoe Perches						}
4138d8aaf121SAndy Whitcroft					}
4139d8aaf121SAndy Whitcroft
4140d8aaf121SAndy Whitcroft				# // is a comment
4141d8aaf121SAndy Whitcroft				} elsif ($op eq '//') {
41420a920b5bSAndy Whitcroft
4143b00e4814SJoe Perches				#   :   when part of a bitfield
4144b00e4814SJoe Perches				} elsif ($opv eq ':B') {
4145b00e4814SJoe Perches					# skip the bitfield test for now
4146b00e4814SJoe Perches
41471f65f947SAndy Whitcroft				# No spaces for:
41481f65f947SAndy Whitcroft				#   ->
4149b00e4814SJoe Perches				} elsif ($op eq '->') {
41504a0df2efSAndy Whitcroft					if ($ctx =~ /Wx.|.xW/) {
41513705ce5bSJoe Perches						if (ERROR("SPACING",
41523705ce5bSJoe Perches							  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
4153b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
41543705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
41553705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
41563705ce5bSJoe Perches							}
4157b34c648bSJoe Perches							$line_fixed = 1;
41583705ce5bSJoe Perches						}
41590a920b5bSAndy Whitcroft					}
41600a920b5bSAndy Whitcroft
41612381097bSJoe Perches				# , must not have a space before and must have a space on the right.
41620a920b5bSAndy Whitcroft				} elsif ($op eq ',') {
41632381097bSJoe Perches					my $rtrim_before = 0;
41642381097bSJoe Perches					my $space_after = 0;
41652381097bSJoe Perches					if ($ctx =~ /Wx./) {
41662381097bSJoe Perches						if (ERROR("SPACING",
41672381097bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
41682381097bSJoe Perches							$line_fixed = 1;
41692381097bSJoe Perches							$rtrim_before = 1;
41702381097bSJoe Perches						}
41712381097bSJoe Perches					}
4172cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
41733705ce5bSJoe Perches						if (ERROR("SPACING",
41743705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
41753705ce5bSJoe Perches							$line_fixed = 1;
4176b34c648bSJoe Perches							$last_after = $n;
41772381097bSJoe Perches							$space_after = 1;
41782381097bSJoe Perches						}
41792381097bSJoe Perches					}
41802381097bSJoe Perches					if ($rtrim_before || $space_after) {
41812381097bSJoe Perches						if ($rtrim_before) {
41822381097bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
41832381097bSJoe Perches						} else {
41842381097bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
41852381097bSJoe Perches						}
41862381097bSJoe Perches						if ($space_after) {
41872381097bSJoe Perches							$good .= " ";
41883705ce5bSJoe Perches						}
41890a920b5bSAndy Whitcroft					}
41900a920b5bSAndy Whitcroft
41919c0ca6f9SAndy Whitcroft				# '*' as part of a type definition -- reported already.
419274048ed8SAndy Whitcroft				} elsif ($opv eq '*_') {
41939c0ca6f9SAndy Whitcroft					#warn "'*' is part of type\n";
41949c0ca6f9SAndy Whitcroft
41959c0ca6f9SAndy Whitcroft				# unary operators should have a space before and
41969c0ca6f9SAndy Whitcroft				# none after.  May be left adjacent to another
41979c0ca6f9SAndy Whitcroft				# unary operator, or a cast
41989c0ca6f9SAndy Whitcroft				} elsif ($op eq '!' || $op eq '~' ||
419974048ed8SAndy Whitcroft					 $opv eq '*U' || $opv eq '-U' ||
42000d413866SAndy Whitcroft					 $opv eq '&U' || $opv eq '&&U') {
4201cf655043SAndy Whitcroft					if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
42023705ce5bSJoe Perches						if (ERROR("SPACING",
42033705ce5bSJoe Perches							  "space required before that '$op' $at\n" . $hereptr)) {
4204b34c648bSJoe Perches							if ($n != $last_after + 2) {
4205b34c648bSJoe Perches								$good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
42063705ce5bSJoe Perches								$line_fixed = 1;
42073705ce5bSJoe Perches							}
42080a920b5bSAndy Whitcroft						}
4209b34c648bSJoe Perches					}
4210a3340b35SAndy Whitcroft					if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
4211171ae1a4SAndy Whitcroft						# A unary '*' may be const
4212171ae1a4SAndy Whitcroft
4213171ae1a4SAndy Whitcroft					} elsif ($ctx =~ /.xW/) {
42143705ce5bSJoe Perches						if (ERROR("SPACING",
42153705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
4216b34c648bSJoe Perches							$good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
42173705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
42183705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
42193705ce5bSJoe Perches							}
4220b34c648bSJoe Perches							$line_fixed = 1;
42213705ce5bSJoe Perches						}
42220a920b5bSAndy Whitcroft					}
42230a920b5bSAndy Whitcroft
42240a920b5bSAndy Whitcroft				# unary ++ and unary -- are allowed no space on one side.
42250a920b5bSAndy Whitcroft				} elsif ($op eq '++' or $op eq '--') {
4226773647a0SAndy Whitcroft					if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
42273705ce5bSJoe Perches						if (ERROR("SPACING",
42283705ce5bSJoe Perches							  "space required one side of that '$op' $at\n" . $hereptr)) {
4229b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
42303705ce5bSJoe Perches							$line_fixed = 1;
42313705ce5bSJoe Perches						}
42320a920b5bSAndy Whitcroft					}
4233773647a0SAndy Whitcroft					if ($ctx =~ /Wx[BE]/ ||
4234773647a0SAndy Whitcroft					    ($ctx =~ /Wx./ && $cc =~ /^;/)) {
42353705ce5bSJoe Perches						if (ERROR("SPACING",
42363705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
4237b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
42383705ce5bSJoe Perches							$line_fixed = 1;
42393705ce5bSJoe Perches						}
4240653d4876SAndy Whitcroft					}
4241773647a0SAndy Whitcroft					if ($ctx =~ /ExW/) {
42423705ce5bSJoe Perches						if (ERROR("SPACING",
42433705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
4244b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
42453705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
42463705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4247773647a0SAndy Whitcroft							}
4248b34c648bSJoe Perches							$line_fixed = 1;
42493705ce5bSJoe Perches						}
42503705ce5bSJoe Perches					}
42510a920b5bSAndy Whitcroft
42520a920b5bSAndy Whitcroft				# << and >> may either have or not have spaces both sides
42539c0ca6f9SAndy Whitcroft				} elsif ($op eq '<<' or $op eq '>>' or
42549c0ca6f9SAndy Whitcroft					 $op eq '&' or $op eq '^' or $op eq '|' or
42559c0ca6f9SAndy Whitcroft					 $op eq '+' or $op eq '-' or
4256c2fdda0dSAndy Whitcroft					 $op eq '*' or $op eq '/' or
4257c2fdda0dSAndy Whitcroft					 $op eq '%')
42580a920b5bSAndy Whitcroft				{
4259d2e025f3SJoe Perches					if ($check) {
4260d2e025f3SJoe Perches						if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
4261d2e025f3SJoe Perches							if (CHK("SPACING",
4262d2e025f3SJoe Perches								"spaces preferred around that '$op' $at\n" . $hereptr)) {
4263d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4264d2e025f3SJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4265d2e025f3SJoe Perches								$line_fixed = 1;
4266d2e025f3SJoe Perches							}
4267d2e025f3SJoe Perches						} elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
4268d2e025f3SJoe Perches							if (CHK("SPACING",
4269d2e025f3SJoe Perches								"space preferred before that '$op' $at\n" . $hereptr)) {
4270d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
4271d2e025f3SJoe Perches								$line_fixed = 1;
4272d2e025f3SJoe Perches							}
4273d2e025f3SJoe Perches						}
4274d2e025f3SJoe Perches					} elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
42753705ce5bSJoe Perches						if (ERROR("SPACING",
42763705ce5bSJoe Perches							  "need consistent spacing around '$op' $at\n" . $hereptr)) {
4277b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4278b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
4279b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4280b34c648bSJoe Perches							}
42813705ce5bSJoe Perches							$line_fixed = 1;
42823705ce5bSJoe Perches						}
42830a920b5bSAndy Whitcroft					}
42840a920b5bSAndy Whitcroft
42851f65f947SAndy Whitcroft				# A colon needs no spaces before when it is
42861f65f947SAndy Whitcroft				# terminating a case value or a label.
42871f65f947SAndy Whitcroft				} elsif ($opv eq ':C' || $opv eq ':L') {
42881f65f947SAndy Whitcroft					if ($ctx =~ /Wx./) {
42893705ce5bSJoe Perches						if (ERROR("SPACING",
42903705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
4291b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
42923705ce5bSJoe Perches							$line_fixed = 1;
42933705ce5bSJoe Perches						}
42941f65f947SAndy Whitcroft					}
42951f65f947SAndy Whitcroft
42960a920b5bSAndy Whitcroft				# All the others need spaces both sides.
4297cf655043SAndy Whitcroft				} elsif ($ctx !~ /[EWC]x[CWE]/) {
42981f65f947SAndy Whitcroft					my $ok = 0;
42991f65f947SAndy Whitcroft
430022f2a2efSAndy Whitcroft					# Ignore email addresses <foo@bar>
43011f65f947SAndy Whitcroft					if (($op eq '<' &&
43021f65f947SAndy Whitcroft					     $cc =~ /^\S+\@\S+>/) ||
43031f65f947SAndy Whitcroft					    ($op eq '>' &&
43041f65f947SAndy Whitcroft					     $ca =~ /<\S+\@\S+$/))
43051f65f947SAndy Whitcroft					{
43061f65f947SAndy Whitcroft					    	$ok = 1;
43071f65f947SAndy Whitcroft					}
43081f65f947SAndy Whitcroft
4309e0df7e1fSJoe Perches					# for asm volatile statements
4310e0df7e1fSJoe Perches					# ignore a colon with another
4311e0df7e1fSJoe Perches					# colon immediately before or after
4312e0df7e1fSJoe Perches					if (($op eq ':') &&
4313e0df7e1fSJoe Perches					    ($ca =~ /:$/ || $cc =~ /^:/)) {
4314e0df7e1fSJoe Perches						$ok = 1;
4315e0df7e1fSJoe Perches					}
4316e0df7e1fSJoe Perches
431784731623SJoe Perches					# messages are ERROR, but ?: are CHK
43181f65f947SAndy Whitcroft					if ($ok == 0) {
431984731623SJoe Perches						my $msg_type = \&ERROR;
432084731623SJoe Perches						$msg_type = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
432184731623SJoe Perches
432284731623SJoe Perches						if (&{$msg_type}("SPACING",
43233705ce5bSJoe Perches								 "spaces required around that '$op' $at\n" . $hereptr)) {
4324b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4325b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
4326b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4327b34c648bSJoe Perches							}
43283705ce5bSJoe Perches							$line_fixed = 1;
43293705ce5bSJoe Perches						}
43300a920b5bSAndy Whitcroft					}
433122f2a2efSAndy Whitcroft				}
43324a0df2efSAndy Whitcroft				$off += length($elements[$n + 1]);
43333705ce5bSJoe Perches
43343705ce5bSJoe Perches##				print("n: <$n> GOOD: <$good>\n");
43353705ce5bSJoe Perches
43363705ce5bSJoe Perches				$fixed_line = $fixed_line . $good;
43370a920b5bSAndy Whitcroft			}
43383705ce5bSJoe Perches
43393705ce5bSJoe Perches			if (($#elements % 2) == 0) {
43403705ce5bSJoe Perches				$fixed_line = $fixed_line . $fix_elements[$#elements];
43413705ce5bSJoe Perches			}
43423705ce5bSJoe Perches
4343194f66fcSJoe Perches			if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
4344194f66fcSJoe Perches				$fixed[$fixlinenr] = $fixed_line;
43453705ce5bSJoe Perches			}
43463705ce5bSJoe Perches
43473705ce5bSJoe Perches
43480a920b5bSAndy Whitcroft		}
43490a920b5bSAndy Whitcroft
4350786b6326SJoe Perches# check for whitespace before a non-naked semicolon
4351d2e248e7SJoe Perches		if ($line =~ /^\+.*\S\s+;\s*$/) {
4352786b6326SJoe Perches			if (WARN("SPACING",
4353786b6326SJoe Perches				 "space prohibited before semicolon\n" . $herecurr) &&
4354786b6326SJoe Perches			    $fix) {
4355194f66fcSJoe Perches				1 while $fixed[$fixlinenr] =~
4356786b6326SJoe Perches				    s/^(\+.*\S)\s+;/$1;/;
4357786b6326SJoe Perches			}
4358786b6326SJoe Perches		}
4359786b6326SJoe Perches
4360f0a594c1SAndy Whitcroft# check for multiple assignments
4361f0a594c1SAndy Whitcroft		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
4362000d1cc1SJoe Perches			CHK("MULTIPLE_ASSIGNMENTS",
4363000d1cc1SJoe Perches			    "multiple assignments should be avoided\n" . $herecurr);
4364f0a594c1SAndy Whitcroft		}
4365f0a594c1SAndy Whitcroft
436622f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration
436722f2a2efSAndy Whitcroft## # continuation.
436822f2a2efSAndy Whitcroft## 		if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
436922f2a2efSAndy Whitcroft## 		    $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
437022f2a2efSAndy Whitcroft##
437122f2a2efSAndy Whitcroft## 			# Remove any bracketed sections to ensure we do not
437222f2a2efSAndy Whitcroft## 			# falsly report the parameters of functions.
437322f2a2efSAndy Whitcroft## 			my $ln = $line;
437422f2a2efSAndy Whitcroft## 			while ($ln =~ s/\([^\(\)]*\)//g) {
437522f2a2efSAndy Whitcroft## 			}
437622f2a2efSAndy Whitcroft## 			if ($ln =~ /,/) {
4377000d1cc1SJoe Perches## 				WARN("MULTIPLE_DECLARATION",
4378000d1cc1SJoe Perches##				     "declaring multiple variables together should be avoided\n" . $herecurr);
437922f2a2efSAndy Whitcroft## 			}
438022f2a2efSAndy Whitcroft## 		}
4381f0a594c1SAndy Whitcroft
43820a920b5bSAndy Whitcroft#need space before brace following if, while, etc
43836b8c69e4SGeyslan G. Bem		if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
43844e5d56bdSEddie Kovsky		    $line =~ /do\{/) {
43853705ce5bSJoe Perches			if (ERROR("SPACING",
43863705ce5bSJoe Perches				  "space required before the open brace '{'\n" . $herecurr) &&
43873705ce5bSJoe Perches			    $fix) {
4388*8d81ae05SCyril Bur				$fixed[$fixlinenr] =~ s/^(\+.*(?:do|\)))\{/$1 {/;
43893705ce5bSJoe Perches			}
4390de7d4f0eSAndy Whitcroft		}
4391de7d4f0eSAndy Whitcroft
4392c4a62ef9SJoe Perches## # check for blank lines before declarations
4393c4a62ef9SJoe Perches##		if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
4394c4a62ef9SJoe Perches##		    $prevrawline =~ /^.\s*$/) {
4395c4a62ef9SJoe Perches##			WARN("SPACING",
4396c4a62ef9SJoe Perches##			     "No blank lines before declarations\n" . $hereprev);
4397c4a62ef9SJoe Perches##		}
4398c4a62ef9SJoe Perches##
4399c4a62ef9SJoe Perches
4400de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything
4401de7d4f0eSAndy Whitcroft# on the line
4402de7d4f0eSAndy Whitcroft		if ($line =~ /}(?!(?:,|;|\)))\S/) {
4403d5e616fcSJoe Perches			if (ERROR("SPACING",
4404d5e616fcSJoe Perches				  "space required after that close brace '}'\n" . $herecurr) &&
4405d5e616fcSJoe Perches			    $fix) {
4406194f66fcSJoe Perches				$fixed[$fixlinenr] =~
4407d5e616fcSJoe Perches				    s/}((?!(?:,|;|\)))\S)/} $1/;
4408d5e616fcSJoe Perches			}
44090a920b5bSAndy Whitcroft		}
44100a920b5bSAndy Whitcroft
441122f2a2efSAndy Whitcroft# check spacing on square brackets
441222f2a2efSAndy Whitcroft		if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
44133705ce5bSJoe Perches			if (ERROR("SPACING",
44143705ce5bSJoe Perches				  "space prohibited after that open square bracket '['\n" . $herecurr) &&
44153705ce5bSJoe Perches			    $fix) {
4416194f66fcSJoe Perches				$fixed[$fixlinenr] =~
44173705ce5bSJoe Perches				    s/\[\s+/\[/;
44183705ce5bSJoe Perches			}
441922f2a2efSAndy Whitcroft		}
442022f2a2efSAndy Whitcroft		if ($line =~ /\s\]/) {
44213705ce5bSJoe Perches			if (ERROR("SPACING",
44223705ce5bSJoe Perches				  "space prohibited before that close square bracket ']'\n" . $herecurr) &&
44233705ce5bSJoe Perches			    $fix) {
4424194f66fcSJoe Perches				$fixed[$fixlinenr] =~
44253705ce5bSJoe Perches				    s/\s+\]/\]/;
44263705ce5bSJoe Perches			}
442722f2a2efSAndy Whitcroft		}
442822f2a2efSAndy Whitcroft
4429c45dcabdSAndy Whitcroft# check spacing on parentheses
44309c0ca6f9SAndy Whitcroft		if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
44319c0ca6f9SAndy Whitcroft		    $line !~ /for\s*\(\s+;/) {
44323705ce5bSJoe Perches			if (ERROR("SPACING",
44333705ce5bSJoe Perches				  "space prohibited after that open parenthesis '('\n" . $herecurr) &&
44343705ce5bSJoe Perches			    $fix) {
4435194f66fcSJoe Perches				$fixed[$fixlinenr] =~
44363705ce5bSJoe Perches				    s/\(\s+/\(/;
44373705ce5bSJoe Perches			}
443822f2a2efSAndy Whitcroft		}
443913214adfSAndy Whitcroft		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
4440c45dcabdSAndy Whitcroft		    $line !~ /for\s*\(.*;\s+\)/ &&
4441c45dcabdSAndy Whitcroft		    $line !~ /:\s+\)/) {
44423705ce5bSJoe Perches			if (ERROR("SPACING",
44433705ce5bSJoe Perches				  "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
44443705ce5bSJoe Perches			    $fix) {
4445194f66fcSJoe Perches				$fixed[$fixlinenr] =~
44463705ce5bSJoe Perches				    s/\s+\)/\)/;
44473705ce5bSJoe Perches			}
444822f2a2efSAndy Whitcroft		}
444922f2a2efSAndy Whitcroft
4450e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals
4451e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
4452e2826fd0SJoe Perches
4453e2826fd0SJoe Perches		while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
4454ea4acbb1SJoe Perches			my $var = $1;
4455ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
4456ea4acbb1SJoe Perches				"Unnecessary parentheses around $var\n" . $herecurr) &&
4457ea4acbb1SJoe Perches			    $fix) {
4458ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
4459ea4acbb1SJoe Perches			}
4460ea4acbb1SJoe Perches		}
4461ea4acbb1SJoe Perches
4462ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses
4463ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar();
4464ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives
4465ea4acbb1SJoe Perches		if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
4466ea4acbb1SJoe Perches			my $var = $2;
4467ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
4468ea4acbb1SJoe Perches				"Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
4469ea4acbb1SJoe Perches			    $fix) {
4470ea4acbb1SJoe Perches				my $var2 = deparenthesize($var);
4471ea4acbb1SJoe Perches				$var2 =~ s/\s//g;
4472ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
4473ea4acbb1SJoe Perches			}
4474e2826fd0SJoe Perches		}
4475e2826fd0SJoe Perches
44760a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however
44774a0df2efSAndy Whitcroft		if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
44780a920b5bSAndy Whitcroft		   !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
44793705ce5bSJoe Perches			if (WARN("INDENTED_LABEL",
44803705ce5bSJoe Perches				 "labels should not be indented\n" . $herecurr) &&
44813705ce5bSJoe Perches			    $fix) {
4482194f66fcSJoe Perches				$fixed[$fixlinenr] =~
44833705ce5bSJoe Perches				    s/^(.)\s+/$1/;
44843705ce5bSJoe Perches			}
44850a920b5bSAndy Whitcroft		}
44860a920b5bSAndy Whitcroft
44875b9553abSJoe Perches# return is not a function
4488507e5141SJoe Perches		if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
4489c45dcabdSAndy Whitcroft			my $spacing = $1;
4490507e5141SJoe Perches			if ($^V && $^V ge 5.10.0 &&
44915b9553abSJoe Perches			    $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
44925b9553abSJoe Perches				my $value = $1;
44935b9553abSJoe Perches				$value = deparenthesize($value);
44945b9553abSJoe Perches				if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
4495000d1cc1SJoe Perches					ERROR("RETURN_PARENTHESES",
4496000d1cc1SJoe Perches					      "return is not a function, parentheses are not required\n" . $herecurr);
44975b9553abSJoe Perches				}
4498c45dcabdSAndy Whitcroft			} elsif ($spacing !~ /\s+/) {
4499000d1cc1SJoe Perches				ERROR("SPACING",
4500000d1cc1SJoe Perches				      "space required before the open parenthesis '('\n" . $herecurr);
4501c45dcabdSAndy Whitcroft			}
4502c45dcabdSAndy Whitcroft		}
4503507e5141SJoe Perches
4504b43ae21bSJoe Perches# unnecessary return in a void function
4505b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return;
4506b43ae21bSJoe Perches# and the line before that not a goto label target like "out:"
4507b43ae21bSJoe Perches		if ($sline =~ /^[ \+]}\s*$/ &&
4508b43ae21bSJoe Perches		    $prevline =~ /^\+\treturn\s*;\s*$/ &&
4509b43ae21bSJoe Perches		    $linenr >= 3 &&
4510b43ae21bSJoe Perches		    $lines[$linenr - 3] =~ /^[ +]/ &&
4511b43ae21bSJoe Perches		    $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
45129819cf25SJoe Perches			WARN("RETURN_VOID",
4513b43ae21bSJoe Perches			     "void function return statements are not generally useful\n" . $hereprev);
45149819cf25SJoe Perches               }
45159819cf25SJoe Perches
4516189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar))
4517189248d8SJoe Perches		if ($^V && $^V ge 5.10.0 &&
4518189248d8SJoe Perches		    $line =~ /\bif\s*((?:\(\s*){2,})/) {
4519189248d8SJoe Perches			my $openparens = $1;
4520189248d8SJoe Perches			my $count = $openparens =~ tr@\(@\(@;
4521189248d8SJoe Perches			my $msg = "";
4522189248d8SJoe Perches			if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
4523189248d8SJoe Perches				my $comp = $4;	#Not $1 because of $LvalOrFunc
4524189248d8SJoe Perches				$msg = " - maybe == should be = ?" if ($comp eq "==");
4525189248d8SJoe Perches				WARN("UNNECESSARY_PARENTHESES",
4526189248d8SJoe Perches				     "Unnecessary parentheses$msg\n" . $herecurr);
4527189248d8SJoe Perches			}
4528189248d8SJoe Perches		}
4529189248d8SJoe Perches
4530c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left
4531c5595fa2SJoe Perches#	avoid cases like "foo + BAR < baz"
4532c5595fa2SJoe Perches#	only fix matches surrounded by parentheses to avoid incorrect
4533c5595fa2SJoe Perches#	conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
4534c5595fa2SJoe Perches		if ($^V && $^V ge 5.10.0 &&
4535c5595fa2SJoe Perches		    $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
4536c5595fa2SJoe Perches			my $lead = $1;
4537c5595fa2SJoe Perches			my $const = $2;
4538c5595fa2SJoe Perches			my $comp = $3;
4539c5595fa2SJoe Perches			my $to = $4;
4540c5595fa2SJoe Perches			my $newcomp = $comp;
4541f39e1769SJoe Perches			if ($lead !~ /(?:$Operators|\.)\s*$/ &&
4542c5595fa2SJoe Perches			    $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
4543c5595fa2SJoe Perches			    WARN("CONSTANT_COMPARISON",
4544c5595fa2SJoe Perches				 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
4545c5595fa2SJoe Perches			    $fix) {
4546c5595fa2SJoe Perches				if ($comp eq "<") {
4547c5595fa2SJoe Perches					$newcomp = ">";
4548c5595fa2SJoe Perches				} elsif ($comp eq "<=") {
4549c5595fa2SJoe Perches					$newcomp = ">=";
4550c5595fa2SJoe Perches				} elsif ($comp eq ">") {
4551c5595fa2SJoe Perches					$newcomp = "<";
4552c5595fa2SJoe Perches				} elsif ($comp eq ">=") {
4553c5595fa2SJoe Perches					$newcomp = "<=";
4554c5595fa2SJoe Perches				}
4555c5595fa2SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
4556c5595fa2SJoe Perches			}
4557c5595fa2SJoe Perches		}
4558c5595fa2SJoe Perches
4559f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative
4560f34e4a4fSJoe Perches		if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
456153a3c448SAndy Whitcroft			my $name = $1;
456253a3c448SAndy Whitcroft			if ($name ne 'EOF' && $name ne 'ERROR') {
4563000d1cc1SJoe Perches				WARN("USE_NEGATIVE_ERRNO",
4564f34e4a4fSJoe Perches				     "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
456553a3c448SAndy Whitcroft			}
456653a3c448SAndy Whitcroft		}
4567c45dcabdSAndy Whitcroft
45680a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc
45694a0df2efSAndy Whitcroft		if ($line =~ /\b(if|while|for|switch)\(/) {
45703705ce5bSJoe Perches			if (ERROR("SPACING",
45713705ce5bSJoe Perches				  "space required before the open parenthesis '('\n" . $herecurr) &&
45723705ce5bSJoe Perches			    $fix) {
4573194f66fcSJoe Perches				$fixed[$fixlinenr] =~
45743705ce5bSJoe Perches				    s/\b(if|while|for|switch)\(/$1 \(/;
45753705ce5bSJoe Perches			}
45760a920b5bSAndy Whitcroft		}
45770a920b5bSAndy Whitcroft
4578f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing
4579f5fe35ddSAndy Whitcroft# statements after the conditional.
4580170d3a22SAndy Whitcroft		if ($line =~ /do\s*(?!{)/) {
45813e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
45823e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
45833e469cdcSAndy Whitcroft					if (!defined $stat);
4584170d3a22SAndy Whitcroft			my ($stat_next) = ctx_statement_block($line_nr_next,
4585170d3a22SAndy Whitcroft						$remain_next, $off_next);
4586170d3a22SAndy Whitcroft			$stat_next =~ s/\n./\n /g;
4587170d3a22SAndy Whitcroft			##print "stat<$stat> stat_next<$stat_next>\n";
4588170d3a22SAndy Whitcroft
4589170d3a22SAndy Whitcroft			if ($stat_next =~ /^\s*while\b/) {
4590170d3a22SAndy Whitcroft				# If the statement carries leading newlines,
4591170d3a22SAndy Whitcroft				# then count those as offsets.
4592170d3a22SAndy Whitcroft				my ($whitespace) =
4593170d3a22SAndy Whitcroft					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
4594170d3a22SAndy Whitcroft				my $offset =
4595170d3a22SAndy Whitcroft					statement_rawlines($whitespace) - 1;
4596170d3a22SAndy Whitcroft
4597170d3a22SAndy Whitcroft				$suppress_whiletrailers{$line_nr_next +
4598170d3a22SAndy Whitcroft								$offset} = 1;
4599170d3a22SAndy Whitcroft			}
4600170d3a22SAndy Whitcroft		}
4601170d3a22SAndy Whitcroft		if (!defined $suppress_whiletrailers{$linenr} &&
4602c11230f4SJoe Perches		    defined($stat) && defined($cond) &&
4603170d3a22SAndy Whitcroft		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
4604171ae1a4SAndy Whitcroft			my ($s, $c) = ($stat, $cond);
46058905a67cSAndy Whitcroft
4606b53c8e10SAndy Whitcroft			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
4607000d1cc1SJoe Perches				ERROR("ASSIGN_IN_IF",
4608000d1cc1SJoe Perches				      "do not use assignment in if condition\n" . $herecurr);
46098905a67cSAndy Whitcroft			}
46108905a67cSAndy Whitcroft
46118905a67cSAndy Whitcroft			# Find out what is on the end of the line after the
46128905a67cSAndy Whitcroft			# conditional.
4613773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
46148905a67cSAndy Whitcroft			$s =~ s/\n.*//g;
461513214adfSAndy Whitcroft			$s =~ s/$;//g; 	# Remove any comments
461653210168SAndy Whitcroft			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
461753210168SAndy Whitcroft			    $c !~ /}\s*while\s*/)
4618773647a0SAndy Whitcroft			{
4619bb44ad39SAndy Whitcroft				# Find out how long the conditional actually is.
4620bb44ad39SAndy Whitcroft				my @newlines = ($c =~ /\n/gs);
4621bb44ad39SAndy Whitcroft				my $cond_lines = 1 + $#newlines;
462242bdf74cSHidetoshi Seto				my $stat_real = '';
4623bb44ad39SAndy Whitcroft
462442bdf74cSHidetoshi Seto				$stat_real = raw_line($linenr, $cond_lines)
462542bdf74cSHidetoshi Seto							. "\n" if ($cond_lines);
4626bb44ad39SAndy Whitcroft				if (defined($stat_real) && $cond_lines > 1) {
4627bb44ad39SAndy Whitcroft					$stat_real = "[...]\n$stat_real";
4628bb44ad39SAndy Whitcroft				}
4629bb44ad39SAndy Whitcroft
4630000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
4631000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr . $stat_real);
46328905a67cSAndy Whitcroft			}
46338905a67cSAndy Whitcroft		}
46348905a67cSAndy Whitcroft
463513214adfSAndy Whitcroft# Check for bitwise tests written as boolean
463613214adfSAndy Whitcroft		if ($line =~ /
463713214adfSAndy Whitcroft			(?:
463813214adfSAndy Whitcroft				(?:\[|\(|\&\&|\|\|)
463913214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
464013214adfSAndy Whitcroft				(?:\&\&|\|\|)
464113214adfSAndy Whitcroft			|
464213214adfSAndy Whitcroft				(?:\&\&|\|\|)
464313214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
464413214adfSAndy Whitcroft				(?:\&\&|\|\||\)|\])
464513214adfSAndy Whitcroft			)/x)
464613214adfSAndy Whitcroft		{
4647000d1cc1SJoe Perches			WARN("HEXADECIMAL_BOOLEAN_TEST",
4648000d1cc1SJoe Perches			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
464913214adfSAndy Whitcroft		}
465013214adfSAndy Whitcroft
46518905a67cSAndy Whitcroft# if and else should not have general statements after it
465213214adfSAndy Whitcroft		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
465313214adfSAndy Whitcroft			my $s = $1;
465413214adfSAndy Whitcroft			$s =~ s/$;//g; 	# Remove any comments
465513214adfSAndy Whitcroft			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
4656000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
4657000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr);
46580a920b5bSAndy Whitcroft			}
465913214adfSAndy Whitcroft		}
466039667782SAndy Whitcroft# if should not continue a brace
466139667782SAndy Whitcroft		if ($line =~ /}\s*if\b/) {
4662000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
4663048b123fSRasmus Villemoes			      "trailing statements should be on next line (or did you mean 'else if'?)\n" .
466439667782SAndy Whitcroft				$herecurr);
466539667782SAndy Whitcroft		}
4666a1080bf8SAndy Whitcroft# case and default should not have general statements after them
4667a1080bf8SAndy Whitcroft		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
4668a1080bf8SAndy Whitcroft		    $line !~ /\G(?:
46693fef12d6SAndy Whitcroft			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
4670a1080bf8SAndy Whitcroft			\s*return\s+
4671a1080bf8SAndy Whitcroft		    )/xg)
4672a1080bf8SAndy Whitcroft		{
4673000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
4674000d1cc1SJoe Perches			      "trailing statements should be on next line\n" . $herecurr);
4675a1080bf8SAndy Whitcroft		}
46760a920b5bSAndy Whitcroft
46770a920b5bSAndy Whitcroft		# Check for }<nl>else {, these must be at the same
46780a920b5bSAndy Whitcroft		# indent level to be relevant to each other.
46798b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
46800a920b5bSAndy Whitcroft		    $previndent == $indent) {
46818b8856f4SJoe Perches			if (ERROR("ELSE_AFTER_BRACE",
46828b8856f4SJoe Perches				  "else should follow close brace '}'\n" . $hereprev) &&
46838b8856f4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
46848b8856f4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
46858b8856f4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
46868b8856f4SJoe Perches				my $fixedline = $prevrawline;
46878b8856f4SJoe Perches				$fixedline =~ s/}\s*$//;
46888b8856f4SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
46898b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
46908b8856f4SJoe Perches				}
46918b8856f4SJoe Perches				$fixedline = $rawline;
46928b8856f4SJoe Perches				$fixedline =~ s/^(.\s*)else/$1} else/;
46938b8856f4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
46948b8856f4SJoe Perches			}
46950a920b5bSAndy Whitcroft		}
46960a920b5bSAndy Whitcroft
46978b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
4698c2fdda0dSAndy Whitcroft		    $previndent == $indent) {
4699c2fdda0dSAndy Whitcroft			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
4700c2fdda0dSAndy Whitcroft
4701c2fdda0dSAndy Whitcroft			# Find out what is on the end of the line after the
4702c2fdda0dSAndy Whitcroft			# conditional.
4703773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
4704c2fdda0dSAndy Whitcroft			$s =~ s/\n.*//g;
4705c2fdda0dSAndy Whitcroft
4706c2fdda0dSAndy Whitcroft			if ($s =~ /^\s*;/) {
47078b8856f4SJoe Perches				if (ERROR("WHILE_AFTER_BRACE",
47088b8856f4SJoe Perches					  "while should follow close brace '}'\n" . $hereprev) &&
47098b8856f4SJoe Perches				    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
47108b8856f4SJoe Perches					fix_delete_line($fixlinenr - 1, $prevrawline);
47118b8856f4SJoe Perches					fix_delete_line($fixlinenr, $rawline);
47128b8856f4SJoe Perches					my $fixedline = $prevrawline;
47138b8856f4SJoe Perches					my $trailing = $rawline;
47148b8856f4SJoe Perches					$trailing =~ s/^\+//;
47158b8856f4SJoe Perches					$trailing = trim($trailing);
47168b8856f4SJoe Perches					$fixedline =~ s/}\s*$/} $trailing/;
47178b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
47188b8856f4SJoe Perches				}
4719c2fdda0dSAndy Whitcroft			}
4720c2fdda0dSAndy Whitcroft		}
4721c2fdda0dSAndy Whitcroft
472295e2c602SJoe Perches#Specific variable tests
4723323c1260SJoe Perches		while ($line =~ m{($Constant|$Lval)}g) {
4724323c1260SJoe Perches			my $var = $1;
472595e2c602SJoe Perches
472695e2c602SJoe Perches#gcc binary extension
472795e2c602SJoe Perches			if ($var =~ /^$Binary$/) {
4728d5e616fcSJoe Perches				if (WARN("GCC_BINARY_CONSTANT",
4729d5e616fcSJoe Perches					 "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) &&
4730d5e616fcSJoe Perches				    $fix) {
4731d5e616fcSJoe Perches					my $hexval = sprintf("0x%x", oct($var));
4732194f66fcSJoe Perches					$fixed[$fixlinenr] =~
4733d5e616fcSJoe Perches					    s/\b$var\b/$hexval/;
4734d5e616fcSJoe Perches				}
473595e2c602SJoe Perches			}
473695e2c602SJoe Perches
473795e2c602SJoe Perches#CamelCase
4738807bd26cSJoe Perches			if ($var !~ /^$Constant$/ &&
4739be79794bSJoe Perches			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
474022735ce8SJoe Perches#Ignore Page<foo> variants
4741807bd26cSJoe Perches			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
474222735ce8SJoe Perches#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show)
4743f5123576SJulius Werner			    $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ &&
4744f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz
4745f5123576SJulius Werner			    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
47467e781f67SJoe Perches				while ($var =~ m{($Ident)}g) {
47477e781f67SJoe Perches					my $word = $1;
47487e781f67SJoe Perches					next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
4749d8b07710SJoe Perches					if ($check) {
4750d8b07710SJoe Perches						seed_camelcase_includes();
4751d8b07710SJoe Perches						if (!$file && !$camelcase_file_seeded) {
4752d8b07710SJoe Perches							seed_camelcase_file($realfile);
4753d8b07710SJoe Perches							$camelcase_file_seeded = 1;
4754d8b07710SJoe Perches						}
4755d8b07710SJoe Perches					}
47567e781f67SJoe Perches					if (!defined $camelcase{$word}) {
47577e781f67SJoe Perches						$camelcase{$word} = 1;
4758be79794bSJoe Perches						CHK("CAMELCASE",
47597e781f67SJoe Perches						    "Avoid CamelCase: <$word>\n" . $herecurr);
47607e781f67SJoe Perches					}
4761323c1260SJoe Perches				}
4762323c1260SJoe Perches			}
47633445686aSJoe Perches		}
47640a920b5bSAndy Whitcroft
47650a920b5bSAndy Whitcroft#no spaces allowed after \ in define
4766d5e616fcSJoe Perches		if ($line =~ /\#\s*define.*\\\s+$/) {
4767d5e616fcSJoe Perches			if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
4768d5e616fcSJoe Perches				 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
4769d5e616fcSJoe Perches			    $fix) {
4770194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
4771d5e616fcSJoe Perches			}
47720a920b5bSAndy Whitcroft		}
47730a920b5bSAndy Whitcroft
47740e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
47750e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line)
4776c45dcabdSAndy Whitcroft		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
4777e09dec48SAndy Whitcroft			my $file = "$1.h";
4778e09dec48SAndy Whitcroft			my $checkfile = "include/linux/$file";
4779e09dec48SAndy Whitcroft			if (-f "$root/$checkfile" &&
4780e09dec48SAndy Whitcroft			    $realfile ne $checkfile &&
47817840a94cSWolfram Sang			    $1 !~ /$allowed_asm_includes/)
4782c45dcabdSAndy Whitcroft			{
47830e212e0aSFabian Frederick				my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
47840e212e0aSFabian Frederick				if ($asminclude > 0) {
4785e09dec48SAndy Whitcroft					if ($realfile =~ m{^arch/}) {
4786000d1cc1SJoe Perches						CHK("ARCH_INCLUDE_LINUX",
4787000d1cc1SJoe Perches						    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
4788e09dec48SAndy Whitcroft					} else {
4789000d1cc1SJoe Perches						WARN("INCLUDE_LINUX",
4790000d1cc1SJoe Perches						     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
4791e09dec48SAndy Whitcroft					}
47920a920b5bSAndy Whitcroft				}
47930a920b5bSAndy Whitcroft			}
47940e212e0aSFabian Frederick		}
47950a920b5bSAndy Whitcroft
4796653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the
4797653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed
4798cf655043SAndy Whitcroft# in a known good container
4799b8f96a31SAndy Whitcroft		if ($realfile !~ m@/vmlinux.lds.h$@ &&
4800b8f96a31SAndy Whitcroft		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
4801d8aaf121SAndy Whitcroft			my $ln = $linenr;
4802d8aaf121SAndy Whitcroft			my $cnt = $realcnt;
4803c45dcabdSAndy Whitcroft			my ($off, $dstat, $dcond, $rest);
4804c45dcabdSAndy Whitcroft			my $ctx = '';
480508a2843eSJoe Perches			my $has_flow_statement = 0;
480608a2843eSJoe Perches			my $has_arg_concat = 0;
4807c45dcabdSAndy Whitcroft			($dstat, $dcond, $ln, $cnt, $off) =
4808f74bd194SAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
4809f74bd194SAndy Whitcroft			$ctx = $dstat;
4810c45dcabdSAndy Whitcroft			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
4811a3bb97a7SAndy Whitcroft			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
4812c45dcabdSAndy Whitcroft
481308a2843eSJoe Perches			$has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
481462e15a6dSJoe Perches			$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
481508a2843eSJoe Perches
4816f59b64bfSJoe Perches			$dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
4817f59b64bfSJoe Perches			my $define_args = $1;
4818f59b64bfSJoe Perches			my $define_stmt = $dstat;
4819f59b64bfSJoe Perches			my @def_args = ();
4820f59b64bfSJoe Perches
4821f59b64bfSJoe Perches			if (defined $define_args && $define_args ne "") {
4822f59b64bfSJoe Perches				$define_args = substr($define_args, 1, length($define_args) - 2);
4823f59b64bfSJoe Perches				$define_args =~ s/\s*//g;
4824f59b64bfSJoe Perches				@def_args = split(",", $define_args);
4825f59b64bfSJoe Perches			}
4826f59b64bfSJoe Perches
4827292f1a9bSAndy Whitcroft			$dstat =~ s/$;//g;
4828c45dcabdSAndy Whitcroft			$dstat =~ s/\\\n.//g;
4829c45dcabdSAndy Whitcroft			$dstat =~ s/^\s*//s;
4830c45dcabdSAndy Whitcroft			$dstat =~ s/\s*$//s;
4831c45dcabdSAndy Whitcroft
4832c45dcabdSAndy Whitcroft			# Flatten any parentheses and braces
4833bf30d6edSAndy Whitcroft			while ($dstat =~ s/\([^\(\)]*\)/1/ ||
4834bf30d6edSAndy Whitcroft			       $dstat =~ s/\{[^\{\}]*\}/1/ ||
48356b10df42SVladimir Zapolskiy			       $dstat =~ s/.\[[^\[\]]*\]/1/)
4836bf30d6edSAndy Whitcroft			{
4837c45dcabdSAndy Whitcroft			}
4838c45dcabdSAndy Whitcroft
4839e45bab8eSAndy Whitcroft			# Flatten any obvious string concatentation.
484033acb54aSJoe Perches			while ($dstat =~ s/($String)\s*$Ident/$1/ ||
484133acb54aSJoe Perches			       $dstat =~ s/$Ident\s*($String)/$1/)
4842e45bab8eSAndy Whitcroft			{
4843e45bab8eSAndy Whitcroft			}
4844e45bab8eSAndy Whitcroft
484542e15293SJoe Perches			# Make asm volatile uses seem like a generic function
484642e15293SJoe Perches			$dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
484742e15293SJoe Perches
4848c45dcabdSAndy Whitcroft			my $exceptions = qr{
4849c45dcabdSAndy Whitcroft				$Declare|
4850c45dcabdSAndy Whitcroft				module_param_named|
4851a0a0a7a9SKees Cook				MODULE_PARM_DESC|
4852c45dcabdSAndy Whitcroft				DECLARE_PER_CPU|
4853c45dcabdSAndy Whitcroft				DEFINE_PER_CPU|
4854383099fdSAndy Whitcroft				__typeof__\(|
485522fd2d3eSStefani Seibold				union|
485622fd2d3eSStefani Seibold				struct|
4857ea71a0a0SAndy Whitcroft				\.$Ident\s*=\s*|
48586b10df42SVladimir Zapolskiy				^\"|\"$|
48596b10df42SVladimir Zapolskiy				^\[
4860c45dcabdSAndy Whitcroft			}x;
48615eaa20b9SAndy Whitcroft			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
4862f59b64bfSJoe Perches
4863f59b64bfSJoe Perches			$ctx =~ s/\n*$//;
4864f59b64bfSJoe Perches			my $herectx = $here . "\n";
4865f59b64bfSJoe Perches			my $stmt_cnt = statement_rawlines($ctx);
4866f59b64bfSJoe Perches
4867f59b64bfSJoe Perches			for (my $n = 0; $n < $stmt_cnt; $n++) {
4868f59b64bfSJoe Perches				$herectx .= raw_line($linenr, $n) . "\n";
4869f59b64bfSJoe Perches			}
4870f59b64bfSJoe Perches
4871f74bd194SAndy Whitcroft			if ($dstat ne '' &&
4872f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),
4873f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();
48743cc4b1c3SJoe Perches			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
4875356fd398SJoe Perches			    $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ &&			# character constants
4876f74bd194SAndy Whitcroft			    $dstat !~ /$exceptions/ &&
4877f74bd194SAndy Whitcroft			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
4878e942e2c3SJoe Perches			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #foo
487972f115f9SAndy Whitcroft			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
4880f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
4881f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
4882f74bd194SAndy Whitcroft			    $dstat !~ /^do\s*{/ &&					# do {...
48834e5d56bdSEddie Kovsky			    $dstat !~ /^\(\{/ &&						# ({...
4884f95a7e6aSJoe Perches			    $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
4885c45dcabdSAndy Whitcroft			{
4886e795556aSJoe Perches				if ($dstat =~ /^\s*if\b/) {
4887e795556aSJoe Perches					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
4888e795556aSJoe Perches					      "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
4889e795556aSJoe Perches				} elsif ($dstat =~ /;/) {
4890f74bd194SAndy Whitcroft					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
4891f74bd194SAndy Whitcroft					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
4892f74bd194SAndy Whitcroft				} else {
4893000d1cc1SJoe Perches					ERROR("COMPLEX_MACRO",
4894388982b5SAndrew Morton					      "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
4895d8aaf121SAndy Whitcroft				}
4896f59b64bfSJoe Perches
4897f59b64bfSJoe Perches			}
48985207649bSJoe Perches
48995207649bSJoe Perches			# Make $define_stmt single line, comment-free, etc
49005207649bSJoe Perches			my @stmt_array = split('\n', $define_stmt);
49015207649bSJoe Perches			my $first = 1;
49025207649bSJoe Perches			$define_stmt = "";
49035207649bSJoe Perches			foreach my $l (@stmt_array) {
49045207649bSJoe Perches				$l =~ s/\\$//;
49055207649bSJoe Perches				if ($first) {
49065207649bSJoe Perches					$define_stmt = $l;
49075207649bSJoe Perches					$first = 0;
49085207649bSJoe Perches				} elsif ($l =~ /^[\+ ]/) {
49095207649bSJoe Perches					$define_stmt .= substr($l, 1);
49105207649bSJoe Perches				}
49115207649bSJoe Perches			}
49125207649bSJoe Perches			$define_stmt =~ s/$;//g;
49135207649bSJoe Perches			$define_stmt =~ s/\s+/ /g;
49145207649bSJoe Perches			$define_stmt = trim($define_stmt);
49155207649bSJoe Perches
4916f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type')
4917f59b64bfSJoe Perches			foreach my $arg (@def_args) {
4918f59b64bfSJoe Perches			        next if ($arg =~ /\.\.\./);
49199192d41aSJoe Perches			        next if ($arg =~ /^type$/i);
4920f59b64bfSJoe Perches				my $tmp = $define_stmt;
4921f59b64bfSJoe Perches				$tmp =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
49225207649bSJoe Perches				$tmp =~ s/\#+\s*$arg\b//g;
4923f59b64bfSJoe Perches				$tmp =~ s/\b$arg\s*\#\#//g;
4924f59b64bfSJoe Perches				my $use_cnt = $tmp =~ s/\b$arg\b//g;
4925f59b64bfSJoe Perches				if ($use_cnt > 1) {
4926f59b64bfSJoe Perches					CHK("MACRO_ARG_REUSE",
4927f59b64bfSJoe Perches					    "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
4928f59b64bfSJoe Perches				    }
49299192d41aSJoe Perches# check if any macro arguments may have other precedence issues
49309192d41aSJoe Perches				if ($define_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
49319192d41aSJoe Perches				    ((defined($1) && $1 ne ',') ||
49329192d41aSJoe Perches				     (defined($2) && $2 ne ','))) {
49339192d41aSJoe Perches					CHK("MACRO_ARG_PRECEDENCE",
49349192d41aSJoe Perches					    "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
49359192d41aSJoe Perches				}
49360a920b5bSAndy Whitcroft			}
49375023d347SJoe Perches
493808a2843eSJoe Perches# check for macros with flow control, but without ## concatenation
493908a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those
494008a2843eSJoe Perches			if ($has_flow_statement && !$has_arg_concat) {
494108a2843eSJoe Perches				my $herectx = $here . "\n";
494208a2843eSJoe Perches				my $cnt = statement_rawlines($ctx);
494308a2843eSJoe Perches
494408a2843eSJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
494508a2843eSJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
494608a2843eSJoe Perches				}
494708a2843eSJoe Perches				WARN("MACRO_WITH_FLOW_CONTROL",
494808a2843eSJoe Perches				     "Macros with flow control statements should be avoided\n" . "$herectx");
494908a2843eSJoe Perches			}
495008a2843eSJoe Perches
4951481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm
49525023d347SJoe Perches
49535023d347SJoe Perches		} else {
49545023d347SJoe Perches			if ($prevline !~ /^..*\\$/ &&
4955481eb486SJoe Perches			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
4956481eb486SJoe Perches			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
49575023d347SJoe Perches			    $line =~ /^\+.*\\$/) {
49585023d347SJoe Perches				WARN("LINE_CONTINUATIONS",
49595023d347SJoe Perches				     "Avoid unnecessary line continuations\n" . $herecurr);
49605023d347SJoe Perches			}
4961653d4876SAndy Whitcroft		}
49620a920b5bSAndy Whitcroft
4963b13edf7fSJoe Perches# do {} while (0) macro tests:
4964b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop,
4965b13edf7fSJoe Perches# macro should not end with a semicolon
4966b13edf7fSJoe Perches		if ($^V && $^V ge 5.10.0 &&
4967b13edf7fSJoe Perches		    $realfile !~ m@/vmlinux.lds.h$@ &&
4968b13edf7fSJoe Perches		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
4969b13edf7fSJoe Perches			my $ln = $linenr;
4970b13edf7fSJoe Perches			my $cnt = $realcnt;
4971b13edf7fSJoe Perches			my ($off, $dstat, $dcond, $rest);
4972b13edf7fSJoe Perches			my $ctx = '';
4973b13edf7fSJoe Perches			($dstat, $dcond, $ln, $cnt, $off) =
4974b13edf7fSJoe Perches				ctx_statement_block($linenr, $realcnt, 0);
4975b13edf7fSJoe Perches			$ctx = $dstat;
4976b13edf7fSJoe Perches
4977b13edf7fSJoe Perches			$dstat =~ s/\\\n.//g;
49781b36b201SJoe Perches			$dstat =~ s/$;/ /g;
4979b13edf7fSJoe Perches
4980b13edf7fSJoe Perches			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
4981b13edf7fSJoe Perches				my $stmts = $2;
4982b13edf7fSJoe Perches				my $semis = $3;
4983b13edf7fSJoe Perches
4984b13edf7fSJoe Perches				$ctx =~ s/\n*$//;
4985b13edf7fSJoe Perches				my $cnt = statement_rawlines($ctx);
4986b13edf7fSJoe Perches				my $herectx = $here . "\n";
4987b13edf7fSJoe Perches
4988b13edf7fSJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
4989b13edf7fSJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
4990b13edf7fSJoe Perches				}
4991b13edf7fSJoe Perches
4992ac8e97f8SJoe Perches				if (($stmts =~ tr/;/;/) == 1 &&
4993ac8e97f8SJoe Perches				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
4994b13edf7fSJoe Perches					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
4995b13edf7fSJoe Perches					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
4996b13edf7fSJoe Perches				}
4997b13edf7fSJoe Perches				if (defined $semis && $semis ne "") {
4998b13edf7fSJoe Perches					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
4999b13edf7fSJoe Perches					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
5000b13edf7fSJoe Perches				}
5001f5ef95b1SJoe Perches			} elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
5002f5ef95b1SJoe Perches				$ctx =~ s/\n*$//;
5003f5ef95b1SJoe Perches				my $cnt = statement_rawlines($ctx);
5004f5ef95b1SJoe Perches				my $herectx = $here . "\n";
5005f5ef95b1SJoe Perches
5006f5ef95b1SJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
5007f5ef95b1SJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
5008f5ef95b1SJoe Perches				}
5009f5ef95b1SJoe Perches
5010f5ef95b1SJoe Perches				WARN("TRAILING_SEMICOLON",
5011f5ef95b1SJoe Perches				     "macros should not use a trailing semicolon\n" . "$herectx");
5012b13edf7fSJoe Perches			}
5013b13edf7fSJoe Perches		}
5014b13edf7fSJoe Perches
5015080ba929SMike Frysinger# make sure symbols are always wrapped with VMLINUX_SYMBOL() ...
5016080ba929SMike Frysinger# all assignments may have only one of the following with an assignment:
5017080ba929SMike Frysinger#	.
5018080ba929SMike Frysinger#	ALIGN(...)
5019080ba929SMike Frysinger#	VMLINUX_SYMBOL(...)
5020080ba929SMike Frysinger		if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) {
5021000d1cc1SJoe Perches			WARN("MISSING_VMLINUX_SYMBOL",
5022000d1cc1SJoe Perches			     "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr);
5023080ba929SMike Frysinger		}
5024080ba929SMike Frysinger
5025f0a594c1SAndy Whitcroft# check for redundant bracing round if etc
502613214adfSAndy Whitcroft		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
502713214adfSAndy Whitcroft			my ($level, $endln, @chunks) =
5028cf655043SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, 1);
502913214adfSAndy Whitcroft			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
5030cf655043SAndy Whitcroft			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
5031cf655043SAndy Whitcroft			if ($#chunks > 0 && $level == 0) {
5032aad4f614SJoe Perches				my @allowed = ();
5033aad4f614SJoe Perches				my $allow = 0;
503413214adfSAndy Whitcroft				my $seen = 0;
5035773647a0SAndy Whitcroft				my $herectx = $here . "\n";
5036cf655043SAndy Whitcroft				my $ln = $linenr - 1;
503713214adfSAndy Whitcroft				for my $chunk (@chunks) {
503813214adfSAndy Whitcroft					my ($cond, $block) = @{$chunk};
503913214adfSAndy Whitcroft
5040773647a0SAndy Whitcroft					# If the condition carries leading newlines, then count those as offsets.
5041773647a0SAndy Whitcroft					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
5042773647a0SAndy Whitcroft					my $offset = statement_rawlines($whitespace) - 1;
5043773647a0SAndy Whitcroft
5044aad4f614SJoe Perches					$allowed[$allow] = 0;
5045773647a0SAndy Whitcroft					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
5046773647a0SAndy Whitcroft
5047773647a0SAndy Whitcroft					# We have looked at and allowed this specific line.
5048773647a0SAndy Whitcroft					$suppress_ifbraces{$ln + $offset} = 1;
5049773647a0SAndy Whitcroft
5050773647a0SAndy Whitcroft					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
5051cf655043SAndy Whitcroft					$ln += statement_rawlines($block) - 1;
5052cf655043SAndy Whitcroft
5053773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
505413214adfSAndy Whitcroft
505513214adfSAndy Whitcroft					$seen++ if ($block =~ /^\s*{/);
505613214adfSAndy Whitcroft
5057aad4f614SJoe Perches					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
5058cf655043SAndy Whitcroft					if (statement_lines($cond) > 1) {
5059cf655043SAndy Whitcroft						#print "APW: ALLOWED: cond<$cond>\n";
5060aad4f614SJoe Perches						$allowed[$allow] = 1;
506113214adfSAndy Whitcroft					}
506213214adfSAndy Whitcroft					if ($block =~/\b(?:if|for|while)\b/) {
5063cf655043SAndy Whitcroft						#print "APW: ALLOWED: block<$block>\n";
5064aad4f614SJoe Perches						$allowed[$allow] = 1;
506513214adfSAndy Whitcroft					}
5066cf655043SAndy Whitcroft					if (statement_block_size($block) > 1) {
5067cf655043SAndy Whitcroft						#print "APW: ALLOWED: lines block<$block>\n";
5068aad4f614SJoe Perches						$allowed[$allow] = 1;
506913214adfSAndy Whitcroft					}
5070aad4f614SJoe Perches					$allow++;
507113214adfSAndy Whitcroft				}
5072aad4f614SJoe Perches				if ($seen) {
5073aad4f614SJoe Perches					my $sum_allowed = 0;
5074aad4f614SJoe Perches					foreach (@allowed) {
5075aad4f614SJoe Perches						$sum_allowed += $_;
5076aad4f614SJoe Perches					}
5077aad4f614SJoe Perches					if ($sum_allowed == 0) {
5078000d1cc1SJoe Perches						WARN("BRACES",
5079000d1cc1SJoe Perches						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
5080aad4f614SJoe Perches					} elsif ($sum_allowed != $allow &&
5081aad4f614SJoe Perches						 $seen != $allow) {
5082aad4f614SJoe Perches						CHK("BRACES",
5083aad4f614SJoe Perches						    "braces {} should be used on all arms of this statement\n" . $herectx);
5084aad4f614SJoe Perches					}
508513214adfSAndy Whitcroft				}
508613214adfSAndy Whitcroft			}
508713214adfSAndy Whitcroft		}
5088773647a0SAndy Whitcroft		if (!defined $suppress_ifbraces{$linenr - 1} &&
508913214adfSAndy Whitcroft					$line =~ /\b(if|while|for|else)\b/) {
5090cf655043SAndy Whitcroft			my $allowed = 0;
5091f0a594c1SAndy Whitcroft
5092cf655043SAndy Whitcroft			# Check the pre-context.
5093cf655043SAndy Whitcroft			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
5094cf655043SAndy Whitcroft				#print "APW: ALLOWED: pre<$1>\n";
5095cf655043SAndy Whitcroft				$allowed = 1;
5096f0a594c1SAndy Whitcroft			}
5097773647a0SAndy Whitcroft
5098773647a0SAndy Whitcroft			my ($level, $endln, @chunks) =
5099773647a0SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, $-[0]);
5100773647a0SAndy Whitcroft
5101cf655043SAndy Whitcroft			# Check the condition.
5102cf655043SAndy Whitcroft			my ($cond, $block) = @{$chunks[0]};
5103773647a0SAndy Whitcroft			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
5104cf655043SAndy Whitcroft			if (defined $cond) {
5105773647a0SAndy Whitcroft				substr($block, 0, length($cond), '');
5106cf655043SAndy Whitcroft			}
5107cf655043SAndy Whitcroft			if (statement_lines($cond) > 1) {
5108cf655043SAndy Whitcroft				#print "APW: ALLOWED: cond<$cond>\n";
5109cf655043SAndy Whitcroft				$allowed = 1;
5110cf655043SAndy Whitcroft			}
5111cf655043SAndy Whitcroft			if ($block =~/\b(?:if|for|while)\b/) {
5112cf655043SAndy Whitcroft				#print "APW: ALLOWED: block<$block>\n";
5113cf655043SAndy Whitcroft				$allowed = 1;
5114cf655043SAndy Whitcroft			}
5115cf655043SAndy Whitcroft			if (statement_block_size($block) > 1) {
5116cf655043SAndy Whitcroft				#print "APW: ALLOWED: lines block<$block>\n";
5117cf655043SAndy Whitcroft				$allowed = 1;
5118cf655043SAndy Whitcroft			}
5119cf655043SAndy Whitcroft			# Check the post-context.
5120cf655043SAndy Whitcroft			if (defined $chunks[1]) {
5121cf655043SAndy Whitcroft				my ($cond, $block) = @{$chunks[1]};
5122cf655043SAndy Whitcroft				if (defined $cond) {
5123773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
5124cf655043SAndy Whitcroft				}
5125cf655043SAndy Whitcroft				if ($block =~ /^\s*\{/) {
5126cf655043SAndy Whitcroft					#print "APW: ALLOWED: chunk-1 block<$block>\n";
5127cf655043SAndy Whitcroft					$allowed = 1;
5128cf655043SAndy Whitcroft				}
5129cf655043SAndy Whitcroft			}
5130cf655043SAndy Whitcroft			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
513169932487SJustin P. Mattock				my $herectx = $here . "\n";
5132f055663cSAndy Whitcroft				my $cnt = statement_rawlines($block);
5133cf655043SAndy Whitcroft
5134f055663cSAndy Whitcroft				for (my $n = 0; $n < $cnt; $n++) {
513569932487SJustin P. Mattock					$herectx .= raw_line($linenr, $n) . "\n";
5136cf655043SAndy Whitcroft				}
5137cf655043SAndy Whitcroft
5138000d1cc1SJoe Perches				WARN("BRACES",
5139000d1cc1SJoe Perches				     "braces {} are not necessary for single statement blocks\n" . $herectx);
5140f0a594c1SAndy Whitcroft			}
5141f0a594c1SAndy Whitcroft		}
5142f0a594c1SAndy Whitcroft
5143e4c5babdSJoe Perches# check for single line unbalanced braces
514495330473SSven Eckelmann		if ($sline =~ /^.\s*\}\s*else\s*$/ ||
514595330473SSven Eckelmann		    $sline =~ /^.\s*else\s*\{\s*$/) {
5146e4c5babdSJoe Perches			CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
5147e4c5babdSJoe Perches		}
5148e4c5babdSJoe Perches
51490979ae66SJoe Perches# check for unnecessary blank lines around braces
515077b9a53aSJoe Perches		if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
5151f8e58219SJoe Perches			if (CHK("BRACES",
5152f8e58219SJoe Perches				"Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
5153f8e58219SJoe Perches			    $fix && $prevrawline =~ /^\+/) {
5154f8e58219SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
5155f8e58219SJoe Perches			}
51560979ae66SJoe Perches		}
515777b9a53aSJoe Perches		if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
5158f8e58219SJoe Perches			if (CHK("BRACES",
5159f8e58219SJoe Perches				"Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
5160f8e58219SJoe Perches			    $fix) {
5161f8e58219SJoe Perches				fix_delete_line($fixlinenr, $rawline);
5162f8e58219SJoe Perches			}
51630979ae66SJoe Perches		}
51640979ae66SJoe Perches
51654a0df2efSAndy Whitcroft# no volatiles please
51666c72ffaaSAndy Whitcroft		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
51676c72ffaaSAndy Whitcroft		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
5168000d1cc1SJoe Perches			WARN("VOLATILE",
51698c27ceffSMauro Carvalho Chehab			     "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
51704a0df2efSAndy Whitcroft		}
51714a0df2efSAndy Whitcroft
51725e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability
51735e4f6ba5SJoe Perches# to grep for the string.  Make exceptions when the previous string ends in a
51745e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
51755e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
517633acb54aSJoe Perches		if ($line =~ /^\+\s*$String/ &&
51775e4f6ba5SJoe Perches		    $prevline =~ /"\s*$/ &&
51785e4f6ba5SJoe Perches		    $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
51795e4f6ba5SJoe Perches			if (WARN("SPLIT_STRING",
51805e4f6ba5SJoe Perches				 "quoted string split across lines\n" . $hereprev) &&
51815e4f6ba5SJoe Perches				     $fix &&
51825e4f6ba5SJoe Perches				     $prevrawline =~ /^\+.*"\s*$/ &&
51835e4f6ba5SJoe Perches				     $last_coalesced_string_linenr != $linenr - 1) {
51845e4f6ba5SJoe Perches				my $extracted_string = get_quoted_string($line, $rawline);
51855e4f6ba5SJoe Perches				my $comma_close = "";
51865e4f6ba5SJoe Perches				if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
51875e4f6ba5SJoe Perches					$comma_close = $1;
51885e4f6ba5SJoe Perches				}
51895e4f6ba5SJoe Perches
51905e4f6ba5SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
51915e4f6ba5SJoe Perches				fix_delete_line($fixlinenr, $rawline);
51925e4f6ba5SJoe Perches				my $fixedline = $prevrawline;
51935e4f6ba5SJoe Perches				$fixedline =~ s/"\s*$//;
51945e4f6ba5SJoe Perches				$fixedline .= substr($extracted_string, 1) . trim($comma_close);
51955e4f6ba5SJoe Perches				fix_insert_line($fixlinenr - 1, $fixedline);
51965e4f6ba5SJoe Perches				$fixedline = $rawline;
51975e4f6ba5SJoe Perches				$fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
51985e4f6ba5SJoe Perches				if ($fixedline !~ /\+\s*$/) {
51995e4f6ba5SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
52005e4f6ba5SJoe Perches				}
52015e4f6ba5SJoe Perches				$last_coalesced_string_linenr = $linenr;
52025e4f6ba5SJoe Perches			}
52035e4f6ba5SJoe Perches		}
52045e4f6ba5SJoe Perches
52055e4f6ba5SJoe Perches# check for missing a space in a string concatenation
52065e4f6ba5SJoe Perches		if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
52075e4f6ba5SJoe Perches			WARN('MISSING_SPACE',
52085e4f6ba5SJoe Perches			     "break quoted strings at a space character\n" . $hereprev);
52095e4f6ba5SJoe Perches		}
52105e4f6ba5SJoe Perches
521177cb8546SJoe Perches# check for an embedded function name in a string when the function is known
5212e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch
5213e4b7d309SJoe Perches# context providing the function name or a single line form for in-file
5214e4b7d309SJoe Perches# function declarations
521577cb8546SJoe Perches		if ($line =~ /^\+.*$String/ &&
521677cb8546SJoe Perches		    defined($context_function) &&
5217e4b7d309SJoe Perches		    get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
5218e4b7d309SJoe Perches		    length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
521977cb8546SJoe Perches			WARN("EMBEDDED_FUNCTION_NAME",
5220e4b7d309SJoe Perches			     "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
522177cb8546SJoe Perches		}
522277cb8546SJoe Perches
52235e4f6ba5SJoe Perches# check for spaces before a quoted newline
52245e4f6ba5SJoe Perches		if ($rawline =~ /^.*\".*\s\\n/) {
52255e4f6ba5SJoe Perches			if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
52265e4f6ba5SJoe Perches				 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
52275e4f6ba5SJoe Perches			    $fix) {
52285e4f6ba5SJoe Perches				$fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
52295e4f6ba5SJoe Perches			}
52305e4f6ba5SJoe Perches
52315e4f6ba5SJoe Perches		}
52325e4f6ba5SJoe Perches
5233f17dba4fSJoe Perches# concatenated string without spaces between elements
523433acb54aSJoe Perches		if ($line =~ /$String[A-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) {
5235f17dba4fSJoe Perches			CHK("CONCATENATED_STRING",
5236f17dba4fSJoe Perches			    "Concatenated strings should use spaces between elements\n" . $herecurr);
5237f17dba4fSJoe Perches		}
5238f17dba4fSJoe Perches
523990ad30e5SJoe Perches# uncoalesced string fragments
524033acb54aSJoe Perches		if ($line =~ /$String\s*"/) {
524190ad30e5SJoe Perches			WARN("STRING_FRAGMENTS",
524290ad30e5SJoe Perches			     "Consecutive strings are generally better as a single string\n" . $herecurr);
524390ad30e5SJoe Perches		}
524490ad30e5SJoe Perches
5245522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats
5246522b837cSAlexey Dobriyan		my $show_L = 1;	#don't show the same defect twice
5247522b837cSAlexey Dobriyan		my $show_Z = 1;
52485e4f6ba5SJoe Perches		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
5249522b837cSAlexey Dobriyan			my $string = substr($rawline, $-[1], $+[1] - $-[1]);
52505e4f6ba5SJoe Perches			$string =~ s/%%/__/g;
5251522b837cSAlexey Dobriyan			# check for %L
5252522b837cSAlexey Dobriyan			if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
52535e4f6ba5SJoe Perches				WARN("PRINTF_L",
5254522b837cSAlexey Dobriyan				     "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
5255522b837cSAlexey Dobriyan				$show_L = 0;
52565e4f6ba5SJoe Perches			}
5257522b837cSAlexey Dobriyan			# check for %Z
5258522b837cSAlexey Dobriyan			if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
5259522b837cSAlexey Dobriyan				WARN("PRINTF_Z",
5260522b837cSAlexey Dobriyan				     "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
5261522b837cSAlexey Dobriyan				$show_Z = 0;
5262522b837cSAlexey Dobriyan			}
5263522b837cSAlexey Dobriyan			# check for 0x<decimal>
5264522b837cSAlexey Dobriyan			if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
5265522b837cSAlexey Dobriyan				ERROR("PRINTF_0XDECIMAL",
52666e300757SJoe Perches				      "Prefixing 0x with decimal output is defective\n" . $herecurr);
52676e300757SJoe Perches			}
52685e4f6ba5SJoe Perches		}
52695e4f6ba5SJoe Perches
52705e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of "
52715e4f6ba5SJoe Perches		if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) {
52725e4f6ba5SJoe Perches			WARN("LINE_CONTINUATIONS",
52735e4f6ba5SJoe Perches			     "Avoid line continuations in quoted strings\n" . $herecurr);
52745e4f6ba5SJoe Perches		}
52755e4f6ba5SJoe Perches
527600df344fSAndy Whitcroft# warn about #if 0
5277c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
5278000d1cc1SJoe Perches			CHK("REDUNDANT_CODE",
5279000d1cc1SJoe Perches			    "if this code is redundant consider removing it\n" .
5280de7d4f0eSAndy Whitcroft				$herecurr);
52814a0df2efSAndy Whitcroft		}
52824a0df2efSAndy Whitcroft
528303df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses
528403df4b51SAndy Whitcroft		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
5285100425deSJoe Perches			my $tested = quotemeta($1);
5286100425deSJoe Perches			my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
5287100425deSJoe Perches			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
5288100425deSJoe Perches				my $func = $1;
5289100425deSJoe Perches				if (WARN('NEEDLESS_IF',
5290100425deSJoe Perches					 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
5291100425deSJoe Perches				    $fix) {
5292100425deSJoe Perches					my $do_fix = 1;
5293100425deSJoe Perches					my $leading_tabs = "";
5294100425deSJoe Perches					my $new_leading_tabs = "";
5295100425deSJoe Perches					if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
5296100425deSJoe Perches						$leading_tabs = $1;
5297100425deSJoe Perches					} else {
5298100425deSJoe Perches						$do_fix = 0;
5299100425deSJoe Perches					}
5300100425deSJoe Perches					if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
5301100425deSJoe Perches						$new_leading_tabs = $1;
5302100425deSJoe Perches						if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
5303100425deSJoe Perches							$do_fix = 0;
5304100425deSJoe Perches						}
5305100425deSJoe Perches					} else {
5306100425deSJoe Perches						$do_fix = 0;
5307100425deSJoe Perches					}
5308100425deSJoe Perches					if ($do_fix) {
5309100425deSJoe Perches						fix_delete_line($fixlinenr - 1, $prevrawline);
5310100425deSJoe Perches						$fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
5311100425deSJoe Perches					}
5312100425deSJoe Perches				}
53134c432a8fSGreg Kroah-Hartman			}
53144c432a8fSGreg Kroah-Hartman		}
5315f0a594c1SAndy Whitcroft
5316ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages
5317ebfdc409SJoe Perches		if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
5318ebfdc409SJoe Perches		    $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
5319ebfdc409SJoe Perches		    (defined $1 || defined $3) &&
5320ebfdc409SJoe Perches		    $linenr > 3) {
5321ebfdc409SJoe Perches			my $testval = $2;
5322ebfdc409SJoe Perches			my $testline = $lines[$linenr - 3];
5323ebfdc409SJoe Perches
5324ebfdc409SJoe Perches			my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
5325ebfdc409SJoe Perches#			print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
5326ebfdc409SJoe Perches
5327fb0d0e08SJoe Perches			if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|kmemdup|(?:dev_)?alloc_skb)/) {
5328ebfdc409SJoe Perches				WARN("OOM_MESSAGE",
5329ebfdc409SJoe Perches				     "Possible unnecessary 'out of memory' message\n" . $hereprev);
5330ebfdc409SJoe Perches			}
5331ebfdc409SJoe Perches		}
5332ebfdc409SJoe Perches
5333f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL>
5334dcaf1123SPaolo Bonzini		if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
5335f78d98f6SJoe Perches		    $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
5336f78d98f6SJoe Perches			my $level = $1;
5337f78d98f6SJoe Perches			if (WARN("UNNECESSARY_KERN_LEVEL",
5338f78d98f6SJoe Perches				 "Possible unnecessary $level\n" . $herecurr) &&
5339f78d98f6SJoe Perches			    $fix) {
5340f78d98f6SJoe Perches				$fixed[$fixlinenr] =~ s/\s*$level\s*//;
5341f78d98f6SJoe Perches			}
5342f78d98f6SJoe Perches		}
5343f78d98f6SJoe Perches
534445c55e92SJoe Perches# check for logging continuations
534545c55e92SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
534645c55e92SJoe Perches			WARN("LOGGING_CONTINUATION",
534745c55e92SJoe Perches			     "Avoid logging continuation uses where feasible\n" . $herecurr);
534845c55e92SJoe Perches		}
534945c55e92SJoe Perches
5350abb08a53SJoe Perches# check for mask then right shift without a parentheses
5351abb08a53SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5352abb08a53SJoe Perches		    $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
5353abb08a53SJoe Perches		    $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
5354abb08a53SJoe Perches			WARN("MASK_THEN_SHIFT",
5355abb08a53SJoe Perches			     "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
5356abb08a53SJoe Perches		}
5357abb08a53SJoe Perches
5358b75ac618SJoe Perches# check for pointer comparisons to NULL
5359b75ac618SJoe Perches		if ($^V && $^V ge 5.10.0) {
5360b75ac618SJoe Perches			while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
5361b75ac618SJoe Perches				my $val = $1;
5362b75ac618SJoe Perches				my $equal = "!";
5363b75ac618SJoe Perches				$equal = "" if ($4 eq "!=");
5364b75ac618SJoe Perches				if (CHK("COMPARISON_TO_NULL",
5365b75ac618SJoe Perches					"Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
5366b75ac618SJoe Perches					    $fix) {
5367b75ac618SJoe Perches					$fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
5368b75ac618SJoe Perches				}
5369b75ac618SJoe Perches			}
5370b75ac618SJoe Perches		}
5371b75ac618SJoe Perches
53728716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata)
53738716de38SJoe Perches		if ($line =~ /(\b$InitAttribute\b)/) {
53748716de38SJoe Perches			my $attr = $1;
53758716de38SJoe Perches			if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
53768716de38SJoe Perches				my $ptr = $1;
53778716de38SJoe Perches				my $var = $2;
53788716de38SJoe Perches				if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
53798716de38SJoe Perches				      ERROR("MISPLACED_INIT",
53808716de38SJoe Perches					    "$attr should be placed after $var\n" . $herecurr)) ||
53818716de38SJoe Perches				     ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
53828716de38SJoe Perches				      WARN("MISPLACED_INIT",
53838716de38SJoe Perches					   "$attr should be placed after $var\n" . $herecurr))) &&
53848716de38SJoe Perches				    $fix) {
5385194f66fcSJoe 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;
53868716de38SJoe Perches				}
53878716de38SJoe Perches			}
53888716de38SJoe Perches		}
53898716de38SJoe Perches
5390e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const
5391e970b884SJoe Perches		if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
5392e970b884SJoe Perches			my $attr = $1;
5393e970b884SJoe Perches			$attr =~ /($InitAttributePrefix)(.*)/;
5394e970b884SJoe Perches			my $attr_prefix = $1;
5395e970b884SJoe Perches			my $attr_type = $2;
5396e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
5397e970b884SJoe Perches				  "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
5398e970b884SJoe Perches			    $fix) {
5399194f66fcSJoe Perches				$fixed[$fixlinenr] =~
5400e970b884SJoe Perches				    s/$InitAttributeData/${attr_prefix}initconst/;
5401e970b884SJoe Perches			}
5402e970b884SJoe Perches		}
5403e970b884SJoe Perches
5404e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const
5405e970b884SJoe Perches		if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
5406e970b884SJoe Perches			my $attr = $1;
5407e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
5408e970b884SJoe Perches				  "Use of $attr requires a separate use of const\n" . $herecurr) &&
5409e970b884SJoe Perches			    $fix) {
5410194f66fcSJoe Perches				my $lead = $fixed[$fixlinenr] =~
5411e970b884SJoe Perches				    /(^\+\s*(?:static\s+))/;
5412e970b884SJoe Perches				$lead = rtrim($1);
5413e970b884SJoe Perches				$lead = "$lead " if ($lead !~ /^\+$/);
5414e970b884SJoe Perches				$lead = "${lead}const ";
5415194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
5416e970b884SJoe Perches			}
5417e970b884SJoe Perches		}
5418e970b884SJoe Perches
5419c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const)
5420c17893c7SJoe Perches		if ($line =~ /\b__read_mostly\b/ &&
5421c17893c7SJoe Perches		    $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
5422c17893c7SJoe Perches			if (ERROR("CONST_READ_MOSTLY",
5423c17893c7SJoe Perches				  "Invalid use of __read_mostly with const type\n" . $herecurr) &&
5424c17893c7SJoe Perches			    $fix) {
5425c17893c7SJoe Perches				$fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
5426c17893c7SJoe Perches			}
5427c17893c7SJoe Perches		}
5428c17893c7SJoe Perches
5429fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/
5430fbdb8138SJoe Perches		if ($realfile !~ m@^include/uapi/@ &&
5431fbdb8138SJoe Perches		    $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
5432fbdb8138SJoe Perches			my $constant_func = $1;
5433fbdb8138SJoe Perches			my $func = $constant_func;
5434fbdb8138SJoe Perches			$func =~ s/^__constant_//;
5435fbdb8138SJoe Perches			if (WARN("CONSTANT_CONVERSION",
5436fbdb8138SJoe Perches				 "$constant_func should be $func\n" . $herecurr) &&
5437fbdb8138SJoe Perches			    $fix) {
5438194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
5439fbdb8138SJoe Perches			}
5440fbdb8138SJoe Perches		}
5441fbdb8138SJoe Perches
54421a15a250SPatrick Pannuto# prefer usleep_range over udelay
544337581c28SBruce Allan		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
544443c1d77cSJoe Perches			my $delay = $1;
54451a15a250SPatrick Pannuto			# ignore udelay's < 10, however
544643c1d77cSJoe Perches			if (! ($delay < 10) ) {
5447000d1cc1SJoe Perches				CHK("USLEEP_RANGE",
544843c1d77cSJoe Perches				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr);
544943c1d77cSJoe Perches			}
545043c1d77cSJoe Perches			if ($delay > 2000) {
545143c1d77cSJoe Perches				WARN("LONG_UDELAY",
545243c1d77cSJoe Perches				     "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
54531a15a250SPatrick Pannuto			}
54541a15a250SPatrick Pannuto		}
54551a15a250SPatrick Pannuto
545609ef8725SPatrick Pannuto# warn about unexpectedly long msleep's
545709ef8725SPatrick Pannuto		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
545809ef8725SPatrick Pannuto			if ($1 < 20) {
5459000d1cc1SJoe Perches				WARN("MSLEEP",
546043c1d77cSJoe Perches				     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr);
546109ef8725SPatrick Pannuto			}
546209ef8725SPatrick Pannuto		}
546309ef8725SPatrick Pannuto
546436ec1939SJoe Perches# check for comparisons of jiffies
546536ec1939SJoe Perches		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
546636ec1939SJoe Perches			WARN("JIFFIES_COMPARISON",
546736ec1939SJoe Perches			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
546836ec1939SJoe Perches		}
546936ec1939SJoe Perches
54709d7a34a5SJoe Perches# check for comparisons of get_jiffies_64()
54719d7a34a5SJoe Perches		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
54729d7a34a5SJoe Perches			WARN("JIFFIES_COMPARISON",
54739d7a34a5SJoe Perches			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
54749d7a34a5SJoe Perches		}
54759d7a34a5SJoe Perches
547600df344fSAndy Whitcroft# warn about #ifdefs in C files
5477c45dcabdSAndy Whitcroft#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
547800df344fSAndy Whitcroft#			print "#ifdef in C files should be avoided\n";
547900df344fSAndy Whitcroft#			print "$herecurr";
548000df344fSAndy Whitcroft#			$clean = 0;
548100df344fSAndy Whitcroft#		}
548200df344fSAndy Whitcroft
548322f2a2efSAndy Whitcroft# warn about spacing in #ifdefs
5484c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
54853705ce5bSJoe Perches			if (ERROR("SPACING",
54863705ce5bSJoe Perches				  "exactly one space required after that #$1\n" . $herecurr) &&
54873705ce5bSJoe Perches			    $fix) {
5488194f66fcSJoe Perches				$fixed[$fixlinenr] =~
54893705ce5bSJoe Perches				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
54903705ce5bSJoe Perches			}
54913705ce5bSJoe Perches
549222f2a2efSAndy Whitcroft		}
549322f2a2efSAndy Whitcroft
54944a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment.
5495171ae1a4SAndy Whitcroft		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
5496171ae1a4SAndy Whitcroft		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
54974a0df2efSAndy Whitcroft			my $which = $1;
54984a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
5499000d1cc1SJoe Perches				CHK("UNCOMMENTED_DEFINITION",
5500000d1cc1SJoe Perches				    "$1 definition without comment\n" . $herecurr);
55014a0df2efSAndy Whitcroft			}
55024a0df2efSAndy Whitcroft		}
55034a0df2efSAndy Whitcroft# check for memory barriers without a comment.
5504402c2553SMichael S. Tsirkin
5505402c2553SMichael S. Tsirkin		my $barriers = qr{
5506402c2553SMichael S. Tsirkin			mb|
5507402c2553SMichael S. Tsirkin			rmb|
5508402c2553SMichael S. Tsirkin			wmb|
5509402c2553SMichael S. Tsirkin			read_barrier_depends
5510402c2553SMichael S. Tsirkin		}x;
5511402c2553SMichael S. Tsirkin		my $barrier_stems = qr{
5512402c2553SMichael S. Tsirkin			mb__before_atomic|
5513402c2553SMichael S. Tsirkin			mb__after_atomic|
5514402c2553SMichael S. Tsirkin			store_release|
5515402c2553SMichael S. Tsirkin			load_acquire|
5516402c2553SMichael S. Tsirkin			store_mb|
5517402c2553SMichael S. Tsirkin			(?:$barriers)
5518402c2553SMichael S. Tsirkin		}x;
5519402c2553SMichael S. Tsirkin		my $all_barriers = qr{
5520402c2553SMichael S. Tsirkin			(?:$barriers)|
552143e361f2SMichael S. Tsirkin			smp_(?:$barrier_stems)|
552243e361f2SMichael S. Tsirkin			virt_(?:$barrier_stems)
5523402c2553SMichael S. Tsirkin		}x;
5524402c2553SMichael S. Tsirkin
5525402c2553SMichael S. Tsirkin		if ($line =~ /\b(?:$all_barriers)\s*\(/) {
55264a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
5527c1fd7bb9SJoe Perches				WARN("MEMORY_BARRIER",
5528000d1cc1SJoe Perches				     "memory barrier without comment\n" . $herecurr);
55294a0df2efSAndy Whitcroft			}
55304a0df2efSAndy Whitcroft		}
55313ad81779SPaul E. McKenney
5532f4073b0fSMichael S. Tsirkin		my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
5533f4073b0fSMichael S. Tsirkin
5534f4073b0fSMichael S. Tsirkin		if ($realfile !~ m@^include/asm-generic/@ &&
5535f4073b0fSMichael S. Tsirkin		    $realfile !~ m@/barrier\.h$@ &&
5536f4073b0fSMichael S. Tsirkin		    $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
5537f4073b0fSMichael S. Tsirkin		    $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
5538f4073b0fSMichael S. Tsirkin			WARN("MEMORY_BARRIER",
5539f4073b0fSMichael S. Tsirkin			     "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
5540f4073b0fSMichael S. Tsirkin		}
5541f4073b0fSMichael S. Tsirkin
5542cb426e99SJoe Perches# check for waitqueue_active without a comment.
5543cb426e99SJoe Perches		if ($line =~ /\bwaitqueue_active\s*\(/) {
5544cb426e99SJoe Perches			if (!ctx_has_comment($first_line, $linenr)) {
5545cb426e99SJoe Perches				WARN("WAITQUEUE_ACTIVE",
5546cb426e99SJoe Perches				     "waitqueue_active without comment\n" . $herecurr);
5547cb426e99SJoe Perches			}
5548cb426e99SJoe Perches		}
55493ad81779SPaul E. McKenney
55504a0df2efSAndy Whitcroft# check of hardware specific defines
5551c45dcabdSAndy Whitcroft		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
5552000d1cc1SJoe Perches			CHK("ARCH_DEFINES",
5553000d1cc1SJoe Perches			    "architecture specific defines should be avoided\n" .  $herecurr);
55540a920b5bSAndy Whitcroft		}
5555653d4876SAndy Whitcroft
5556d4977c78STobias Klauser# Check that the storage class is at the beginning of a declaration
5557d4977c78STobias Klauser		if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) {
5558000d1cc1SJoe Perches			WARN("STORAGE_CLASS",
5559000d1cc1SJoe Perches			     "storage class should be at the beginning of the declaration\n" . $herecurr)
5560d4977c78STobias Klauser		}
5561d4977c78STobias Klauser
5562de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between
5563de7d4f0eSAndy Whitcroft# storage class and type.
55649c0ca6f9SAndy Whitcroft		if ($line =~ /\b$Type\s+$Inline\b/ ||
55659c0ca6f9SAndy Whitcroft		    $line =~ /\b$Inline\s+$Storage\b/) {
5566000d1cc1SJoe Perches			ERROR("INLINE_LOCATION",
5567000d1cc1SJoe Perches			      "inline keyword should sit between storage class and type\n" . $herecurr);
5568de7d4f0eSAndy Whitcroft		}
5569de7d4f0eSAndy Whitcroft
55708905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline
55712b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
55722b7ab453SJoe Perches		    $line =~ /\b(__inline__|__inline)\b/) {
5573d5e616fcSJoe Perches			if (WARN("INLINE",
5574d5e616fcSJoe Perches				 "plain inline is preferred over $1\n" . $herecurr) &&
5575d5e616fcSJoe Perches			    $fix) {
5576194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
5577d5e616fcSJoe Perches
5578d5e616fcSJoe Perches			}
55798905a67cSAndy Whitcroft		}
55808905a67cSAndy Whitcroft
55813d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed
55822b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
55832b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
5584000d1cc1SJoe Perches			WARN("PREFER_PACKED",
5585000d1cc1SJoe Perches			     "__packed is preferred over __attribute__((packed))\n" . $herecurr);
55863d130fd0SJoe Perches		}
55873d130fd0SJoe Perches
558839b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned
55892b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
55902b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
5591000d1cc1SJoe Perches			WARN("PREFER_ALIGNED",
5592000d1cc1SJoe Perches			     "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
559339b7e287SJoe Perches		}
559439b7e287SJoe Perches
55955f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf
55962b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
55972b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
5598d5e616fcSJoe Perches			if (WARN("PREFER_PRINTF",
5599d5e616fcSJoe Perches				 "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
5600d5e616fcSJoe Perches			    $fix) {
5601194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
5602d5e616fcSJoe Perches
5603d5e616fcSJoe Perches			}
56045f14d3bdSJoe Perches		}
56055f14d3bdSJoe Perches
56066061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf
56072b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
56082b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
5609d5e616fcSJoe Perches			if (WARN("PREFER_SCANF",
5610d5e616fcSJoe Perches				 "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
5611d5e616fcSJoe Perches			    $fix) {
5612194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
5613d5e616fcSJoe Perches			}
56146061d949SJoe Perches		}
56156061d949SJoe Perches
5616619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues)
5617619a908aSJoe Perches		if ($^V && $^V ge 5.10.0 &&
5618619a908aSJoe Perches		    $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
5619619a908aSJoe Perches		    ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
5620619a908aSJoe Perches		     $line =~ /\b__weak\b/)) {
5621619a908aSJoe Perches			ERROR("WEAK_DECLARATION",
5622619a908aSJoe Perches			      "Using weak declarations can have unintended link defects\n" . $herecurr);
5623619a908aSJoe Perches		}
5624619a908aSJoe Perches
5625fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/
5626e6176fa4SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
5627fd39f904STomas Winkler		    $realfile !~ m@\btools/@ &&
5628e6176fa4SJoe Perches		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
5629e6176fa4SJoe Perches			my $type = $1;
5630e6176fa4SJoe Perches			if ($type =~ /\b($typeC99Typedefs)\b/) {
5631e6176fa4SJoe Perches				$type = $1;
5632e6176fa4SJoe Perches				my $kernel_type = 'u';
5633e6176fa4SJoe Perches				$kernel_type = 's' if ($type =~ /^_*[si]/);
5634e6176fa4SJoe Perches				$type =~ /(\d+)/;
5635e6176fa4SJoe Perches				$kernel_type .= $1;
5636e6176fa4SJoe Perches				if (CHK("PREFER_KERNEL_TYPES",
5637e6176fa4SJoe Perches					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
5638e6176fa4SJoe Perches				    $fix) {
5639e6176fa4SJoe Perches					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
5640e6176fa4SJoe Perches				}
5641e6176fa4SJoe Perches			}
5642e6176fa4SJoe Perches		}
5643e6176fa4SJoe Perches
5644938224b5SJoe Perches# check for cast of C90 native int or longer types constants
5645938224b5SJoe Perches		if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
5646938224b5SJoe Perches			my $cast = $1;
5647938224b5SJoe Perches			my $const = $2;
5648938224b5SJoe Perches			if (WARN("TYPECAST_INT_CONSTANT",
5649938224b5SJoe Perches				 "Unnecessary typecast of c90 int constant\n" . $herecurr) &&
5650938224b5SJoe Perches			    $fix) {
5651938224b5SJoe Perches				my $suffix = "";
5652938224b5SJoe Perches				my $newconst = $const;
5653938224b5SJoe Perches				$newconst =~ s/${Int_type}$//;
5654938224b5SJoe Perches				$suffix .= 'U' if ($cast =~ /\bunsigned\b/);
5655938224b5SJoe Perches				if ($cast =~ /\blong\s+long\b/) {
5656938224b5SJoe Perches					$suffix .= 'LL';
5657938224b5SJoe Perches				} elsif ($cast =~ /\blong\b/) {
5658938224b5SJoe Perches					$suffix .= 'L';
5659938224b5SJoe Perches				}
5660938224b5SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
5661938224b5SJoe Perches			}
5662938224b5SJoe Perches		}
5663938224b5SJoe Perches
56648f53a9b8SJoe Perches# check for sizeof(&)
56658f53a9b8SJoe Perches		if ($line =~ /\bsizeof\s*\(\s*\&/) {
5666000d1cc1SJoe Perches			WARN("SIZEOF_ADDRESS",
5667000d1cc1SJoe Perches			     "sizeof(& should be avoided\n" . $herecurr);
56688f53a9b8SJoe Perches		}
56698f53a9b8SJoe Perches
567066c80b60SJoe Perches# check for sizeof without parenthesis
567166c80b60SJoe Perches		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
5672d5e616fcSJoe Perches			if (WARN("SIZEOF_PARENTHESIS",
5673d5e616fcSJoe Perches				 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
5674d5e616fcSJoe Perches			    $fix) {
5675194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
5676d5e616fcSJoe Perches			}
567766c80b60SJoe Perches		}
567866c80b60SJoe Perches
567988982feaSJoe Perches# check for struct spinlock declarations
568088982feaSJoe Perches		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
568188982feaSJoe Perches			WARN("USE_SPINLOCK_T",
568288982feaSJoe Perches			     "struct spinlock should be spinlock_t\n" . $herecurr);
568388982feaSJoe Perches		}
568488982feaSJoe Perches
5685a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts
568606668727SJoe Perches		if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
5687a6962d72SJoe Perches			my $fmt = get_quoted_string($line, $rawline);
5688caac1d5fSHeba Aamer			$fmt =~ s/%%//g;
5689caac1d5fSHeba Aamer			if ($fmt !~ /%/) {
5690d5e616fcSJoe Perches				if (WARN("PREFER_SEQ_PUTS",
5691d5e616fcSJoe Perches					 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
5692d5e616fcSJoe Perches				    $fix) {
5693194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
5694d5e616fcSJoe Perches				}
5695a6962d72SJoe Perches			}
5696a6962d72SJoe Perches		}
5697a6962d72SJoe Perches
56980b523769SJoe Perches		# check for vsprintf extension %p<foo> misuses
56990b523769SJoe Perches		if ($^V && $^V ge 5.10.0 &&
57000b523769SJoe Perches		    defined $stat &&
57010b523769SJoe Perches		    $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
57020b523769SJoe Perches		    $1 !~ /^_*volatile_*$/) {
57030b523769SJoe Perches			my $bad_extension = "";
57040b523769SJoe Perches			my $lc = $stat =~ tr@\n@@;
57050b523769SJoe Perches			$lc = $lc + $linenr;
57060b523769SJoe Perches		        for (my $count = $linenr; $count <= $lc; $count++) {
57070b523769SJoe Perches				my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
57080b523769SJoe Perches				$fmt =~ s/%%//g;
5709ce4fecf1SPantelis Antoniou				if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNO]).)/) {
57100b523769SJoe Perches					$bad_extension = $1;
57110b523769SJoe Perches					last;
57120b523769SJoe Perches				}
57130b523769SJoe Perches			}
57140b523769SJoe Perches			if ($bad_extension ne "") {
57150b523769SJoe Perches				my $stat_real = raw_line($linenr, 0);
57160b523769SJoe Perches				for (my $count = $linenr + 1; $count <= $lc; $count++) {
57170b523769SJoe Perches					$stat_real = $stat_real . "\n" . raw_line($count, 0);
57180b523769SJoe Perches				}
57190b523769SJoe Perches				WARN("VSPRINTF_POINTER_EXTENSION",
57200b523769SJoe Perches				     "Invalid vsprintf pointer extension '$bad_extension'\n" . "$here\n$stat_real\n");
57210b523769SJoe Perches			}
57220b523769SJoe Perches		}
57230b523769SJoe Perches
5724554e165cSAndy Whitcroft# Check for misused memsets
5725d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5726d1fe9c09SJoe Perches		    defined $stat &&
57279e20a853SMateusz Kulikowski		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
5728554e165cSAndy Whitcroft
5729d7c76ba7SJoe Perches			my $ms_addr = $2;
5730d1fe9c09SJoe Perches			my $ms_val = $7;
5731d1fe9c09SJoe Perches			my $ms_size = $12;
5732d7c76ba7SJoe Perches
5733554e165cSAndy Whitcroft			if ($ms_size =~ /^(0x|)0$/i) {
5734554e165cSAndy Whitcroft				ERROR("MEMSET",
5735d7c76ba7SJoe Perches				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
5736554e165cSAndy Whitcroft			} elsif ($ms_size =~ /^(0x|)1$/i) {
5737554e165cSAndy Whitcroft				WARN("MEMSET",
5738d7c76ba7SJoe Perches				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
5739d7c76ba7SJoe Perches			}
5740d7c76ba7SJoe Perches		}
5741d7c76ba7SJoe Perches
574298a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
5743f333195dSJoe Perches#		if ($^V && $^V ge 5.10.0 &&
5744f333195dSJoe Perches#		    defined $stat &&
5745f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
5746f333195dSJoe Perches#			if (WARN("PREFER_ETHER_ADDR_COPY",
5747f333195dSJoe Perches#				 "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
5748f333195dSJoe Perches#			    $fix) {
5749f333195dSJoe Perches#				$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
5750f333195dSJoe Perches#			}
5751f333195dSJoe Perches#		}
575298a9bba5SJoe Perches
5753b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
5754f333195dSJoe Perches#		if ($^V && $^V ge 5.10.0 &&
5755f333195dSJoe Perches#		    defined $stat &&
5756f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
5757f333195dSJoe Perches#			WARN("PREFER_ETHER_ADDR_EQUAL",
5758f333195dSJoe Perches#			     "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
5759f333195dSJoe Perches#		}
5760b6117d17SMateusz Kulikowski
57618617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
57628617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
5763f333195dSJoe Perches#		if ($^V && $^V ge 5.10.0 &&
5764f333195dSJoe Perches#		    defined $stat &&
5765f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
5766f333195dSJoe Perches#
5767f333195dSJoe Perches#			my $ms_val = $7;
5768f333195dSJoe Perches#
5769f333195dSJoe Perches#			if ($ms_val =~ /^(?:0x|)0+$/i) {
5770f333195dSJoe Perches#				if (WARN("PREFER_ETH_ZERO_ADDR",
5771f333195dSJoe Perches#					 "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
5772f333195dSJoe Perches#				    $fix) {
5773f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
5774f333195dSJoe Perches#				}
5775f333195dSJoe Perches#			} elsif ($ms_val =~ /^(?:0xff|255)$/i) {
5776f333195dSJoe Perches#				if (WARN("PREFER_ETH_BROADCAST_ADDR",
5777f333195dSJoe Perches#					 "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
5778f333195dSJoe Perches#				    $fix) {
5779f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
5780f333195dSJoe Perches#				}
5781f333195dSJoe Perches#			}
5782f333195dSJoe Perches#		}
57838617cd09SMateusz Kulikowski
5784d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t
5785d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5786d1fe9c09SJoe Perches		    defined $stat &&
5787d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
5788d1fe9c09SJoe Perches			if (defined $2 || defined $7) {
5789d7c76ba7SJoe Perches				my $call = $1;
5790d7c76ba7SJoe Perches				my $cast1 = deparenthesize($2);
5791d7c76ba7SJoe Perches				my $arg1 = $3;
5792d1fe9c09SJoe Perches				my $cast2 = deparenthesize($7);
5793d1fe9c09SJoe Perches				my $arg2 = $8;
5794d7c76ba7SJoe Perches				my $cast;
5795d7c76ba7SJoe Perches
5796d1fe9c09SJoe Perches				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
5797d7c76ba7SJoe Perches					$cast = "$cast1 or $cast2";
5798d7c76ba7SJoe Perches				} elsif ($cast1 ne "") {
5799d7c76ba7SJoe Perches					$cast = $cast1;
5800d7c76ba7SJoe Perches				} else {
5801d7c76ba7SJoe Perches					$cast = $cast2;
5802d7c76ba7SJoe Perches				}
5803d7c76ba7SJoe Perches				WARN("MINMAX",
5804d7c76ba7SJoe Perches				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
5805554e165cSAndy Whitcroft			}
5806554e165cSAndy Whitcroft		}
5807554e165cSAndy Whitcroft
58084a273195SJoe Perches# check usleep_range arguments
58094a273195SJoe Perches		if ($^V && $^V ge 5.10.0 &&
58104a273195SJoe Perches		    defined $stat &&
58114a273195SJoe Perches		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
58124a273195SJoe Perches			my $min = $1;
58134a273195SJoe Perches			my $max = $7;
58144a273195SJoe Perches			if ($min eq $max) {
58154a273195SJoe Perches				WARN("USLEEP_RANGE",
58164a273195SJoe Perches				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
58174a273195SJoe Perches			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
58184a273195SJoe Perches				 $min > $max) {
58194a273195SJoe Perches				WARN("USLEEP_RANGE",
58204a273195SJoe Perches				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
58214a273195SJoe Perches			}
58224a273195SJoe Perches		}
58234a273195SJoe Perches
5824823b794cSJoe Perches# check for naked sscanf
5825823b794cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
5826823b794cSJoe Perches		    defined $stat &&
58276c8bd707SJoe Perches		    $line =~ /\bsscanf\b/ &&
5828823b794cSJoe Perches		    ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
5829823b794cSJoe Perches		     $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
5830823b794cSJoe Perches		     $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
5831823b794cSJoe Perches			my $lc = $stat =~ tr@\n@@;
5832823b794cSJoe Perches			$lc = $lc + $linenr;
5833823b794cSJoe Perches			my $stat_real = raw_line($linenr, 0);
5834823b794cSJoe Perches		        for (my $count = $linenr + 1; $count <= $lc; $count++) {
5835823b794cSJoe Perches				$stat_real = $stat_real . "\n" . raw_line($count, 0);
5836823b794cSJoe Perches			}
5837823b794cSJoe Perches			WARN("NAKED_SSCANF",
5838823b794cSJoe Perches			     "unchecked sscanf return value\n" . "$here\n$stat_real\n");
5839823b794cSJoe Perches		}
5840823b794cSJoe Perches
5841afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo>
5842afc819abSJoe Perches		if ($^V && $^V ge 5.10.0 &&
5843afc819abSJoe Perches		    defined $stat &&
5844afc819abSJoe Perches		    $line =~ /\bsscanf\b/) {
5845afc819abSJoe Perches			my $lc = $stat =~ tr@\n@@;
5846afc819abSJoe Perches			$lc = $lc + $linenr;
5847afc819abSJoe Perches			my $stat_real = raw_line($linenr, 0);
5848afc819abSJoe Perches		        for (my $count = $linenr + 1; $count <= $lc; $count++) {
5849afc819abSJoe Perches				$stat_real = $stat_real . "\n" . raw_line($count, 0);
5850afc819abSJoe Perches			}
5851afc819abSJoe Perches			if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
5852afc819abSJoe Perches				my $format = $6;
5853afc819abSJoe Perches				my $count = $format =~ tr@%@%@;
5854afc819abSJoe Perches				if ($count == 1 &&
5855afc819abSJoe Perches				    $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
5856afc819abSJoe Perches					WARN("SSCANF_TO_KSTRTO",
5857afc819abSJoe Perches					     "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
5858afc819abSJoe Perches				}
5859afc819abSJoe Perches			}
5860afc819abSJoe Perches		}
5861afc819abSJoe Perches
586270dc8a48SJoe Perches# check for new externs in .h files.
586370dc8a48SJoe Perches		if ($realfile =~ /\.h$/ &&
586470dc8a48SJoe Perches		    $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
5865d1d85780SJoe Perches			if (CHK("AVOID_EXTERNS",
586670dc8a48SJoe Perches				"extern prototypes should be avoided in .h files\n" . $herecurr) &&
586770dc8a48SJoe Perches			    $fix) {
5868194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
586970dc8a48SJoe Perches			}
587070dc8a48SJoe Perches		}
587170dc8a48SJoe Perches
5872de7d4f0eSAndy Whitcroft# check for new externs in .c files.
5873171ae1a4SAndy Whitcroft		if ($realfile =~ /\.c$/ && defined $stat &&
5874c45dcabdSAndy Whitcroft		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
5875171ae1a4SAndy Whitcroft		{
5876c45dcabdSAndy Whitcroft			my $function_name = $1;
5877c45dcabdSAndy Whitcroft			my $paren_space = $2;
5878171ae1a4SAndy Whitcroft
5879171ae1a4SAndy Whitcroft			my $s = $stat;
5880171ae1a4SAndy Whitcroft			if (defined $cond) {
5881171ae1a4SAndy Whitcroft				substr($s, 0, length($cond), '');
5882171ae1a4SAndy Whitcroft			}
5883c45dcabdSAndy Whitcroft			if ($s =~ /^\s*;/ &&
5884c45dcabdSAndy Whitcroft			    $function_name ne 'uninitialized_var')
5885c45dcabdSAndy Whitcroft			{
5886000d1cc1SJoe Perches				WARN("AVOID_EXTERNS",
5887000d1cc1SJoe Perches				     "externs should be avoided in .c files\n" .  $herecurr);
5888de7d4f0eSAndy Whitcroft			}
5889de7d4f0eSAndy Whitcroft
5890171ae1a4SAndy Whitcroft			if ($paren_space =~ /\n/) {
5891000d1cc1SJoe Perches				WARN("FUNCTION_ARGUMENTS",
5892000d1cc1SJoe Perches				     "arguments for function declarations should follow identifier\n" . $herecurr);
5893171ae1a4SAndy Whitcroft			}
58949c9ba34eSAndy Whitcroft
58959c9ba34eSAndy Whitcroft		} elsif ($realfile =~ /\.c$/ && defined $stat &&
58969c9ba34eSAndy Whitcroft		    $stat =~ /^.\s*extern\s+/)
58979c9ba34eSAndy Whitcroft		{
5898000d1cc1SJoe Perches			WARN("AVOID_EXTERNS",
5899000d1cc1SJoe Perches			     "externs should be avoided in .c files\n" .  $herecurr);
5900171ae1a4SAndy Whitcroft		}
5901171ae1a4SAndy Whitcroft
5902a0ad7596SJoe Perches# check for function declarations that have arguments without identifier names
5903a0ad7596SJoe Perches		if (defined $stat &&
5904ca0d8929SJoe Perches		    $stat =~ /^.\s*(?:extern\s+)?$Type\s*$Ident\s*\(\s*([^{]+)\s*\)\s*;/s &&
5905ca0d8929SJoe Perches		    $1 ne "void") {
5906ca0d8929SJoe Perches			my $args = trim($1);
5907ca0d8929SJoe Perches			while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
5908ca0d8929SJoe Perches				my $arg = trim($1);
5909ca0d8929SJoe Perches				if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
5910ca0d8929SJoe Perches					WARN("FUNCTION_ARGUMENTS",
5911ca0d8929SJoe Perches					     "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
5912ca0d8929SJoe Perches				}
5913ca0d8929SJoe Perches			}
5914ca0d8929SJoe Perches		}
5915ca0d8929SJoe Perches
5916a0ad7596SJoe Perches# check for function definitions
5917a0ad7596SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5918a0ad7596SJoe Perches		    defined $stat &&
5919a0ad7596SJoe Perches		    $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {
5920a0ad7596SJoe Perches			$context_function = $1;
5921a0ad7596SJoe Perches
5922a0ad7596SJoe Perches# check for multiline function definition with misplaced open brace
5923a0ad7596SJoe Perches			my $ok = 0;
5924a0ad7596SJoe Perches			my $cnt = statement_rawlines($stat);
5925a0ad7596SJoe Perches			my $herectx = $here . "\n";
5926a0ad7596SJoe Perches			for (my $n = 0; $n < $cnt; $n++) {
5927a0ad7596SJoe Perches				my $rl = raw_line($linenr, $n);
5928a0ad7596SJoe Perches				$herectx .=  $rl . "\n";
5929a0ad7596SJoe Perches				$ok = 1 if ($rl =~ /^[ \+]\{/);
5930a0ad7596SJoe Perches				$ok = 1 if ($rl =~ /\{/ && $n == 0);
5931a0ad7596SJoe Perches				last if $rl =~ /^[ \+].*\{/;
5932a0ad7596SJoe Perches			}
5933a0ad7596SJoe Perches			if (!$ok) {
5934a0ad7596SJoe Perches				ERROR("OPEN_BRACE",
5935a0ad7596SJoe Perches				      "open brace '{' following function definitions go on the next line\n" . $herectx);
5936a0ad7596SJoe Perches			}
5937a0ad7596SJoe Perches		}
5938a0ad7596SJoe Perches
5939de7d4f0eSAndy Whitcroft# checks for new __setup's
5940de7d4f0eSAndy Whitcroft		if ($rawline =~ /\b__setup\("([^"]*)"/) {
5941de7d4f0eSAndy Whitcroft			my $name = $1;
5942de7d4f0eSAndy Whitcroft
5943de7d4f0eSAndy Whitcroft			if (!grep(/$name/, @setup_docs)) {
5944000d1cc1SJoe Perches				CHK("UNDOCUMENTED_SETUP",
59458c27ceffSMauro Carvalho Chehab				    "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr);
5946de7d4f0eSAndy Whitcroft			}
5947653d4876SAndy Whitcroft		}
59489c0ca6f9SAndy Whitcroft
59499c0ca6f9SAndy Whitcroft# check for pointless casting of kmalloc return
5950caf2a54fSJoe Perches		if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) {
5951000d1cc1SJoe Perches			WARN("UNNECESSARY_CASTS",
5952000d1cc1SJoe Perches			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
59539c0ca6f9SAndy Whitcroft		}
595413214adfSAndy Whitcroft
5955a640d25cSJoe Perches# alloc style
5956a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
5957a640d25cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
5958a640d25cSJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
5959a640d25cSJoe Perches			CHK("ALLOC_SIZEOF_STRUCT",
5960a640d25cSJoe Perches			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
5961a640d25cSJoe Perches		}
5962a640d25cSJoe Perches
596360a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
596460a55369SJoe Perches		if ($^V && $^V ge 5.10.0 &&
59651b4a2ed4SJoe Perches		    defined $stat &&
59661b4a2ed4SJoe Perches		    $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
596760a55369SJoe Perches			my $oldfunc = $3;
596860a55369SJoe Perches			my $a1 = $4;
596960a55369SJoe Perches			my $a2 = $10;
597060a55369SJoe Perches			my $newfunc = "kmalloc_array";
597160a55369SJoe Perches			$newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
597260a55369SJoe Perches			my $r1 = $a1;
597360a55369SJoe Perches			my $r2 = $a2;
597460a55369SJoe Perches			if ($a1 =~ /^sizeof\s*\S/) {
597560a55369SJoe Perches				$r1 = $a2;
597660a55369SJoe Perches				$r2 = $a1;
597760a55369SJoe Perches			}
5978e367455aSJoe Perches			if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
5979e367455aSJoe Perches			    !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
59801b4a2ed4SJoe Perches				my $ctx = '';
59811b4a2ed4SJoe Perches				my $herectx = $here . "\n";
59821b4a2ed4SJoe Perches				my $cnt = statement_rawlines($stat);
59831b4a2ed4SJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
59841b4a2ed4SJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
59851b4a2ed4SJoe Perches				}
5986e367455aSJoe Perches				if (WARN("ALLOC_WITH_MULTIPLY",
59871b4a2ed4SJoe Perches					 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
59881b4a2ed4SJoe Perches				    $cnt == 1 &&
5989e367455aSJoe Perches				    $fix) {
5990194f66fcSJoe 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;
599160a55369SJoe Perches				}
599260a55369SJoe Perches			}
599360a55369SJoe Perches		}
599460a55369SJoe Perches
5995972fdea2SJoe Perches# check for krealloc arg reuse
5996972fdea2SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5997972fdea2SJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) {
5998972fdea2SJoe Perches			WARN("KREALLOC_ARG_REUSE",
5999972fdea2SJoe Perches			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
6000972fdea2SJoe Perches		}
6001972fdea2SJoe Perches
60025ce59ae0SJoe Perches# check for alloc argument mismatch
60035ce59ae0SJoe Perches		if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
60045ce59ae0SJoe Perches			WARN("ALLOC_ARRAY_ARGS",
60055ce59ae0SJoe Perches			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
60065ce59ae0SJoe Perches		}
60075ce59ae0SJoe Perches
6008caf2a54fSJoe Perches# check for multiple semicolons
6009caf2a54fSJoe Perches		if ($line =~ /;\s*;\s*$/) {
6010d5e616fcSJoe Perches			if (WARN("ONE_SEMICOLON",
6011d5e616fcSJoe Perches				 "Statements terminations use 1 semicolon\n" . $herecurr) &&
6012d5e616fcSJoe Perches			    $fix) {
6013194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
6014d5e616fcSJoe Perches			}
6015d1e2ad07SJoe Perches		}
6016d1e2ad07SJoe Perches
6017cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
6018cec3aaa5STomas Winkler		if ($realfile !~ m@^include/uapi/@ &&
6019cec3aaa5STomas Winkler		    $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
60200ab90191SJoe Perches			my $ull = "";
60210ab90191SJoe Perches			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
60220ab90191SJoe Perches			if (CHK("BIT_MACRO",
60230ab90191SJoe Perches				"Prefer using the BIT$ull macro\n" . $herecurr) &&
60240ab90191SJoe Perches			    $fix) {
60250ab90191SJoe Perches				$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
60260ab90191SJoe Perches			}
60270ab90191SJoe Perches		}
60280ab90191SJoe Perches
60292d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
60302d632745SJoe 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*$/) {
60312d632745SJoe Perches			my $config = $1;
60322d632745SJoe Perches			if (WARN("PREFER_IS_ENABLED",
60332d632745SJoe Perches				 "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) &&
60342d632745SJoe Perches			    $fix) {
60352d632745SJoe Perches				$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
60362d632745SJoe Perches			}
60372d632745SJoe Perches		}
60382d632745SJoe Perches
6039e81f239bSJoe Perches# check for case / default statements not preceded by break/fallthrough/switch
6040c34c09a8SJoe Perches		if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
6041c34c09a8SJoe Perches			my $has_break = 0;
6042c34c09a8SJoe Perches			my $has_statement = 0;
6043c34c09a8SJoe Perches			my $count = 0;
6044c34c09a8SJoe Perches			my $prevline = $linenr;
6045e81f239bSJoe Perches			while ($prevline > 1 && ($file || $count < 3) && !$has_break) {
6046c34c09a8SJoe Perches				$prevline--;
6047c34c09a8SJoe Perches				my $rline = $rawlines[$prevline - 1];
6048c34c09a8SJoe Perches				my $fline = $lines[$prevline - 1];
6049c34c09a8SJoe Perches				last if ($fline =~ /^\@\@/);
6050c34c09a8SJoe Perches				next if ($fline =~ /^\-/);
6051c34c09a8SJoe Perches				next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/);
6052c34c09a8SJoe Perches				$has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i);
6053c34c09a8SJoe Perches				next if ($fline =~ /^.[\s$;]*$/);
6054c34c09a8SJoe Perches				$has_statement = 1;
6055c34c09a8SJoe Perches				$count++;
6056c34c09a8SJoe Perches				$has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/);
6057c34c09a8SJoe Perches			}
6058c34c09a8SJoe Perches			if (!$has_break && $has_statement) {
6059c34c09a8SJoe Perches				WARN("MISSING_BREAK",
6060224236d9SAndrew Morton				     "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr);
6061c34c09a8SJoe Perches			}
6062c34c09a8SJoe Perches		}
6063c34c09a8SJoe Perches
6064d1e2ad07SJoe Perches# check for switch/default statements without a break;
6065d1e2ad07SJoe Perches		if ($^V && $^V ge 5.10.0 &&
6066d1e2ad07SJoe Perches		    defined $stat &&
6067d1e2ad07SJoe Perches		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
6068d1e2ad07SJoe Perches			my $ctx = '';
6069d1e2ad07SJoe Perches			my $herectx = $here . "\n";
6070d1e2ad07SJoe Perches			my $cnt = statement_rawlines($stat);
6071d1e2ad07SJoe Perches			for (my $n = 0; $n < $cnt; $n++) {
6072d1e2ad07SJoe Perches				$herectx .= raw_line($linenr, $n) . "\n";
6073d1e2ad07SJoe Perches			}
6074d1e2ad07SJoe Perches			WARN("DEFAULT_NO_BREAK",
6075d1e2ad07SJoe Perches			     "switch default: should use break\n" . $herectx);
6076caf2a54fSJoe Perches		}
6077caf2a54fSJoe Perches
607813214adfSAndy Whitcroft# check for gcc specific __FUNCTION__
6079d5e616fcSJoe Perches		if ($line =~ /\b__FUNCTION__\b/) {
6080d5e616fcSJoe Perches			if (WARN("USE_FUNC",
6081d5e616fcSJoe Perches				 "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr) &&
6082d5e616fcSJoe Perches			    $fix) {
6083194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
6084d5e616fcSJoe Perches			}
608513214adfSAndy Whitcroft		}
6086773647a0SAndy Whitcroft
608762ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__
608862ec818fSJoe Perches		while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
608962ec818fSJoe Perches			ERROR("DATE_TIME",
609062ec818fSJoe Perches			      "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
609162ec818fSJoe Perches		}
609262ec818fSJoe Perches
60932c92488aSJoe Perches# check for use of yield()
60942c92488aSJoe Perches		if ($line =~ /\byield\s*\(\s*\)/) {
60952c92488aSJoe Perches			WARN("YIELD",
60962c92488aSJoe Perches			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
60972c92488aSJoe Perches		}
60982c92488aSJoe Perches
6099179f8f40SJoe Perches# check for comparisons against true and false
6100179f8f40SJoe Perches		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
6101179f8f40SJoe Perches			my $lead = $1;
6102179f8f40SJoe Perches			my $arg = $2;
6103179f8f40SJoe Perches			my $test = $3;
6104179f8f40SJoe Perches			my $otype = $4;
6105179f8f40SJoe Perches			my $trail = $5;
6106179f8f40SJoe Perches			my $op = "!";
6107179f8f40SJoe Perches
6108179f8f40SJoe Perches			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
6109179f8f40SJoe Perches
6110179f8f40SJoe Perches			my $type = lc($otype);
6111179f8f40SJoe Perches			if ($type =~ /^(?:true|false)$/) {
6112179f8f40SJoe Perches				if (("$test" eq "==" && "$type" eq "true") ||
6113179f8f40SJoe Perches				    ("$test" eq "!=" && "$type" eq "false")) {
6114179f8f40SJoe Perches					$op = "";
6115179f8f40SJoe Perches				}
6116179f8f40SJoe Perches
6117179f8f40SJoe Perches				CHK("BOOL_COMPARISON",
6118179f8f40SJoe Perches				    "Using comparison to $otype is error prone\n" . $herecurr);
6119179f8f40SJoe Perches
6120179f8f40SJoe Perches## maybe suggesting a correct construct would better
6121179f8f40SJoe Perches##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
6122179f8f40SJoe Perches
6123179f8f40SJoe Perches			}
6124179f8f40SJoe Perches		}
6125179f8f40SJoe Perches
61264882720bSThomas Gleixner# check for semaphores initialized locked
61274882720bSThomas Gleixner		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
6128000d1cc1SJoe Perches			WARN("CONSIDER_COMPLETION",
6129000d1cc1SJoe Perches			     "consider using a completion\n" . $herecurr);
6130773647a0SAndy Whitcroft		}
61316712d858SJoe Perches
613267d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto*
613367d0a075SJoe Perches		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
6134000d1cc1SJoe Perches			WARN("CONSIDER_KSTRTO",
613567d0a075SJoe Perches			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
6136773647a0SAndy Whitcroft		}
61376712d858SJoe Perches
6138ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please
6139f3db6639SMichael Ellerman		if ($line =~ /^.\s*__initcall\s*\(/) {
6140000d1cc1SJoe Perches			WARN("USE_DEVICE_INITCALL",
6141ae3ccc46SFabian Frederick			     "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
6142f3db6639SMichael Ellerman		}
61436712d858SJoe Perches
61440f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree)
6145d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {'
61466903ffb2SAndy Whitcroft		if ($line !~ /\bconst\b/ &&
6147d9190e4eSJoe Perches		    $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
6148000d1cc1SJoe Perches			WARN("CONST_STRUCT",
6149d9190e4eSJoe Perches			     "struct $1 should normally be const\n" . $herecurr);
61502b6db5cbSAndy Whitcroft		}
6151773647a0SAndy Whitcroft
6152773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong
6153773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right
6154773647a0SAndy Whitcroft		if ($line =~ /\bNR_CPUS\b/ &&
6155c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
6156c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
6157171ae1a4SAndy Whitcroft		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
6158171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
6159171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/)
6160773647a0SAndy Whitcroft		{
6161000d1cc1SJoe Perches			WARN("NR_CPUS",
6162000d1cc1SJoe Perches			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
6163773647a0SAndy Whitcroft		}
61649c9ba34eSAndy Whitcroft
616552ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
616652ea8506SJoe Perches		if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
616752ea8506SJoe Perches			ERROR("DEFINE_ARCH_HAS",
616852ea8506SJoe Perches			      "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
616952ea8506SJoe Perches		}
617052ea8506SJoe Perches
6171acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)"
6172acd9362cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
6173acd9362cSJoe Perches		    $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
6174acd9362cSJoe Perches			WARN("LIKELY_MISUSE",
6175acd9362cSJoe Perches			     "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
6176acd9362cSJoe Perches		}
6177acd9362cSJoe Perches
6178691d77b6SAndy Whitcroft# whine mightly about in_atomic
6179691d77b6SAndy Whitcroft		if ($line =~ /\bin_atomic\s*\(/) {
6180691d77b6SAndy Whitcroft			if ($realfile =~ m@^drivers/@) {
6181000d1cc1SJoe Perches				ERROR("IN_ATOMIC",
6182000d1cc1SJoe Perches				      "do not use in_atomic in drivers\n" . $herecurr);
6183f4a87736SAndy Whitcroft			} elsif ($realfile !~ m@^kernel/@) {
6184000d1cc1SJoe Perches				WARN("IN_ATOMIC",
6185000d1cc1SJoe Perches				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
6186691d77b6SAndy Whitcroft			}
6187691d77b6SAndy Whitcroft		}
61881704f47bSPeter Zijlstra
6189481aea5cSJoe Perches# whine about ACCESS_ONCE
6190481aea5cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
6191481aea5cSJoe Perches		    $line =~ /\bACCESS_ONCE\s*$balanced_parens\s*(=(?!=))?\s*($FuncArg)?/) {
6192481aea5cSJoe Perches			my $par = $1;
6193481aea5cSJoe Perches			my $eq = $2;
6194481aea5cSJoe Perches			my $fun = $3;
6195481aea5cSJoe Perches			$par =~ s/^\(\s*(.*)\s*\)$/$1/;
6196481aea5cSJoe Perches			if (defined($eq)) {
6197481aea5cSJoe Perches				if (WARN("PREFER_WRITE_ONCE",
6198481aea5cSJoe Perches					 "Prefer WRITE_ONCE(<FOO>, <BAR>) over ACCESS_ONCE(<FOO>) = <BAR>\n" . $herecurr) &&
6199481aea5cSJoe Perches				    $fix) {
6200481aea5cSJoe Perches					$fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)\s*$eq\s*\Q$fun\E/WRITE_ONCE($par, $fun)/;
6201481aea5cSJoe Perches				}
6202481aea5cSJoe Perches			} else {
6203481aea5cSJoe Perches				if (WARN("PREFER_READ_ONCE",
6204481aea5cSJoe Perches					 "Prefer READ_ONCE(<FOO>) over ACCESS_ONCE(<FOO>)\n" . $herecurr) &&
6205481aea5cSJoe Perches				    $fix) {
6206481aea5cSJoe Perches					$fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)/READ_ONCE($par)/;
6207481aea5cSJoe Perches				}
6208481aea5cSJoe Perches			}
6209481aea5cSJoe Perches		}
6210481aea5cSJoe Perches
62110f5225b0SPeter Zijlstra# check for mutex_trylock_recursive usage
62120f5225b0SPeter Zijlstra		if ($line =~ /mutex_trylock_recursive/) {
62130f5225b0SPeter Zijlstra			ERROR("LOCKING",
62140f5225b0SPeter Zijlstra			      "recursive locking is bad, do not use this ever.\n" . $herecurr);
62150f5225b0SPeter Zijlstra		}
62160f5225b0SPeter Zijlstra
62171704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class
62181704f47bSPeter Zijlstra		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
62191704f47bSPeter Zijlstra		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
62201704f47bSPeter Zijlstra			if ($realfile !~ m@^kernel/lockdep@ &&
62211704f47bSPeter Zijlstra			    $realfile !~ m@^include/linux/lockdep@ &&
62221704f47bSPeter Zijlstra			    $realfile !~ m@^drivers/base/core@) {
6223000d1cc1SJoe Perches				ERROR("LOCKDEP",
6224000d1cc1SJoe Perches				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
62251704f47bSPeter Zijlstra			}
62261704f47bSPeter Zijlstra		}
622788f8831cSDave Jones
6228b392c64fSJoe Perches		if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
6229b392c64fSJoe Perches		    $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
6230000d1cc1SJoe Perches			WARN("EXPORTED_WORLD_WRITABLE",
6231000d1cc1SJoe Perches			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
623288f8831cSDave Jones		}
62332435880fSJoe Perches
6234515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal
6235515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
6236515a235eSJoe Perches		if ($^V && $^V ge 5.10.0 &&
6237459cf0aeSJoe Perches		    defined $stat &&
6238515a235eSJoe Perches		    $line =~ /$mode_perms_search/) {
62392435880fSJoe Perches			foreach my $entry (@mode_permission_funcs) {
62402435880fSJoe Perches				my $func = $entry->[0];
62412435880fSJoe Perches				my $arg_pos = $entry->[1];
62422435880fSJoe Perches
6243459cf0aeSJoe Perches				my $lc = $stat =~ tr@\n@@;
6244459cf0aeSJoe Perches				$lc = $lc + $linenr;
6245459cf0aeSJoe Perches				my $stat_real = raw_line($linenr, 0);
6246459cf0aeSJoe Perches				for (my $count = $linenr + 1; $count <= $lc; $count++) {
6247459cf0aeSJoe Perches					$stat_real = $stat_real . "\n" . raw_line($count, 0);
6248459cf0aeSJoe Perches				}
6249459cf0aeSJoe Perches
62502435880fSJoe Perches				my $skip_args = "";
62512435880fSJoe Perches				if ($arg_pos > 1) {
62522435880fSJoe Perches					$arg_pos--;
62532435880fSJoe Perches					$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
62542435880fSJoe Perches				}
6255f90774e1SJoe Perches				my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
6256459cf0aeSJoe Perches				if ($stat =~ /$test/) {
62572435880fSJoe Perches					my $val = $1;
62582435880fSJoe Perches					$val = $6 if ($skip_args ne "");
6259f90774e1SJoe Perches					if (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
6260f90774e1SJoe Perches					    ($val =~ /^$Octal$/ && length($val) ne 4)) {
62612435880fSJoe Perches						ERROR("NON_OCTAL_PERMISSIONS",
6262459cf0aeSJoe Perches						      "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
6263f90774e1SJoe Perches					}
6264f90774e1SJoe Perches					if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
6265c0a5c898SJoe Perches						ERROR("EXPORTED_WORLD_WRITABLE",
6266459cf0aeSJoe Perches						      "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
62672435880fSJoe Perches					}
6268459cf0aeSJoe Perches				}
6269459cf0aeSJoe Perches			}
6270459cf0aeSJoe Perches		}
6271459cf0aeSJoe Perches
6272459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability
6273459cf0aeSJoe Perches		if ($line =~ /\b$mode_perms_string_search\b/) {
6274459cf0aeSJoe Perches			my $val = "";
6275459cf0aeSJoe Perches			my $oval = "";
6276f90774e1SJoe Perches			my $to = 0;
6277459cf0aeSJoe Perches			my $curpos = 0;
6278459cf0aeSJoe Perches			my $lastpos = 0;
6279459cf0aeSJoe Perches			while ($line =~ /\b(($mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
6280459cf0aeSJoe Perches				$curpos = pos($line);
6281459cf0aeSJoe Perches				my $match = $2;
6282459cf0aeSJoe Perches				my $omatch = $1;
6283459cf0aeSJoe Perches				last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
6284459cf0aeSJoe Perches				$lastpos = $curpos;
6285459cf0aeSJoe Perches				$to |= $mode_permission_string_types{$match};
6286459cf0aeSJoe Perches				$val .= '\s*\|\s*' if ($val ne "");
6287459cf0aeSJoe Perches				$val .= $match;
6288459cf0aeSJoe Perches				$oval .= $omatch;
6289f90774e1SJoe Perches			}
6290459cf0aeSJoe Perches			$oval =~ s/^\s*\|\s*//;
6291459cf0aeSJoe Perches			$oval =~ s/\s*\|\s*$//;
6292459cf0aeSJoe Perches			my $octal = sprintf("%04o", $to);
6293f90774e1SJoe Perches			if (WARN("SYMBOLIC_PERMS",
6294459cf0aeSJoe Perches				 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
6295f90774e1SJoe Perches			    $fix) {
6296459cf0aeSJoe Perches				$fixed[$fixlinenr] =~ s/$val/$octal/;
62972435880fSJoe Perches			}
629813214adfSAndy Whitcroft		}
62995a6d20ceSBjorn Andersson
63005a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h
63015a6d20ceSBjorn Andersson		if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
63025a6d20ceSBjorn Andersson			my $extracted_string = get_quoted_string($line, $rawline);
63035a6d20ceSBjorn Andersson			my $valid_licenses = qr{
63045a6d20ceSBjorn Andersson						GPL|
63055a6d20ceSBjorn Andersson						GPL\ v2|
63065a6d20ceSBjorn Andersson						GPL\ and\ additional\ rights|
63075a6d20ceSBjorn Andersson						Dual\ BSD/GPL|
63085a6d20ceSBjorn Andersson						Dual\ MIT/GPL|
63095a6d20ceSBjorn Andersson						Dual\ MPL/GPL|
63105a6d20ceSBjorn Andersson						Proprietary
63115a6d20ceSBjorn Andersson					}x;
63125a6d20ceSBjorn Andersson			if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
63135a6d20ceSBjorn Andersson				WARN("MODULE_LICENSE",
63145a6d20ceSBjorn Andersson				     "unknown module license " . $extracted_string . "\n" . $herecurr);
63155a6d20ceSBjorn Andersson			}
63165a6d20ceSBjorn Andersson		}
6317515a235eSJoe Perches	}
631813214adfSAndy Whitcroft
631913214adfSAndy Whitcroft	# If we have no input at all, then there is nothing to report on
632013214adfSAndy Whitcroft	# so just keep quiet.
632113214adfSAndy Whitcroft	if ($#rawlines == -1) {
632213214adfSAndy Whitcroft		exit(0);
63230a920b5bSAndy Whitcroft	}
63240a920b5bSAndy Whitcroft
63258905a67cSAndy Whitcroft	# In mailback mode only produce a report in the negative, for
63268905a67cSAndy Whitcroft	# things that appear to be patches.
63278905a67cSAndy Whitcroft	if ($mailback && ($clean == 1 || !$is_patch)) {
63288905a67cSAndy Whitcroft		exit(0);
63298905a67cSAndy Whitcroft	}
63308905a67cSAndy Whitcroft
63318905a67cSAndy Whitcroft	# This is not a patch, and we are are in 'no-patch' mode so
63328905a67cSAndy Whitcroft	# just keep quiet.
63338905a67cSAndy Whitcroft	if (!$chk_patch && !$is_patch) {
63348905a67cSAndy Whitcroft		exit(0);
63358905a67cSAndy Whitcroft	}
63368905a67cSAndy Whitcroft
633706330fc4SJoe Perches	if (!$is_patch && $file !~ /cover-letter\.patch$/) {
6338000d1cc1SJoe Perches		ERROR("NOT_UNIFIED_DIFF",
6339000d1cc1SJoe Perches		      "Does not appear to be a unified-diff format patch\n");
63400a920b5bSAndy Whitcroft	}
6341ed43c4e5SAllen Hubbe	if ($is_patch && $has_commit_log && $chk_signoff && $signoff == 0) {
6342000d1cc1SJoe Perches		ERROR("MISSING_SIGN_OFF",
6343000d1cc1SJoe Perches		      "Missing Signed-off-by: line(s)\n");
63440a920b5bSAndy Whitcroft	}
63450a920b5bSAndy Whitcroft
6346f0a594c1SAndy Whitcroft	print report_dump();
634713214adfSAndy Whitcroft	if ($summary && !($clean == 1 && $quiet == 1)) {
634813214adfSAndy Whitcroft		print "$filename " if ($summary_file);
63496c72ffaaSAndy Whitcroft		print "total: $cnt_error errors, $cnt_warn warnings, " .
63506c72ffaaSAndy Whitcroft			(($check)? "$cnt_chk checks, " : "") .
63516c72ffaaSAndy Whitcroft			"$cnt_lines lines checked\n";
63526c72ffaaSAndy Whitcroft	}
63538905a67cSAndy Whitcroft
6354d2c0a235SAndy Whitcroft	if ($quiet == 0) {
6355ef212196SJoe Perches		# If there were any defects found and not already fixing them
6356ef212196SJoe Perches		if (!$clean and !$fix) {
6357ef212196SJoe Perches			print << "EOM"
6358ef212196SJoe Perches
6359ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to
6360ef212196SJoe Perches      mechanically convert to the typical style using --fix or --fix-inplace.
6361ef212196SJoe PerchesEOM
6362ef212196SJoe Perches		}
6363d2c0a235SAndy Whitcroft		# If there were whitespace errors which cleanpatch can fix
6364d2c0a235SAndy Whitcroft		# then suggest that.
6365d2c0a235SAndy Whitcroft		if ($rpt_cleaners) {
6366b0781216SMike Frysinger			$rpt_cleaners = 0;
6367d8469f16SJoe Perches			print << "EOM"
6368d8469f16SJoe Perches
6369d8469f16SJoe PerchesNOTE: Whitespace errors detected.
6370d8469f16SJoe Perches      You may wish to use scripts/cleanpatch or scripts/cleanfile
6371d8469f16SJoe PerchesEOM
6372d2c0a235SAndy Whitcroft		}
6373d2c0a235SAndy Whitcroft	}
6374d2c0a235SAndy Whitcroft
6375d752fcc8SJoe Perches	if ($clean == 0 && $fix &&
6376d752fcc8SJoe Perches	    ("@rawlines" ne "@fixed" ||
6377d752fcc8SJoe Perches	     $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
63789624b8d6SJoe Perches		my $newfile = $filename;
63799624b8d6SJoe Perches		$newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
63803705ce5bSJoe Perches		my $linecount = 0;
63813705ce5bSJoe Perches		my $f;
63823705ce5bSJoe Perches
6383d752fcc8SJoe Perches		@fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
6384d752fcc8SJoe Perches
63853705ce5bSJoe Perches		open($f, '>', $newfile)
63863705ce5bSJoe Perches		    or die "$P: Can't open $newfile for write\n";
63873705ce5bSJoe Perches		foreach my $fixed_line (@fixed) {
63883705ce5bSJoe Perches			$linecount++;
63893705ce5bSJoe Perches			if ($file) {
63903705ce5bSJoe Perches				if ($linecount > 3) {
63913705ce5bSJoe Perches					$fixed_line =~ s/^\+//;
63923705ce5bSJoe Perches					print $f $fixed_line . "\n";
63933705ce5bSJoe Perches				}
63943705ce5bSJoe Perches			} else {
63953705ce5bSJoe Perches				print $f $fixed_line . "\n";
63963705ce5bSJoe Perches			}
63973705ce5bSJoe Perches		}
63983705ce5bSJoe Perches		close($f);
63993705ce5bSJoe Perches
64003705ce5bSJoe Perches		if (!$quiet) {
64013705ce5bSJoe Perches			print << "EOM";
6402d8469f16SJoe Perches
64033705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile'
64043705ce5bSJoe Perches
64053705ce5bSJoe PerchesDo _NOT_ trust the results written to this file.
64063705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness.
64073705ce5bSJoe Perches
64083705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches.
64093705ce5bSJoe PerchesNo warranties, expressed or implied...
64103705ce5bSJoe PerchesEOM
64113705ce5bSJoe Perches		}
64123705ce5bSJoe Perches	}
64133705ce5bSJoe Perches
6414d8469f16SJoe Perches	if ($quiet == 0) {
6415d8469f16SJoe Perches		print "\n";
6416d8469f16SJoe Perches		if ($clean == 1) {
6417d8469f16SJoe Perches			print "$vname has no obvious style problems and is ready for submission.\n";
6418d8469f16SJoe Perches		} else {
6419d8469f16SJoe Perches			print "$vname has style problems, please review.\n";
64200a920b5bSAndy Whitcroft		}
64210a920b5bSAndy Whitcroft	}
64220a920b5bSAndy Whitcroft	return $clean;
64230a920b5bSAndy Whitcroft}
6424