xref: /linux-6.15/scripts/checkpatch.pl (revision 74fd4f34)
10a920b5bSAndy Whitcroft#!/usr/bin/perl -w
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;
9c707a81dSJoe Perchesuse POSIX;
1036061e38SJoe Perchesuse File::Basename;
1136061e38SJoe Perchesuse Cwd 'abs_path';
1257230297SJoe Perchesuse Term::ANSIColor qw(:constants);
130a920b5bSAndy Whitcroft
140a920b5bSAndy Whitcroftmy $P = $0;
1536061e38SJoe Perchesmy $D = dirname(abs_path($P));
160a920b5bSAndy Whitcroft
17000d1cc1SJoe Perchesmy $V = '0.32';
180a920b5bSAndy Whitcroft
190a920b5bSAndy Whitcroftuse Getopt::Long qw(:config no_auto_abbrev);
200a920b5bSAndy Whitcroft
210a920b5bSAndy Whitcroftmy $quiet = 0;
220a920b5bSAndy Whitcroftmy $tree = 1;
230a920b5bSAndy Whitcroftmy $chk_signoff = 1;
240a920b5bSAndy Whitcroftmy $chk_patch = 1;
25773647a0SAndy Whitcroftmy $tst_only;
266c72ffaaSAndy Whitcroftmy $emacs = 0;
278905a67cSAndy Whitcroftmy $terse = 0;
2834d8815fSJoe Perchesmy $showfile = 0;
296c72ffaaSAndy Whitcroftmy $file = 0;
304a593c34SDu, Changbinmy $git = 0;
310dea9f1eSJoe Perchesmy %git_commits = ();
326c72ffaaSAndy Whitcroftmy $check = 0;
332ac73b4fSJoe Perchesmy $check_orig = 0;
348905a67cSAndy Whitcroftmy $summary = 1;
358905a67cSAndy Whitcroftmy $mailback = 0;
3613214adfSAndy Whitcroftmy $summary_file = 0;
37000d1cc1SJoe Perchesmy $show_types = 0;
383beb42ecSJoe Perchesmy $list_types = 0;
393705ce5bSJoe Perchesmy $fix = 0;
409624b8d6SJoe Perchesmy $fix_inplace = 0;
416c72ffaaSAndy Whitcroftmy $root;
42c2fdda0dSAndy Whitcroftmy %debug;
433445686aSJoe Perchesmy %camelcase = ();
4491bfe484SJoe Perchesmy %use_type = ();
4591bfe484SJoe Perchesmy @use = ();
4691bfe484SJoe Perchesmy %ignore_type = ();
47000d1cc1SJoe Perchesmy @ignore = ();
4877f5b10aSHannes Edermy $help = 0;
49000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf";
506cd7f386SJoe Perchesmy $max_line_length = 80;
51d62a201fSDave Hansenmy $ignore_perl_version = 0;
52d62a201fSDave Hansenmy $minimum_perl_version = 5.10.0;
5356193274SVadim Bendeburymy $min_conf_desc_length = 4;
5466b47b4aSKees Cookmy $spelling_file = "$D/spelling.txt";
55ebfd7d62SJoe Perchesmy $codespell = 0;
56f1a63678SMaxim Uvarovmy $codespellfile = "/usr/share/codespell/dictionary.txt";
57bf1fa1daSJoe Perchesmy $conststructsfile = "$D/const_structs.checkpatch";
5875ad8c57SJerome Forissiermy $typedefsfile = "";
5957230297SJoe Perchesmy $color = 1;
60dadf680dSJoe Perchesmy $allow_c99_comments = 1;
6177f5b10aSHannes Eder
6277f5b10aSHannes Edersub help {
6377f5b10aSHannes Eder	my ($exitcode) = @_;
6477f5b10aSHannes Eder
6577f5b10aSHannes Eder	print << "EOM";
6677f5b10aSHannes EderUsage: $P [OPTION]... [FILE]...
6777f5b10aSHannes EderVersion: $V
6877f5b10aSHannes Eder
6977f5b10aSHannes EderOptions:
7077f5b10aSHannes Eder  -q, --quiet                quiet
7177f5b10aSHannes Eder  --no-tree                  run without a kernel tree
7277f5b10aSHannes Eder  --no-signoff               do not check for 'Signed-off-by' line
7377f5b10aSHannes Eder  --patch                    treat FILE as patchfile (default)
7477f5b10aSHannes Eder  --emacs                    emacs compile window format
7577f5b10aSHannes Eder  --terse                    one line per report
7634d8815fSJoe Perches  --showfile                 emit diffed file position, not input file position
774a593c34SDu, Changbin  -g, --git                  treat FILE as a single commit or git revision range
784a593c34SDu, Changbin                             single git commit with:
794a593c34SDu, Changbin                               <rev>
804a593c34SDu, Changbin                               <rev>^
814a593c34SDu, Changbin                               <rev>~n
824a593c34SDu, Changbin                             multiple git commits with:
834a593c34SDu, Changbin                               <rev1>..<rev2>
844a593c34SDu, Changbin                               <rev1>...<rev2>
854a593c34SDu, Changbin                               <rev>-<count>
864a593c34SDu, Changbin                             git merges are ignored
8777f5b10aSHannes Eder  -f, --file                 treat FILE as regular source file
8877f5b10aSHannes Eder  --subjective, --strict     enable more subjective tests
893beb42ecSJoe Perches  --list-types               list the possible message types
9091bfe484SJoe Perches  --types TYPE(,TYPE2...)    show only these comma separated message types
91000d1cc1SJoe Perches  --ignore TYPE(,TYPE2...)   ignore various comma separated message types
923beb42ecSJoe Perches  --show-types               show the specific message type in the output
936cd7f386SJoe Perches  --max-line-length=n        set the maximum line length, if exceeded, warn
9456193274SVadim Bendebury  --min-conf-desc-length=n   set the min description length, if shorter, warn
9577f5b10aSHannes Eder  --root=PATH                PATH to the kernel tree root
9677f5b10aSHannes Eder  --no-summary               suppress the per-file summary
9777f5b10aSHannes Eder  --mailback                 only produce a report in case of warnings/errors
9877f5b10aSHannes Eder  --summary-file             include the filename in summary
9977f5b10aSHannes Eder  --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of
10077f5b10aSHannes Eder                             'values', 'possible', 'type', and 'attr' (default
10177f5b10aSHannes Eder                             is all off)
10277f5b10aSHannes Eder  --test-only=WORD           report only warnings/errors containing WORD
10377f5b10aSHannes Eder                             literally
1043705ce5bSJoe Perches  --fix                      EXPERIMENTAL - may create horrible results
1053705ce5bSJoe Perches                             If correctable single-line errors exist, create
1063705ce5bSJoe Perches                             "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
1073705ce5bSJoe Perches                             with potential errors corrected to the preferred
1083705ce5bSJoe Perches                             checkpatch style
1099624b8d6SJoe Perches  --fix-inplace              EXPERIMENTAL - may create horrible results
1109624b8d6SJoe Perches                             Is the same as --fix, but overwrites the input
1119624b8d6SJoe Perches                             file.  It's your fault if there's no backup or git
112d62a201fSDave Hansen  --ignore-perl-version      override checking of perl version.  expect
113d62a201fSDave Hansen                             runtime errors.
114ebfd7d62SJoe Perches  --codespell                Use the codespell dictionary for spelling/typos
115f1a63678SMaxim Uvarov                             (default:/usr/share/codespell/dictionary.txt)
116ebfd7d62SJoe Perches  --codespellfile            Use this codespell dictionary
11775ad8c57SJerome Forissier  --typedefsfile             Read additional types from this file
11857230297SJoe Perches  --color                    Use colors when output is STDOUT (default: on)
11977f5b10aSHannes Eder  -h, --help, --version      display this help and exit
12077f5b10aSHannes Eder
12177f5b10aSHannes EderWhen FILE is - read standard input.
12277f5b10aSHannes EderEOM
12377f5b10aSHannes Eder
12477f5b10aSHannes Eder	exit($exitcode);
12577f5b10aSHannes Eder}
12677f5b10aSHannes Eder
1273beb42ecSJoe Perchessub uniq {
1283beb42ecSJoe Perches	my %seen;
1293beb42ecSJoe Perches	return grep { !$seen{$_}++ } @_;
1303beb42ecSJoe Perches}
1313beb42ecSJoe Perches
1323beb42ecSJoe Perchessub list_types {
1333beb42ecSJoe Perches	my ($exitcode) = @_;
1343beb42ecSJoe Perches
1353beb42ecSJoe Perches	my $count = 0;
1363beb42ecSJoe Perches
1373beb42ecSJoe Perches	local $/ = undef;
1383beb42ecSJoe Perches
1393beb42ecSJoe Perches	open(my $script, '<', abs_path($P)) or
1403beb42ecSJoe Perches	    die "$P: Can't read '$P' $!\n";
1413beb42ecSJoe Perches
1423beb42ecSJoe Perches	my $text = <$script>;
1433beb42ecSJoe Perches	close($script);
1443beb42ecSJoe Perches
1453beb42ecSJoe Perches	my @types = ();
1463beb42ecSJoe Perches	for ($text =~ /\b(?:(?:CHK|WARN|ERROR)\s*\(\s*"([^"]+)")/g) {
1473beb42ecSJoe Perches		push (@types, $_);
1483beb42ecSJoe Perches	}
1493beb42ecSJoe Perches	@types = sort(uniq(@types));
1503beb42ecSJoe Perches	print("#\tMessage type\n\n");
1513beb42ecSJoe Perches	foreach my $type (@types) {
1523beb42ecSJoe Perches		print(++$count . "\t" . $type . "\n");
1533beb42ecSJoe Perches	}
1543beb42ecSJoe Perches
1553beb42ecSJoe Perches	exit($exitcode);
1563beb42ecSJoe Perches}
1573beb42ecSJoe Perches
158000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file);
159000d1cc1SJoe Perchesif (-f $conf) {
160000d1cc1SJoe Perches	my @conf_args;
161000d1cc1SJoe Perches	open(my $conffile, '<', "$conf")
162000d1cc1SJoe Perches	    or warn "$P: Can't find a readable $configuration_file file $!\n";
163000d1cc1SJoe Perches
164000d1cc1SJoe Perches	while (<$conffile>) {
165000d1cc1SJoe Perches		my $line = $_;
166000d1cc1SJoe Perches
167000d1cc1SJoe Perches		$line =~ s/\s*\n?$//g;
168000d1cc1SJoe Perches		$line =~ s/^\s*//g;
169000d1cc1SJoe Perches		$line =~ s/\s+/ /g;
170000d1cc1SJoe Perches
171000d1cc1SJoe Perches		next if ($line =~ m/^\s*#/);
172000d1cc1SJoe Perches		next if ($line =~ m/^\s*$/);
173000d1cc1SJoe Perches
174000d1cc1SJoe Perches		my @words = split(" ", $line);
175000d1cc1SJoe Perches		foreach my $word (@words) {
176000d1cc1SJoe Perches			last if ($word =~ m/^#/);
177000d1cc1SJoe Perches			push (@conf_args, $word);
178000d1cc1SJoe Perches		}
179000d1cc1SJoe Perches	}
180000d1cc1SJoe Perches	close($conffile);
181000d1cc1SJoe Perches	unshift(@ARGV, @conf_args) if @conf_args;
182000d1cc1SJoe Perches}
183000d1cc1SJoe Perches
1840a920b5bSAndy WhitcroftGetOptions(
1856c72ffaaSAndy Whitcroft	'q|quiet+'	=> \$quiet,
1860a920b5bSAndy Whitcroft	'tree!'		=> \$tree,
1870a920b5bSAndy Whitcroft	'signoff!'	=> \$chk_signoff,
1880a920b5bSAndy Whitcroft	'patch!'	=> \$chk_patch,
1896c72ffaaSAndy Whitcroft	'emacs!'	=> \$emacs,
1908905a67cSAndy Whitcroft	'terse!'	=> \$terse,
19134d8815fSJoe Perches	'showfile!'	=> \$showfile,
19277f5b10aSHannes Eder	'f|file!'	=> \$file,
1934a593c34SDu, Changbin	'g|git!'	=> \$git,
1946c72ffaaSAndy Whitcroft	'subjective!'	=> \$check,
1956c72ffaaSAndy Whitcroft	'strict!'	=> \$check,
196000d1cc1SJoe Perches	'ignore=s'	=> \@ignore,
19791bfe484SJoe Perches	'types=s'	=> \@use,
198000d1cc1SJoe Perches	'show-types!'	=> \$show_types,
1993beb42ecSJoe Perches	'list-types!'	=> \$list_types,
2006cd7f386SJoe Perches	'max-line-length=i' => \$max_line_length,
20156193274SVadim Bendebury	'min-conf-desc-length=i' => \$min_conf_desc_length,
2026c72ffaaSAndy Whitcroft	'root=s'	=> \$root,
2038905a67cSAndy Whitcroft	'summary!'	=> \$summary,
2048905a67cSAndy Whitcroft	'mailback!'	=> \$mailback,
20513214adfSAndy Whitcroft	'summary-file!'	=> \$summary_file,
2063705ce5bSJoe Perches	'fix!'		=> \$fix,
2079624b8d6SJoe Perches	'fix-inplace!'	=> \$fix_inplace,
208d62a201fSDave Hansen	'ignore-perl-version!' => \$ignore_perl_version,
209c2fdda0dSAndy Whitcroft	'debug=s'	=> \%debug,
210773647a0SAndy Whitcroft	'test-only=s'	=> \$tst_only,
211ebfd7d62SJoe Perches	'codespell!'	=> \$codespell,
212ebfd7d62SJoe Perches	'codespellfile=s'	=> \$codespellfile,
21375ad8c57SJerome Forissier	'typedefsfile=s'	=> \$typedefsfile,
21457230297SJoe Perches	'color!'	=> \$color,
21577f5b10aSHannes Eder	'h|help'	=> \$help,
21677f5b10aSHannes Eder	'version'	=> \$help
21777f5b10aSHannes Eder) or help(1);
21877f5b10aSHannes Eder
21977f5b10aSHannes Ederhelp(0) if ($help);
2200a920b5bSAndy Whitcroft
2213beb42ecSJoe Percheslist_types(0) if ($list_types);
2223beb42ecSJoe Perches
2239624b8d6SJoe Perches$fix = 1 if ($fix_inplace);
2242ac73b4fSJoe Perches$check_orig = $check;
2259624b8d6SJoe Perches
2260a920b5bSAndy Whitcroftmy $exit = 0;
2270a920b5bSAndy Whitcroft
228d62a201fSDave Hansenif ($^V && $^V lt $minimum_perl_version) {
229d62a201fSDave Hansen	printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
230d62a201fSDave Hansen	if (!$ignore_perl_version) {
231d62a201fSDave Hansen		exit(1);
232d62a201fSDave Hansen	}
233d62a201fSDave Hansen}
234d62a201fSDave Hansen
23545107ff6SAllen Hubbe#if no filenames are given, push '-' to read patch from stdin
2360a920b5bSAndy Whitcroftif ($#ARGV < 0) {
23745107ff6SAllen Hubbe	push(@ARGV, '-');
2380a920b5bSAndy Whitcroft}
2390a920b5bSAndy Whitcroft
24091bfe484SJoe Perchessub hash_save_array_words {
24191bfe484SJoe Perches	my ($hashRef, $arrayRef) = @_;
24291bfe484SJoe Perches
24391bfe484SJoe Perches	my @array = split(/,/, join(',', @$arrayRef));
24491bfe484SJoe Perches	foreach my $word (@array) {
245000d1cc1SJoe Perches		$word =~ s/\s*\n?$//g;
246000d1cc1SJoe Perches		$word =~ s/^\s*//g;
247000d1cc1SJoe Perches		$word =~ s/\s+/ /g;
248000d1cc1SJoe Perches		$word =~ tr/[a-z]/[A-Z]/;
249000d1cc1SJoe Perches
250000d1cc1SJoe Perches		next if ($word =~ m/^\s*#/);
251000d1cc1SJoe Perches		next if ($word =~ m/^\s*$/);
252000d1cc1SJoe Perches
25391bfe484SJoe Perches		$hashRef->{$word}++;
254000d1cc1SJoe Perches	}
25591bfe484SJoe Perches}
25691bfe484SJoe Perches
25791bfe484SJoe Perchessub hash_show_words {
25891bfe484SJoe Perches	my ($hashRef, $prefix) = @_;
25991bfe484SJoe Perches
2603c816e49SJoe Perches	if (keys %$hashRef) {
261d8469f16SJoe Perches		print "\nNOTE: $prefix message types:";
26258cb3cf6SJoe Perches		foreach my $word (sort keys %$hashRef) {
26391bfe484SJoe Perches			print " $word";
26491bfe484SJoe Perches		}
265d8469f16SJoe Perches		print "\n";
26691bfe484SJoe Perches	}
26791bfe484SJoe Perches}
26891bfe484SJoe Perches
26991bfe484SJoe Percheshash_save_array_words(\%ignore_type, \@ignore);
27091bfe484SJoe Percheshash_save_array_words(\%use_type, \@use);
271000d1cc1SJoe Perches
272c2fdda0dSAndy Whitcroftmy $dbg_values = 0;
273c2fdda0dSAndy Whitcroftmy $dbg_possible = 0;
2747429c690SAndy Whitcroftmy $dbg_type = 0;
275a1ef277eSAndy Whitcroftmy $dbg_attr = 0;
276c2fdda0dSAndy Whitcroftfor my $key (keys %debug) {
27721caa13cSAndy Whitcroft	## no critic
27821caa13cSAndy Whitcroft	eval "\${dbg_$key} = '$debug{$key}';";
27921caa13cSAndy Whitcroft	die "$@" if ($@);
280c2fdda0dSAndy Whitcroft}
281c2fdda0dSAndy Whitcroft
282d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0;
283d2c0a235SAndy Whitcroft
2848905a67cSAndy Whitcroftif ($terse) {
2858905a67cSAndy Whitcroft	$emacs = 1;
2868905a67cSAndy Whitcroft	$quiet++;
2878905a67cSAndy Whitcroft}
2888905a67cSAndy Whitcroft
2896c72ffaaSAndy Whitcroftif ($tree) {
2906c72ffaaSAndy Whitcroft	if (defined $root) {
2916c72ffaaSAndy Whitcroft		if (!top_of_kernel_tree($root)) {
2926c72ffaaSAndy Whitcroft			die "$P: $root: --root does not point at a valid tree\n";
2936c72ffaaSAndy Whitcroft		}
2946c72ffaaSAndy Whitcroft	} else {
2956c72ffaaSAndy Whitcroft		if (top_of_kernel_tree('.')) {
2966c72ffaaSAndy Whitcroft			$root = '.';
2976c72ffaaSAndy Whitcroft		} elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
2986c72ffaaSAndy Whitcroft						top_of_kernel_tree($1)) {
2996c72ffaaSAndy Whitcroft			$root = $1;
3006c72ffaaSAndy Whitcroft		}
3016c72ffaaSAndy Whitcroft	}
3026c72ffaaSAndy Whitcroft
3036c72ffaaSAndy Whitcroft	if (!defined $root) {
3040a920b5bSAndy Whitcroft		print "Must be run from the top-level dir. of a kernel tree\n";
3050a920b5bSAndy Whitcroft		exit(2);
3060a920b5bSAndy Whitcroft	}
3076c72ffaaSAndy Whitcroft}
3086c72ffaaSAndy Whitcroft
3096c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0;
3106c72ffaaSAndy Whitcroft
3112ceb532bSAndy Whitcroftour $Ident	= qr{
3122ceb532bSAndy Whitcroft			[A-Za-z_][A-Za-z\d_]*
3132ceb532bSAndy Whitcroft			(?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
3142ceb532bSAndy Whitcroft		}x;
3156c72ffaaSAndy Whitcroftour $Storage	= qr{extern|static|asmlinkage};
3166c72ffaaSAndy Whitcroftour $Sparse	= qr{
3176c72ffaaSAndy Whitcroft			__user|
3186c72ffaaSAndy Whitcroft			__kernel|
3196c72ffaaSAndy Whitcroft			__force|
3206c72ffaaSAndy Whitcroft			__iomem|
3216c72ffaaSAndy Whitcroft			__must_check|
3226c72ffaaSAndy Whitcroft			__init_refok|
323417495edSAndy Whitcroft			__kprobes|
324165e72a6SSven Eckelmann			__ref|
325ad315455SBoqun Feng			__rcu|
326ad315455SBoqun Feng			__private
3276c72ffaaSAndy Whitcroft		}x;
328e970b884SJoe Perchesour $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
329e970b884SJoe Perchesour $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
330e970b884SJoe Perchesour $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
331e970b884SJoe Perchesour $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
332e970b884SJoe Perchesour $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
3338716de38SJoe Perches
33452131292SWolfram Sang# Notes to $Attribute:
33552131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
3366c72ffaaSAndy Whitcroftour $Attribute	= qr{
3376c72ffaaSAndy Whitcroft			const|
33803f1df7dSJoe Perches			__percpu|
33903f1df7dSJoe Perches			__nocast|
34003f1df7dSJoe Perches			__safe|
34146d832f5SMichael S. Tsirkin			__bitwise|
34203f1df7dSJoe Perches			__packed__|
34303f1df7dSJoe Perches			__packed2__|
34403f1df7dSJoe Perches			__naked|
34503f1df7dSJoe Perches			__maybe_unused|
34603f1df7dSJoe Perches			__always_unused|
34703f1df7dSJoe Perches			__noreturn|
34803f1df7dSJoe Perches			__used|
34903f1df7dSJoe Perches			__cold|
350e23ef1f3SJoe Perches			__pure|
35103f1df7dSJoe Perches			__noclone|
35203f1df7dSJoe Perches			__deprecated|
3536c72ffaaSAndy Whitcroft			__read_mostly|
3546c72ffaaSAndy Whitcroft			__kprobes|
3558716de38SJoe Perches			$InitAttribute|
35624e1d81aSAndy Whitcroft			____cacheline_aligned|
35724e1d81aSAndy Whitcroft			____cacheline_aligned_in_smp|
3585fe3af11SAndy Whitcroft			____cacheline_internodealigned_in_smp|
3595fe3af11SAndy Whitcroft			__weak
3606c72ffaaSAndy Whitcroft		  }x;
361c45dcabdSAndy Whitcroftour $Modifier;
36291cb5195SJoe Perchesour $Inline	= qr{inline|__always_inline|noinline|__inline|__inline__};
3636c72ffaaSAndy Whitcroftour $Member	= qr{->$Ident|\.$Ident|\[[^]]*\]};
3646c72ffaaSAndy Whitcroftour $Lval	= qr{$Ident(?:$Member)*};
3656c72ffaaSAndy Whitcroft
36695e2c602SJoe Perchesour $Int_type	= qr{(?i)llu|ull|ll|lu|ul|l|u};
36795e2c602SJoe Perchesour $Binary	= qr{(?i)0b[01]+$Int_type?};
36895e2c602SJoe Perchesour $Hex	= qr{(?i)0x[0-9a-f]+$Int_type?};
36995e2c602SJoe Perchesour $Int	= qr{[0-9]+$Int_type?};
3702435880fSJoe Perchesour $Octal	= qr{0[0-7]+$Int_type?};
371c0a5c898SJoe Perchesour $String	= qr{"[X\t]*"};
372326b1ffcSJoe Perchesour $Float_hex	= qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
373326b1ffcSJoe Perchesour $Float_dec	= qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
374326b1ffcSJoe Perchesour $Float_int	= qr{(?i)[0-9]+e-?[0-9]+[fl]?};
37574349bccSJoe Perchesour $Float	= qr{$Float_hex|$Float_dec|$Float_int};
3762435880fSJoe Perchesour $Constant	= qr{$Float|$Binary|$Octal|$Hex|$Int};
377326b1ffcSJoe Perchesour $Assignment	= qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
378447432f3SJoe Perchesour $Compare    = qr{<=|>=|==|!=|<|(?<!-)>};
37923f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%};
3806c72ffaaSAndy Whitcroftour $Operators	= qr{
3816c72ffaaSAndy Whitcroft			<=|>=|==|!=|
3826c72ffaaSAndy Whitcroft			=>|->|<<|>>|<|>|!|~|
38323f780c9SJoe Perches			&&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
3846c72ffaaSAndy Whitcroft		  }x;
3856c72ffaaSAndy Whitcroft
38691cb5195SJoe Perchesour $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
38791cb5195SJoe Perches
388ab7e23f3SJoe Perchesour $BasicType;
3898905a67cSAndy Whitcroftour $NonptrType;
3901813087dSJoe Perchesour $NonptrTypeMisordered;
3918716de38SJoe Perchesour $NonptrTypeWithAttr;
3928905a67cSAndy Whitcroftour $Type;
3931813087dSJoe Perchesour $TypeMisordered;
3948905a67cSAndy Whitcroftour $Declare;
3951813087dSJoe Perchesour $DeclareMisordered;
3968905a67cSAndy Whitcroft
39715662b3eSJoe Perchesour $NON_ASCII_UTF8	= qr{
39815662b3eSJoe Perches	[\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte
399171ae1a4SAndy Whitcroft	|  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
400171ae1a4SAndy Whitcroft	| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
401171ae1a4SAndy Whitcroft	|  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
402171ae1a4SAndy Whitcroft	|  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
403171ae1a4SAndy Whitcroft	| [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
404171ae1a4SAndy Whitcroft	|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
405171ae1a4SAndy Whitcroft}x;
406171ae1a4SAndy Whitcroft
40715662b3eSJoe Perchesour $UTF8	= qr{
40815662b3eSJoe Perches	[\x09\x0A\x0D\x20-\x7E]              # ASCII
40915662b3eSJoe Perches	| $NON_ASCII_UTF8
41015662b3eSJoe Perches}x;
41115662b3eSJoe Perches
412e6176fa4SJoe Perchesour $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
413021158b4SJoe Perchesour $typeOtherOSTypedefs = qr{(?x:
414021158b4SJoe Perches	u_(?:char|short|int|long) |          # bsd
415021158b4SJoe Perches	u(?:nchar|short|int|long)            # sysv
416021158b4SJoe Perches)};
417e6176fa4SJoe Perchesour $typeKernelTypedefs = qr{(?x:
418fb9e9096SAndy Whitcroft	(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
4198ed22cadSAndy Whitcroft	atomic_t
4208ed22cadSAndy Whitcroft)};
421e6176fa4SJoe Perchesour $typeTypedefs = qr{(?x:
422e6176fa4SJoe Perches	$typeC99Typedefs\b|
423e6176fa4SJoe Perches	$typeOtherOSTypedefs\b|
424e6176fa4SJoe Perches	$typeKernelTypedefs\b
425e6176fa4SJoe Perches)};
4268ed22cadSAndy Whitcroft
4276d32f7a3SJoe Perchesour $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
4286d32f7a3SJoe Perches
429691e669bSJoe Perchesour $logFunctions = qr{(?x:
430758d7aadSMiles Chen	printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
4317d0b6594SJacob Keller	(?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
4326e60c02eSJoe Perches	WARN(?:_RATELIMIT|_ONCE|)|
433b0531722SJoe Perches	panic|
43406668727SJoe Perches	MODULE_[A-Z_]+|
43506668727SJoe Perches	seq_vprintf|seq_printf|seq_puts
436691e669bSJoe Perches)};
437691e669bSJoe Perches
43820112475SJoe Perchesour $signature_tags = qr{(?xi:
43920112475SJoe Perches	Signed-off-by:|
44020112475SJoe Perches	Acked-by:|
44120112475SJoe Perches	Tested-by:|
44220112475SJoe Perches	Reviewed-by:|
44320112475SJoe Perches	Reported-by:|
4448543ae12SMugunthan V N	Suggested-by:|
44520112475SJoe Perches	To:|
44620112475SJoe Perches	Cc:
44720112475SJoe Perches)};
44820112475SJoe Perches
4491813087dSJoe Perchesour @typeListMisordered = (
4501813087dSJoe Perches	qr{char\s+(?:un)?signed},
4511813087dSJoe Perches	qr{int\s+(?:(?:un)?signed\s+)?short\s},
4521813087dSJoe Perches	qr{int\s+short(?:\s+(?:un)?signed)},
4531813087dSJoe Perches	qr{short\s+int(?:\s+(?:un)?signed)},
4541813087dSJoe Perches	qr{(?:un)?signed\s+int\s+short},
4551813087dSJoe Perches	qr{short\s+(?:un)?signed},
4561813087dSJoe Perches	qr{long\s+int\s+(?:un)?signed},
4571813087dSJoe Perches	qr{int\s+long\s+(?:un)?signed},
4581813087dSJoe Perches	qr{long\s+(?:un)?signed\s+int},
4591813087dSJoe Perches	qr{int\s+(?:un)?signed\s+long},
4601813087dSJoe Perches	qr{int\s+(?:un)?signed},
4611813087dSJoe Perches	qr{int\s+long\s+long\s+(?:un)?signed},
4621813087dSJoe Perches	qr{long\s+long\s+int\s+(?:un)?signed},
4631813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed\s+int},
4641813087dSJoe Perches	qr{long\s+long\s+(?:un)?signed},
4651813087dSJoe Perches	qr{long\s+(?:un)?signed},
4661813087dSJoe Perches);
4671813087dSJoe Perches
4688905a67cSAndy Whitcroftour @typeList = (
4698905a67cSAndy Whitcroft	qr{void},
4700c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?char},
4710c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short\s+int},
4720c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?short},
4730c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?int},
4740c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+int},
4750c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
4760c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long\s+long},
4770c773d9dSJoe Perches	qr{(?:(?:un)?signed\s+)?long},
4780c773d9dSJoe Perches	qr{(?:un)?signed},
4798905a67cSAndy Whitcroft	qr{float},
4808905a67cSAndy Whitcroft	qr{double},
4818905a67cSAndy Whitcroft	qr{bool},
4828905a67cSAndy Whitcroft	qr{struct\s+$Ident},
4838905a67cSAndy Whitcroft	qr{union\s+$Ident},
4848905a67cSAndy Whitcroft	qr{enum\s+$Ident},
4858905a67cSAndy Whitcroft	qr{${Ident}_t},
4868905a67cSAndy Whitcroft	qr{${Ident}_handler},
4878905a67cSAndy Whitcroft	qr{${Ident}_handler_fn},
4881813087dSJoe Perches	@typeListMisordered,
4898905a67cSAndy Whitcroft);
490938224b5SJoe Perches
491938224b5SJoe Perchesour $C90_int_types = qr{(?x:
492938224b5SJoe Perches	long\s+long\s+int\s+(?:un)?signed|
493938224b5SJoe Perches	long\s+long\s+(?:un)?signed\s+int|
494938224b5SJoe Perches	long\s+long\s+(?:un)?signed|
495938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long\s+int|
496938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+long|
497938224b5SJoe Perches	int\s+long\s+long\s+(?:un)?signed|
498938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long\s+long|
499938224b5SJoe Perches
500938224b5SJoe Perches	long\s+int\s+(?:un)?signed|
501938224b5SJoe Perches	long\s+(?:un)?signed\s+int|
502938224b5SJoe Perches	long\s+(?:un)?signed|
503938224b5SJoe Perches	(?:(?:un)?signed\s+)?long\s+int|
504938224b5SJoe Perches	(?:(?:un)?signed\s+)?long|
505938224b5SJoe Perches	int\s+long\s+(?:un)?signed|
506938224b5SJoe Perches	int\s+(?:(?:un)?signed\s+)?long|
507938224b5SJoe Perches
508938224b5SJoe Perches	int\s+(?:un)?signed|
509938224b5SJoe Perches	(?:(?:un)?signed\s+)?int
510938224b5SJoe Perches)};
511938224b5SJoe Perches
512485ff23eSAlex Dowadour @typeListFile = ();
5138716de38SJoe Perchesour @typeListWithAttr = (
5148716de38SJoe Perches	@typeList,
5158716de38SJoe Perches	qr{struct\s+$InitAttribute\s+$Ident},
5168716de38SJoe Perches	qr{union\s+$InitAttribute\s+$Ident},
5178716de38SJoe Perches);
5188716de38SJoe Perches
519c45dcabdSAndy Whitcroftour @modifierList = (
520c45dcabdSAndy Whitcroft	qr{fastcall},
521c45dcabdSAndy Whitcroft);
522485ff23eSAlex Dowadour @modifierListFile = ();
5238905a67cSAndy Whitcroft
5242435880fSJoe Perchesour @mode_permission_funcs = (
5252435880fSJoe Perches	["module_param", 3],
5262435880fSJoe Perches	["module_param_(?:array|named|string)", 4],
5272435880fSJoe Perches	["module_param_array_named", 5],
5282435880fSJoe Perches	["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
5292435880fSJoe Perches	["proc_create(?:_data|)", 2],
530459cf0aeSJoe Perches	["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
531459cf0aeSJoe Perches	["IIO_DEV_ATTR_[A-Z_]+", 1],
532459cf0aeSJoe Perches	["SENSOR_(?:DEVICE_|)ATTR_2", 2],
533459cf0aeSJoe Perches	["SENSOR_TEMPLATE(?:_2|)", 3],
534459cf0aeSJoe Perches	["__ATTR", 2],
5352435880fSJoe Perches);
5362435880fSJoe Perches
537515a235eSJoe Perches#Create a search pattern for all these functions to speed up a loop below
538515a235eSJoe Perchesour $mode_perms_search = "";
539515a235eSJoe Perchesforeach my $entry (@mode_permission_funcs) {
540515a235eSJoe Perches	$mode_perms_search .= '|' if ($mode_perms_search ne "");
541515a235eSJoe Perches	$mode_perms_search .= $entry->[0];
542515a235eSJoe Perches}
543515a235eSJoe Perches
544b392c64fSJoe Perchesour $mode_perms_world_writable = qr{
545b392c64fSJoe Perches	S_IWUGO		|
546b392c64fSJoe Perches	S_IWOTH		|
547b392c64fSJoe Perches	S_IRWXUGO	|
548b392c64fSJoe Perches	S_IALLUGO	|
549b392c64fSJoe Perches	0[0-7][0-7][2367]
550b392c64fSJoe Perches}x;
551b392c64fSJoe Perches
552f90774e1SJoe Perchesour %mode_permission_string_types = (
553f90774e1SJoe Perches	"S_IRWXU" => 0700,
554f90774e1SJoe Perches	"S_IRUSR" => 0400,
555f90774e1SJoe Perches	"S_IWUSR" => 0200,
556f90774e1SJoe Perches	"S_IXUSR" => 0100,
557f90774e1SJoe Perches	"S_IRWXG" => 0070,
558f90774e1SJoe Perches	"S_IRGRP" => 0040,
559f90774e1SJoe Perches	"S_IWGRP" => 0020,
560f90774e1SJoe Perches	"S_IXGRP" => 0010,
561f90774e1SJoe Perches	"S_IRWXO" => 0007,
562f90774e1SJoe Perches	"S_IROTH" => 0004,
563f90774e1SJoe Perches	"S_IWOTH" => 0002,
564f90774e1SJoe Perches	"S_IXOTH" => 0001,
565f90774e1SJoe Perches	"S_IRWXUGO" => 0777,
566f90774e1SJoe Perches	"S_IRUGO" => 0444,
567f90774e1SJoe Perches	"S_IWUGO" => 0222,
568f90774e1SJoe Perches	"S_IXUGO" => 0111,
569f90774e1SJoe Perches);
570f90774e1SJoe Perches
571f90774e1SJoe Perches#Create a search pattern for all these strings to speed up a loop below
572f90774e1SJoe Perchesour $mode_perms_string_search = "";
573f90774e1SJoe Perchesforeach my $entry (keys %mode_permission_string_types) {
574f90774e1SJoe Perches	$mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
575f90774e1SJoe Perches	$mode_perms_string_search .= $entry;
576f90774e1SJoe Perches}
577f90774e1SJoe Perches
5787840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x:
5797840a94cSWolfram Sang	irq|
580cdcee686SSergey Ryazanov	memory|
581cdcee686SSergey Ryazanov	time|
582cdcee686SSergey Ryazanov	reboot
5837840a94cSWolfram Sang)};
5847840a94cSWolfram Sang# memory.h: ARM has a custom one
5857840a94cSWolfram Sang
58666b47b4aSKees Cook# Load common spelling mistakes and build regular expression list.
58766b47b4aSKees Cookmy $misspellings;
58866b47b4aSKees Cookmy %spelling_fix;
58936061e38SJoe Perches
59036061e38SJoe Perchesif (open(my $spelling, '<', $spelling_file)) {
59166b47b4aSKees Cook	while (<$spelling>) {
59266b47b4aSKees Cook		my $line = $_;
59366b47b4aSKees Cook
59466b47b4aSKees Cook		$line =~ s/\s*\n?$//g;
59566b47b4aSKees Cook		$line =~ s/^\s*//g;
59666b47b4aSKees Cook
59766b47b4aSKees Cook		next if ($line =~ m/^\s*#/);
59866b47b4aSKees Cook		next if ($line =~ m/^\s*$/);
59966b47b4aSKees Cook
60066b47b4aSKees Cook		my ($suspect, $fix) = split(/\|\|/, $line);
60166b47b4aSKees Cook
60266b47b4aSKees Cook		$spelling_fix{$suspect} = $fix;
60366b47b4aSKees Cook	}
60466b47b4aSKees Cook	close($spelling);
60536061e38SJoe Perches} else {
60636061e38SJoe Perches	warn "No typos will be found - file '$spelling_file': $!\n";
60736061e38SJoe Perches}
60866b47b4aSKees Cook
609ebfd7d62SJoe Perchesif ($codespell) {
610ebfd7d62SJoe Perches	if (open(my $spelling, '<', $codespellfile)) {
611ebfd7d62SJoe Perches		while (<$spelling>) {
612ebfd7d62SJoe Perches			my $line = $_;
613ebfd7d62SJoe Perches
614ebfd7d62SJoe Perches			$line =~ s/\s*\n?$//g;
615ebfd7d62SJoe Perches			$line =~ s/^\s*//g;
616ebfd7d62SJoe Perches
617ebfd7d62SJoe Perches			next if ($line =~ m/^\s*#/);
618ebfd7d62SJoe Perches			next if ($line =~ m/^\s*$/);
619ebfd7d62SJoe Perches			next if ($line =~ m/, disabled/i);
620ebfd7d62SJoe Perches
621ebfd7d62SJoe Perches			$line =~ s/,.*$//;
622ebfd7d62SJoe Perches
623ebfd7d62SJoe Perches			my ($suspect, $fix) = split(/->/, $line);
624ebfd7d62SJoe Perches
625ebfd7d62SJoe Perches			$spelling_fix{$suspect} = $fix;
626ebfd7d62SJoe Perches		}
627ebfd7d62SJoe Perches		close($spelling);
628ebfd7d62SJoe Perches	} else {
629ebfd7d62SJoe Perches		warn "No codespell typos will be found - file '$codespellfile': $!\n";
630ebfd7d62SJoe Perches	}
631ebfd7d62SJoe Perches}
632ebfd7d62SJoe Perches
633ebfd7d62SJoe Perches$misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
634ebfd7d62SJoe Perches
63575ad8c57SJerome Forissiersub read_words {
63675ad8c57SJerome Forissier	my ($wordsRef, $file) = @_;
63775ad8c57SJerome Forissier
63875ad8c57SJerome Forissier	if (open(my $words, '<', $file)) {
63975ad8c57SJerome Forissier		while (<$words>) {
640bf1fa1daSJoe Perches			my $line = $_;
641bf1fa1daSJoe Perches
642bf1fa1daSJoe Perches			$line =~ s/\s*\n?$//g;
643bf1fa1daSJoe Perches			$line =~ s/^\s*//g;
644bf1fa1daSJoe Perches
645bf1fa1daSJoe Perches			next if ($line =~ m/^\s*#/);
646bf1fa1daSJoe Perches			next if ($line =~ m/^\s*$/);
647bf1fa1daSJoe Perches			if ($line =~ /\s/) {
64875ad8c57SJerome Forissier				print("$file: '$line' invalid - ignored\n");
649bf1fa1daSJoe Perches				next;
650bf1fa1daSJoe Perches			}
651bf1fa1daSJoe Perches
65275ad8c57SJerome Forissier			$$wordsRef .= '|' if ($$wordsRef ne "");
65375ad8c57SJerome Forissier			$$wordsRef .= $line;
654bf1fa1daSJoe Perches		}
65575ad8c57SJerome Forissier		close($file);
65675ad8c57SJerome Forissier		return 1;
657bf1fa1daSJoe Perches	}
658bf1fa1daSJoe Perches
65975ad8c57SJerome Forissier	return 0;
66075ad8c57SJerome Forissier}
66175ad8c57SJerome Forissier
66275ad8c57SJerome Forissiermy $const_structs = "";
66375ad8c57SJerome Forissierread_words(\$const_structs, $conststructsfile)
66475ad8c57SJerome Forissier    or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
66575ad8c57SJerome Forissier
66675ad8c57SJerome Forissiermy $typeOtherTypedefs = "";
66775ad8c57SJerome Forissierif (length($typedefsfile)) {
66875ad8c57SJerome Forissier	read_words(\$typeOtherTypedefs, $typedefsfile)
66975ad8c57SJerome Forissier	    or warn "No additional types will be considered - file '$typedefsfile': $!\n";
67075ad8c57SJerome Forissier}
67175ad8c57SJerome Forissier$typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne "");
67275ad8c57SJerome Forissier
6738905a67cSAndy Whitcroftsub build_types {
674485ff23eSAlex Dowad	my $mods = "(?x:  \n" . join("|\n  ", (@modifierList, @modifierListFile)) . "\n)";
675485ff23eSAlex Dowad	my $all = "(?x:  \n" . join("|\n  ", (@typeList, @typeListFile)) . "\n)";
6761813087dSJoe Perches	my $Misordered = "(?x:  \n" . join("|\n  ", @typeListMisordered) . "\n)";
6778716de38SJoe Perches	my $allWithAttr = "(?x:  \n" . join("|\n  ", @typeListWithAttr) . "\n)";
678c8cb2ca3SAndy Whitcroft	$Modifier	= qr{(?:$Attribute|$Sparse|$mods)};
679ab7e23f3SJoe Perches	$BasicType	= qr{
680ab7e23f3SJoe Perches				(?:$typeTypedefs\b)|
681ab7e23f3SJoe Perches				(?:${all}\b)
682ab7e23f3SJoe Perches		}x;
6838905a67cSAndy Whitcroft	$NonptrType	= qr{
684d2172eb5SAndy Whitcroft			(?:$Modifier\s+|const\s+)*
685cf655043SAndy Whitcroft			(?:
6866b48db24SAndy Whitcroft				(?:typeof|__typeof__)\s*\([^\)]*\)|
6878ed22cadSAndy Whitcroft				(?:$typeTypedefs\b)|
688c45dcabdSAndy Whitcroft				(?:${all}\b)
689cf655043SAndy Whitcroft			)
690c8cb2ca3SAndy Whitcroft			(?:\s+$Modifier|\s+const)*
6918905a67cSAndy Whitcroft		  }x;
6921813087dSJoe Perches	$NonptrTypeMisordered	= qr{
6931813087dSJoe Perches			(?:$Modifier\s+|const\s+)*
6941813087dSJoe Perches			(?:
6951813087dSJoe Perches				(?:${Misordered}\b)
6961813087dSJoe Perches			)
6971813087dSJoe Perches			(?:\s+$Modifier|\s+const)*
6981813087dSJoe Perches		  }x;
6998716de38SJoe Perches	$NonptrTypeWithAttr	= qr{
7008716de38SJoe Perches			(?:$Modifier\s+|const\s+)*
7018716de38SJoe Perches			(?:
7028716de38SJoe Perches				(?:typeof|__typeof__)\s*\([^\)]*\)|
7038716de38SJoe Perches				(?:$typeTypedefs\b)|
7048716de38SJoe Perches				(?:${allWithAttr}\b)
7058716de38SJoe Perches			)
7068716de38SJoe Perches			(?:\s+$Modifier|\s+const)*
7078716de38SJoe Perches		  }x;
7088905a67cSAndy Whitcroft	$Type	= qr{
709c45dcabdSAndy Whitcroft			$NonptrType
7101574a29fSJoe Perches			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
711c8cb2ca3SAndy Whitcroft			(?:\s+$Inline|\s+$Modifier)*
7128905a67cSAndy Whitcroft		  }x;
7131813087dSJoe Perches	$TypeMisordered	= qr{
7141813087dSJoe Perches			$NonptrTypeMisordered
7151813087dSJoe Perches			(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
7161813087dSJoe Perches			(?:\s+$Inline|\s+$Modifier)*
7171813087dSJoe Perches		  }x;
71891cb5195SJoe Perches	$Declare	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
7191813087dSJoe Perches	$DeclareMisordered	= qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
7208905a67cSAndy Whitcroft}
7218905a67cSAndy Whitcroftbuild_types();
7226c72ffaaSAndy Whitcroft
7237d2367afSJoe Perchesour $Typecast	= qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
724d1fe9c09SJoe Perches
725d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg
726d1fe9c09SJoe Perches# requires at least perl version v5.10.0
727d1fe9c09SJoe Perches# Any use must be runtime checked with $^V
728d1fe9c09SJoe Perches
729d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
7302435880fSJoe Perchesour $LvalOrFunc	= qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
731c0a5c898SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
7327d2367afSJoe Perches
733f8422308SJoe Perchesour $declaration_macros = qr{(?x:
7343e838b6cSJoe Perches	(?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
735f8422308SJoe Perches	(?:$Storage\s+)?LIST_HEAD\s*\(|
736f8422308SJoe Perches	(?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(
737f8422308SJoe Perches)};
738f8422308SJoe Perches
7397d2367afSJoe Perchessub deparenthesize {
7407d2367afSJoe Perches	my ($string) = @_;
7417d2367afSJoe Perches	return "" if (!defined($string));
7425b9553abSJoe Perches
7435b9553abSJoe Perches	while ($string =~ /^\s*\(.*\)\s*$/) {
7445b9553abSJoe Perches		$string =~ s@^\s*\(\s*@@;
7455b9553abSJoe Perches		$string =~ s@\s*\)\s*$@@;
7465b9553abSJoe Perches	}
7475b9553abSJoe Perches
7487d2367afSJoe Perches	$string =~ s@\s+@ @g;
7495b9553abSJoe Perches
7507d2367afSJoe Perches	return $string;
7517d2367afSJoe Perches}
7527d2367afSJoe Perches
7533445686aSJoe Perchessub seed_camelcase_file {
7543445686aSJoe Perches	my ($file) = @_;
7553445686aSJoe Perches
7563445686aSJoe Perches	return if (!(-f $file));
7573445686aSJoe Perches
7583445686aSJoe Perches	local $/;
7593445686aSJoe Perches
7603445686aSJoe Perches	open(my $include_file, '<', "$file")
7613445686aSJoe Perches	    or warn "$P: Can't read '$file' $!\n";
7623445686aSJoe Perches	my $text = <$include_file>;
7633445686aSJoe Perches	close($include_file);
7643445686aSJoe Perches
7653445686aSJoe Perches	my @lines = split('\n', $text);
7663445686aSJoe Perches
7673445686aSJoe Perches	foreach my $line (@lines) {
7683445686aSJoe Perches		next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
7693445686aSJoe Perches		if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
7703445686aSJoe Perches			$camelcase{$1} = 1;
77111ea516aSJoe Perches		} elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
77211ea516aSJoe Perches			$camelcase{$1} = 1;
77311ea516aSJoe Perches		} elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
7743445686aSJoe Perches			$camelcase{$1} = 1;
7753445686aSJoe Perches		}
7763445686aSJoe Perches	}
7773445686aSJoe Perches}
7783445686aSJoe Perches
77985b0ee18SJoe Perchessub is_maintained_obsolete {
78085b0ee18SJoe Perches	my ($filename) = @_;
78185b0ee18SJoe Perches
782f2c19c2fSJerome Forissier	return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
78385b0ee18SJoe Perches
7840616efa4SJoe Perches	my $status = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
78585b0ee18SJoe Perches
78685b0ee18SJoe Perches	return $status =~ /obsolete/i;
78785b0ee18SJoe Perches}
78885b0ee18SJoe Perches
7893445686aSJoe Perchesmy $camelcase_seeded = 0;
7903445686aSJoe Perchessub seed_camelcase_includes {
7913445686aSJoe Perches	return if ($camelcase_seeded);
7923445686aSJoe Perches
7933445686aSJoe Perches	my $files;
794c707a81dSJoe Perches	my $camelcase_cache = "";
795c707a81dSJoe Perches	my @include_files = ();
796c707a81dSJoe Perches
797c707a81dSJoe Perches	$camelcase_seeded = 1;
798351b2a1fSJoe Perches
7993645e328SRichard Genoud	if (-e ".git") {
800351b2a1fSJoe Perches		my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`;
801351b2a1fSJoe Perches		chomp $git_last_include_commit;
802c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
803c707a81dSJoe Perches	} else {
804c707a81dSJoe Perches		my $last_mod_date = 0;
805c707a81dSJoe Perches		$files = `find $root/include -name "*.h"`;
806c707a81dSJoe Perches		@include_files = split('\n', $files);
807c707a81dSJoe Perches		foreach my $file (@include_files) {
808c707a81dSJoe Perches			my $date = POSIX::strftime("%Y%m%d%H%M",
809c707a81dSJoe Perches						   localtime((stat $file)[9]));
810c707a81dSJoe Perches			$last_mod_date = $date if ($last_mod_date < $date);
811c707a81dSJoe Perches		}
812c707a81dSJoe Perches		$camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
813c707a81dSJoe Perches	}
814c707a81dSJoe Perches
815c707a81dSJoe Perches	if ($camelcase_cache ne "" && -f $camelcase_cache) {
816c707a81dSJoe Perches		open(my $camelcase_file, '<', "$camelcase_cache")
817c707a81dSJoe Perches		    or warn "$P: Can't read '$camelcase_cache' $!\n";
818351b2a1fSJoe Perches		while (<$camelcase_file>) {
819351b2a1fSJoe Perches			chomp;
820351b2a1fSJoe Perches			$camelcase{$_} = 1;
821351b2a1fSJoe Perches		}
822351b2a1fSJoe Perches		close($camelcase_file);
823351b2a1fSJoe Perches
824351b2a1fSJoe Perches		return;
825351b2a1fSJoe Perches	}
826c707a81dSJoe Perches
8273645e328SRichard Genoud	if (-e ".git") {
828c707a81dSJoe Perches		$files = `git ls-files "include/*.h"`;
829c707a81dSJoe Perches		@include_files = split('\n', $files);
8303445686aSJoe Perches	}
831c707a81dSJoe Perches
8323445686aSJoe Perches	foreach my $file (@include_files) {
8333445686aSJoe Perches		seed_camelcase_file($file);
8343445686aSJoe Perches	}
835351b2a1fSJoe Perches
836c707a81dSJoe Perches	if ($camelcase_cache ne "") {
837351b2a1fSJoe Perches		unlink glob ".checkpatch-camelcase.*";
838c707a81dSJoe Perches		open(my $camelcase_file, '>', "$camelcase_cache")
839c707a81dSJoe Perches		    or warn "$P: Can't write '$camelcase_cache' $!\n";
840351b2a1fSJoe Perches		foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
841351b2a1fSJoe Perches			print $camelcase_file ("$_\n");
842351b2a1fSJoe Perches		}
843351b2a1fSJoe Perches		close($camelcase_file);
844351b2a1fSJoe Perches	}
8453445686aSJoe Perches}
8463445686aSJoe Perches
847d311cd44SJoe Perchessub git_commit_info {
848d311cd44SJoe Perches	my ($commit, $id, $desc) = @_;
849d311cd44SJoe Perches
850d311cd44SJoe Perches	return ($id, $desc) if ((which("git") eq "") || !(-e ".git"));
851d311cd44SJoe Perches
852d311cd44SJoe Perches	my $output = `git log --no-color --format='%H %s' -1 $commit 2>&1`;
853d311cd44SJoe Perches	$output =~ s/^\s*//gm;
854d311cd44SJoe Perches	my @lines = split("\n", $output);
855d311cd44SJoe Perches
8560d7835fcSJoe Perches	return ($id, $desc) if ($#lines < 0);
8570d7835fcSJoe Perches
858d311cd44SJoe Perches	if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous\./) {
859d311cd44SJoe Perches# Maybe one day convert this block of bash into something that returns
860d311cd44SJoe Perches# all matching commit ids, but it's very slow...
861d311cd44SJoe Perches#
862d311cd44SJoe Perches#		echo "checking commits $1..."
863d311cd44SJoe Perches#		git rev-list --remotes | grep -i "^$1" |
864d311cd44SJoe Perches#		while read line ; do
865d311cd44SJoe Perches#		    git log --format='%H %s' -1 $line |
866d311cd44SJoe Perches#		    echo "commit $(cut -c 1-12,41-)"
867d311cd44SJoe Perches#		done
868d311cd44SJoe Perches	} elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) {
869d311cd44SJoe Perches	} else {
870d311cd44SJoe Perches		$id = substr($lines[0], 0, 12);
871d311cd44SJoe Perches		$desc = substr($lines[0], 41);
872d311cd44SJoe Perches	}
873d311cd44SJoe Perches
874d311cd44SJoe Perches	return ($id, $desc);
875d311cd44SJoe Perches}
876d311cd44SJoe Perches
8776c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file);
8780a920b5bSAndy Whitcroft
87900df344fSAndy Whitcroftmy @rawlines = ();
880c2fdda0dSAndy Whitcroftmy @lines = ();
8813705ce5bSJoe Perchesmy @fixed = ();
882d752fcc8SJoe Perchesmy @fixed_inserted = ();
883d752fcc8SJoe Perchesmy @fixed_deleted = ();
884194f66fcSJoe Perchesmy $fixlinenr = -1;
885194f66fcSJoe Perches
8864a593c34SDu, Changbin# If input is git commits, extract all commits from the commit expressions.
8874a593c34SDu, Changbin# For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
8884a593c34SDu, Changbindie "$P: No git repository found\n" if ($git && !-e ".git");
8894a593c34SDu, Changbin
8904a593c34SDu, Changbinif ($git) {
8914a593c34SDu, Changbin	my @commits = ();
8920dea9f1eSJoe Perches	foreach my $commit_expr (@ARGV) {
8934a593c34SDu, Changbin		my $git_range;
89428898fd1SJoe Perches		if ($commit_expr =~ m/^(.*)-(\d+)$/) {
89528898fd1SJoe Perches			$git_range = "-$2 $1";
8964a593c34SDu, Changbin		} elsif ($commit_expr =~ m/\.\./) {
8974a593c34SDu, Changbin			$git_range = "$commit_expr";
8984a593c34SDu, Changbin		} else {
8990dea9f1eSJoe Perches			$git_range = "-1 $commit_expr";
9000dea9f1eSJoe Perches		}
9010dea9f1eSJoe Perches		my $lines = `git log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
9020dea9f1eSJoe Perches		foreach my $line (split(/\n/, $lines)) {
90328898fd1SJoe Perches			$line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
90428898fd1SJoe Perches			next if (!defined($1) || !defined($2));
9050dea9f1eSJoe Perches			my $sha1 = $1;
9060dea9f1eSJoe Perches			my $subject = $2;
9070dea9f1eSJoe Perches			unshift(@commits, $sha1);
9080dea9f1eSJoe Perches			$git_commits{$sha1} = $subject;
9094a593c34SDu, Changbin		}
9104a593c34SDu, Changbin	}
9114a593c34SDu, Changbin	die "$P: no git commits after extraction!\n" if (@commits == 0);
9124a593c34SDu, Changbin	@ARGV = @commits;
9134a593c34SDu, Changbin}
9144a593c34SDu, Changbin
915c2fdda0dSAndy Whitcroftmy $vname;
9166c72ffaaSAndy Whitcroftfor my $filename (@ARGV) {
91721caa13cSAndy Whitcroft	my $FILE;
9184a593c34SDu, Changbin	if ($git) {
9194a593c34SDu, Changbin		open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
9204a593c34SDu, Changbin			die "$P: $filename: git format-patch failed - $!\n";
9214a593c34SDu, Changbin	} elsif ($file) {
92221caa13cSAndy Whitcroft		open($FILE, '-|', "diff -u /dev/null $filename") ||
9236c72ffaaSAndy Whitcroft			die "$P: $filename: diff failed - $!\n";
92421caa13cSAndy Whitcroft	} elsif ($filename eq '-') {
92521caa13cSAndy Whitcroft		open($FILE, '<&STDIN');
9266c72ffaaSAndy Whitcroft	} else {
92721caa13cSAndy Whitcroft		open($FILE, '<', "$filename") ||
9286c72ffaaSAndy Whitcroft			die "$P: $filename: open failed - $!\n";
9296c72ffaaSAndy Whitcroft	}
930c2fdda0dSAndy Whitcroft	if ($filename eq '-') {
931c2fdda0dSAndy Whitcroft		$vname = 'Your patch';
9324a593c34SDu, Changbin	} elsif ($git) {
9330dea9f1eSJoe Perches		$vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
934c2fdda0dSAndy Whitcroft	} else {
935c2fdda0dSAndy Whitcroft		$vname = $filename;
936c2fdda0dSAndy Whitcroft	}
93721caa13cSAndy Whitcroft	while (<$FILE>) {
9380a920b5bSAndy Whitcroft		chomp;
93900df344fSAndy Whitcroft		push(@rawlines, $_);
9406c72ffaaSAndy Whitcroft	}
94121caa13cSAndy Whitcroft	close($FILE);
942d8469f16SJoe Perches
943d8469f16SJoe Perches	if ($#ARGV > 0 && $quiet == 0) {
944d8469f16SJoe Perches		print '-' x length($vname) . "\n";
945d8469f16SJoe Perches		print "$vname\n";
946d8469f16SJoe Perches		print '-' x length($vname) . "\n";
947d8469f16SJoe Perches	}
948d8469f16SJoe Perches
949c2fdda0dSAndy Whitcroft	if (!process($filename)) {
9500a920b5bSAndy Whitcroft		$exit = 1;
9510a920b5bSAndy Whitcroft	}
95200df344fSAndy Whitcroft	@rawlines = ();
95313214adfSAndy Whitcroft	@lines = ();
9543705ce5bSJoe Perches	@fixed = ();
955d752fcc8SJoe Perches	@fixed_inserted = ();
956d752fcc8SJoe Perches	@fixed_deleted = ();
957194f66fcSJoe Perches	$fixlinenr = -1;
958485ff23eSAlex Dowad	@modifierListFile = ();
959485ff23eSAlex Dowad	@typeListFile = ();
960485ff23eSAlex Dowad	build_types();
9610a920b5bSAndy Whitcroft}
9620a920b5bSAndy Whitcroft
963d8469f16SJoe Perchesif (!$quiet) {
9643c816e49SJoe Perches	hash_show_words(\%use_type, "Used");
9653c816e49SJoe Perches	hash_show_words(\%ignore_type, "Ignored");
9663c816e49SJoe Perches
967d8469f16SJoe Perches	if ($^V lt 5.10.0) {
968d8469f16SJoe Perches		print << "EOM"
969d8469f16SJoe Perches
970d8469f16SJoe PerchesNOTE: perl $^V is not modern enough to detect all possible issues.
971d8469f16SJoe Perches      An upgrade to at least perl v5.10.0 is suggested.
972d8469f16SJoe PerchesEOM
973d8469f16SJoe Perches	}
974d8469f16SJoe Perches	if ($exit) {
975d8469f16SJoe Perches		print << "EOM"
976d8469f16SJoe Perches
977d8469f16SJoe PerchesNOTE: If any of the errors are false positives, please report
978d8469f16SJoe Perches      them to the maintainer, see CHECKPATCH in MAINTAINERS.
979d8469f16SJoe PerchesEOM
980d8469f16SJoe Perches	}
981d8469f16SJoe Perches}
982d8469f16SJoe Perches
9830a920b5bSAndy Whitcroftexit($exit);
9840a920b5bSAndy Whitcroft
9850a920b5bSAndy Whitcroftsub top_of_kernel_tree {
9866c72ffaaSAndy Whitcroft	my ($root) = @_;
9876c72ffaaSAndy Whitcroft
9886c72ffaaSAndy Whitcroft	my @tree_check = (
9896c72ffaaSAndy Whitcroft		"COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
9906c72ffaaSAndy Whitcroft		"README", "Documentation", "arch", "include", "drivers",
9916c72ffaaSAndy Whitcroft		"fs", "init", "ipc", "kernel", "lib", "scripts",
9926c72ffaaSAndy Whitcroft	);
9936c72ffaaSAndy Whitcroft
9946c72ffaaSAndy Whitcroft	foreach my $check (@tree_check) {
9956c72ffaaSAndy Whitcroft		if (! -e $root . '/' . $check) {
9960a920b5bSAndy Whitcroft			return 0;
9970a920b5bSAndy Whitcroft		}
9986c72ffaaSAndy Whitcroft	}
9996c72ffaaSAndy Whitcroft	return 1;
10006c72ffaaSAndy Whitcroft}
10010a920b5bSAndy Whitcroft
100220112475SJoe Perchessub parse_email {
100320112475SJoe Perches	my ($formatted_email) = @_;
100420112475SJoe Perches
100520112475SJoe Perches	my $name = "";
100620112475SJoe Perches	my $address = "";
100720112475SJoe Perches	my $comment = "";
100820112475SJoe Perches
100920112475SJoe Perches	if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
101020112475SJoe Perches		$name = $1;
101120112475SJoe Perches		$address = $2;
101220112475SJoe Perches		$comment = $3 if defined $3;
101320112475SJoe Perches	} elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
101420112475SJoe Perches		$address = $1;
101520112475SJoe Perches		$comment = $2 if defined $2;
101620112475SJoe Perches	} elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
101720112475SJoe Perches		$address = $1;
101820112475SJoe Perches		$comment = $2 if defined $2;
101920112475SJoe Perches		$formatted_email =~ s/$address.*$//;
102020112475SJoe Perches		$name = $formatted_email;
10213705ce5bSJoe Perches		$name = trim($name);
102220112475SJoe Perches		$name =~ s/^\"|\"$//g;
102320112475SJoe Perches		# If there's a name left after stripping spaces and
102420112475SJoe Perches		# leading quotes, and the address doesn't have both
102520112475SJoe Perches		# leading and trailing angle brackets, the address
102620112475SJoe Perches		# is invalid. ie:
102720112475SJoe Perches		#   "joe smith [email protected]" bad
102820112475SJoe Perches		#   "joe smith <[email protected]" bad
102920112475SJoe Perches		if ($name ne "" && $address !~ /^<[^>]+>$/) {
103020112475SJoe Perches			$name = "";
103120112475SJoe Perches			$address = "";
103220112475SJoe Perches			$comment = "";
103320112475SJoe Perches		}
103420112475SJoe Perches	}
103520112475SJoe Perches
10363705ce5bSJoe Perches	$name = trim($name);
103720112475SJoe Perches	$name =~ s/^\"|\"$//g;
10383705ce5bSJoe Perches	$address = trim($address);
103920112475SJoe Perches	$address =~ s/^\<|\>$//g;
104020112475SJoe Perches
104120112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
104220112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
104320112475SJoe Perches		$name = "\"$name\"";
104420112475SJoe Perches	}
104520112475SJoe Perches
104620112475SJoe Perches	return ($name, $address, $comment);
104720112475SJoe Perches}
104820112475SJoe Perches
104920112475SJoe Perchessub format_email {
105020112475SJoe Perches	my ($name, $address) = @_;
105120112475SJoe Perches
105220112475SJoe Perches	my $formatted_email;
105320112475SJoe Perches
10543705ce5bSJoe Perches	$name = trim($name);
105520112475SJoe Perches	$name =~ s/^\"|\"$//g;
10563705ce5bSJoe Perches	$address = trim($address);
105720112475SJoe Perches
105820112475SJoe Perches	if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
105920112475SJoe Perches		$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
106020112475SJoe Perches		$name = "\"$name\"";
106120112475SJoe Perches	}
106220112475SJoe Perches
106320112475SJoe Perches	if ("$name" eq "") {
106420112475SJoe Perches		$formatted_email = "$address";
106520112475SJoe Perches	} else {
106620112475SJoe Perches		$formatted_email = "$name <$address>";
106720112475SJoe Perches	}
106820112475SJoe Perches
106920112475SJoe Perches	return $formatted_email;
107020112475SJoe Perches}
107120112475SJoe Perches
1072d311cd44SJoe Perchessub which {
1073d311cd44SJoe Perches	my ($bin) = @_;
1074d311cd44SJoe Perches
1075d311cd44SJoe Perches	foreach my $path (split(/:/, $ENV{PATH})) {
1076d311cd44SJoe Perches		if (-e "$path/$bin") {
1077d311cd44SJoe Perches			return "$path/$bin";
1078d311cd44SJoe Perches		}
1079d311cd44SJoe Perches	}
1080d311cd44SJoe Perches
1081d311cd44SJoe Perches	return "";
1082d311cd44SJoe Perches}
1083d311cd44SJoe Perches
1084000d1cc1SJoe Perchessub which_conf {
1085000d1cc1SJoe Perches	my ($conf) = @_;
1086000d1cc1SJoe Perches
1087000d1cc1SJoe Perches	foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
1088000d1cc1SJoe Perches		if (-e "$path/$conf") {
1089000d1cc1SJoe Perches			return "$path/$conf";
1090000d1cc1SJoe Perches		}
1091000d1cc1SJoe Perches	}
1092000d1cc1SJoe Perches
1093000d1cc1SJoe Perches	return "";
1094000d1cc1SJoe Perches}
1095000d1cc1SJoe Perches
10960a920b5bSAndy Whitcroftsub expand_tabs {
10970a920b5bSAndy Whitcroft	my ($str) = @_;
10980a920b5bSAndy Whitcroft
10990a920b5bSAndy Whitcroft	my $res = '';
11000a920b5bSAndy Whitcroft	my $n = 0;
11010a920b5bSAndy Whitcroft	for my $c (split(//, $str)) {
11020a920b5bSAndy Whitcroft		if ($c eq "\t") {
11030a920b5bSAndy Whitcroft			$res .= ' ';
11040a920b5bSAndy Whitcroft			$n++;
11050a920b5bSAndy Whitcroft			for (; ($n % 8) != 0; $n++) {
11060a920b5bSAndy Whitcroft				$res .= ' ';
11070a920b5bSAndy Whitcroft			}
11080a920b5bSAndy Whitcroft			next;
11090a920b5bSAndy Whitcroft		}
11100a920b5bSAndy Whitcroft		$res .= $c;
11110a920b5bSAndy Whitcroft		$n++;
11120a920b5bSAndy Whitcroft	}
11130a920b5bSAndy Whitcroft
11140a920b5bSAndy Whitcroft	return $res;
11150a920b5bSAndy Whitcroft}
11166c72ffaaSAndy Whitcroftsub copy_spacing {
1117773647a0SAndy Whitcroft	(my $res = shift) =~ tr/\t/ /c;
11186c72ffaaSAndy Whitcroft	return $res;
11196c72ffaaSAndy Whitcroft}
11200a920b5bSAndy Whitcroft
11214a0df2efSAndy Whitcroftsub line_stats {
11224a0df2efSAndy Whitcroft	my ($line) = @_;
11234a0df2efSAndy Whitcroft
11244a0df2efSAndy Whitcroft	# Drop the diff line leader and expand tabs
11254a0df2efSAndy Whitcroft	$line =~ s/^.//;
11264a0df2efSAndy Whitcroft	$line = expand_tabs($line);
11274a0df2efSAndy Whitcroft
11284a0df2efSAndy Whitcroft	# Pick the indent from the front of the line.
11294a0df2efSAndy Whitcroft	my ($white) = ($line =~ /^(\s*)/);
11304a0df2efSAndy Whitcroft
11314a0df2efSAndy Whitcroft	return (length($line), length($white));
11324a0df2efSAndy Whitcroft}
11334a0df2efSAndy Whitcroft
1134773647a0SAndy Whitcroftmy $sanitise_quote = '';
1135773647a0SAndy Whitcroft
1136773647a0SAndy Whitcroftsub sanitise_line_reset {
1137773647a0SAndy Whitcroft	my ($in_comment) = @_;
1138773647a0SAndy Whitcroft
1139773647a0SAndy Whitcroft	if ($in_comment) {
1140773647a0SAndy Whitcroft		$sanitise_quote = '*/';
1141773647a0SAndy Whitcroft	} else {
1142773647a0SAndy Whitcroft		$sanitise_quote = '';
1143773647a0SAndy Whitcroft	}
1144773647a0SAndy Whitcroft}
114500df344fSAndy Whitcroftsub sanitise_line {
114600df344fSAndy Whitcroft	my ($line) = @_;
114700df344fSAndy Whitcroft
114800df344fSAndy Whitcroft	my $res = '';
114900df344fSAndy Whitcroft	my $l = '';
115000df344fSAndy Whitcroft
1151c2fdda0dSAndy Whitcroft	my $qlen = 0;
1152773647a0SAndy Whitcroft	my $off = 0;
1153773647a0SAndy Whitcroft	my $c;
115400df344fSAndy Whitcroft
1155773647a0SAndy Whitcroft	# Always copy over the diff marker.
1156773647a0SAndy Whitcroft	$res = substr($line, 0, 1);
1157773647a0SAndy Whitcroft
1158773647a0SAndy Whitcroft	for ($off = 1; $off < length($line); $off++) {
1159773647a0SAndy Whitcroft		$c = substr($line, $off, 1);
1160773647a0SAndy Whitcroft
1161773647a0SAndy Whitcroft		# Comments we are wacking completly including the begin
1162773647a0SAndy Whitcroft		# and end, all to $;.
1163773647a0SAndy Whitcroft		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
1164773647a0SAndy Whitcroft			$sanitise_quote = '*/';
1165773647a0SAndy Whitcroft
1166773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1167773647a0SAndy Whitcroft			$off++;
116800df344fSAndy Whitcroft			next;
1169773647a0SAndy Whitcroft		}
117081bc0e02SAndy Whitcroft		if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
1171773647a0SAndy Whitcroft			$sanitise_quote = '';
1172773647a0SAndy Whitcroft			substr($res, $off, 2, "$;$;");
1173773647a0SAndy Whitcroft			$off++;
1174773647a0SAndy Whitcroft			next;
1175773647a0SAndy Whitcroft		}
1176113f04a8SDaniel Walker		if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
1177113f04a8SDaniel Walker			$sanitise_quote = '//';
1178113f04a8SDaniel Walker
1179113f04a8SDaniel Walker			substr($res, $off, 2, $sanitise_quote);
1180113f04a8SDaniel Walker			$off++;
1181113f04a8SDaniel Walker			next;
1182113f04a8SDaniel Walker		}
1183773647a0SAndy Whitcroft
1184773647a0SAndy Whitcroft		# A \ in a string means ignore the next character.
1185773647a0SAndy Whitcroft		if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
1186773647a0SAndy Whitcroft		    $c eq "\\") {
1187773647a0SAndy Whitcroft			substr($res, $off, 2, 'XX');
1188773647a0SAndy Whitcroft			$off++;
1189773647a0SAndy Whitcroft			next;
1190773647a0SAndy Whitcroft		}
1191773647a0SAndy Whitcroft		# Regular quotes.
1192773647a0SAndy Whitcroft		if ($c eq "'" || $c eq '"') {
1193773647a0SAndy Whitcroft			if ($sanitise_quote eq '') {
1194773647a0SAndy Whitcroft				$sanitise_quote = $c;
1195773647a0SAndy Whitcroft
1196773647a0SAndy Whitcroft				substr($res, $off, 1, $c);
1197773647a0SAndy Whitcroft				next;
1198773647a0SAndy Whitcroft			} elsif ($sanitise_quote eq $c) {
1199773647a0SAndy Whitcroft				$sanitise_quote = '';
120000df344fSAndy Whitcroft			}
120100df344fSAndy Whitcroft		}
1202773647a0SAndy Whitcroft
1203fae17daeSAndy Whitcroft		#print "c<$c> SQ<$sanitise_quote>\n";
1204773647a0SAndy Whitcroft		if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
1205773647a0SAndy Whitcroft			substr($res, $off, 1, $;);
1206113f04a8SDaniel Walker		} elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
1207113f04a8SDaniel Walker			substr($res, $off, 1, $;);
1208773647a0SAndy Whitcroft		} elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
1209773647a0SAndy Whitcroft			substr($res, $off, 1, 'X');
121000df344fSAndy Whitcroft		} else {
1211773647a0SAndy Whitcroft			substr($res, $off, 1, $c);
121200df344fSAndy Whitcroft		}
1213c2fdda0dSAndy Whitcroft	}
1214c2fdda0dSAndy Whitcroft
1215113f04a8SDaniel Walker	if ($sanitise_quote eq '//') {
1216113f04a8SDaniel Walker		$sanitise_quote = '';
1217113f04a8SDaniel Walker	}
1218113f04a8SDaniel Walker
1219c2fdda0dSAndy Whitcroft	# The pathname on a #include may be surrounded by '<' and '>'.
1220c45dcabdSAndy Whitcroft	if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
1221c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1222c2fdda0dSAndy Whitcroft		$res =~ s@\<.*\>@<$clean>@;
1223c2fdda0dSAndy Whitcroft
1224c2fdda0dSAndy Whitcroft	# The whole of a #error is a string.
1225c45dcabdSAndy Whitcroft	} elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
1226c2fdda0dSAndy Whitcroft		my $clean = 'X' x length($1);
1227c45dcabdSAndy Whitcroft		$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
1228c2fdda0dSAndy Whitcroft	}
1229c2fdda0dSAndy Whitcroft
1230dadf680dSJoe Perches	if ($allow_c99_comments && $res =~ m@(//.*$)@) {
1231dadf680dSJoe Perches		my $match = $1;
1232dadf680dSJoe Perches		$res =~ s/\Q$match\E/"$;" x length($match)/e;
1233dadf680dSJoe Perches	}
1234dadf680dSJoe Perches
123500df344fSAndy Whitcroft	return $res;
123600df344fSAndy Whitcroft}
123700df344fSAndy Whitcroft
1238a6962d72SJoe Perchessub get_quoted_string {
1239a6962d72SJoe Perches	my ($line, $rawline) = @_;
1240a6962d72SJoe Perches
124133acb54aSJoe Perches	return "" if ($line !~ m/($String)/g);
1242a6962d72SJoe Perches	return substr($rawline, $-[0], $+[0] - $-[0]);
1243a6962d72SJoe Perches}
1244a6962d72SJoe Perches
12458905a67cSAndy Whitcroftsub ctx_statement_block {
12468905a67cSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
12478905a67cSAndy Whitcroft	my $line = $linenr - 1;
12488905a67cSAndy Whitcroft	my $blk = '';
12498905a67cSAndy Whitcroft	my $soff = $off;
12508905a67cSAndy Whitcroft	my $coff = $off - 1;
1251773647a0SAndy Whitcroft	my $coff_set = 0;
12528905a67cSAndy Whitcroft
125313214adfSAndy Whitcroft	my $loff = 0;
125413214adfSAndy Whitcroft
12558905a67cSAndy Whitcroft	my $type = '';
12568905a67cSAndy Whitcroft	my $level = 0;
1257a2750645SAndy Whitcroft	my @stack = ();
1258cf655043SAndy Whitcroft	my $p;
12598905a67cSAndy Whitcroft	my $c;
12608905a67cSAndy Whitcroft	my $len = 0;
126113214adfSAndy Whitcroft
126213214adfSAndy Whitcroft	my $remainder;
12638905a67cSAndy Whitcroft	while (1) {
1264a2750645SAndy Whitcroft		@stack = (['', 0]) if ($#stack == -1);
1265a2750645SAndy Whitcroft
1266773647a0SAndy Whitcroft		#warn "CSB: blk<$blk> remain<$remain>\n";
12678905a67cSAndy Whitcroft		# If we are about to drop off the end, pull in more
12688905a67cSAndy Whitcroft		# context.
12698905a67cSAndy Whitcroft		if ($off >= $len) {
12708905a67cSAndy Whitcroft			for (; $remain > 0; $line++) {
1271dea33496SAndy Whitcroft				last if (!defined $lines[$line]);
1272c2fdda0dSAndy Whitcroft				next if ($lines[$line] =~ /^-/);
12738905a67cSAndy Whitcroft				$remain--;
127413214adfSAndy Whitcroft				$loff = $len;
1275c2fdda0dSAndy Whitcroft				$blk .= $lines[$line] . "\n";
12768905a67cSAndy Whitcroft				$len = length($blk);
12778905a67cSAndy Whitcroft				$line++;
12788905a67cSAndy Whitcroft				last;
12798905a67cSAndy Whitcroft			}
12808905a67cSAndy Whitcroft			# Bail if there is no further context.
12818905a67cSAndy Whitcroft			#warn "CSB: blk<$blk> off<$off> len<$len>\n";
128213214adfSAndy Whitcroft			if ($off >= $len) {
12838905a67cSAndy Whitcroft				last;
12848905a67cSAndy Whitcroft			}
1285f74bd194SAndy Whitcroft			if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
1286f74bd194SAndy Whitcroft				$level++;
1287f74bd194SAndy Whitcroft				$type = '#';
1288f74bd194SAndy Whitcroft			}
12898905a67cSAndy Whitcroft		}
1290cf655043SAndy Whitcroft		$p = $c;
12918905a67cSAndy Whitcroft		$c = substr($blk, $off, 1);
129213214adfSAndy Whitcroft		$remainder = substr($blk, $off);
12938905a67cSAndy Whitcroft
1294773647a0SAndy Whitcroft		#warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
12954635f4fbSAndy Whitcroft
12964635f4fbSAndy Whitcroft		# Handle nested #if/#else.
12974635f4fbSAndy Whitcroft		if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
12984635f4fbSAndy Whitcroft			push(@stack, [ $type, $level ]);
12994635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
13004635f4fbSAndy Whitcroft			($type, $level) = @{$stack[$#stack - 1]};
13014635f4fbSAndy Whitcroft		} elsif ($remainder =~ /^#\s*endif\b/) {
13024635f4fbSAndy Whitcroft			($type, $level) = @{pop(@stack)};
13034635f4fbSAndy Whitcroft		}
13044635f4fbSAndy Whitcroft
13058905a67cSAndy Whitcroft		# Statement ends at the ';' or a close '}' at the
13068905a67cSAndy Whitcroft		# outermost level.
13078905a67cSAndy Whitcroft		if ($level == 0 && $c eq ';') {
13088905a67cSAndy Whitcroft			last;
13098905a67cSAndy Whitcroft		}
13108905a67cSAndy Whitcroft
131113214adfSAndy Whitcroft		# An else is really a conditional as long as its not else if
1312773647a0SAndy Whitcroft		if ($level == 0 && $coff_set == 0 &&
1313773647a0SAndy Whitcroft				(!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
1314773647a0SAndy Whitcroft				$remainder =~ /^(else)(?:\s|{)/ &&
1315773647a0SAndy Whitcroft				$remainder !~ /^else\s+if\b/) {
1316773647a0SAndy Whitcroft			$coff = $off + length($1) - 1;
1317773647a0SAndy Whitcroft			$coff_set = 1;
1318773647a0SAndy Whitcroft			#warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
1319773647a0SAndy Whitcroft			#warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
132013214adfSAndy Whitcroft		}
132113214adfSAndy Whitcroft
13228905a67cSAndy Whitcroft		if (($type eq '' || $type eq '(') && $c eq '(') {
13238905a67cSAndy Whitcroft			$level++;
13248905a67cSAndy Whitcroft			$type = '(';
13258905a67cSAndy Whitcroft		}
13268905a67cSAndy Whitcroft		if ($type eq '(' && $c eq ')') {
13278905a67cSAndy Whitcroft			$level--;
13288905a67cSAndy Whitcroft			$type = ($level != 0)? '(' : '';
13298905a67cSAndy Whitcroft
13308905a67cSAndy Whitcroft			if ($level == 0 && $coff < $soff) {
13318905a67cSAndy Whitcroft				$coff = $off;
1332773647a0SAndy Whitcroft				$coff_set = 1;
1333773647a0SAndy Whitcroft				#warn "CSB: mark coff<$coff>\n";
13348905a67cSAndy Whitcroft			}
13358905a67cSAndy Whitcroft		}
13368905a67cSAndy Whitcroft		if (($type eq '' || $type eq '{') && $c eq '{') {
13378905a67cSAndy Whitcroft			$level++;
13388905a67cSAndy Whitcroft			$type = '{';
13398905a67cSAndy Whitcroft		}
13408905a67cSAndy Whitcroft		if ($type eq '{' && $c eq '}') {
13418905a67cSAndy Whitcroft			$level--;
13428905a67cSAndy Whitcroft			$type = ($level != 0)? '{' : '';
13438905a67cSAndy Whitcroft
13448905a67cSAndy Whitcroft			if ($level == 0) {
1345b998e001SPatrick Pannuto				if (substr($blk, $off + 1, 1) eq ';') {
1346b998e001SPatrick Pannuto					$off++;
1347b998e001SPatrick Pannuto				}
13488905a67cSAndy Whitcroft				last;
13498905a67cSAndy Whitcroft			}
13508905a67cSAndy Whitcroft		}
1351f74bd194SAndy Whitcroft		# Preprocessor commands end at the newline unless escaped.
1352f74bd194SAndy Whitcroft		if ($type eq '#' && $c eq "\n" && $p ne "\\") {
1353f74bd194SAndy Whitcroft			$level--;
1354f74bd194SAndy Whitcroft			$type = '';
1355f74bd194SAndy Whitcroft			$off++;
1356f74bd194SAndy Whitcroft			last;
1357f74bd194SAndy Whitcroft		}
13588905a67cSAndy Whitcroft		$off++;
13598905a67cSAndy Whitcroft	}
1360a3bb97a7SAndy Whitcroft	# We are truly at the end, so shuffle to the next line.
136113214adfSAndy Whitcroft	if ($off == $len) {
1362a3bb97a7SAndy Whitcroft		$loff = $len + 1;
136313214adfSAndy Whitcroft		$line++;
136413214adfSAndy Whitcroft		$remain--;
136513214adfSAndy Whitcroft	}
13668905a67cSAndy Whitcroft
13678905a67cSAndy Whitcroft	my $statement = substr($blk, $soff, $off - $soff + 1);
13688905a67cSAndy Whitcroft	my $condition = substr($blk, $soff, $coff - $soff + 1);
13698905a67cSAndy Whitcroft
13708905a67cSAndy Whitcroft	#warn "STATEMENT<$statement>\n";
13718905a67cSAndy Whitcroft	#warn "CONDITION<$condition>\n";
13728905a67cSAndy Whitcroft
1373773647a0SAndy Whitcroft	#print "coff<$coff> soff<$off> loff<$loff>\n";
137413214adfSAndy Whitcroft
137513214adfSAndy Whitcroft	return ($statement, $condition,
137613214adfSAndy Whitcroft			$line, $remain + 1, $off - $loff + 1, $level);
137713214adfSAndy Whitcroft}
137813214adfSAndy Whitcroft
1379cf655043SAndy Whitcroftsub statement_lines {
1380cf655043SAndy Whitcroft	my ($stmt) = @_;
1381cf655043SAndy Whitcroft
1382cf655043SAndy Whitcroft	# Strip the diff line prefixes and rip blank lines at start and end.
1383cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1384cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1385cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1386cf655043SAndy Whitcroft
1387cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1388cf655043SAndy Whitcroft
1389cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1390cf655043SAndy Whitcroft}
1391cf655043SAndy Whitcroft
1392cf655043SAndy Whitcroftsub statement_rawlines {
1393cf655043SAndy Whitcroft	my ($stmt) = @_;
1394cf655043SAndy Whitcroft
1395cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1396cf655043SAndy Whitcroft
1397cf655043SAndy Whitcroft	return $#stmt_lines + 2;
1398cf655043SAndy Whitcroft}
1399cf655043SAndy Whitcroft
1400cf655043SAndy Whitcroftsub statement_block_size {
1401cf655043SAndy Whitcroft	my ($stmt) = @_;
1402cf655043SAndy Whitcroft
1403cf655043SAndy Whitcroft	$stmt =~ s/(^|\n)./$1/g;
1404cf655043SAndy Whitcroft	$stmt =~ s/^\s*{//;
1405cf655043SAndy Whitcroft	$stmt =~ s/}\s*$//;
1406cf655043SAndy Whitcroft	$stmt =~ s/^\s*//;
1407cf655043SAndy Whitcroft	$stmt =~ s/\s*$//;
1408cf655043SAndy Whitcroft
1409cf655043SAndy Whitcroft	my @stmt_lines = ($stmt =~ /\n/g);
1410cf655043SAndy Whitcroft	my @stmt_statements = ($stmt =~ /;/g);
1411cf655043SAndy Whitcroft
1412cf655043SAndy Whitcroft	my $stmt_lines = $#stmt_lines + 2;
1413cf655043SAndy Whitcroft	my $stmt_statements = $#stmt_statements + 1;
1414cf655043SAndy Whitcroft
1415cf655043SAndy Whitcroft	if ($stmt_lines > $stmt_statements) {
1416cf655043SAndy Whitcroft		return $stmt_lines;
1417cf655043SAndy Whitcroft	} else {
1418cf655043SAndy Whitcroft		return $stmt_statements;
1419cf655043SAndy Whitcroft	}
1420cf655043SAndy Whitcroft}
1421cf655043SAndy Whitcroft
142213214adfSAndy Whitcroftsub ctx_statement_full {
142313214adfSAndy Whitcroft	my ($linenr, $remain, $off) = @_;
142413214adfSAndy Whitcroft	my ($statement, $condition, $level);
142513214adfSAndy Whitcroft
142613214adfSAndy Whitcroft	my (@chunks);
142713214adfSAndy Whitcroft
1428cf655043SAndy Whitcroft	# Grab the first conditional/block pair.
142913214adfSAndy Whitcroft	($statement, $condition, $linenr, $remain, $off, $level) =
143013214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1431773647a0SAndy Whitcroft	#print "F: c<$condition> s<$statement> remain<$remain>\n";
143213214adfSAndy Whitcroft	push(@chunks, [ $condition, $statement ]);
1433cf655043SAndy Whitcroft	if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1434cf655043SAndy Whitcroft		return ($level, $linenr, @chunks);
1435cf655043SAndy Whitcroft	}
1436cf655043SAndy Whitcroft
1437cf655043SAndy Whitcroft	# Pull in the following conditional/block pairs and see if they
1438cf655043SAndy Whitcroft	# could continue the statement.
1439cf655043SAndy Whitcroft	for (;;) {
144013214adfSAndy Whitcroft		($statement, $condition, $linenr, $remain, $off, $level) =
144113214adfSAndy Whitcroft				ctx_statement_block($linenr, $remain, $off);
1442cf655043SAndy Whitcroft		#print "C: c<$condition> s<$statement> remain<$remain>\n";
1443773647a0SAndy Whitcroft		last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1444cf655043SAndy Whitcroft		#print "C: push\n";
1445cf655043SAndy Whitcroft		push(@chunks, [ $condition, $statement ]);
144613214adfSAndy Whitcroft	}
144713214adfSAndy Whitcroft
144813214adfSAndy Whitcroft	return ($level, $linenr, @chunks);
14498905a67cSAndy Whitcroft}
14508905a67cSAndy Whitcroft
14514a0df2efSAndy Whitcroftsub ctx_block_get {
1452f0a594c1SAndy Whitcroft	my ($linenr, $remain, $outer, $open, $close, $off) = @_;
14534a0df2efSAndy Whitcroft	my $line;
14544a0df2efSAndy Whitcroft	my $start = $linenr - 1;
14554a0df2efSAndy Whitcroft	my $blk = '';
14564a0df2efSAndy Whitcroft	my @o;
14574a0df2efSAndy Whitcroft	my @c;
14584a0df2efSAndy Whitcroft	my @res = ();
14594a0df2efSAndy Whitcroft
1460f0a594c1SAndy Whitcroft	my $level = 0;
14614635f4fbSAndy Whitcroft	my @stack = ($level);
146200df344fSAndy Whitcroft	for ($line = $start; $remain > 0; $line++) {
146300df344fSAndy Whitcroft		next if ($rawlines[$line] =~ /^-/);
146400df344fSAndy Whitcroft		$remain--;
146500df344fSAndy Whitcroft
146600df344fSAndy Whitcroft		$blk .= $rawlines[$line];
14674635f4fbSAndy Whitcroft
14684635f4fbSAndy Whitcroft		# Handle nested #if/#else.
146901464f30SAndy Whitcroft		if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
14704635f4fbSAndy Whitcroft			push(@stack, $level);
147101464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
14724635f4fbSAndy Whitcroft			$level = $stack[$#stack - 1];
147301464f30SAndy Whitcroft		} elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
14744635f4fbSAndy Whitcroft			$level = pop(@stack);
14754635f4fbSAndy Whitcroft		}
14764635f4fbSAndy Whitcroft
147701464f30SAndy Whitcroft		foreach my $c (split(//, $lines[$line])) {
1478f0a594c1SAndy Whitcroft			##print "C<$c>L<$level><$open$close>O<$off>\n";
1479f0a594c1SAndy Whitcroft			if ($off > 0) {
1480f0a594c1SAndy Whitcroft				$off--;
1481f0a594c1SAndy Whitcroft				next;
1482f0a594c1SAndy Whitcroft			}
14834a0df2efSAndy Whitcroft
1484f0a594c1SAndy Whitcroft			if ($c eq $close && $level > 0) {
1485f0a594c1SAndy Whitcroft				$level--;
1486f0a594c1SAndy Whitcroft				last if ($level == 0);
1487f0a594c1SAndy Whitcroft			} elsif ($c eq $open) {
1488f0a594c1SAndy Whitcroft				$level++;
1489f0a594c1SAndy Whitcroft			}
1490f0a594c1SAndy Whitcroft		}
14914a0df2efSAndy Whitcroft
1492f0a594c1SAndy Whitcroft		if (!$outer || $level <= 1) {
149300df344fSAndy Whitcroft			push(@res, $rawlines[$line]);
14944a0df2efSAndy Whitcroft		}
14954a0df2efSAndy Whitcroft
1496f0a594c1SAndy Whitcroft		last if ($level == 0);
14974a0df2efSAndy Whitcroft	}
14984a0df2efSAndy Whitcroft
1499f0a594c1SAndy Whitcroft	return ($level, @res);
15004a0df2efSAndy Whitcroft}
15014a0df2efSAndy Whitcroftsub ctx_block_outer {
15024a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
15034a0df2efSAndy Whitcroft
1504f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1505f0a594c1SAndy Whitcroft	return @r;
15064a0df2efSAndy Whitcroft}
15074a0df2efSAndy Whitcroftsub ctx_block {
15084a0df2efSAndy Whitcroft	my ($linenr, $remain) = @_;
15094a0df2efSAndy Whitcroft
1510f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1511f0a594c1SAndy Whitcroft	return @r;
1512653d4876SAndy Whitcroft}
1513653d4876SAndy Whitcroftsub ctx_statement {
1514f0a594c1SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
1515f0a594c1SAndy Whitcroft
1516f0a594c1SAndy Whitcroft	my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1517f0a594c1SAndy Whitcroft	return @r;
1518f0a594c1SAndy Whitcroft}
1519f0a594c1SAndy Whitcroftsub ctx_block_level {
1520653d4876SAndy Whitcroft	my ($linenr, $remain) = @_;
1521653d4876SAndy Whitcroft
1522f0a594c1SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
15234a0df2efSAndy Whitcroft}
15249c0ca6f9SAndy Whitcroftsub ctx_statement_level {
15259c0ca6f9SAndy Whitcroft	my ($linenr, $remain, $off) = @_;
15269c0ca6f9SAndy Whitcroft
15279c0ca6f9SAndy Whitcroft	return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
15289c0ca6f9SAndy Whitcroft}
15294a0df2efSAndy Whitcroft
15304a0df2efSAndy Whitcroftsub ctx_locate_comment {
15314a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
15324a0df2efSAndy Whitcroft
15334a0df2efSAndy Whitcroft	# Catch a comment on the end of the line itself.
1534beae6332SAndy Whitcroft	my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
15354a0df2efSAndy Whitcroft	return $current_comment if (defined $current_comment);
15364a0df2efSAndy Whitcroft
15374a0df2efSAndy Whitcroft	# Look through the context and try and figure out if there is a
15384a0df2efSAndy Whitcroft	# comment.
15394a0df2efSAndy Whitcroft	my $in_comment = 0;
15404a0df2efSAndy Whitcroft	$current_comment = '';
15414a0df2efSAndy Whitcroft	for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
154200df344fSAndy Whitcroft		my $line = $rawlines[$linenr - 1];
154300df344fSAndy Whitcroft		#warn "           $line\n";
15444a0df2efSAndy Whitcroft		if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
15454a0df2efSAndy Whitcroft			$in_comment = 1;
15464a0df2efSAndy Whitcroft		}
15474a0df2efSAndy Whitcroft		if ($line =~ m@/\*@) {
15484a0df2efSAndy Whitcroft			$in_comment = 1;
15494a0df2efSAndy Whitcroft		}
15504a0df2efSAndy Whitcroft		if (!$in_comment && $current_comment ne '') {
15514a0df2efSAndy Whitcroft			$current_comment = '';
15524a0df2efSAndy Whitcroft		}
15534a0df2efSAndy Whitcroft		$current_comment .= $line . "\n" if ($in_comment);
15544a0df2efSAndy Whitcroft		if ($line =~ m@\*/@) {
15554a0df2efSAndy Whitcroft			$in_comment = 0;
15564a0df2efSAndy Whitcroft		}
15574a0df2efSAndy Whitcroft	}
15584a0df2efSAndy Whitcroft
15594a0df2efSAndy Whitcroft	chomp($current_comment);
15604a0df2efSAndy Whitcroft	return($current_comment);
15614a0df2efSAndy Whitcroft}
15624a0df2efSAndy Whitcroftsub ctx_has_comment {
15634a0df2efSAndy Whitcroft	my ($first_line, $end_line) = @_;
15644a0df2efSAndy Whitcroft	my $cmt = ctx_locate_comment($first_line, $end_line);
15654a0df2efSAndy Whitcroft
156600df344fSAndy Whitcroft	##print "LINE: $rawlines[$end_line - 1 ]\n";
15674a0df2efSAndy Whitcroft	##print "CMMT: $cmt\n";
15684a0df2efSAndy Whitcroft
15694a0df2efSAndy Whitcroft	return ($cmt ne '');
15704a0df2efSAndy Whitcroft}
15714a0df2efSAndy Whitcroft
15724d001e4dSAndy Whitcroftsub raw_line {
15734d001e4dSAndy Whitcroft	my ($linenr, $cnt) = @_;
15744d001e4dSAndy Whitcroft
15754d001e4dSAndy Whitcroft	my $offset = $linenr - 1;
15764d001e4dSAndy Whitcroft	$cnt++;
15774d001e4dSAndy Whitcroft
15784d001e4dSAndy Whitcroft	my $line;
15794d001e4dSAndy Whitcroft	while ($cnt) {
15804d001e4dSAndy Whitcroft		$line = $rawlines[$offset++];
15814d001e4dSAndy Whitcroft		next if (defined($line) && $line =~ /^-/);
15824d001e4dSAndy Whitcroft		$cnt--;
15834d001e4dSAndy Whitcroft	}
15844d001e4dSAndy Whitcroft
15854d001e4dSAndy Whitcroft	return $line;
15864d001e4dSAndy Whitcroft}
15874d001e4dSAndy Whitcroft
15880a920b5bSAndy Whitcroftsub cat_vet {
15890a920b5bSAndy Whitcroft	my ($vet) = @_;
15909c0ca6f9SAndy Whitcroft	my ($res, $coded);
15910a920b5bSAndy Whitcroft
15929c0ca6f9SAndy Whitcroft	$res = '';
15936c72ffaaSAndy Whitcroft	while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
15946c72ffaaSAndy Whitcroft		$res .= $1;
15956c72ffaaSAndy Whitcroft		if ($2 ne '') {
15969c0ca6f9SAndy Whitcroft			$coded = sprintf("^%c", unpack('C', $2) + 64);
15976c72ffaaSAndy Whitcroft			$res .= $coded;
15986c72ffaaSAndy Whitcroft		}
15999c0ca6f9SAndy Whitcroft	}
16009c0ca6f9SAndy Whitcroft	$res =~ s/$/\$/;
16010a920b5bSAndy Whitcroft
16029c0ca6f9SAndy Whitcroft	return $res;
16030a920b5bSAndy Whitcroft}
16040a920b5bSAndy Whitcroft
1605c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0;
1606cf655043SAndy Whitcroftmy $av_pending;
1607c2fdda0dSAndy Whitcroftmy @av_paren_type;
16081f65f947SAndy Whitcroftmy $av_pend_colon;
1609c2fdda0dSAndy Whitcroft
1610c2fdda0dSAndy Whitcroftsub annotate_reset {
1611c2fdda0dSAndy Whitcroft	$av_preprocessor = 0;
1612cf655043SAndy Whitcroft	$av_pending = '_';
1613cf655043SAndy Whitcroft	@av_paren_type = ('E');
16141f65f947SAndy Whitcroft	$av_pend_colon = 'O';
1615c2fdda0dSAndy Whitcroft}
1616c2fdda0dSAndy Whitcroft
16176c72ffaaSAndy Whitcroftsub annotate_values {
16186c72ffaaSAndy Whitcroft	my ($stream, $type) = @_;
16196c72ffaaSAndy Whitcroft
16206c72ffaaSAndy Whitcroft	my $res;
16211f65f947SAndy Whitcroft	my $var = '_' x length($stream);
16226c72ffaaSAndy Whitcroft	my $cur = $stream;
16236c72ffaaSAndy Whitcroft
1624c2fdda0dSAndy Whitcroft	print "$stream\n" if ($dbg_values > 1);
16256c72ffaaSAndy Whitcroft
16266c72ffaaSAndy Whitcroft	while (length($cur)) {
1627773647a0SAndy Whitcroft		@av_paren_type = ('E') if ($#av_paren_type < 0);
1628cf655043SAndy Whitcroft		print " <" . join('', @av_paren_type) .
1629171ae1a4SAndy Whitcroft				"> <$type> <$av_pending>" if ($dbg_values > 1);
16306c72ffaaSAndy Whitcroft		if ($cur =~ /^(\s+)/o) {
1631c2fdda0dSAndy Whitcroft			print "WS($1)\n" if ($dbg_values > 1);
1632c2fdda0dSAndy Whitcroft			if ($1 =~ /\n/ && $av_preprocessor) {
1633cf655043SAndy Whitcroft				$type = pop(@av_paren_type);
1634c2fdda0dSAndy Whitcroft				$av_preprocessor = 0;
16356c72ffaaSAndy Whitcroft			}
16366c72ffaaSAndy Whitcroft
1637c023e473SFlorian Mickler		} elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
16389446ef56SAndy Whitcroft			print "CAST($1)\n" if ($dbg_values > 1);
16399446ef56SAndy Whitcroft			push(@av_paren_type, $type);
1640addcdceaSAndy Whitcroft			$type = 'c';
16419446ef56SAndy Whitcroft
1642e91b6e26SAndy Whitcroft		} elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
1643c2fdda0dSAndy Whitcroft			print "DECLARE($1)\n" if ($dbg_values > 1);
16446c72ffaaSAndy Whitcroft			$type = 'T';
16456c72ffaaSAndy Whitcroft
1646389a2fe5SAndy Whitcroft		} elsif ($cur =~ /^($Modifier)\s*/) {
1647389a2fe5SAndy Whitcroft			print "MODIFIER($1)\n" if ($dbg_values > 1);
1648389a2fe5SAndy Whitcroft			$type = 'T';
1649389a2fe5SAndy Whitcroft
1650c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
1651171ae1a4SAndy Whitcroft			print "DEFINE($1,$2)\n" if ($dbg_values > 1);
1652c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1653171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
1654171ae1a4SAndy Whitcroft			if ($2 ne '') {
1655cf655043SAndy Whitcroft				$av_pending = 'N';
1656171ae1a4SAndy Whitcroft			}
1657171ae1a4SAndy Whitcroft			$type = 'E';
1658171ae1a4SAndy Whitcroft
1659c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
1660171ae1a4SAndy Whitcroft			print "UNDEF($1)\n" if ($dbg_values > 1);
1661171ae1a4SAndy Whitcroft			$av_preprocessor = 1;
1662171ae1a4SAndy Whitcroft			push(@av_paren_type, $type);
16636c72ffaaSAndy Whitcroft
1664c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
1665cf655043SAndy Whitcroft			print "PRE_START($1)\n" if ($dbg_values > 1);
1666c2fdda0dSAndy Whitcroft			$av_preprocessor = 1;
1667cf655043SAndy Whitcroft
1668cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1669cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1670171ae1a4SAndy Whitcroft			$type = 'E';
1671cf655043SAndy Whitcroft
1672c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
1673cf655043SAndy Whitcroft			print "PRE_RESTART($1)\n" if ($dbg_values > 1);
1674cf655043SAndy Whitcroft			$av_preprocessor = 1;
1675cf655043SAndy Whitcroft
1676cf655043SAndy Whitcroft			push(@av_paren_type, $av_paren_type[$#av_paren_type]);
1677cf655043SAndy Whitcroft
1678171ae1a4SAndy Whitcroft			$type = 'E';
1679cf655043SAndy Whitcroft
1680c45dcabdSAndy Whitcroft		} elsif ($cur =~ /^(\#\s*(?:endif))/o) {
1681cf655043SAndy Whitcroft			print "PRE_END($1)\n" if ($dbg_values > 1);
1682cf655043SAndy Whitcroft
1683cf655043SAndy Whitcroft			$av_preprocessor = 1;
1684cf655043SAndy Whitcroft
1685cf655043SAndy Whitcroft			# Assume all arms of the conditional end as this
1686cf655043SAndy Whitcroft			# one does, and continue as if the #endif was not here.
1687cf655043SAndy Whitcroft			pop(@av_paren_type);
1688cf655043SAndy Whitcroft			push(@av_paren_type, $type);
1689171ae1a4SAndy Whitcroft			$type = 'E';
16906c72ffaaSAndy Whitcroft
16916c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\\\n)/o) {
1692c2fdda0dSAndy Whitcroft			print "PRECONT($1)\n" if ($dbg_values > 1);
16936c72ffaaSAndy Whitcroft
1694171ae1a4SAndy Whitcroft		} elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
1695171ae1a4SAndy Whitcroft			print "ATTR($1)\n" if ($dbg_values > 1);
1696171ae1a4SAndy Whitcroft			$av_pending = $type;
1697171ae1a4SAndy Whitcroft			$type = 'N';
1698171ae1a4SAndy Whitcroft
16996c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
1700c2fdda0dSAndy Whitcroft			print "SIZEOF($1)\n" if ($dbg_values > 1);
17016c72ffaaSAndy Whitcroft			if (defined $2) {
1702cf655043SAndy Whitcroft				$av_pending = 'V';
17036c72ffaaSAndy Whitcroft			}
17046c72ffaaSAndy Whitcroft			$type = 'N';
17056c72ffaaSAndy Whitcroft
170614b111c1SAndy Whitcroft		} elsif ($cur =~ /^(if|while|for)\b/o) {
1707c2fdda0dSAndy Whitcroft			print "COND($1)\n" if ($dbg_values > 1);
170814b111c1SAndy Whitcroft			$av_pending = 'E';
17096c72ffaaSAndy Whitcroft			$type = 'N';
17106c72ffaaSAndy Whitcroft
17111f65f947SAndy Whitcroft		} elsif ($cur =~/^(case)/o) {
17121f65f947SAndy Whitcroft			print "CASE($1)\n" if ($dbg_values > 1);
17131f65f947SAndy Whitcroft			$av_pend_colon = 'C';
17141f65f947SAndy Whitcroft			$type = 'N';
17151f65f947SAndy Whitcroft
171614b111c1SAndy Whitcroft		} elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
1717c2fdda0dSAndy Whitcroft			print "KEYWORD($1)\n" if ($dbg_values > 1);
17186c72ffaaSAndy Whitcroft			$type = 'N';
17196c72ffaaSAndy Whitcroft
17206c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\()/o) {
1721c2fdda0dSAndy Whitcroft			print "PAREN('$1')\n" if ($dbg_values > 1);
1722cf655043SAndy Whitcroft			push(@av_paren_type, $av_pending);
1723cf655043SAndy Whitcroft			$av_pending = '_';
17246c72ffaaSAndy Whitcroft			$type = 'N';
17256c72ffaaSAndy Whitcroft
17266c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^(\))/o) {
1727cf655043SAndy Whitcroft			my $new_type = pop(@av_paren_type);
1728cf655043SAndy Whitcroft			if ($new_type ne '_') {
1729cf655043SAndy Whitcroft				$type = $new_type;
1730c2fdda0dSAndy Whitcroft				print "PAREN('$1') -> $type\n"
1731c2fdda0dSAndy Whitcroft							if ($dbg_values > 1);
17326c72ffaaSAndy Whitcroft			} else {
1733c2fdda0dSAndy Whitcroft				print "PAREN('$1')\n" if ($dbg_values > 1);
17346c72ffaaSAndy Whitcroft			}
17356c72ffaaSAndy Whitcroft
1736c8cb2ca3SAndy Whitcroft		} elsif ($cur =~ /^($Ident)\s*\(/o) {
1737c2fdda0dSAndy Whitcroft			print "FUNC($1)\n" if ($dbg_values > 1);
1738c8cb2ca3SAndy Whitcroft			$type = 'V';
1739cf655043SAndy Whitcroft			$av_pending = 'V';
17406c72ffaaSAndy Whitcroft
17418e761b04SAndy Whitcroft		} elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
17428e761b04SAndy Whitcroft			if (defined $2 && $type eq 'C' || $type eq 'T') {
17431f65f947SAndy Whitcroft				$av_pend_colon = 'B';
17448e761b04SAndy Whitcroft			} elsif ($type eq 'E') {
17458e761b04SAndy Whitcroft				$av_pend_colon = 'L';
17461f65f947SAndy Whitcroft			}
17471f65f947SAndy Whitcroft			print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
17481f65f947SAndy Whitcroft			$type = 'V';
17491f65f947SAndy Whitcroft
17506c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Ident|$Constant)/o) {
1751c2fdda0dSAndy Whitcroft			print "IDENT($1)\n" if ($dbg_values > 1);
17526c72ffaaSAndy Whitcroft			$type = 'V';
17536c72ffaaSAndy Whitcroft
17546c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Assignment)/o) {
1755c2fdda0dSAndy Whitcroft			print "ASSIGN($1)\n" if ($dbg_values > 1);
17566c72ffaaSAndy Whitcroft			$type = 'N';
17576c72ffaaSAndy Whitcroft
1758cf655043SAndy Whitcroft		} elsif ($cur =~/^(;|{|})/) {
1759c2fdda0dSAndy Whitcroft			print "END($1)\n" if ($dbg_values > 1);
176013214adfSAndy Whitcroft			$type = 'E';
17611f65f947SAndy Whitcroft			$av_pend_colon = 'O';
176213214adfSAndy Whitcroft
17638e761b04SAndy Whitcroft		} elsif ($cur =~/^(,)/) {
17648e761b04SAndy Whitcroft			print "COMMA($1)\n" if ($dbg_values > 1);
17658e761b04SAndy Whitcroft			$type = 'C';
17668e761b04SAndy Whitcroft
17671f65f947SAndy Whitcroft		} elsif ($cur =~ /^(\?)/o) {
17681f65f947SAndy Whitcroft			print "QUESTION($1)\n" if ($dbg_values > 1);
17691f65f947SAndy Whitcroft			$type = 'N';
17701f65f947SAndy Whitcroft
17711f65f947SAndy Whitcroft		} elsif ($cur =~ /^(:)/o) {
17721f65f947SAndy Whitcroft			print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
17731f65f947SAndy Whitcroft
17741f65f947SAndy Whitcroft			substr($var, length($res), 1, $av_pend_colon);
17751f65f947SAndy Whitcroft			if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
17761f65f947SAndy Whitcroft				$type = 'E';
17771f65f947SAndy Whitcroft			} else {
17781f65f947SAndy Whitcroft				$type = 'N';
17791f65f947SAndy Whitcroft			}
17801f65f947SAndy Whitcroft			$av_pend_colon = 'O';
17811f65f947SAndy Whitcroft
17828e761b04SAndy Whitcroft		} elsif ($cur =~ /^(\[)/o) {
178313214adfSAndy Whitcroft			print "CLOSE($1)\n" if ($dbg_values > 1);
17846c72ffaaSAndy Whitcroft			$type = 'N';
17856c72ffaaSAndy Whitcroft
17860d413866SAndy Whitcroft		} elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
178774048ed8SAndy Whitcroft			my $variant;
178874048ed8SAndy Whitcroft
178974048ed8SAndy Whitcroft			print "OPV($1)\n" if ($dbg_values > 1);
179074048ed8SAndy Whitcroft			if ($type eq 'V') {
179174048ed8SAndy Whitcroft				$variant = 'B';
179274048ed8SAndy Whitcroft			} else {
179374048ed8SAndy Whitcroft				$variant = 'U';
179474048ed8SAndy Whitcroft			}
179574048ed8SAndy Whitcroft
179674048ed8SAndy Whitcroft			substr($var, length($res), 1, $variant);
179774048ed8SAndy Whitcroft			$type = 'N';
179874048ed8SAndy Whitcroft
17996c72ffaaSAndy Whitcroft		} elsif ($cur =~ /^($Operators)/o) {
1800c2fdda0dSAndy Whitcroft			print "OP($1)\n" if ($dbg_values > 1);
18016c72ffaaSAndy Whitcroft			if ($1 ne '++' && $1 ne '--') {
18026c72ffaaSAndy Whitcroft				$type = 'N';
18036c72ffaaSAndy Whitcroft			}
18046c72ffaaSAndy Whitcroft
18056c72ffaaSAndy Whitcroft		} elsif ($cur =~ /(^.)/o) {
1806c2fdda0dSAndy Whitcroft			print "C($1)\n" if ($dbg_values > 1);
18076c72ffaaSAndy Whitcroft		}
18086c72ffaaSAndy Whitcroft		if (defined $1) {
18096c72ffaaSAndy Whitcroft			$cur = substr($cur, length($1));
18106c72ffaaSAndy Whitcroft			$res .= $type x length($1);
18116c72ffaaSAndy Whitcroft		}
18126c72ffaaSAndy Whitcroft	}
18136c72ffaaSAndy Whitcroft
18141f65f947SAndy Whitcroft	return ($res, $var);
18156c72ffaaSAndy Whitcroft}
18166c72ffaaSAndy Whitcroft
18178905a67cSAndy Whitcroftsub possible {
181813214adfSAndy Whitcroft	my ($possible, $line) = @_;
18199a974fdbSAndy Whitcroft	my $notPermitted = qr{(?:
18200776e594SAndy Whitcroft		^(?:
18210776e594SAndy Whitcroft			$Modifier|
18220776e594SAndy Whitcroft			$Storage|
18230776e594SAndy Whitcroft			$Type|
18249a974fdbSAndy Whitcroft			DEFINE_\S+
18259a974fdbSAndy Whitcroft		)$|
18269a974fdbSAndy Whitcroft		^(?:
18270776e594SAndy Whitcroft			goto|
18280776e594SAndy Whitcroft			return|
18290776e594SAndy Whitcroft			case|
18300776e594SAndy Whitcroft			else|
18310776e594SAndy Whitcroft			asm|__asm__|
183289a88353SAndy Whitcroft			do|
183389a88353SAndy Whitcroft			\#|
183489a88353SAndy Whitcroft			\#\#|
18359a974fdbSAndy Whitcroft		)(?:\s|$)|
18360776e594SAndy Whitcroft		^(?:typedef|struct|enum)\b
18379a974fdbSAndy Whitcroft	    )}x;
18389a974fdbSAndy Whitcroft	warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
18399a974fdbSAndy Whitcroft	if ($possible !~ $notPermitted) {
1840c45dcabdSAndy Whitcroft		# Check for modifiers.
1841c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Storage\s*//g;
1842c45dcabdSAndy Whitcroft		$possible =~ s/\s*$Sparse\s*//g;
1843c45dcabdSAndy Whitcroft		if ($possible =~ /^\s*$/) {
1844c45dcabdSAndy Whitcroft
1845c45dcabdSAndy Whitcroft		} elsif ($possible =~ /\s/) {
1846c45dcabdSAndy Whitcroft			$possible =~ s/\s*$Type\s*//g;
1847d2506586SAndy Whitcroft			for my $modifier (split(' ', $possible)) {
18489a974fdbSAndy Whitcroft				if ($modifier !~ $notPermitted) {
1849d2506586SAndy Whitcroft					warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
1850485ff23eSAlex Dowad					push(@modifierListFile, $modifier);
1851d2506586SAndy Whitcroft				}
18529a974fdbSAndy Whitcroft			}
1853c45dcabdSAndy Whitcroft
1854c45dcabdSAndy Whitcroft		} else {
185513214adfSAndy Whitcroft			warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
1856485ff23eSAlex Dowad			push(@typeListFile, $possible);
1857c45dcabdSAndy Whitcroft		}
18588905a67cSAndy Whitcroft		build_types();
18590776e594SAndy Whitcroft	} else {
18600776e594SAndy Whitcroft		warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
18618905a67cSAndy Whitcroft	}
18628905a67cSAndy Whitcroft}
18638905a67cSAndy Whitcroft
18646c72ffaaSAndy Whitcroftmy $prefix = '';
18656c72ffaaSAndy Whitcroft
1866000d1cc1SJoe Perchessub show_type {
1867cbec18afSJoe Perches	my ($type) = @_;
186891bfe484SJoe Perches
1869522b837cSAlexey Dobriyan	$type =~ tr/[a-z]/[A-Z]/;
1870522b837cSAlexey Dobriyan
1871cbec18afSJoe Perches	return defined $use_type{$type} if (scalar keys %use_type > 0);
1872cbec18afSJoe Perches
1873cbec18afSJoe Perches	return !defined $ignore_type{$type};
1874000d1cc1SJoe Perches}
1875000d1cc1SJoe Perches
1876f0a594c1SAndy Whitcroftsub report {
1877cbec18afSJoe Perches	my ($level, $type, $msg) = @_;
1878cbec18afSJoe Perches
1879cbec18afSJoe Perches	if (!show_type($type) ||
1880cbec18afSJoe Perches	    (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
1881773647a0SAndy Whitcroft		return 0;
1882773647a0SAndy Whitcroft	}
188357230297SJoe Perches	my $output = '';
188457230297SJoe Perches	if (-t STDOUT && $color) {
188557230297SJoe Perches		if ($level eq 'ERROR') {
188657230297SJoe Perches			$output .= RED;
188757230297SJoe Perches		} elsif ($level eq 'WARNING') {
188857230297SJoe Perches			$output .= YELLOW;
1889000d1cc1SJoe Perches		} else {
189057230297SJoe Perches			$output .= GREEN;
1891000d1cc1SJoe Perches		}
189257230297SJoe Perches	}
189357230297SJoe Perches	$output .= $prefix . $level . ':';
189457230297SJoe Perches	if ($show_types) {
189557230297SJoe Perches		$output .= BLUE if (-t STDOUT && $color);
189657230297SJoe Perches		$output .= "$type:";
189757230297SJoe Perches	}
189857230297SJoe Perches	$output .= RESET if (-t STDOUT && $color);
189957230297SJoe Perches	$output .= ' ' . $msg . "\n";
190034d8815fSJoe Perches
190134d8815fSJoe Perches	if ($showfile) {
190234d8815fSJoe Perches		my @lines = split("\n", $output, -1);
190334d8815fSJoe Perches		splice(@lines, 1, 1);
190434d8815fSJoe Perches		$output = join("\n", @lines);
190534d8815fSJoe Perches	}
190657230297SJoe Perches	$output = (split('\n', $output))[0] . "\n" if ($terse);
19078905a67cSAndy Whitcroft
190857230297SJoe Perches	push(our @report, $output);
1909773647a0SAndy Whitcroft
1910773647a0SAndy Whitcroft	return 1;
1911f0a594c1SAndy Whitcroft}
1912cbec18afSJoe Perches
1913f0a594c1SAndy Whitcroftsub report_dump {
191413214adfSAndy Whitcroft	our @report;
1915f0a594c1SAndy Whitcroft}
1916000d1cc1SJoe Perches
1917d752fcc8SJoe Perchessub fixup_current_range {
1918d752fcc8SJoe Perches	my ($lineRef, $offset, $length) = @_;
1919d752fcc8SJoe Perches
1920d752fcc8SJoe Perches	if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
1921d752fcc8SJoe Perches		my $o = $1;
1922d752fcc8SJoe Perches		my $l = $2;
1923d752fcc8SJoe Perches		my $no = $o + $offset;
1924d752fcc8SJoe Perches		my $nl = $l + $length;
1925d752fcc8SJoe Perches		$$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
1926d752fcc8SJoe Perches	}
1927d752fcc8SJoe Perches}
1928d752fcc8SJoe Perches
1929d752fcc8SJoe Perchessub fix_inserted_deleted_lines {
1930d752fcc8SJoe Perches	my ($linesRef, $insertedRef, $deletedRef) = @_;
1931d752fcc8SJoe Perches
1932d752fcc8SJoe Perches	my $range_last_linenr = 0;
1933d752fcc8SJoe Perches	my $delta_offset = 0;
1934d752fcc8SJoe Perches
1935d752fcc8SJoe Perches	my $old_linenr = 0;
1936d752fcc8SJoe Perches	my $new_linenr = 0;
1937d752fcc8SJoe Perches
1938d752fcc8SJoe Perches	my $next_insert = 0;
1939d752fcc8SJoe Perches	my $next_delete = 0;
1940d752fcc8SJoe Perches
1941d752fcc8SJoe Perches	my @lines = ();
1942d752fcc8SJoe Perches
1943d752fcc8SJoe Perches	my $inserted = @{$insertedRef}[$next_insert++];
1944d752fcc8SJoe Perches	my $deleted = @{$deletedRef}[$next_delete++];
1945d752fcc8SJoe Perches
1946d752fcc8SJoe Perches	foreach my $old_line (@{$linesRef}) {
1947d752fcc8SJoe Perches		my $save_line = 1;
1948d752fcc8SJoe Perches		my $line = $old_line;	#don't modify the array
1949323b267fSJoe Perches		if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) {	#new filename
1950d752fcc8SJoe Perches			$delta_offset = 0;
1951d752fcc8SJoe Perches		} elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) {	#new hunk
1952d752fcc8SJoe Perches			$range_last_linenr = $new_linenr;
1953d752fcc8SJoe Perches			fixup_current_range(\$line, $delta_offset, 0);
1954d752fcc8SJoe Perches		}
1955d752fcc8SJoe Perches
1956d752fcc8SJoe Perches		while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
1957d752fcc8SJoe Perches			$deleted = @{$deletedRef}[$next_delete++];
1958d752fcc8SJoe Perches			$save_line = 0;
1959d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
1960d752fcc8SJoe Perches		}
1961d752fcc8SJoe Perches
1962d752fcc8SJoe Perches		while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
1963d752fcc8SJoe Perches			push(@lines, ${$inserted}{'LINE'});
1964d752fcc8SJoe Perches			$inserted = @{$insertedRef}[$next_insert++];
1965d752fcc8SJoe Perches			$new_linenr++;
1966d752fcc8SJoe Perches			fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
1967d752fcc8SJoe Perches		}
1968d752fcc8SJoe Perches
1969d752fcc8SJoe Perches		if ($save_line) {
1970d752fcc8SJoe Perches			push(@lines, $line);
1971d752fcc8SJoe Perches			$new_linenr++;
1972d752fcc8SJoe Perches		}
1973d752fcc8SJoe Perches
1974d752fcc8SJoe Perches		$old_linenr++;
1975d752fcc8SJoe Perches	}
1976d752fcc8SJoe Perches
1977d752fcc8SJoe Perches	return @lines;
1978d752fcc8SJoe Perches}
1979d752fcc8SJoe Perches
1980f2d7e4d4SJoe Perchessub fix_insert_line {
1981f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
1982f2d7e4d4SJoe Perches
1983f2d7e4d4SJoe Perches	my $inserted = {
1984f2d7e4d4SJoe Perches		LINENR => $linenr,
1985f2d7e4d4SJoe Perches		LINE => $line,
1986f2d7e4d4SJoe Perches	};
1987f2d7e4d4SJoe Perches	push(@fixed_inserted, $inserted);
1988f2d7e4d4SJoe Perches}
1989f2d7e4d4SJoe Perches
1990f2d7e4d4SJoe Perchessub fix_delete_line {
1991f2d7e4d4SJoe Perches	my ($linenr, $line) = @_;
1992f2d7e4d4SJoe Perches
1993f2d7e4d4SJoe Perches	my $deleted = {
1994f2d7e4d4SJoe Perches		LINENR => $linenr,
1995f2d7e4d4SJoe Perches		LINE => $line,
1996f2d7e4d4SJoe Perches	};
1997f2d7e4d4SJoe Perches
1998f2d7e4d4SJoe Perches	push(@fixed_deleted, $deleted);
1999f2d7e4d4SJoe Perches}
2000f2d7e4d4SJoe Perches
2001de7d4f0eSAndy Whitcroftsub ERROR {
2002cbec18afSJoe Perches	my ($type, $msg) = @_;
2003cbec18afSJoe Perches
2004cbec18afSJoe Perches	if (report("ERROR", $type, $msg)) {
2005de7d4f0eSAndy Whitcroft		our $clean = 0;
20066c72ffaaSAndy Whitcroft		our $cnt_error++;
20073705ce5bSJoe Perches		return 1;
2008de7d4f0eSAndy Whitcroft	}
20093705ce5bSJoe Perches	return 0;
2010773647a0SAndy Whitcroft}
2011de7d4f0eSAndy Whitcroftsub WARN {
2012cbec18afSJoe Perches	my ($type, $msg) = @_;
2013cbec18afSJoe Perches
2014cbec18afSJoe Perches	if (report("WARNING", $type, $msg)) {
2015de7d4f0eSAndy Whitcroft		our $clean = 0;
20166c72ffaaSAndy Whitcroft		our $cnt_warn++;
20173705ce5bSJoe Perches		return 1;
2018de7d4f0eSAndy Whitcroft	}
20193705ce5bSJoe Perches	return 0;
2020773647a0SAndy Whitcroft}
2021de7d4f0eSAndy Whitcroftsub CHK {
2022cbec18afSJoe Perches	my ($type, $msg) = @_;
2023cbec18afSJoe Perches
2024cbec18afSJoe Perches	if ($check && report("CHECK", $type, $msg)) {
2025de7d4f0eSAndy Whitcroft		our $clean = 0;
20266c72ffaaSAndy Whitcroft		our $cnt_chk++;
20273705ce5bSJoe Perches		return 1;
20286c72ffaaSAndy Whitcroft	}
20293705ce5bSJoe Perches	return 0;
2030de7d4f0eSAndy Whitcroft}
2031de7d4f0eSAndy Whitcroft
20326ecd9674SAndy Whitcroftsub check_absolute_file {
20336ecd9674SAndy Whitcroft	my ($absolute, $herecurr) = @_;
20346ecd9674SAndy Whitcroft	my $file = $absolute;
20356ecd9674SAndy Whitcroft
20366ecd9674SAndy Whitcroft	##print "absolute<$absolute>\n";
20376ecd9674SAndy Whitcroft
20386ecd9674SAndy Whitcroft	# See if any suffix of this path is a path within the tree.
20396ecd9674SAndy Whitcroft	while ($file =~ s@^[^/]*/@@) {
20406ecd9674SAndy Whitcroft		if (-f "$root/$file") {
20416ecd9674SAndy Whitcroft			##print "file<$file>\n";
20426ecd9674SAndy Whitcroft			last;
20436ecd9674SAndy Whitcroft		}
20446ecd9674SAndy Whitcroft	}
20456ecd9674SAndy Whitcroft	if (! -f _)  {
20466ecd9674SAndy Whitcroft		return 0;
20476ecd9674SAndy Whitcroft	}
20486ecd9674SAndy Whitcroft
20496ecd9674SAndy Whitcroft	# It is, so see if the prefix is acceptable.
20506ecd9674SAndy Whitcroft	my $prefix = $absolute;
20516ecd9674SAndy Whitcroft	substr($prefix, -length($file)) = '';
20526ecd9674SAndy Whitcroft
20536ecd9674SAndy Whitcroft	##print "prefix<$prefix>\n";
20546ecd9674SAndy Whitcroft	if ($prefix ne ".../") {
2055000d1cc1SJoe Perches		WARN("USE_RELATIVE_PATH",
2056000d1cc1SJoe Perches		     "use relative pathname instead of absolute in changelog text\n" . $herecurr);
20576ecd9674SAndy Whitcroft	}
20586ecd9674SAndy Whitcroft}
20596ecd9674SAndy Whitcroft
20603705ce5bSJoe Perchessub trim {
20613705ce5bSJoe Perches	my ($string) = @_;
20623705ce5bSJoe Perches
2063b34c648bSJoe Perches	$string =~ s/^\s+|\s+$//g;
2064b34c648bSJoe Perches
2065b34c648bSJoe Perches	return $string;
2066b34c648bSJoe Perches}
2067b34c648bSJoe Perches
2068b34c648bSJoe Perchessub ltrim {
2069b34c648bSJoe Perches	my ($string) = @_;
2070b34c648bSJoe Perches
2071b34c648bSJoe Perches	$string =~ s/^\s+//;
2072b34c648bSJoe Perches
2073b34c648bSJoe Perches	return $string;
2074b34c648bSJoe Perches}
2075b34c648bSJoe Perches
2076b34c648bSJoe Perchessub rtrim {
2077b34c648bSJoe Perches	my ($string) = @_;
2078b34c648bSJoe Perches
2079b34c648bSJoe Perches	$string =~ s/\s+$//;
20803705ce5bSJoe Perches
20813705ce5bSJoe Perches	return $string;
20823705ce5bSJoe Perches}
20833705ce5bSJoe Perches
208452ea8506SJoe Perchessub string_find_replace {
208552ea8506SJoe Perches	my ($string, $find, $replace) = @_;
208652ea8506SJoe Perches
208752ea8506SJoe Perches	$string =~ s/$find/$replace/g;
208852ea8506SJoe Perches
208952ea8506SJoe Perches	return $string;
209052ea8506SJoe Perches}
209152ea8506SJoe Perches
20923705ce5bSJoe Perchessub tabify {
20933705ce5bSJoe Perches	my ($leading) = @_;
20943705ce5bSJoe Perches
20953705ce5bSJoe Perches	my $source_indent = 8;
20963705ce5bSJoe Perches	my $max_spaces_before_tab = $source_indent - 1;
20973705ce5bSJoe Perches	my $spaces_to_tab = " " x $source_indent;
20983705ce5bSJoe Perches
20993705ce5bSJoe Perches	#convert leading spaces to tabs
21003705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
21013705ce5bSJoe Perches	#Remove spaces before a tab
21023705ce5bSJoe Perches	1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
21033705ce5bSJoe Perches
21043705ce5bSJoe Perches	return "$leading";
21053705ce5bSJoe Perches}
21063705ce5bSJoe Perches
2107d1fe9c09SJoe Perchessub pos_last_openparen {
2108d1fe9c09SJoe Perches	my ($line) = @_;
2109d1fe9c09SJoe Perches
2110d1fe9c09SJoe Perches	my $pos = 0;
2111d1fe9c09SJoe Perches
2112d1fe9c09SJoe Perches	my $opens = $line =~ tr/\(/\(/;
2113d1fe9c09SJoe Perches	my $closes = $line =~ tr/\)/\)/;
2114d1fe9c09SJoe Perches
2115d1fe9c09SJoe Perches	my $last_openparen = 0;
2116d1fe9c09SJoe Perches
2117d1fe9c09SJoe Perches	if (($opens == 0) || ($closes >= $opens)) {
2118d1fe9c09SJoe Perches		return -1;
2119d1fe9c09SJoe Perches	}
2120d1fe9c09SJoe Perches
2121d1fe9c09SJoe Perches	my $len = length($line);
2122d1fe9c09SJoe Perches
2123d1fe9c09SJoe Perches	for ($pos = 0; $pos < $len; $pos++) {
2124d1fe9c09SJoe Perches		my $string = substr($line, $pos);
2125d1fe9c09SJoe Perches		if ($string =~ /^($FuncArg|$balanced_parens)/) {
2126d1fe9c09SJoe Perches			$pos += length($1) - 1;
2127d1fe9c09SJoe Perches		} elsif (substr($line, $pos, 1) eq '(') {
2128d1fe9c09SJoe Perches			$last_openparen = $pos;
2129d1fe9c09SJoe Perches		} elsif (index($string, '(') == -1) {
2130d1fe9c09SJoe Perches			last;
2131d1fe9c09SJoe Perches		}
2132d1fe9c09SJoe Perches	}
2133d1fe9c09SJoe Perches
213491cb5195SJoe Perches	return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
2135d1fe9c09SJoe Perches}
2136d1fe9c09SJoe Perches
21370a920b5bSAndy Whitcroftsub process {
21380a920b5bSAndy Whitcroft	my $filename = shift;
21390a920b5bSAndy Whitcroft
21400a920b5bSAndy Whitcroft	my $linenr=0;
21410a920b5bSAndy Whitcroft	my $prevline="";
2142c2fdda0dSAndy Whitcroft	my $prevrawline="";
21430a920b5bSAndy Whitcroft	my $stashline="";
2144c2fdda0dSAndy Whitcroft	my $stashrawline="";
21450a920b5bSAndy Whitcroft
21464a0df2efSAndy Whitcroft	my $length;
21470a920b5bSAndy Whitcroft	my $indent;
21480a920b5bSAndy Whitcroft	my $previndent=0;
21490a920b5bSAndy Whitcroft	my $stashindent=0;
21500a920b5bSAndy Whitcroft
2151de7d4f0eSAndy Whitcroft	our $clean = 1;
21520a920b5bSAndy Whitcroft	my $signoff = 0;
21530a920b5bSAndy Whitcroft	my $is_patch = 0;
215429ee1b0cSJoe Perches	my $in_header_lines = $file ? 0 : 1;
215515662b3eSJoe Perches	my $in_commit_log = 0;		#Scanning lines before patch
2156ed43c4e5SAllen Hubbe	my $has_commit_log = 0;		#Encountered lines before patch
2157bf4daf12SJoe Perches	my $commit_log_possible_stack_dump = 0;
21582a076f40SJoe Perches	my $commit_log_long_line = 0;
2159e518e9a5SJoe Perches	my $commit_log_has_diff = 0;
216013f1937eSJoe Perches	my $reported_maintainer_file = 0;
2161fa64205dSPasi Savanainen	my $non_utf8_charset = 0;
2162fa64205dSPasi Savanainen
2163365dd4eaSJoe Perches	my $last_blank_line = 0;
21645e4f6ba5SJoe Perches	my $last_coalesced_string_linenr = -1;
2165365dd4eaSJoe Perches
216613214adfSAndy Whitcroft	our @report = ();
21676c72ffaaSAndy Whitcroft	our $cnt_lines = 0;
21686c72ffaaSAndy Whitcroft	our $cnt_error = 0;
21696c72ffaaSAndy Whitcroft	our $cnt_warn = 0;
21706c72ffaaSAndy Whitcroft	our $cnt_chk = 0;
21716c72ffaaSAndy Whitcroft
21720a920b5bSAndy Whitcroft	# Trace the real file/line as we go.
21730a920b5bSAndy Whitcroft	my $realfile = '';
21740a920b5bSAndy Whitcroft	my $realline = 0;
21750a920b5bSAndy Whitcroft	my $realcnt = 0;
21760a920b5bSAndy Whitcroft	my $here = '';
217777cb8546SJoe Perches	my $context_function;		#undef'd unless there's a known function
21780a920b5bSAndy Whitcroft	my $in_comment = 0;
2179c2fdda0dSAndy Whitcroft	my $comment_edge = 0;
21800a920b5bSAndy Whitcroft	my $first_line = 0;
21811e855726SWolfram Sang	my $p1_prefix = '';
21820a920b5bSAndy Whitcroft
218313214adfSAndy Whitcroft	my $prev_values = 'E';
218413214adfSAndy Whitcroft
218513214adfSAndy Whitcroft	# suppression flags
2186773647a0SAndy Whitcroft	my %suppress_ifbraces;
2187170d3a22SAndy Whitcroft	my %suppress_whiletrailers;
21882b474a1aSAndy Whitcroft	my %suppress_export;
21893e469cdcSAndy Whitcroft	my $suppress_statement = 0;
2190653d4876SAndy Whitcroft
21917e51f197SJoe Perches	my %signatures = ();
2192323c1260SJoe Perches
2193c2fdda0dSAndy Whitcroft	# Pre-scan the patch sanitizing the lines.
2194de7d4f0eSAndy Whitcroft	# Pre-scan the patch looking for any __setup documentation.
2195c2fdda0dSAndy Whitcroft	#
2196de7d4f0eSAndy Whitcroft	my @setup_docs = ();
2197de7d4f0eSAndy Whitcroft	my $setup_docs = 0;
2198773647a0SAndy Whitcroft
2199d8b07710SJoe Perches	my $camelcase_file_seeded = 0;
2200d8b07710SJoe Perches
2201773647a0SAndy Whitcroft	sanitise_line_reset();
2202c2fdda0dSAndy Whitcroft	my $line;
2203c2fdda0dSAndy Whitcroft	foreach my $rawline (@rawlines) {
2204773647a0SAndy Whitcroft		$linenr++;
2205773647a0SAndy Whitcroft		$line = $rawline;
2206c2fdda0dSAndy Whitcroft
22073705ce5bSJoe Perches		push(@fixed, $rawline) if ($fix);
22083705ce5bSJoe Perches
2209773647a0SAndy Whitcroft		if ($rawline=~/^\+\+\+\s+(\S+)/) {
2210de7d4f0eSAndy Whitcroft			$setup_docs = 0;
22118c27ceffSMauro Carvalho Chehab			if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) {
2212de7d4f0eSAndy Whitcroft				$setup_docs = 1;
2213de7d4f0eSAndy Whitcroft			}
2214773647a0SAndy Whitcroft			#next;
2215de7d4f0eSAndy Whitcroft		}
2216*74fd4f34SJoe Perches		if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
2217773647a0SAndy Whitcroft			$realline=$1-1;
2218773647a0SAndy Whitcroft			if (defined $2) {
2219773647a0SAndy Whitcroft				$realcnt=$3+1;
2220773647a0SAndy Whitcroft			} else {
2221773647a0SAndy Whitcroft				$realcnt=1+1;
2222773647a0SAndy Whitcroft			}
2223c45dcabdSAndy Whitcroft			$in_comment = 0;
2224773647a0SAndy Whitcroft
2225773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  Run
2226773647a0SAndy Whitcroft			# the context looking for a comment "edge".  If this
2227773647a0SAndy Whitcroft			# edge is a close comment then we must be in a comment
2228773647a0SAndy Whitcroft			# at context start.
2229773647a0SAndy Whitcroft			my $edge;
223001fa9147SAndy Whitcroft			my $cnt = $realcnt;
223101fa9147SAndy Whitcroft			for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
223201fa9147SAndy Whitcroft				next if (defined $rawlines[$ln - 1] &&
223301fa9147SAndy Whitcroft					 $rawlines[$ln - 1] =~ /^-/);
223401fa9147SAndy Whitcroft				$cnt--;
223501fa9147SAndy Whitcroft				#print "RAW<$rawlines[$ln - 1]>\n";
2236721c1cb6SAndy Whitcroft				last if (!defined $rawlines[$ln - 1]);
2237fae17daeSAndy Whitcroft				if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
2238fae17daeSAndy Whitcroft				    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
2239fae17daeSAndy Whitcroft					($edge) = $1;
2240fae17daeSAndy Whitcroft					last;
2241fae17daeSAndy Whitcroft				}
2242773647a0SAndy Whitcroft			}
2243773647a0SAndy Whitcroft			if (defined $edge && $edge eq '*/') {
2244773647a0SAndy Whitcroft				$in_comment = 1;
2245773647a0SAndy Whitcroft			}
2246773647a0SAndy Whitcroft
2247773647a0SAndy Whitcroft			# Guestimate if this is a continuing comment.  If this
2248773647a0SAndy Whitcroft			# is the start of a diff block and this line starts
2249773647a0SAndy Whitcroft			# ' *' then it is very likely a comment.
2250773647a0SAndy Whitcroft			if (!defined $edge &&
225183242e0cSAndy Whitcroft			    $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
2252773647a0SAndy Whitcroft			{
2253773647a0SAndy Whitcroft				$in_comment = 1;
2254773647a0SAndy Whitcroft			}
2255773647a0SAndy Whitcroft
2256773647a0SAndy Whitcroft			##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2257773647a0SAndy Whitcroft			sanitise_line_reset($in_comment);
2258773647a0SAndy Whitcroft
2259171ae1a4SAndy Whitcroft		} elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
2260773647a0SAndy Whitcroft			# Standardise the strings and chars within the input to
2261171ae1a4SAndy Whitcroft			# simplify matching -- only bother with positive lines.
2262773647a0SAndy Whitcroft			$line = sanitise_line($rawline);
2263773647a0SAndy Whitcroft		}
2264773647a0SAndy Whitcroft		push(@lines, $line);
2265773647a0SAndy Whitcroft
2266773647a0SAndy Whitcroft		if ($realcnt > 1) {
2267773647a0SAndy Whitcroft			$realcnt-- if ($line =~ /^(?:\+| |$)/);
2268773647a0SAndy Whitcroft		} else {
2269773647a0SAndy Whitcroft			$realcnt = 0;
2270773647a0SAndy Whitcroft		}
2271773647a0SAndy Whitcroft
2272773647a0SAndy Whitcroft		#print "==>$rawline\n";
2273773647a0SAndy Whitcroft		#print "-->$line\n";
2274de7d4f0eSAndy Whitcroft
2275de7d4f0eSAndy Whitcroft		if ($setup_docs && $line =~ /^\+/) {
2276de7d4f0eSAndy Whitcroft			push(@setup_docs, $line);
2277de7d4f0eSAndy Whitcroft		}
2278de7d4f0eSAndy Whitcroft	}
2279de7d4f0eSAndy Whitcroft
22806c72ffaaSAndy Whitcroft	$prefix = '';
22816c72ffaaSAndy Whitcroft
2282773647a0SAndy Whitcroft	$realcnt = 0;
2283773647a0SAndy Whitcroft	$linenr = 0;
2284194f66fcSJoe Perches	$fixlinenr = -1;
22850a920b5bSAndy Whitcroft	foreach my $line (@lines) {
22860a920b5bSAndy Whitcroft		$linenr++;
2287194f66fcSJoe Perches		$fixlinenr++;
22881b5539b1SJoe Perches		my $sline = $line;	#copy of $line
22891b5539b1SJoe Perches		$sline =~ s/$;/ /g;	#with comments as spaces
22900a920b5bSAndy Whitcroft
2291c2fdda0dSAndy Whitcroft		my $rawline = $rawlines[$linenr - 1];
22926c72ffaaSAndy Whitcroft
22930a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied
2294e518e9a5SJoe Perches		if (!$in_commit_log &&
2295*74fd4f34SJoe Perches		    $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
2296*74fd4f34SJoe Perches			my $context = $4;
22970a920b5bSAndy Whitcroft			$is_patch = 1;
22984a0df2efSAndy Whitcroft			$first_line = $linenr + 1;
22990a920b5bSAndy Whitcroft			$realline=$1-1;
23000a920b5bSAndy Whitcroft			if (defined $2) {
23010a920b5bSAndy Whitcroft				$realcnt=$3+1;
23020a920b5bSAndy Whitcroft			} else {
23030a920b5bSAndy Whitcroft				$realcnt=1+1;
23040a920b5bSAndy Whitcroft			}
2305c2fdda0dSAndy Whitcroft			annotate_reset();
230613214adfSAndy Whitcroft			$prev_values = 'E';
230713214adfSAndy Whitcroft
2308773647a0SAndy Whitcroft			%suppress_ifbraces = ();
2309170d3a22SAndy Whitcroft			%suppress_whiletrailers = ();
23102b474a1aSAndy Whitcroft			%suppress_export = ();
23113e469cdcSAndy Whitcroft			$suppress_statement = 0;
2312*74fd4f34SJoe Perches			if ($context =~ /\b(\w+)\s*\(/) {
2313*74fd4f34SJoe Perches				$context_function = $1;
2314*74fd4f34SJoe Perches			} else {
2315*74fd4f34SJoe Perches				undef $context_function;
2316*74fd4f34SJoe Perches			}
23170a920b5bSAndy Whitcroft			next;
23180a920b5bSAndy Whitcroft
23194a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that
23204a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely
23214a0df2efSAndy Whitcroft# blank context lines so we need to count that too.
2322773647a0SAndy Whitcroft		} elsif ($line =~ /^( |\+|$)/) {
23230a920b5bSAndy Whitcroft			$realline++;
2324d8aaf121SAndy Whitcroft			$realcnt-- if ($realcnt != 0);
23250a920b5bSAndy Whitcroft
23264a0df2efSAndy Whitcroft			# Measure the line length and indent.
2327c2fdda0dSAndy Whitcroft			($length, $indent) = line_stats($rawline);
23280a920b5bSAndy Whitcroft
23290a920b5bSAndy Whitcroft			# Track the previous line.
23300a920b5bSAndy Whitcroft			($prevline, $stashline) = ($stashline, $line);
23310a920b5bSAndy Whitcroft			($previndent, $stashindent) = ($stashindent, $indent);
2332c2fdda0dSAndy Whitcroft			($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2333c2fdda0dSAndy Whitcroft
2334773647a0SAndy Whitcroft			#warn "line<$line>\n";
23356c72ffaaSAndy Whitcroft
2336d8aaf121SAndy Whitcroft		} elsif ($realcnt == 1) {
2337d8aaf121SAndy Whitcroft			$realcnt--;
23380a920b5bSAndy Whitcroft		}
23390a920b5bSAndy Whitcroft
2340cc77cdcaSAndy Whitcroft		my $hunk_line = ($realcnt != 0);
2341cc77cdcaSAndy Whitcroft
23426c72ffaaSAndy Whitcroft		$here = "#$linenr: " if (!$file);
23436c72ffaaSAndy Whitcroft		$here = "#$realline: " if ($file);
2344773647a0SAndy Whitcroft
23452ac73b4fSJoe Perches		my $found_file = 0;
2346773647a0SAndy Whitcroft		# extract the filename as it passes
23473bf9a009SRabin Vincent		if ($line =~ /^diff --git.*?(\S+)$/) {
23483bf9a009SRabin Vincent			$realfile = $1;
23492b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2350270c49a0SJoe Perches			$in_commit_log = 0;
23512ac73b4fSJoe Perches			$found_file = 1;
23523bf9a009SRabin Vincent		} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
2353773647a0SAndy Whitcroft			$realfile = $1;
23542b7ab453SJoe Perches			$realfile =~ s@^([^/]*)/@@ if (!$file);
2355270c49a0SJoe Perches			$in_commit_log = 0;
23561e855726SWolfram Sang
23571e855726SWolfram Sang			$p1_prefix = $1;
2358e2f7aa4bSAndy Whitcroft			if (!$file && $tree && $p1_prefix ne '' &&
2359e2f7aa4bSAndy Whitcroft			    -e "$root/$p1_prefix") {
2360000d1cc1SJoe Perches				WARN("PATCH_PREFIX",
2361000d1cc1SJoe Perches				     "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
23621e855726SWolfram Sang			}
2363773647a0SAndy Whitcroft
2364c1ab3326SAndy Whitcroft			if ($realfile =~ m@^include/asm/@) {
2365000d1cc1SJoe Perches				ERROR("MODIFIED_INCLUDE_ASM",
2366000d1cc1SJoe Perches				      "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
2367773647a0SAndy Whitcroft			}
23682ac73b4fSJoe Perches			$found_file = 1;
23692ac73b4fSJoe Perches		}
23702ac73b4fSJoe Perches
237134d8815fSJoe Perches#make up the handle for any error we report on this line
237234d8815fSJoe Perches		if ($showfile) {
237334d8815fSJoe Perches			$prefix = "$realfile:$realline: "
237434d8815fSJoe Perches		} elsif ($emacs) {
23757d3a9f67SJoe Perches			if ($file) {
23767d3a9f67SJoe Perches				$prefix = "$filename:$realline: ";
23777d3a9f67SJoe Perches			} else {
237834d8815fSJoe Perches				$prefix = "$filename:$linenr: ";
237934d8815fSJoe Perches			}
23807d3a9f67SJoe Perches		}
238134d8815fSJoe Perches
23822ac73b4fSJoe Perches		if ($found_file) {
238385b0ee18SJoe Perches			if (is_maintained_obsolete($realfile)) {
238485b0ee18SJoe Perches				WARN("OBSOLETE",
238585b0ee18SJoe Perches				     "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy.  No unnecessary modifications please.\n");
238685b0ee18SJoe Perches			}
23877bd7e483SJoe Perches			if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
23882ac73b4fSJoe Perches				$check = 1;
23892ac73b4fSJoe Perches			} else {
23902ac73b4fSJoe Perches				$check = $check_orig;
23912ac73b4fSJoe Perches			}
2392773647a0SAndy Whitcroft			next;
2393773647a0SAndy Whitcroft		}
2394773647a0SAndy Whitcroft
2395389834b6SRandy Dunlap		$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
23960a920b5bSAndy Whitcroft
2397c2fdda0dSAndy Whitcroft		my $hereline = "$here\n$rawline\n";
2398c2fdda0dSAndy Whitcroft		my $herecurr = "$here\n$rawline\n";
2399c2fdda0dSAndy Whitcroft		my $hereprev = "$here\n$prevrawline\n$rawline\n";
24000a920b5bSAndy Whitcroft
24016c72ffaaSAndy Whitcroft		$cnt_lines++ if ($realcnt != 0);
24026c72ffaaSAndy Whitcroft
2403e518e9a5SJoe Perches# Check if the commit log has what seems like a diff which can confuse patch
2404e518e9a5SJoe Perches		if ($in_commit_log && !$commit_log_has_diff &&
2405e518e9a5SJoe Perches		    (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&
2406e518e9a5SJoe Perches		      $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||
2407e518e9a5SJoe Perches		     $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
2408e518e9a5SJoe Perches		     $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
2409e518e9a5SJoe Perches			ERROR("DIFF_IN_COMMIT_MSG",
2410e518e9a5SJoe Perches			      "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
2411e518e9a5SJoe Perches			$commit_log_has_diff = 1;
2412e518e9a5SJoe Perches		}
2413e518e9a5SJoe Perches
24143bf9a009SRabin Vincent# Check for incorrect file permissions
24153bf9a009SRabin Vincent		if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
24163bf9a009SRabin Vincent			my $permhere = $here . "FILE: $realfile\n";
241704db4d25SJoe Perches			if ($realfile !~ m@scripts/@ &&
241804db4d25SJoe Perches			    $realfile !~ /\.(py|pl|awk|sh)$/) {
2419000d1cc1SJoe Perches				ERROR("EXECUTE_PERMISSIONS",
2420000d1cc1SJoe Perches				      "do not set execute permissions for source files\n" . $permhere);
24213bf9a009SRabin Vincent			}
24223bf9a009SRabin Vincent		}
24233bf9a009SRabin Vincent
242420112475SJoe Perches# Check the patch for a signoff:
2425d8aaf121SAndy Whitcroft		if ($line =~ /^\s*signed-off-by:/i) {
24264a0df2efSAndy Whitcroft			$signoff++;
242715662b3eSJoe Perches			$in_commit_log = 0;
24280a920b5bSAndy Whitcroft		}
242920112475SJoe Perches
2430e0d975b1SJoe Perches# Check if MAINTAINERS is being updated.  If so, there's probably no need to
2431e0d975b1SJoe Perches# emit the "does MAINTAINERS need updating?" message on file add/move/delete
2432e0d975b1SJoe Perches		if ($line =~ /^\s*MAINTAINERS\s*\|/) {
2433e0d975b1SJoe Perches			$reported_maintainer_file = 1;
2434e0d975b1SJoe Perches		}
2435e0d975b1SJoe Perches
243620112475SJoe Perches# Check signature styles
2437270c49a0SJoe Perches		if (!$in_header_lines &&
2438ce0338dfSJoe Perches		    $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
243920112475SJoe Perches			my $space_before = $1;
244020112475SJoe Perches			my $sign_off = $2;
244120112475SJoe Perches			my $space_after = $3;
244220112475SJoe Perches			my $email = $4;
244320112475SJoe Perches			my $ucfirst_sign_off = ucfirst(lc($sign_off));
244420112475SJoe Perches
2445ce0338dfSJoe Perches			if ($sign_off !~ /$signature_tags/) {
2446ce0338dfSJoe Perches				WARN("BAD_SIGN_OFF",
2447ce0338dfSJoe Perches				     "Non-standard signature: $sign_off\n" . $herecurr);
2448ce0338dfSJoe Perches			}
244920112475SJoe Perches			if (defined $space_before && $space_before ne "") {
24503705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
24513705ce5bSJoe Perches					 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
24523705ce5bSJoe Perches				    $fix) {
2453194f66fcSJoe Perches					$fixed[$fixlinenr] =
24543705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
24553705ce5bSJoe Perches				}
245620112475SJoe Perches			}
245720112475SJoe Perches			if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
24583705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
24593705ce5bSJoe Perches					 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
24603705ce5bSJoe Perches				    $fix) {
2461194f66fcSJoe Perches					$fixed[$fixlinenr] =
24623705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
24633705ce5bSJoe Perches				}
24643705ce5bSJoe Perches
246520112475SJoe Perches			}
246620112475SJoe Perches			if (!defined $space_after || $space_after ne " ") {
24673705ce5bSJoe Perches				if (WARN("BAD_SIGN_OFF",
24683705ce5bSJoe Perches					 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
24693705ce5bSJoe Perches				    $fix) {
2470194f66fcSJoe Perches					$fixed[$fixlinenr] =
24713705ce5bSJoe Perches					    "$ucfirst_sign_off $email";
24723705ce5bSJoe Perches				}
247320112475SJoe Perches			}
247420112475SJoe Perches
247520112475SJoe Perches			my ($email_name, $email_address, $comment) = parse_email($email);
247620112475SJoe Perches			my $suggested_email = format_email(($email_name, $email_address));
247720112475SJoe Perches			if ($suggested_email eq "") {
2478000d1cc1SJoe Perches				ERROR("BAD_SIGN_OFF",
2479000d1cc1SJoe Perches				      "Unrecognized email address: '$email'\n" . $herecurr);
248020112475SJoe Perches			} else {
248120112475SJoe Perches				my $dequoted = $suggested_email;
248220112475SJoe Perches				$dequoted =~ s/^"//;
248320112475SJoe Perches				$dequoted =~ s/" </ </;
248420112475SJoe Perches				# Don't force email to have quotes
248520112475SJoe Perches				# Allow just an angle bracketed address
248620112475SJoe Perches				if ("$dequoted$comment" ne $email &&
248720112475SJoe Perches				    "<$email_address>$comment" ne $email &&
248820112475SJoe Perches				    "$suggested_email$comment" ne $email) {
2489000d1cc1SJoe Perches					WARN("BAD_SIGN_OFF",
2490000d1cc1SJoe Perches					     "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
249120112475SJoe Perches				}
24920a920b5bSAndy Whitcroft			}
24937e51f197SJoe Perches
24947e51f197SJoe Perches# Check for duplicate signatures
24957e51f197SJoe Perches			my $sig_nospace = $line;
24967e51f197SJoe Perches			$sig_nospace =~ s/\s//g;
24977e51f197SJoe Perches			$sig_nospace = lc($sig_nospace);
24987e51f197SJoe Perches			if (defined $signatures{$sig_nospace}) {
24997e51f197SJoe Perches				WARN("BAD_SIGN_OFF",
25007e51f197SJoe Perches				     "Duplicate signature\n" . $herecurr);
25017e51f197SJoe Perches			} else {
25027e51f197SJoe Perches				$signatures{$sig_nospace} = 1;
25037e51f197SJoe Perches			}
25040a920b5bSAndy Whitcroft		}
25050a920b5bSAndy Whitcroft
2506a2fe16b9SJoe Perches# Check email subject for common tools that don't need to be mentioned
2507a2fe16b9SJoe Perches		if ($in_header_lines &&
2508a2fe16b9SJoe Perches		    $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
2509a2fe16b9SJoe Perches			WARN("EMAIL_SUBJECT",
2510a2fe16b9SJoe Perches			     "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
2511a2fe16b9SJoe Perches		}
2512a2fe16b9SJoe Perches
25139b3189ebSJoe Perches# Check for old stable address
25149b3189ebSJoe Perches		if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) {
25159b3189ebSJoe Perches			ERROR("STABLE_ADDRESS",
25169b3189ebSJoe Perches			      "The 'stable' address should be 'stable\@vger.kernel.org'\n" . $herecurr);
25179b3189ebSJoe Perches		}
25189b3189ebSJoe Perches
25197ebd05efSChristopher Covington# Check for unwanted Gerrit info
25207ebd05efSChristopher Covington		if ($in_commit_log && $line =~ /^\s*change-id:/i) {
25217ebd05efSChristopher Covington			ERROR("GERRIT_CHANGE_ID",
25227ebd05efSChristopher Covington			      "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr);
25237ebd05efSChristopher Covington		}
25247ebd05efSChristopher Covington
2525369c8dd3SJoe Perches# Check if the commit log is in a possible stack dump
2526369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
2527369c8dd3SJoe Perches		    ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
2528369c8dd3SJoe Perches		     $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
2529369c8dd3SJoe Perches					# timestamp
2530369c8dd3SJoe Perches		     $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) {
2531369c8dd3SJoe Perches					# stack dump address
2532369c8dd3SJoe Perches			$commit_log_possible_stack_dump = 1;
2533369c8dd3SJoe Perches		}
2534369c8dd3SJoe Perches
25352a076f40SJoe Perches# Check for line lengths > 75 in commit log, warn once
25362a076f40SJoe Perches		if ($in_commit_log && !$commit_log_long_line &&
2537bf4daf12SJoe Perches		    length($line) > 75 &&
2538bf4daf12SJoe Perches		    !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
2539bf4daf12SJoe Perches					# file delta changes
2540bf4daf12SJoe Perches		      $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||
2541bf4daf12SJoe Perches					# filename then :
2542bf4daf12SJoe Perches		      $line =~ /^\s*(?:Fixes:|Link:)/i ||
2543bf4daf12SJoe Perches					# A Fixes: or Link: line
2544bf4daf12SJoe Perches		      $commit_log_possible_stack_dump)) {
25452a076f40SJoe Perches			WARN("COMMIT_LOG_LONG_LINE",
25462a076f40SJoe Perches			     "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
25472a076f40SJoe Perches			$commit_log_long_line = 1;
25482a076f40SJoe Perches		}
25492a076f40SJoe Perches
2550bf4daf12SJoe Perches# Reset possible stack dump if a blank line is found
2551bf4daf12SJoe Perches		if ($in_commit_log && $commit_log_possible_stack_dump &&
2552bf4daf12SJoe Perches		    $line =~ /^\s*$/) {
2553bf4daf12SJoe Perches			$commit_log_possible_stack_dump = 0;
2554bf4daf12SJoe Perches		}
2555bf4daf12SJoe Perches
25560d7835fcSJoe Perches# Check for git id commit length and improperly formed commit descriptions
2557369c8dd3SJoe Perches		if ($in_commit_log && !$commit_log_possible_stack_dump &&
2558aab38f51SJoe Perches		    $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i &&
2559e882dbfcSWei Wang		    $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
2560fe043ea1SJoe Perches		    ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
2561aab38f51SJoe Perches		     ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
2562369c8dd3SJoe Perches		      $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
2563bf4daf12SJoe Perches		      $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
2564fe043ea1SJoe Perches			my $init_char = "c";
2565fe043ea1SJoe Perches			my $orig_commit = "";
25660d7835fcSJoe Perches			my $short = 1;
25670d7835fcSJoe Perches			my $long = 0;
25680d7835fcSJoe Perches			my $case = 1;
25690d7835fcSJoe Perches			my $space = 1;
25700d7835fcSJoe Perches			my $hasdesc = 0;
257119c146a6SJoe Perches			my $hasparens = 0;
25720d7835fcSJoe Perches			my $id = '0123456789ab';
25730d7835fcSJoe Perches			my $orig_desc = "commit description";
25740d7835fcSJoe Perches			my $description = "";
25750d7835fcSJoe Perches
2576fe043ea1SJoe Perches			if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
2577fe043ea1SJoe Perches				$init_char = $1;
2578fe043ea1SJoe Perches				$orig_commit = lc($2);
2579fe043ea1SJoe Perches			} elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {
2580fe043ea1SJoe Perches				$orig_commit = lc($1);
2581fe043ea1SJoe Perches			}
2582fe043ea1SJoe Perches
25830d7835fcSJoe Perches			$short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);
25840d7835fcSJoe Perches			$long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);
25850d7835fcSJoe Perches			$space = 0 if ($line =~ /\bcommit [0-9a-f]/i);
25860d7835fcSJoe Perches			$case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
25870d7835fcSJoe Perches			if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) {
25880d7835fcSJoe Perches				$orig_desc = $1;
258919c146a6SJoe Perches				$hasparens = 1;
25900d7835fcSJoe Perches			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i &&
25910d7835fcSJoe Perches				 defined $rawlines[$linenr] &&
25920d7835fcSJoe Perches				 $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) {
25930d7835fcSJoe Perches				$orig_desc = $1;
259419c146a6SJoe Perches				$hasparens = 1;
2595b671fde0SJoe Perches			} elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i &&
2596b671fde0SJoe Perches				 defined $rawlines[$linenr] &&
2597b671fde0SJoe Perches				 $rawlines[$linenr] =~ /^\s*[^"]+"\)/) {
2598b671fde0SJoe Perches				$line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i;
2599b671fde0SJoe Perches				$orig_desc = $1;
2600b671fde0SJoe Perches				$rawlines[$linenr] =~ /^\s*([^"]+)"\)/;
2601b671fde0SJoe Perches				$orig_desc .= " " . $1;
260219c146a6SJoe Perches				$hasparens = 1;
26030d7835fcSJoe Perches			}
26040d7835fcSJoe Perches
26050d7835fcSJoe Perches			($id, $description) = git_commit_info($orig_commit,
26060d7835fcSJoe Perches							      $id, $orig_desc);
26070d7835fcSJoe Perches
260819c146a6SJoe Perches			if ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens) {
2609d311cd44SJoe Perches				ERROR("GIT_COMMIT_ID",
26100d7835fcSJoe Perches				      "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);
26110d7835fcSJoe Perches			}
2612d311cd44SJoe Perches		}
2613d311cd44SJoe Perches
261413f1937eSJoe Perches# Check for added, moved or deleted files
261513f1937eSJoe Perches		if (!$reported_maintainer_file && !$in_commit_log &&
261613f1937eSJoe Perches		    ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
261713f1937eSJoe Perches		     $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
261813f1937eSJoe Perches		     ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
261913f1937eSJoe Perches		      (defined($1) || defined($2))))) {
2620a82603a8SAndrew Jeffery			$is_patch = 1;
262113f1937eSJoe Perches			$reported_maintainer_file = 1;
262213f1937eSJoe Perches			WARN("FILE_PATH_CHANGES",
262313f1937eSJoe Perches			     "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
262413f1937eSJoe Perches		}
262513f1937eSJoe Perches
262600df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file
26278905a67cSAndy Whitcroft		if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
2628000d1cc1SJoe Perches			ERROR("CORRUPTED_PATCH",
2629000d1cc1SJoe Perches			      "patch seems to be corrupt (line wrapped?)\n" .
26306c72ffaaSAndy Whitcroft				$herecurr) if (!$emitted_corrupt++);
2631de7d4f0eSAndy Whitcroft		}
2632de7d4f0eSAndy Whitcroft
2633de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
2634de7d4f0eSAndy Whitcroft		if (($realfile =~ /^$/ || $line =~ /^\+/) &&
2635171ae1a4SAndy Whitcroft		    $rawline !~ m/^$UTF8*$/) {
2636171ae1a4SAndy Whitcroft			my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
2637171ae1a4SAndy Whitcroft
2638171ae1a4SAndy Whitcroft			my $blank = copy_spacing($rawline);
2639171ae1a4SAndy Whitcroft			my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
2640171ae1a4SAndy Whitcroft			my $hereptr = "$hereline$ptr\n";
2641171ae1a4SAndy Whitcroft
264234d99219SJoe Perches			CHK("INVALID_UTF8",
2643000d1cc1SJoe Perches			    "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
264400df344fSAndy Whitcroft		}
26450a920b5bSAndy Whitcroft
264615662b3eSJoe Perches# Check if it's the start of a commit log
264715662b3eSJoe Perches# (not a header line and we haven't seen the patch filename)
264815662b3eSJoe Perches		if ($in_header_lines && $realfile =~ /^$/ &&
2649eb3a58deSJoe Perches		    !($rawline =~ /^\s+(?:\S|$)/ ||
2650eb3a58deSJoe Perches		      $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
265115662b3eSJoe Perches			$in_header_lines = 0;
265215662b3eSJoe Perches			$in_commit_log = 1;
2653ed43c4e5SAllen Hubbe			$has_commit_log = 1;
265415662b3eSJoe Perches		}
265515662b3eSJoe Perches
2656fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly
2657fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing.
2658fa64205dSPasi Savanainen		if ($in_header_lines &&
2659fa64205dSPasi Savanainen		    $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
2660fa64205dSPasi Savanainen		    $1 !~ /utf-8/i) {
2661fa64205dSPasi Savanainen			$non_utf8_charset = 1;
2662fa64205dSPasi Savanainen		}
2663fa64205dSPasi Savanainen
2664fa64205dSPasi Savanainen		if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
266515662b3eSJoe Perches		    $rawline =~ /$NON_ASCII_UTF8/) {
2666fa64205dSPasi Savanainen			WARN("UTF8_BEFORE_PATCH",
266715662b3eSJoe Perches			    "8-bit UTF-8 used in possible commit log\n" . $herecurr);
266815662b3eSJoe Perches		}
266915662b3eSJoe Perches
2670d6430f71SJoe Perches# Check for absolute kernel paths in commit message
2671d6430f71SJoe Perches		if ($tree && $in_commit_log) {
2672d6430f71SJoe Perches			while ($line =~ m{(?:^|\s)(/\S*)}g) {
2673d6430f71SJoe Perches				my $file = $1;
2674d6430f71SJoe Perches
2675d6430f71SJoe Perches				if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
2676d6430f71SJoe Perches				    check_absolute_file($1, $herecurr)) {
2677d6430f71SJoe Perches					#
2678d6430f71SJoe Perches				} else {
2679d6430f71SJoe Perches					check_absolute_file($file, $herecurr);
2680d6430f71SJoe Perches				}
2681d6430f71SJoe Perches			}
2682d6430f71SJoe Perches		}
2683d6430f71SJoe Perches
268466b47b4aSKees Cook# Check for various typo / spelling mistakes
268566d7a382SJoe Perches		if (defined($misspellings) &&
268666d7a382SJoe Perches		    ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
2687ebfd7d62SJoe Perches			while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) {
268866b47b4aSKees Cook				my $typo = $1;
268966b47b4aSKees Cook				my $typo_fix = $spelling_fix{lc($typo)};
269066b47b4aSKees Cook				$typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
269166b47b4aSKees Cook				$typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
269266b47b4aSKees Cook				my $msg_type = \&WARN;
269366b47b4aSKees Cook				$msg_type = \&CHK if ($file);
269466b47b4aSKees Cook				if (&{$msg_type}("TYPO_SPELLING",
269566b47b4aSKees Cook						 "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) &&
269666b47b4aSKees Cook				    $fix) {
269766b47b4aSKees Cook					$fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
269866b47b4aSKees Cook				}
269966b47b4aSKees Cook			}
270066b47b4aSKees Cook		}
270166b47b4aSKees Cook
270230670854SAndy Whitcroft# ignore non-hunk lines and lines being removed
270330670854SAndy Whitcroft		next if (!$hunk_line || $line =~ /^-/);
270400df344fSAndy Whitcroft
27050a920b5bSAndy Whitcroft#trailing whitespace
27069c0ca6f9SAndy Whitcroft		if ($line =~ /^\+.*\015/) {
2707c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2708d5e616fcSJoe Perches			if (ERROR("DOS_LINE_ENDINGS",
2709d5e616fcSJoe Perches				  "DOS line endings\n" . $herevet) &&
2710d5e616fcSJoe Perches			    $fix) {
2711194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/[\s\015]+$//;
2712d5e616fcSJoe Perches			}
2713c2fdda0dSAndy Whitcroft		} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
2714c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
27153705ce5bSJoe Perches			if (ERROR("TRAILING_WHITESPACE",
27163705ce5bSJoe Perches				  "trailing whitespace\n" . $herevet) &&
27173705ce5bSJoe Perches			    $fix) {
2718194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
27193705ce5bSJoe Perches			}
27203705ce5bSJoe Perches
2721d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
27220a920b5bSAndy Whitcroft		}
27235368df20SAndy Whitcroft
27244783f894SJosh Triplett# Check for FSF mailing addresses.
2725109d8cb2SAlexander Duyck		if ($rawline =~ /\bwrite to the Free/i ||
27261bde561eSMatthew Wilcox		    $rawline =~ /\b675\s+Mass\s+Ave/i ||
27273e2232f2SJoe Perches		    $rawline =~ /\b59\s+Temple\s+Pl/i ||
27283e2232f2SJoe Perches		    $rawline =~ /\b51\s+Franklin\s+St/i) {
27294783f894SJosh Triplett			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
27304783f894SJosh Triplett			my $msg_type = \&ERROR;
27314783f894SJosh Triplett			$msg_type = \&CHK if ($file);
27324783f894SJosh Triplett			&{$msg_type}("FSF_MAILING_ADDRESS",
27334783f894SJosh 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)
27344783f894SJosh Triplett		}
27354783f894SJosh Triplett
27363354957aSAndi Kleen# check for Kconfig help text having a real description
27379fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have
27389fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough.
27393354957aSAndi Kleen		if ($realfile =~ /Kconfig/ &&
27408d73e0e7SJoe Perches		    $line =~ /^\+\s*config\s+/) {
27413354957aSAndi Kleen			my $length = 0;
27429fe287d7SAndy Whitcroft			my $cnt = $realcnt;
27439fe287d7SAndy Whitcroft			my $ln = $linenr + 1;
27449fe287d7SAndy Whitcroft			my $f;
2745a1385803SAndy Whitcroft			my $is_start = 0;
27469fe287d7SAndy Whitcroft			my $is_end = 0;
2747a1385803SAndy Whitcroft			for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
27489fe287d7SAndy Whitcroft				$f = $lines[$ln - 1];
27499fe287d7SAndy Whitcroft				$cnt-- if ($lines[$ln - 1] !~ /^-/);
27509fe287d7SAndy Whitcroft				$is_end = $lines[$ln - 1] =~ /^\+/;
27519fe287d7SAndy Whitcroft
27529fe287d7SAndy Whitcroft				next if ($f =~ /^-/);
27538d73e0e7SJoe Perches				last if (!$file && $f =~ /^\@\@/);
2754a1385803SAndy Whitcroft
27558d73e0e7SJoe Perches				if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate)\s*\"/) {
2756a1385803SAndy Whitcroft					$is_start = 1;
27578d73e0e7SJoe Perches				} elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) {
2758a1385803SAndy Whitcroft					$length = -1;
2759a1385803SAndy Whitcroft				}
2760a1385803SAndy Whitcroft
27619fe287d7SAndy Whitcroft				$f =~ s/^.//;
27623354957aSAndi Kleen				$f =~ s/#.*//;
27633354957aSAndi Kleen				$f =~ s/^\s+//;
27643354957aSAndi Kleen				next if ($f =~ /^$/);
27659fe287d7SAndy Whitcroft				if ($f =~ /^\s*config\s/) {
27669fe287d7SAndy Whitcroft					$is_end = 1;
27679fe287d7SAndy Whitcroft					last;
27689fe287d7SAndy Whitcroft				}
27693354957aSAndi Kleen				$length++;
27703354957aSAndi Kleen			}
277156193274SVadim Bendebury			if ($is_start && $is_end && $length < $min_conf_desc_length) {
2772000d1cc1SJoe Perches				WARN("CONFIG_DESCRIPTION",
277356193274SVadim Bendebury				     "please write a paragraph that describes the config symbol fully\n" . $herecurr);
277456193274SVadim Bendebury			}
2775a1385803SAndy Whitcroft			#print "is_start<$is_start> is_end<$is_end> length<$length>\n";
27763354957aSAndi Kleen		}
27773354957aSAndi Kleen
2778327953e9SChristoph Jaeger# discourage the use of boolean for type definition attributes of Kconfig options
2779327953e9SChristoph Jaeger		if ($realfile =~ /Kconfig/ &&
2780327953e9SChristoph Jaeger		    $line =~ /^\+\s*\bboolean\b/) {
2781327953e9SChristoph Jaeger			WARN("CONFIG_TYPE_BOOLEAN",
2782327953e9SChristoph Jaeger			     "Use of boolean is deprecated, please use bool instead.\n" . $herecurr);
2783327953e9SChristoph Jaeger		}
2784327953e9SChristoph Jaeger
2785c68e5878SArnaud Lacombe		if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
2786c68e5878SArnaud Lacombe		    ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
2787c68e5878SArnaud Lacombe			my $flag = $1;
2788c68e5878SArnaud Lacombe			my $replacement = {
2789c68e5878SArnaud Lacombe				'EXTRA_AFLAGS' =>   'asflags-y',
2790c68e5878SArnaud Lacombe				'EXTRA_CFLAGS' =>   'ccflags-y',
2791c68e5878SArnaud Lacombe				'EXTRA_CPPFLAGS' => 'cppflags-y',
2792c68e5878SArnaud Lacombe				'EXTRA_LDFLAGS' =>  'ldflags-y',
2793c68e5878SArnaud Lacombe			};
2794c68e5878SArnaud Lacombe
2795c68e5878SArnaud Lacombe			WARN("DEPRECATED_VARIABLE",
2796c68e5878SArnaud Lacombe			     "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
2797c68e5878SArnaud Lacombe		}
2798c68e5878SArnaud Lacombe
2799bff5da43SRob Herring# check for DT compatible documentation
28007dd05b38SFlorian Vaussard		if (defined $root &&
28017dd05b38SFlorian Vaussard			(($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
28027dd05b38SFlorian Vaussard			 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
28037dd05b38SFlorian Vaussard
2804bff5da43SRob Herring			my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
2805bff5da43SRob Herring
2806cc93319bSFlorian Vaussard			my $dt_path = $root . "/Documentation/devicetree/bindings/";
2807cc93319bSFlorian Vaussard			my $vp_file = $dt_path . "vendor-prefixes.txt";
2808cc93319bSFlorian Vaussard
2809bff5da43SRob Herring			foreach my $compat (@compats) {
2810bff5da43SRob Herring				my $compat2 = $compat;
2811185d566bSRob Herring				$compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
2812185d566bSRob Herring				my $compat3 = $compat;
2813185d566bSRob Herring				$compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
2814185d566bSRob Herring				`grep -Erq "$compat|$compat2|$compat3" $dt_path`;
2815bff5da43SRob Herring				if ( $? >> 8 ) {
2816bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
2817bff5da43SRob Herring					     "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
2818bff5da43SRob Herring				}
2819bff5da43SRob Herring
28204fbf32a6SFlorian Vaussard				next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
28214fbf32a6SFlorian Vaussard				my $vendor = $1;
2822cc93319bSFlorian Vaussard				`grep -Eq "^$vendor\\b" $vp_file`;
2823bff5da43SRob Herring				if ( $? >> 8 ) {
2824bff5da43SRob Herring					WARN("UNDOCUMENTED_DT_STRING",
2825cc93319bSFlorian Vaussard					     "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
2826bff5da43SRob Herring				}
2827bff5da43SRob Herring			}
2828bff5da43SRob Herring		}
2829bff5da43SRob Herring
28305368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk
2831d6430f71SJoe Perches		next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
28325368df20SAndy Whitcroft
283347e0c88bSJoe Perches# line length limit (with some exclusions)
283447e0c88bSJoe Perches#
283547e0c88bSJoe Perches# There are a few types of lines that may extend beyond $max_line_length:
283647e0c88bSJoe Perches#	logging functions like pr_info that end in a string
283747e0c88bSJoe Perches#	lines with a single string
283847e0c88bSJoe Perches#	#defines that are a single string
283947e0c88bSJoe Perches#
284047e0c88bSJoe Perches# There are 3 different line length message types:
284147e0c88bSJoe Perches# LONG_LINE_COMMENT	a comment starts before but extends beyond $max_linelength
284247e0c88bSJoe Perches# LONG_LINE_STRING	a string starts before but extends beyond $max_line_length
284347e0c88bSJoe Perches# LONG_LINE		all other lines longer than $max_line_length
284447e0c88bSJoe Perches#
284547e0c88bSJoe Perches# if LONG_LINE is ignored, the other 2 types are also ignored
284647e0c88bSJoe Perches#
284747e0c88bSJoe Perches
2848b4749e96SJoe Perches		if ($line =~ /^\+/ && $length > $max_line_length) {
284947e0c88bSJoe Perches			my $msg_type = "LONG_LINE";
285047e0c88bSJoe Perches
285147e0c88bSJoe Perches			# Check the allowed long line types first
285247e0c88bSJoe Perches
285347e0c88bSJoe Perches			# logging functions that end in a string that starts
285447e0c88bSJoe Perches			# before $max_line_length
285547e0c88bSJoe Perches			if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
285647e0c88bSJoe Perches			    length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
285747e0c88bSJoe Perches				$msg_type = "";
285847e0c88bSJoe Perches
285947e0c88bSJoe Perches			# lines with only strings (w/ possible termination)
286047e0c88bSJoe Perches			# #defines with only strings
286147e0c88bSJoe Perches			} elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
286247e0c88bSJoe Perches				 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
286347e0c88bSJoe Perches				$msg_type = "";
286447e0c88bSJoe Perches
2865d560a5f8SJoe Perches			# EFI_GUID is another special case
2866d560a5f8SJoe Perches			} elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/) {
2867d560a5f8SJoe Perches				$msg_type = "";
2868d560a5f8SJoe Perches
286947e0c88bSJoe Perches			# Otherwise set the alternate message types
287047e0c88bSJoe Perches
287147e0c88bSJoe Perches			# a comment starts before $max_line_length
287247e0c88bSJoe Perches			} elsif ($line =~ /($;[\s$;]*)$/ &&
287347e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
287447e0c88bSJoe Perches				$msg_type = "LONG_LINE_COMMENT"
287547e0c88bSJoe Perches
287647e0c88bSJoe Perches			# a quoted string starts before $max_line_length
287747e0c88bSJoe Perches			} elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
287847e0c88bSJoe Perches				 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
287947e0c88bSJoe Perches				$msg_type = "LONG_LINE_STRING"
288047e0c88bSJoe Perches			}
288147e0c88bSJoe Perches
288247e0c88bSJoe Perches			if ($msg_type ne "" &&
288347e0c88bSJoe Perches			    (show_type("LONG_LINE") || show_type($msg_type))) {
288447e0c88bSJoe Perches				WARN($msg_type,
28856cd7f386SJoe Perches				     "line over $max_line_length characters\n" . $herecurr);
28860a920b5bSAndy Whitcroft			}
288747e0c88bSJoe Perches		}
28880a920b5bSAndy Whitcroft
28898905a67cSAndy Whitcroft# check for adding lines without a newline.
28908905a67cSAndy Whitcroft		if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
2891000d1cc1SJoe Perches			WARN("MISSING_EOF_NEWLINE",
2892000d1cc1SJoe Perches			     "adding a line without newline at end of file\n" . $herecurr);
28938905a67cSAndy Whitcroft		}
28948905a67cSAndy Whitcroft
289542e41c54SMike Frysinger# Blackfin: use hi/lo macros
289642e41c54SMike Frysinger		if ($realfile =~ m@arch/blackfin/.*\.S$@) {
289742e41c54SMike Frysinger			if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) {
289842e41c54SMike Frysinger				my $herevet = "$here\n" . cat_vet($line) . "\n";
2899000d1cc1SJoe Perches				ERROR("LO_MACRO",
2900000d1cc1SJoe Perches				      "use the LO() macro, not (... & 0xFFFF)\n" . $herevet);
290142e41c54SMike Frysinger			}
290242e41c54SMike Frysinger			if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) {
290342e41c54SMike Frysinger				my $herevet = "$here\n" . cat_vet($line) . "\n";
2904000d1cc1SJoe Perches				ERROR("HI_MACRO",
2905000d1cc1SJoe Perches				      "use the HI() macro, not (... >> 16)\n" . $herevet);
290642e41c54SMike Frysinger			}
290742e41c54SMike Frysinger		}
290842e41c54SMike Frysinger
2909b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk
2910de4c924cSGeert Uytterhoeven		next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
29110a920b5bSAndy Whitcroft
29120a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything
29130a920b5bSAndy Whitcroft# more than 8 must use tabs.
2914c2fdda0dSAndy Whitcroft		if ($rawline =~ /^\+\s* \t\s*\S/ ||
2915c2fdda0dSAndy Whitcroft		    $rawline =~ /^\+\s*        \s*/) {
2916c2fdda0dSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2917d2c0a235SAndy Whitcroft			$rpt_cleaners = 1;
29183705ce5bSJoe Perches			if (ERROR("CODE_INDENT",
29193705ce5bSJoe Perches				  "code indent should use tabs where possible\n" . $herevet) &&
29203705ce5bSJoe Perches			    $fix) {
2921194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
29223705ce5bSJoe Perches			}
29230a920b5bSAndy Whitcroft		}
29240a920b5bSAndy Whitcroft
292508e44365SAlberto Panizzo# check for space before tabs.
292608e44365SAlberto Panizzo		if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
292708e44365SAlberto Panizzo			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
29283705ce5bSJoe Perches			if (WARN("SPACE_BEFORE_TAB",
29293705ce5bSJoe Perches				"please, no space before tabs\n" . $herevet) &&
29303705ce5bSJoe Perches			    $fix) {
2931194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
2932d2207ccbSJoe Perches					   s/(^\+.*) {8,8}\t/$1\t\t/) {}
2933194f66fcSJoe Perches				while ($fixed[$fixlinenr] =~
2934c76f4cb3SJoe Perches					   s/(^\+.*) +\t/$1\t/) {}
29353705ce5bSJoe Perches			}
293608e44365SAlberto Panizzo		}
293708e44365SAlberto Panizzo
2938d1fe9c09SJoe Perches# check for && or || at the start of a line
2939d1fe9c09SJoe Perches		if ($rawline =~ /^\+\s*(&&|\|\|)/) {
2940d1fe9c09SJoe Perches			CHK("LOGICAL_CONTINUATIONS",
2941d1fe9c09SJoe Perches			    "Logical continuations should be on the previous line\n" . $hereprev);
2942d1fe9c09SJoe Perches		}
2943d1fe9c09SJoe Perches
2944a91e8994SJoe Perches# check indentation starts on a tab stop
2945a91e8994SJoe Perches		if ($^V && $^V ge 5.10.0 &&
2946a91e8994SJoe Perches		    $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$))/) {
2947a91e8994SJoe Perches			my $indent = length($1);
2948a91e8994SJoe Perches			if ($indent % 8) {
2949a91e8994SJoe Perches				if (WARN("TABSTOP",
2950a91e8994SJoe Perches					 "Statements should start on a tabstop\n" . $herecurr) &&
2951a91e8994SJoe Perches				    $fix) {
2952a91e8994SJoe Perches					$fixed[$fixlinenr] =~ s@(^\+\t+) +@$1 . "\t" x ($indent/8)@e;
2953a91e8994SJoe Perches				}
2954a91e8994SJoe Perches			}
2955a91e8994SJoe Perches		}
2956a91e8994SJoe Perches
2957d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line
2958d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
295991cb5195SJoe Perches		    $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|$Ident\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
2960d1fe9c09SJoe Perches			$prevline =~ /^\+(\t*)(.*)$/;
2961d1fe9c09SJoe Perches			my $oldindent = $1;
2962d1fe9c09SJoe Perches			my $rest = $2;
2963d1fe9c09SJoe Perches
2964d1fe9c09SJoe Perches			my $pos = pos_last_openparen($rest);
2965d1fe9c09SJoe Perches			if ($pos >= 0) {
2966b34a26f3SJoe Perches				$line =~ /^(\+| )([ \t]*)/;
2967b34a26f3SJoe Perches				my $newindent = $2;
2968d1fe9c09SJoe Perches
2969d1fe9c09SJoe Perches				my $goodtabindent = $oldindent .
2970d1fe9c09SJoe Perches					"\t" x ($pos / 8) .
2971d1fe9c09SJoe Perches					" "  x ($pos % 8);
2972d1fe9c09SJoe Perches				my $goodspaceindent = $oldindent . " "  x $pos;
2973d1fe9c09SJoe Perches
2974d1fe9c09SJoe Perches				if ($newindent ne $goodtabindent &&
2975d1fe9c09SJoe Perches				    $newindent ne $goodspaceindent) {
29763705ce5bSJoe Perches
29773705ce5bSJoe Perches					if (CHK("PARENTHESIS_ALIGNMENT",
29783705ce5bSJoe Perches						"Alignment should match open parenthesis\n" . $hereprev) &&
29793705ce5bSJoe Perches					    $fix && $line =~ /^\+/) {
2980194f66fcSJoe Perches						$fixed[$fixlinenr] =~
29813705ce5bSJoe Perches						    s/^\+[ \t]*/\+$goodtabindent/;
29823705ce5bSJoe Perches					}
2983d1fe9c09SJoe Perches				}
2984d1fe9c09SJoe Perches			}
2985d1fe9c09SJoe Perches		}
2986d1fe9c09SJoe Perches
29876ab3a970SJoe Perches# check for space after cast like "(int) foo" or "(struct foo) bar"
29886ab3a970SJoe Perches# avoid checking a few false positives:
29896ab3a970SJoe Perches#   "sizeof(<type>)" or "__alignof__(<type>)"
29906ab3a970SJoe Perches#   function pointer declarations like "(*foo)(int) = bar;"
29916ab3a970SJoe Perches#   structure definitions like "(struct foo) { 0 };"
29926ab3a970SJoe Perches#   multiline macros that define functions
29936ab3a970SJoe Perches#   known attributes or the __attribute__ keyword
29946ab3a970SJoe Perches		if ($line =~ /^\+(.*)\(\s*$Type\s*\)([ \t]++)((?![={]|\\$|$Attribute|__attribute__))/ &&
29956ab3a970SJoe Perches		    (!defined($1) || $1 !~ /\b(?:sizeof|__alignof__)\s*$/)) {
29963705ce5bSJoe Perches			if (CHK("SPACING",
2997f27c95dbSJoe Perches				"No space is necessary after a cast\n" . $herecurr) &&
29983705ce5bSJoe Perches			    $fix) {
2999194f66fcSJoe Perches				$fixed[$fixlinenr] =~
3000f27c95dbSJoe Perches				    s/(\(\s*$Type\s*\))[ \t]+/$1/;
30013705ce5bSJoe Perches			}
3002aad4f614SJoe Perches		}
3003aad4f614SJoe Perches
300486406b1cSJoe Perches# Block comment styles
300586406b1cSJoe Perches# Networking with an initial /*
300605880600SJoe Perches		if ($realfile =~ m@^(drivers/net/|net/)@ &&
3007fdb4bcd6SJoe Perches		    $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
300885ad978cSJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&
300985ad978cSJoe Perches		    $realline > 2) {
301005880600SJoe Perches			WARN("NETWORKING_BLOCK_COMMENT_STYLE",
301105880600SJoe Perches			     "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
301205880600SJoe Perches		}
301305880600SJoe Perches
301486406b1cSJoe Perches# Block comments use * on subsequent lines
301586406b1cSJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
301686406b1cSJoe Perches		    $prevrawline =~ /^\+.*?\/\*/ &&		#starting /*
3017a605e32eSJoe Perches		    $prevrawline !~ /\*\/[ \t]*$/ &&		#no trailing */
301861135e96SJoe Perches		    $rawline =~ /^\+/ &&			#line is new
3019a605e32eSJoe Perches		    $rawline !~ /^\+[ \t]*\*/) {		#no leading *
302086406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
302186406b1cSJoe Perches			     "Block comments use * on subsequent lines\n" . $hereprev);
3022a605e32eSJoe Perches		}
3023a605e32eSJoe Perches
302486406b1cSJoe Perches# Block comments use */ on trailing lines
302586406b1cSJoe Perches		if ($rawline !~ m@^\+[ \t]*\*/[ \t]*$@ &&	#trailing */
3026c24f9f19SJoe Perches		    $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ &&	#inline /*...*/
3027c24f9f19SJoe Perches		    $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ &&	#trailing **/
3028c24f9f19SJoe Perches		    $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) {	#non blank */
302986406b1cSJoe Perches			WARN("BLOCK_COMMENT_STYLE",
303086406b1cSJoe Perches			     "Block comments use a trailing */ on a separate line\n" . $herecurr);
303105880600SJoe Perches		}
303205880600SJoe Perches
303308eb9b80SJoe Perches# Block comment * alignment
303408eb9b80SJoe Perches		if ($prevline =~ /$;[ \t]*$/ &&			#ends in comment
3035af207524SJoe Perches		    $line =~ /^\+[ \t]*$;/ &&			#leading comment
3036af207524SJoe Perches		    $rawline =~ /^\+[ \t]*\*/ &&		#leading *
3037af207524SJoe Perches		    (($prevrawline =~ /^\+.*?\/\*/ &&		#leading /*
303808eb9b80SJoe Perches		      $prevrawline !~ /\*\/[ \t]*$/) ||		#no trailing */
3039af207524SJoe Perches		     $prevrawline =~ /^\+[ \t]*\*/)) {		#leading *
3040af207524SJoe Perches			my $oldindent;
304108eb9b80SJoe Perches			$prevrawline =~ m@^\+([ \t]*/?)\*@;
3042af207524SJoe Perches			if (defined($1)) {
3043af207524SJoe Perches				$oldindent = expand_tabs($1);
3044af207524SJoe Perches			} else {
3045af207524SJoe Perches				$prevrawline =~ m@^\+(.*/?)\*@;
3046af207524SJoe Perches				$oldindent = expand_tabs($1);
3047af207524SJoe Perches			}
304808eb9b80SJoe Perches			$rawline =~ m@^\+([ \t]*)\*@;
304908eb9b80SJoe Perches			my $newindent = $1;
305008eb9b80SJoe Perches			$newindent = expand_tabs($newindent);
3051af207524SJoe Perches			if (length($oldindent) ne length($newindent)) {
305208eb9b80SJoe Perches				WARN("BLOCK_COMMENT_STYLE",
305308eb9b80SJoe Perches				     "Block comments should align the * on each line\n" . $hereprev);
305408eb9b80SJoe Perches			}
305508eb9b80SJoe Perches		}
305608eb9b80SJoe Perches
30577f619191SJoe Perches# check for missing blank lines after struct/union declarations
30587f619191SJoe Perches# with exceptions for various attributes and macros
30597f619191SJoe Perches		if ($prevline =~ /^[\+ ]};?\s*$/ &&
30607f619191SJoe Perches		    $line =~ /^\+/ &&
30617f619191SJoe Perches		    !($line =~ /^\+\s*$/ ||
30627f619191SJoe Perches		      $line =~ /^\+\s*EXPORT_SYMBOL/ ||
30637f619191SJoe Perches		      $line =~ /^\+\s*MODULE_/i ||
30647f619191SJoe Perches		      $line =~ /^\+\s*\#\s*(?:end|elif|else)/ ||
30657f619191SJoe Perches		      $line =~ /^\+[a-z_]*init/ ||
30667f619191SJoe Perches		      $line =~ /^\+\s*(?:static\s+)?[A-Z_]*ATTR/ ||
30677f619191SJoe Perches		      $line =~ /^\+\s*DECLARE/ ||
30687f619191SJoe Perches		      $line =~ /^\+\s*__setup/)) {
3069d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
3070d752fcc8SJoe Perches				"Please use a blank line after function/struct/union/enum declarations\n" . $hereprev) &&
3071d752fcc8SJoe Perches			    $fix) {
3072f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, "\+");
3073d752fcc8SJoe Perches			}
30747f619191SJoe Perches		}
30757f619191SJoe Perches
3076365dd4eaSJoe Perches# check for multiple consecutive blank lines
3077365dd4eaSJoe Perches		if ($prevline =~ /^[\+ ]\s*$/ &&
3078365dd4eaSJoe Perches		    $line =~ /^\+\s*$/ &&
3079365dd4eaSJoe Perches		    $last_blank_line != ($linenr - 1)) {
3080d752fcc8SJoe Perches			if (CHK("LINE_SPACING",
3081d752fcc8SJoe Perches				"Please don't use multiple blank lines\n" . $hereprev) &&
3082d752fcc8SJoe Perches			    $fix) {
3083f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
3084d752fcc8SJoe Perches			}
3085d752fcc8SJoe Perches
3086365dd4eaSJoe Perches			$last_blank_line = $linenr;
3087365dd4eaSJoe Perches		}
3088365dd4eaSJoe Perches
30893b617e3bSJoe Perches# check for missing blank lines after declarations
30903f7bac03SJoe Perches		if ($sline =~ /^\+\s+\S/ &&			#Not at char 1
30913f7bac03SJoe Perches			# actual declarations
30923f7bac03SJoe Perches		    ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
30935a4e1fd3SJoe Perches			# function pointer declarations
30945a4e1fd3SJoe Perches		     $prevline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
30953f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
30963f7bac03SJoe Perches		     $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
30973f7bac03SJoe Perches			# known declaration macros
30983f7bac03SJoe Perches		     $prevline =~ /^\+\s+$declaration_macros/) &&
30993f7bac03SJoe Perches			# for "else if" which can look like "$Ident $Ident"
31003f7bac03SJoe Perches		    !($prevline =~ /^\+\s+$c90_Keywords\b/ ||
31013f7bac03SJoe Perches			# other possible extensions of declaration lines
31023f7bac03SJoe Perches		      $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
31033f7bac03SJoe Perches			# not starting a section or a macro "\" extended line
31043f7bac03SJoe Perches		      $prevline =~ /(?:\{\s*|\\)$/) &&
31053f7bac03SJoe Perches			# looks like a declaration
31063f7bac03SJoe Perches		    !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
31075a4e1fd3SJoe Perches			# function pointer declarations
31085a4e1fd3SJoe Perches		      $sline =~ /^\+\s+$Declare\s*\(\s*\*\s*$Ident\s*\)\s*[=,;:\[\(]/ ||
31093f7bac03SJoe Perches			# foo bar; where foo is some local typedef or #define
31103f7bac03SJoe Perches		      $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
31113f7bac03SJoe Perches			# known declaration macros
31123f7bac03SJoe Perches		      $sline =~ /^\+\s+$declaration_macros/ ||
31133f7bac03SJoe Perches			# start of struct or union or enum
31143b617e3bSJoe Perches		      $sline =~ /^\+\s+(?:union|struct|enum|typedef)\b/ ||
31153f7bac03SJoe Perches			# start or end of block or continuation of declaration
31163f7bac03SJoe Perches		      $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
31173f7bac03SJoe Perches			# bitfield continuation
31183f7bac03SJoe Perches		      $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
31193f7bac03SJoe Perches			# other possible extensions of declaration lines
31203f7bac03SJoe Perches		      $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) &&
31213f7bac03SJoe Perches			# indentation of previous and current line are the same
31223f7bac03SJoe Perches		    (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) {
3123d752fcc8SJoe Perches			if (WARN("LINE_SPACING",
3124d752fcc8SJoe Perches				 "Missing a blank line after declarations\n" . $hereprev) &&
3125d752fcc8SJoe Perches			    $fix) {
3126f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, "\+");
3127d752fcc8SJoe Perches			}
31283b617e3bSJoe Perches		}
31293b617e3bSJoe Perches
31305f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line.
31316b4c5bebSAndy Whitcroft# Exceptions:
31326b4c5bebSAndy Whitcroft#  1) within comments
31336b4c5bebSAndy Whitcroft#  2) indented preprocessor commands
31346b4c5bebSAndy Whitcroft#  3) hanging labels
31353705ce5bSJoe Perches		if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/)  {
31365f7ddae6SRaffaele Recalcati			my $herevet = "$here\n" . cat_vet($rawline) . "\n";
31373705ce5bSJoe Perches			if (WARN("LEADING_SPACE",
31383705ce5bSJoe Perches				 "please, no spaces at the start of a line\n" . $herevet) &&
31393705ce5bSJoe Perches			    $fix) {
3140194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
31413705ce5bSJoe Perches			}
31425f7ddae6SRaffaele Recalcati		}
31435f7ddae6SRaffaele Recalcati
3144b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk
3145b9ea10d6SAndy Whitcroft		next if ($realfile !~ /\.(h|c)$/);
3146b9ea10d6SAndy Whitcroft
31474dbed76fSJoe Perches# check if this appears to be the start function declaration, save the name
31484dbed76fSJoe Perches		if ($sline =~ /^\+\{\s*$/ &&
31494dbed76fSJoe Perches		    $prevline =~ /^\+(?:(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*)?($Ident)\(/) {
31504dbed76fSJoe Perches			$context_function = $1;
31514dbed76fSJoe Perches		}
31524dbed76fSJoe Perches
31534dbed76fSJoe Perches# check if this appears to be the end of function declaration
31544dbed76fSJoe Perches		if ($sline =~ /^\+\}\s*$/) {
31554dbed76fSJoe Perches			undef $context_function;
31564dbed76fSJoe Perches		}
31574dbed76fSJoe Perches
3158032a4c0fSJoe Perches# check indentation of any line with a bare else
3159840080a0SJoe Perches# (but not if it is a multiple line "if (foo) return bar; else return baz;")
3160032a4c0fSJoe Perches# if the previous line is a break or return and is indented 1 tab more...
3161032a4c0fSJoe Perches		if ($sline =~ /^\+([\t]+)(?:}[ \t]*)?else(?:[ \t]*{)?\s*$/) {
3162032a4c0fSJoe Perches			my $tabs = length($1) + 1;
3163840080a0SJoe Perches			if ($prevline =~ /^\+\t{$tabs,$tabs}break\b/ ||
3164840080a0SJoe Perches			    ($prevline =~ /^\+\t{$tabs,$tabs}return\b/ &&
3165840080a0SJoe Perches			     defined $lines[$linenr] &&
3166840080a0SJoe Perches			     $lines[$linenr] !~ /^[ \+]\t{$tabs,$tabs}return/)) {
3167032a4c0fSJoe Perches				WARN("UNNECESSARY_ELSE",
3168032a4c0fSJoe Perches				     "else is not generally useful after a break or return\n" . $hereprev);
3169032a4c0fSJoe Perches			}
3170032a4c0fSJoe Perches		}
3171032a4c0fSJoe Perches
3172c00df19aSJoe Perches# check indentation of a line with a break;
3173c00df19aSJoe Perches# if the previous line is a goto or return and is indented the same # of tabs
3174c00df19aSJoe Perches		if ($sline =~ /^\+([\t]+)break\s*;\s*$/) {
3175c00df19aSJoe Perches			my $tabs = $1;
3176c00df19aSJoe Perches			if ($prevline =~ /^\+$tabs(?:goto|return)\b/) {
3177c00df19aSJoe Perches				WARN("UNNECESSARY_BREAK",
3178c00df19aSJoe Perches				     "break is not useful after a goto or return\n" . $hereprev);
3179c00df19aSJoe Perches			}
3180c00df19aSJoe Perches		}
3181c00df19aSJoe Perches
3182c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers
3183cf655043SAndy Whitcroft		if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
3184000d1cc1SJoe Perches			WARN("CVS_KEYWORD",
3185000d1cc1SJoe Perches			     "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
3186c2fdda0dSAndy Whitcroft		}
318722f2a2efSAndy Whitcroft
318842e41c54SMike Frysinger# Blackfin: don't use __builtin_bfin_[cs]sync
318942e41c54SMike Frysinger		if ($line =~ /__builtin_bfin_csync/) {
319042e41c54SMike Frysinger			my $herevet = "$here\n" . cat_vet($line) . "\n";
3191000d1cc1SJoe Perches			ERROR("CSYNC",
3192000d1cc1SJoe Perches			      "use the CSYNC() macro in asm/blackfin.h\n" . $herevet);
319342e41c54SMike Frysinger		}
319442e41c54SMike Frysinger		if ($line =~ /__builtin_bfin_ssync/) {
319542e41c54SMike Frysinger			my $herevet = "$here\n" . cat_vet($line) . "\n";
3196000d1cc1SJoe Perches			ERROR("SSYNC",
3197000d1cc1SJoe Perches			      "use the SSYNC() macro in asm/blackfin.h\n" . $herevet);
319842e41c54SMike Frysinger		}
319942e41c54SMike Frysinger
320056e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings
320156e77d70SJoe Perches		if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) {
320256e77d70SJoe Perches			WARN("HOTPLUG_SECTION",
320356e77d70SJoe Perches			     "Using $1 is unnecessary\n" . $herecurr);
320456e77d70SJoe Perches		}
320556e77d70SJoe Perches
32069c0ca6f9SAndy Whitcroft# Check for potential 'bare' types
32072b474a1aSAndy Whitcroft		my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
32082b474a1aSAndy Whitcroft		    $realline_next);
32093e469cdcSAndy Whitcroft#print "LINE<$line>\n";
32103e469cdcSAndy Whitcroft		if ($linenr >= $suppress_statement &&
32111b5539b1SJoe Perches		    $realcnt && $sline =~ /.\s*\S/) {
3212170d3a22SAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
3213f5fe35ddSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
3214171ae1a4SAndy Whitcroft			$stat =~ s/\n./\n /g;
3215171ae1a4SAndy Whitcroft			$cond =~ s/\n./\n /g;
3216171ae1a4SAndy Whitcroft
32173e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n";
32183e469cdcSAndy Whitcroft			# If this statement has no statement boundaries within
32193e469cdcSAndy Whitcroft			# it there is no point in retrying a statement scan
32203e469cdcSAndy Whitcroft			# until we hit end of it.
32213e469cdcSAndy Whitcroft			my $frag = $stat; $frag =~ s/;+\s*$//;
32223e469cdcSAndy Whitcroft			if ($frag !~ /(?:{|;)/) {
32233e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n";
32243e469cdcSAndy Whitcroft				$suppress_statement = $line_nr_next;
32253e469cdcSAndy Whitcroft			}
3226f74bd194SAndy Whitcroft
32272b474a1aSAndy Whitcroft			# Find the real next line.
32282b474a1aSAndy Whitcroft			$realline_next = $line_nr_next;
32292b474a1aSAndy Whitcroft			if (defined $realline_next &&
32302b474a1aSAndy Whitcroft			    (!defined $lines[$realline_next - 1] ||
32312b474a1aSAndy Whitcroft			     substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
32322b474a1aSAndy Whitcroft				$realline_next++;
32332b474a1aSAndy Whitcroft			}
32342b474a1aSAndy Whitcroft
3235171ae1a4SAndy Whitcroft			my $s = $stat;
3236171ae1a4SAndy Whitcroft			$s =~ s/{.*$//s;
3237cf655043SAndy Whitcroft
3238c2fdda0dSAndy Whitcroft			# Ignore goto labels.
3239171ae1a4SAndy Whitcroft			if ($s =~ /$Ident:\*$/s) {
3240c2fdda0dSAndy Whitcroft
3241c2fdda0dSAndy Whitcroft			# Ignore functions being called
3242171ae1a4SAndy Whitcroft			} elsif ($s =~ /^.\s*$Ident\s*\(/s) {
3243c2fdda0dSAndy Whitcroft
3244463f2864SAndy Whitcroft			} elsif ($s =~ /^.\s*else\b/s) {
3245463f2864SAndy Whitcroft
3246c45dcabdSAndy Whitcroft			# declarations always start with types
3247d2506586SAndy 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) {
3248c45dcabdSAndy Whitcroft				my $type = $1;
3249c45dcabdSAndy Whitcroft				$type =~ s/\s+/ /g;
3250c45dcabdSAndy Whitcroft				possible($type, "A:" . $s);
3251c45dcabdSAndy Whitcroft
32526c72ffaaSAndy Whitcroft			# definitions in global scope can only start with types
3253a6a84062SAndy Whitcroft			} elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
3254c45dcabdSAndy Whitcroft				possible($1, "B:" . $s);
3255c2fdda0dSAndy Whitcroft			}
32568905a67cSAndy Whitcroft
32576c72ffaaSAndy Whitcroft			# any (foo ... *) is a pointer cast, and foo is a type
325865863862SAndy Whitcroft			while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
3259c45dcabdSAndy Whitcroft				possible($1, "C:" . $s);
32609c0ca6f9SAndy Whitcroft			}
32618905a67cSAndy Whitcroft
32628905a67cSAndy Whitcroft			# Check for any sort of function declaration.
32638905a67cSAndy Whitcroft			# int foo(something bar, other baz);
32648905a67cSAndy Whitcroft			# void (*store_gdt)(x86_descr_ptr *);
3265171ae1a4SAndy Whitcroft			if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
32668905a67cSAndy Whitcroft				my ($name_len) = length($1);
32678905a67cSAndy Whitcroft
3268cf655043SAndy Whitcroft				my $ctx = $s;
3269773647a0SAndy Whitcroft				substr($ctx, 0, $name_len + 1, '');
32708905a67cSAndy Whitcroft				$ctx =~ s/\)[^\)]*$//;
3271cf655043SAndy Whitcroft
32728905a67cSAndy Whitcroft				for my $arg (split(/\s*,\s*/, $ctx)) {
3273c45dcabdSAndy Whitcroft					if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
32748905a67cSAndy Whitcroft
3275c45dcabdSAndy Whitcroft						possible($1, "D:" . $s);
32768905a67cSAndy Whitcroft					}
32778905a67cSAndy Whitcroft				}
32788905a67cSAndy Whitcroft			}
32798905a67cSAndy Whitcroft
32809c0ca6f9SAndy Whitcroft		}
32819c0ca6f9SAndy Whitcroft
328200df344fSAndy Whitcroft#
328300df344fSAndy Whitcroft# Checks which may be anchored in the context.
328400df344fSAndy Whitcroft#
328500df344fSAndy Whitcroft
328600df344fSAndy Whitcroft# Check for switch () and associated case and default
328700df344fSAndy Whitcroft# statements should be at the same indent.
328800df344fSAndy Whitcroft		if ($line=~/\bswitch\s*\(.*\)/) {
328900df344fSAndy Whitcroft			my $err = '';
329000df344fSAndy Whitcroft			my $sep = '';
329100df344fSAndy Whitcroft			my @ctx = ctx_block_outer($linenr, $realcnt);
329200df344fSAndy Whitcroft			shift(@ctx);
329300df344fSAndy Whitcroft			for my $ctx (@ctx) {
329400df344fSAndy Whitcroft				my ($clen, $cindent) = line_stats($ctx);
329500df344fSAndy Whitcroft				if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
329600df344fSAndy Whitcroft							$indent != $cindent) {
329700df344fSAndy Whitcroft					$err .= "$sep$ctx\n";
329800df344fSAndy Whitcroft					$sep = '';
329900df344fSAndy Whitcroft				} else {
330000df344fSAndy Whitcroft					$sep = "[...]\n";
330100df344fSAndy Whitcroft				}
330200df344fSAndy Whitcroft			}
330300df344fSAndy Whitcroft			if ($err ne '') {
3304000d1cc1SJoe Perches				ERROR("SWITCH_CASE_INDENT_LEVEL",
3305000d1cc1SJoe Perches				      "switch and case should be at the same indent\n$hereline$err");
3306de7d4f0eSAndy Whitcroft			}
3307de7d4f0eSAndy Whitcroft		}
3308de7d4f0eSAndy Whitcroft
3309de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop,
3310de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else
33110fe3dc2bSJoe Perches		if ($line =~ /(.*)\b((?:if|while|for|switch|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
3312773647a0SAndy Whitcroft			my $pre_ctx = "$1$2";
3313773647a0SAndy Whitcroft
33149c0ca6f9SAndy Whitcroft			my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
33158eef05ddSJoe Perches
33168eef05ddSJoe Perches			if ($line =~ /^\+\t{6,}/) {
33178eef05ddSJoe Perches				WARN("DEEP_INDENTATION",
33188eef05ddSJoe Perches				     "Too many leading tabs - consider code refactoring\n" . $herecurr);
33198eef05ddSJoe Perches			}
33208eef05ddSJoe Perches
3321de7d4f0eSAndy Whitcroft			my $ctx_cnt = $realcnt - $#ctx - 1;
3322de7d4f0eSAndy Whitcroft			my $ctx = join("\n", @ctx);
3323de7d4f0eSAndy Whitcroft
3324548596d5SAndy Whitcroft			my $ctx_ln = $linenr;
3325548596d5SAndy Whitcroft			my $ctx_skip = $realcnt;
3326de7d4f0eSAndy Whitcroft
3327548596d5SAndy Whitcroft			while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
3328548596d5SAndy Whitcroft					defined $lines[$ctx_ln - 1] &&
3329548596d5SAndy Whitcroft					$lines[$ctx_ln - 1] =~ /^-/)) {
3330548596d5SAndy Whitcroft				##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
3331548596d5SAndy Whitcroft				$ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
3332773647a0SAndy Whitcroft				$ctx_ln++;
3333773647a0SAndy Whitcroft			}
3334548596d5SAndy Whitcroft
333553210168SAndy Whitcroft			#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
333653210168SAndy Whitcroft			#print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
3337773647a0SAndy Whitcroft
3338773647a0SAndy Whitcroft			if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
3339000d1cc1SJoe Perches				ERROR("OPEN_BRACE",
3340000d1cc1SJoe Perches				      "that open brace { should be on the previous line\n" .
334101464f30SAndy Whitcroft					"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
334200df344fSAndy Whitcroft			}
3343773647a0SAndy Whitcroft			if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
3344773647a0SAndy Whitcroft			    $ctx =~ /\)\s*\;\s*$/ &&
3345773647a0SAndy Whitcroft			    defined $lines[$ctx_ln - 1])
3346773647a0SAndy Whitcroft			{
33479c0ca6f9SAndy Whitcroft				my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
33489c0ca6f9SAndy Whitcroft				if ($nindent > $indent) {
3349000d1cc1SJoe Perches					WARN("TRAILING_SEMICOLON",
3350000d1cc1SJoe Perches					     "trailing semicolon indicates no statements, indent implies otherwise\n" .
335101464f30SAndy Whitcroft						"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
33529c0ca6f9SAndy Whitcroft				}
33539c0ca6f9SAndy Whitcroft			}
335400df344fSAndy Whitcroft		}
335500df344fSAndy Whitcroft
33564d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks.
33570fe3dc2bSJoe Perches		if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
33583e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
33593e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
33603e469cdcSAndy Whitcroft					if (!defined $stat);
33614d001e4dSAndy Whitcroft			my ($s, $c) = ($stat, $cond);
33624d001e4dSAndy Whitcroft
33634d001e4dSAndy Whitcroft			substr($s, 0, length($c), '');
33644d001e4dSAndy Whitcroft
33659f5af480SJoe Perches			# remove inline comments
33669f5af480SJoe Perches			$s =~ s/$;/ /g;
33679f5af480SJoe Perches			$c =~ s/$;/ /g;
33684d001e4dSAndy Whitcroft
33694d001e4dSAndy Whitcroft			# Find out how long the conditional actually is.
33706f779c18SAndy Whitcroft			my @newlines = ($c =~ /\n/gs);
33716f779c18SAndy Whitcroft			my $cond_lines = 1 + $#newlines;
33724d001e4dSAndy Whitcroft
33739f5af480SJoe Perches			# Make sure we remove the line prefixes as we have
33749f5af480SJoe Perches			# none on the first line, and are going to readd them
33759f5af480SJoe Perches			# where necessary.
33769f5af480SJoe Perches			$s =~ s/\n./\n/gs;
33779f5af480SJoe Perches			while ($s =~ /\n\s+\\\n/) {
33789f5af480SJoe Perches				$cond_lines += $s =~ s/\n\s+\\\n/\n/g;
33799f5af480SJoe Perches			}
33809f5af480SJoe Perches
33814d001e4dSAndy Whitcroft			# We want to check the first line inside the block
33824d001e4dSAndy Whitcroft			# starting at the end of the conditional, so remove:
33834d001e4dSAndy Whitcroft			#  1) any blank line termination
33844d001e4dSAndy Whitcroft			#  2) any opening brace { on end of the line
33854d001e4dSAndy Whitcroft			#  3) any do (...) {
33864d001e4dSAndy Whitcroft			my $continuation = 0;
33874d001e4dSAndy Whitcroft			my $check = 0;
33884d001e4dSAndy Whitcroft			$s =~ s/^.*\bdo\b//;
33894d001e4dSAndy Whitcroft			$s =~ s/^\s*{//;
33904d001e4dSAndy Whitcroft			if ($s =~ s/^\s*\\//) {
33914d001e4dSAndy Whitcroft				$continuation = 1;
33924d001e4dSAndy Whitcroft			}
33939bd49efeSAndy Whitcroft			if ($s =~ s/^\s*?\n//) {
33944d001e4dSAndy Whitcroft				$check = 1;
33954d001e4dSAndy Whitcroft				$cond_lines++;
33964d001e4dSAndy Whitcroft			}
33974d001e4dSAndy Whitcroft
33984d001e4dSAndy Whitcroft			# Also ignore a loop construct at the end of a
33994d001e4dSAndy Whitcroft			# preprocessor statement.
34004d001e4dSAndy Whitcroft			if (($prevline =~ /^.\s*#\s*define\s/ ||
34014d001e4dSAndy Whitcroft			    $prevline =~ /\\\s*$/) && $continuation == 0) {
34024d001e4dSAndy Whitcroft				$check = 0;
34034d001e4dSAndy Whitcroft			}
34044d001e4dSAndy Whitcroft
34059bd49efeSAndy Whitcroft			my $cond_ptr = -1;
3406740504c6SAndy Whitcroft			$continuation = 0;
34079bd49efeSAndy Whitcroft			while ($cond_ptr != $cond_lines) {
34089bd49efeSAndy Whitcroft				$cond_ptr = $cond_lines;
34094d001e4dSAndy Whitcroft
3410f16fa28fSAndy Whitcroft				# If we see an #else/#elif then the code
3411f16fa28fSAndy Whitcroft				# is not linear.
3412f16fa28fSAndy Whitcroft				if ($s =~ /^\s*\#\s*(?:else|elif)/) {
3413f16fa28fSAndy Whitcroft					$check = 0;
3414f16fa28fSAndy Whitcroft				}
3415f16fa28fSAndy Whitcroft
34169bd49efeSAndy Whitcroft				# Ignore:
34179bd49efeSAndy Whitcroft				#  1) blank lines, they should be at 0,
34189bd49efeSAndy Whitcroft				#  2) preprocessor lines, and
34199bd49efeSAndy Whitcroft				#  3) labels.
3420740504c6SAndy Whitcroft				if ($continuation ||
3421740504c6SAndy Whitcroft				    $s =~ /^\s*?\n/ ||
34229bd49efeSAndy Whitcroft				    $s =~ /^\s*#\s*?/ ||
34239bd49efeSAndy Whitcroft				    $s =~ /^\s*$Ident\s*:/) {
3424740504c6SAndy Whitcroft					$continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
342530dad6ebSAndy Whitcroft					if ($s =~ s/^.*?\n//) {
34269bd49efeSAndy Whitcroft						$cond_lines++;
34279bd49efeSAndy Whitcroft					}
34284d001e4dSAndy Whitcroft				}
342930dad6ebSAndy Whitcroft			}
34304d001e4dSAndy Whitcroft
34314d001e4dSAndy Whitcroft			my (undef, $sindent) = line_stats("+" . $s);
34324d001e4dSAndy Whitcroft			my $stat_real = raw_line($linenr, $cond_lines);
34334d001e4dSAndy Whitcroft
34344d001e4dSAndy Whitcroft			# Check if either of these lines are modified, else
34354d001e4dSAndy Whitcroft			# this is not this patch's fault.
34364d001e4dSAndy Whitcroft			if (!defined($stat_real) ||
34374d001e4dSAndy Whitcroft			    $stat !~ /^\+/ && $stat_real !~ /^\+/) {
34384d001e4dSAndy Whitcroft				$check = 0;
34394d001e4dSAndy Whitcroft			}
34404d001e4dSAndy Whitcroft			if (defined($stat_real) && $cond_lines > 1) {
34414d001e4dSAndy Whitcroft				$stat_real = "[...]\n$stat_real";
34424d001e4dSAndy Whitcroft			}
34434d001e4dSAndy Whitcroft
34449bd49efeSAndy 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";
34454d001e4dSAndy Whitcroft
34469f5af480SJoe Perches			if ($check && $s ne '' &&
34479f5af480SJoe Perches			    (($sindent % 8) != 0 ||
34489f5af480SJoe Perches			     ($sindent < $indent) ||
34499f5af480SJoe Perches			     ($sindent > $indent + 8))) {
3450000d1cc1SJoe Perches				WARN("SUSPECT_CODE_INDENT",
3451000d1cc1SJoe Perches				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
34524d001e4dSAndy Whitcroft			}
34534d001e4dSAndy Whitcroft		}
34544d001e4dSAndy Whitcroft
34556c72ffaaSAndy Whitcroft		# Track the 'values' across context and added lines.
34566c72ffaaSAndy Whitcroft		my $opline = $line; $opline =~ s/^./ /;
34571f65f947SAndy Whitcroft		my ($curr_values, $curr_vars) =
34581f65f947SAndy Whitcroft				annotate_values($opline . "\n", $prev_values);
34596c72ffaaSAndy Whitcroft		$curr_values = $prev_values . $curr_values;
3460c2fdda0dSAndy Whitcroft		if ($dbg_values) {
3461c2fdda0dSAndy Whitcroft			my $outline = $opline; $outline =~ s/\t/ /g;
3462cf655043SAndy Whitcroft			print "$linenr > .$outline\n";
3463cf655043SAndy Whitcroft			print "$linenr > $curr_values\n";
34641f65f947SAndy Whitcroft			print "$linenr >  $curr_vars\n";
3465c2fdda0dSAndy Whitcroft		}
34666c72ffaaSAndy Whitcroft		$prev_values = substr($curr_values, -1);
34676c72ffaaSAndy Whitcroft
346800df344fSAndy Whitcroft#ignore lines not being added
34693705ce5bSJoe Perches		next if ($line =~ /^[^\+]/);
347000df344fSAndy Whitcroft
347111ca40a0SJoe Perches# check for dereferences that span multiple lines
347211ca40a0SJoe Perches		if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
347311ca40a0SJoe Perches		    $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
347411ca40a0SJoe Perches			$prevline =~ /($Lval\s*(?:\.|->))\s*$/;
347511ca40a0SJoe Perches			my $ref = $1;
347611ca40a0SJoe Perches			$line =~ /^.\s*($Lval)/;
347711ca40a0SJoe Perches			$ref .= $1;
347811ca40a0SJoe Perches			$ref =~ s/\s//g;
347911ca40a0SJoe Perches			WARN("MULTILINE_DEREFERENCE",
348011ca40a0SJoe Perches			     "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
348111ca40a0SJoe Perches		}
348211ca40a0SJoe Perches
3483a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int
3484c8447115SJoe Perches		while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
3485a1ce18e4SJoe Perches			my $type = $1;
3486a1ce18e4SJoe Perches			my $var = $2;
3487207a8e84SJoe Perches			$var = "" if (!defined $var);
3488207a8e84SJoe Perches			if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
3489a1ce18e4SJoe Perches				my $sign = $1;
3490a1ce18e4SJoe Perches				my $pointer = $2;
3491a1ce18e4SJoe Perches
3492a1ce18e4SJoe Perches				$pointer = "" if (!defined $pointer);
3493a1ce18e4SJoe Perches
3494a1ce18e4SJoe Perches				if (WARN("UNSPECIFIED_INT",
3495a1ce18e4SJoe Perches					 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
3496a1ce18e4SJoe Perches				    $fix) {
3497a1ce18e4SJoe Perches					my $decl = trim($sign) . " int ";
3498207a8e84SJoe Perches					my $comp_pointer = $pointer;
3499207a8e84SJoe Perches					$comp_pointer =~ s/\s//g;
3500207a8e84SJoe Perches					$decl .= $comp_pointer;
3501207a8e84SJoe Perches					$decl = rtrim($decl) if ($var eq "");
3502207a8e84SJoe Perches					$fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
3503a1ce18e4SJoe Perches				}
3504a1ce18e4SJoe Perches			}
3505a1ce18e4SJoe Perches		}
3506a1ce18e4SJoe Perches
3507653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher.
35087429c690SAndy Whitcroft		if ($dbg_type) {
35097429c690SAndy Whitcroft			if ($line =~ /^.\s*$Declare\s*$/) {
3510000d1cc1SJoe Perches				ERROR("TEST_TYPE",
3511000d1cc1SJoe Perches				      "TEST: is type\n" . $herecurr);
35127429c690SAndy Whitcroft			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
3513000d1cc1SJoe Perches				ERROR("TEST_NOT_TYPE",
3514000d1cc1SJoe Perches				      "TEST: is not type ($1 is)\n". $herecurr);
35157429c690SAndy Whitcroft			}
3516653d4876SAndy Whitcroft			next;
3517653d4876SAndy Whitcroft		}
3518a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher.
3519a1ef277eSAndy Whitcroft		if ($dbg_attr) {
35209360b0e5SAndy Whitcroft			if ($line =~ /^.\s*$Modifier\s*$/) {
3521000d1cc1SJoe Perches				ERROR("TEST_ATTR",
3522000d1cc1SJoe Perches				      "TEST: is attr\n" . $herecurr);
35239360b0e5SAndy Whitcroft			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
3524000d1cc1SJoe Perches				ERROR("TEST_NOT_ATTR",
3525000d1cc1SJoe Perches				      "TEST: is not attr ($1 is)\n". $herecurr);
3526a1ef277eSAndy Whitcroft			}
3527a1ef277eSAndy Whitcroft			next;
3528a1ef277eSAndy Whitcroft		}
3529653d4876SAndy Whitcroft
3530f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line
353199423c20SAndy Whitcroft		if ($line =~ /^.\s*{/ &&
353299423c20SAndy Whitcroft		    $prevline =~ /(?:^|[^=])=\s*$/) {
3533d752fcc8SJoe Perches			if (ERROR("OPEN_BRACE",
3534d752fcc8SJoe Perches				  "that open brace { should be on the previous line\n" . $hereprev) &&
3535f2d7e4d4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
3536f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
3537f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
3538d752fcc8SJoe Perches				my $fixedline = $prevrawline;
3539d752fcc8SJoe Perches				$fixedline =~ s/\s*=\s*$/ = {/;
3540f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
3541d752fcc8SJoe Perches				$fixedline = $line;
3542d752fcc8SJoe Perches				$fixedline =~ s/^(.\s*){\s*/$1/;
3543f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
3544d752fcc8SJoe Perches			}
3545f0a594c1SAndy Whitcroft		}
3546f0a594c1SAndy Whitcroft
354700df344fSAndy Whitcroft#
354800df344fSAndy Whitcroft# Checks which are anchored on the added line.
354900df344fSAndy Whitcroft#
355000df344fSAndy Whitcroft
3551653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line)
3552c45dcabdSAndy Whitcroft		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
3553653d4876SAndy Whitcroft			my $path = $1;
3554653d4876SAndy Whitcroft			if ($path =~ m{//}) {
3555000d1cc1SJoe Perches				ERROR("MALFORMED_INCLUDE",
3556495e9d84SJoe Perches				      "malformed #include filename\n" . $herecurr);
3557495e9d84SJoe Perches			}
3558495e9d84SJoe Perches			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
3559495e9d84SJoe Perches				ERROR("UAPI_INCLUDE",
3560495e9d84SJoe Perches				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
3561653d4876SAndy Whitcroft			}
3562653d4876SAndy Whitcroft		}
3563653d4876SAndy Whitcroft
356400df344fSAndy Whitcroft# no C99 // comments
356500df344fSAndy Whitcroft		if ($line =~ m{//}) {
35663705ce5bSJoe Perches			if (ERROR("C99_COMMENTS",
35673705ce5bSJoe Perches				  "do not use C99 // comments\n" . $herecurr) &&
35683705ce5bSJoe Perches			    $fix) {
3569194f66fcSJoe Perches				my $line = $fixed[$fixlinenr];
35703705ce5bSJoe Perches				if ($line =~ /\/\/(.*)$/) {
35713705ce5bSJoe Perches					my $comment = trim($1);
3572194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
35733705ce5bSJoe Perches				}
35743705ce5bSJoe Perches			}
357500df344fSAndy Whitcroft		}
357600df344fSAndy Whitcroft		# Remove C99 comments.
35770a920b5bSAndy Whitcroft		$line =~ s@//.*@@;
35786c72ffaaSAndy Whitcroft		$opline =~ s@//.*@@;
35790a920b5bSAndy Whitcroft
35802b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
35812b474a1aSAndy Whitcroft# the whole statement.
35822b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n";
35832b474a1aSAndy Whitcroft		if (defined $realline_next &&
35842b474a1aSAndy Whitcroft		    exists $lines[$realline_next - 1] &&
35852b474a1aSAndy Whitcroft		    !defined $suppress_export{$realline_next} &&
35862b474a1aSAndy Whitcroft		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
35872b474a1aSAndy Whitcroft		     $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
35883cbf62dfSAndy Whitcroft			# Handle definitions which produce identifiers with
35893cbf62dfSAndy Whitcroft			# a prefix:
35903cbf62dfSAndy Whitcroft			#   XXX(foo);
35913cbf62dfSAndy Whitcroft			#   EXPORT_SYMBOL(something_foo);
3592653d4876SAndy Whitcroft			my $name = $1;
359387a53877SAndy Whitcroft			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
35943cbf62dfSAndy Whitcroft			    $name =~ /^${Ident}_$2/) {
35953cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n";
35963cbf62dfSAndy Whitcroft				$suppress_export{$realline_next} = 1;
35973cbf62dfSAndy Whitcroft
35983cbf62dfSAndy Whitcroft			} elsif ($stat !~ /(?:
35992b474a1aSAndy Whitcroft				\n.}\s*$|
360048012058SAndy Whitcroft				^.DEFINE_$Ident\(\Q$name\E\)|
360148012058SAndy Whitcroft				^.DECLARE_$Ident\(\Q$name\E\)|
360248012058SAndy Whitcroft				^.LIST_HEAD\(\Q$name\E\)|
36032b474a1aSAndy Whitcroft				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
36042b474a1aSAndy Whitcroft				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
360548012058SAndy Whitcroft			    )/x) {
36062b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
36072b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 2;
36082b474a1aSAndy Whitcroft			} else {
36092b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 1;
36100a920b5bSAndy Whitcroft			}
36110a920b5bSAndy Whitcroft		}
36122b474a1aSAndy Whitcroft		if (!defined $suppress_export{$linenr} &&
36132b474a1aSAndy Whitcroft		    $prevline =~ /^.\s*$/ &&
36142b474a1aSAndy Whitcroft		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
36152b474a1aSAndy Whitcroft		     $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
36162b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n";
36172b474a1aSAndy Whitcroft			$suppress_export{$linenr} = 2;
36182b474a1aSAndy Whitcroft		}
36192b474a1aSAndy Whitcroft		if (defined $suppress_export{$linenr} &&
36202b474a1aSAndy Whitcroft		    $suppress_export{$linenr} == 2) {
3621000d1cc1SJoe Perches			WARN("EXPORT_SYMBOL",
3622000d1cc1SJoe Perches			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
36232b474a1aSAndy Whitcroft		}
36240a920b5bSAndy Whitcroft
36255150bda4SJoe Eloff# check for global initialisers.
36266d32f7a3SJoe Perches		if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) {
3627d5e616fcSJoe Perches			if (ERROR("GLOBAL_INITIALISERS",
36286d32f7a3SJoe Perches				  "do not initialise globals to $1\n" . $herecurr) &&
3629d5e616fcSJoe Perches			    $fix) {
36306d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
3631d5e616fcSJoe Perches			}
3632f0a594c1SAndy Whitcroft		}
36330a920b5bSAndy Whitcroft# check for static initialisers.
36346d32f7a3SJoe Perches		if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
3635d5e616fcSJoe Perches			if (ERROR("INITIALISED_STATIC",
36366d32f7a3SJoe Perches				  "do not initialise statics to $1\n" .
3637d5e616fcSJoe Perches				      $herecurr) &&
3638d5e616fcSJoe Perches			    $fix) {
36396d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
3640d5e616fcSJoe Perches			}
36410a920b5bSAndy Whitcroft		}
36420a920b5bSAndy Whitcroft
36431813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned
36441813087dSJoe Perches		while ($sline =~ m{(\b$TypeMisordered\b)}g) {
36451813087dSJoe Perches			my $tmp = trim($1);
36461813087dSJoe Perches			WARN("MISORDERED_TYPE",
36471813087dSJoe Perches			     "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
36481813087dSJoe Perches		}
36491813087dSJoe Perches
3650cb710ecaSJoe Perches# check for static const char * arrays.
3651cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
3652000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
3653000d1cc1SJoe Perches			     "static const char * array should probably be static const char * const\n" .
3654cb710ecaSJoe Perches				$herecurr);
3655cb710ecaSJoe Perches               }
3656cb710ecaSJoe Perches
3657cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations.
3658cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
3659000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
3660000d1cc1SJoe Perches			     "static char array declaration should probably be static const char\n" .
3661cb710ecaSJoe Perches				$herecurr);
3662cb710ecaSJoe Perches               }
3663cb710ecaSJoe Perches
3664ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type
3665ab7e23f3SJoe Perches		if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
3666ab7e23f3SJoe Perches			my $found = $1;
3667ab7e23f3SJoe Perches			if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
3668ab7e23f3SJoe Perches				WARN("CONST_CONST",
3669ab7e23f3SJoe Perches				     "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
3670ab7e23f3SJoe Perches			} elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
3671ab7e23f3SJoe Perches				WARN("CONST_CONST",
3672ab7e23f3SJoe Perches				     "'const $found const' should probably be 'const $found'\n" . $herecurr);
3673ab7e23f3SJoe Perches			}
3674ab7e23f3SJoe Perches		}
3675ab7e23f3SJoe Perches
36769b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations.
36779b0fa60dSJoe Perches		if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
36789b0fa60dSJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
36799b0fa60dSJoe Perches			     "char * array declaration might be better as static const\n" .
36809b0fa60dSJoe Perches				$herecurr);
36819b0fa60dSJoe Perches               }
36829b0fa60dSJoe Perches
3683b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
3684b598b670SJoe Perches		if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
3685b598b670SJoe Perches			my $array = $1;
3686b598b670SJoe 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*\))@) {
3687b598b670SJoe Perches				my $array_div = $1;
3688b598b670SJoe Perches				if (WARN("ARRAY_SIZE",
3689b598b670SJoe Perches					 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
3690b598b670SJoe Perches				    $fix) {
3691b598b670SJoe Perches					$fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
3692b598b670SJoe Perches				}
3693b598b670SJoe Perches			}
3694b598b670SJoe Perches		}
3695b598b670SJoe Perches
3696b36190c5SJoe Perches# check for function declarations without arguments like "int foo()"
3697b36190c5SJoe Perches		if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) {
3698b36190c5SJoe Perches			if (ERROR("FUNCTION_WITHOUT_ARGS",
3699b36190c5SJoe Perches				  "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
3700b36190c5SJoe Perches			    $fix) {
3701194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
3702b36190c5SJoe Perches			}
3703b36190c5SJoe Perches		}
3704b36190c5SJoe Perches
3705653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations
3706653d4876SAndy Whitcroft# make sense.
3707653d4876SAndy Whitcroft		if ($line =~ /\btypedef\s/ &&
37088054576dSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
3709c45dcabdSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
37108ed22cadSAndy Whitcroft		    $line !~ /\b$typeTypedefs\b/ &&
371146d832f5SMichael S. Tsirkin		    $line !~ /\b__bitwise\b/) {
3712000d1cc1SJoe Perches			WARN("NEW_TYPEDEFS",
3713000d1cc1SJoe Perches			     "do not add new typedefs\n" . $herecurr);
37140a920b5bSAndy Whitcroft		}
37150a920b5bSAndy Whitcroft
37160a920b5bSAndy Whitcroft# * goes on variable not on type
371765863862SAndy Whitcroft		# (char*[ const])
3718bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
3719bfcb2cc7SAndy Whitcroft			#print "AA<$1>\n";
37203705ce5bSJoe Perches			my ($ident, $from, $to) = ($1, $2, $2);
3721d8aaf121SAndy Whitcroft
372265863862SAndy Whitcroft			# Should start with a space.
372365863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
372465863862SAndy Whitcroft			# Should not end with a space.
372565863862SAndy Whitcroft			$to =~ s/\s+$//;
372665863862SAndy Whitcroft			# '*'s should not have spaces between.
3727f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
372865863862SAndy Whitcroft			}
3729d8aaf121SAndy Whitcroft
37303705ce5bSJoe Perches##			print "1: from<$from> to<$to> ident<$ident>\n";
373165863862SAndy Whitcroft			if ($from ne $to) {
37323705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
37333705ce5bSJoe Perches					  "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
37343705ce5bSJoe Perches				    $fix) {
37353705ce5bSJoe Perches					my $sub_from = $ident;
37363705ce5bSJoe Perches					my $sub_to = $ident;
37373705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
3738194f66fcSJoe Perches					$fixed[$fixlinenr] =~
37393705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
37403705ce5bSJoe Perches				}
374165863862SAndy Whitcroft			}
3742bfcb2cc7SAndy Whitcroft		}
3743bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
3744bfcb2cc7SAndy Whitcroft			#print "BB<$1>\n";
37453705ce5bSJoe Perches			my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
3746d8aaf121SAndy Whitcroft
374765863862SAndy Whitcroft			# Should start with a space.
374865863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
374965863862SAndy Whitcroft			# Should not end with a space.
375065863862SAndy Whitcroft			$to =~ s/\s+$//;
375165863862SAndy Whitcroft			# '*'s should not have spaces between.
3752f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
375365863862SAndy Whitcroft			}
375465863862SAndy Whitcroft			# Modifiers should have spaces.
375565863862SAndy Whitcroft			$to =~ s/(\b$Modifier$)/$1 /;
375665863862SAndy Whitcroft
37573705ce5bSJoe Perches##			print "2: from<$from> to<$to> ident<$ident>\n";
3758667026e7SAndy Whitcroft			if ($from ne $to && $ident !~ /^$Modifier$/) {
37593705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
37603705ce5bSJoe Perches					  "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
37613705ce5bSJoe Perches				    $fix) {
37623705ce5bSJoe Perches
37633705ce5bSJoe Perches					my $sub_from = $match;
37643705ce5bSJoe Perches					my $sub_to = $match;
37653705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
3766194f66fcSJoe Perches					$fixed[$fixlinenr] =~
37673705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
37683705ce5bSJoe Perches				}
376965863862SAndy Whitcroft			}
37700a920b5bSAndy Whitcroft		}
37710a920b5bSAndy Whitcroft
37729d3e3c70SJoe Perches# avoid BUG() or BUG_ON()
37739d3e3c70SJoe Perches		if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
37749d3e3c70SJoe Perches			my $msg_type = \&WARN;
37759d3e3c70SJoe Perches			$msg_type = \&CHK if ($file);
37769d3e3c70SJoe Perches			&{$msg_type}("AVOID_BUG",
37779d3e3c70SJoe Perches				     "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
37789d3e3c70SJoe Perches		}
37790a920b5bSAndy Whitcroft
37809d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE
37818905a67cSAndy Whitcroft		if ($line =~ /\bLINUX_VERSION_CODE\b/) {
3782000d1cc1SJoe Perches			WARN("LINUX_VERSION_CODE",
3783000d1cc1SJoe Perches			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
37848905a67cSAndy Whitcroft		}
37858905a67cSAndy Whitcroft
378617441227SJoe Perches# check for uses of printk_ratelimit
378717441227SJoe Perches		if ($line =~ /\bprintk_ratelimit\s*\(/) {
3788000d1cc1SJoe Perches			WARN("PRINTK_RATELIMITED",
3789000d1cc1SJoe Perches			     "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
379017441227SJoe Perches		}
379117441227SJoe Perches
379200df344fSAndy Whitcroft# printk should use KERN_* levels.  Note that follow on printk's on the
379300df344fSAndy Whitcroft# same line do not need a level, so we use the current block context
379400df344fSAndy Whitcroft# to try and find and validate the current printk.  In summary the current
379525985edcSLucas De Marchi# printk includes all preceding printk's which have no newline on the end.
379600df344fSAndy Whitcroft# we assume the first bad printk is the one to report.
3797f0a594c1SAndy Whitcroft		if ($line =~ /\bprintk\((?!KERN_)\s*"/) {
379800df344fSAndy Whitcroft			my $ok = 0;
379900df344fSAndy Whitcroft			for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) {
380000df344fSAndy Whitcroft				#print "CHECK<$lines[$ln - 1]\n";
380125985edcSLucas De Marchi				# we have a preceding printk if it ends
380200df344fSAndy Whitcroft				# with "\n" ignore it, else it is to blame
380300df344fSAndy Whitcroft				if ($lines[$ln - 1] =~ m{\bprintk\(}) {
380400df344fSAndy Whitcroft					if ($rawlines[$ln - 1] !~ m{\\n"}) {
380500df344fSAndy Whitcroft						$ok = 1;
380600df344fSAndy Whitcroft					}
380700df344fSAndy Whitcroft					last;
380800df344fSAndy Whitcroft				}
380900df344fSAndy Whitcroft			}
381000df344fSAndy Whitcroft			if ($ok == 0) {
3811000d1cc1SJoe Perches				WARN("PRINTK_WITHOUT_KERN_LEVEL",
3812000d1cc1SJoe Perches				     "printk() should include KERN_ facility level\n" . $herecurr);
38130a920b5bSAndy Whitcroft			}
381400df344fSAndy Whitcroft		}
38150a920b5bSAndy Whitcroft
3816243f3803SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) {
3817243f3803SJoe Perches			my $orig = $1;
3818243f3803SJoe Perches			my $level = lc($orig);
3819243f3803SJoe Perches			$level = "warn" if ($level eq "warning");
38208f26b837SJoe Perches			my $level2 = $level;
38218f26b837SJoe Perches			$level2 = "dbg" if ($level eq "debug");
3822243f3803SJoe Perches			WARN("PREFER_PR_LEVEL",
3823daa8b059SYogesh Chaudhari			     "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(...  to printk(KERN_$orig ...\n" . $herecurr);
3824243f3803SJoe Perches		}
3825243f3803SJoe Perches
3826243f3803SJoe Perches		if ($line =~ /\bpr_warning\s*\(/) {
3827d5e616fcSJoe Perches			if (WARN("PREFER_PR_LEVEL",
3828d5e616fcSJoe Perches				 "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) &&
3829d5e616fcSJoe Perches			    $fix) {
3830194f66fcSJoe Perches				$fixed[$fixlinenr] =~
3831d5e616fcSJoe Perches				    s/\bpr_warning\b/pr_warn/;
3832d5e616fcSJoe Perches			}
3833243f3803SJoe Perches		}
3834243f3803SJoe Perches
3835dc139313SJoe Perches		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
3836dc139313SJoe Perches			my $orig = $1;
3837dc139313SJoe Perches			my $level = lc($orig);
3838dc139313SJoe Perches			$level = "warn" if ($level eq "warning");
3839dc139313SJoe Perches			$level = "dbg" if ($level eq "debug");
3840dc139313SJoe Perches			WARN("PREFER_DEV_LEVEL",
3841dc139313SJoe Perches			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
3842dc139313SJoe Perches		}
3843dc139313SJoe Perches
384491c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else.  This will have a small
384591c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at
384691c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning.
384791c9afafSAndy Lutomirski		if ($line =~ /\bENOSYS\b/) {
384891c9afafSAndy Lutomirski			WARN("ENOSYS",
384991c9afafSAndy Lutomirski			     "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
385091c9afafSAndy Lutomirski		}
385191c9afafSAndy Lutomirski
3852653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while,
3853653d4876SAndy Whitcroft# or if closed on same line
38548d182478SJoe Perches		if (($line=~/$Type\s*$Ident\(.*\).*\s*{/) and
38554e5d56bdSEddie Kovsky		    !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) {
38568d182478SJoe Perches			if (ERROR("OPEN_BRACE",
38578d182478SJoe Perches				  "open brace '{' following function declarations go on the next line\n" . $herecurr) &&
38588d182478SJoe Perches			    $fix) {
38598d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
38608d182478SJoe Perches				my $fixed_line = $rawline;
38618d182478SJoe Perches				$fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/;
38628d182478SJoe Perches				my $line1 = $1;
38638d182478SJoe Perches				my $line2 = $2;
38648d182478SJoe Perches				fix_insert_line($fixlinenr, ltrim($line1));
38658d182478SJoe Perches				fix_insert_line($fixlinenr, "\+{");
38668d182478SJoe Perches				if ($line2 !~ /^\s*$/) {
38678d182478SJoe Perches					fix_insert_line($fixlinenr, "\+\t" . trim($line2));
38688d182478SJoe Perches				}
38698d182478SJoe Perches			}
38700a920b5bSAndy Whitcroft		}
3871653d4876SAndy Whitcroft
38728905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line.
38738905a67cSAndy Whitcroft		if ($line =~ /^.\s*{/ &&
38748905a67cSAndy Whitcroft		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
38758d182478SJoe Perches			if (ERROR("OPEN_BRACE",
38768d182478SJoe Perches				  "open brace '{' following $1 go on the same line\n" . $hereprev) &&
38778d182478SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
38788d182478SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
38798d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
38808d182478SJoe Perches				my $fixedline = rtrim($prevrawline) . " {";
38818d182478SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
38828d182478SJoe Perches				$fixedline = $rawline;
38838d182478SJoe Perches				$fixedline =~ s/^(.\s*){\s*/$1\t/;
38848d182478SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
38858d182478SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
38868d182478SJoe Perches				}
38878d182478SJoe Perches			}
38888905a67cSAndy Whitcroft		}
38898905a67cSAndy Whitcroft
38900c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition
38913705ce5bSJoe Perches		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
38923705ce5bSJoe Perches			if (WARN("SPACING",
38933705ce5bSJoe Perches				 "missing space after $1 definition\n" . $herecurr) &&
38943705ce5bSJoe Perches			    $fix) {
3895194f66fcSJoe Perches				$fixed[$fixlinenr] =~
38963705ce5bSJoe Perches				    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
38973705ce5bSJoe Perches			}
38980c73b4ebSAndy Whitcroft		}
38990c73b4ebSAndy Whitcroft
390031070b5dSJoe Perches# Function pointer declarations
390131070b5dSJoe Perches# check spacing between type, funcptr, and args
390231070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)"
390391f72e9cSJoe Perches		if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
390431070b5dSJoe Perches			my $declare = $1;
390531070b5dSJoe Perches			my $pre_pointer_space = $2;
390631070b5dSJoe Perches			my $post_pointer_space = $3;
390731070b5dSJoe Perches			my $funcname = $4;
390831070b5dSJoe Perches			my $post_funcname_space = $5;
390931070b5dSJoe Perches			my $pre_args_space = $6;
391031070b5dSJoe Perches
391191f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type
391291f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types
391391f72e9cSJoe Perches# don't need a space so don't warn for those.
391491f72e9cSJoe Perches			my $post_declare_space = "";
391591f72e9cSJoe Perches			if ($declare =~ /(\s+)$/) {
391691f72e9cSJoe Perches				$post_declare_space = $1;
391791f72e9cSJoe Perches				$declare = rtrim($declare);
391891f72e9cSJoe Perches			}
391991f72e9cSJoe Perches			if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
392031070b5dSJoe Perches				WARN("SPACING",
392131070b5dSJoe Perches				     "missing space after return type\n" . $herecurr);
392291f72e9cSJoe Perches				$post_declare_space = " ";
392331070b5dSJoe Perches			}
392431070b5dSJoe Perches
392531070b5dSJoe Perches# unnecessary space "type  (*funcptr)(args...)"
392691f72e9cSJoe Perches# This test is not currently implemented because these declarations are
392791f72e9cSJoe Perches# equivalent to
392891f72e9cSJoe Perches#	int  foo(int bar, ...)
392991f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning.
393091f72e9cSJoe Perches#
393191f72e9cSJoe Perches#			elsif ($declare =~ /\s{2,}$/) {
393291f72e9cSJoe Perches#				WARN("SPACING",
393391f72e9cSJoe Perches#				     "Multiple spaces after return type\n" . $herecurr);
393491f72e9cSJoe Perches#			}
393531070b5dSJoe Perches
393631070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)"
393731070b5dSJoe Perches			if (defined $pre_pointer_space &&
393831070b5dSJoe Perches			    $pre_pointer_space =~ /^\s/) {
393931070b5dSJoe Perches				WARN("SPACING",
394031070b5dSJoe Perches				     "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
394131070b5dSJoe Perches			}
394231070b5dSJoe Perches
394331070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)"
394431070b5dSJoe Perches			if (defined $post_pointer_space &&
394531070b5dSJoe Perches			    $post_pointer_space =~ /^\s/) {
394631070b5dSJoe Perches				WARN("SPACING",
394731070b5dSJoe Perches				     "Unnecessary space before function pointer name\n" . $herecurr);
394831070b5dSJoe Perches			}
394931070b5dSJoe Perches
395031070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)"
395131070b5dSJoe Perches			if (defined $post_funcname_space &&
395231070b5dSJoe Perches			    $post_funcname_space =~ /^\s/) {
395331070b5dSJoe Perches				WARN("SPACING",
395431070b5dSJoe Perches				     "Unnecessary space after function pointer name\n" . $herecurr);
395531070b5dSJoe Perches			}
395631070b5dSJoe Perches
395731070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)"
395831070b5dSJoe Perches			if (defined $pre_args_space &&
395931070b5dSJoe Perches			    $pre_args_space =~ /^\s/) {
396031070b5dSJoe Perches				WARN("SPACING",
396131070b5dSJoe Perches				     "Unnecessary space before function pointer arguments\n" . $herecurr);
396231070b5dSJoe Perches			}
396331070b5dSJoe Perches
396431070b5dSJoe Perches			if (show_type("SPACING") && $fix) {
3965194f66fcSJoe Perches				$fixed[$fixlinenr] =~
396691f72e9cSJoe Perches				    s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
396731070b5dSJoe Perches			}
396831070b5dSJoe Perches		}
396931070b5dSJoe Perches
39708d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed:
39718d31cfceSAndy Whitcroft#  1. with a type on the left -- int [] a;
3972fe2a7dbcSAndy Whitcroft#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
3973fe2a7dbcSAndy Whitcroft#  3. inside a curly brace -- = { [0...10] = 5 }
39748d31cfceSAndy Whitcroft		while ($line =~ /(.*?\s)\[/g) {
39758d31cfceSAndy Whitcroft			my ($where, $prefix) = ($-[1], $1);
39768d31cfceSAndy Whitcroft			if ($prefix !~ /$Type\s+$/ &&
3977fe2a7dbcSAndy Whitcroft			    ($where != 0 || $prefix !~ /^.\s+$/) &&
3978daebc534SAndy Whitcroft			    $prefix !~ /[{,]\s+$/) {
39793705ce5bSJoe Perches				if (ERROR("BRACKET_SPACE",
39803705ce5bSJoe Perches					  "space prohibited before open square bracket '['\n" . $herecurr) &&
39813705ce5bSJoe Perches				    $fix) {
3982194f66fcSJoe Perches				    $fixed[$fixlinenr] =~
39833705ce5bSJoe Perches					s/^(\+.*?)\s+\[/$1\[/;
39843705ce5bSJoe Perches				}
39858d31cfceSAndy Whitcroft			}
39868d31cfceSAndy Whitcroft		}
39878d31cfceSAndy Whitcroft
3988f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses.
39896c72ffaaSAndy Whitcroft		while ($line =~ /($Ident)\s+\(/g) {
3990c2fdda0dSAndy Whitcroft			my $name = $1;
3991773647a0SAndy Whitcroft			my $ctx_before = substr($line, 0, $-[1]);
3992773647a0SAndy Whitcroft			my $ctx = "$ctx_before$name";
3993c2fdda0dSAndy Whitcroft
3994c2fdda0dSAndy Whitcroft			# Ignore those directives where spaces _are_ permitted.
3995773647a0SAndy Whitcroft			if ($name =~ /^(?:
3996773647a0SAndy Whitcroft				if|for|while|switch|return|case|
3997773647a0SAndy Whitcroft				volatile|__volatile__|
3998773647a0SAndy Whitcroft				__attribute__|format|__extension__|
3999773647a0SAndy Whitcroft				asm|__asm__)$/x)
4000773647a0SAndy Whitcroft			{
4001c2fdda0dSAndy Whitcroft			# cpp #define statements have non-optional spaces, ie
4002c2fdda0dSAndy Whitcroft			# if there is a space between the name and the open
4003c2fdda0dSAndy Whitcroft			# parenthesis it is simply not a parameter group.
4004c45dcabdSAndy Whitcroft			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
4005773647a0SAndy Whitcroft
4006773647a0SAndy Whitcroft			# cpp #elif statement condition may start with a (
4007c45dcabdSAndy Whitcroft			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
4008c2fdda0dSAndy Whitcroft
4009c2fdda0dSAndy Whitcroft			# If this whole things ends with a type its most
4010c2fdda0dSAndy Whitcroft			# likely a typedef for a function.
4011773647a0SAndy Whitcroft			} elsif ($ctx =~ /$Type$/) {
4012c2fdda0dSAndy Whitcroft
4013c2fdda0dSAndy Whitcroft			} else {
40143705ce5bSJoe Perches				if (WARN("SPACING",
40153705ce5bSJoe Perches					 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
40163705ce5bSJoe Perches					     $fix) {
4017194f66fcSJoe Perches					$fixed[$fixlinenr] =~
40183705ce5bSJoe Perches					    s/\b$name\s+\(/$name\(/;
40193705ce5bSJoe Perches				}
4020f0a594c1SAndy Whitcroft			}
40216c72ffaaSAndy Whitcroft		}
40229a4cad4eSEric Nelson
4023653d4876SAndy Whitcroft# Check operator spacing.
40240a920b5bSAndy Whitcroft		if (!($line=~/\#\s*include/)) {
40253705ce5bSJoe Perches			my $fixed_line = "";
40263705ce5bSJoe Perches			my $line_fixed = 0;
40273705ce5bSJoe Perches
40289c0ca6f9SAndy Whitcroft			my $ops = qr{
40299c0ca6f9SAndy Whitcroft				<<=|>>=|<=|>=|==|!=|
40309c0ca6f9SAndy Whitcroft				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
40319c0ca6f9SAndy Whitcroft				=>|->|<<|>>|<|>|=|!|~|
40321f65f947SAndy Whitcroft				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
403384731623SJoe Perches				\?:|\?|:
40349c0ca6f9SAndy Whitcroft			}x;
4035cf655043SAndy Whitcroft			my @elements = split(/($ops|;)/, $opline);
40363705ce5bSJoe Perches
40373705ce5bSJoe Perches##			print("element count: <" . $#elements . ">\n");
40383705ce5bSJoe Perches##			foreach my $el (@elements) {
40393705ce5bSJoe Perches##				print("el: <$el>\n");
40403705ce5bSJoe Perches##			}
40413705ce5bSJoe Perches
40423705ce5bSJoe Perches			my @fix_elements = ();
404300df344fSAndy Whitcroft			my $off = 0;
40446c72ffaaSAndy Whitcroft
40453705ce5bSJoe Perches			foreach my $el (@elements) {
40463705ce5bSJoe Perches				push(@fix_elements, substr($rawline, $off, length($el)));
40473705ce5bSJoe Perches				$off += length($el);
40483705ce5bSJoe Perches			}
40493705ce5bSJoe Perches
40503705ce5bSJoe Perches			$off = 0;
40513705ce5bSJoe Perches
40526c72ffaaSAndy Whitcroft			my $blank = copy_spacing($opline);
4053b34c648bSJoe Perches			my $last_after = -1;
40546c72ffaaSAndy Whitcroft
40550a920b5bSAndy Whitcroft			for (my $n = 0; $n < $#elements; $n += 2) {
40563705ce5bSJoe Perches
40573705ce5bSJoe Perches				my $good = $fix_elements[$n] . $fix_elements[$n + 1];
40583705ce5bSJoe Perches
40593705ce5bSJoe Perches##				print("n: <$n> good: <$good>\n");
40603705ce5bSJoe Perches
40614a0df2efSAndy Whitcroft				$off += length($elements[$n]);
40624a0df2efSAndy Whitcroft
406325985edcSLucas De Marchi				# Pick up the preceding and succeeding characters.
4064773647a0SAndy Whitcroft				my $ca = substr($opline, 0, $off);
4065773647a0SAndy Whitcroft				my $cc = '';
4066773647a0SAndy Whitcroft				if (length($opline) >= ($off + length($elements[$n + 1]))) {
4067773647a0SAndy Whitcroft					$cc = substr($opline, $off + length($elements[$n + 1]));
4068773647a0SAndy Whitcroft				}
4069773647a0SAndy Whitcroft				my $cb = "$ca$;$cc";
4070773647a0SAndy Whitcroft
40714a0df2efSAndy Whitcroft				my $a = '';
40724a0df2efSAndy Whitcroft				$a = 'V' if ($elements[$n] ne '');
40734a0df2efSAndy Whitcroft				$a = 'W' if ($elements[$n] =~ /\s$/);
4074cf655043SAndy Whitcroft				$a = 'C' if ($elements[$n] =~ /$;$/);
40754a0df2efSAndy Whitcroft				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
40764a0df2efSAndy Whitcroft				$a = 'O' if ($elements[$n] eq '');
4077773647a0SAndy Whitcroft				$a = 'E' if ($ca =~ /^\s*$/);
40784a0df2efSAndy Whitcroft
40790a920b5bSAndy Whitcroft				my $op = $elements[$n + 1];
40804a0df2efSAndy Whitcroft
40814a0df2efSAndy Whitcroft				my $c = '';
40820a920b5bSAndy Whitcroft				if (defined $elements[$n + 2]) {
40834a0df2efSAndy Whitcroft					$c = 'V' if ($elements[$n + 2] ne '');
40844a0df2efSAndy Whitcroft					$c = 'W' if ($elements[$n + 2] =~ /^\s/);
4085cf655043SAndy Whitcroft					$c = 'C' if ($elements[$n + 2] =~ /^$;/);
40864a0df2efSAndy Whitcroft					$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
40874a0df2efSAndy Whitcroft					$c = 'O' if ($elements[$n + 2] eq '');
40888b1b3378SAndy Whitcroft					$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
40894a0df2efSAndy Whitcroft				} else {
40904a0df2efSAndy Whitcroft					$c = 'E';
40910a920b5bSAndy Whitcroft				}
40920a920b5bSAndy Whitcroft
40934a0df2efSAndy Whitcroft				my $ctx = "${a}x${c}";
40944a0df2efSAndy Whitcroft
40954a0df2efSAndy Whitcroft				my $at = "(ctx:$ctx)";
40964a0df2efSAndy Whitcroft
40976c72ffaaSAndy Whitcroft				my $ptr = substr($blank, 0, $off) . "^";
4098de7d4f0eSAndy Whitcroft				my $hereptr = "$hereline$ptr\n";
40990a920b5bSAndy Whitcroft
410074048ed8SAndy Whitcroft				# Pull out the value of this operator.
41016c72ffaaSAndy Whitcroft				my $op_type = substr($curr_values, $off + 1, 1);
41020a920b5bSAndy Whitcroft
41031f65f947SAndy Whitcroft				# Get the full operator variant.
41041f65f947SAndy Whitcroft				my $opv = $op . substr($curr_vars, $off, 1);
41051f65f947SAndy Whitcroft
410613214adfSAndy Whitcroft				# Ignore operators passed as parameters.
410713214adfSAndy Whitcroft				if ($op_type ne 'V' &&
4108d7fe8065SSam Bobroff				    $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
410913214adfSAndy Whitcroft
4110cf655043SAndy Whitcroft#				# Ignore comments
4111cf655043SAndy Whitcroft#				} elsif ($op =~ /^$;+$/) {
411213214adfSAndy Whitcroft
4113d8aaf121SAndy Whitcroft				# ; should have either the end of line or a space or \ after it
411413214adfSAndy Whitcroft				} elsif ($op eq ';') {
4115cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEBC]/ &&
4116cf655043SAndy Whitcroft					    $cc !~ /^\\/ && $cc !~ /^;/) {
41173705ce5bSJoe Perches						if (ERROR("SPACING",
41183705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
4119b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
41203705ce5bSJoe Perches							$line_fixed = 1;
41213705ce5bSJoe Perches						}
4122d8aaf121SAndy Whitcroft					}
4123d8aaf121SAndy Whitcroft
4124d8aaf121SAndy Whitcroft				# // is a comment
4125d8aaf121SAndy Whitcroft				} elsif ($op eq '//') {
41260a920b5bSAndy Whitcroft
4127b00e4814SJoe Perches				#   :   when part of a bitfield
4128b00e4814SJoe Perches				} elsif ($opv eq ':B') {
4129b00e4814SJoe Perches					# skip the bitfield test for now
4130b00e4814SJoe Perches
41311f65f947SAndy Whitcroft				# No spaces for:
41321f65f947SAndy Whitcroft				#   ->
4133b00e4814SJoe Perches				} elsif ($op eq '->') {
41344a0df2efSAndy Whitcroft					if ($ctx =~ /Wx.|.xW/) {
41353705ce5bSJoe Perches						if (ERROR("SPACING",
41363705ce5bSJoe Perches							  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
4137b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
41383705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
41393705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
41403705ce5bSJoe Perches							}
4141b34c648bSJoe Perches							$line_fixed = 1;
41423705ce5bSJoe Perches						}
41430a920b5bSAndy Whitcroft					}
41440a920b5bSAndy Whitcroft
41452381097bSJoe Perches				# , must not have a space before and must have a space on the right.
41460a920b5bSAndy Whitcroft				} elsif ($op eq ',') {
41472381097bSJoe Perches					my $rtrim_before = 0;
41482381097bSJoe Perches					my $space_after = 0;
41492381097bSJoe Perches					if ($ctx =~ /Wx./) {
41502381097bSJoe Perches						if (ERROR("SPACING",
41512381097bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
41522381097bSJoe Perches							$line_fixed = 1;
41532381097bSJoe Perches							$rtrim_before = 1;
41542381097bSJoe Perches						}
41552381097bSJoe Perches					}
4156cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
41573705ce5bSJoe Perches						if (ERROR("SPACING",
41583705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
41593705ce5bSJoe Perches							$line_fixed = 1;
4160b34c648bSJoe Perches							$last_after = $n;
41612381097bSJoe Perches							$space_after = 1;
41622381097bSJoe Perches						}
41632381097bSJoe Perches					}
41642381097bSJoe Perches					if ($rtrim_before || $space_after) {
41652381097bSJoe Perches						if ($rtrim_before) {
41662381097bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
41672381097bSJoe Perches						} else {
41682381097bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
41692381097bSJoe Perches						}
41702381097bSJoe Perches						if ($space_after) {
41712381097bSJoe Perches							$good .= " ";
41723705ce5bSJoe Perches						}
41730a920b5bSAndy Whitcroft					}
41740a920b5bSAndy Whitcroft
41759c0ca6f9SAndy Whitcroft				# '*' as part of a type definition -- reported already.
417674048ed8SAndy Whitcroft				} elsif ($opv eq '*_') {
41779c0ca6f9SAndy Whitcroft					#warn "'*' is part of type\n";
41789c0ca6f9SAndy Whitcroft
41799c0ca6f9SAndy Whitcroft				# unary operators should have a space before and
41809c0ca6f9SAndy Whitcroft				# none after.  May be left adjacent to another
41819c0ca6f9SAndy Whitcroft				# unary operator, or a cast
41829c0ca6f9SAndy Whitcroft				} elsif ($op eq '!' || $op eq '~' ||
418374048ed8SAndy Whitcroft					 $opv eq '*U' || $opv eq '-U' ||
41840d413866SAndy Whitcroft					 $opv eq '&U' || $opv eq '&&U') {
4185cf655043SAndy Whitcroft					if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
41863705ce5bSJoe Perches						if (ERROR("SPACING",
41873705ce5bSJoe Perches							  "space required before that '$op' $at\n" . $hereptr)) {
4188b34c648bSJoe Perches							if ($n != $last_after + 2) {
4189b34c648bSJoe Perches								$good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
41903705ce5bSJoe Perches								$line_fixed = 1;
41913705ce5bSJoe Perches							}
41920a920b5bSAndy Whitcroft						}
4193b34c648bSJoe Perches					}
4194a3340b35SAndy Whitcroft					if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
4195171ae1a4SAndy Whitcroft						# A unary '*' may be const
4196171ae1a4SAndy Whitcroft
4197171ae1a4SAndy Whitcroft					} elsif ($ctx =~ /.xW/) {
41983705ce5bSJoe Perches						if (ERROR("SPACING",
41993705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
4200b34c648bSJoe Perches							$good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
42013705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
42023705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
42033705ce5bSJoe Perches							}
4204b34c648bSJoe Perches							$line_fixed = 1;
42053705ce5bSJoe Perches						}
42060a920b5bSAndy Whitcroft					}
42070a920b5bSAndy Whitcroft
42080a920b5bSAndy Whitcroft				# unary ++ and unary -- are allowed no space on one side.
42090a920b5bSAndy Whitcroft				} elsif ($op eq '++' or $op eq '--') {
4210773647a0SAndy Whitcroft					if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
42113705ce5bSJoe Perches						if (ERROR("SPACING",
42123705ce5bSJoe Perches							  "space required one side of that '$op' $at\n" . $hereptr)) {
4213b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
42143705ce5bSJoe Perches							$line_fixed = 1;
42153705ce5bSJoe Perches						}
42160a920b5bSAndy Whitcroft					}
4217773647a0SAndy Whitcroft					if ($ctx =~ /Wx[BE]/ ||
4218773647a0SAndy Whitcroft					    ($ctx =~ /Wx./ && $cc =~ /^;/)) {
42193705ce5bSJoe Perches						if (ERROR("SPACING",
42203705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
4221b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
42223705ce5bSJoe Perches							$line_fixed = 1;
42233705ce5bSJoe Perches						}
4224653d4876SAndy Whitcroft					}
4225773647a0SAndy Whitcroft					if ($ctx =~ /ExW/) {
42263705ce5bSJoe Perches						if (ERROR("SPACING",
42273705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
4228b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
42293705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
42303705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4231773647a0SAndy Whitcroft							}
4232b34c648bSJoe Perches							$line_fixed = 1;
42333705ce5bSJoe Perches						}
42343705ce5bSJoe Perches					}
42350a920b5bSAndy Whitcroft
42360a920b5bSAndy Whitcroft				# << and >> may either have or not have spaces both sides
42379c0ca6f9SAndy Whitcroft				} elsif ($op eq '<<' or $op eq '>>' or
42389c0ca6f9SAndy Whitcroft					 $op eq '&' or $op eq '^' or $op eq '|' or
42399c0ca6f9SAndy Whitcroft					 $op eq '+' or $op eq '-' or
4240c2fdda0dSAndy Whitcroft					 $op eq '*' or $op eq '/' or
4241c2fdda0dSAndy Whitcroft					 $op eq '%')
42420a920b5bSAndy Whitcroft				{
4243d2e025f3SJoe Perches					if ($check) {
4244d2e025f3SJoe Perches						if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
4245d2e025f3SJoe Perches							if (CHK("SPACING",
4246d2e025f3SJoe Perches								"spaces preferred around that '$op' $at\n" . $hereptr)) {
4247d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4248d2e025f3SJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4249d2e025f3SJoe Perches								$line_fixed = 1;
4250d2e025f3SJoe Perches							}
4251d2e025f3SJoe Perches						} elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
4252d2e025f3SJoe Perches							if (CHK("SPACING",
4253d2e025f3SJoe Perches								"space preferred before that '$op' $at\n" . $hereptr)) {
4254d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
4255d2e025f3SJoe Perches								$line_fixed = 1;
4256d2e025f3SJoe Perches							}
4257d2e025f3SJoe Perches						}
4258d2e025f3SJoe Perches					} elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
42593705ce5bSJoe Perches						if (ERROR("SPACING",
42603705ce5bSJoe Perches							  "need consistent spacing around '$op' $at\n" . $hereptr)) {
4261b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4262b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
4263b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4264b34c648bSJoe Perches							}
42653705ce5bSJoe Perches							$line_fixed = 1;
42663705ce5bSJoe Perches						}
42670a920b5bSAndy Whitcroft					}
42680a920b5bSAndy Whitcroft
42691f65f947SAndy Whitcroft				# A colon needs no spaces before when it is
42701f65f947SAndy Whitcroft				# terminating a case value or a label.
42711f65f947SAndy Whitcroft				} elsif ($opv eq ':C' || $opv eq ':L') {
42721f65f947SAndy Whitcroft					if ($ctx =~ /Wx./) {
42733705ce5bSJoe Perches						if (ERROR("SPACING",
42743705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
4275b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
42763705ce5bSJoe Perches							$line_fixed = 1;
42773705ce5bSJoe Perches						}
42781f65f947SAndy Whitcroft					}
42791f65f947SAndy Whitcroft
42800a920b5bSAndy Whitcroft				# All the others need spaces both sides.
4281cf655043SAndy Whitcroft				} elsif ($ctx !~ /[EWC]x[CWE]/) {
42821f65f947SAndy Whitcroft					my $ok = 0;
42831f65f947SAndy Whitcroft
428422f2a2efSAndy Whitcroft					# Ignore email addresses <foo@bar>
42851f65f947SAndy Whitcroft					if (($op eq '<' &&
42861f65f947SAndy Whitcroft					     $cc =~ /^\S+\@\S+>/) ||
42871f65f947SAndy Whitcroft					    ($op eq '>' &&
42881f65f947SAndy Whitcroft					     $ca =~ /<\S+\@\S+$/))
42891f65f947SAndy Whitcroft					{
42901f65f947SAndy Whitcroft					    	$ok = 1;
42911f65f947SAndy Whitcroft					}
42921f65f947SAndy Whitcroft
4293e0df7e1fSJoe Perches					# for asm volatile statements
4294e0df7e1fSJoe Perches					# ignore a colon with another
4295e0df7e1fSJoe Perches					# colon immediately before or after
4296e0df7e1fSJoe Perches					if (($op eq ':') &&
4297e0df7e1fSJoe Perches					    ($ca =~ /:$/ || $cc =~ /^:/)) {
4298e0df7e1fSJoe Perches						$ok = 1;
4299e0df7e1fSJoe Perches					}
4300e0df7e1fSJoe Perches
430184731623SJoe Perches					# messages are ERROR, but ?: are CHK
43021f65f947SAndy Whitcroft					if ($ok == 0) {
430384731623SJoe Perches						my $msg_type = \&ERROR;
430484731623SJoe Perches						$msg_type = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
430584731623SJoe Perches
430684731623SJoe Perches						if (&{$msg_type}("SPACING",
43073705ce5bSJoe Perches								 "spaces required around that '$op' $at\n" . $hereptr)) {
4308b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4309b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
4310b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4311b34c648bSJoe Perches							}
43123705ce5bSJoe Perches							$line_fixed = 1;
43133705ce5bSJoe Perches						}
43140a920b5bSAndy Whitcroft					}
431522f2a2efSAndy Whitcroft				}
43164a0df2efSAndy Whitcroft				$off += length($elements[$n + 1]);
43173705ce5bSJoe Perches
43183705ce5bSJoe Perches##				print("n: <$n> GOOD: <$good>\n");
43193705ce5bSJoe Perches
43203705ce5bSJoe Perches				$fixed_line = $fixed_line . $good;
43210a920b5bSAndy Whitcroft			}
43223705ce5bSJoe Perches
43233705ce5bSJoe Perches			if (($#elements % 2) == 0) {
43243705ce5bSJoe Perches				$fixed_line = $fixed_line . $fix_elements[$#elements];
43253705ce5bSJoe Perches			}
43263705ce5bSJoe Perches
4327194f66fcSJoe Perches			if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
4328194f66fcSJoe Perches				$fixed[$fixlinenr] = $fixed_line;
43293705ce5bSJoe Perches			}
43303705ce5bSJoe Perches
43313705ce5bSJoe Perches
43320a920b5bSAndy Whitcroft		}
43330a920b5bSAndy Whitcroft
4334786b6326SJoe Perches# check for whitespace before a non-naked semicolon
4335d2e248e7SJoe Perches		if ($line =~ /^\+.*\S\s+;\s*$/) {
4336786b6326SJoe Perches			if (WARN("SPACING",
4337786b6326SJoe Perches				 "space prohibited before semicolon\n" . $herecurr) &&
4338786b6326SJoe Perches			    $fix) {
4339194f66fcSJoe Perches				1 while $fixed[$fixlinenr] =~
4340786b6326SJoe Perches				    s/^(\+.*\S)\s+;/$1;/;
4341786b6326SJoe Perches			}
4342786b6326SJoe Perches		}
4343786b6326SJoe Perches
4344f0a594c1SAndy Whitcroft# check for multiple assignments
4345f0a594c1SAndy Whitcroft		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
4346000d1cc1SJoe Perches			CHK("MULTIPLE_ASSIGNMENTS",
4347000d1cc1SJoe Perches			    "multiple assignments should be avoided\n" . $herecurr);
4348f0a594c1SAndy Whitcroft		}
4349f0a594c1SAndy Whitcroft
435022f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration
435122f2a2efSAndy Whitcroft## # continuation.
435222f2a2efSAndy Whitcroft## 		if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
435322f2a2efSAndy Whitcroft## 		    $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
435422f2a2efSAndy Whitcroft##
435522f2a2efSAndy Whitcroft## 			# Remove any bracketed sections to ensure we do not
435622f2a2efSAndy Whitcroft## 			# falsly report the parameters of functions.
435722f2a2efSAndy Whitcroft## 			my $ln = $line;
435822f2a2efSAndy Whitcroft## 			while ($ln =~ s/\([^\(\)]*\)//g) {
435922f2a2efSAndy Whitcroft## 			}
436022f2a2efSAndy Whitcroft## 			if ($ln =~ /,/) {
4361000d1cc1SJoe Perches## 				WARN("MULTIPLE_DECLARATION",
4362000d1cc1SJoe Perches##				     "declaring multiple variables together should be avoided\n" . $herecurr);
436322f2a2efSAndy Whitcroft## 			}
436422f2a2efSAndy Whitcroft## 		}
4365f0a594c1SAndy Whitcroft
43660a920b5bSAndy Whitcroft#need space before brace following if, while, etc
43676b8c69e4SGeyslan G. Bem		if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
43684e5d56bdSEddie Kovsky		    $line =~ /do\{/) {
43693705ce5bSJoe Perches			if (ERROR("SPACING",
43703705ce5bSJoe Perches				  "space required before the open brace '{'\n" . $herecurr) &&
43713705ce5bSJoe Perches			    $fix) {
4372194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^(\+.*(?:do|\))){/$1 {/;
43733705ce5bSJoe Perches			}
4374de7d4f0eSAndy Whitcroft		}
4375de7d4f0eSAndy Whitcroft
4376c4a62ef9SJoe Perches## # check for blank lines before declarations
4377c4a62ef9SJoe Perches##		if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
4378c4a62ef9SJoe Perches##		    $prevrawline =~ /^.\s*$/) {
4379c4a62ef9SJoe Perches##			WARN("SPACING",
4380c4a62ef9SJoe Perches##			     "No blank lines before declarations\n" . $hereprev);
4381c4a62ef9SJoe Perches##		}
4382c4a62ef9SJoe Perches##
4383c4a62ef9SJoe Perches
4384de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything
4385de7d4f0eSAndy Whitcroft# on the line
4386de7d4f0eSAndy Whitcroft		if ($line =~ /}(?!(?:,|;|\)))\S/) {
4387d5e616fcSJoe Perches			if (ERROR("SPACING",
4388d5e616fcSJoe Perches				  "space required after that close brace '}'\n" . $herecurr) &&
4389d5e616fcSJoe Perches			    $fix) {
4390194f66fcSJoe Perches				$fixed[$fixlinenr] =~
4391d5e616fcSJoe Perches				    s/}((?!(?:,|;|\)))\S)/} $1/;
4392d5e616fcSJoe Perches			}
43930a920b5bSAndy Whitcroft		}
43940a920b5bSAndy Whitcroft
439522f2a2efSAndy Whitcroft# check spacing on square brackets
439622f2a2efSAndy Whitcroft		if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
43973705ce5bSJoe Perches			if (ERROR("SPACING",
43983705ce5bSJoe Perches				  "space prohibited after that open square bracket '['\n" . $herecurr) &&
43993705ce5bSJoe Perches			    $fix) {
4400194f66fcSJoe Perches				$fixed[$fixlinenr] =~
44013705ce5bSJoe Perches				    s/\[\s+/\[/;
44023705ce5bSJoe Perches			}
440322f2a2efSAndy Whitcroft		}
440422f2a2efSAndy Whitcroft		if ($line =~ /\s\]/) {
44053705ce5bSJoe Perches			if (ERROR("SPACING",
44063705ce5bSJoe Perches				  "space prohibited before that close square bracket ']'\n" . $herecurr) &&
44073705ce5bSJoe Perches			    $fix) {
4408194f66fcSJoe Perches				$fixed[$fixlinenr] =~
44093705ce5bSJoe Perches				    s/\s+\]/\]/;
44103705ce5bSJoe Perches			}
441122f2a2efSAndy Whitcroft		}
441222f2a2efSAndy Whitcroft
4413c45dcabdSAndy Whitcroft# check spacing on parentheses
44149c0ca6f9SAndy Whitcroft		if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
44159c0ca6f9SAndy Whitcroft		    $line !~ /for\s*\(\s+;/) {
44163705ce5bSJoe Perches			if (ERROR("SPACING",
44173705ce5bSJoe Perches				  "space prohibited after that open parenthesis '('\n" . $herecurr) &&
44183705ce5bSJoe Perches			    $fix) {
4419194f66fcSJoe Perches				$fixed[$fixlinenr] =~
44203705ce5bSJoe Perches				    s/\(\s+/\(/;
44213705ce5bSJoe Perches			}
442222f2a2efSAndy Whitcroft		}
442313214adfSAndy Whitcroft		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
4424c45dcabdSAndy Whitcroft		    $line !~ /for\s*\(.*;\s+\)/ &&
4425c45dcabdSAndy Whitcroft		    $line !~ /:\s+\)/) {
44263705ce5bSJoe Perches			if (ERROR("SPACING",
44273705ce5bSJoe Perches				  "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
44283705ce5bSJoe Perches			    $fix) {
4429194f66fcSJoe Perches				$fixed[$fixlinenr] =~
44303705ce5bSJoe Perches				    s/\s+\)/\)/;
44313705ce5bSJoe Perches			}
443222f2a2efSAndy Whitcroft		}
443322f2a2efSAndy Whitcroft
4434e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals
4435e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
4436e2826fd0SJoe Perches
4437e2826fd0SJoe Perches		while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
4438ea4acbb1SJoe Perches			my $var = $1;
4439ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
4440ea4acbb1SJoe Perches				"Unnecessary parentheses around $var\n" . $herecurr) &&
4441ea4acbb1SJoe Perches			    $fix) {
4442ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
4443ea4acbb1SJoe Perches			}
4444ea4acbb1SJoe Perches		}
4445ea4acbb1SJoe Perches
4446ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses
4447ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar();
4448ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives
4449ea4acbb1SJoe Perches		if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
4450ea4acbb1SJoe Perches			my $var = $2;
4451ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
4452ea4acbb1SJoe Perches				"Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
4453ea4acbb1SJoe Perches			    $fix) {
4454ea4acbb1SJoe Perches				my $var2 = deparenthesize($var);
4455ea4acbb1SJoe Perches				$var2 =~ s/\s//g;
4456ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
4457ea4acbb1SJoe Perches			}
4458e2826fd0SJoe Perches		}
4459e2826fd0SJoe Perches
44600a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however
44614a0df2efSAndy Whitcroft		if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
44620a920b5bSAndy Whitcroft		   !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
44633705ce5bSJoe Perches			if (WARN("INDENTED_LABEL",
44643705ce5bSJoe Perches				 "labels should not be indented\n" . $herecurr) &&
44653705ce5bSJoe Perches			    $fix) {
4466194f66fcSJoe Perches				$fixed[$fixlinenr] =~
44673705ce5bSJoe Perches				    s/^(.)\s+/$1/;
44683705ce5bSJoe Perches			}
44690a920b5bSAndy Whitcroft		}
44700a920b5bSAndy Whitcroft
44715b9553abSJoe Perches# return is not a function
4472507e5141SJoe Perches		if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
4473c45dcabdSAndy Whitcroft			my $spacing = $1;
4474507e5141SJoe Perches			if ($^V && $^V ge 5.10.0 &&
44755b9553abSJoe Perches			    $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
44765b9553abSJoe Perches				my $value = $1;
44775b9553abSJoe Perches				$value = deparenthesize($value);
44785b9553abSJoe Perches				if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
4479000d1cc1SJoe Perches					ERROR("RETURN_PARENTHESES",
4480000d1cc1SJoe Perches					      "return is not a function, parentheses are not required\n" . $herecurr);
44815b9553abSJoe Perches				}
4482c45dcabdSAndy Whitcroft			} elsif ($spacing !~ /\s+/) {
4483000d1cc1SJoe Perches				ERROR("SPACING",
4484000d1cc1SJoe Perches				      "space required before the open parenthesis '('\n" . $herecurr);
4485c45dcabdSAndy Whitcroft			}
4486c45dcabdSAndy Whitcroft		}
4487507e5141SJoe Perches
4488b43ae21bSJoe Perches# unnecessary return in a void function
4489b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return;
4490b43ae21bSJoe Perches# and the line before that not a goto label target like "out:"
4491b43ae21bSJoe Perches		if ($sline =~ /^[ \+]}\s*$/ &&
4492b43ae21bSJoe Perches		    $prevline =~ /^\+\treturn\s*;\s*$/ &&
4493b43ae21bSJoe Perches		    $linenr >= 3 &&
4494b43ae21bSJoe Perches		    $lines[$linenr - 3] =~ /^[ +]/ &&
4495b43ae21bSJoe Perches		    $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
44969819cf25SJoe Perches			WARN("RETURN_VOID",
4497b43ae21bSJoe Perches			     "void function return statements are not generally useful\n" . $hereprev);
44989819cf25SJoe Perches               }
44999819cf25SJoe Perches
4500189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar))
4501189248d8SJoe Perches		if ($^V && $^V ge 5.10.0 &&
4502189248d8SJoe Perches		    $line =~ /\bif\s*((?:\(\s*){2,})/) {
4503189248d8SJoe Perches			my $openparens = $1;
4504189248d8SJoe Perches			my $count = $openparens =~ tr@\(@\(@;
4505189248d8SJoe Perches			my $msg = "";
4506189248d8SJoe Perches			if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
4507189248d8SJoe Perches				my $comp = $4;	#Not $1 because of $LvalOrFunc
4508189248d8SJoe Perches				$msg = " - maybe == should be = ?" if ($comp eq "==");
4509189248d8SJoe Perches				WARN("UNNECESSARY_PARENTHESES",
4510189248d8SJoe Perches				     "Unnecessary parentheses$msg\n" . $herecurr);
4511189248d8SJoe Perches			}
4512189248d8SJoe Perches		}
4513189248d8SJoe Perches
4514c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left
4515c5595fa2SJoe Perches#	avoid cases like "foo + BAR < baz"
4516c5595fa2SJoe Perches#	only fix matches surrounded by parentheses to avoid incorrect
4517c5595fa2SJoe Perches#	conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
4518c5595fa2SJoe Perches		if ($^V && $^V ge 5.10.0 &&
4519c5595fa2SJoe Perches		    $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
4520c5595fa2SJoe Perches			my $lead = $1;
4521c5595fa2SJoe Perches			my $const = $2;
4522c5595fa2SJoe Perches			my $comp = $3;
4523c5595fa2SJoe Perches			my $to = $4;
4524c5595fa2SJoe Perches			my $newcomp = $comp;
4525f39e1769SJoe Perches			if ($lead !~ /(?:$Operators|\.)\s*$/ &&
4526c5595fa2SJoe Perches			    $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
4527c5595fa2SJoe Perches			    WARN("CONSTANT_COMPARISON",
4528c5595fa2SJoe Perches				 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
4529c5595fa2SJoe Perches			    $fix) {
4530c5595fa2SJoe Perches				if ($comp eq "<") {
4531c5595fa2SJoe Perches					$newcomp = ">";
4532c5595fa2SJoe Perches				} elsif ($comp eq "<=") {
4533c5595fa2SJoe Perches					$newcomp = ">=";
4534c5595fa2SJoe Perches				} elsif ($comp eq ">") {
4535c5595fa2SJoe Perches					$newcomp = "<";
4536c5595fa2SJoe Perches				} elsif ($comp eq ">=") {
4537c5595fa2SJoe Perches					$newcomp = "<=";
4538c5595fa2SJoe Perches				}
4539c5595fa2SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
4540c5595fa2SJoe Perches			}
4541c5595fa2SJoe Perches		}
4542c5595fa2SJoe Perches
4543f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative
4544f34e4a4fSJoe Perches		if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
454553a3c448SAndy Whitcroft			my $name = $1;
454653a3c448SAndy Whitcroft			if ($name ne 'EOF' && $name ne 'ERROR') {
4547000d1cc1SJoe Perches				WARN("USE_NEGATIVE_ERRNO",
4548f34e4a4fSJoe Perches				     "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
454953a3c448SAndy Whitcroft			}
455053a3c448SAndy Whitcroft		}
4551c45dcabdSAndy Whitcroft
45520a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc
45534a0df2efSAndy Whitcroft		if ($line =~ /\b(if|while|for|switch)\(/) {
45543705ce5bSJoe Perches			if (ERROR("SPACING",
45553705ce5bSJoe Perches				  "space required before the open parenthesis '('\n" . $herecurr) &&
45563705ce5bSJoe Perches			    $fix) {
4557194f66fcSJoe Perches				$fixed[$fixlinenr] =~
45583705ce5bSJoe Perches				    s/\b(if|while|for|switch)\(/$1 \(/;
45593705ce5bSJoe Perches			}
45600a920b5bSAndy Whitcroft		}
45610a920b5bSAndy Whitcroft
4562f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing
4563f5fe35ddSAndy Whitcroft# statements after the conditional.
4564170d3a22SAndy Whitcroft		if ($line =~ /do\s*(?!{)/) {
45653e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
45663e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
45673e469cdcSAndy Whitcroft					if (!defined $stat);
4568170d3a22SAndy Whitcroft			my ($stat_next) = ctx_statement_block($line_nr_next,
4569170d3a22SAndy Whitcroft						$remain_next, $off_next);
4570170d3a22SAndy Whitcroft			$stat_next =~ s/\n./\n /g;
4571170d3a22SAndy Whitcroft			##print "stat<$stat> stat_next<$stat_next>\n";
4572170d3a22SAndy Whitcroft
4573170d3a22SAndy Whitcroft			if ($stat_next =~ /^\s*while\b/) {
4574170d3a22SAndy Whitcroft				# If the statement carries leading newlines,
4575170d3a22SAndy Whitcroft				# then count those as offsets.
4576170d3a22SAndy Whitcroft				my ($whitespace) =
4577170d3a22SAndy Whitcroft					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
4578170d3a22SAndy Whitcroft				my $offset =
4579170d3a22SAndy Whitcroft					statement_rawlines($whitespace) - 1;
4580170d3a22SAndy Whitcroft
4581170d3a22SAndy Whitcroft				$suppress_whiletrailers{$line_nr_next +
4582170d3a22SAndy Whitcroft								$offset} = 1;
4583170d3a22SAndy Whitcroft			}
4584170d3a22SAndy Whitcroft		}
4585170d3a22SAndy Whitcroft		if (!defined $suppress_whiletrailers{$linenr} &&
4586c11230f4SJoe Perches		    defined($stat) && defined($cond) &&
4587170d3a22SAndy Whitcroft		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
4588171ae1a4SAndy Whitcroft			my ($s, $c) = ($stat, $cond);
45898905a67cSAndy Whitcroft
4590b53c8e10SAndy Whitcroft			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
4591000d1cc1SJoe Perches				ERROR("ASSIGN_IN_IF",
4592000d1cc1SJoe Perches				      "do not use assignment in if condition\n" . $herecurr);
45938905a67cSAndy Whitcroft			}
45948905a67cSAndy Whitcroft
45958905a67cSAndy Whitcroft			# Find out what is on the end of the line after the
45968905a67cSAndy Whitcroft			# conditional.
4597773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
45988905a67cSAndy Whitcroft			$s =~ s/\n.*//g;
459913214adfSAndy Whitcroft			$s =~ s/$;//g; 	# Remove any comments
460053210168SAndy Whitcroft			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
460153210168SAndy Whitcroft			    $c !~ /}\s*while\s*/)
4602773647a0SAndy Whitcroft			{
4603bb44ad39SAndy Whitcroft				# Find out how long the conditional actually is.
4604bb44ad39SAndy Whitcroft				my @newlines = ($c =~ /\n/gs);
4605bb44ad39SAndy Whitcroft				my $cond_lines = 1 + $#newlines;
460642bdf74cSHidetoshi Seto				my $stat_real = '';
4607bb44ad39SAndy Whitcroft
460842bdf74cSHidetoshi Seto				$stat_real = raw_line($linenr, $cond_lines)
460942bdf74cSHidetoshi Seto							. "\n" if ($cond_lines);
4610bb44ad39SAndy Whitcroft				if (defined($stat_real) && $cond_lines > 1) {
4611bb44ad39SAndy Whitcroft					$stat_real = "[...]\n$stat_real";
4612bb44ad39SAndy Whitcroft				}
4613bb44ad39SAndy Whitcroft
4614000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
4615000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr . $stat_real);
46168905a67cSAndy Whitcroft			}
46178905a67cSAndy Whitcroft		}
46188905a67cSAndy Whitcroft
461913214adfSAndy Whitcroft# Check for bitwise tests written as boolean
462013214adfSAndy Whitcroft		if ($line =~ /
462113214adfSAndy Whitcroft			(?:
462213214adfSAndy Whitcroft				(?:\[|\(|\&\&|\|\|)
462313214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
462413214adfSAndy Whitcroft				(?:\&\&|\|\|)
462513214adfSAndy Whitcroft			|
462613214adfSAndy Whitcroft				(?:\&\&|\|\|)
462713214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
462813214adfSAndy Whitcroft				(?:\&\&|\|\||\)|\])
462913214adfSAndy Whitcroft			)/x)
463013214adfSAndy Whitcroft		{
4631000d1cc1SJoe Perches			WARN("HEXADECIMAL_BOOLEAN_TEST",
4632000d1cc1SJoe Perches			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
463313214adfSAndy Whitcroft		}
463413214adfSAndy Whitcroft
46358905a67cSAndy Whitcroft# if and else should not have general statements after it
463613214adfSAndy Whitcroft		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
463713214adfSAndy Whitcroft			my $s = $1;
463813214adfSAndy Whitcroft			$s =~ s/$;//g; 	# Remove any comments
463913214adfSAndy Whitcroft			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
4640000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
4641000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr);
46420a920b5bSAndy Whitcroft			}
464313214adfSAndy Whitcroft		}
464439667782SAndy Whitcroft# if should not continue a brace
464539667782SAndy Whitcroft		if ($line =~ /}\s*if\b/) {
4646000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
4647048b123fSRasmus Villemoes			      "trailing statements should be on next line (or did you mean 'else if'?)\n" .
464839667782SAndy Whitcroft				$herecurr);
464939667782SAndy Whitcroft		}
4650a1080bf8SAndy Whitcroft# case and default should not have general statements after them
4651a1080bf8SAndy Whitcroft		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
4652a1080bf8SAndy Whitcroft		    $line !~ /\G(?:
46533fef12d6SAndy Whitcroft			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
4654a1080bf8SAndy Whitcroft			\s*return\s+
4655a1080bf8SAndy Whitcroft		    )/xg)
4656a1080bf8SAndy Whitcroft		{
4657000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
4658000d1cc1SJoe Perches			      "trailing statements should be on next line\n" . $herecurr);
4659a1080bf8SAndy Whitcroft		}
46600a920b5bSAndy Whitcroft
46610a920b5bSAndy Whitcroft		# Check for }<nl>else {, these must be at the same
46620a920b5bSAndy Whitcroft		# indent level to be relevant to each other.
46638b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
46640a920b5bSAndy Whitcroft		    $previndent == $indent) {
46658b8856f4SJoe Perches			if (ERROR("ELSE_AFTER_BRACE",
46668b8856f4SJoe Perches				  "else should follow close brace '}'\n" . $hereprev) &&
46678b8856f4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
46688b8856f4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
46698b8856f4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
46708b8856f4SJoe Perches				my $fixedline = $prevrawline;
46718b8856f4SJoe Perches				$fixedline =~ s/}\s*$//;
46728b8856f4SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
46738b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
46748b8856f4SJoe Perches				}
46758b8856f4SJoe Perches				$fixedline = $rawline;
46768b8856f4SJoe Perches				$fixedline =~ s/^(.\s*)else/$1} else/;
46778b8856f4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
46788b8856f4SJoe Perches			}
46790a920b5bSAndy Whitcroft		}
46800a920b5bSAndy Whitcroft
46818b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
4682c2fdda0dSAndy Whitcroft		    $previndent == $indent) {
4683c2fdda0dSAndy Whitcroft			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
4684c2fdda0dSAndy Whitcroft
4685c2fdda0dSAndy Whitcroft			# Find out what is on the end of the line after the
4686c2fdda0dSAndy Whitcroft			# conditional.
4687773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
4688c2fdda0dSAndy Whitcroft			$s =~ s/\n.*//g;
4689c2fdda0dSAndy Whitcroft
4690c2fdda0dSAndy Whitcroft			if ($s =~ /^\s*;/) {
46918b8856f4SJoe Perches				if (ERROR("WHILE_AFTER_BRACE",
46928b8856f4SJoe Perches					  "while should follow close brace '}'\n" . $hereprev) &&
46938b8856f4SJoe Perches				    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
46948b8856f4SJoe Perches					fix_delete_line($fixlinenr - 1, $prevrawline);
46958b8856f4SJoe Perches					fix_delete_line($fixlinenr, $rawline);
46968b8856f4SJoe Perches					my $fixedline = $prevrawline;
46978b8856f4SJoe Perches					my $trailing = $rawline;
46988b8856f4SJoe Perches					$trailing =~ s/^\+//;
46998b8856f4SJoe Perches					$trailing = trim($trailing);
47008b8856f4SJoe Perches					$fixedline =~ s/}\s*$/} $trailing/;
47018b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
47028b8856f4SJoe Perches				}
4703c2fdda0dSAndy Whitcroft			}
4704c2fdda0dSAndy Whitcroft		}
4705c2fdda0dSAndy Whitcroft
470695e2c602SJoe Perches#Specific variable tests
4707323c1260SJoe Perches		while ($line =~ m{($Constant|$Lval)}g) {
4708323c1260SJoe Perches			my $var = $1;
470995e2c602SJoe Perches
471095e2c602SJoe Perches#gcc binary extension
471195e2c602SJoe Perches			if ($var =~ /^$Binary$/) {
4712d5e616fcSJoe Perches				if (WARN("GCC_BINARY_CONSTANT",
4713d5e616fcSJoe Perches					 "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) &&
4714d5e616fcSJoe Perches				    $fix) {
4715d5e616fcSJoe Perches					my $hexval = sprintf("0x%x", oct($var));
4716194f66fcSJoe Perches					$fixed[$fixlinenr] =~
4717d5e616fcSJoe Perches					    s/\b$var\b/$hexval/;
4718d5e616fcSJoe Perches				}
471995e2c602SJoe Perches			}
472095e2c602SJoe Perches
472195e2c602SJoe Perches#CamelCase
4722807bd26cSJoe Perches			if ($var !~ /^$Constant$/ &&
4723be79794bSJoe Perches			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
472422735ce8SJoe Perches#Ignore Page<foo> variants
4725807bd26cSJoe Perches			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
472622735ce8SJoe Perches#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show)
4727f5123576SJulius Werner			    $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ &&
4728f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz
4729f5123576SJulius Werner			    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
47307e781f67SJoe Perches				while ($var =~ m{($Ident)}g) {
47317e781f67SJoe Perches					my $word = $1;
47327e781f67SJoe Perches					next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
4733d8b07710SJoe Perches					if ($check) {
4734d8b07710SJoe Perches						seed_camelcase_includes();
4735d8b07710SJoe Perches						if (!$file && !$camelcase_file_seeded) {
4736d8b07710SJoe Perches							seed_camelcase_file($realfile);
4737d8b07710SJoe Perches							$camelcase_file_seeded = 1;
4738d8b07710SJoe Perches						}
4739d8b07710SJoe Perches					}
47407e781f67SJoe Perches					if (!defined $camelcase{$word}) {
47417e781f67SJoe Perches						$camelcase{$word} = 1;
4742be79794bSJoe Perches						CHK("CAMELCASE",
47437e781f67SJoe Perches						    "Avoid CamelCase: <$word>\n" . $herecurr);
47447e781f67SJoe Perches					}
4745323c1260SJoe Perches				}
4746323c1260SJoe Perches			}
47473445686aSJoe Perches		}
47480a920b5bSAndy Whitcroft
47490a920b5bSAndy Whitcroft#no spaces allowed after \ in define
4750d5e616fcSJoe Perches		if ($line =~ /\#\s*define.*\\\s+$/) {
4751d5e616fcSJoe Perches			if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
4752d5e616fcSJoe Perches				 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
4753d5e616fcSJoe Perches			    $fix) {
4754194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
4755d5e616fcSJoe Perches			}
47560a920b5bSAndy Whitcroft		}
47570a920b5bSAndy Whitcroft
47580e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
47590e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line)
4760c45dcabdSAndy Whitcroft		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
4761e09dec48SAndy Whitcroft			my $file = "$1.h";
4762e09dec48SAndy Whitcroft			my $checkfile = "include/linux/$file";
4763e09dec48SAndy Whitcroft			if (-f "$root/$checkfile" &&
4764e09dec48SAndy Whitcroft			    $realfile ne $checkfile &&
47657840a94cSWolfram Sang			    $1 !~ /$allowed_asm_includes/)
4766c45dcabdSAndy Whitcroft			{
47670e212e0aSFabian Frederick				my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
47680e212e0aSFabian Frederick				if ($asminclude > 0) {
4769e09dec48SAndy Whitcroft					if ($realfile =~ m{^arch/}) {
4770000d1cc1SJoe Perches						CHK("ARCH_INCLUDE_LINUX",
4771000d1cc1SJoe Perches						    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
4772e09dec48SAndy Whitcroft					} else {
4773000d1cc1SJoe Perches						WARN("INCLUDE_LINUX",
4774000d1cc1SJoe Perches						     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
4775e09dec48SAndy Whitcroft					}
47760a920b5bSAndy Whitcroft				}
47770a920b5bSAndy Whitcroft			}
47780e212e0aSFabian Frederick		}
47790a920b5bSAndy Whitcroft
4780653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the
4781653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed
4782cf655043SAndy Whitcroft# in a known good container
4783b8f96a31SAndy Whitcroft		if ($realfile !~ m@/vmlinux.lds.h$@ &&
4784b8f96a31SAndy Whitcroft		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
4785d8aaf121SAndy Whitcroft			my $ln = $linenr;
4786d8aaf121SAndy Whitcroft			my $cnt = $realcnt;
4787c45dcabdSAndy Whitcroft			my ($off, $dstat, $dcond, $rest);
4788c45dcabdSAndy Whitcroft			my $ctx = '';
478908a2843eSJoe Perches			my $has_flow_statement = 0;
479008a2843eSJoe Perches			my $has_arg_concat = 0;
4791c45dcabdSAndy Whitcroft			($dstat, $dcond, $ln, $cnt, $off) =
4792f74bd194SAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
4793f74bd194SAndy Whitcroft			$ctx = $dstat;
4794c45dcabdSAndy Whitcroft			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
4795a3bb97a7SAndy Whitcroft			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
4796c45dcabdSAndy Whitcroft
479708a2843eSJoe Perches			$has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
479862e15a6dSJoe Perches			$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
479908a2843eSJoe Perches
4800f59b64bfSJoe Perches			$dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
4801f59b64bfSJoe Perches			my $define_args = $1;
4802f59b64bfSJoe Perches			my $define_stmt = $dstat;
4803f59b64bfSJoe Perches			my @def_args = ();
4804f59b64bfSJoe Perches
4805f59b64bfSJoe Perches			if (defined $define_args && $define_args ne "") {
4806f59b64bfSJoe Perches				$define_args = substr($define_args, 1, length($define_args) - 2);
4807f59b64bfSJoe Perches				$define_args =~ s/\s*//g;
4808f59b64bfSJoe Perches				@def_args = split(",", $define_args);
4809f59b64bfSJoe Perches			}
4810f59b64bfSJoe Perches
4811292f1a9bSAndy Whitcroft			$dstat =~ s/$;//g;
4812c45dcabdSAndy Whitcroft			$dstat =~ s/\\\n.//g;
4813c45dcabdSAndy Whitcroft			$dstat =~ s/^\s*//s;
4814c45dcabdSAndy Whitcroft			$dstat =~ s/\s*$//s;
4815c45dcabdSAndy Whitcroft
4816c45dcabdSAndy Whitcroft			# Flatten any parentheses and braces
4817bf30d6edSAndy Whitcroft			while ($dstat =~ s/\([^\(\)]*\)/1/ ||
4818bf30d6edSAndy Whitcroft			       $dstat =~ s/\{[^\{\}]*\}/1/ ||
48196b10df42SVladimir Zapolskiy			       $dstat =~ s/.\[[^\[\]]*\]/1/)
4820bf30d6edSAndy Whitcroft			{
4821c45dcabdSAndy Whitcroft			}
4822c45dcabdSAndy Whitcroft
4823e45bab8eSAndy Whitcroft			# Flatten any obvious string concatentation.
482433acb54aSJoe Perches			while ($dstat =~ s/($String)\s*$Ident/$1/ ||
482533acb54aSJoe Perches			       $dstat =~ s/$Ident\s*($String)/$1/)
4826e45bab8eSAndy Whitcroft			{
4827e45bab8eSAndy Whitcroft			}
4828e45bab8eSAndy Whitcroft
482942e15293SJoe Perches			# Make asm volatile uses seem like a generic function
483042e15293SJoe Perches			$dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
483142e15293SJoe Perches
4832c45dcabdSAndy Whitcroft			my $exceptions = qr{
4833c45dcabdSAndy Whitcroft				$Declare|
4834c45dcabdSAndy Whitcroft				module_param_named|
4835a0a0a7a9SKees Cook				MODULE_PARM_DESC|
4836c45dcabdSAndy Whitcroft				DECLARE_PER_CPU|
4837c45dcabdSAndy Whitcroft				DEFINE_PER_CPU|
4838383099fdSAndy Whitcroft				__typeof__\(|
483922fd2d3eSStefani Seibold				union|
484022fd2d3eSStefani Seibold				struct|
4841ea71a0a0SAndy Whitcroft				\.$Ident\s*=\s*|
48426b10df42SVladimir Zapolskiy				^\"|\"$|
48436b10df42SVladimir Zapolskiy				^\[
4844c45dcabdSAndy Whitcroft			}x;
48455eaa20b9SAndy Whitcroft			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
4846f59b64bfSJoe Perches
4847f59b64bfSJoe Perches			$ctx =~ s/\n*$//;
4848f59b64bfSJoe Perches			my $herectx = $here . "\n";
4849f59b64bfSJoe Perches			my $stmt_cnt = statement_rawlines($ctx);
4850f59b64bfSJoe Perches
4851f59b64bfSJoe Perches			for (my $n = 0; $n < $stmt_cnt; $n++) {
4852f59b64bfSJoe Perches				$herectx .= raw_line($linenr, $n) . "\n";
4853f59b64bfSJoe Perches			}
4854f59b64bfSJoe Perches
4855f74bd194SAndy Whitcroft			if ($dstat ne '' &&
4856f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),
4857f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();
48583cc4b1c3SJoe Perches			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
4859356fd398SJoe Perches			    $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ &&			# character constants
4860f74bd194SAndy Whitcroft			    $dstat !~ /$exceptions/ &&
4861f74bd194SAndy Whitcroft			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
4862e942e2c3SJoe Perches			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #foo
486372f115f9SAndy Whitcroft			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
4864f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
4865f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
4866f74bd194SAndy Whitcroft			    $dstat !~ /^do\s*{/ &&					# do {...
48674e5d56bdSEddie Kovsky			    $dstat !~ /^\(\{/ &&						# ({...
4868f95a7e6aSJoe Perches			    $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
4869c45dcabdSAndy Whitcroft			{
4870e795556aSJoe Perches				if ($dstat =~ /^\s*if\b/) {
4871e795556aSJoe Perches					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
4872e795556aSJoe Perches					      "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
4873e795556aSJoe Perches				} elsif ($dstat =~ /;/) {
4874f74bd194SAndy Whitcroft					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
4875f74bd194SAndy Whitcroft					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
4876f74bd194SAndy Whitcroft				} else {
4877000d1cc1SJoe Perches					ERROR("COMPLEX_MACRO",
4878388982b5SAndrew Morton					      "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
4879d8aaf121SAndy Whitcroft				}
4880f59b64bfSJoe Perches
4881f59b64bfSJoe Perches			}
48825207649bSJoe Perches
48835207649bSJoe Perches			# Make $define_stmt single line, comment-free, etc
48845207649bSJoe Perches			my @stmt_array = split('\n', $define_stmt);
48855207649bSJoe Perches			my $first = 1;
48865207649bSJoe Perches			$define_stmt = "";
48875207649bSJoe Perches			foreach my $l (@stmt_array) {
48885207649bSJoe Perches				$l =~ s/\\$//;
48895207649bSJoe Perches				if ($first) {
48905207649bSJoe Perches					$define_stmt = $l;
48915207649bSJoe Perches					$first = 0;
48925207649bSJoe Perches				} elsif ($l =~ /^[\+ ]/) {
48935207649bSJoe Perches					$define_stmt .= substr($l, 1);
48945207649bSJoe Perches				}
48955207649bSJoe Perches			}
48965207649bSJoe Perches			$define_stmt =~ s/$;//g;
48975207649bSJoe Perches			$define_stmt =~ s/\s+/ /g;
48985207649bSJoe Perches			$define_stmt = trim($define_stmt);
48995207649bSJoe Perches
4900f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type')
4901f59b64bfSJoe Perches			foreach my $arg (@def_args) {
4902f59b64bfSJoe Perches			        next if ($arg =~ /\.\.\./);
49039192d41aSJoe Perches			        next if ($arg =~ /^type$/i);
4904f59b64bfSJoe Perches				my $tmp = $define_stmt;
4905f59b64bfSJoe Perches				$tmp =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
49065207649bSJoe Perches				$tmp =~ s/\#+\s*$arg\b//g;
4907f59b64bfSJoe Perches				$tmp =~ s/\b$arg\s*\#\#//g;
4908f59b64bfSJoe Perches				my $use_cnt = $tmp =~ s/\b$arg\b//g;
4909f59b64bfSJoe Perches				if ($use_cnt > 1) {
4910f59b64bfSJoe Perches					CHK("MACRO_ARG_REUSE",
4911f59b64bfSJoe Perches					    "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
4912f59b64bfSJoe Perches				    }
49139192d41aSJoe Perches# check if any macro arguments may have other precedence issues
49149192d41aSJoe Perches				if ($define_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
49159192d41aSJoe Perches				    ((defined($1) && $1 ne ',') ||
49169192d41aSJoe Perches				     (defined($2) && $2 ne ','))) {
49179192d41aSJoe Perches					CHK("MACRO_ARG_PRECEDENCE",
49189192d41aSJoe Perches					    "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
49199192d41aSJoe Perches				}
49200a920b5bSAndy Whitcroft			}
49215023d347SJoe Perches
492208a2843eSJoe Perches# check for macros with flow control, but without ## concatenation
492308a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those
492408a2843eSJoe Perches			if ($has_flow_statement && !$has_arg_concat) {
492508a2843eSJoe Perches				my $herectx = $here . "\n";
492608a2843eSJoe Perches				my $cnt = statement_rawlines($ctx);
492708a2843eSJoe Perches
492808a2843eSJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
492908a2843eSJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
493008a2843eSJoe Perches				}
493108a2843eSJoe Perches				WARN("MACRO_WITH_FLOW_CONTROL",
493208a2843eSJoe Perches				     "Macros with flow control statements should be avoided\n" . "$herectx");
493308a2843eSJoe Perches			}
493408a2843eSJoe Perches
4935481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm
49365023d347SJoe Perches
49375023d347SJoe Perches		} else {
49385023d347SJoe Perches			if ($prevline !~ /^..*\\$/ &&
4939481eb486SJoe Perches			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
4940481eb486SJoe Perches			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
49415023d347SJoe Perches			    $line =~ /^\+.*\\$/) {
49425023d347SJoe Perches				WARN("LINE_CONTINUATIONS",
49435023d347SJoe Perches				     "Avoid unnecessary line continuations\n" . $herecurr);
49445023d347SJoe Perches			}
4945653d4876SAndy Whitcroft		}
49460a920b5bSAndy Whitcroft
4947b13edf7fSJoe Perches# do {} while (0) macro tests:
4948b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop,
4949b13edf7fSJoe Perches# macro should not end with a semicolon
4950b13edf7fSJoe Perches		if ($^V && $^V ge 5.10.0 &&
4951b13edf7fSJoe Perches		    $realfile !~ m@/vmlinux.lds.h$@ &&
4952b13edf7fSJoe Perches		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
4953b13edf7fSJoe Perches			my $ln = $linenr;
4954b13edf7fSJoe Perches			my $cnt = $realcnt;
4955b13edf7fSJoe Perches			my ($off, $dstat, $dcond, $rest);
4956b13edf7fSJoe Perches			my $ctx = '';
4957b13edf7fSJoe Perches			($dstat, $dcond, $ln, $cnt, $off) =
4958b13edf7fSJoe Perches				ctx_statement_block($linenr, $realcnt, 0);
4959b13edf7fSJoe Perches			$ctx = $dstat;
4960b13edf7fSJoe Perches
4961b13edf7fSJoe Perches			$dstat =~ s/\\\n.//g;
49621b36b201SJoe Perches			$dstat =~ s/$;/ /g;
4963b13edf7fSJoe Perches
4964b13edf7fSJoe Perches			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
4965b13edf7fSJoe Perches				my $stmts = $2;
4966b13edf7fSJoe Perches				my $semis = $3;
4967b13edf7fSJoe Perches
4968b13edf7fSJoe Perches				$ctx =~ s/\n*$//;
4969b13edf7fSJoe Perches				my $cnt = statement_rawlines($ctx);
4970b13edf7fSJoe Perches				my $herectx = $here . "\n";
4971b13edf7fSJoe Perches
4972b13edf7fSJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
4973b13edf7fSJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
4974b13edf7fSJoe Perches				}
4975b13edf7fSJoe Perches
4976ac8e97f8SJoe Perches				if (($stmts =~ tr/;/;/) == 1 &&
4977ac8e97f8SJoe Perches				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
4978b13edf7fSJoe Perches					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
4979b13edf7fSJoe Perches					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
4980b13edf7fSJoe Perches				}
4981b13edf7fSJoe Perches				if (defined $semis && $semis ne "") {
4982b13edf7fSJoe Perches					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
4983b13edf7fSJoe Perches					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
4984b13edf7fSJoe Perches				}
4985f5ef95b1SJoe Perches			} elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
4986f5ef95b1SJoe Perches				$ctx =~ s/\n*$//;
4987f5ef95b1SJoe Perches				my $cnt = statement_rawlines($ctx);
4988f5ef95b1SJoe Perches				my $herectx = $here . "\n";
4989f5ef95b1SJoe Perches
4990f5ef95b1SJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
4991f5ef95b1SJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
4992f5ef95b1SJoe Perches				}
4993f5ef95b1SJoe Perches
4994f5ef95b1SJoe Perches				WARN("TRAILING_SEMICOLON",
4995f5ef95b1SJoe Perches				     "macros should not use a trailing semicolon\n" . "$herectx");
4996b13edf7fSJoe Perches			}
4997b13edf7fSJoe Perches		}
4998b13edf7fSJoe Perches
4999080ba929SMike Frysinger# make sure symbols are always wrapped with VMLINUX_SYMBOL() ...
5000080ba929SMike Frysinger# all assignments may have only one of the following with an assignment:
5001080ba929SMike Frysinger#	.
5002080ba929SMike Frysinger#	ALIGN(...)
5003080ba929SMike Frysinger#	VMLINUX_SYMBOL(...)
5004080ba929SMike Frysinger		if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) {
5005000d1cc1SJoe Perches			WARN("MISSING_VMLINUX_SYMBOL",
5006000d1cc1SJoe Perches			     "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr);
5007080ba929SMike Frysinger		}
5008080ba929SMike Frysinger
5009f0a594c1SAndy Whitcroft# check for redundant bracing round if etc
501013214adfSAndy Whitcroft		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
501113214adfSAndy Whitcroft			my ($level, $endln, @chunks) =
5012cf655043SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, 1);
501313214adfSAndy Whitcroft			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
5014cf655043SAndy Whitcroft			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
5015cf655043SAndy Whitcroft			if ($#chunks > 0 && $level == 0) {
5016aad4f614SJoe Perches				my @allowed = ();
5017aad4f614SJoe Perches				my $allow = 0;
501813214adfSAndy Whitcroft				my $seen = 0;
5019773647a0SAndy Whitcroft				my $herectx = $here . "\n";
5020cf655043SAndy Whitcroft				my $ln = $linenr - 1;
502113214adfSAndy Whitcroft				for my $chunk (@chunks) {
502213214adfSAndy Whitcroft					my ($cond, $block) = @{$chunk};
502313214adfSAndy Whitcroft
5024773647a0SAndy Whitcroft					# If the condition carries leading newlines, then count those as offsets.
5025773647a0SAndy Whitcroft					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
5026773647a0SAndy Whitcroft					my $offset = statement_rawlines($whitespace) - 1;
5027773647a0SAndy Whitcroft
5028aad4f614SJoe Perches					$allowed[$allow] = 0;
5029773647a0SAndy Whitcroft					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
5030773647a0SAndy Whitcroft
5031773647a0SAndy Whitcroft					# We have looked at and allowed this specific line.
5032773647a0SAndy Whitcroft					$suppress_ifbraces{$ln + $offset} = 1;
5033773647a0SAndy Whitcroft
5034773647a0SAndy Whitcroft					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
5035cf655043SAndy Whitcroft					$ln += statement_rawlines($block) - 1;
5036cf655043SAndy Whitcroft
5037773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
503813214adfSAndy Whitcroft
503913214adfSAndy Whitcroft					$seen++ if ($block =~ /^\s*{/);
504013214adfSAndy Whitcroft
5041aad4f614SJoe Perches					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
5042cf655043SAndy Whitcroft					if (statement_lines($cond) > 1) {
5043cf655043SAndy Whitcroft						#print "APW: ALLOWED: cond<$cond>\n";
5044aad4f614SJoe Perches						$allowed[$allow] = 1;
504513214adfSAndy Whitcroft					}
504613214adfSAndy Whitcroft					if ($block =~/\b(?:if|for|while)\b/) {
5047cf655043SAndy Whitcroft						#print "APW: ALLOWED: block<$block>\n";
5048aad4f614SJoe Perches						$allowed[$allow] = 1;
504913214adfSAndy Whitcroft					}
5050cf655043SAndy Whitcroft					if (statement_block_size($block) > 1) {
5051cf655043SAndy Whitcroft						#print "APW: ALLOWED: lines block<$block>\n";
5052aad4f614SJoe Perches						$allowed[$allow] = 1;
505313214adfSAndy Whitcroft					}
5054aad4f614SJoe Perches					$allow++;
505513214adfSAndy Whitcroft				}
5056aad4f614SJoe Perches				if ($seen) {
5057aad4f614SJoe Perches					my $sum_allowed = 0;
5058aad4f614SJoe Perches					foreach (@allowed) {
5059aad4f614SJoe Perches						$sum_allowed += $_;
5060aad4f614SJoe Perches					}
5061aad4f614SJoe Perches					if ($sum_allowed == 0) {
5062000d1cc1SJoe Perches						WARN("BRACES",
5063000d1cc1SJoe Perches						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
5064aad4f614SJoe Perches					} elsif ($sum_allowed != $allow &&
5065aad4f614SJoe Perches						 $seen != $allow) {
5066aad4f614SJoe Perches						CHK("BRACES",
5067aad4f614SJoe Perches						    "braces {} should be used on all arms of this statement\n" . $herectx);
5068aad4f614SJoe Perches					}
506913214adfSAndy Whitcroft				}
507013214adfSAndy Whitcroft			}
507113214adfSAndy Whitcroft		}
5072773647a0SAndy Whitcroft		if (!defined $suppress_ifbraces{$linenr - 1} &&
507313214adfSAndy Whitcroft					$line =~ /\b(if|while|for|else)\b/) {
5074cf655043SAndy Whitcroft			my $allowed = 0;
5075f0a594c1SAndy Whitcroft
5076cf655043SAndy Whitcroft			# Check the pre-context.
5077cf655043SAndy Whitcroft			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
5078cf655043SAndy Whitcroft				#print "APW: ALLOWED: pre<$1>\n";
5079cf655043SAndy Whitcroft				$allowed = 1;
5080f0a594c1SAndy Whitcroft			}
5081773647a0SAndy Whitcroft
5082773647a0SAndy Whitcroft			my ($level, $endln, @chunks) =
5083773647a0SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, $-[0]);
5084773647a0SAndy Whitcroft
5085cf655043SAndy Whitcroft			# Check the condition.
5086cf655043SAndy Whitcroft			my ($cond, $block) = @{$chunks[0]};
5087773647a0SAndy Whitcroft			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
5088cf655043SAndy Whitcroft			if (defined $cond) {
5089773647a0SAndy Whitcroft				substr($block, 0, length($cond), '');
5090cf655043SAndy Whitcroft			}
5091cf655043SAndy Whitcroft			if (statement_lines($cond) > 1) {
5092cf655043SAndy Whitcroft				#print "APW: ALLOWED: cond<$cond>\n";
5093cf655043SAndy Whitcroft				$allowed = 1;
5094cf655043SAndy Whitcroft			}
5095cf655043SAndy Whitcroft			if ($block =~/\b(?:if|for|while)\b/) {
5096cf655043SAndy Whitcroft				#print "APW: ALLOWED: block<$block>\n";
5097cf655043SAndy Whitcroft				$allowed = 1;
5098cf655043SAndy Whitcroft			}
5099cf655043SAndy Whitcroft			if (statement_block_size($block) > 1) {
5100cf655043SAndy Whitcroft				#print "APW: ALLOWED: lines block<$block>\n";
5101cf655043SAndy Whitcroft				$allowed = 1;
5102cf655043SAndy Whitcroft			}
5103cf655043SAndy Whitcroft			# Check the post-context.
5104cf655043SAndy Whitcroft			if (defined $chunks[1]) {
5105cf655043SAndy Whitcroft				my ($cond, $block) = @{$chunks[1]};
5106cf655043SAndy Whitcroft				if (defined $cond) {
5107773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
5108cf655043SAndy Whitcroft				}
5109cf655043SAndy Whitcroft				if ($block =~ /^\s*\{/) {
5110cf655043SAndy Whitcroft					#print "APW: ALLOWED: chunk-1 block<$block>\n";
5111cf655043SAndy Whitcroft					$allowed = 1;
5112cf655043SAndy Whitcroft				}
5113cf655043SAndy Whitcroft			}
5114cf655043SAndy Whitcroft			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
511569932487SJustin P. Mattock				my $herectx = $here . "\n";
5116f055663cSAndy Whitcroft				my $cnt = statement_rawlines($block);
5117cf655043SAndy Whitcroft
5118f055663cSAndy Whitcroft				for (my $n = 0; $n < $cnt; $n++) {
511969932487SJustin P. Mattock					$herectx .= raw_line($linenr, $n) . "\n";
5120cf655043SAndy Whitcroft				}
5121cf655043SAndy Whitcroft
5122000d1cc1SJoe Perches				WARN("BRACES",
5123000d1cc1SJoe Perches				     "braces {} are not necessary for single statement blocks\n" . $herectx);
5124f0a594c1SAndy Whitcroft			}
5125f0a594c1SAndy Whitcroft		}
5126f0a594c1SAndy Whitcroft
5127e4c5babdSJoe Perches# check for single line unbalanced braces
512895330473SSven Eckelmann		if ($sline =~ /^.\s*\}\s*else\s*$/ ||
512995330473SSven Eckelmann		    $sline =~ /^.\s*else\s*\{\s*$/) {
5130e4c5babdSJoe Perches			CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
5131e4c5babdSJoe Perches		}
5132e4c5babdSJoe Perches
51330979ae66SJoe Perches# check for unnecessary blank lines around braces
513477b9a53aSJoe Perches		if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
5135f8e58219SJoe Perches			if (CHK("BRACES",
5136f8e58219SJoe Perches				"Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
5137f8e58219SJoe Perches			    $fix && $prevrawline =~ /^\+/) {
5138f8e58219SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
5139f8e58219SJoe Perches			}
51400979ae66SJoe Perches		}
514177b9a53aSJoe Perches		if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
5142f8e58219SJoe Perches			if (CHK("BRACES",
5143f8e58219SJoe Perches				"Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
5144f8e58219SJoe Perches			    $fix) {
5145f8e58219SJoe Perches				fix_delete_line($fixlinenr, $rawline);
5146f8e58219SJoe Perches			}
51470979ae66SJoe Perches		}
51480979ae66SJoe Perches
51494a0df2efSAndy Whitcroft# no volatiles please
51506c72ffaaSAndy Whitcroft		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
51516c72ffaaSAndy Whitcroft		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
5152000d1cc1SJoe Perches			WARN("VOLATILE",
51538c27ceffSMauro Carvalho Chehab			     "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
51544a0df2efSAndy Whitcroft		}
51554a0df2efSAndy Whitcroft
51565e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability
51575e4f6ba5SJoe Perches# to grep for the string.  Make exceptions when the previous string ends in a
51585e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
51595e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
516033acb54aSJoe Perches		if ($line =~ /^\+\s*$String/ &&
51615e4f6ba5SJoe Perches		    $prevline =~ /"\s*$/ &&
51625e4f6ba5SJoe Perches		    $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
51635e4f6ba5SJoe Perches			if (WARN("SPLIT_STRING",
51645e4f6ba5SJoe Perches				 "quoted string split across lines\n" . $hereprev) &&
51655e4f6ba5SJoe Perches				     $fix &&
51665e4f6ba5SJoe Perches				     $prevrawline =~ /^\+.*"\s*$/ &&
51675e4f6ba5SJoe Perches				     $last_coalesced_string_linenr != $linenr - 1) {
51685e4f6ba5SJoe Perches				my $extracted_string = get_quoted_string($line, $rawline);
51695e4f6ba5SJoe Perches				my $comma_close = "";
51705e4f6ba5SJoe Perches				if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
51715e4f6ba5SJoe Perches					$comma_close = $1;
51725e4f6ba5SJoe Perches				}
51735e4f6ba5SJoe Perches
51745e4f6ba5SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
51755e4f6ba5SJoe Perches				fix_delete_line($fixlinenr, $rawline);
51765e4f6ba5SJoe Perches				my $fixedline = $prevrawline;
51775e4f6ba5SJoe Perches				$fixedline =~ s/"\s*$//;
51785e4f6ba5SJoe Perches				$fixedline .= substr($extracted_string, 1) . trim($comma_close);
51795e4f6ba5SJoe Perches				fix_insert_line($fixlinenr - 1, $fixedline);
51805e4f6ba5SJoe Perches				$fixedline = $rawline;
51815e4f6ba5SJoe Perches				$fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
51825e4f6ba5SJoe Perches				if ($fixedline !~ /\+\s*$/) {
51835e4f6ba5SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
51845e4f6ba5SJoe Perches				}
51855e4f6ba5SJoe Perches				$last_coalesced_string_linenr = $linenr;
51865e4f6ba5SJoe Perches			}
51875e4f6ba5SJoe Perches		}
51885e4f6ba5SJoe Perches
51895e4f6ba5SJoe Perches# check for missing a space in a string concatenation
51905e4f6ba5SJoe Perches		if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
51915e4f6ba5SJoe Perches			WARN('MISSING_SPACE',
51925e4f6ba5SJoe Perches			     "break quoted strings at a space character\n" . $hereprev);
51935e4f6ba5SJoe Perches		}
51945e4f6ba5SJoe Perches
519577cb8546SJoe Perches# check for an embedded function name in a string when the function is known
5196e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch
5197e4b7d309SJoe Perches# context providing the function name or a single line form for in-file
5198e4b7d309SJoe Perches# function declarations
519977cb8546SJoe Perches		if ($line =~ /^\+.*$String/ &&
520077cb8546SJoe Perches		    defined($context_function) &&
5201e4b7d309SJoe Perches		    get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
5202e4b7d309SJoe Perches		    length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
520377cb8546SJoe Perches			WARN("EMBEDDED_FUNCTION_NAME",
5204e4b7d309SJoe Perches			     "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
520577cb8546SJoe Perches		}
520677cb8546SJoe Perches
52075e4f6ba5SJoe Perches# check for spaces before a quoted newline
52085e4f6ba5SJoe Perches		if ($rawline =~ /^.*\".*\s\\n/) {
52095e4f6ba5SJoe Perches			if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
52105e4f6ba5SJoe Perches				 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
52115e4f6ba5SJoe Perches			    $fix) {
52125e4f6ba5SJoe Perches				$fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
52135e4f6ba5SJoe Perches			}
52145e4f6ba5SJoe Perches
52155e4f6ba5SJoe Perches		}
52165e4f6ba5SJoe Perches
5217f17dba4fSJoe Perches# concatenated string without spaces between elements
521833acb54aSJoe Perches		if ($line =~ /$String[A-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) {
5219f17dba4fSJoe Perches			CHK("CONCATENATED_STRING",
5220f17dba4fSJoe Perches			    "Concatenated strings should use spaces between elements\n" . $herecurr);
5221f17dba4fSJoe Perches		}
5222f17dba4fSJoe Perches
522390ad30e5SJoe Perches# uncoalesced string fragments
522433acb54aSJoe Perches		if ($line =~ /$String\s*"/) {
522590ad30e5SJoe Perches			WARN("STRING_FRAGMENTS",
522690ad30e5SJoe Perches			     "Consecutive strings are generally better as a single string\n" . $herecurr);
522790ad30e5SJoe Perches		}
522890ad30e5SJoe Perches
5229522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats
5230522b837cSAlexey Dobriyan		my $show_L = 1;	#don't show the same defect twice
5231522b837cSAlexey Dobriyan		my $show_Z = 1;
52325e4f6ba5SJoe Perches		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
5233522b837cSAlexey Dobriyan			my $string = substr($rawline, $-[1], $+[1] - $-[1]);
52345e4f6ba5SJoe Perches			$string =~ s/%%/__/g;
5235522b837cSAlexey Dobriyan			# check for %L
5236522b837cSAlexey Dobriyan			if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
52375e4f6ba5SJoe Perches				WARN("PRINTF_L",
5238522b837cSAlexey Dobriyan				     "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
5239522b837cSAlexey Dobriyan				$show_L = 0;
52405e4f6ba5SJoe Perches			}
5241522b837cSAlexey Dobriyan			# check for %Z
5242522b837cSAlexey Dobriyan			if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
5243522b837cSAlexey Dobriyan				WARN("PRINTF_Z",
5244522b837cSAlexey Dobriyan				     "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
5245522b837cSAlexey Dobriyan				$show_Z = 0;
5246522b837cSAlexey Dobriyan			}
5247522b837cSAlexey Dobriyan			# check for 0x<decimal>
5248522b837cSAlexey Dobriyan			if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
5249522b837cSAlexey Dobriyan				ERROR("PRINTF_0XDECIMAL",
52506e300757SJoe Perches				      "Prefixing 0x with decimal output is defective\n" . $herecurr);
52516e300757SJoe Perches			}
52525e4f6ba5SJoe Perches		}
52535e4f6ba5SJoe Perches
52545e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of "
52555e4f6ba5SJoe Perches		if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) {
52565e4f6ba5SJoe Perches			WARN("LINE_CONTINUATIONS",
52575e4f6ba5SJoe Perches			     "Avoid line continuations in quoted strings\n" . $herecurr);
52585e4f6ba5SJoe Perches		}
52595e4f6ba5SJoe Perches
526000df344fSAndy Whitcroft# warn about #if 0
5261c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
5262000d1cc1SJoe Perches			CHK("REDUNDANT_CODE",
5263000d1cc1SJoe Perches			    "if this code is redundant consider removing it\n" .
5264de7d4f0eSAndy Whitcroft				$herecurr);
52654a0df2efSAndy Whitcroft		}
52664a0df2efSAndy Whitcroft
526703df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses
526803df4b51SAndy Whitcroft		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
5269100425deSJoe Perches			my $tested = quotemeta($1);
5270100425deSJoe Perches			my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
5271100425deSJoe Perches			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
5272100425deSJoe Perches				my $func = $1;
5273100425deSJoe Perches				if (WARN('NEEDLESS_IF',
5274100425deSJoe Perches					 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
5275100425deSJoe Perches				    $fix) {
5276100425deSJoe Perches					my $do_fix = 1;
5277100425deSJoe Perches					my $leading_tabs = "";
5278100425deSJoe Perches					my $new_leading_tabs = "";
5279100425deSJoe Perches					if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
5280100425deSJoe Perches						$leading_tabs = $1;
5281100425deSJoe Perches					} else {
5282100425deSJoe Perches						$do_fix = 0;
5283100425deSJoe Perches					}
5284100425deSJoe Perches					if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
5285100425deSJoe Perches						$new_leading_tabs = $1;
5286100425deSJoe Perches						if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
5287100425deSJoe Perches							$do_fix = 0;
5288100425deSJoe Perches						}
5289100425deSJoe Perches					} else {
5290100425deSJoe Perches						$do_fix = 0;
5291100425deSJoe Perches					}
5292100425deSJoe Perches					if ($do_fix) {
5293100425deSJoe Perches						fix_delete_line($fixlinenr - 1, $prevrawline);
5294100425deSJoe Perches						$fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
5295100425deSJoe Perches					}
5296100425deSJoe Perches				}
52974c432a8fSGreg Kroah-Hartman			}
52984c432a8fSGreg Kroah-Hartman		}
5299f0a594c1SAndy Whitcroft
5300ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages
5301ebfdc409SJoe Perches		if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
5302ebfdc409SJoe Perches		    $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
5303ebfdc409SJoe Perches		    (defined $1 || defined $3) &&
5304ebfdc409SJoe Perches		    $linenr > 3) {
5305ebfdc409SJoe Perches			my $testval = $2;
5306ebfdc409SJoe Perches			my $testline = $lines[$linenr - 3];
5307ebfdc409SJoe Perches
5308ebfdc409SJoe Perches			my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
5309ebfdc409SJoe Perches#			print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
5310ebfdc409SJoe Perches
5311ebfdc409SJoe Perches			if ($c =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|(?:dev_)?alloc_skb)/) {
5312ebfdc409SJoe Perches				WARN("OOM_MESSAGE",
5313ebfdc409SJoe Perches				     "Possible unnecessary 'out of memory' message\n" . $hereprev);
5314ebfdc409SJoe Perches			}
5315ebfdc409SJoe Perches		}
5316ebfdc409SJoe Perches
5317f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL>
5318dcaf1123SPaolo Bonzini		if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
5319f78d98f6SJoe Perches		    $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
5320f78d98f6SJoe Perches			my $level = $1;
5321f78d98f6SJoe Perches			if (WARN("UNNECESSARY_KERN_LEVEL",
5322f78d98f6SJoe Perches				 "Possible unnecessary $level\n" . $herecurr) &&
5323f78d98f6SJoe Perches			    $fix) {
5324f78d98f6SJoe Perches				$fixed[$fixlinenr] =~ s/\s*$level\s*//;
5325f78d98f6SJoe Perches			}
5326f78d98f6SJoe Perches		}
5327f78d98f6SJoe Perches
532845c55e92SJoe Perches# check for logging continuations
532945c55e92SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
533045c55e92SJoe Perches			WARN("LOGGING_CONTINUATION",
533145c55e92SJoe Perches			     "Avoid logging continuation uses where feasible\n" . $herecurr);
533245c55e92SJoe Perches		}
533345c55e92SJoe Perches
5334abb08a53SJoe Perches# check for mask then right shift without a parentheses
5335abb08a53SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5336abb08a53SJoe Perches		    $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
5337abb08a53SJoe Perches		    $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
5338abb08a53SJoe Perches			WARN("MASK_THEN_SHIFT",
5339abb08a53SJoe Perches			     "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
5340abb08a53SJoe Perches		}
5341abb08a53SJoe Perches
5342b75ac618SJoe Perches# check for pointer comparisons to NULL
5343b75ac618SJoe Perches		if ($^V && $^V ge 5.10.0) {
5344b75ac618SJoe Perches			while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
5345b75ac618SJoe Perches				my $val = $1;
5346b75ac618SJoe Perches				my $equal = "!";
5347b75ac618SJoe Perches				$equal = "" if ($4 eq "!=");
5348b75ac618SJoe Perches				if (CHK("COMPARISON_TO_NULL",
5349b75ac618SJoe Perches					"Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
5350b75ac618SJoe Perches					    $fix) {
5351b75ac618SJoe Perches					$fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
5352b75ac618SJoe Perches				}
5353b75ac618SJoe Perches			}
5354b75ac618SJoe Perches		}
5355b75ac618SJoe Perches
53568716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata)
53578716de38SJoe Perches		if ($line =~ /(\b$InitAttribute\b)/) {
53588716de38SJoe Perches			my $attr = $1;
53598716de38SJoe Perches			if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
53608716de38SJoe Perches				my $ptr = $1;
53618716de38SJoe Perches				my $var = $2;
53628716de38SJoe Perches				if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
53638716de38SJoe Perches				      ERROR("MISPLACED_INIT",
53648716de38SJoe Perches					    "$attr should be placed after $var\n" . $herecurr)) ||
53658716de38SJoe Perches				     ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
53668716de38SJoe Perches				      WARN("MISPLACED_INIT",
53678716de38SJoe Perches					   "$attr should be placed after $var\n" . $herecurr))) &&
53688716de38SJoe Perches				    $fix) {
5369194f66fcSJoe 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;
53708716de38SJoe Perches				}
53718716de38SJoe Perches			}
53728716de38SJoe Perches		}
53738716de38SJoe Perches
5374e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const
5375e970b884SJoe Perches		if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
5376e970b884SJoe Perches			my $attr = $1;
5377e970b884SJoe Perches			$attr =~ /($InitAttributePrefix)(.*)/;
5378e970b884SJoe Perches			my $attr_prefix = $1;
5379e970b884SJoe Perches			my $attr_type = $2;
5380e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
5381e970b884SJoe Perches				  "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
5382e970b884SJoe Perches			    $fix) {
5383194f66fcSJoe Perches				$fixed[$fixlinenr] =~
5384e970b884SJoe Perches				    s/$InitAttributeData/${attr_prefix}initconst/;
5385e970b884SJoe Perches			}
5386e970b884SJoe Perches		}
5387e970b884SJoe Perches
5388e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const
5389e970b884SJoe Perches		if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
5390e970b884SJoe Perches			my $attr = $1;
5391e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
5392e970b884SJoe Perches				  "Use of $attr requires a separate use of const\n" . $herecurr) &&
5393e970b884SJoe Perches			    $fix) {
5394194f66fcSJoe Perches				my $lead = $fixed[$fixlinenr] =~
5395e970b884SJoe Perches				    /(^\+\s*(?:static\s+))/;
5396e970b884SJoe Perches				$lead = rtrim($1);
5397e970b884SJoe Perches				$lead = "$lead " if ($lead !~ /^\+$/);
5398e970b884SJoe Perches				$lead = "${lead}const ";
5399194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
5400e970b884SJoe Perches			}
5401e970b884SJoe Perches		}
5402e970b884SJoe Perches
5403c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const)
5404c17893c7SJoe Perches		if ($line =~ /\b__read_mostly\b/ &&
5405c17893c7SJoe Perches		    $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
5406c17893c7SJoe Perches			if (ERROR("CONST_READ_MOSTLY",
5407c17893c7SJoe Perches				  "Invalid use of __read_mostly with const type\n" . $herecurr) &&
5408c17893c7SJoe Perches			    $fix) {
5409c17893c7SJoe Perches				$fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
5410c17893c7SJoe Perches			}
5411c17893c7SJoe Perches		}
5412c17893c7SJoe Perches
5413fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/
5414fbdb8138SJoe Perches		if ($realfile !~ m@^include/uapi/@ &&
5415fbdb8138SJoe Perches		    $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
5416fbdb8138SJoe Perches			my $constant_func = $1;
5417fbdb8138SJoe Perches			my $func = $constant_func;
5418fbdb8138SJoe Perches			$func =~ s/^__constant_//;
5419fbdb8138SJoe Perches			if (WARN("CONSTANT_CONVERSION",
5420fbdb8138SJoe Perches				 "$constant_func should be $func\n" . $herecurr) &&
5421fbdb8138SJoe Perches			    $fix) {
5422194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
5423fbdb8138SJoe Perches			}
5424fbdb8138SJoe Perches		}
5425fbdb8138SJoe Perches
54261a15a250SPatrick Pannuto# prefer usleep_range over udelay
542737581c28SBruce Allan		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
542843c1d77cSJoe Perches			my $delay = $1;
54291a15a250SPatrick Pannuto			# ignore udelay's < 10, however
543043c1d77cSJoe Perches			if (! ($delay < 10) ) {
5431000d1cc1SJoe Perches				CHK("USLEEP_RANGE",
543243c1d77cSJoe Perches				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr);
543343c1d77cSJoe Perches			}
543443c1d77cSJoe Perches			if ($delay > 2000) {
543543c1d77cSJoe Perches				WARN("LONG_UDELAY",
543643c1d77cSJoe Perches				     "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
54371a15a250SPatrick Pannuto			}
54381a15a250SPatrick Pannuto		}
54391a15a250SPatrick Pannuto
544009ef8725SPatrick Pannuto# warn about unexpectedly long msleep's
544109ef8725SPatrick Pannuto		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
544209ef8725SPatrick Pannuto			if ($1 < 20) {
5443000d1cc1SJoe Perches				WARN("MSLEEP",
544443c1d77cSJoe Perches				     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr);
544509ef8725SPatrick Pannuto			}
544609ef8725SPatrick Pannuto		}
544709ef8725SPatrick Pannuto
544836ec1939SJoe Perches# check for comparisons of jiffies
544936ec1939SJoe Perches		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
545036ec1939SJoe Perches			WARN("JIFFIES_COMPARISON",
545136ec1939SJoe Perches			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
545236ec1939SJoe Perches		}
545336ec1939SJoe Perches
54549d7a34a5SJoe Perches# check for comparisons of get_jiffies_64()
54559d7a34a5SJoe Perches		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
54569d7a34a5SJoe Perches			WARN("JIFFIES_COMPARISON",
54579d7a34a5SJoe Perches			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
54589d7a34a5SJoe Perches		}
54599d7a34a5SJoe Perches
546000df344fSAndy Whitcroft# warn about #ifdefs in C files
5461c45dcabdSAndy Whitcroft#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
546200df344fSAndy Whitcroft#			print "#ifdef in C files should be avoided\n";
546300df344fSAndy Whitcroft#			print "$herecurr";
546400df344fSAndy Whitcroft#			$clean = 0;
546500df344fSAndy Whitcroft#		}
546600df344fSAndy Whitcroft
546722f2a2efSAndy Whitcroft# warn about spacing in #ifdefs
5468c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
54693705ce5bSJoe Perches			if (ERROR("SPACING",
54703705ce5bSJoe Perches				  "exactly one space required after that #$1\n" . $herecurr) &&
54713705ce5bSJoe Perches			    $fix) {
5472194f66fcSJoe Perches				$fixed[$fixlinenr] =~
54733705ce5bSJoe Perches				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
54743705ce5bSJoe Perches			}
54753705ce5bSJoe Perches
547622f2a2efSAndy Whitcroft		}
547722f2a2efSAndy Whitcroft
54784a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment.
5479171ae1a4SAndy Whitcroft		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
5480171ae1a4SAndy Whitcroft		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
54814a0df2efSAndy Whitcroft			my $which = $1;
54824a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
5483000d1cc1SJoe Perches				CHK("UNCOMMENTED_DEFINITION",
5484000d1cc1SJoe Perches				    "$1 definition without comment\n" . $herecurr);
54854a0df2efSAndy Whitcroft			}
54864a0df2efSAndy Whitcroft		}
54874a0df2efSAndy Whitcroft# check for memory barriers without a comment.
5488402c2553SMichael S. Tsirkin
5489402c2553SMichael S. Tsirkin		my $barriers = qr{
5490402c2553SMichael S. Tsirkin			mb|
5491402c2553SMichael S. Tsirkin			rmb|
5492402c2553SMichael S. Tsirkin			wmb|
5493402c2553SMichael S. Tsirkin			read_barrier_depends
5494402c2553SMichael S. Tsirkin		}x;
5495402c2553SMichael S. Tsirkin		my $barrier_stems = qr{
5496402c2553SMichael S. Tsirkin			mb__before_atomic|
5497402c2553SMichael S. Tsirkin			mb__after_atomic|
5498402c2553SMichael S. Tsirkin			store_release|
5499402c2553SMichael S. Tsirkin			load_acquire|
5500402c2553SMichael S. Tsirkin			store_mb|
5501402c2553SMichael S. Tsirkin			(?:$barriers)
5502402c2553SMichael S. Tsirkin		}x;
5503402c2553SMichael S. Tsirkin		my $all_barriers = qr{
5504402c2553SMichael S. Tsirkin			(?:$barriers)|
550543e361f2SMichael S. Tsirkin			smp_(?:$barrier_stems)|
550643e361f2SMichael S. Tsirkin			virt_(?:$barrier_stems)
5507402c2553SMichael S. Tsirkin		}x;
5508402c2553SMichael S. Tsirkin
5509402c2553SMichael S. Tsirkin		if ($line =~ /\b(?:$all_barriers)\s*\(/) {
55104a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
5511c1fd7bb9SJoe Perches				WARN("MEMORY_BARRIER",
5512000d1cc1SJoe Perches				     "memory barrier without comment\n" . $herecurr);
55134a0df2efSAndy Whitcroft			}
55144a0df2efSAndy Whitcroft		}
55153ad81779SPaul E. McKenney
5516f4073b0fSMichael S. Tsirkin		my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
5517f4073b0fSMichael S. Tsirkin
5518f4073b0fSMichael S. Tsirkin		if ($realfile !~ m@^include/asm-generic/@ &&
5519f4073b0fSMichael S. Tsirkin		    $realfile !~ m@/barrier\.h$@ &&
5520f4073b0fSMichael S. Tsirkin		    $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
5521f4073b0fSMichael S. Tsirkin		    $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
5522f4073b0fSMichael S. Tsirkin			WARN("MEMORY_BARRIER",
5523f4073b0fSMichael S. Tsirkin			     "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
5524f4073b0fSMichael S. Tsirkin		}
5525f4073b0fSMichael S. Tsirkin
5526cb426e99SJoe Perches# check for waitqueue_active without a comment.
5527cb426e99SJoe Perches		if ($line =~ /\bwaitqueue_active\s*\(/) {
5528cb426e99SJoe Perches			if (!ctx_has_comment($first_line, $linenr)) {
5529cb426e99SJoe Perches				WARN("WAITQUEUE_ACTIVE",
5530cb426e99SJoe Perches				     "waitqueue_active without comment\n" . $herecurr);
5531cb426e99SJoe Perches			}
5532cb426e99SJoe Perches		}
55333ad81779SPaul E. McKenney
55343ad81779SPaul E. McKenney# Check for expedited grace periods that interrupt non-idle non-nohz
55353ad81779SPaul E. McKenney# online CPUs.  These expedited can therefore degrade real-time response
55363ad81779SPaul E. McKenney# if used carelessly, and should be avoided where not absolutely
55373ad81779SPaul E. McKenney# needed.  It is always OK to use synchronize_rcu_expedited() and
55383ad81779SPaul E. McKenney# synchronize_sched_expedited() at boot time (before real-time applications
55393ad81779SPaul E. McKenney# start) and in error situations where real-time response is compromised in
55403ad81779SPaul E. McKenney# any case.  Note that synchronize_srcu_expedited() does -not- interrupt
55413ad81779SPaul E. McKenney# other CPUs, so don't warn on uses of synchronize_srcu_expedited().
55423ad81779SPaul E. McKenney# Of course, nothing comes for free, and srcu_read_lock() and
55433ad81779SPaul E. McKenney# srcu_read_unlock() do contain full memory barriers in payment for
55443ad81779SPaul E. McKenney# synchronize_srcu_expedited() non-interruption properties.
55453ad81779SPaul E. McKenney		if ($line =~ /\b(synchronize_rcu_expedited|synchronize_sched_expedited)\(/) {
55463ad81779SPaul E. McKenney			WARN("EXPEDITED_RCU_GRACE_PERIOD",
55473ad81779SPaul E. McKenney			     "expedited RCU grace periods should be avoided where they can degrade real-time response\n" . $herecurr);
55483ad81779SPaul E. McKenney
55493ad81779SPaul E. McKenney		}
55503ad81779SPaul E. McKenney
55514a0df2efSAndy Whitcroft# check of hardware specific defines
5552c45dcabdSAndy Whitcroft		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
5553000d1cc1SJoe Perches			CHK("ARCH_DEFINES",
5554000d1cc1SJoe Perches			    "architecture specific defines should be avoided\n" .  $herecurr);
55550a920b5bSAndy Whitcroft		}
5556653d4876SAndy Whitcroft
5557d4977c78STobias Klauser# Check that the storage class is at the beginning of a declaration
5558d4977c78STobias Klauser		if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) {
5559000d1cc1SJoe Perches			WARN("STORAGE_CLASS",
5560000d1cc1SJoe Perches			     "storage class should be at the beginning of the declaration\n" . $herecurr)
5561d4977c78STobias Klauser		}
5562d4977c78STobias Klauser
5563de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between
5564de7d4f0eSAndy Whitcroft# storage class and type.
55659c0ca6f9SAndy Whitcroft		if ($line =~ /\b$Type\s+$Inline\b/ ||
55669c0ca6f9SAndy Whitcroft		    $line =~ /\b$Inline\s+$Storage\b/) {
5567000d1cc1SJoe Perches			ERROR("INLINE_LOCATION",
5568000d1cc1SJoe Perches			      "inline keyword should sit between storage class and type\n" . $herecurr);
5569de7d4f0eSAndy Whitcroft		}
5570de7d4f0eSAndy Whitcroft
55718905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline
55722b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
55732b7ab453SJoe Perches		    $line =~ /\b(__inline__|__inline)\b/) {
5574d5e616fcSJoe Perches			if (WARN("INLINE",
5575d5e616fcSJoe Perches				 "plain inline is preferred over $1\n" . $herecurr) &&
5576d5e616fcSJoe Perches			    $fix) {
5577194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
5578d5e616fcSJoe Perches
5579d5e616fcSJoe Perches			}
55808905a67cSAndy Whitcroft		}
55818905a67cSAndy Whitcroft
55823d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed
55832b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
55842b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
5585000d1cc1SJoe Perches			WARN("PREFER_PACKED",
5586000d1cc1SJoe Perches			     "__packed is preferred over __attribute__((packed))\n" . $herecurr);
55873d130fd0SJoe Perches		}
55883d130fd0SJoe Perches
558939b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned
55902b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
55912b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
5592000d1cc1SJoe Perches			WARN("PREFER_ALIGNED",
5593000d1cc1SJoe Perches			     "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
559439b7e287SJoe Perches		}
559539b7e287SJoe Perches
55965f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf
55972b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
55982b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
5599d5e616fcSJoe Perches			if (WARN("PREFER_PRINTF",
5600d5e616fcSJoe Perches				 "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
5601d5e616fcSJoe Perches			    $fix) {
5602194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
5603d5e616fcSJoe Perches
5604d5e616fcSJoe Perches			}
56055f14d3bdSJoe Perches		}
56065f14d3bdSJoe Perches
56076061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf
56082b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
56092b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
5610d5e616fcSJoe Perches			if (WARN("PREFER_SCANF",
5611d5e616fcSJoe Perches				 "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
5612d5e616fcSJoe Perches			    $fix) {
5613194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
5614d5e616fcSJoe Perches			}
56156061d949SJoe Perches		}
56166061d949SJoe Perches
5617619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues)
5618619a908aSJoe Perches		if ($^V && $^V ge 5.10.0 &&
5619619a908aSJoe Perches		    $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
5620619a908aSJoe Perches		    ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
5621619a908aSJoe Perches		     $line =~ /\b__weak\b/)) {
5622619a908aSJoe Perches			ERROR("WEAK_DECLARATION",
5623619a908aSJoe Perches			      "Using weak declarations can have unintended link defects\n" . $herecurr);
5624619a908aSJoe Perches		}
5625619a908aSJoe Perches
5626fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/
5627e6176fa4SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
5628fd39f904STomas Winkler		    $realfile !~ m@\btools/@ &&
5629e6176fa4SJoe Perches		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
5630e6176fa4SJoe Perches			my $type = $1;
5631e6176fa4SJoe Perches			if ($type =~ /\b($typeC99Typedefs)\b/) {
5632e6176fa4SJoe Perches				$type = $1;
5633e6176fa4SJoe Perches				my $kernel_type = 'u';
5634e6176fa4SJoe Perches				$kernel_type = 's' if ($type =~ /^_*[si]/);
5635e6176fa4SJoe Perches				$type =~ /(\d+)/;
5636e6176fa4SJoe Perches				$kernel_type .= $1;
5637e6176fa4SJoe Perches				if (CHK("PREFER_KERNEL_TYPES",
5638e6176fa4SJoe Perches					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
5639e6176fa4SJoe Perches				    $fix) {
5640e6176fa4SJoe Perches					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
5641e6176fa4SJoe Perches				}
5642e6176fa4SJoe Perches			}
5643e6176fa4SJoe Perches		}
5644e6176fa4SJoe Perches
5645938224b5SJoe Perches# check for cast of C90 native int or longer types constants
5646938224b5SJoe Perches		if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
5647938224b5SJoe Perches			my $cast = $1;
5648938224b5SJoe Perches			my $const = $2;
5649938224b5SJoe Perches			if (WARN("TYPECAST_INT_CONSTANT",
5650938224b5SJoe Perches				 "Unnecessary typecast of c90 int constant\n" . $herecurr) &&
5651938224b5SJoe Perches			    $fix) {
5652938224b5SJoe Perches				my $suffix = "";
5653938224b5SJoe Perches				my $newconst = $const;
5654938224b5SJoe Perches				$newconst =~ s/${Int_type}$//;
5655938224b5SJoe Perches				$suffix .= 'U' if ($cast =~ /\bunsigned\b/);
5656938224b5SJoe Perches				if ($cast =~ /\blong\s+long\b/) {
5657938224b5SJoe Perches					$suffix .= 'LL';
5658938224b5SJoe Perches				} elsif ($cast =~ /\blong\b/) {
5659938224b5SJoe Perches					$suffix .= 'L';
5660938224b5SJoe Perches				}
5661938224b5SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
5662938224b5SJoe Perches			}
5663938224b5SJoe Perches		}
5664938224b5SJoe Perches
56658f53a9b8SJoe Perches# check for sizeof(&)
56668f53a9b8SJoe Perches		if ($line =~ /\bsizeof\s*\(\s*\&/) {
5667000d1cc1SJoe Perches			WARN("SIZEOF_ADDRESS",
5668000d1cc1SJoe Perches			     "sizeof(& should be avoided\n" . $herecurr);
56698f53a9b8SJoe Perches		}
56708f53a9b8SJoe Perches
567166c80b60SJoe Perches# check for sizeof without parenthesis
567266c80b60SJoe Perches		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
5673d5e616fcSJoe Perches			if (WARN("SIZEOF_PARENTHESIS",
5674d5e616fcSJoe Perches				 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
5675d5e616fcSJoe Perches			    $fix) {
5676194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
5677d5e616fcSJoe Perches			}
567866c80b60SJoe Perches		}
567966c80b60SJoe Perches
568088982feaSJoe Perches# check for struct spinlock declarations
568188982feaSJoe Perches		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
568288982feaSJoe Perches			WARN("USE_SPINLOCK_T",
568388982feaSJoe Perches			     "struct spinlock should be spinlock_t\n" . $herecurr);
568488982feaSJoe Perches		}
568588982feaSJoe Perches
5686a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts
568706668727SJoe Perches		if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
5688a6962d72SJoe Perches			my $fmt = get_quoted_string($line, $rawline);
5689caac1d5fSHeba Aamer			$fmt =~ s/%%//g;
5690caac1d5fSHeba Aamer			if ($fmt !~ /%/) {
5691d5e616fcSJoe Perches				if (WARN("PREFER_SEQ_PUTS",
5692d5e616fcSJoe Perches					 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
5693d5e616fcSJoe Perches				    $fix) {
5694194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
5695d5e616fcSJoe Perches				}
5696a6962d72SJoe Perches			}
5697a6962d72SJoe Perches		}
5698a6962d72SJoe Perches
56990b523769SJoe Perches		# check for vsprintf extension %p<foo> misuses
57000b523769SJoe Perches		if ($^V && $^V ge 5.10.0 &&
57010b523769SJoe Perches		    defined $stat &&
57020b523769SJoe Perches		    $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
57030b523769SJoe Perches		    $1 !~ /^_*volatile_*$/) {
57040b523769SJoe Perches			my $bad_extension = "";
57050b523769SJoe Perches			my $lc = $stat =~ tr@\n@@;
57060b523769SJoe Perches			$lc = $lc + $linenr;
57070b523769SJoe Perches		        for (my $count = $linenr; $count <= $lc; $count++) {
57080b523769SJoe Perches				my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
57090b523769SJoe Perches				$fmt =~ s/%%//g;
57100b523769SJoe Perches				if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGN]).)/) {
57110b523769SJoe Perches					$bad_extension = $1;
57120b523769SJoe Perches					last;
57130b523769SJoe Perches				}
57140b523769SJoe Perches			}
57150b523769SJoe Perches			if ($bad_extension ne "") {
57160b523769SJoe Perches				my $stat_real = raw_line($linenr, 0);
57170b523769SJoe Perches				for (my $count = $linenr + 1; $count <= $lc; $count++) {
57180b523769SJoe Perches					$stat_real = $stat_real . "\n" . raw_line($count, 0);
57190b523769SJoe Perches				}
57200b523769SJoe Perches				WARN("VSPRINTF_POINTER_EXTENSION",
57210b523769SJoe Perches				     "Invalid vsprintf pointer extension '$bad_extension'\n" . "$here\n$stat_real\n");
57220b523769SJoe Perches			}
57230b523769SJoe Perches		}
57240b523769SJoe Perches
5725554e165cSAndy Whitcroft# Check for misused memsets
5726d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5727d1fe9c09SJoe Perches		    defined $stat &&
57289e20a853SMateusz Kulikowski		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
5729554e165cSAndy Whitcroft
5730d7c76ba7SJoe Perches			my $ms_addr = $2;
5731d1fe9c09SJoe Perches			my $ms_val = $7;
5732d1fe9c09SJoe Perches			my $ms_size = $12;
5733d7c76ba7SJoe Perches
5734554e165cSAndy Whitcroft			if ($ms_size =~ /^(0x|)0$/i) {
5735554e165cSAndy Whitcroft				ERROR("MEMSET",
5736d7c76ba7SJoe Perches				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
5737554e165cSAndy Whitcroft			} elsif ($ms_size =~ /^(0x|)1$/i) {
5738554e165cSAndy Whitcroft				WARN("MEMSET",
5739d7c76ba7SJoe Perches				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
5740d7c76ba7SJoe Perches			}
5741d7c76ba7SJoe Perches		}
5742d7c76ba7SJoe Perches
574398a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
5744f333195dSJoe Perches#		if ($^V && $^V ge 5.10.0 &&
5745f333195dSJoe Perches#		    defined $stat &&
5746f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
5747f333195dSJoe Perches#			if (WARN("PREFER_ETHER_ADDR_COPY",
5748f333195dSJoe Perches#				 "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
5749f333195dSJoe Perches#			    $fix) {
5750f333195dSJoe Perches#				$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
5751f333195dSJoe Perches#			}
5752f333195dSJoe Perches#		}
575398a9bba5SJoe Perches
5754b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
5755f333195dSJoe Perches#		if ($^V && $^V ge 5.10.0 &&
5756f333195dSJoe Perches#		    defined $stat &&
5757f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
5758f333195dSJoe Perches#			WARN("PREFER_ETHER_ADDR_EQUAL",
5759f333195dSJoe Perches#			     "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
5760f333195dSJoe Perches#		}
5761b6117d17SMateusz Kulikowski
57628617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
57638617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
5764f333195dSJoe Perches#		if ($^V && $^V ge 5.10.0 &&
5765f333195dSJoe Perches#		    defined $stat &&
5766f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
5767f333195dSJoe Perches#
5768f333195dSJoe Perches#			my $ms_val = $7;
5769f333195dSJoe Perches#
5770f333195dSJoe Perches#			if ($ms_val =~ /^(?:0x|)0+$/i) {
5771f333195dSJoe Perches#				if (WARN("PREFER_ETH_ZERO_ADDR",
5772f333195dSJoe Perches#					 "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
5773f333195dSJoe Perches#				    $fix) {
5774f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
5775f333195dSJoe Perches#				}
5776f333195dSJoe Perches#			} elsif ($ms_val =~ /^(?:0xff|255)$/i) {
5777f333195dSJoe Perches#				if (WARN("PREFER_ETH_BROADCAST_ADDR",
5778f333195dSJoe Perches#					 "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
5779f333195dSJoe Perches#				    $fix) {
5780f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
5781f333195dSJoe Perches#				}
5782f333195dSJoe Perches#			}
5783f333195dSJoe Perches#		}
57848617cd09SMateusz Kulikowski
5785d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t
5786d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5787d1fe9c09SJoe Perches		    defined $stat &&
5788d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
5789d1fe9c09SJoe Perches			if (defined $2 || defined $7) {
5790d7c76ba7SJoe Perches				my $call = $1;
5791d7c76ba7SJoe Perches				my $cast1 = deparenthesize($2);
5792d7c76ba7SJoe Perches				my $arg1 = $3;
5793d1fe9c09SJoe Perches				my $cast2 = deparenthesize($7);
5794d1fe9c09SJoe Perches				my $arg2 = $8;
5795d7c76ba7SJoe Perches				my $cast;
5796d7c76ba7SJoe Perches
5797d1fe9c09SJoe Perches				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
5798d7c76ba7SJoe Perches					$cast = "$cast1 or $cast2";
5799d7c76ba7SJoe Perches				} elsif ($cast1 ne "") {
5800d7c76ba7SJoe Perches					$cast = $cast1;
5801d7c76ba7SJoe Perches				} else {
5802d7c76ba7SJoe Perches					$cast = $cast2;
5803d7c76ba7SJoe Perches				}
5804d7c76ba7SJoe Perches				WARN("MINMAX",
5805d7c76ba7SJoe Perches				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
5806554e165cSAndy Whitcroft			}
5807554e165cSAndy Whitcroft		}
5808554e165cSAndy Whitcroft
58094a273195SJoe Perches# check usleep_range arguments
58104a273195SJoe Perches		if ($^V && $^V ge 5.10.0 &&
58114a273195SJoe Perches		    defined $stat &&
58124a273195SJoe Perches		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
58134a273195SJoe Perches			my $min = $1;
58144a273195SJoe Perches			my $max = $7;
58154a273195SJoe Perches			if ($min eq $max) {
58164a273195SJoe Perches				WARN("USLEEP_RANGE",
58174a273195SJoe Perches				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
58184a273195SJoe Perches			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
58194a273195SJoe Perches				 $min > $max) {
58204a273195SJoe Perches				WARN("USLEEP_RANGE",
58214a273195SJoe Perches				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
58224a273195SJoe Perches			}
58234a273195SJoe Perches		}
58244a273195SJoe Perches
5825823b794cSJoe Perches# check for naked sscanf
5826823b794cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
5827823b794cSJoe Perches		    defined $stat &&
58286c8bd707SJoe Perches		    $line =~ /\bsscanf\b/ &&
5829823b794cSJoe Perches		    ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
5830823b794cSJoe Perches		     $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
5831823b794cSJoe Perches		     $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
5832823b794cSJoe Perches			my $lc = $stat =~ tr@\n@@;
5833823b794cSJoe Perches			$lc = $lc + $linenr;
5834823b794cSJoe Perches			my $stat_real = raw_line($linenr, 0);
5835823b794cSJoe Perches		        for (my $count = $linenr + 1; $count <= $lc; $count++) {
5836823b794cSJoe Perches				$stat_real = $stat_real . "\n" . raw_line($count, 0);
5837823b794cSJoe Perches			}
5838823b794cSJoe Perches			WARN("NAKED_SSCANF",
5839823b794cSJoe Perches			     "unchecked sscanf return value\n" . "$here\n$stat_real\n");
5840823b794cSJoe Perches		}
5841823b794cSJoe Perches
5842afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo>
5843afc819abSJoe Perches		if ($^V && $^V ge 5.10.0 &&
5844afc819abSJoe Perches		    defined $stat &&
5845afc819abSJoe Perches		    $line =~ /\bsscanf\b/) {
5846afc819abSJoe Perches			my $lc = $stat =~ tr@\n@@;
5847afc819abSJoe Perches			$lc = $lc + $linenr;
5848afc819abSJoe Perches			my $stat_real = raw_line($linenr, 0);
5849afc819abSJoe Perches		        for (my $count = $linenr + 1; $count <= $lc; $count++) {
5850afc819abSJoe Perches				$stat_real = $stat_real . "\n" . raw_line($count, 0);
5851afc819abSJoe Perches			}
5852afc819abSJoe Perches			if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
5853afc819abSJoe Perches				my $format = $6;
5854afc819abSJoe Perches				my $count = $format =~ tr@%@%@;
5855afc819abSJoe Perches				if ($count == 1 &&
5856afc819abSJoe Perches				    $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
5857afc819abSJoe Perches					WARN("SSCANF_TO_KSTRTO",
5858afc819abSJoe Perches					     "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
5859afc819abSJoe Perches				}
5860afc819abSJoe Perches			}
5861afc819abSJoe Perches		}
5862afc819abSJoe Perches
586370dc8a48SJoe Perches# check for new externs in .h files.
586470dc8a48SJoe Perches		if ($realfile =~ /\.h$/ &&
586570dc8a48SJoe Perches		    $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
5866d1d85780SJoe Perches			if (CHK("AVOID_EXTERNS",
586770dc8a48SJoe Perches				"extern prototypes should be avoided in .h files\n" . $herecurr) &&
586870dc8a48SJoe Perches			    $fix) {
5869194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
587070dc8a48SJoe Perches			}
587170dc8a48SJoe Perches		}
587270dc8a48SJoe Perches
5873de7d4f0eSAndy Whitcroft# check for new externs in .c files.
5874171ae1a4SAndy Whitcroft		if ($realfile =~ /\.c$/ && defined $stat &&
5875c45dcabdSAndy Whitcroft		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
5876171ae1a4SAndy Whitcroft		{
5877c45dcabdSAndy Whitcroft			my $function_name = $1;
5878c45dcabdSAndy Whitcroft			my $paren_space = $2;
5879171ae1a4SAndy Whitcroft
5880171ae1a4SAndy Whitcroft			my $s = $stat;
5881171ae1a4SAndy Whitcroft			if (defined $cond) {
5882171ae1a4SAndy Whitcroft				substr($s, 0, length($cond), '');
5883171ae1a4SAndy Whitcroft			}
5884c45dcabdSAndy Whitcroft			if ($s =~ /^\s*;/ &&
5885c45dcabdSAndy Whitcroft			    $function_name ne 'uninitialized_var')
5886c45dcabdSAndy Whitcroft			{
5887000d1cc1SJoe Perches				WARN("AVOID_EXTERNS",
5888000d1cc1SJoe Perches				     "externs should be avoided in .c files\n" .  $herecurr);
5889de7d4f0eSAndy Whitcroft			}
5890de7d4f0eSAndy Whitcroft
5891171ae1a4SAndy Whitcroft			if ($paren_space =~ /\n/) {
5892000d1cc1SJoe Perches				WARN("FUNCTION_ARGUMENTS",
5893000d1cc1SJoe Perches				     "arguments for function declarations should follow identifier\n" . $herecurr);
5894171ae1a4SAndy Whitcroft			}
58959c9ba34eSAndy Whitcroft
58969c9ba34eSAndy Whitcroft		} elsif ($realfile =~ /\.c$/ && defined $stat &&
58979c9ba34eSAndy Whitcroft		    $stat =~ /^.\s*extern\s+/)
58989c9ba34eSAndy Whitcroft		{
5899000d1cc1SJoe Perches			WARN("AVOID_EXTERNS",
5900000d1cc1SJoe Perches			     "externs should be avoided in .c files\n" .  $herecurr);
5901171ae1a4SAndy Whitcroft		}
5902171ae1a4SAndy Whitcroft
5903ca0d8929SJoe Perches		if ($realfile =~ /\.[ch]$/ && 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
5916de7d4f0eSAndy Whitcroft# checks for new __setup's
5917de7d4f0eSAndy Whitcroft		if ($rawline =~ /\b__setup\("([^"]*)"/) {
5918de7d4f0eSAndy Whitcroft			my $name = $1;
5919de7d4f0eSAndy Whitcroft
5920de7d4f0eSAndy Whitcroft			if (!grep(/$name/, @setup_docs)) {
5921000d1cc1SJoe Perches				CHK("UNDOCUMENTED_SETUP",
59228c27ceffSMauro Carvalho Chehab				    "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr);
5923de7d4f0eSAndy Whitcroft			}
5924653d4876SAndy Whitcroft		}
59259c0ca6f9SAndy Whitcroft
59269c0ca6f9SAndy Whitcroft# check for pointless casting of kmalloc return
5927caf2a54fSJoe Perches		if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) {
5928000d1cc1SJoe Perches			WARN("UNNECESSARY_CASTS",
5929000d1cc1SJoe Perches			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
59309c0ca6f9SAndy Whitcroft		}
593113214adfSAndy Whitcroft
5932a640d25cSJoe Perches# alloc style
5933a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
5934a640d25cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
5935a640d25cSJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
5936a640d25cSJoe Perches			CHK("ALLOC_SIZEOF_STRUCT",
5937a640d25cSJoe Perches			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
5938a640d25cSJoe Perches		}
5939a640d25cSJoe Perches
594060a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
594160a55369SJoe Perches		if ($^V && $^V ge 5.10.0 &&
59421b4a2ed4SJoe Perches		    defined $stat &&
59431b4a2ed4SJoe Perches		    $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
594460a55369SJoe Perches			my $oldfunc = $3;
594560a55369SJoe Perches			my $a1 = $4;
594660a55369SJoe Perches			my $a2 = $10;
594760a55369SJoe Perches			my $newfunc = "kmalloc_array";
594860a55369SJoe Perches			$newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
594960a55369SJoe Perches			my $r1 = $a1;
595060a55369SJoe Perches			my $r2 = $a2;
595160a55369SJoe Perches			if ($a1 =~ /^sizeof\s*\S/) {
595260a55369SJoe Perches				$r1 = $a2;
595360a55369SJoe Perches				$r2 = $a1;
595460a55369SJoe Perches			}
5955e367455aSJoe Perches			if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
5956e367455aSJoe Perches			    !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
59571b4a2ed4SJoe Perches				my $ctx = '';
59581b4a2ed4SJoe Perches				my $herectx = $here . "\n";
59591b4a2ed4SJoe Perches				my $cnt = statement_rawlines($stat);
59601b4a2ed4SJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
59611b4a2ed4SJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
59621b4a2ed4SJoe Perches				}
5963e367455aSJoe Perches				if (WARN("ALLOC_WITH_MULTIPLY",
59641b4a2ed4SJoe Perches					 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
59651b4a2ed4SJoe Perches				    $cnt == 1 &&
5966e367455aSJoe Perches				    $fix) {
5967194f66fcSJoe 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;
596860a55369SJoe Perches				}
596960a55369SJoe Perches			}
597060a55369SJoe Perches		}
597160a55369SJoe Perches
5972972fdea2SJoe Perches# check for krealloc arg reuse
5973972fdea2SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5974972fdea2SJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) {
5975972fdea2SJoe Perches			WARN("KREALLOC_ARG_REUSE",
5976972fdea2SJoe Perches			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
5977972fdea2SJoe Perches		}
5978972fdea2SJoe Perches
59795ce59ae0SJoe Perches# check for alloc argument mismatch
59805ce59ae0SJoe Perches		if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
59815ce59ae0SJoe Perches			WARN("ALLOC_ARRAY_ARGS",
59825ce59ae0SJoe Perches			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
59835ce59ae0SJoe Perches		}
59845ce59ae0SJoe Perches
5985caf2a54fSJoe Perches# check for multiple semicolons
5986caf2a54fSJoe Perches		if ($line =~ /;\s*;\s*$/) {
5987d5e616fcSJoe Perches			if (WARN("ONE_SEMICOLON",
5988d5e616fcSJoe Perches				 "Statements terminations use 1 semicolon\n" . $herecurr) &&
5989d5e616fcSJoe Perches			    $fix) {
5990194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
5991d5e616fcSJoe Perches			}
5992d1e2ad07SJoe Perches		}
5993d1e2ad07SJoe Perches
5994cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
5995cec3aaa5STomas Winkler		if ($realfile !~ m@^include/uapi/@ &&
5996cec3aaa5STomas Winkler		    $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
59970ab90191SJoe Perches			my $ull = "";
59980ab90191SJoe Perches			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
59990ab90191SJoe Perches			if (CHK("BIT_MACRO",
60000ab90191SJoe Perches				"Prefer using the BIT$ull macro\n" . $herecurr) &&
60010ab90191SJoe Perches			    $fix) {
60020ab90191SJoe Perches				$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
60030ab90191SJoe Perches			}
60040ab90191SJoe Perches		}
60050ab90191SJoe Perches
60062d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
60072d632745SJoe 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*$/) {
60082d632745SJoe Perches			my $config = $1;
60092d632745SJoe Perches			if (WARN("PREFER_IS_ENABLED",
60102d632745SJoe Perches				 "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) &&
60112d632745SJoe Perches			    $fix) {
60122d632745SJoe Perches				$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
60132d632745SJoe Perches			}
60142d632745SJoe Perches		}
60152d632745SJoe Perches
6016e81f239bSJoe Perches# check for case / default statements not preceded by break/fallthrough/switch
6017c34c09a8SJoe Perches		if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
6018c34c09a8SJoe Perches			my $has_break = 0;
6019c34c09a8SJoe Perches			my $has_statement = 0;
6020c34c09a8SJoe Perches			my $count = 0;
6021c34c09a8SJoe Perches			my $prevline = $linenr;
6022e81f239bSJoe Perches			while ($prevline > 1 && ($file || $count < 3) && !$has_break) {
6023c34c09a8SJoe Perches				$prevline--;
6024c34c09a8SJoe Perches				my $rline = $rawlines[$prevline - 1];
6025c34c09a8SJoe Perches				my $fline = $lines[$prevline - 1];
6026c34c09a8SJoe Perches				last if ($fline =~ /^\@\@/);
6027c34c09a8SJoe Perches				next if ($fline =~ /^\-/);
6028c34c09a8SJoe Perches				next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/);
6029c34c09a8SJoe Perches				$has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i);
6030c34c09a8SJoe Perches				next if ($fline =~ /^.[\s$;]*$/);
6031c34c09a8SJoe Perches				$has_statement = 1;
6032c34c09a8SJoe Perches				$count++;
6033c34c09a8SJoe Perches				$has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/);
6034c34c09a8SJoe Perches			}
6035c34c09a8SJoe Perches			if (!$has_break && $has_statement) {
6036c34c09a8SJoe Perches				WARN("MISSING_BREAK",
6037224236d9SAndrew Morton				     "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr);
6038c34c09a8SJoe Perches			}
6039c34c09a8SJoe Perches		}
6040c34c09a8SJoe Perches
6041d1e2ad07SJoe Perches# check for switch/default statements without a break;
6042d1e2ad07SJoe Perches		if ($^V && $^V ge 5.10.0 &&
6043d1e2ad07SJoe Perches		    defined $stat &&
6044d1e2ad07SJoe Perches		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
6045d1e2ad07SJoe Perches			my $ctx = '';
6046d1e2ad07SJoe Perches			my $herectx = $here . "\n";
6047d1e2ad07SJoe Perches			my $cnt = statement_rawlines($stat);
6048d1e2ad07SJoe Perches			for (my $n = 0; $n < $cnt; $n++) {
6049d1e2ad07SJoe Perches				$herectx .= raw_line($linenr, $n) . "\n";
6050d1e2ad07SJoe Perches			}
6051d1e2ad07SJoe Perches			WARN("DEFAULT_NO_BREAK",
6052d1e2ad07SJoe Perches			     "switch default: should use break\n" . $herectx);
6053caf2a54fSJoe Perches		}
6054caf2a54fSJoe Perches
605513214adfSAndy Whitcroft# check for gcc specific __FUNCTION__
6056d5e616fcSJoe Perches		if ($line =~ /\b__FUNCTION__\b/) {
6057d5e616fcSJoe Perches			if (WARN("USE_FUNC",
6058d5e616fcSJoe Perches				 "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr) &&
6059d5e616fcSJoe Perches			    $fix) {
6060194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
6061d5e616fcSJoe Perches			}
606213214adfSAndy Whitcroft		}
6063773647a0SAndy Whitcroft
606462ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__
606562ec818fSJoe Perches		while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
606662ec818fSJoe Perches			ERROR("DATE_TIME",
606762ec818fSJoe Perches			      "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
606862ec818fSJoe Perches		}
606962ec818fSJoe Perches
60702c92488aSJoe Perches# check for use of yield()
60712c92488aSJoe Perches		if ($line =~ /\byield\s*\(\s*\)/) {
60722c92488aSJoe Perches			WARN("YIELD",
60732c92488aSJoe Perches			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
60742c92488aSJoe Perches		}
60752c92488aSJoe Perches
6076179f8f40SJoe Perches# check for comparisons against true and false
6077179f8f40SJoe Perches		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
6078179f8f40SJoe Perches			my $lead = $1;
6079179f8f40SJoe Perches			my $arg = $2;
6080179f8f40SJoe Perches			my $test = $3;
6081179f8f40SJoe Perches			my $otype = $4;
6082179f8f40SJoe Perches			my $trail = $5;
6083179f8f40SJoe Perches			my $op = "!";
6084179f8f40SJoe Perches
6085179f8f40SJoe Perches			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
6086179f8f40SJoe Perches
6087179f8f40SJoe Perches			my $type = lc($otype);
6088179f8f40SJoe Perches			if ($type =~ /^(?:true|false)$/) {
6089179f8f40SJoe Perches				if (("$test" eq "==" && "$type" eq "true") ||
6090179f8f40SJoe Perches				    ("$test" eq "!=" && "$type" eq "false")) {
6091179f8f40SJoe Perches					$op = "";
6092179f8f40SJoe Perches				}
6093179f8f40SJoe Perches
6094179f8f40SJoe Perches				CHK("BOOL_COMPARISON",
6095179f8f40SJoe Perches				    "Using comparison to $otype is error prone\n" . $herecurr);
6096179f8f40SJoe Perches
6097179f8f40SJoe Perches## maybe suggesting a correct construct would better
6098179f8f40SJoe Perches##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
6099179f8f40SJoe Perches
6100179f8f40SJoe Perches			}
6101179f8f40SJoe Perches		}
6102179f8f40SJoe Perches
61034882720bSThomas Gleixner# check for semaphores initialized locked
61044882720bSThomas Gleixner		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
6105000d1cc1SJoe Perches			WARN("CONSIDER_COMPLETION",
6106000d1cc1SJoe Perches			     "consider using a completion\n" . $herecurr);
6107773647a0SAndy Whitcroft		}
61086712d858SJoe Perches
610967d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto*
611067d0a075SJoe Perches		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
6111000d1cc1SJoe Perches			WARN("CONSIDER_KSTRTO",
611267d0a075SJoe Perches			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
6113773647a0SAndy Whitcroft		}
61146712d858SJoe Perches
6115ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please
6116f3db6639SMichael Ellerman		if ($line =~ /^.\s*__initcall\s*\(/) {
6117000d1cc1SJoe Perches			WARN("USE_DEVICE_INITCALL",
6118ae3ccc46SFabian Frederick			     "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
6119f3db6639SMichael Ellerman		}
61206712d858SJoe Perches
61210f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree)
6122d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {'
61236903ffb2SAndy Whitcroft		if ($line !~ /\bconst\b/ &&
6124d9190e4eSJoe Perches		    $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
6125000d1cc1SJoe Perches			WARN("CONST_STRUCT",
6126d9190e4eSJoe Perches			     "struct $1 should normally be const\n" . $herecurr);
61272b6db5cbSAndy Whitcroft		}
6128773647a0SAndy Whitcroft
6129773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong
6130773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right
6131773647a0SAndy Whitcroft		if ($line =~ /\bNR_CPUS\b/ &&
6132c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
6133c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
6134171ae1a4SAndy Whitcroft		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
6135171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
6136171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/)
6137773647a0SAndy Whitcroft		{
6138000d1cc1SJoe Perches			WARN("NR_CPUS",
6139000d1cc1SJoe Perches			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
6140773647a0SAndy Whitcroft		}
61419c9ba34eSAndy Whitcroft
614252ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
614352ea8506SJoe Perches		if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
614452ea8506SJoe Perches			ERROR("DEFINE_ARCH_HAS",
614552ea8506SJoe Perches			      "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
614652ea8506SJoe Perches		}
614752ea8506SJoe Perches
6148acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)"
6149acd9362cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
6150acd9362cSJoe Perches		    $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
6151acd9362cSJoe Perches			WARN("LIKELY_MISUSE",
6152acd9362cSJoe Perches			     "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
6153acd9362cSJoe Perches		}
6154acd9362cSJoe Perches
6155691d77b6SAndy Whitcroft# whine mightly about in_atomic
6156691d77b6SAndy Whitcroft		if ($line =~ /\bin_atomic\s*\(/) {
6157691d77b6SAndy Whitcroft			if ($realfile =~ m@^drivers/@) {
6158000d1cc1SJoe Perches				ERROR("IN_ATOMIC",
6159000d1cc1SJoe Perches				      "do not use in_atomic in drivers\n" . $herecurr);
6160f4a87736SAndy Whitcroft			} elsif ($realfile !~ m@^kernel/@) {
6161000d1cc1SJoe Perches				WARN("IN_ATOMIC",
6162000d1cc1SJoe Perches				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
6163691d77b6SAndy Whitcroft			}
6164691d77b6SAndy Whitcroft		}
61651704f47bSPeter Zijlstra
6166481aea5cSJoe Perches# whine about ACCESS_ONCE
6167481aea5cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
6168481aea5cSJoe Perches		    $line =~ /\bACCESS_ONCE\s*$balanced_parens\s*(=(?!=))?\s*($FuncArg)?/) {
6169481aea5cSJoe Perches			my $par = $1;
6170481aea5cSJoe Perches			my $eq = $2;
6171481aea5cSJoe Perches			my $fun = $3;
6172481aea5cSJoe Perches			$par =~ s/^\(\s*(.*)\s*\)$/$1/;
6173481aea5cSJoe Perches			if (defined($eq)) {
6174481aea5cSJoe Perches				if (WARN("PREFER_WRITE_ONCE",
6175481aea5cSJoe Perches					 "Prefer WRITE_ONCE(<FOO>, <BAR>) over ACCESS_ONCE(<FOO>) = <BAR>\n" . $herecurr) &&
6176481aea5cSJoe Perches				    $fix) {
6177481aea5cSJoe Perches					$fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)\s*$eq\s*\Q$fun\E/WRITE_ONCE($par, $fun)/;
6178481aea5cSJoe Perches				}
6179481aea5cSJoe Perches			} else {
6180481aea5cSJoe Perches				if (WARN("PREFER_READ_ONCE",
6181481aea5cSJoe Perches					 "Prefer READ_ONCE(<FOO>) over ACCESS_ONCE(<FOO>)\n" . $herecurr) &&
6182481aea5cSJoe Perches				    $fix) {
6183481aea5cSJoe Perches					$fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)/READ_ONCE($par)/;
6184481aea5cSJoe Perches				}
6185481aea5cSJoe Perches			}
6186481aea5cSJoe Perches		}
6187481aea5cSJoe Perches
61880f5225b0SPeter Zijlstra# check for mutex_trylock_recursive usage
61890f5225b0SPeter Zijlstra		if ($line =~ /mutex_trylock_recursive/) {
61900f5225b0SPeter Zijlstra			ERROR("LOCKING",
61910f5225b0SPeter Zijlstra			      "recursive locking is bad, do not use this ever.\n" . $herecurr);
61920f5225b0SPeter Zijlstra		}
61930f5225b0SPeter Zijlstra
61941704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class
61951704f47bSPeter Zijlstra		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
61961704f47bSPeter Zijlstra		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
61971704f47bSPeter Zijlstra			if ($realfile !~ m@^kernel/lockdep@ &&
61981704f47bSPeter Zijlstra			    $realfile !~ m@^include/linux/lockdep@ &&
61991704f47bSPeter Zijlstra			    $realfile !~ m@^drivers/base/core@) {
6200000d1cc1SJoe Perches				ERROR("LOCKDEP",
6201000d1cc1SJoe Perches				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
62021704f47bSPeter Zijlstra			}
62031704f47bSPeter Zijlstra		}
620488f8831cSDave Jones
6205b392c64fSJoe Perches		if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
6206b392c64fSJoe Perches		    $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
6207000d1cc1SJoe Perches			WARN("EXPORTED_WORLD_WRITABLE",
6208000d1cc1SJoe Perches			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
620988f8831cSDave Jones		}
62102435880fSJoe Perches
6211515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal
6212515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
6213515a235eSJoe Perches		if ($^V && $^V ge 5.10.0 &&
6214459cf0aeSJoe Perches		    defined $stat &&
6215515a235eSJoe Perches		    $line =~ /$mode_perms_search/) {
62162435880fSJoe Perches			foreach my $entry (@mode_permission_funcs) {
62172435880fSJoe Perches				my $func = $entry->[0];
62182435880fSJoe Perches				my $arg_pos = $entry->[1];
62192435880fSJoe Perches
6220459cf0aeSJoe Perches				my $lc = $stat =~ tr@\n@@;
6221459cf0aeSJoe Perches				$lc = $lc + $linenr;
6222459cf0aeSJoe Perches				my $stat_real = raw_line($linenr, 0);
6223459cf0aeSJoe Perches				for (my $count = $linenr + 1; $count <= $lc; $count++) {
6224459cf0aeSJoe Perches					$stat_real = $stat_real . "\n" . raw_line($count, 0);
6225459cf0aeSJoe Perches				}
6226459cf0aeSJoe Perches
62272435880fSJoe Perches				my $skip_args = "";
62282435880fSJoe Perches				if ($arg_pos > 1) {
62292435880fSJoe Perches					$arg_pos--;
62302435880fSJoe Perches					$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
62312435880fSJoe Perches				}
6232f90774e1SJoe Perches				my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
6233459cf0aeSJoe Perches				if ($stat =~ /$test/) {
62342435880fSJoe Perches					my $val = $1;
62352435880fSJoe Perches					$val = $6 if ($skip_args ne "");
6236f90774e1SJoe Perches					if (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
6237f90774e1SJoe Perches					    ($val =~ /^$Octal$/ && length($val) ne 4)) {
62382435880fSJoe Perches						ERROR("NON_OCTAL_PERMISSIONS",
6239459cf0aeSJoe Perches						      "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
6240f90774e1SJoe Perches					}
6241f90774e1SJoe Perches					if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
6242c0a5c898SJoe Perches						ERROR("EXPORTED_WORLD_WRITABLE",
6243459cf0aeSJoe Perches						      "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
62442435880fSJoe Perches					}
6245459cf0aeSJoe Perches				}
6246459cf0aeSJoe Perches			}
6247459cf0aeSJoe Perches		}
6248459cf0aeSJoe Perches
6249459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability
6250459cf0aeSJoe Perches		if ($line =~ /\b$mode_perms_string_search\b/) {
6251459cf0aeSJoe Perches			my $val = "";
6252459cf0aeSJoe Perches			my $oval = "";
6253f90774e1SJoe Perches			my $to = 0;
6254459cf0aeSJoe Perches			my $curpos = 0;
6255459cf0aeSJoe Perches			my $lastpos = 0;
6256459cf0aeSJoe Perches			while ($line =~ /\b(($mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
6257459cf0aeSJoe Perches				$curpos = pos($line);
6258459cf0aeSJoe Perches				my $match = $2;
6259459cf0aeSJoe Perches				my $omatch = $1;
6260459cf0aeSJoe Perches				last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
6261459cf0aeSJoe Perches				$lastpos = $curpos;
6262459cf0aeSJoe Perches				$to |= $mode_permission_string_types{$match};
6263459cf0aeSJoe Perches				$val .= '\s*\|\s*' if ($val ne "");
6264459cf0aeSJoe Perches				$val .= $match;
6265459cf0aeSJoe Perches				$oval .= $omatch;
6266f90774e1SJoe Perches			}
6267459cf0aeSJoe Perches			$oval =~ s/^\s*\|\s*//;
6268459cf0aeSJoe Perches			$oval =~ s/\s*\|\s*$//;
6269459cf0aeSJoe Perches			my $octal = sprintf("%04o", $to);
6270f90774e1SJoe Perches			if (WARN("SYMBOLIC_PERMS",
6271459cf0aeSJoe Perches				 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
6272f90774e1SJoe Perches			    $fix) {
6273459cf0aeSJoe Perches				$fixed[$fixlinenr] =~ s/$val/$octal/;
62742435880fSJoe Perches			}
627513214adfSAndy Whitcroft		}
62765a6d20ceSBjorn Andersson
62775a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h
62785a6d20ceSBjorn Andersson		if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
62795a6d20ceSBjorn Andersson			my $extracted_string = get_quoted_string($line, $rawline);
62805a6d20ceSBjorn Andersson			my $valid_licenses = qr{
62815a6d20ceSBjorn Andersson						GPL|
62825a6d20ceSBjorn Andersson						GPL\ v2|
62835a6d20ceSBjorn Andersson						GPL\ and\ additional\ rights|
62845a6d20ceSBjorn Andersson						Dual\ BSD/GPL|
62855a6d20ceSBjorn Andersson						Dual\ MIT/GPL|
62865a6d20ceSBjorn Andersson						Dual\ MPL/GPL|
62875a6d20ceSBjorn Andersson						Proprietary
62885a6d20ceSBjorn Andersson					}x;
62895a6d20ceSBjorn Andersson			if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
62905a6d20ceSBjorn Andersson				WARN("MODULE_LICENSE",
62915a6d20ceSBjorn Andersson				     "unknown module license " . $extracted_string . "\n" . $herecurr);
62925a6d20ceSBjorn Andersson			}
62935a6d20ceSBjorn Andersson		}
6294515a235eSJoe Perches	}
629513214adfSAndy Whitcroft
629613214adfSAndy Whitcroft	# If we have no input at all, then there is nothing to report on
629713214adfSAndy Whitcroft	# so just keep quiet.
629813214adfSAndy Whitcroft	if ($#rawlines == -1) {
629913214adfSAndy Whitcroft		exit(0);
63000a920b5bSAndy Whitcroft	}
63010a920b5bSAndy Whitcroft
63028905a67cSAndy Whitcroft	# In mailback mode only produce a report in the negative, for
63038905a67cSAndy Whitcroft	# things that appear to be patches.
63048905a67cSAndy Whitcroft	if ($mailback && ($clean == 1 || !$is_patch)) {
63058905a67cSAndy Whitcroft		exit(0);
63068905a67cSAndy Whitcroft	}
63078905a67cSAndy Whitcroft
63088905a67cSAndy Whitcroft	# This is not a patch, and we are are in 'no-patch' mode so
63098905a67cSAndy Whitcroft	# just keep quiet.
63108905a67cSAndy Whitcroft	if (!$chk_patch && !$is_patch) {
63118905a67cSAndy Whitcroft		exit(0);
63128905a67cSAndy Whitcroft	}
63138905a67cSAndy Whitcroft
631406330fc4SJoe Perches	if (!$is_patch && $file !~ /cover-letter\.patch$/) {
6315000d1cc1SJoe Perches		ERROR("NOT_UNIFIED_DIFF",
6316000d1cc1SJoe Perches		      "Does not appear to be a unified-diff format patch\n");
63170a920b5bSAndy Whitcroft	}
6318ed43c4e5SAllen Hubbe	if ($is_patch && $has_commit_log && $chk_signoff && $signoff == 0) {
6319000d1cc1SJoe Perches		ERROR("MISSING_SIGN_OFF",
6320000d1cc1SJoe Perches		      "Missing Signed-off-by: line(s)\n");
63210a920b5bSAndy Whitcroft	}
63220a920b5bSAndy Whitcroft
6323f0a594c1SAndy Whitcroft	print report_dump();
632413214adfSAndy Whitcroft	if ($summary && !($clean == 1 && $quiet == 1)) {
632513214adfSAndy Whitcroft		print "$filename " if ($summary_file);
63266c72ffaaSAndy Whitcroft		print "total: $cnt_error errors, $cnt_warn warnings, " .
63276c72ffaaSAndy Whitcroft			(($check)? "$cnt_chk checks, " : "") .
63286c72ffaaSAndy Whitcroft			"$cnt_lines lines checked\n";
63296c72ffaaSAndy Whitcroft	}
63308905a67cSAndy Whitcroft
6331d2c0a235SAndy Whitcroft	if ($quiet == 0) {
6332ef212196SJoe Perches		# If there were any defects found and not already fixing them
6333ef212196SJoe Perches		if (!$clean and !$fix) {
6334ef212196SJoe Perches			print << "EOM"
6335ef212196SJoe Perches
6336ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to
6337ef212196SJoe Perches      mechanically convert to the typical style using --fix or --fix-inplace.
6338ef212196SJoe PerchesEOM
6339ef212196SJoe Perches		}
6340d2c0a235SAndy Whitcroft		# If there were whitespace errors which cleanpatch can fix
6341d2c0a235SAndy Whitcroft		# then suggest that.
6342d2c0a235SAndy Whitcroft		if ($rpt_cleaners) {
6343b0781216SMike Frysinger			$rpt_cleaners = 0;
6344d8469f16SJoe Perches			print << "EOM"
6345d8469f16SJoe Perches
6346d8469f16SJoe PerchesNOTE: Whitespace errors detected.
6347d8469f16SJoe Perches      You may wish to use scripts/cleanpatch or scripts/cleanfile
6348d8469f16SJoe PerchesEOM
6349d2c0a235SAndy Whitcroft		}
6350d2c0a235SAndy Whitcroft	}
6351d2c0a235SAndy Whitcroft
6352d752fcc8SJoe Perches	if ($clean == 0 && $fix &&
6353d752fcc8SJoe Perches	    ("@rawlines" ne "@fixed" ||
6354d752fcc8SJoe Perches	     $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
63559624b8d6SJoe Perches		my $newfile = $filename;
63569624b8d6SJoe Perches		$newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
63573705ce5bSJoe Perches		my $linecount = 0;
63583705ce5bSJoe Perches		my $f;
63593705ce5bSJoe Perches
6360d752fcc8SJoe Perches		@fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
6361d752fcc8SJoe Perches
63623705ce5bSJoe Perches		open($f, '>', $newfile)
63633705ce5bSJoe Perches		    or die "$P: Can't open $newfile for write\n";
63643705ce5bSJoe Perches		foreach my $fixed_line (@fixed) {
63653705ce5bSJoe Perches			$linecount++;
63663705ce5bSJoe Perches			if ($file) {
63673705ce5bSJoe Perches				if ($linecount > 3) {
63683705ce5bSJoe Perches					$fixed_line =~ s/^\+//;
63693705ce5bSJoe Perches					print $f $fixed_line . "\n";
63703705ce5bSJoe Perches				}
63713705ce5bSJoe Perches			} else {
63723705ce5bSJoe Perches				print $f $fixed_line . "\n";
63733705ce5bSJoe Perches			}
63743705ce5bSJoe Perches		}
63753705ce5bSJoe Perches		close($f);
63763705ce5bSJoe Perches
63773705ce5bSJoe Perches		if (!$quiet) {
63783705ce5bSJoe Perches			print << "EOM";
6379d8469f16SJoe Perches
63803705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile'
63813705ce5bSJoe Perches
63823705ce5bSJoe PerchesDo _NOT_ trust the results written to this file.
63833705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness.
63843705ce5bSJoe Perches
63853705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches.
63863705ce5bSJoe PerchesNo warranties, expressed or implied...
63873705ce5bSJoe PerchesEOM
63883705ce5bSJoe Perches		}
63893705ce5bSJoe Perches	}
63903705ce5bSJoe Perches
6391d8469f16SJoe Perches	if ($quiet == 0) {
6392d8469f16SJoe Perches		print "\n";
6393d8469f16SJoe Perches		if ($clean == 1) {
6394d8469f16SJoe Perches			print "$vname has no obvious style problems and is ready for submission.\n";
6395d8469f16SJoe Perches		} else {
6396d8469f16SJoe Perches			print "$vname has style problems, please review.\n";
63970a920b5bSAndy Whitcroft		}
63980a920b5bSAndy Whitcroft	}
63990a920b5bSAndy Whitcroft	return $clean;
64000a920b5bSAndy Whitcroft}
6401