xref: /linux-6.15/scripts/checkpatch.pl (revision ce4fecf1)
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		}
221674fd4f34SJoe 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 &&
229574fd4f34SJoe Perches		    $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
229674fd4f34SJoe 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;
231274fd4f34SJoe Perches			if ($context =~ /\b(\w+)\s*\(/) {
231374fd4f34SJoe Perches				$context_function = $1;
231474fd4f34SJoe Perches			} else {
231574fd4f34SJoe Perches				undef $context_function;
231674fd4f34SJoe 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.
3357f6950a73SJoe Perches		if ($line =~ /\b(?:(?:if|while|for|(?:[a-z_]+|)for_each[a-z_]+)\s*\(|(?:do|else)\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) ||
3449f6950a73SJoe Perches			     ($sindent == $indent &&
3450f6950a73SJoe Perches			      ($s !~ /^\s*(?:\}|\{|else\b)/)) ||
34519f5af480SJoe Perches			     ($sindent > $indent + 8))) {
3452000d1cc1SJoe Perches				WARN("SUSPECT_CODE_INDENT",
3453000d1cc1SJoe Perches				     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
34544d001e4dSAndy Whitcroft			}
34554d001e4dSAndy Whitcroft		}
34564d001e4dSAndy Whitcroft
34576c72ffaaSAndy Whitcroft		# Track the 'values' across context and added lines.
34586c72ffaaSAndy Whitcroft		my $opline = $line; $opline =~ s/^./ /;
34591f65f947SAndy Whitcroft		my ($curr_values, $curr_vars) =
34601f65f947SAndy Whitcroft				annotate_values($opline . "\n", $prev_values);
34616c72ffaaSAndy Whitcroft		$curr_values = $prev_values . $curr_values;
3462c2fdda0dSAndy Whitcroft		if ($dbg_values) {
3463c2fdda0dSAndy Whitcroft			my $outline = $opline; $outline =~ s/\t/ /g;
3464cf655043SAndy Whitcroft			print "$linenr > .$outline\n";
3465cf655043SAndy Whitcroft			print "$linenr > $curr_values\n";
34661f65f947SAndy Whitcroft			print "$linenr >  $curr_vars\n";
3467c2fdda0dSAndy Whitcroft		}
34686c72ffaaSAndy Whitcroft		$prev_values = substr($curr_values, -1);
34696c72ffaaSAndy Whitcroft
347000df344fSAndy Whitcroft#ignore lines not being added
34713705ce5bSJoe Perches		next if ($line =~ /^[^\+]/);
347200df344fSAndy Whitcroft
347311ca40a0SJoe Perches# check for dereferences that span multiple lines
347411ca40a0SJoe Perches		if ($prevline =~ /^\+.*$Lval\s*(?:\.|->)\s*$/ &&
347511ca40a0SJoe Perches		    $line =~ /^\+\s*(?!\#\s*(?!define\s+|if))\s*$Lval/) {
347611ca40a0SJoe Perches			$prevline =~ /($Lval\s*(?:\.|->))\s*$/;
347711ca40a0SJoe Perches			my $ref = $1;
347811ca40a0SJoe Perches			$line =~ /^.\s*($Lval)/;
347911ca40a0SJoe Perches			$ref .= $1;
348011ca40a0SJoe Perches			$ref =~ s/\s//g;
348111ca40a0SJoe Perches			WARN("MULTILINE_DEREFERENCE",
348211ca40a0SJoe Perches			     "Avoid multiple line dereference - prefer '$ref'\n" . $hereprev);
348311ca40a0SJoe Perches		}
348411ca40a0SJoe Perches
3485a1ce18e4SJoe Perches# check for declarations of signed or unsigned without int
3486c8447115SJoe Perches		while ($line =~ m{\b($Declare)\s*(?!char\b|short\b|int\b|long\b)\s*($Ident)?\s*[=,;\[\)\(]}g) {
3487a1ce18e4SJoe Perches			my $type = $1;
3488a1ce18e4SJoe Perches			my $var = $2;
3489207a8e84SJoe Perches			$var = "" if (!defined $var);
3490207a8e84SJoe Perches			if ($type =~ /^(?:(?:$Storage|$Inline|$Attribute)\s+)*((?:un)?signed)((?:\s*\*)*)\s*$/) {
3491a1ce18e4SJoe Perches				my $sign = $1;
3492a1ce18e4SJoe Perches				my $pointer = $2;
3493a1ce18e4SJoe Perches
3494a1ce18e4SJoe Perches				$pointer = "" if (!defined $pointer);
3495a1ce18e4SJoe Perches
3496a1ce18e4SJoe Perches				if (WARN("UNSPECIFIED_INT",
3497a1ce18e4SJoe Perches					 "Prefer '" . trim($sign) . " int" . rtrim($pointer) . "' to bare use of '$sign" . rtrim($pointer) . "'\n" . $herecurr) &&
3498a1ce18e4SJoe Perches				    $fix) {
3499a1ce18e4SJoe Perches					my $decl = trim($sign) . " int ";
3500207a8e84SJoe Perches					my $comp_pointer = $pointer;
3501207a8e84SJoe Perches					$comp_pointer =~ s/\s//g;
3502207a8e84SJoe Perches					$decl .= $comp_pointer;
3503207a8e84SJoe Perches					$decl = rtrim($decl) if ($var eq "");
3504207a8e84SJoe Perches					$fixed[$fixlinenr] =~ s@\b$sign\s*\Q$pointer\E\s*$var\b@$decl$var@;
3505a1ce18e4SJoe Perches				}
3506a1ce18e4SJoe Perches			}
3507a1ce18e4SJoe Perches		}
3508a1ce18e4SJoe Perches
3509653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher.
35107429c690SAndy Whitcroft		if ($dbg_type) {
35117429c690SAndy Whitcroft			if ($line =~ /^.\s*$Declare\s*$/) {
3512000d1cc1SJoe Perches				ERROR("TEST_TYPE",
3513000d1cc1SJoe Perches				      "TEST: is type\n" . $herecurr);
35147429c690SAndy Whitcroft			} elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
3515000d1cc1SJoe Perches				ERROR("TEST_NOT_TYPE",
3516000d1cc1SJoe Perches				      "TEST: is not type ($1 is)\n". $herecurr);
35177429c690SAndy Whitcroft			}
3518653d4876SAndy Whitcroft			next;
3519653d4876SAndy Whitcroft		}
3520a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher.
3521a1ef277eSAndy Whitcroft		if ($dbg_attr) {
35229360b0e5SAndy Whitcroft			if ($line =~ /^.\s*$Modifier\s*$/) {
3523000d1cc1SJoe Perches				ERROR("TEST_ATTR",
3524000d1cc1SJoe Perches				      "TEST: is attr\n" . $herecurr);
35259360b0e5SAndy Whitcroft			} elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
3526000d1cc1SJoe Perches				ERROR("TEST_NOT_ATTR",
3527000d1cc1SJoe Perches				      "TEST: is not attr ($1 is)\n". $herecurr);
3528a1ef277eSAndy Whitcroft			}
3529a1ef277eSAndy Whitcroft			next;
3530a1ef277eSAndy Whitcroft		}
3531653d4876SAndy Whitcroft
3532f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line
353399423c20SAndy Whitcroft		if ($line =~ /^.\s*{/ &&
353499423c20SAndy Whitcroft		    $prevline =~ /(?:^|[^=])=\s*$/) {
3535d752fcc8SJoe Perches			if (ERROR("OPEN_BRACE",
3536d752fcc8SJoe Perches				  "that open brace { should be on the previous line\n" . $hereprev) &&
3537f2d7e4d4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
3538f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
3539f2d7e4d4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
3540d752fcc8SJoe Perches				my $fixedline = $prevrawline;
3541d752fcc8SJoe Perches				$fixedline =~ s/\s*=\s*$/ = {/;
3542f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
3543d752fcc8SJoe Perches				$fixedline = $line;
3544d752fcc8SJoe Perches				$fixedline =~ s/^(.\s*){\s*/$1/;
3545f2d7e4d4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
3546d752fcc8SJoe Perches			}
3547f0a594c1SAndy Whitcroft		}
3548f0a594c1SAndy Whitcroft
354900df344fSAndy Whitcroft#
355000df344fSAndy Whitcroft# Checks which are anchored on the added line.
355100df344fSAndy Whitcroft#
355200df344fSAndy Whitcroft
3553653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line)
3554c45dcabdSAndy Whitcroft		if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
3555653d4876SAndy Whitcroft			my $path = $1;
3556653d4876SAndy Whitcroft			if ($path =~ m{//}) {
3557000d1cc1SJoe Perches				ERROR("MALFORMED_INCLUDE",
3558495e9d84SJoe Perches				      "malformed #include filename\n" . $herecurr);
3559495e9d84SJoe Perches			}
3560495e9d84SJoe Perches			if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
3561495e9d84SJoe Perches				ERROR("UAPI_INCLUDE",
3562495e9d84SJoe Perches				      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
3563653d4876SAndy Whitcroft			}
3564653d4876SAndy Whitcroft		}
3565653d4876SAndy Whitcroft
356600df344fSAndy Whitcroft# no C99 // comments
356700df344fSAndy Whitcroft		if ($line =~ m{//}) {
35683705ce5bSJoe Perches			if (ERROR("C99_COMMENTS",
35693705ce5bSJoe Perches				  "do not use C99 // comments\n" . $herecurr) &&
35703705ce5bSJoe Perches			    $fix) {
3571194f66fcSJoe Perches				my $line = $fixed[$fixlinenr];
35723705ce5bSJoe Perches				if ($line =~ /\/\/(.*)$/) {
35733705ce5bSJoe Perches					my $comment = trim($1);
3574194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
35753705ce5bSJoe Perches				}
35763705ce5bSJoe Perches			}
357700df344fSAndy Whitcroft		}
357800df344fSAndy Whitcroft		# Remove C99 comments.
35790a920b5bSAndy Whitcroft		$line =~ s@//.*@@;
35806c72ffaaSAndy Whitcroft		$opline =~ s@//.*@@;
35810a920b5bSAndy Whitcroft
35822b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
35832b474a1aSAndy Whitcroft# the whole statement.
35842b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n";
35852b474a1aSAndy Whitcroft		if (defined $realline_next &&
35862b474a1aSAndy Whitcroft		    exists $lines[$realline_next - 1] &&
35872b474a1aSAndy Whitcroft		    !defined $suppress_export{$realline_next} &&
35882b474a1aSAndy Whitcroft		    ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
35892b474a1aSAndy Whitcroft		     $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
35903cbf62dfSAndy Whitcroft			# Handle definitions which produce identifiers with
35913cbf62dfSAndy Whitcroft			# a prefix:
35923cbf62dfSAndy Whitcroft			#   XXX(foo);
35933cbf62dfSAndy Whitcroft			#   EXPORT_SYMBOL(something_foo);
3594653d4876SAndy Whitcroft			my $name = $1;
359587a53877SAndy Whitcroft			if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
35963cbf62dfSAndy Whitcroft			    $name =~ /^${Ident}_$2/) {
35973cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n";
35983cbf62dfSAndy Whitcroft				$suppress_export{$realline_next} = 1;
35993cbf62dfSAndy Whitcroft
36003cbf62dfSAndy Whitcroft			} elsif ($stat !~ /(?:
36012b474a1aSAndy Whitcroft				\n.}\s*$|
360248012058SAndy Whitcroft				^.DEFINE_$Ident\(\Q$name\E\)|
360348012058SAndy Whitcroft				^.DECLARE_$Ident\(\Q$name\E\)|
360448012058SAndy Whitcroft				^.LIST_HEAD\(\Q$name\E\)|
36052b474a1aSAndy Whitcroft				^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
36062b474a1aSAndy Whitcroft				\b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
360748012058SAndy Whitcroft			    )/x) {
36082b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
36092b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 2;
36102b474a1aSAndy Whitcroft			} else {
36112b474a1aSAndy Whitcroft				$suppress_export{$realline_next} = 1;
36120a920b5bSAndy Whitcroft			}
36130a920b5bSAndy Whitcroft		}
36142b474a1aSAndy Whitcroft		if (!defined $suppress_export{$linenr} &&
36152b474a1aSAndy Whitcroft		    $prevline =~ /^.\s*$/ &&
36162b474a1aSAndy Whitcroft		    ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
36172b474a1aSAndy Whitcroft		     $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
36182b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n";
36192b474a1aSAndy Whitcroft			$suppress_export{$linenr} = 2;
36202b474a1aSAndy Whitcroft		}
36212b474a1aSAndy Whitcroft		if (defined $suppress_export{$linenr} &&
36222b474a1aSAndy Whitcroft		    $suppress_export{$linenr} == 2) {
3623000d1cc1SJoe Perches			WARN("EXPORT_SYMBOL",
3624000d1cc1SJoe Perches			     "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
36252b474a1aSAndy Whitcroft		}
36260a920b5bSAndy Whitcroft
36275150bda4SJoe Eloff# check for global initialisers.
36286d32f7a3SJoe Perches		if ($line =~ /^\+$Type\s*$Ident(?:\s+$Modifier)*\s*=\s*($zero_initializer)\s*;/) {
3629d5e616fcSJoe Perches			if (ERROR("GLOBAL_INITIALISERS",
36306d32f7a3SJoe Perches				  "do not initialise globals to $1\n" . $herecurr) &&
3631d5e616fcSJoe Perches			    $fix) {
36326d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(^.$Type\s*$Ident(?:\s+$Modifier)*)\s*=\s*$zero_initializer\s*;/$1;/;
3633d5e616fcSJoe Perches			}
3634f0a594c1SAndy Whitcroft		}
36350a920b5bSAndy Whitcroft# check for static initialisers.
36366d32f7a3SJoe Perches		if ($line =~ /^\+.*\bstatic\s.*=\s*($zero_initializer)\s*;/) {
3637d5e616fcSJoe Perches			if (ERROR("INITIALISED_STATIC",
36386d32f7a3SJoe Perches				  "do not initialise statics to $1\n" .
3639d5e616fcSJoe Perches				      $herecurr) &&
3640d5e616fcSJoe Perches			    $fix) {
36416d32f7a3SJoe Perches				$fixed[$fixlinenr] =~ s/(\bstatic\s.*?)\s*=\s*$zero_initializer\s*;/$1;/;
3642d5e616fcSJoe Perches			}
36430a920b5bSAndy Whitcroft		}
36440a920b5bSAndy Whitcroft
36451813087dSJoe Perches# check for misordered declarations of char/short/int/long with signed/unsigned
36461813087dSJoe Perches		while ($sline =~ m{(\b$TypeMisordered\b)}g) {
36471813087dSJoe Perches			my $tmp = trim($1);
36481813087dSJoe Perches			WARN("MISORDERED_TYPE",
36491813087dSJoe Perches			     "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr);
36501813087dSJoe Perches		}
36511813087dSJoe Perches
3652cb710ecaSJoe Perches# check for static const char * arrays.
3653cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
3654000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
3655000d1cc1SJoe Perches			     "static const char * array should probably be static const char * const\n" .
3656cb710ecaSJoe Perches				$herecurr);
3657cb710ecaSJoe Perches               }
3658cb710ecaSJoe Perches
3659cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations.
3660cb710ecaSJoe Perches		if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
3661000d1cc1SJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
3662000d1cc1SJoe Perches			     "static char array declaration should probably be static const char\n" .
3663cb710ecaSJoe Perches				$herecurr);
3664cb710ecaSJoe Perches               }
3665cb710ecaSJoe Perches
3666ab7e23f3SJoe Perches# check for const <foo> const where <foo> is not a pointer or array type
3667ab7e23f3SJoe Perches		if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) {
3668ab7e23f3SJoe Perches			my $found = $1;
3669ab7e23f3SJoe Perches			if ($sline =~ /\bconst\s+\Q$found\E\s+const\b\s*\*/) {
3670ab7e23f3SJoe Perches				WARN("CONST_CONST",
3671ab7e23f3SJoe Perches				     "'const $found const *' should probably be 'const $found * const'\n" . $herecurr);
3672ab7e23f3SJoe Perches			} elsif ($sline !~ /\bconst\s+\Q$found\E\s+const\s+\w+\s*\[/) {
3673ab7e23f3SJoe Perches				WARN("CONST_CONST",
3674ab7e23f3SJoe Perches				     "'const $found const' should probably be 'const $found'\n" . $herecurr);
3675ab7e23f3SJoe Perches			}
3676ab7e23f3SJoe Perches		}
3677ab7e23f3SJoe Perches
36789b0fa60dSJoe Perches# check for non-global char *foo[] = {"bar", ...} declarations.
36799b0fa60dSJoe Perches		if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
36809b0fa60dSJoe Perches			WARN("STATIC_CONST_CHAR_ARRAY",
36819b0fa60dSJoe Perches			     "char * array declaration might be better as static const\n" .
36829b0fa60dSJoe Perches				$herecurr);
36839b0fa60dSJoe Perches               }
36849b0fa60dSJoe Perches
3685b598b670SJoe Perches# check for sizeof(foo)/sizeof(foo[0]) that could be ARRAY_SIZE(foo)
3686b598b670SJoe Perches		if ($line =~ m@\bsizeof\s*\(\s*($Lval)\s*\)@) {
3687b598b670SJoe Perches			my $array = $1;
3688b598b670SJoe 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*\))@) {
3689b598b670SJoe Perches				my $array_div = $1;
3690b598b670SJoe Perches				if (WARN("ARRAY_SIZE",
3691b598b670SJoe Perches					 "Prefer ARRAY_SIZE($array)\n" . $herecurr) &&
3692b598b670SJoe Perches				    $fix) {
3693b598b670SJoe Perches					$fixed[$fixlinenr] =~ s/\Q$array_div\E/ARRAY_SIZE($array)/;
3694b598b670SJoe Perches				}
3695b598b670SJoe Perches			}
3696b598b670SJoe Perches		}
3697b598b670SJoe Perches
3698b36190c5SJoe Perches# check for function declarations without arguments like "int foo()"
3699b36190c5SJoe Perches		if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) {
3700b36190c5SJoe Perches			if (ERROR("FUNCTION_WITHOUT_ARGS",
3701b36190c5SJoe Perches				  "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
3702b36190c5SJoe Perches			    $fix) {
3703194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
3704b36190c5SJoe Perches			}
3705b36190c5SJoe Perches		}
3706b36190c5SJoe Perches
3707653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations
3708653d4876SAndy Whitcroft# make sense.
3709653d4876SAndy Whitcroft		if ($line =~ /\btypedef\s/ &&
37108054576dSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
3711c45dcabdSAndy Whitcroft		    $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
37128ed22cadSAndy Whitcroft		    $line !~ /\b$typeTypedefs\b/ &&
371346d832f5SMichael S. Tsirkin		    $line !~ /\b__bitwise\b/) {
3714000d1cc1SJoe Perches			WARN("NEW_TYPEDEFS",
3715000d1cc1SJoe Perches			     "do not add new typedefs\n" . $herecurr);
37160a920b5bSAndy Whitcroft		}
37170a920b5bSAndy Whitcroft
37180a920b5bSAndy Whitcroft# * goes on variable not on type
371965863862SAndy Whitcroft		# (char*[ const])
3720bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
3721bfcb2cc7SAndy Whitcroft			#print "AA<$1>\n";
37223705ce5bSJoe Perches			my ($ident, $from, $to) = ($1, $2, $2);
3723d8aaf121SAndy Whitcroft
372465863862SAndy Whitcroft			# Should start with a space.
372565863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
372665863862SAndy Whitcroft			# Should not end with a space.
372765863862SAndy Whitcroft			$to =~ s/\s+$//;
372865863862SAndy Whitcroft			# '*'s should not have spaces between.
3729f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
373065863862SAndy Whitcroft			}
3731d8aaf121SAndy Whitcroft
37323705ce5bSJoe Perches##			print "1: from<$from> to<$to> ident<$ident>\n";
373365863862SAndy Whitcroft			if ($from ne $to) {
37343705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
37353705ce5bSJoe Perches					  "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
37363705ce5bSJoe Perches				    $fix) {
37373705ce5bSJoe Perches					my $sub_from = $ident;
37383705ce5bSJoe Perches					my $sub_to = $ident;
37393705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
3740194f66fcSJoe Perches					$fixed[$fixlinenr] =~
37413705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
37423705ce5bSJoe Perches				}
374365863862SAndy Whitcroft			}
3744bfcb2cc7SAndy Whitcroft		}
3745bfcb2cc7SAndy Whitcroft		while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
3746bfcb2cc7SAndy Whitcroft			#print "BB<$1>\n";
37473705ce5bSJoe Perches			my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
3748d8aaf121SAndy Whitcroft
374965863862SAndy Whitcroft			# Should start with a space.
375065863862SAndy Whitcroft			$to =~ s/^(\S)/ $1/;
375165863862SAndy Whitcroft			# Should not end with a space.
375265863862SAndy Whitcroft			$to =~ s/\s+$//;
375365863862SAndy Whitcroft			# '*'s should not have spaces between.
3754f9a0b3d1SAndy Whitcroft			while ($to =~ s/\*\s+\*/\*\*/) {
375565863862SAndy Whitcroft			}
375665863862SAndy Whitcroft			# Modifiers should have spaces.
375765863862SAndy Whitcroft			$to =~ s/(\b$Modifier$)/$1 /;
375865863862SAndy Whitcroft
37593705ce5bSJoe Perches##			print "2: from<$from> to<$to> ident<$ident>\n";
3760667026e7SAndy Whitcroft			if ($from ne $to && $ident !~ /^$Modifier$/) {
37613705ce5bSJoe Perches				if (ERROR("POINTER_LOCATION",
37623705ce5bSJoe Perches					  "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
37633705ce5bSJoe Perches				    $fix) {
37643705ce5bSJoe Perches
37653705ce5bSJoe Perches					my $sub_from = $match;
37663705ce5bSJoe Perches					my $sub_to = $match;
37673705ce5bSJoe Perches					$sub_to =~ s/\Q$from\E/$to/;
3768194f66fcSJoe Perches					$fixed[$fixlinenr] =~
37693705ce5bSJoe Perches					    s@\Q$sub_from\E@$sub_to@;
37703705ce5bSJoe Perches				}
377165863862SAndy Whitcroft			}
37720a920b5bSAndy Whitcroft		}
37730a920b5bSAndy Whitcroft
37749d3e3c70SJoe Perches# avoid BUG() or BUG_ON()
37759d3e3c70SJoe Perches		if ($line =~ /\b(?:BUG|BUG_ON)\b/) {
37769d3e3c70SJoe Perches			my $msg_type = \&WARN;
37779d3e3c70SJoe Perches			$msg_type = \&CHK if ($file);
37789d3e3c70SJoe Perches			&{$msg_type}("AVOID_BUG",
37799d3e3c70SJoe Perches				     "Avoid crashing the kernel - try using WARN_ON & recovery code rather than BUG() or BUG_ON()\n" . $herecurr);
37809d3e3c70SJoe Perches		}
37810a920b5bSAndy Whitcroft
37829d3e3c70SJoe Perches# avoid LINUX_VERSION_CODE
37838905a67cSAndy Whitcroft		if ($line =~ /\bLINUX_VERSION_CODE\b/) {
3784000d1cc1SJoe Perches			WARN("LINUX_VERSION_CODE",
3785000d1cc1SJoe Perches			     "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
37868905a67cSAndy Whitcroft		}
37878905a67cSAndy Whitcroft
378817441227SJoe Perches# check for uses of printk_ratelimit
378917441227SJoe Perches		if ($line =~ /\bprintk_ratelimit\s*\(/) {
3790000d1cc1SJoe Perches			WARN("PRINTK_RATELIMITED",
3791000d1cc1SJoe Perches			     "Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr);
379217441227SJoe Perches		}
379317441227SJoe Perches
379400df344fSAndy Whitcroft# printk should use KERN_* levels.  Note that follow on printk's on the
379500df344fSAndy Whitcroft# same line do not need a level, so we use the current block context
379600df344fSAndy Whitcroft# to try and find and validate the current printk.  In summary the current
379725985edcSLucas De Marchi# printk includes all preceding printk's which have no newline on the end.
379800df344fSAndy Whitcroft# we assume the first bad printk is the one to report.
3799f0a594c1SAndy Whitcroft		if ($line =~ /\bprintk\((?!KERN_)\s*"/) {
380000df344fSAndy Whitcroft			my $ok = 0;
380100df344fSAndy Whitcroft			for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) {
380200df344fSAndy Whitcroft				#print "CHECK<$lines[$ln - 1]\n";
380325985edcSLucas De Marchi				# we have a preceding printk if it ends
380400df344fSAndy Whitcroft				# with "\n" ignore it, else it is to blame
380500df344fSAndy Whitcroft				if ($lines[$ln - 1] =~ m{\bprintk\(}) {
380600df344fSAndy Whitcroft					if ($rawlines[$ln - 1] !~ m{\\n"}) {
380700df344fSAndy Whitcroft						$ok = 1;
380800df344fSAndy Whitcroft					}
380900df344fSAndy Whitcroft					last;
381000df344fSAndy Whitcroft				}
381100df344fSAndy Whitcroft			}
381200df344fSAndy Whitcroft			if ($ok == 0) {
3813000d1cc1SJoe Perches				WARN("PRINTK_WITHOUT_KERN_LEVEL",
3814000d1cc1SJoe Perches				     "printk() should include KERN_ facility level\n" . $herecurr);
38150a920b5bSAndy Whitcroft			}
381600df344fSAndy Whitcroft		}
38170a920b5bSAndy Whitcroft
3818243f3803SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) {
3819243f3803SJoe Perches			my $orig = $1;
3820243f3803SJoe Perches			my $level = lc($orig);
3821243f3803SJoe Perches			$level = "warn" if ($level eq "warning");
38228f26b837SJoe Perches			my $level2 = $level;
38238f26b837SJoe Perches			$level2 = "dbg" if ($level eq "debug");
3824243f3803SJoe Perches			WARN("PREFER_PR_LEVEL",
3825daa8b059SYogesh Chaudhari			     "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(...  to printk(KERN_$orig ...\n" . $herecurr);
3826243f3803SJoe Perches		}
3827243f3803SJoe Perches
3828243f3803SJoe Perches		if ($line =~ /\bpr_warning\s*\(/) {
3829d5e616fcSJoe Perches			if (WARN("PREFER_PR_LEVEL",
3830d5e616fcSJoe Perches				 "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) &&
3831d5e616fcSJoe Perches			    $fix) {
3832194f66fcSJoe Perches				$fixed[$fixlinenr] =~
3833d5e616fcSJoe Perches				    s/\bpr_warning\b/pr_warn/;
3834d5e616fcSJoe Perches			}
3835243f3803SJoe Perches		}
3836243f3803SJoe Perches
3837dc139313SJoe Perches		if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
3838dc139313SJoe Perches			my $orig = $1;
3839dc139313SJoe Perches			my $level = lc($orig);
3840dc139313SJoe Perches			$level = "warn" if ($level eq "warning");
3841dc139313SJoe Perches			$level = "dbg" if ($level eq "debug");
3842dc139313SJoe Perches			WARN("PREFER_DEV_LEVEL",
3843dc139313SJoe Perches			     "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr);
3844dc139313SJoe Perches		}
3845dc139313SJoe Perches
384691c9afafSAndy Lutomirski# ENOSYS means "bad syscall nr" and nothing else.  This will have a small
384791c9afafSAndy Lutomirski# number of false positives, but assembly files are not checked, so at
384891c9afafSAndy Lutomirski# least the arch entry code will not trigger this warning.
384991c9afafSAndy Lutomirski		if ($line =~ /\bENOSYS\b/) {
385091c9afafSAndy Lutomirski			WARN("ENOSYS",
385191c9afafSAndy Lutomirski			     "ENOSYS means 'invalid syscall nr' and nothing else\n" . $herecurr);
385291c9afafSAndy Lutomirski		}
385391c9afafSAndy Lutomirski
3854653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while,
3855653d4876SAndy Whitcroft# or if closed on same line
38568d182478SJoe Perches		if (($line=~/$Type\s*$Ident\(.*\).*\s*{/) and
38574e5d56bdSEddie Kovsky		    !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) {
38588d182478SJoe Perches			if (ERROR("OPEN_BRACE",
38598d182478SJoe Perches				  "open brace '{' following function declarations go on the next line\n" . $herecurr) &&
38608d182478SJoe Perches			    $fix) {
38618d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
38628d182478SJoe Perches				my $fixed_line = $rawline;
38638d182478SJoe Perches				$fixed_line =~ /(^..*$Type\s*$Ident\(.*\)\s*){(.*)$/;
38648d182478SJoe Perches				my $line1 = $1;
38658d182478SJoe Perches				my $line2 = $2;
38668d182478SJoe Perches				fix_insert_line($fixlinenr, ltrim($line1));
38678d182478SJoe Perches				fix_insert_line($fixlinenr, "\+{");
38688d182478SJoe Perches				if ($line2 !~ /^\s*$/) {
38698d182478SJoe Perches					fix_insert_line($fixlinenr, "\+\t" . trim($line2));
38708d182478SJoe Perches				}
38718d182478SJoe Perches			}
38720a920b5bSAndy Whitcroft		}
3873653d4876SAndy Whitcroft
38748905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line.
38758905a67cSAndy Whitcroft		if ($line =~ /^.\s*{/ &&
38768905a67cSAndy Whitcroft		    $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
38778d182478SJoe Perches			if (ERROR("OPEN_BRACE",
38788d182478SJoe Perches				  "open brace '{' following $1 go on the same line\n" . $hereprev) &&
38798d182478SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
38808d182478SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
38818d182478SJoe Perches				fix_delete_line($fixlinenr, $rawline);
38828d182478SJoe Perches				my $fixedline = rtrim($prevrawline) . " {";
38838d182478SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
38848d182478SJoe Perches				$fixedline = $rawline;
38858d182478SJoe Perches				$fixedline =~ s/^(.\s*){\s*/$1\t/;
38868d182478SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
38878d182478SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
38888d182478SJoe Perches				}
38898d182478SJoe Perches			}
38908905a67cSAndy Whitcroft		}
38918905a67cSAndy Whitcroft
38920c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition
38933705ce5bSJoe Perches		if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
38943705ce5bSJoe Perches			if (WARN("SPACING",
38953705ce5bSJoe Perches				 "missing space after $1 definition\n" . $herecurr) &&
38963705ce5bSJoe Perches			    $fix) {
3897194f66fcSJoe Perches				$fixed[$fixlinenr] =~
38983705ce5bSJoe Perches				    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
38993705ce5bSJoe Perches			}
39000c73b4ebSAndy Whitcroft		}
39010c73b4ebSAndy Whitcroft
390231070b5dSJoe Perches# Function pointer declarations
390331070b5dSJoe Perches# check spacing between type, funcptr, and args
390431070b5dSJoe Perches# canonical declaration is "type (*funcptr)(args...)"
390591f72e9cSJoe Perches		if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
390631070b5dSJoe Perches			my $declare = $1;
390731070b5dSJoe Perches			my $pre_pointer_space = $2;
390831070b5dSJoe Perches			my $post_pointer_space = $3;
390931070b5dSJoe Perches			my $funcname = $4;
391031070b5dSJoe Perches			my $post_funcname_space = $5;
391131070b5dSJoe Perches			my $pre_args_space = $6;
391231070b5dSJoe Perches
391391f72e9cSJoe Perches# the $Declare variable will capture all spaces after the type
391491f72e9cSJoe Perches# so check it for a missing trailing missing space but pointer return types
391591f72e9cSJoe Perches# don't need a space so don't warn for those.
391691f72e9cSJoe Perches			my $post_declare_space = "";
391791f72e9cSJoe Perches			if ($declare =~ /(\s+)$/) {
391891f72e9cSJoe Perches				$post_declare_space = $1;
391991f72e9cSJoe Perches				$declare = rtrim($declare);
392091f72e9cSJoe Perches			}
392191f72e9cSJoe Perches			if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
392231070b5dSJoe Perches				WARN("SPACING",
392331070b5dSJoe Perches				     "missing space after return type\n" . $herecurr);
392491f72e9cSJoe Perches				$post_declare_space = " ";
392531070b5dSJoe Perches			}
392631070b5dSJoe Perches
392731070b5dSJoe Perches# unnecessary space "type  (*funcptr)(args...)"
392891f72e9cSJoe Perches# This test is not currently implemented because these declarations are
392991f72e9cSJoe Perches# equivalent to
393091f72e9cSJoe Perches#	int  foo(int bar, ...)
393191f72e9cSJoe Perches# and this is form shouldn't/doesn't generate a checkpatch warning.
393291f72e9cSJoe Perches#
393391f72e9cSJoe Perches#			elsif ($declare =~ /\s{2,}$/) {
393491f72e9cSJoe Perches#				WARN("SPACING",
393591f72e9cSJoe Perches#				     "Multiple spaces after return type\n" . $herecurr);
393691f72e9cSJoe Perches#			}
393731070b5dSJoe Perches
393831070b5dSJoe Perches# unnecessary space "type ( *funcptr)(args...)"
393931070b5dSJoe Perches			if (defined $pre_pointer_space &&
394031070b5dSJoe Perches			    $pre_pointer_space =~ /^\s/) {
394131070b5dSJoe Perches				WARN("SPACING",
394231070b5dSJoe Perches				     "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
394331070b5dSJoe Perches			}
394431070b5dSJoe Perches
394531070b5dSJoe Perches# unnecessary space "type (* funcptr)(args...)"
394631070b5dSJoe Perches			if (defined $post_pointer_space &&
394731070b5dSJoe Perches			    $post_pointer_space =~ /^\s/) {
394831070b5dSJoe Perches				WARN("SPACING",
394931070b5dSJoe Perches				     "Unnecessary space before function pointer name\n" . $herecurr);
395031070b5dSJoe Perches			}
395131070b5dSJoe Perches
395231070b5dSJoe Perches# unnecessary space "type (*funcptr )(args...)"
395331070b5dSJoe Perches			if (defined $post_funcname_space &&
395431070b5dSJoe Perches			    $post_funcname_space =~ /^\s/) {
395531070b5dSJoe Perches				WARN("SPACING",
395631070b5dSJoe Perches				     "Unnecessary space after function pointer name\n" . $herecurr);
395731070b5dSJoe Perches			}
395831070b5dSJoe Perches
395931070b5dSJoe Perches# unnecessary space "type (*funcptr) (args...)"
396031070b5dSJoe Perches			if (defined $pre_args_space &&
396131070b5dSJoe Perches			    $pre_args_space =~ /^\s/) {
396231070b5dSJoe Perches				WARN("SPACING",
396331070b5dSJoe Perches				     "Unnecessary space before function pointer arguments\n" . $herecurr);
396431070b5dSJoe Perches			}
396531070b5dSJoe Perches
396631070b5dSJoe Perches			if (show_type("SPACING") && $fix) {
3967194f66fcSJoe Perches				$fixed[$fixlinenr] =~
396891f72e9cSJoe Perches				    s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
396931070b5dSJoe Perches			}
397031070b5dSJoe Perches		}
397131070b5dSJoe Perches
39728d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed:
39738d31cfceSAndy Whitcroft#  1. with a type on the left -- int [] a;
3974fe2a7dbcSAndy Whitcroft#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
3975fe2a7dbcSAndy Whitcroft#  3. inside a curly brace -- = { [0...10] = 5 }
39768d31cfceSAndy Whitcroft		while ($line =~ /(.*?\s)\[/g) {
39778d31cfceSAndy Whitcroft			my ($where, $prefix) = ($-[1], $1);
39788d31cfceSAndy Whitcroft			if ($prefix !~ /$Type\s+$/ &&
3979fe2a7dbcSAndy Whitcroft			    ($where != 0 || $prefix !~ /^.\s+$/) &&
3980daebc534SAndy Whitcroft			    $prefix !~ /[{,]\s+$/) {
39813705ce5bSJoe Perches				if (ERROR("BRACKET_SPACE",
39823705ce5bSJoe Perches					  "space prohibited before open square bracket '['\n" . $herecurr) &&
39833705ce5bSJoe Perches				    $fix) {
3984194f66fcSJoe Perches				    $fixed[$fixlinenr] =~
39853705ce5bSJoe Perches					s/^(\+.*?)\s+\[/$1\[/;
39863705ce5bSJoe Perches				}
39878d31cfceSAndy Whitcroft			}
39888d31cfceSAndy Whitcroft		}
39898d31cfceSAndy Whitcroft
3990f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses.
39916c72ffaaSAndy Whitcroft		while ($line =~ /($Ident)\s+\(/g) {
3992c2fdda0dSAndy Whitcroft			my $name = $1;
3993773647a0SAndy Whitcroft			my $ctx_before = substr($line, 0, $-[1]);
3994773647a0SAndy Whitcroft			my $ctx = "$ctx_before$name";
3995c2fdda0dSAndy Whitcroft
3996c2fdda0dSAndy Whitcroft			# Ignore those directives where spaces _are_ permitted.
3997773647a0SAndy Whitcroft			if ($name =~ /^(?:
3998773647a0SAndy Whitcroft				if|for|while|switch|return|case|
3999773647a0SAndy Whitcroft				volatile|__volatile__|
4000773647a0SAndy Whitcroft				__attribute__|format|__extension__|
4001773647a0SAndy Whitcroft				asm|__asm__)$/x)
4002773647a0SAndy Whitcroft			{
4003c2fdda0dSAndy Whitcroft			# cpp #define statements have non-optional spaces, ie
4004c2fdda0dSAndy Whitcroft			# if there is a space between the name and the open
4005c2fdda0dSAndy Whitcroft			# parenthesis it is simply not a parameter group.
4006c45dcabdSAndy Whitcroft			} elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
4007773647a0SAndy Whitcroft
4008773647a0SAndy Whitcroft			# cpp #elif statement condition may start with a (
4009c45dcabdSAndy Whitcroft			} elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
4010c2fdda0dSAndy Whitcroft
4011c2fdda0dSAndy Whitcroft			# If this whole things ends with a type its most
4012c2fdda0dSAndy Whitcroft			# likely a typedef for a function.
4013773647a0SAndy Whitcroft			} elsif ($ctx =~ /$Type$/) {
4014c2fdda0dSAndy Whitcroft
4015c2fdda0dSAndy Whitcroft			} else {
40163705ce5bSJoe Perches				if (WARN("SPACING",
40173705ce5bSJoe Perches					 "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
40183705ce5bSJoe Perches					     $fix) {
4019194f66fcSJoe Perches					$fixed[$fixlinenr] =~
40203705ce5bSJoe Perches					    s/\b$name\s+\(/$name\(/;
40213705ce5bSJoe Perches				}
4022f0a594c1SAndy Whitcroft			}
40236c72ffaaSAndy Whitcroft		}
40249a4cad4eSEric Nelson
4025653d4876SAndy Whitcroft# Check operator spacing.
40260a920b5bSAndy Whitcroft		if (!($line=~/\#\s*include/)) {
40273705ce5bSJoe Perches			my $fixed_line = "";
40283705ce5bSJoe Perches			my $line_fixed = 0;
40293705ce5bSJoe Perches
40309c0ca6f9SAndy Whitcroft			my $ops = qr{
40319c0ca6f9SAndy Whitcroft				<<=|>>=|<=|>=|==|!=|
40329c0ca6f9SAndy Whitcroft				\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
40339c0ca6f9SAndy Whitcroft				=>|->|<<|>>|<|>|=|!|~|
40341f65f947SAndy Whitcroft				&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
403584731623SJoe Perches				\?:|\?|:
40369c0ca6f9SAndy Whitcroft			}x;
4037cf655043SAndy Whitcroft			my @elements = split(/($ops|;)/, $opline);
40383705ce5bSJoe Perches
40393705ce5bSJoe Perches##			print("element count: <" . $#elements . ">\n");
40403705ce5bSJoe Perches##			foreach my $el (@elements) {
40413705ce5bSJoe Perches##				print("el: <$el>\n");
40423705ce5bSJoe Perches##			}
40433705ce5bSJoe Perches
40443705ce5bSJoe Perches			my @fix_elements = ();
404500df344fSAndy Whitcroft			my $off = 0;
40466c72ffaaSAndy Whitcroft
40473705ce5bSJoe Perches			foreach my $el (@elements) {
40483705ce5bSJoe Perches				push(@fix_elements, substr($rawline, $off, length($el)));
40493705ce5bSJoe Perches				$off += length($el);
40503705ce5bSJoe Perches			}
40513705ce5bSJoe Perches
40523705ce5bSJoe Perches			$off = 0;
40533705ce5bSJoe Perches
40546c72ffaaSAndy Whitcroft			my $blank = copy_spacing($opline);
4055b34c648bSJoe Perches			my $last_after = -1;
40566c72ffaaSAndy Whitcroft
40570a920b5bSAndy Whitcroft			for (my $n = 0; $n < $#elements; $n += 2) {
40583705ce5bSJoe Perches
40593705ce5bSJoe Perches				my $good = $fix_elements[$n] . $fix_elements[$n + 1];
40603705ce5bSJoe Perches
40613705ce5bSJoe Perches##				print("n: <$n> good: <$good>\n");
40623705ce5bSJoe Perches
40634a0df2efSAndy Whitcroft				$off += length($elements[$n]);
40644a0df2efSAndy Whitcroft
406525985edcSLucas De Marchi				# Pick up the preceding and succeeding characters.
4066773647a0SAndy Whitcroft				my $ca = substr($opline, 0, $off);
4067773647a0SAndy Whitcroft				my $cc = '';
4068773647a0SAndy Whitcroft				if (length($opline) >= ($off + length($elements[$n + 1]))) {
4069773647a0SAndy Whitcroft					$cc = substr($opline, $off + length($elements[$n + 1]));
4070773647a0SAndy Whitcroft				}
4071773647a0SAndy Whitcroft				my $cb = "$ca$;$cc";
4072773647a0SAndy Whitcroft
40734a0df2efSAndy Whitcroft				my $a = '';
40744a0df2efSAndy Whitcroft				$a = 'V' if ($elements[$n] ne '');
40754a0df2efSAndy Whitcroft				$a = 'W' if ($elements[$n] =~ /\s$/);
4076cf655043SAndy Whitcroft				$a = 'C' if ($elements[$n] =~ /$;$/);
40774a0df2efSAndy Whitcroft				$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
40784a0df2efSAndy Whitcroft				$a = 'O' if ($elements[$n] eq '');
4079773647a0SAndy Whitcroft				$a = 'E' if ($ca =~ /^\s*$/);
40804a0df2efSAndy Whitcroft
40810a920b5bSAndy Whitcroft				my $op = $elements[$n + 1];
40824a0df2efSAndy Whitcroft
40834a0df2efSAndy Whitcroft				my $c = '';
40840a920b5bSAndy Whitcroft				if (defined $elements[$n + 2]) {
40854a0df2efSAndy Whitcroft					$c = 'V' if ($elements[$n + 2] ne '');
40864a0df2efSAndy Whitcroft					$c = 'W' if ($elements[$n + 2] =~ /^\s/);
4087cf655043SAndy Whitcroft					$c = 'C' if ($elements[$n + 2] =~ /^$;/);
40884a0df2efSAndy Whitcroft					$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
40894a0df2efSAndy Whitcroft					$c = 'O' if ($elements[$n + 2] eq '');
40908b1b3378SAndy Whitcroft					$c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
40914a0df2efSAndy Whitcroft				} else {
40924a0df2efSAndy Whitcroft					$c = 'E';
40930a920b5bSAndy Whitcroft				}
40940a920b5bSAndy Whitcroft
40954a0df2efSAndy Whitcroft				my $ctx = "${a}x${c}";
40964a0df2efSAndy Whitcroft
40974a0df2efSAndy Whitcroft				my $at = "(ctx:$ctx)";
40984a0df2efSAndy Whitcroft
40996c72ffaaSAndy Whitcroft				my $ptr = substr($blank, 0, $off) . "^";
4100de7d4f0eSAndy Whitcroft				my $hereptr = "$hereline$ptr\n";
41010a920b5bSAndy Whitcroft
410274048ed8SAndy Whitcroft				# Pull out the value of this operator.
41036c72ffaaSAndy Whitcroft				my $op_type = substr($curr_values, $off + 1, 1);
41040a920b5bSAndy Whitcroft
41051f65f947SAndy Whitcroft				# Get the full operator variant.
41061f65f947SAndy Whitcroft				my $opv = $op . substr($curr_vars, $off, 1);
41071f65f947SAndy Whitcroft
410813214adfSAndy Whitcroft				# Ignore operators passed as parameters.
410913214adfSAndy Whitcroft				if ($op_type ne 'V' &&
4110d7fe8065SSam Bobroff				    $ca =~ /\s$/ && $cc =~ /^\s*[,\)]/) {
411113214adfSAndy Whitcroft
4112cf655043SAndy Whitcroft#				# Ignore comments
4113cf655043SAndy Whitcroft#				} elsif ($op =~ /^$;+$/) {
411413214adfSAndy Whitcroft
4115d8aaf121SAndy Whitcroft				# ; should have either the end of line or a space or \ after it
411613214adfSAndy Whitcroft				} elsif ($op eq ';') {
4117cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEBC]/ &&
4118cf655043SAndy Whitcroft					    $cc !~ /^\\/ && $cc !~ /^;/) {
41193705ce5bSJoe Perches						if (ERROR("SPACING",
41203705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
4121b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
41223705ce5bSJoe Perches							$line_fixed = 1;
41233705ce5bSJoe Perches						}
4124d8aaf121SAndy Whitcroft					}
4125d8aaf121SAndy Whitcroft
4126d8aaf121SAndy Whitcroft				# // is a comment
4127d8aaf121SAndy Whitcroft				} elsif ($op eq '//') {
41280a920b5bSAndy Whitcroft
4129b00e4814SJoe Perches				#   :   when part of a bitfield
4130b00e4814SJoe Perches				} elsif ($opv eq ':B') {
4131b00e4814SJoe Perches					# skip the bitfield test for now
4132b00e4814SJoe Perches
41331f65f947SAndy Whitcroft				# No spaces for:
41341f65f947SAndy Whitcroft				#   ->
4135b00e4814SJoe Perches				} elsif ($op eq '->') {
41364a0df2efSAndy Whitcroft					if ($ctx =~ /Wx.|.xW/) {
41373705ce5bSJoe Perches						if (ERROR("SPACING",
41383705ce5bSJoe Perches							  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
4139b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
41403705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
41413705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
41423705ce5bSJoe Perches							}
4143b34c648bSJoe Perches							$line_fixed = 1;
41443705ce5bSJoe Perches						}
41450a920b5bSAndy Whitcroft					}
41460a920b5bSAndy Whitcroft
41472381097bSJoe Perches				# , must not have a space before and must have a space on the right.
41480a920b5bSAndy Whitcroft				} elsif ($op eq ',') {
41492381097bSJoe Perches					my $rtrim_before = 0;
41502381097bSJoe Perches					my $space_after = 0;
41512381097bSJoe Perches					if ($ctx =~ /Wx./) {
41522381097bSJoe Perches						if (ERROR("SPACING",
41532381097bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
41542381097bSJoe Perches							$line_fixed = 1;
41552381097bSJoe Perches							$rtrim_before = 1;
41562381097bSJoe Perches						}
41572381097bSJoe Perches					}
4158cf655043SAndy Whitcroft					if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
41593705ce5bSJoe Perches						if (ERROR("SPACING",
41603705ce5bSJoe Perches							  "space required after that '$op' $at\n" . $hereptr)) {
41613705ce5bSJoe Perches							$line_fixed = 1;
4162b34c648bSJoe Perches							$last_after = $n;
41632381097bSJoe Perches							$space_after = 1;
41642381097bSJoe Perches						}
41652381097bSJoe Perches					}
41662381097bSJoe Perches					if ($rtrim_before || $space_after) {
41672381097bSJoe Perches						if ($rtrim_before) {
41682381097bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
41692381097bSJoe Perches						} else {
41702381097bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
41712381097bSJoe Perches						}
41722381097bSJoe Perches						if ($space_after) {
41732381097bSJoe Perches							$good .= " ";
41743705ce5bSJoe Perches						}
41750a920b5bSAndy Whitcroft					}
41760a920b5bSAndy Whitcroft
41779c0ca6f9SAndy Whitcroft				# '*' as part of a type definition -- reported already.
417874048ed8SAndy Whitcroft				} elsif ($opv eq '*_') {
41799c0ca6f9SAndy Whitcroft					#warn "'*' is part of type\n";
41809c0ca6f9SAndy Whitcroft
41819c0ca6f9SAndy Whitcroft				# unary operators should have a space before and
41829c0ca6f9SAndy Whitcroft				# none after.  May be left adjacent to another
41839c0ca6f9SAndy Whitcroft				# unary operator, or a cast
41849c0ca6f9SAndy Whitcroft				} elsif ($op eq '!' || $op eq '~' ||
418574048ed8SAndy Whitcroft					 $opv eq '*U' || $opv eq '-U' ||
41860d413866SAndy Whitcroft					 $opv eq '&U' || $opv eq '&&U') {
4187cf655043SAndy Whitcroft					if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
41883705ce5bSJoe Perches						if (ERROR("SPACING",
41893705ce5bSJoe Perches							  "space required before that '$op' $at\n" . $hereptr)) {
4190b34c648bSJoe Perches							if ($n != $last_after + 2) {
4191b34c648bSJoe Perches								$good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
41923705ce5bSJoe Perches								$line_fixed = 1;
41933705ce5bSJoe Perches							}
41940a920b5bSAndy Whitcroft						}
4195b34c648bSJoe Perches					}
4196a3340b35SAndy Whitcroft					if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
4197171ae1a4SAndy Whitcroft						# A unary '*' may be const
4198171ae1a4SAndy Whitcroft
4199171ae1a4SAndy Whitcroft					} elsif ($ctx =~ /.xW/) {
42003705ce5bSJoe Perches						if (ERROR("SPACING",
42013705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
4202b34c648bSJoe Perches							$good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
42033705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
42043705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
42053705ce5bSJoe Perches							}
4206b34c648bSJoe Perches							$line_fixed = 1;
42073705ce5bSJoe Perches						}
42080a920b5bSAndy Whitcroft					}
42090a920b5bSAndy Whitcroft
42100a920b5bSAndy Whitcroft				# unary ++ and unary -- are allowed no space on one side.
42110a920b5bSAndy Whitcroft				} elsif ($op eq '++' or $op eq '--') {
4212773647a0SAndy Whitcroft					if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
42133705ce5bSJoe Perches						if (ERROR("SPACING",
42143705ce5bSJoe Perches							  "space required one side of that '$op' $at\n" . $hereptr)) {
4215b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
42163705ce5bSJoe Perches							$line_fixed = 1;
42173705ce5bSJoe Perches						}
42180a920b5bSAndy Whitcroft					}
4219773647a0SAndy Whitcroft					if ($ctx =~ /Wx[BE]/ ||
4220773647a0SAndy Whitcroft					    ($ctx =~ /Wx./ && $cc =~ /^;/)) {
42213705ce5bSJoe Perches						if (ERROR("SPACING",
42223705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
4223b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
42243705ce5bSJoe Perches							$line_fixed = 1;
42253705ce5bSJoe Perches						}
4226653d4876SAndy Whitcroft					}
4227773647a0SAndy Whitcroft					if ($ctx =~ /ExW/) {
42283705ce5bSJoe Perches						if (ERROR("SPACING",
42293705ce5bSJoe Perches							  "space prohibited after that '$op' $at\n" . $hereptr)) {
4230b34c648bSJoe Perches							$good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
42313705ce5bSJoe Perches							if (defined $fix_elements[$n + 2]) {
42323705ce5bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4233773647a0SAndy Whitcroft							}
4234b34c648bSJoe Perches							$line_fixed = 1;
42353705ce5bSJoe Perches						}
42363705ce5bSJoe Perches					}
42370a920b5bSAndy Whitcroft
42380a920b5bSAndy Whitcroft				# << and >> may either have or not have spaces both sides
42399c0ca6f9SAndy Whitcroft				} elsif ($op eq '<<' or $op eq '>>' or
42409c0ca6f9SAndy Whitcroft					 $op eq '&' or $op eq '^' or $op eq '|' or
42419c0ca6f9SAndy Whitcroft					 $op eq '+' or $op eq '-' or
4242c2fdda0dSAndy Whitcroft					 $op eq '*' or $op eq '/' or
4243c2fdda0dSAndy Whitcroft					 $op eq '%')
42440a920b5bSAndy Whitcroft				{
4245d2e025f3SJoe Perches					if ($check) {
4246d2e025f3SJoe Perches						if (defined $fix_elements[$n + 2] && $ctx !~ /[EW]x[EW]/) {
4247d2e025f3SJoe Perches							if (CHK("SPACING",
4248d2e025f3SJoe Perches								"spaces preferred around that '$op' $at\n" . $hereptr)) {
4249d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4250d2e025f3SJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4251d2e025f3SJoe Perches								$line_fixed = 1;
4252d2e025f3SJoe Perches							}
4253d2e025f3SJoe Perches						} elsif (!defined $fix_elements[$n + 2] && $ctx !~ /Wx[OE]/) {
4254d2e025f3SJoe Perches							if (CHK("SPACING",
4255d2e025f3SJoe Perches								"space preferred before that '$op' $at\n" . $hereptr)) {
4256d2e025f3SJoe Perches								$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]);
4257d2e025f3SJoe Perches								$line_fixed = 1;
4258d2e025f3SJoe Perches							}
4259d2e025f3SJoe Perches						}
4260d2e025f3SJoe Perches					} elsif ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
42613705ce5bSJoe Perches						if (ERROR("SPACING",
42623705ce5bSJoe Perches							  "need consistent spacing around '$op' $at\n" . $hereptr)) {
4263b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4264b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
4265b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4266b34c648bSJoe Perches							}
42673705ce5bSJoe Perches							$line_fixed = 1;
42683705ce5bSJoe Perches						}
42690a920b5bSAndy Whitcroft					}
42700a920b5bSAndy Whitcroft
42711f65f947SAndy Whitcroft				# A colon needs no spaces before when it is
42721f65f947SAndy Whitcroft				# terminating a case value or a label.
42731f65f947SAndy Whitcroft				} elsif ($opv eq ':C' || $opv eq ':L') {
42741f65f947SAndy Whitcroft					if ($ctx =~ /Wx./) {
42753705ce5bSJoe Perches						if (ERROR("SPACING",
42763705ce5bSJoe Perches							  "space prohibited before that '$op' $at\n" . $hereptr)) {
4277b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
42783705ce5bSJoe Perches							$line_fixed = 1;
42793705ce5bSJoe Perches						}
42801f65f947SAndy Whitcroft					}
42811f65f947SAndy Whitcroft
42820a920b5bSAndy Whitcroft				# All the others need spaces both sides.
4283cf655043SAndy Whitcroft				} elsif ($ctx !~ /[EWC]x[CWE]/) {
42841f65f947SAndy Whitcroft					my $ok = 0;
42851f65f947SAndy Whitcroft
428622f2a2efSAndy Whitcroft					# Ignore email addresses <foo@bar>
42871f65f947SAndy Whitcroft					if (($op eq '<' &&
42881f65f947SAndy Whitcroft					     $cc =~ /^\S+\@\S+>/) ||
42891f65f947SAndy Whitcroft					    ($op eq '>' &&
42901f65f947SAndy Whitcroft					     $ca =~ /<\S+\@\S+$/))
42911f65f947SAndy Whitcroft					{
42921f65f947SAndy Whitcroft					    	$ok = 1;
42931f65f947SAndy Whitcroft					}
42941f65f947SAndy Whitcroft
4295e0df7e1fSJoe Perches					# for asm volatile statements
4296e0df7e1fSJoe Perches					# ignore a colon with another
4297e0df7e1fSJoe Perches					# colon immediately before or after
4298e0df7e1fSJoe Perches					if (($op eq ':') &&
4299e0df7e1fSJoe Perches					    ($ca =~ /:$/ || $cc =~ /^:/)) {
4300e0df7e1fSJoe Perches						$ok = 1;
4301e0df7e1fSJoe Perches					}
4302e0df7e1fSJoe Perches
430384731623SJoe Perches					# messages are ERROR, but ?: are CHK
43041f65f947SAndy Whitcroft					if ($ok == 0) {
430584731623SJoe Perches						my $msg_type = \&ERROR;
430684731623SJoe Perches						$msg_type = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
430784731623SJoe Perches
430884731623SJoe Perches						if (&{$msg_type}("SPACING",
43093705ce5bSJoe Perches								 "spaces required around that '$op' $at\n" . $hereptr)) {
4310b34c648bSJoe Perches							$good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
4311b34c648bSJoe Perches							if (defined $fix_elements[$n + 2]) {
4312b34c648bSJoe Perches								$fix_elements[$n + 2] =~ s/^\s+//;
4313b34c648bSJoe Perches							}
43143705ce5bSJoe Perches							$line_fixed = 1;
43153705ce5bSJoe Perches						}
43160a920b5bSAndy Whitcroft					}
431722f2a2efSAndy Whitcroft				}
43184a0df2efSAndy Whitcroft				$off += length($elements[$n + 1]);
43193705ce5bSJoe Perches
43203705ce5bSJoe Perches##				print("n: <$n> GOOD: <$good>\n");
43213705ce5bSJoe Perches
43223705ce5bSJoe Perches				$fixed_line = $fixed_line . $good;
43230a920b5bSAndy Whitcroft			}
43243705ce5bSJoe Perches
43253705ce5bSJoe Perches			if (($#elements % 2) == 0) {
43263705ce5bSJoe Perches				$fixed_line = $fixed_line . $fix_elements[$#elements];
43273705ce5bSJoe Perches			}
43283705ce5bSJoe Perches
4329194f66fcSJoe Perches			if ($fix && $line_fixed && $fixed_line ne $fixed[$fixlinenr]) {
4330194f66fcSJoe Perches				$fixed[$fixlinenr] = $fixed_line;
43313705ce5bSJoe Perches			}
43323705ce5bSJoe Perches
43333705ce5bSJoe Perches
43340a920b5bSAndy Whitcroft		}
43350a920b5bSAndy Whitcroft
4336786b6326SJoe Perches# check for whitespace before a non-naked semicolon
4337d2e248e7SJoe Perches		if ($line =~ /^\+.*\S\s+;\s*$/) {
4338786b6326SJoe Perches			if (WARN("SPACING",
4339786b6326SJoe Perches				 "space prohibited before semicolon\n" . $herecurr) &&
4340786b6326SJoe Perches			    $fix) {
4341194f66fcSJoe Perches				1 while $fixed[$fixlinenr] =~
4342786b6326SJoe Perches				    s/^(\+.*\S)\s+;/$1;/;
4343786b6326SJoe Perches			}
4344786b6326SJoe Perches		}
4345786b6326SJoe Perches
4346f0a594c1SAndy Whitcroft# check for multiple assignments
4347f0a594c1SAndy Whitcroft		if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
4348000d1cc1SJoe Perches			CHK("MULTIPLE_ASSIGNMENTS",
4349000d1cc1SJoe Perches			    "multiple assignments should be avoided\n" . $herecurr);
4350f0a594c1SAndy Whitcroft		}
4351f0a594c1SAndy Whitcroft
435222f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration
435322f2a2efSAndy Whitcroft## # continuation.
435422f2a2efSAndy Whitcroft## 		if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
435522f2a2efSAndy Whitcroft## 		    $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
435622f2a2efSAndy Whitcroft##
435722f2a2efSAndy Whitcroft## 			# Remove any bracketed sections to ensure we do not
435822f2a2efSAndy Whitcroft## 			# falsly report the parameters of functions.
435922f2a2efSAndy Whitcroft## 			my $ln = $line;
436022f2a2efSAndy Whitcroft## 			while ($ln =~ s/\([^\(\)]*\)//g) {
436122f2a2efSAndy Whitcroft## 			}
436222f2a2efSAndy Whitcroft## 			if ($ln =~ /,/) {
4363000d1cc1SJoe Perches## 				WARN("MULTIPLE_DECLARATION",
4364000d1cc1SJoe Perches##				     "declaring multiple variables together should be avoided\n" . $herecurr);
436522f2a2efSAndy Whitcroft## 			}
436622f2a2efSAndy Whitcroft## 		}
4367f0a594c1SAndy Whitcroft
43680a920b5bSAndy Whitcroft#need space before brace following if, while, etc
43696b8c69e4SGeyslan G. Bem		if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
43704e5d56bdSEddie Kovsky		    $line =~ /do\{/) {
43713705ce5bSJoe Perches			if (ERROR("SPACING",
43723705ce5bSJoe Perches				  "space required before the open brace '{'\n" . $herecurr) &&
43733705ce5bSJoe Perches			    $fix) {
4374194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/^(\+.*(?:do|\))){/$1 {/;
43753705ce5bSJoe Perches			}
4376de7d4f0eSAndy Whitcroft		}
4377de7d4f0eSAndy Whitcroft
4378c4a62ef9SJoe Perches## # check for blank lines before declarations
4379c4a62ef9SJoe Perches##		if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
4380c4a62ef9SJoe Perches##		    $prevrawline =~ /^.\s*$/) {
4381c4a62ef9SJoe Perches##			WARN("SPACING",
4382c4a62ef9SJoe Perches##			     "No blank lines before declarations\n" . $hereprev);
4383c4a62ef9SJoe Perches##		}
4384c4a62ef9SJoe Perches##
4385c4a62ef9SJoe Perches
4386de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything
4387de7d4f0eSAndy Whitcroft# on the line
4388de7d4f0eSAndy Whitcroft		if ($line =~ /}(?!(?:,|;|\)))\S/) {
4389d5e616fcSJoe Perches			if (ERROR("SPACING",
4390d5e616fcSJoe Perches				  "space required after that close brace '}'\n" . $herecurr) &&
4391d5e616fcSJoe Perches			    $fix) {
4392194f66fcSJoe Perches				$fixed[$fixlinenr] =~
4393d5e616fcSJoe Perches				    s/}((?!(?:,|;|\)))\S)/} $1/;
4394d5e616fcSJoe Perches			}
43950a920b5bSAndy Whitcroft		}
43960a920b5bSAndy Whitcroft
439722f2a2efSAndy Whitcroft# check spacing on square brackets
439822f2a2efSAndy Whitcroft		if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
43993705ce5bSJoe Perches			if (ERROR("SPACING",
44003705ce5bSJoe Perches				  "space prohibited after that open square bracket '['\n" . $herecurr) &&
44013705ce5bSJoe Perches			    $fix) {
4402194f66fcSJoe Perches				$fixed[$fixlinenr] =~
44033705ce5bSJoe Perches				    s/\[\s+/\[/;
44043705ce5bSJoe Perches			}
440522f2a2efSAndy Whitcroft		}
440622f2a2efSAndy Whitcroft		if ($line =~ /\s\]/) {
44073705ce5bSJoe Perches			if (ERROR("SPACING",
44083705ce5bSJoe Perches				  "space prohibited before that close square bracket ']'\n" . $herecurr) &&
44093705ce5bSJoe Perches			    $fix) {
4410194f66fcSJoe Perches				$fixed[$fixlinenr] =~
44113705ce5bSJoe Perches				    s/\s+\]/\]/;
44123705ce5bSJoe Perches			}
441322f2a2efSAndy Whitcroft		}
441422f2a2efSAndy Whitcroft
4415c45dcabdSAndy Whitcroft# check spacing on parentheses
44169c0ca6f9SAndy Whitcroft		if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
44179c0ca6f9SAndy Whitcroft		    $line !~ /for\s*\(\s+;/) {
44183705ce5bSJoe Perches			if (ERROR("SPACING",
44193705ce5bSJoe Perches				  "space prohibited after that open parenthesis '('\n" . $herecurr) &&
44203705ce5bSJoe Perches			    $fix) {
4421194f66fcSJoe Perches				$fixed[$fixlinenr] =~
44223705ce5bSJoe Perches				    s/\(\s+/\(/;
44233705ce5bSJoe Perches			}
442422f2a2efSAndy Whitcroft		}
442513214adfSAndy Whitcroft		if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
4426c45dcabdSAndy Whitcroft		    $line !~ /for\s*\(.*;\s+\)/ &&
4427c45dcabdSAndy Whitcroft		    $line !~ /:\s+\)/) {
44283705ce5bSJoe Perches			if (ERROR("SPACING",
44293705ce5bSJoe Perches				  "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
44303705ce5bSJoe Perches			    $fix) {
4431194f66fcSJoe Perches				$fixed[$fixlinenr] =~
44323705ce5bSJoe Perches				    s/\s+\)/\)/;
44333705ce5bSJoe Perches			}
443422f2a2efSAndy Whitcroft		}
443522f2a2efSAndy Whitcroft
4436e2826fd0SJoe Perches# check unnecessary parentheses around addressof/dereference single $Lvals
4437e2826fd0SJoe Perches# ie: &(foo->bar) should be &foo->bar and *(foo->bar) should be *foo->bar
4438e2826fd0SJoe Perches
4439e2826fd0SJoe Perches		while ($line =~ /(?:[^&]&\s*|\*)\(\s*($Ident\s*(?:$Member\s*)+)\s*\)/g) {
4440ea4acbb1SJoe Perches			my $var = $1;
4441ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
4442ea4acbb1SJoe Perches				"Unnecessary parentheses around $var\n" . $herecurr) &&
4443ea4acbb1SJoe Perches			    $fix) {
4444ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$var\E\s*\)/$var/;
4445ea4acbb1SJoe Perches			}
4446ea4acbb1SJoe Perches		}
4447ea4acbb1SJoe Perches
4448ea4acbb1SJoe Perches# check for unnecessary parentheses around function pointer uses
4449ea4acbb1SJoe Perches# ie: (foo->bar)(); should be foo->bar();
4450ea4acbb1SJoe Perches# but not "if (foo->bar) (" to avoid some false positives
4451ea4acbb1SJoe Perches		if ($line =~ /(\bif\s*|)(\(\s*$Ident\s*(?:$Member\s*)+\))[ \t]*\(/ && $1 !~ /^if/) {
4452ea4acbb1SJoe Perches			my $var = $2;
4453ea4acbb1SJoe Perches			if (CHK("UNNECESSARY_PARENTHESES",
4454ea4acbb1SJoe Perches				"Unnecessary parentheses around function pointer $var\n" . $herecurr) &&
4455ea4acbb1SJoe Perches			    $fix) {
4456ea4acbb1SJoe Perches				my $var2 = deparenthesize($var);
4457ea4acbb1SJoe Perches				$var2 =~ s/\s//g;
4458ea4acbb1SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$var\E/$var2/;
4459ea4acbb1SJoe Perches			}
4460e2826fd0SJoe Perches		}
4461e2826fd0SJoe Perches
44620a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however
44634a0df2efSAndy Whitcroft		if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
44640a920b5bSAndy Whitcroft		   !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
44653705ce5bSJoe Perches			if (WARN("INDENTED_LABEL",
44663705ce5bSJoe Perches				 "labels should not be indented\n" . $herecurr) &&
44673705ce5bSJoe Perches			    $fix) {
4468194f66fcSJoe Perches				$fixed[$fixlinenr] =~
44693705ce5bSJoe Perches				    s/^(.)\s+/$1/;
44703705ce5bSJoe Perches			}
44710a920b5bSAndy Whitcroft		}
44720a920b5bSAndy Whitcroft
44735b9553abSJoe Perches# return is not a function
4474507e5141SJoe Perches		if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
4475c45dcabdSAndy Whitcroft			my $spacing = $1;
4476507e5141SJoe Perches			if ($^V && $^V ge 5.10.0 &&
44775b9553abSJoe Perches			    $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
44785b9553abSJoe Perches				my $value = $1;
44795b9553abSJoe Perches				$value = deparenthesize($value);
44805b9553abSJoe Perches				if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
4481000d1cc1SJoe Perches					ERROR("RETURN_PARENTHESES",
4482000d1cc1SJoe Perches					      "return is not a function, parentheses are not required\n" . $herecurr);
44835b9553abSJoe Perches				}
4484c45dcabdSAndy Whitcroft			} elsif ($spacing !~ /\s+/) {
4485000d1cc1SJoe Perches				ERROR("SPACING",
4486000d1cc1SJoe Perches				      "space required before the open parenthesis '('\n" . $herecurr);
4487c45dcabdSAndy Whitcroft			}
4488c45dcabdSAndy Whitcroft		}
4489507e5141SJoe Perches
4490b43ae21bSJoe Perches# unnecessary return in a void function
4491b43ae21bSJoe Perches# at end-of-function, with the previous line a single leading tab, then return;
4492b43ae21bSJoe Perches# and the line before that not a goto label target like "out:"
4493b43ae21bSJoe Perches		if ($sline =~ /^[ \+]}\s*$/ &&
4494b43ae21bSJoe Perches		    $prevline =~ /^\+\treturn\s*;\s*$/ &&
4495b43ae21bSJoe Perches		    $linenr >= 3 &&
4496b43ae21bSJoe Perches		    $lines[$linenr - 3] =~ /^[ +]/ &&
4497b43ae21bSJoe Perches		    $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
44989819cf25SJoe Perches			WARN("RETURN_VOID",
4499b43ae21bSJoe Perches			     "void function return statements are not generally useful\n" . $hereprev);
45009819cf25SJoe Perches               }
45019819cf25SJoe Perches
4502189248d8SJoe Perches# if statements using unnecessary parentheses - ie: if ((foo == bar))
4503189248d8SJoe Perches		if ($^V && $^V ge 5.10.0 &&
4504189248d8SJoe Perches		    $line =~ /\bif\s*((?:\(\s*){2,})/) {
4505189248d8SJoe Perches			my $openparens = $1;
4506189248d8SJoe Perches			my $count = $openparens =~ tr@\(@\(@;
4507189248d8SJoe Perches			my $msg = "";
4508189248d8SJoe Perches			if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
4509189248d8SJoe Perches				my $comp = $4;	#Not $1 because of $LvalOrFunc
4510189248d8SJoe Perches				$msg = " - maybe == should be = ?" if ($comp eq "==");
4511189248d8SJoe Perches				WARN("UNNECESSARY_PARENTHESES",
4512189248d8SJoe Perches				     "Unnecessary parentheses$msg\n" . $herecurr);
4513189248d8SJoe Perches			}
4514189248d8SJoe Perches		}
4515189248d8SJoe Perches
4516c5595fa2SJoe Perches# comparisons with a constant or upper case identifier on the left
4517c5595fa2SJoe Perches#	avoid cases like "foo + BAR < baz"
4518c5595fa2SJoe Perches#	only fix matches surrounded by parentheses to avoid incorrect
4519c5595fa2SJoe Perches#	conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5"
4520c5595fa2SJoe Perches		if ($^V && $^V ge 5.10.0 &&
4521c5595fa2SJoe Perches		    $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) {
4522c5595fa2SJoe Perches			my $lead = $1;
4523c5595fa2SJoe Perches			my $const = $2;
4524c5595fa2SJoe Perches			my $comp = $3;
4525c5595fa2SJoe Perches			my $to = $4;
4526c5595fa2SJoe Perches			my $newcomp = $comp;
4527f39e1769SJoe Perches			if ($lead !~ /(?:$Operators|\.)\s*$/ &&
4528c5595fa2SJoe Perches			    $to !~ /^(?:Constant|[A-Z_][A-Z0-9_]*)$/ &&
4529c5595fa2SJoe Perches			    WARN("CONSTANT_COMPARISON",
4530c5595fa2SJoe Perches				 "Comparisons should place the constant on the right side of the test\n" . $herecurr) &&
4531c5595fa2SJoe Perches			    $fix) {
4532c5595fa2SJoe Perches				if ($comp eq "<") {
4533c5595fa2SJoe Perches					$newcomp = ">";
4534c5595fa2SJoe Perches				} elsif ($comp eq "<=") {
4535c5595fa2SJoe Perches					$newcomp = ">=";
4536c5595fa2SJoe Perches				} elsif ($comp eq ">") {
4537c5595fa2SJoe Perches					$newcomp = "<";
4538c5595fa2SJoe Perches				} elsif ($comp eq ">=") {
4539c5595fa2SJoe Perches					$newcomp = "<=";
4540c5595fa2SJoe Perches				}
4541c5595fa2SJoe Perches				$fixed[$fixlinenr] =~ s/\(\s*\Q$const\E\s*$Compare\s*\Q$to\E\s*\)/($to $newcomp $const)/;
4542c5595fa2SJoe Perches			}
4543c5595fa2SJoe Perches		}
4544c5595fa2SJoe Perches
4545f34e4a4fSJoe Perches# Return of what appears to be an errno should normally be negative
4546f34e4a4fSJoe Perches		if ($sline =~ /\breturn(?:\s*\(+\s*|\s+)(E[A-Z]+)(?:\s*\)+\s*|\s*)[;:,]/) {
454753a3c448SAndy Whitcroft			my $name = $1;
454853a3c448SAndy Whitcroft			if ($name ne 'EOF' && $name ne 'ERROR') {
4549000d1cc1SJoe Perches				WARN("USE_NEGATIVE_ERRNO",
4550f34e4a4fSJoe Perches				     "return of an errno should typically be negative (ie: return -$1)\n" . $herecurr);
455153a3c448SAndy Whitcroft			}
455253a3c448SAndy Whitcroft		}
4553c45dcabdSAndy Whitcroft
45540a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc
45554a0df2efSAndy Whitcroft		if ($line =~ /\b(if|while|for|switch)\(/) {
45563705ce5bSJoe Perches			if (ERROR("SPACING",
45573705ce5bSJoe Perches				  "space required before the open parenthesis '('\n" . $herecurr) &&
45583705ce5bSJoe Perches			    $fix) {
4559194f66fcSJoe Perches				$fixed[$fixlinenr] =~
45603705ce5bSJoe Perches				    s/\b(if|while|for|switch)\(/$1 \(/;
45613705ce5bSJoe Perches			}
45620a920b5bSAndy Whitcroft		}
45630a920b5bSAndy Whitcroft
4564f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing
4565f5fe35ddSAndy Whitcroft# statements after the conditional.
4566170d3a22SAndy Whitcroft		if ($line =~ /do\s*(?!{)/) {
45673e469cdcSAndy Whitcroft			($stat, $cond, $line_nr_next, $remain_next, $off_next) =
45683e469cdcSAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0)
45693e469cdcSAndy Whitcroft					if (!defined $stat);
4570170d3a22SAndy Whitcroft			my ($stat_next) = ctx_statement_block($line_nr_next,
4571170d3a22SAndy Whitcroft						$remain_next, $off_next);
4572170d3a22SAndy Whitcroft			$stat_next =~ s/\n./\n /g;
4573170d3a22SAndy Whitcroft			##print "stat<$stat> stat_next<$stat_next>\n";
4574170d3a22SAndy Whitcroft
4575170d3a22SAndy Whitcroft			if ($stat_next =~ /^\s*while\b/) {
4576170d3a22SAndy Whitcroft				# If the statement carries leading newlines,
4577170d3a22SAndy Whitcroft				# then count those as offsets.
4578170d3a22SAndy Whitcroft				my ($whitespace) =
4579170d3a22SAndy Whitcroft					($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
4580170d3a22SAndy Whitcroft				my $offset =
4581170d3a22SAndy Whitcroft					statement_rawlines($whitespace) - 1;
4582170d3a22SAndy Whitcroft
4583170d3a22SAndy Whitcroft				$suppress_whiletrailers{$line_nr_next +
4584170d3a22SAndy Whitcroft								$offset} = 1;
4585170d3a22SAndy Whitcroft			}
4586170d3a22SAndy Whitcroft		}
4587170d3a22SAndy Whitcroft		if (!defined $suppress_whiletrailers{$linenr} &&
4588c11230f4SJoe Perches		    defined($stat) && defined($cond) &&
4589170d3a22SAndy Whitcroft		    $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
4590171ae1a4SAndy Whitcroft			my ($s, $c) = ($stat, $cond);
45918905a67cSAndy Whitcroft
4592b53c8e10SAndy Whitcroft			if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
4593000d1cc1SJoe Perches				ERROR("ASSIGN_IN_IF",
4594000d1cc1SJoe Perches				      "do not use assignment in if condition\n" . $herecurr);
45958905a67cSAndy Whitcroft			}
45968905a67cSAndy Whitcroft
45978905a67cSAndy Whitcroft			# Find out what is on the end of the line after the
45988905a67cSAndy Whitcroft			# conditional.
4599773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
46008905a67cSAndy Whitcroft			$s =~ s/\n.*//g;
460113214adfSAndy Whitcroft			$s =~ s/$;//g; 	# Remove any comments
460253210168SAndy Whitcroft			if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
460353210168SAndy Whitcroft			    $c !~ /}\s*while\s*/)
4604773647a0SAndy Whitcroft			{
4605bb44ad39SAndy Whitcroft				# Find out how long the conditional actually is.
4606bb44ad39SAndy Whitcroft				my @newlines = ($c =~ /\n/gs);
4607bb44ad39SAndy Whitcroft				my $cond_lines = 1 + $#newlines;
460842bdf74cSHidetoshi Seto				my $stat_real = '';
4609bb44ad39SAndy Whitcroft
461042bdf74cSHidetoshi Seto				$stat_real = raw_line($linenr, $cond_lines)
461142bdf74cSHidetoshi Seto							. "\n" if ($cond_lines);
4612bb44ad39SAndy Whitcroft				if (defined($stat_real) && $cond_lines > 1) {
4613bb44ad39SAndy Whitcroft					$stat_real = "[...]\n$stat_real";
4614bb44ad39SAndy Whitcroft				}
4615bb44ad39SAndy Whitcroft
4616000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
4617000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr . $stat_real);
46188905a67cSAndy Whitcroft			}
46198905a67cSAndy Whitcroft		}
46208905a67cSAndy Whitcroft
462113214adfSAndy Whitcroft# Check for bitwise tests written as boolean
462213214adfSAndy Whitcroft		if ($line =~ /
462313214adfSAndy Whitcroft			(?:
462413214adfSAndy Whitcroft				(?:\[|\(|\&\&|\|\|)
462513214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
462613214adfSAndy Whitcroft				(?:\&\&|\|\|)
462713214adfSAndy Whitcroft			|
462813214adfSAndy Whitcroft				(?:\&\&|\|\|)
462913214adfSAndy Whitcroft				\s*0[xX][0-9]+\s*
463013214adfSAndy Whitcroft				(?:\&\&|\|\||\)|\])
463113214adfSAndy Whitcroft			)/x)
463213214adfSAndy Whitcroft		{
4633000d1cc1SJoe Perches			WARN("HEXADECIMAL_BOOLEAN_TEST",
4634000d1cc1SJoe Perches			     "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
463513214adfSAndy Whitcroft		}
463613214adfSAndy Whitcroft
46378905a67cSAndy Whitcroft# if and else should not have general statements after it
463813214adfSAndy Whitcroft		if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
463913214adfSAndy Whitcroft			my $s = $1;
464013214adfSAndy Whitcroft			$s =~ s/$;//g; 	# Remove any comments
464113214adfSAndy Whitcroft			if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
4642000d1cc1SJoe Perches				ERROR("TRAILING_STATEMENTS",
4643000d1cc1SJoe Perches				      "trailing statements should be on next line\n" . $herecurr);
46440a920b5bSAndy Whitcroft			}
464513214adfSAndy Whitcroft		}
464639667782SAndy Whitcroft# if should not continue a brace
464739667782SAndy Whitcroft		if ($line =~ /}\s*if\b/) {
4648000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
4649048b123fSRasmus Villemoes			      "trailing statements should be on next line (or did you mean 'else if'?)\n" .
465039667782SAndy Whitcroft				$herecurr);
465139667782SAndy Whitcroft		}
4652a1080bf8SAndy Whitcroft# case and default should not have general statements after them
4653a1080bf8SAndy Whitcroft		if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
4654a1080bf8SAndy Whitcroft		    $line !~ /\G(?:
46553fef12d6SAndy Whitcroft			(?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
4656a1080bf8SAndy Whitcroft			\s*return\s+
4657a1080bf8SAndy Whitcroft		    )/xg)
4658a1080bf8SAndy Whitcroft		{
4659000d1cc1SJoe Perches			ERROR("TRAILING_STATEMENTS",
4660000d1cc1SJoe Perches			      "trailing statements should be on next line\n" . $herecurr);
4661a1080bf8SAndy Whitcroft		}
46620a920b5bSAndy Whitcroft
46630a920b5bSAndy Whitcroft		# Check for }<nl>else {, these must be at the same
46640a920b5bSAndy Whitcroft		# indent level to be relevant to each other.
46658b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ &&
46660a920b5bSAndy Whitcroft		    $previndent == $indent) {
46678b8856f4SJoe Perches			if (ERROR("ELSE_AFTER_BRACE",
46688b8856f4SJoe Perches				  "else should follow close brace '}'\n" . $hereprev) &&
46698b8856f4SJoe Perches			    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
46708b8856f4SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
46718b8856f4SJoe Perches				fix_delete_line($fixlinenr, $rawline);
46728b8856f4SJoe Perches				my $fixedline = $prevrawline;
46738b8856f4SJoe Perches				$fixedline =~ s/}\s*$//;
46748b8856f4SJoe Perches				if ($fixedline !~ /^\+\s*$/) {
46758b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
46768b8856f4SJoe Perches				}
46778b8856f4SJoe Perches				$fixedline = $rawline;
46788b8856f4SJoe Perches				$fixedline =~ s/^(.\s*)else/$1} else/;
46798b8856f4SJoe Perches				fix_insert_line($fixlinenr, $fixedline);
46808b8856f4SJoe Perches			}
46810a920b5bSAndy Whitcroft		}
46820a920b5bSAndy Whitcroft
46838b8856f4SJoe Perches		if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ &&
4684c2fdda0dSAndy Whitcroft		    $previndent == $indent) {
4685c2fdda0dSAndy Whitcroft			my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
4686c2fdda0dSAndy Whitcroft
4687c2fdda0dSAndy Whitcroft			# Find out what is on the end of the line after the
4688c2fdda0dSAndy Whitcroft			# conditional.
4689773647a0SAndy Whitcroft			substr($s, 0, length($c), '');
4690c2fdda0dSAndy Whitcroft			$s =~ s/\n.*//g;
4691c2fdda0dSAndy Whitcroft
4692c2fdda0dSAndy Whitcroft			if ($s =~ /^\s*;/) {
46938b8856f4SJoe Perches				if (ERROR("WHILE_AFTER_BRACE",
46948b8856f4SJoe Perches					  "while should follow close brace '}'\n" . $hereprev) &&
46958b8856f4SJoe Perches				    $fix && $prevline =~ /^\+/ && $line =~ /^\+/) {
46968b8856f4SJoe Perches					fix_delete_line($fixlinenr - 1, $prevrawline);
46978b8856f4SJoe Perches					fix_delete_line($fixlinenr, $rawline);
46988b8856f4SJoe Perches					my $fixedline = $prevrawline;
46998b8856f4SJoe Perches					my $trailing = $rawline;
47008b8856f4SJoe Perches					$trailing =~ s/^\+//;
47018b8856f4SJoe Perches					$trailing = trim($trailing);
47028b8856f4SJoe Perches					$fixedline =~ s/}\s*$/} $trailing/;
47038b8856f4SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
47048b8856f4SJoe Perches				}
4705c2fdda0dSAndy Whitcroft			}
4706c2fdda0dSAndy Whitcroft		}
4707c2fdda0dSAndy Whitcroft
470895e2c602SJoe Perches#Specific variable tests
4709323c1260SJoe Perches		while ($line =~ m{($Constant|$Lval)}g) {
4710323c1260SJoe Perches			my $var = $1;
471195e2c602SJoe Perches
471295e2c602SJoe Perches#gcc binary extension
471395e2c602SJoe Perches			if ($var =~ /^$Binary$/) {
4714d5e616fcSJoe Perches				if (WARN("GCC_BINARY_CONSTANT",
4715d5e616fcSJoe Perches					 "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) &&
4716d5e616fcSJoe Perches				    $fix) {
4717d5e616fcSJoe Perches					my $hexval = sprintf("0x%x", oct($var));
4718194f66fcSJoe Perches					$fixed[$fixlinenr] =~
4719d5e616fcSJoe Perches					    s/\b$var\b/$hexval/;
4720d5e616fcSJoe Perches				}
472195e2c602SJoe Perches			}
472295e2c602SJoe Perches
472395e2c602SJoe Perches#CamelCase
4724807bd26cSJoe Perches			if ($var !~ /^$Constant$/ &&
4725be79794bSJoe Perches			    $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
472622735ce8SJoe Perches#Ignore Page<foo> variants
4727807bd26cSJoe Perches			    $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
472822735ce8SJoe Perches#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show)
4729f5123576SJulius Werner			    $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/ &&
4730f5123576SJulius Werner#Ignore some three character SI units explicitly, like MiB and KHz
4731f5123576SJulius Werner			    $var !~ /^(?:[a-z_]*?)_?(?:[KMGT]iB|[KMGT]?Hz)(?:_[a-z_]+)?$/) {
47327e781f67SJoe Perches				while ($var =~ m{($Ident)}g) {
47337e781f67SJoe Perches					my $word = $1;
47347e781f67SJoe Perches					next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
4735d8b07710SJoe Perches					if ($check) {
4736d8b07710SJoe Perches						seed_camelcase_includes();
4737d8b07710SJoe Perches						if (!$file && !$camelcase_file_seeded) {
4738d8b07710SJoe Perches							seed_camelcase_file($realfile);
4739d8b07710SJoe Perches							$camelcase_file_seeded = 1;
4740d8b07710SJoe Perches						}
4741d8b07710SJoe Perches					}
47427e781f67SJoe Perches					if (!defined $camelcase{$word}) {
47437e781f67SJoe Perches						$camelcase{$word} = 1;
4744be79794bSJoe Perches						CHK("CAMELCASE",
47457e781f67SJoe Perches						    "Avoid CamelCase: <$word>\n" . $herecurr);
47467e781f67SJoe Perches					}
4747323c1260SJoe Perches				}
4748323c1260SJoe Perches			}
47493445686aSJoe Perches		}
47500a920b5bSAndy Whitcroft
47510a920b5bSAndy Whitcroft#no spaces allowed after \ in define
4752d5e616fcSJoe Perches		if ($line =~ /\#\s*define.*\\\s+$/) {
4753d5e616fcSJoe Perches			if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
4754d5e616fcSJoe Perches				 "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
4755d5e616fcSJoe Perches			    $fix) {
4756194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\s+$//;
4757d5e616fcSJoe Perches			}
47580a920b5bSAndy Whitcroft		}
47590a920b5bSAndy Whitcroft
47600e212e0aSFabian Frederick# warn if <asm/foo.h> is #included and <linux/foo.h> is available and includes
47610e212e0aSFabian Frederick# itself <asm/foo.h> (uses RAW line)
4762c45dcabdSAndy Whitcroft		if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
4763e09dec48SAndy Whitcroft			my $file = "$1.h";
4764e09dec48SAndy Whitcroft			my $checkfile = "include/linux/$file";
4765e09dec48SAndy Whitcroft			if (-f "$root/$checkfile" &&
4766e09dec48SAndy Whitcroft			    $realfile ne $checkfile &&
47677840a94cSWolfram Sang			    $1 !~ /$allowed_asm_includes/)
4768c45dcabdSAndy Whitcroft			{
47690e212e0aSFabian Frederick				my $asminclude = `grep -Ec "#include\\s+<asm/$file>" $root/$checkfile`;
47700e212e0aSFabian Frederick				if ($asminclude > 0) {
4771e09dec48SAndy Whitcroft					if ($realfile =~ m{^arch/}) {
4772000d1cc1SJoe Perches						CHK("ARCH_INCLUDE_LINUX",
4773000d1cc1SJoe Perches						    "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
4774e09dec48SAndy Whitcroft					} else {
4775000d1cc1SJoe Perches						WARN("INCLUDE_LINUX",
4776000d1cc1SJoe Perches						     "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
4777e09dec48SAndy Whitcroft					}
47780a920b5bSAndy Whitcroft				}
47790a920b5bSAndy Whitcroft			}
47800e212e0aSFabian Frederick		}
47810a920b5bSAndy Whitcroft
4782653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the
4783653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed
4784cf655043SAndy Whitcroft# in a known good container
4785b8f96a31SAndy Whitcroft		if ($realfile !~ m@/vmlinux.lds.h$@ &&
4786b8f96a31SAndy Whitcroft		    $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
4787d8aaf121SAndy Whitcroft			my $ln = $linenr;
4788d8aaf121SAndy Whitcroft			my $cnt = $realcnt;
4789c45dcabdSAndy Whitcroft			my ($off, $dstat, $dcond, $rest);
4790c45dcabdSAndy Whitcroft			my $ctx = '';
479108a2843eSJoe Perches			my $has_flow_statement = 0;
479208a2843eSJoe Perches			my $has_arg_concat = 0;
4793c45dcabdSAndy Whitcroft			($dstat, $dcond, $ln, $cnt, $off) =
4794f74bd194SAndy Whitcroft				ctx_statement_block($linenr, $realcnt, 0);
4795f74bd194SAndy Whitcroft			$ctx = $dstat;
4796c45dcabdSAndy Whitcroft			#print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
4797a3bb97a7SAndy Whitcroft			#print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
4798c45dcabdSAndy Whitcroft
479908a2843eSJoe Perches			$has_flow_statement = 1 if ($ctx =~ /\b(goto|return)\b/);
480062e15a6dSJoe Perches			$has_arg_concat = 1 if ($ctx =~ /\#\#/ && $ctx !~ /\#\#\s*(?:__VA_ARGS__|args)\b/);
480108a2843eSJoe Perches
4802f59b64bfSJoe Perches			$dstat =~ s/^.\s*\#\s*define\s+$Ident(\([^\)]*\))?\s*//;
4803f59b64bfSJoe Perches			my $define_args = $1;
4804f59b64bfSJoe Perches			my $define_stmt = $dstat;
4805f59b64bfSJoe Perches			my @def_args = ();
4806f59b64bfSJoe Perches
4807f59b64bfSJoe Perches			if (defined $define_args && $define_args ne "") {
4808f59b64bfSJoe Perches				$define_args = substr($define_args, 1, length($define_args) - 2);
4809f59b64bfSJoe Perches				$define_args =~ s/\s*//g;
4810f59b64bfSJoe Perches				@def_args = split(",", $define_args);
4811f59b64bfSJoe Perches			}
4812f59b64bfSJoe Perches
4813292f1a9bSAndy Whitcroft			$dstat =~ s/$;//g;
4814c45dcabdSAndy Whitcroft			$dstat =~ s/\\\n.//g;
4815c45dcabdSAndy Whitcroft			$dstat =~ s/^\s*//s;
4816c45dcabdSAndy Whitcroft			$dstat =~ s/\s*$//s;
4817c45dcabdSAndy Whitcroft
4818c45dcabdSAndy Whitcroft			# Flatten any parentheses and braces
4819bf30d6edSAndy Whitcroft			while ($dstat =~ s/\([^\(\)]*\)/1/ ||
4820bf30d6edSAndy Whitcroft			       $dstat =~ s/\{[^\{\}]*\}/1/ ||
48216b10df42SVladimir Zapolskiy			       $dstat =~ s/.\[[^\[\]]*\]/1/)
4822bf30d6edSAndy Whitcroft			{
4823c45dcabdSAndy Whitcroft			}
4824c45dcabdSAndy Whitcroft
4825e45bab8eSAndy Whitcroft			# Flatten any obvious string concatentation.
482633acb54aSJoe Perches			while ($dstat =~ s/($String)\s*$Ident/$1/ ||
482733acb54aSJoe Perches			       $dstat =~ s/$Ident\s*($String)/$1/)
4828e45bab8eSAndy Whitcroft			{
4829e45bab8eSAndy Whitcroft			}
4830e45bab8eSAndy Whitcroft
483142e15293SJoe Perches			# Make asm volatile uses seem like a generic function
483242e15293SJoe Perches			$dstat =~ s/\b_*asm_*\s+_*volatile_*\b/asm_volatile/g;
483342e15293SJoe Perches
4834c45dcabdSAndy Whitcroft			my $exceptions = qr{
4835c45dcabdSAndy Whitcroft				$Declare|
4836c45dcabdSAndy Whitcroft				module_param_named|
4837a0a0a7a9SKees Cook				MODULE_PARM_DESC|
4838c45dcabdSAndy Whitcroft				DECLARE_PER_CPU|
4839c45dcabdSAndy Whitcroft				DEFINE_PER_CPU|
4840383099fdSAndy Whitcroft				__typeof__\(|
484122fd2d3eSStefani Seibold				union|
484222fd2d3eSStefani Seibold				struct|
4843ea71a0a0SAndy Whitcroft				\.$Ident\s*=\s*|
48446b10df42SVladimir Zapolskiy				^\"|\"$|
48456b10df42SVladimir Zapolskiy				^\[
4846c45dcabdSAndy Whitcroft			}x;
48475eaa20b9SAndy Whitcroft			#print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
4848f59b64bfSJoe Perches
4849f59b64bfSJoe Perches			$ctx =~ s/\n*$//;
4850f59b64bfSJoe Perches			my $herectx = $here . "\n";
4851f59b64bfSJoe Perches			my $stmt_cnt = statement_rawlines($ctx);
4852f59b64bfSJoe Perches
4853f59b64bfSJoe Perches			for (my $n = 0; $n < $stmt_cnt; $n++) {
4854f59b64bfSJoe Perches				$herectx .= raw_line($linenr, $n) . "\n";
4855f59b64bfSJoe Perches			}
4856f59b64bfSJoe Perches
4857f74bd194SAndy Whitcroft			if ($dstat ne '' &&
4858f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant),$/ &&			# 10, // foo(),
4859f74bd194SAndy Whitcroft			    $dstat !~ /^(?:$Ident|-?$Constant);$/ &&			# foo();
48603cc4b1c3SJoe Perches			    $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&		# 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
4861356fd398SJoe Perches			    $dstat !~ /^'X'$/ && $dstat !~ /^'XX'$/ &&			# character constants
4862f74bd194SAndy Whitcroft			    $dstat !~ /$exceptions/ &&
4863f74bd194SAndy Whitcroft			    $dstat !~ /^\.$Ident\s*=/ &&				# .foo =
4864e942e2c3SJoe Perches			    $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&		# stringification #foo
486572f115f9SAndy Whitcroft			    $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&	# do {...} while (...); // do {...} while (...)
4866f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant$/ &&				# for (...)
4867f74bd194SAndy Whitcroft			    $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&	# for (...) bar()
4868f74bd194SAndy Whitcroft			    $dstat !~ /^do\s*{/ &&					# do {...
48694e5d56bdSEddie Kovsky			    $dstat !~ /^\(\{/ &&						# ({...
4870f95a7e6aSJoe Perches			    $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
4871c45dcabdSAndy Whitcroft			{
4872e795556aSJoe Perches				if ($dstat =~ /^\s*if\b/) {
4873e795556aSJoe Perches					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
4874e795556aSJoe Perches					      "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx");
4875e795556aSJoe Perches				} elsif ($dstat =~ /;/) {
4876f74bd194SAndy Whitcroft					ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
4877f74bd194SAndy Whitcroft					      "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
4878f74bd194SAndy Whitcroft				} else {
4879000d1cc1SJoe Perches					ERROR("COMPLEX_MACRO",
4880388982b5SAndrew Morton					      "Macros with complex values should be enclosed in parentheses\n" . "$herectx");
4881d8aaf121SAndy Whitcroft				}
4882f59b64bfSJoe Perches
4883f59b64bfSJoe Perches			}
48845207649bSJoe Perches
48855207649bSJoe Perches			# Make $define_stmt single line, comment-free, etc
48865207649bSJoe Perches			my @stmt_array = split('\n', $define_stmt);
48875207649bSJoe Perches			my $first = 1;
48885207649bSJoe Perches			$define_stmt = "";
48895207649bSJoe Perches			foreach my $l (@stmt_array) {
48905207649bSJoe Perches				$l =~ s/\\$//;
48915207649bSJoe Perches				if ($first) {
48925207649bSJoe Perches					$define_stmt = $l;
48935207649bSJoe Perches					$first = 0;
48945207649bSJoe Perches				} elsif ($l =~ /^[\+ ]/) {
48955207649bSJoe Perches					$define_stmt .= substr($l, 1);
48965207649bSJoe Perches				}
48975207649bSJoe Perches			}
48985207649bSJoe Perches			$define_stmt =~ s/$;//g;
48995207649bSJoe Perches			$define_stmt =~ s/\s+/ /g;
49005207649bSJoe Perches			$define_stmt = trim($define_stmt);
49015207649bSJoe Perches
4902f59b64bfSJoe Perches# check if any macro arguments are reused (ignore '...' and 'type')
4903f59b64bfSJoe Perches			foreach my $arg (@def_args) {
4904f59b64bfSJoe Perches			        next if ($arg =~ /\.\.\./);
49059192d41aSJoe Perches			        next if ($arg =~ /^type$/i);
4906f59b64bfSJoe Perches				my $tmp = $define_stmt;
4907f59b64bfSJoe Perches				$tmp =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g;
49085207649bSJoe Perches				$tmp =~ s/\#+\s*$arg\b//g;
4909f59b64bfSJoe Perches				$tmp =~ s/\b$arg\s*\#\#//g;
4910f59b64bfSJoe Perches				my $use_cnt = $tmp =~ s/\b$arg\b//g;
4911f59b64bfSJoe Perches				if ($use_cnt > 1) {
4912f59b64bfSJoe Perches					CHK("MACRO_ARG_REUSE",
4913f59b64bfSJoe Perches					    "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx");
4914f59b64bfSJoe Perches				    }
49159192d41aSJoe Perches# check if any macro arguments may have other precedence issues
49169192d41aSJoe Perches				if ($define_stmt =~ m/($Operators)?\s*\b$arg\b\s*($Operators)?/m &&
49179192d41aSJoe Perches				    ((defined($1) && $1 ne ',') ||
49189192d41aSJoe Perches				     (defined($2) && $2 ne ','))) {
49199192d41aSJoe Perches					CHK("MACRO_ARG_PRECEDENCE",
49209192d41aSJoe Perches					    "Macro argument '$arg' may be better as '($arg)' to avoid precedence issues\n" . "$herectx");
49219192d41aSJoe Perches				}
49220a920b5bSAndy Whitcroft			}
49235023d347SJoe Perches
492408a2843eSJoe Perches# check for macros with flow control, but without ## concatenation
492508a2843eSJoe Perches# ## concatenation is commonly a macro that defines a function so ignore those
492608a2843eSJoe Perches			if ($has_flow_statement && !$has_arg_concat) {
492708a2843eSJoe Perches				my $herectx = $here . "\n";
492808a2843eSJoe Perches				my $cnt = statement_rawlines($ctx);
492908a2843eSJoe Perches
493008a2843eSJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
493108a2843eSJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
493208a2843eSJoe Perches				}
493308a2843eSJoe Perches				WARN("MACRO_WITH_FLOW_CONTROL",
493408a2843eSJoe Perches				     "Macros with flow control statements should be avoided\n" . "$herectx");
493508a2843eSJoe Perches			}
493608a2843eSJoe Perches
4937481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm
49385023d347SJoe Perches
49395023d347SJoe Perches		} else {
49405023d347SJoe Perches			if ($prevline !~ /^..*\\$/ &&
4941481eb486SJoe Perches			    $line !~ /^\+\s*\#.*\\$/ &&		# preprocessor
4942481eb486SJoe Perches			    $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&	# asm
49435023d347SJoe Perches			    $line =~ /^\+.*\\$/) {
49445023d347SJoe Perches				WARN("LINE_CONTINUATIONS",
49455023d347SJoe Perches				     "Avoid unnecessary line continuations\n" . $herecurr);
49465023d347SJoe Perches			}
4947653d4876SAndy Whitcroft		}
49480a920b5bSAndy Whitcroft
4949b13edf7fSJoe Perches# do {} while (0) macro tests:
4950b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop,
4951b13edf7fSJoe Perches# macro should not end with a semicolon
4952b13edf7fSJoe Perches		if ($^V && $^V ge 5.10.0 &&
4953b13edf7fSJoe Perches		    $realfile !~ m@/vmlinux.lds.h$@ &&
4954b13edf7fSJoe Perches		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
4955b13edf7fSJoe Perches			my $ln = $linenr;
4956b13edf7fSJoe Perches			my $cnt = $realcnt;
4957b13edf7fSJoe Perches			my ($off, $dstat, $dcond, $rest);
4958b13edf7fSJoe Perches			my $ctx = '';
4959b13edf7fSJoe Perches			($dstat, $dcond, $ln, $cnt, $off) =
4960b13edf7fSJoe Perches				ctx_statement_block($linenr, $realcnt, 0);
4961b13edf7fSJoe Perches			$ctx = $dstat;
4962b13edf7fSJoe Perches
4963b13edf7fSJoe Perches			$dstat =~ s/\\\n.//g;
49641b36b201SJoe Perches			$dstat =~ s/$;/ /g;
4965b13edf7fSJoe Perches
4966b13edf7fSJoe Perches			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
4967b13edf7fSJoe Perches				my $stmts = $2;
4968b13edf7fSJoe Perches				my $semis = $3;
4969b13edf7fSJoe Perches
4970b13edf7fSJoe Perches				$ctx =~ s/\n*$//;
4971b13edf7fSJoe Perches				my $cnt = statement_rawlines($ctx);
4972b13edf7fSJoe Perches				my $herectx = $here . "\n";
4973b13edf7fSJoe Perches
4974b13edf7fSJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
4975b13edf7fSJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
4976b13edf7fSJoe Perches				}
4977b13edf7fSJoe Perches
4978ac8e97f8SJoe Perches				if (($stmts =~ tr/;/;/) == 1 &&
4979ac8e97f8SJoe Perches				    $stmts !~ /^\s*(if|while|for|switch)\b/) {
4980b13edf7fSJoe Perches					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
4981b13edf7fSJoe Perches					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
4982b13edf7fSJoe Perches				}
4983b13edf7fSJoe Perches				if (defined $semis && $semis ne "") {
4984b13edf7fSJoe Perches					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
4985b13edf7fSJoe Perches					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
4986b13edf7fSJoe Perches				}
4987f5ef95b1SJoe Perches			} elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
4988f5ef95b1SJoe Perches				$ctx =~ s/\n*$//;
4989f5ef95b1SJoe Perches				my $cnt = statement_rawlines($ctx);
4990f5ef95b1SJoe Perches				my $herectx = $here . "\n";
4991f5ef95b1SJoe Perches
4992f5ef95b1SJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
4993f5ef95b1SJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
4994f5ef95b1SJoe Perches				}
4995f5ef95b1SJoe Perches
4996f5ef95b1SJoe Perches				WARN("TRAILING_SEMICOLON",
4997f5ef95b1SJoe Perches				     "macros should not use a trailing semicolon\n" . "$herectx");
4998b13edf7fSJoe Perches			}
4999b13edf7fSJoe Perches		}
5000b13edf7fSJoe Perches
5001080ba929SMike Frysinger# make sure symbols are always wrapped with VMLINUX_SYMBOL() ...
5002080ba929SMike Frysinger# all assignments may have only one of the following with an assignment:
5003080ba929SMike Frysinger#	.
5004080ba929SMike Frysinger#	ALIGN(...)
5005080ba929SMike Frysinger#	VMLINUX_SYMBOL(...)
5006080ba929SMike Frysinger		if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) {
5007000d1cc1SJoe Perches			WARN("MISSING_VMLINUX_SYMBOL",
5008000d1cc1SJoe Perches			     "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr);
5009080ba929SMike Frysinger		}
5010080ba929SMike Frysinger
5011f0a594c1SAndy Whitcroft# check for redundant bracing round if etc
501213214adfSAndy Whitcroft		if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
501313214adfSAndy Whitcroft			my ($level, $endln, @chunks) =
5014cf655043SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, 1);
501513214adfSAndy Whitcroft			#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
5016cf655043SAndy Whitcroft			#print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
5017cf655043SAndy Whitcroft			if ($#chunks > 0 && $level == 0) {
5018aad4f614SJoe Perches				my @allowed = ();
5019aad4f614SJoe Perches				my $allow = 0;
502013214adfSAndy Whitcroft				my $seen = 0;
5021773647a0SAndy Whitcroft				my $herectx = $here . "\n";
5022cf655043SAndy Whitcroft				my $ln = $linenr - 1;
502313214adfSAndy Whitcroft				for my $chunk (@chunks) {
502413214adfSAndy Whitcroft					my ($cond, $block) = @{$chunk};
502513214adfSAndy Whitcroft
5026773647a0SAndy Whitcroft					# If the condition carries leading newlines, then count those as offsets.
5027773647a0SAndy Whitcroft					my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
5028773647a0SAndy Whitcroft					my $offset = statement_rawlines($whitespace) - 1;
5029773647a0SAndy Whitcroft
5030aad4f614SJoe Perches					$allowed[$allow] = 0;
5031773647a0SAndy Whitcroft					#print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
5032773647a0SAndy Whitcroft
5033773647a0SAndy Whitcroft					# We have looked at and allowed this specific line.
5034773647a0SAndy Whitcroft					$suppress_ifbraces{$ln + $offset} = 1;
5035773647a0SAndy Whitcroft
5036773647a0SAndy Whitcroft					$herectx .= "$rawlines[$ln + $offset]\n[...]\n";
5037cf655043SAndy Whitcroft					$ln += statement_rawlines($block) - 1;
5038cf655043SAndy Whitcroft
5039773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
504013214adfSAndy Whitcroft
504113214adfSAndy Whitcroft					$seen++ if ($block =~ /^\s*{/);
504213214adfSAndy Whitcroft
5043aad4f614SJoe Perches					#print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
5044cf655043SAndy Whitcroft					if (statement_lines($cond) > 1) {
5045cf655043SAndy Whitcroft						#print "APW: ALLOWED: cond<$cond>\n";
5046aad4f614SJoe Perches						$allowed[$allow] = 1;
504713214adfSAndy Whitcroft					}
504813214adfSAndy Whitcroft					if ($block =~/\b(?:if|for|while)\b/) {
5049cf655043SAndy Whitcroft						#print "APW: ALLOWED: block<$block>\n";
5050aad4f614SJoe Perches						$allowed[$allow] = 1;
505113214adfSAndy Whitcroft					}
5052cf655043SAndy Whitcroft					if (statement_block_size($block) > 1) {
5053cf655043SAndy Whitcroft						#print "APW: ALLOWED: lines block<$block>\n";
5054aad4f614SJoe Perches						$allowed[$allow] = 1;
505513214adfSAndy Whitcroft					}
5056aad4f614SJoe Perches					$allow++;
505713214adfSAndy Whitcroft				}
5058aad4f614SJoe Perches				if ($seen) {
5059aad4f614SJoe Perches					my $sum_allowed = 0;
5060aad4f614SJoe Perches					foreach (@allowed) {
5061aad4f614SJoe Perches						$sum_allowed += $_;
5062aad4f614SJoe Perches					}
5063aad4f614SJoe Perches					if ($sum_allowed == 0) {
5064000d1cc1SJoe Perches						WARN("BRACES",
5065000d1cc1SJoe Perches						     "braces {} are not necessary for any arm of this statement\n" . $herectx);
5066aad4f614SJoe Perches					} elsif ($sum_allowed != $allow &&
5067aad4f614SJoe Perches						 $seen != $allow) {
5068aad4f614SJoe Perches						CHK("BRACES",
5069aad4f614SJoe Perches						    "braces {} should be used on all arms of this statement\n" . $herectx);
5070aad4f614SJoe Perches					}
507113214adfSAndy Whitcroft				}
507213214adfSAndy Whitcroft			}
507313214adfSAndy Whitcroft		}
5074773647a0SAndy Whitcroft		if (!defined $suppress_ifbraces{$linenr - 1} &&
507513214adfSAndy Whitcroft					$line =~ /\b(if|while|for|else)\b/) {
5076cf655043SAndy Whitcroft			my $allowed = 0;
5077f0a594c1SAndy Whitcroft
5078cf655043SAndy Whitcroft			# Check the pre-context.
5079cf655043SAndy Whitcroft			if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
5080cf655043SAndy Whitcroft				#print "APW: ALLOWED: pre<$1>\n";
5081cf655043SAndy Whitcroft				$allowed = 1;
5082f0a594c1SAndy Whitcroft			}
5083773647a0SAndy Whitcroft
5084773647a0SAndy Whitcroft			my ($level, $endln, @chunks) =
5085773647a0SAndy Whitcroft				ctx_statement_full($linenr, $realcnt, $-[0]);
5086773647a0SAndy Whitcroft
5087cf655043SAndy Whitcroft			# Check the condition.
5088cf655043SAndy Whitcroft			my ($cond, $block) = @{$chunks[0]};
5089773647a0SAndy Whitcroft			#print "CHECKING<$linenr> cond<$cond> block<$block>\n";
5090cf655043SAndy Whitcroft			if (defined $cond) {
5091773647a0SAndy Whitcroft				substr($block, 0, length($cond), '');
5092cf655043SAndy Whitcroft			}
5093cf655043SAndy Whitcroft			if (statement_lines($cond) > 1) {
5094cf655043SAndy Whitcroft				#print "APW: ALLOWED: cond<$cond>\n";
5095cf655043SAndy Whitcroft				$allowed = 1;
5096cf655043SAndy Whitcroft			}
5097cf655043SAndy Whitcroft			if ($block =~/\b(?:if|for|while)\b/) {
5098cf655043SAndy Whitcroft				#print "APW: ALLOWED: block<$block>\n";
5099cf655043SAndy Whitcroft				$allowed = 1;
5100cf655043SAndy Whitcroft			}
5101cf655043SAndy Whitcroft			if (statement_block_size($block) > 1) {
5102cf655043SAndy Whitcroft				#print "APW: ALLOWED: lines block<$block>\n";
5103cf655043SAndy Whitcroft				$allowed = 1;
5104cf655043SAndy Whitcroft			}
5105cf655043SAndy Whitcroft			# Check the post-context.
5106cf655043SAndy Whitcroft			if (defined $chunks[1]) {
5107cf655043SAndy Whitcroft				my ($cond, $block) = @{$chunks[1]};
5108cf655043SAndy Whitcroft				if (defined $cond) {
5109773647a0SAndy Whitcroft					substr($block, 0, length($cond), '');
5110cf655043SAndy Whitcroft				}
5111cf655043SAndy Whitcroft				if ($block =~ /^\s*\{/) {
5112cf655043SAndy Whitcroft					#print "APW: ALLOWED: chunk-1 block<$block>\n";
5113cf655043SAndy Whitcroft					$allowed = 1;
5114cf655043SAndy Whitcroft				}
5115cf655043SAndy Whitcroft			}
5116cf655043SAndy Whitcroft			if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
511769932487SJustin P. Mattock				my $herectx = $here . "\n";
5118f055663cSAndy Whitcroft				my $cnt = statement_rawlines($block);
5119cf655043SAndy Whitcroft
5120f055663cSAndy Whitcroft				for (my $n = 0; $n < $cnt; $n++) {
512169932487SJustin P. Mattock					$herectx .= raw_line($linenr, $n) . "\n";
5122cf655043SAndy Whitcroft				}
5123cf655043SAndy Whitcroft
5124000d1cc1SJoe Perches				WARN("BRACES",
5125000d1cc1SJoe Perches				     "braces {} are not necessary for single statement blocks\n" . $herectx);
5126f0a594c1SAndy Whitcroft			}
5127f0a594c1SAndy Whitcroft		}
5128f0a594c1SAndy Whitcroft
5129e4c5babdSJoe Perches# check for single line unbalanced braces
513095330473SSven Eckelmann		if ($sline =~ /^.\s*\}\s*else\s*$/ ||
513195330473SSven Eckelmann		    $sline =~ /^.\s*else\s*\{\s*$/) {
5132e4c5babdSJoe Perches			CHK("BRACES", "Unbalanced braces around else statement\n" . $herecurr);
5133e4c5babdSJoe Perches		}
5134e4c5babdSJoe Perches
51350979ae66SJoe Perches# check for unnecessary blank lines around braces
513677b9a53aSJoe Perches		if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
5137f8e58219SJoe Perches			if (CHK("BRACES",
5138f8e58219SJoe Perches				"Blank lines aren't necessary before a close brace '}'\n" . $hereprev) &&
5139f8e58219SJoe Perches			    $fix && $prevrawline =~ /^\+/) {
5140f8e58219SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
5141f8e58219SJoe Perches			}
51420979ae66SJoe Perches		}
514377b9a53aSJoe Perches		if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
5144f8e58219SJoe Perches			if (CHK("BRACES",
5145f8e58219SJoe Perches				"Blank lines aren't necessary after an open brace '{'\n" . $hereprev) &&
5146f8e58219SJoe Perches			    $fix) {
5147f8e58219SJoe Perches				fix_delete_line($fixlinenr, $rawline);
5148f8e58219SJoe Perches			}
51490979ae66SJoe Perches		}
51500979ae66SJoe Perches
51514a0df2efSAndy Whitcroft# no volatiles please
51526c72ffaaSAndy Whitcroft		my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
51536c72ffaaSAndy Whitcroft		if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
5154000d1cc1SJoe Perches			WARN("VOLATILE",
51558c27ceffSMauro Carvalho Chehab			     "Use of volatile is usually wrong: see Documentation/process/volatile-considered-harmful.rst\n" . $herecurr);
51564a0df2efSAndy Whitcroft		}
51574a0df2efSAndy Whitcroft
51585e4f6ba5SJoe Perches# Check for user-visible strings broken across lines, which breaks the ability
51595e4f6ba5SJoe Perches# to grep for the string.  Make exceptions when the previous string ends in a
51605e4f6ba5SJoe Perches# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
51615e4f6ba5SJoe Perches# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
516233acb54aSJoe Perches		if ($line =~ /^\+\s*$String/ &&
51635e4f6ba5SJoe Perches		    $prevline =~ /"\s*$/ &&
51645e4f6ba5SJoe Perches		    $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
51655e4f6ba5SJoe Perches			if (WARN("SPLIT_STRING",
51665e4f6ba5SJoe Perches				 "quoted string split across lines\n" . $hereprev) &&
51675e4f6ba5SJoe Perches				     $fix &&
51685e4f6ba5SJoe Perches				     $prevrawline =~ /^\+.*"\s*$/ &&
51695e4f6ba5SJoe Perches				     $last_coalesced_string_linenr != $linenr - 1) {
51705e4f6ba5SJoe Perches				my $extracted_string = get_quoted_string($line, $rawline);
51715e4f6ba5SJoe Perches				my $comma_close = "";
51725e4f6ba5SJoe Perches				if ($rawline =~ /\Q$extracted_string\E(\s*\)\s*;\s*$|\s*,\s*)/) {
51735e4f6ba5SJoe Perches					$comma_close = $1;
51745e4f6ba5SJoe Perches				}
51755e4f6ba5SJoe Perches
51765e4f6ba5SJoe Perches				fix_delete_line($fixlinenr - 1, $prevrawline);
51775e4f6ba5SJoe Perches				fix_delete_line($fixlinenr, $rawline);
51785e4f6ba5SJoe Perches				my $fixedline = $prevrawline;
51795e4f6ba5SJoe Perches				$fixedline =~ s/"\s*$//;
51805e4f6ba5SJoe Perches				$fixedline .= substr($extracted_string, 1) . trim($comma_close);
51815e4f6ba5SJoe Perches				fix_insert_line($fixlinenr - 1, $fixedline);
51825e4f6ba5SJoe Perches				$fixedline = $rawline;
51835e4f6ba5SJoe Perches				$fixedline =~ s/\Q$extracted_string\E\Q$comma_close\E//;
51845e4f6ba5SJoe Perches				if ($fixedline !~ /\+\s*$/) {
51855e4f6ba5SJoe Perches					fix_insert_line($fixlinenr, $fixedline);
51865e4f6ba5SJoe Perches				}
51875e4f6ba5SJoe Perches				$last_coalesced_string_linenr = $linenr;
51885e4f6ba5SJoe Perches			}
51895e4f6ba5SJoe Perches		}
51905e4f6ba5SJoe Perches
51915e4f6ba5SJoe Perches# check for missing a space in a string concatenation
51925e4f6ba5SJoe Perches		if ($prevrawline =~ /[^\\]\w"$/ && $rawline =~ /^\+[\t ]+"\w/) {
51935e4f6ba5SJoe Perches			WARN('MISSING_SPACE',
51945e4f6ba5SJoe Perches			     "break quoted strings at a space character\n" . $hereprev);
51955e4f6ba5SJoe Perches		}
51965e4f6ba5SJoe Perches
519777cb8546SJoe Perches# check for an embedded function name in a string when the function is known
5198e4b7d309SJoe Perches# This does not work very well for -f --file checking as it depends on patch
5199e4b7d309SJoe Perches# context providing the function name or a single line form for in-file
5200e4b7d309SJoe Perches# function declarations
520177cb8546SJoe Perches		if ($line =~ /^\+.*$String/ &&
520277cb8546SJoe Perches		    defined($context_function) &&
5203e4b7d309SJoe Perches		    get_quoted_string($line, $rawline) =~ /\b$context_function\b/ &&
5204e4b7d309SJoe Perches		    length(get_quoted_string($line, $rawline)) != (length($context_function) + 2)) {
520577cb8546SJoe Perches			WARN("EMBEDDED_FUNCTION_NAME",
5206e4b7d309SJoe Perches			     "Prefer using '\"%s...\", __func__' to using '$context_function', this function's name, in a string\n" . $herecurr);
520777cb8546SJoe Perches		}
520877cb8546SJoe Perches
52095e4f6ba5SJoe Perches# check for spaces before a quoted newline
52105e4f6ba5SJoe Perches		if ($rawline =~ /^.*\".*\s\\n/) {
52115e4f6ba5SJoe Perches			if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
52125e4f6ba5SJoe Perches				 "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
52135e4f6ba5SJoe Perches			    $fix) {
52145e4f6ba5SJoe Perches				$fixed[$fixlinenr] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
52155e4f6ba5SJoe Perches			}
52165e4f6ba5SJoe Perches
52175e4f6ba5SJoe Perches		}
52185e4f6ba5SJoe Perches
5219f17dba4fSJoe Perches# concatenated string without spaces between elements
522033acb54aSJoe Perches		if ($line =~ /$String[A-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) {
5221f17dba4fSJoe Perches			CHK("CONCATENATED_STRING",
5222f17dba4fSJoe Perches			    "Concatenated strings should use spaces between elements\n" . $herecurr);
5223f17dba4fSJoe Perches		}
5224f17dba4fSJoe Perches
522590ad30e5SJoe Perches# uncoalesced string fragments
522633acb54aSJoe Perches		if ($line =~ /$String\s*"/) {
522790ad30e5SJoe Perches			WARN("STRING_FRAGMENTS",
522890ad30e5SJoe Perches			     "Consecutive strings are generally better as a single string\n" . $herecurr);
522990ad30e5SJoe Perches		}
523090ad30e5SJoe Perches
5231522b837cSAlexey Dobriyan# check for non-standard and hex prefixed decimal printf formats
5232522b837cSAlexey Dobriyan		my $show_L = 1;	#don't show the same defect twice
5233522b837cSAlexey Dobriyan		my $show_Z = 1;
52345e4f6ba5SJoe Perches		while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
5235522b837cSAlexey Dobriyan			my $string = substr($rawline, $-[1], $+[1] - $-[1]);
52365e4f6ba5SJoe Perches			$string =~ s/%%/__/g;
5237522b837cSAlexey Dobriyan			# check for %L
5238522b837cSAlexey Dobriyan			if ($show_L && $string =~ /%[\*\d\.\$]*L([diouxX])/) {
52395e4f6ba5SJoe Perches				WARN("PRINTF_L",
5240522b837cSAlexey Dobriyan				     "\%L$1 is non-standard C, use %ll$1\n" . $herecurr);
5241522b837cSAlexey Dobriyan				$show_L = 0;
52425e4f6ba5SJoe Perches			}
5243522b837cSAlexey Dobriyan			# check for %Z
5244522b837cSAlexey Dobriyan			if ($show_Z && $string =~ /%[\*\d\.\$]*Z([diouxX])/) {
5245522b837cSAlexey Dobriyan				WARN("PRINTF_Z",
5246522b837cSAlexey Dobriyan				     "%Z$1 is non-standard C, use %z$1\n" . $herecurr);
5247522b837cSAlexey Dobriyan				$show_Z = 0;
5248522b837cSAlexey Dobriyan			}
5249522b837cSAlexey Dobriyan			# check for 0x<decimal>
5250522b837cSAlexey Dobriyan			if ($string =~ /0x%[\*\d\.\$\Llzth]*[diou]/) {
5251522b837cSAlexey Dobriyan				ERROR("PRINTF_0XDECIMAL",
52526e300757SJoe Perches				      "Prefixing 0x with decimal output is defective\n" . $herecurr);
52536e300757SJoe Perches			}
52545e4f6ba5SJoe Perches		}
52555e4f6ba5SJoe Perches
52565e4f6ba5SJoe Perches# check for line continuations in quoted strings with odd counts of "
52575e4f6ba5SJoe Perches		if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) {
52585e4f6ba5SJoe Perches			WARN("LINE_CONTINUATIONS",
52595e4f6ba5SJoe Perches			     "Avoid line continuations in quoted strings\n" . $herecurr);
52605e4f6ba5SJoe Perches		}
52615e4f6ba5SJoe Perches
526200df344fSAndy Whitcroft# warn about #if 0
5263c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*if\s+0\b/) {
5264000d1cc1SJoe Perches			CHK("REDUNDANT_CODE",
5265000d1cc1SJoe Perches			    "if this code is redundant consider removing it\n" .
5266de7d4f0eSAndy Whitcroft				$herecurr);
52674a0df2efSAndy Whitcroft		}
52684a0df2efSAndy Whitcroft
526903df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses
527003df4b51SAndy Whitcroft		if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
5271100425deSJoe Perches			my $tested = quotemeta($1);
5272100425deSJoe Perches			my $expr = '\s*\(\s*' . $tested . '\s*\)\s*;';
5273100425deSJoe Perches			if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?|(?:kmem_cache|mempool|dma_pool)_destroy)$expr/) {
5274100425deSJoe Perches				my $func = $1;
5275100425deSJoe Perches				if (WARN('NEEDLESS_IF',
5276100425deSJoe Perches					 "$func(NULL) is safe and this check is probably not required\n" . $hereprev) &&
5277100425deSJoe Perches				    $fix) {
5278100425deSJoe Perches					my $do_fix = 1;
5279100425deSJoe Perches					my $leading_tabs = "";
5280100425deSJoe Perches					my $new_leading_tabs = "";
5281100425deSJoe Perches					if ($lines[$linenr - 2] =~ /^\+(\t*)if\s*\(\s*$tested\s*\)\s*$/) {
5282100425deSJoe Perches						$leading_tabs = $1;
5283100425deSJoe Perches					} else {
5284100425deSJoe Perches						$do_fix = 0;
5285100425deSJoe Perches					}
5286100425deSJoe Perches					if ($lines[$linenr - 1] =~ /^\+(\t+)$func\s*\(\s*$tested\s*\)\s*;\s*$/) {
5287100425deSJoe Perches						$new_leading_tabs = $1;
5288100425deSJoe Perches						if (length($leading_tabs) + 1 ne length($new_leading_tabs)) {
5289100425deSJoe Perches							$do_fix = 0;
5290100425deSJoe Perches						}
5291100425deSJoe Perches					} else {
5292100425deSJoe Perches						$do_fix = 0;
5293100425deSJoe Perches					}
5294100425deSJoe Perches					if ($do_fix) {
5295100425deSJoe Perches						fix_delete_line($fixlinenr - 1, $prevrawline);
5296100425deSJoe Perches						$fixed[$fixlinenr] =~ s/^\+$new_leading_tabs/\+$leading_tabs/;
5297100425deSJoe Perches					}
5298100425deSJoe Perches				}
52994c432a8fSGreg Kroah-Hartman			}
53004c432a8fSGreg Kroah-Hartman		}
5301f0a594c1SAndy Whitcroft
5302ebfdc409SJoe Perches# check for unnecessary "Out of Memory" messages
5303ebfdc409SJoe Perches		if ($line =~ /^\+.*\b$logFunctions\s*\(/ &&
5304ebfdc409SJoe Perches		    $prevline =~ /^[ \+]\s*if\s*\(\s*(\!\s*|NULL\s*==\s*)?($Lval)(\s*==\s*NULL\s*)?\s*\)/ &&
5305ebfdc409SJoe Perches		    (defined $1 || defined $3) &&
5306ebfdc409SJoe Perches		    $linenr > 3) {
5307ebfdc409SJoe Perches			my $testval = $2;
5308ebfdc409SJoe Perches			my $testline = $lines[$linenr - 3];
5309ebfdc409SJoe Perches
5310ebfdc409SJoe Perches			my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0);
5311ebfdc409SJoe Perches#			print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n");
5312ebfdc409SJoe Perches
5313ebfdc409SJoe 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)/) {
5314ebfdc409SJoe Perches				WARN("OOM_MESSAGE",
5315ebfdc409SJoe Perches				     "Possible unnecessary 'out of memory' message\n" . $hereprev);
5316ebfdc409SJoe Perches			}
5317ebfdc409SJoe Perches		}
5318ebfdc409SJoe Perches
5319f78d98f6SJoe Perches# check for logging functions with KERN_<LEVEL>
5320dcaf1123SPaolo Bonzini		if ($line !~ /printk(?:_ratelimited|_once)?\s*\(/ &&
5321f78d98f6SJoe Perches		    $line =~ /\b$logFunctions\s*\(.*\b(KERN_[A-Z]+)\b/) {
5322f78d98f6SJoe Perches			my $level = $1;
5323f78d98f6SJoe Perches			if (WARN("UNNECESSARY_KERN_LEVEL",
5324f78d98f6SJoe Perches				 "Possible unnecessary $level\n" . $herecurr) &&
5325f78d98f6SJoe Perches			    $fix) {
5326f78d98f6SJoe Perches				$fixed[$fixlinenr] =~ s/\s*$level\s*//;
5327f78d98f6SJoe Perches			}
5328f78d98f6SJoe Perches		}
5329f78d98f6SJoe Perches
533045c55e92SJoe Perches# check for logging continuations
533145c55e92SJoe Perches		if ($line =~ /\bprintk\s*\(\s*KERN_CONT\b|\bpr_cont\s*\(/) {
533245c55e92SJoe Perches			WARN("LOGGING_CONTINUATION",
533345c55e92SJoe Perches			     "Avoid logging continuation uses where feasible\n" . $herecurr);
533445c55e92SJoe Perches		}
533545c55e92SJoe Perches
5336abb08a53SJoe Perches# check for mask then right shift without a parentheses
5337abb08a53SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5338abb08a53SJoe Perches		    $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ &&
5339abb08a53SJoe Perches		    $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so
5340abb08a53SJoe Perches			WARN("MASK_THEN_SHIFT",
5341abb08a53SJoe Perches			     "Possible precedence defect with mask then right shift - may need parentheses\n" . $herecurr);
5342abb08a53SJoe Perches		}
5343abb08a53SJoe Perches
5344b75ac618SJoe Perches# check for pointer comparisons to NULL
5345b75ac618SJoe Perches		if ($^V && $^V ge 5.10.0) {
5346b75ac618SJoe Perches			while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) {
5347b75ac618SJoe Perches				my $val = $1;
5348b75ac618SJoe Perches				my $equal = "!";
5349b75ac618SJoe Perches				$equal = "" if ($4 eq "!=");
5350b75ac618SJoe Perches				if (CHK("COMPARISON_TO_NULL",
5351b75ac618SJoe Perches					"Comparison to NULL could be written \"${equal}${val}\"\n" . $herecurr) &&
5352b75ac618SJoe Perches					    $fix) {
5353b75ac618SJoe Perches					$fixed[$fixlinenr] =~ s/\b\Q$val\E\s*(?:==|\!=)\s*NULL\b/$equal$val/;
5354b75ac618SJoe Perches				}
5355b75ac618SJoe Perches			}
5356b75ac618SJoe Perches		}
5357b75ac618SJoe Perches
53588716de38SJoe Perches# check for bad placement of section $InitAttribute (e.g.: __initdata)
53598716de38SJoe Perches		if ($line =~ /(\b$InitAttribute\b)/) {
53608716de38SJoe Perches			my $attr = $1;
53618716de38SJoe Perches			if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
53628716de38SJoe Perches				my $ptr = $1;
53638716de38SJoe Perches				my $var = $2;
53648716de38SJoe Perches				if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
53658716de38SJoe Perches				      ERROR("MISPLACED_INIT",
53668716de38SJoe Perches					    "$attr should be placed after $var\n" . $herecurr)) ||
53678716de38SJoe Perches				     ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
53688716de38SJoe Perches				      WARN("MISPLACED_INIT",
53698716de38SJoe Perches					   "$attr should be placed after $var\n" . $herecurr))) &&
53708716de38SJoe Perches				    $fix) {
5371194f66fcSJoe 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;
53728716de38SJoe Perches				}
53738716de38SJoe Perches			}
53748716de38SJoe Perches		}
53758716de38SJoe Perches
5376e970b884SJoe Perches# check for $InitAttributeData (ie: __initdata) with const
5377e970b884SJoe Perches		if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
5378e970b884SJoe Perches			my $attr = $1;
5379e970b884SJoe Perches			$attr =~ /($InitAttributePrefix)(.*)/;
5380e970b884SJoe Perches			my $attr_prefix = $1;
5381e970b884SJoe Perches			my $attr_type = $2;
5382e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
5383e970b884SJoe Perches				  "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
5384e970b884SJoe Perches			    $fix) {
5385194f66fcSJoe Perches				$fixed[$fixlinenr] =~
5386e970b884SJoe Perches				    s/$InitAttributeData/${attr_prefix}initconst/;
5387e970b884SJoe Perches			}
5388e970b884SJoe Perches		}
5389e970b884SJoe Perches
5390e970b884SJoe Perches# check for $InitAttributeConst (ie: __initconst) without const
5391e970b884SJoe Perches		if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
5392e970b884SJoe Perches			my $attr = $1;
5393e970b884SJoe Perches			if (ERROR("INIT_ATTRIBUTE",
5394e970b884SJoe Perches				  "Use of $attr requires a separate use of const\n" . $herecurr) &&
5395e970b884SJoe Perches			    $fix) {
5396194f66fcSJoe Perches				my $lead = $fixed[$fixlinenr] =~
5397e970b884SJoe Perches				    /(^\+\s*(?:static\s+))/;
5398e970b884SJoe Perches				$lead = rtrim($1);
5399e970b884SJoe Perches				$lead = "$lead " if ($lead !~ /^\+$/);
5400e970b884SJoe Perches				$lead = "${lead}const ";
5401194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(^\+\s*(?:static\s+))/$lead/;
5402e970b884SJoe Perches			}
5403e970b884SJoe Perches		}
5404e970b884SJoe Perches
5405c17893c7SJoe Perches# check for __read_mostly with const non-pointer (should just be const)
5406c17893c7SJoe Perches		if ($line =~ /\b__read_mostly\b/ &&
5407c17893c7SJoe Perches		    $line =~ /($Type)\s*$Ident/ && $1 !~ /\*\s*$/ && $1 =~ /\bconst\b/) {
5408c17893c7SJoe Perches			if (ERROR("CONST_READ_MOSTLY",
5409c17893c7SJoe Perches				  "Invalid use of __read_mostly with const type\n" . $herecurr) &&
5410c17893c7SJoe Perches			    $fix) {
5411c17893c7SJoe Perches				$fixed[$fixlinenr] =~ s/\s+__read_mostly\b//;
5412c17893c7SJoe Perches			}
5413c17893c7SJoe Perches		}
5414c17893c7SJoe Perches
5415fbdb8138SJoe Perches# don't use __constant_<foo> functions outside of include/uapi/
5416fbdb8138SJoe Perches		if ($realfile !~ m@^include/uapi/@ &&
5417fbdb8138SJoe Perches		    $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
5418fbdb8138SJoe Perches			my $constant_func = $1;
5419fbdb8138SJoe Perches			my $func = $constant_func;
5420fbdb8138SJoe Perches			$func =~ s/^__constant_//;
5421fbdb8138SJoe Perches			if (WARN("CONSTANT_CONVERSION",
5422fbdb8138SJoe Perches				 "$constant_func should be $func\n" . $herecurr) &&
5423fbdb8138SJoe Perches			    $fix) {
5424194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b$constant_func\b/$func/g;
5425fbdb8138SJoe Perches			}
5426fbdb8138SJoe Perches		}
5427fbdb8138SJoe Perches
54281a15a250SPatrick Pannuto# prefer usleep_range over udelay
542937581c28SBruce Allan		if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
543043c1d77cSJoe Perches			my $delay = $1;
54311a15a250SPatrick Pannuto			# ignore udelay's < 10, however
543243c1d77cSJoe Perches			if (! ($delay < 10) ) {
5433000d1cc1SJoe Perches				CHK("USLEEP_RANGE",
543443c1d77cSJoe Perches				    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr);
543543c1d77cSJoe Perches			}
543643c1d77cSJoe Perches			if ($delay > 2000) {
543743c1d77cSJoe Perches				WARN("LONG_UDELAY",
543843c1d77cSJoe Perches				     "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
54391a15a250SPatrick Pannuto			}
54401a15a250SPatrick Pannuto		}
54411a15a250SPatrick Pannuto
544209ef8725SPatrick Pannuto# warn about unexpectedly long msleep's
544309ef8725SPatrick Pannuto		if ($line =~ /\bmsleep\s*\((\d+)\);/) {
544409ef8725SPatrick Pannuto			if ($1 < 20) {
5445000d1cc1SJoe Perches				WARN("MSLEEP",
544643c1d77cSJoe Perches				     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr);
544709ef8725SPatrick Pannuto			}
544809ef8725SPatrick Pannuto		}
544909ef8725SPatrick Pannuto
545036ec1939SJoe Perches# check for comparisons of jiffies
545136ec1939SJoe Perches		if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
545236ec1939SJoe Perches			WARN("JIFFIES_COMPARISON",
545336ec1939SJoe Perches			     "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
545436ec1939SJoe Perches		}
545536ec1939SJoe Perches
54569d7a34a5SJoe Perches# check for comparisons of get_jiffies_64()
54579d7a34a5SJoe Perches		if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
54589d7a34a5SJoe Perches			WARN("JIFFIES_COMPARISON",
54599d7a34a5SJoe Perches			     "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
54609d7a34a5SJoe Perches		}
54619d7a34a5SJoe Perches
546200df344fSAndy Whitcroft# warn about #ifdefs in C files
5463c45dcabdSAndy Whitcroft#		if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
546400df344fSAndy Whitcroft#			print "#ifdef in C files should be avoided\n";
546500df344fSAndy Whitcroft#			print "$herecurr";
546600df344fSAndy Whitcroft#			$clean = 0;
546700df344fSAndy Whitcroft#		}
546800df344fSAndy Whitcroft
546922f2a2efSAndy Whitcroft# warn about spacing in #ifdefs
5470c45dcabdSAndy Whitcroft		if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
54713705ce5bSJoe Perches			if (ERROR("SPACING",
54723705ce5bSJoe Perches				  "exactly one space required after that #$1\n" . $herecurr) &&
54733705ce5bSJoe Perches			    $fix) {
5474194f66fcSJoe Perches				$fixed[$fixlinenr] =~
54753705ce5bSJoe Perches				    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
54763705ce5bSJoe Perches			}
54773705ce5bSJoe Perches
547822f2a2efSAndy Whitcroft		}
547922f2a2efSAndy Whitcroft
54804a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment.
5481171ae1a4SAndy Whitcroft		if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
5482171ae1a4SAndy Whitcroft		    $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
54834a0df2efSAndy Whitcroft			my $which = $1;
54844a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
5485000d1cc1SJoe Perches				CHK("UNCOMMENTED_DEFINITION",
5486000d1cc1SJoe Perches				    "$1 definition without comment\n" . $herecurr);
54874a0df2efSAndy Whitcroft			}
54884a0df2efSAndy Whitcroft		}
54894a0df2efSAndy Whitcroft# check for memory barriers without a comment.
5490402c2553SMichael S. Tsirkin
5491402c2553SMichael S. Tsirkin		my $barriers = qr{
5492402c2553SMichael S. Tsirkin			mb|
5493402c2553SMichael S. Tsirkin			rmb|
5494402c2553SMichael S. Tsirkin			wmb|
5495402c2553SMichael S. Tsirkin			read_barrier_depends
5496402c2553SMichael S. Tsirkin		}x;
5497402c2553SMichael S. Tsirkin		my $barrier_stems = qr{
5498402c2553SMichael S. Tsirkin			mb__before_atomic|
5499402c2553SMichael S. Tsirkin			mb__after_atomic|
5500402c2553SMichael S. Tsirkin			store_release|
5501402c2553SMichael S. Tsirkin			load_acquire|
5502402c2553SMichael S. Tsirkin			store_mb|
5503402c2553SMichael S. Tsirkin			(?:$barriers)
5504402c2553SMichael S. Tsirkin		}x;
5505402c2553SMichael S. Tsirkin		my $all_barriers = qr{
5506402c2553SMichael S. Tsirkin			(?:$barriers)|
550743e361f2SMichael S. Tsirkin			smp_(?:$barrier_stems)|
550843e361f2SMichael S. Tsirkin			virt_(?:$barrier_stems)
5509402c2553SMichael S. Tsirkin		}x;
5510402c2553SMichael S. Tsirkin
5511402c2553SMichael S. Tsirkin		if ($line =~ /\b(?:$all_barriers)\s*\(/) {
55124a0df2efSAndy Whitcroft			if (!ctx_has_comment($first_line, $linenr)) {
5513c1fd7bb9SJoe Perches				WARN("MEMORY_BARRIER",
5514000d1cc1SJoe Perches				     "memory barrier without comment\n" . $herecurr);
55154a0df2efSAndy Whitcroft			}
55164a0df2efSAndy Whitcroft		}
55173ad81779SPaul E. McKenney
5518f4073b0fSMichael S. Tsirkin		my $underscore_smp_barriers = qr{__smp_(?:$barrier_stems)}x;
5519f4073b0fSMichael S. Tsirkin
5520f4073b0fSMichael S. Tsirkin		if ($realfile !~ m@^include/asm-generic/@ &&
5521f4073b0fSMichael S. Tsirkin		    $realfile !~ m@/barrier\.h$@ &&
5522f4073b0fSMichael S. Tsirkin		    $line =~ m/\b(?:$underscore_smp_barriers)\s*\(/ &&
5523f4073b0fSMichael S. Tsirkin		    $line !~ m/^.\s*\#\s*define\s+(?:$underscore_smp_barriers)\s*\(/) {
5524f4073b0fSMichael S. Tsirkin			WARN("MEMORY_BARRIER",
5525f4073b0fSMichael S. Tsirkin			     "__smp memory barriers shouldn't be used outside barrier.h and asm-generic\n" . $herecurr);
5526f4073b0fSMichael S. Tsirkin		}
5527f4073b0fSMichael S. Tsirkin
5528cb426e99SJoe Perches# check for waitqueue_active without a comment.
5529cb426e99SJoe Perches		if ($line =~ /\bwaitqueue_active\s*\(/) {
5530cb426e99SJoe Perches			if (!ctx_has_comment($first_line, $linenr)) {
5531cb426e99SJoe Perches				WARN("WAITQUEUE_ACTIVE",
5532cb426e99SJoe Perches				     "waitqueue_active without comment\n" . $herecurr);
5533cb426e99SJoe Perches			}
5534cb426e99SJoe Perches		}
55353ad81779SPaul E. McKenney
55363ad81779SPaul E. McKenney# Check for expedited grace periods that interrupt non-idle non-nohz
55373ad81779SPaul E. McKenney# online CPUs.  These expedited can therefore degrade real-time response
55383ad81779SPaul E. McKenney# if used carelessly, and should be avoided where not absolutely
55393ad81779SPaul E. McKenney# needed.  It is always OK to use synchronize_rcu_expedited() and
55403ad81779SPaul E. McKenney# synchronize_sched_expedited() at boot time (before real-time applications
55413ad81779SPaul E. McKenney# start) and in error situations where real-time response is compromised in
55423ad81779SPaul E. McKenney# any case.  Note that synchronize_srcu_expedited() does -not- interrupt
55433ad81779SPaul E. McKenney# other CPUs, so don't warn on uses of synchronize_srcu_expedited().
55443ad81779SPaul E. McKenney# Of course, nothing comes for free, and srcu_read_lock() and
55453ad81779SPaul E. McKenney# srcu_read_unlock() do contain full memory barriers in payment for
55463ad81779SPaul E. McKenney# synchronize_srcu_expedited() non-interruption properties.
55473ad81779SPaul E. McKenney		if ($line =~ /\b(synchronize_rcu_expedited|synchronize_sched_expedited)\(/) {
55483ad81779SPaul E. McKenney			WARN("EXPEDITED_RCU_GRACE_PERIOD",
55493ad81779SPaul E. McKenney			     "expedited RCU grace periods should be avoided where they can degrade real-time response\n" . $herecurr);
55503ad81779SPaul E. McKenney
55513ad81779SPaul E. McKenney		}
55523ad81779SPaul E. McKenney
55534a0df2efSAndy Whitcroft# check of hardware specific defines
5554c45dcabdSAndy Whitcroft		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
5555000d1cc1SJoe Perches			CHK("ARCH_DEFINES",
5556000d1cc1SJoe Perches			    "architecture specific defines should be avoided\n" .  $herecurr);
55570a920b5bSAndy Whitcroft		}
5558653d4876SAndy Whitcroft
5559d4977c78STobias Klauser# Check that the storage class is at the beginning of a declaration
5560d4977c78STobias Klauser		if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) {
5561000d1cc1SJoe Perches			WARN("STORAGE_CLASS",
5562000d1cc1SJoe Perches			     "storage class should be at the beginning of the declaration\n" . $herecurr)
5563d4977c78STobias Klauser		}
5564d4977c78STobias Klauser
5565de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between
5566de7d4f0eSAndy Whitcroft# storage class and type.
55679c0ca6f9SAndy Whitcroft		if ($line =~ /\b$Type\s+$Inline\b/ ||
55689c0ca6f9SAndy Whitcroft		    $line =~ /\b$Inline\s+$Storage\b/) {
5569000d1cc1SJoe Perches			ERROR("INLINE_LOCATION",
5570000d1cc1SJoe Perches			      "inline keyword should sit between storage class and type\n" . $herecurr);
5571de7d4f0eSAndy Whitcroft		}
5572de7d4f0eSAndy Whitcroft
55738905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline
55742b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
55752b7ab453SJoe Perches		    $line =~ /\b(__inline__|__inline)\b/) {
5576d5e616fcSJoe Perches			if (WARN("INLINE",
5577d5e616fcSJoe Perches				 "plain inline is preferred over $1\n" . $herecurr) &&
5578d5e616fcSJoe Perches			    $fix) {
5579194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/;
5580d5e616fcSJoe Perches
5581d5e616fcSJoe Perches			}
55828905a67cSAndy Whitcroft		}
55838905a67cSAndy Whitcroft
55843d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed
55852b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
55862b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
5587000d1cc1SJoe Perches			WARN("PREFER_PACKED",
5588000d1cc1SJoe Perches			     "__packed is preferred over __attribute__((packed))\n" . $herecurr);
55893d130fd0SJoe Perches		}
55903d130fd0SJoe Perches
559139b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned
55922b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
55932b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
5594000d1cc1SJoe Perches			WARN("PREFER_ALIGNED",
5595000d1cc1SJoe Perches			     "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
559639b7e287SJoe Perches		}
559739b7e287SJoe Perches
55985f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf
55992b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
56002b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
5601d5e616fcSJoe Perches			if (WARN("PREFER_PRINTF",
5602d5e616fcSJoe Perches				 "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
5603d5e616fcSJoe Perches			    $fix) {
5604194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
5605d5e616fcSJoe Perches
5606d5e616fcSJoe Perches			}
56075f14d3bdSJoe Perches		}
56085f14d3bdSJoe Perches
56096061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf
56102b7ab453SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
56112b7ab453SJoe Perches		    $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
5612d5e616fcSJoe Perches			if (WARN("PREFER_SCANF",
5613d5e616fcSJoe Perches				 "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
5614d5e616fcSJoe Perches			    $fix) {
5615194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
5616d5e616fcSJoe Perches			}
56176061d949SJoe Perches		}
56186061d949SJoe Perches
5619619a908aSJoe Perches# Check for __attribute__ weak, or __weak declarations (may have link issues)
5620619a908aSJoe Perches		if ($^V && $^V ge 5.10.0 &&
5621619a908aSJoe Perches		    $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&
5622619a908aSJoe Perches		    ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||
5623619a908aSJoe Perches		     $line =~ /\b__weak\b/)) {
5624619a908aSJoe Perches			ERROR("WEAK_DECLARATION",
5625619a908aSJoe Perches			      "Using weak declarations can have unintended link defects\n" . $herecurr);
5626619a908aSJoe Perches		}
5627619a908aSJoe Perches
5628fd39f904STomas Winkler# check for c99 types like uint8_t used outside of uapi/ and tools/
5629e6176fa4SJoe Perches		if ($realfile !~ m@\binclude/uapi/@ &&
5630fd39f904STomas Winkler		    $realfile !~ m@\btools/@ &&
5631e6176fa4SJoe Perches		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {
5632e6176fa4SJoe Perches			my $type = $1;
5633e6176fa4SJoe Perches			if ($type =~ /\b($typeC99Typedefs)\b/) {
5634e6176fa4SJoe Perches				$type = $1;
5635e6176fa4SJoe Perches				my $kernel_type = 'u';
5636e6176fa4SJoe Perches				$kernel_type = 's' if ($type =~ /^_*[si]/);
5637e6176fa4SJoe Perches				$type =~ /(\d+)/;
5638e6176fa4SJoe Perches				$kernel_type .= $1;
5639e6176fa4SJoe Perches				if (CHK("PREFER_KERNEL_TYPES",
5640e6176fa4SJoe Perches					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&
5641e6176fa4SJoe Perches				    $fix) {
5642e6176fa4SJoe Perches					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;
5643e6176fa4SJoe Perches				}
5644e6176fa4SJoe Perches			}
5645e6176fa4SJoe Perches		}
5646e6176fa4SJoe Perches
5647938224b5SJoe Perches# check for cast of C90 native int or longer types constants
5648938224b5SJoe Perches		if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {
5649938224b5SJoe Perches			my $cast = $1;
5650938224b5SJoe Perches			my $const = $2;
5651938224b5SJoe Perches			if (WARN("TYPECAST_INT_CONSTANT",
5652938224b5SJoe Perches				 "Unnecessary typecast of c90 int constant\n" . $herecurr) &&
5653938224b5SJoe Perches			    $fix) {
5654938224b5SJoe Perches				my $suffix = "";
5655938224b5SJoe Perches				my $newconst = $const;
5656938224b5SJoe Perches				$newconst =~ s/${Int_type}$//;
5657938224b5SJoe Perches				$suffix .= 'U' if ($cast =~ /\bunsigned\b/);
5658938224b5SJoe Perches				if ($cast =~ /\blong\s+long\b/) {
5659938224b5SJoe Perches					$suffix .= 'LL';
5660938224b5SJoe Perches				} elsif ($cast =~ /\blong\b/) {
5661938224b5SJoe Perches					$suffix .= 'L';
5662938224b5SJoe Perches				}
5663938224b5SJoe Perches				$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;
5664938224b5SJoe Perches			}
5665938224b5SJoe Perches		}
5666938224b5SJoe Perches
56678f53a9b8SJoe Perches# check for sizeof(&)
56688f53a9b8SJoe Perches		if ($line =~ /\bsizeof\s*\(\s*\&/) {
5669000d1cc1SJoe Perches			WARN("SIZEOF_ADDRESS",
5670000d1cc1SJoe Perches			     "sizeof(& should be avoided\n" . $herecurr);
56718f53a9b8SJoe Perches		}
56728f53a9b8SJoe Perches
567366c80b60SJoe Perches# check for sizeof without parenthesis
567466c80b60SJoe Perches		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
5675d5e616fcSJoe Perches			if (WARN("SIZEOF_PARENTHESIS",
5676d5e616fcSJoe Perches				 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
5677d5e616fcSJoe Perches			    $fix) {
5678194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
5679d5e616fcSJoe Perches			}
568066c80b60SJoe Perches		}
568166c80b60SJoe Perches
568288982feaSJoe Perches# check for struct spinlock declarations
568388982feaSJoe Perches		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
568488982feaSJoe Perches			WARN("USE_SPINLOCK_T",
568588982feaSJoe Perches			     "struct spinlock should be spinlock_t\n" . $herecurr);
568688982feaSJoe Perches		}
568788982feaSJoe Perches
5688a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts
568906668727SJoe Perches		if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
5690a6962d72SJoe Perches			my $fmt = get_quoted_string($line, $rawline);
5691caac1d5fSHeba Aamer			$fmt =~ s/%%//g;
5692caac1d5fSHeba Aamer			if ($fmt !~ /%/) {
5693d5e616fcSJoe Perches				if (WARN("PREFER_SEQ_PUTS",
5694d5e616fcSJoe Perches					 "Prefer seq_puts to seq_printf\n" . $herecurr) &&
5695d5e616fcSJoe Perches				    $fix) {
5696194f66fcSJoe Perches					$fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;
5697d5e616fcSJoe Perches				}
5698a6962d72SJoe Perches			}
5699a6962d72SJoe Perches		}
5700a6962d72SJoe Perches
57010b523769SJoe Perches		# check for vsprintf extension %p<foo> misuses
57020b523769SJoe Perches		if ($^V && $^V ge 5.10.0 &&
57030b523769SJoe Perches		    defined $stat &&
57040b523769SJoe Perches		    $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
57050b523769SJoe Perches		    $1 !~ /^_*volatile_*$/) {
57060b523769SJoe Perches			my $bad_extension = "";
57070b523769SJoe Perches			my $lc = $stat =~ tr@\n@@;
57080b523769SJoe Perches			$lc = $lc + $linenr;
57090b523769SJoe Perches		        for (my $count = $linenr; $count <= $lc; $count++) {
57100b523769SJoe Perches				my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
57110b523769SJoe Perches				$fmt =~ s/%%//g;
5712*ce4fecf1SPantelis Antoniou				if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGNO]).)/) {
57130b523769SJoe Perches					$bad_extension = $1;
57140b523769SJoe Perches					last;
57150b523769SJoe Perches				}
57160b523769SJoe Perches			}
57170b523769SJoe Perches			if ($bad_extension ne "") {
57180b523769SJoe Perches				my $stat_real = raw_line($linenr, 0);
57190b523769SJoe Perches				for (my $count = $linenr + 1; $count <= $lc; $count++) {
57200b523769SJoe Perches					$stat_real = $stat_real . "\n" . raw_line($count, 0);
57210b523769SJoe Perches				}
57220b523769SJoe Perches				WARN("VSPRINTF_POINTER_EXTENSION",
57230b523769SJoe Perches				     "Invalid vsprintf pointer extension '$bad_extension'\n" . "$here\n$stat_real\n");
57240b523769SJoe Perches			}
57250b523769SJoe Perches		}
57260b523769SJoe Perches
5727554e165cSAndy Whitcroft# Check for misused memsets
5728d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5729d1fe9c09SJoe Perches		    defined $stat &&
57309e20a853SMateusz Kulikowski		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) {
5731554e165cSAndy Whitcroft
5732d7c76ba7SJoe Perches			my $ms_addr = $2;
5733d1fe9c09SJoe Perches			my $ms_val = $7;
5734d1fe9c09SJoe Perches			my $ms_size = $12;
5735d7c76ba7SJoe Perches
5736554e165cSAndy Whitcroft			if ($ms_size =~ /^(0x|)0$/i) {
5737554e165cSAndy Whitcroft				ERROR("MEMSET",
5738d7c76ba7SJoe Perches				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
5739554e165cSAndy Whitcroft			} elsif ($ms_size =~ /^(0x|)1$/i) {
5740554e165cSAndy Whitcroft				WARN("MEMSET",
5741d7c76ba7SJoe Perches				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
5742d7c76ba7SJoe Perches			}
5743d7c76ba7SJoe Perches		}
5744d7c76ba7SJoe Perches
574598a9bba5SJoe Perches# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
5746f333195dSJoe Perches#		if ($^V && $^V ge 5.10.0 &&
5747f333195dSJoe Perches#		    defined $stat &&
5748f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
5749f333195dSJoe Perches#			if (WARN("PREFER_ETHER_ADDR_COPY",
5750f333195dSJoe Perches#				 "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&
5751f333195dSJoe Perches#			    $fix) {
5752f333195dSJoe Perches#				$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
5753f333195dSJoe Perches#			}
5754f333195dSJoe Perches#		}
575598a9bba5SJoe Perches
5756b6117d17SMateusz Kulikowski# Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)
5757f333195dSJoe Perches#		if ($^V && $^V ge 5.10.0 &&
5758f333195dSJoe Perches#		    defined $stat &&
5759f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
5760f333195dSJoe Perches#			WARN("PREFER_ETHER_ADDR_EQUAL",
5761f333195dSJoe Perches#			     "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")
5762f333195dSJoe Perches#		}
5763b6117d17SMateusz Kulikowski
57648617cd09SMateusz Kulikowski# check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr
57658617cd09SMateusz Kulikowski# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr
5766f333195dSJoe Perches#		if ($^V && $^V ge 5.10.0 &&
5767f333195dSJoe Perches#		    defined $stat &&
5768f333195dSJoe Perches#		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {
5769f333195dSJoe Perches#
5770f333195dSJoe Perches#			my $ms_val = $7;
5771f333195dSJoe Perches#
5772f333195dSJoe Perches#			if ($ms_val =~ /^(?:0x|)0+$/i) {
5773f333195dSJoe Perches#				if (WARN("PREFER_ETH_ZERO_ADDR",
5774f333195dSJoe Perches#					 "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&
5775f333195dSJoe Perches#				    $fix) {
5776f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;
5777f333195dSJoe Perches#				}
5778f333195dSJoe Perches#			} elsif ($ms_val =~ /^(?:0xff|255)$/i) {
5779f333195dSJoe Perches#				if (WARN("PREFER_ETH_BROADCAST_ADDR",
5780f333195dSJoe Perches#					 "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&
5781f333195dSJoe Perches#				    $fix) {
5782f333195dSJoe Perches#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;
5783f333195dSJoe Perches#				}
5784f333195dSJoe Perches#			}
5785f333195dSJoe Perches#		}
57868617cd09SMateusz Kulikowski
5787d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t
5788d1fe9c09SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5789d1fe9c09SJoe Perches		    defined $stat &&
5790d7c76ba7SJoe Perches		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
5791d1fe9c09SJoe Perches			if (defined $2 || defined $7) {
5792d7c76ba7SJoe Perches				my $call = $1;
5793d7c76ba7SJoe Perches				my $cast1 = deparenthesize($2);
5794d7c76ba7SJoe Perches				my $arg1 = $3;
5795d1fe9c09SJoe Perches				my $cast2 = deparenthesize($7);
5796d1fe9c09SJoe Perches				my $arg2 = $8;
5797d7c76ba7SJoe Perches				my $cast;
5798d7c76ba7SJoe Perches
5799d1fe9c09SJoe Perches				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
5800d7c76ba7SJoe Perches					$cast = "$cast1 or $cast2";
5801d7c76ba7SJoe Perches				} elsif ($cast1 ne "") {
5802d7c76ba7SJoe Perches					$cast = $cast1;
5803d7c76ba7SJoe Perches				} else {
5804d7c76ba7SJoe Perches					$cast = $cast2;
5805d7c76ba7SJoe Perches				}
5806d7c76ba7SJoe Perches				WARN("MINMAX",
5807d7c76ba7SJoe Perches				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
5808554e165cSAndy Whitcroft			}
5809554e165cSAndy Whitcroft		}
5810554e165cSAndy Whitcroft
58114a273195SJoe Perches# check usleep_range arguments
58124a273195SJoe Perches		if ($^V && $^V ge 5.10.0 &&
58134a273195SJoe Perches		    defined $stat &&
58144a273195SJoe Perches		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
58154a273195SJoe Perches			my $min = $1;
58164a273195SJoe Perches			my $max = $7;
58174a273195SJoe Perches			if ($min eq $max) {
58184a273195SJoe Perches				WARN("USLEEP_RANGE",
58194a273195SJoe Perches				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
58204a273195SJoe Perches			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
58214a273195SJoe Perches				 $min > $max) {
58224a273195SJoe Perches				WARN("USLEEP_RANGE",
58234a273195SJoe Perches				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
58244a273195SJoe Perches			}
58254a273195SJoe Perches		}
58264a273195SJoe Perches
5827823b794cSJoe Perches# check for naked sscanf
5828823b794cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
5829823b794cSJoe Perches		    defined $stat &&
58306c8bd707SJoe Perches		    $line =~ /\bsscanf\b/ &&
5831823b794cSJoe Perches		    ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
5832823b794cSJoe Perches		     $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
5833823b794cSJoe Perches		     $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
5834823b794cSJoe Perches			my $lc = $stat =~ tr@\n@@;
5835823b794cSJoe Perches			$lc = $lc + $linenr;
5836823b794cSJoe Perches			my $stat_real = raw_line($linenr, 0);
5837823b794cSJoe Perches		        for (my $count = $linenr + 1; $count <= $lc; $count++) {
5838823b794cSJoe Perches				$stat_real = $stat_real . "\n" . raw_line($count, 0);
5839823b794cSJoe Perches			}
5840823b794cSJoe Perches			WARN("NAKED_SSCANF",
5841823b794cSJoe Perches			     "unchecked sscanf return value\n" . "$here\n$stat_real\n");
5842823b794cSJoe Perches		}
5843823b794cSJoe Perches
5844afc819abSJoe Perches# check for simple sscanf that should be kstrto<foo>
5845afc819abSJoe Perches		if ($^V && $^V ge 5.10.0 &&
5846afc819abSJoe Perches		    defined $stat &&
5847afc819abSJoe Perches		    $line =~ /\bsscanf\b/) {
5848afc819abSJoe Perches			my $lc = $stat =~ tr@\n@@;
5849afc819abSJoe Perches			$lc = $lc + $linenr;
5850afc819abSJoe Perches			my $stat_real = raw_line($linenr, 0);
5851afc819abSJoe Perches		        for (my $count = $linenr + 1; $count <= $lc; $count++) {
5852afc819abSJoe Perches				$stat_real = $stat_real . "\n" . raw_line($count, 0);
5853afc819abSJoe Perches			}
5854afc819abSJoe Perches			if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
5855afc819abSJoe Perches				my $format = $6;
5856afc819abSJoe Perches				my $count = $format =~ tr@%@%@;
5857afc819abSJoe Perches				if ($count == 1 &&
5858afc819abSJoe Perches				    $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
5859afc819abSJoe Perches					WARN("SSCANF_TO_KSTRTO",
5860afc819abSJoe Perches					     "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
5861afc819abSJoe Perches				}
5862afc819abSJoe Perches			}
5863afc819abSJoe Perches		}
5864afc819abSJoe Perches
586570dc8a48SJoe Perches# check for new externs in .h files.
586670dc8a48SJoe Perches		if ($realfile =~ /\.h$/ &&
586770dc8a48SJoe Perches		    $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
5868d1d85780SJoe Perches			if (CHK("AVOID_EXTERNS",
586970dc8a48SJoe Perches				"extern prototypes should be avoided in .h files\n" . $herecurr) &&
587070dc8a48SJoe Perches			    $fix) {
5871194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
587270dc8a48SJoe Perches			}
587370dc8a48SJoe Perches		}
587470dc8a48SJoe Perches
5875de7d4f0eSAndy Whitcroft# check for new externs in .c files.
5876171ae1a4SAndy Whitcroft		if ($realfile =~ /\.c$/ && defined $stat &&
5877c45dcabdSAndy Whitcroft		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
5878171ae1a4SAndy Whitcroft		{
5879c45dcabdSAndy Whitcroft			my $function_name = $1;
5880c45dcabdSAndy Whitcroft			my $paren_space = $2;
5881171ae1a4SAndy Whitcroft
5882171ae1a4SAndy Whitcroft			my $s = $stat;
5883171ae1a4SAndy Whitcroft			if (defined $cond) {
5884171ae1a4SAndy Whitcroft				substr($s, 0, length($cond), '');
5885171ae1a4SAndy Whitcroft			}
5886c45dcabdSAndy Whitcroft			if ($s =~ /^\s*;/ &&
5887c45dcabdSAndy Whitcroft			    $function_name ne 'uninitialized_var')
5888c45dcabdSAndy Whitcroft			{
5889000d1cc1SJoe Perches				WARN("AVOID_EXTERNS",
5890000d1cc1SJoe Perches				     "externs should be avoided in .c files\n" .  $herecurr);
5891de7d4f0eSAndy Whitcroft			}
5892de7d4f0eSAndy Whitcroft
5893171ae1a4SAndy Whitcroft			if ($paren_space =~ /\n/) {
5894000d1cc1SJoe Perches				WARN("FUNCTION_ARGUMENTS",
5895000d1cc1SJoe Perches				     "arguments for function declarations should follow identifier\n" . $herecurr);
5896171ae1a4SAndy Whitcroft			}
58979c9ba34eSAndy Whitcroft
58989c9ba34eSAndy Whitcroft		} elsif ($realfile =~ /\.c$/ && defined $stat &&
58999c9ba34eSAndy Whitcroft		    $stat =~ /^.\s*extern\s+/)
59009c9ba34eSAndy Whitcroft		{
5901000d1cc1SJoe Perches			WARN("AVOID_EXTERNS",
5902000d1cc1SJoe Perches			     "externs should be avoided in .c files\n" .  $herecurr);
5903171ae1a4SAndy Whitcroft		}
5904171ae1a4SAndy Whitcroft
5905ca0d8929SJoe Perches		if ($realfile =~ /\.[ch]$/ && defined $stat &&
5906ca0d8929SJoe Perches		    $stat =~ /^.\s*(?:extern\s+)?$Type\s*$Ident\s*\(\s*([^{]+)\s*\)\s*;/s &&
5907ca0d8929SJoe Perches		    $1 ne "void") {
5908ca0d8929SJoe Perches			my $args = trim($1);
5909ca0d8929SJoe Perches			while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {
5910ca0d8929SJoe Perches				my $arg = trim($1);
5911ca0d8929SJoe Perches				if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {
5912ca0d8929SJoe Perches					WARN("FUNCTION_ARGUMENTS",
5913ca0d8929SJoe Perches					     "function definition argument '$arg' should also have an identifier name\n" . $herecurr);
5914ca0d8929SJoe Perches				}
5915ca0d8929SJoe Perches			}
5916ca0d8929SJoe Perches		}
5917ca0d8929SJoe Perches
5918de7d4f0eSAndy Whitcroft# checks for new __setup's
5919de7d4f0eSAndy Whitcroft		if ($rawline =~ /\b__setup\("([^"]*)"/) {
5920de7d4f0eSAndy Whitcroft			my $name = $1;
5921de7d4f0eSAndy Whitcroft
5922de7d4f0eSAndy Whitcroft			if (!grep(/$name/, @setup_docs)) {
5923000d1cc1SJoe Perches				CHK("UNDOCUMENTED_SETUP",
59248c27ceffSMauro Carvalho Chehab				    "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.rst\n" . $herecurr);
5925de7d4f0eSAndy Whitcroft			}
5926653d4876SAndy Whitcroft		}
59279c0ca6f9SAndy Whitcroft
59289c0ca6f9SAndy Whitcroft# check for pointless casting of kmalloc return
5929caf2a54fSJoe Perches		if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) {
5930000d1cc1SJoe Perches			WARN("UNNECESSARY_CASTS",
5931000d1cc1SJoe Perches			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
59329c0ca6f9SAndy Whitcroft		}
593313214adfSAndy Whitcroft
5934a640d25cSJoe Perches# alloc style
5935a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
5936a640d25cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
5937a640d25cSJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
5938a640d25cSJoe Perches			CHK("ALLOC_SIZEOF_STRUCT",
5939a640d25cSJoe Perches			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
5940a640d25cSJoe Perches		}
5941a640d25cSJoe Perches
594260a55369SJoe Perches# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
594360a55369SJoe Perches		if ($^V && $^V ge 5.10.0 &&
59441b4a2ed4SJoe Perches		    defined $stat &&
59451b4a2ed4SJoe Perches		    $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {
594660a55369SJoe Perches			my $oldfunc = $3;
594760a55369SJoe Perches			my $a1 = $4;
594860a55369SJoe Perches			my $a2 = $10;
594960a55369SJoe Perches			my $newfunc = "kmalloc_array";
595060a55369SJoe Perches			$newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
595160a55369SJoe Perches			my $r1 = $a1;
595260a55369SJoe Perches			my $r2 = $a2;
595360a55369SJoe Perches			if ($a1 =~ /^sizeof\s*\S/) {
595460a55369SJoe Perches				$r1 = $a2;
595560a55369SJoe Perches				$r2 = $a1;
595660a55369SJoe Perches			}
5957e367455aSJoe Perches			if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&
5958e367455aSJoe Perches			    !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {
59591b4a2ed4SJoe Perches				my $ctx = '';
59601b4a2ed4SJoe Perches				my $herectx = $here . "\n";
59611b4a2ed4SJoe Perches				my $cnt = statement_rawlines($stat);
59621b4a2ed4SJoe Perches				for (my $n = 0; $n < $cnt; $n++) {
59631b4a2ed4SJoe Perches					$herectx .= raw_line($linenr, $n) . "\n";
59641b4a2ed4SJoe Perches				}
5965e367455aSJoe Perches				if (WARN("ALLOC_WITH_MULTIPLY",
59661b4a2ed4SJoe Perches					 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&
59671b4a2ed4SJoe Perches				    $cnt == 1 &&
5968e367455aSJoe Perches				    $fix) {
5969194f66fcSJoe 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;
597060a55369SJoe Perches				}
597160a55369SJoe Perches			}
597260a55369SJoe Perches		}
597360a55369SJoe Perches
5974972fdea2SJoe Perches# check for krealloc arg reuse
5975972fdea2SJoe Perches		if ($^V && $^V ge 5.10.0 &&
5976972fdea2SJoe Perches		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) {
5977972fdea2SJoe Perches			WARN("KREALLOC_ARG_REUSE",
5978972fdea2SJoe Perches			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);
5979972fdea2SJoe Perches		}
5980972fdea2SJoe Perches
59815ce59ae0SJoe Perches# check for alloc argument mismatch
59825ce59ae0SJoe Perches		if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {
59835ce59ae0SJoe Perches			WARN("ALLOC_ARRAY_ARGS",
59845ce59ae0SJoe Perches			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);
59855ce59ae0SJoe Perches		}
59865ce59ae0SJoe Perches
5987caf2a54fSJoe Perches# check for multiple semicolons
5988caf2a54fSJoe Perches		if ($line =~ /;\s*;\s*$/) {
5989d5e616fcSJoe Perches			if (WARN("ONE_SEMICOLON",
5990d5e616fcSJoe Perches				 "Statements terminations use 1 semicolon\n" . $herecurr) &&
5991d5e616fcSJoe Perches			    $fix) {
5992194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;
5993d5e616fcSJoe Perches			}
5994d1e2ad07SJoe Perches		}
5995d1e2ad07SJoe Perches
5996cec3aaa5STomas Winkler# check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi
5997cec3aaa5STomas Winkler		if ($realfile !~ m@^include/uapi/@ &&
5998cec3aaa5STomas Winkler		    $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {
59990ab90191SJoe Perches			my $ull = "";
60000ab90191SJoe Perches			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);
60010ab90191SJoe Perches			if (CHK("BIT_MACRO",
60020ab90191SJoe Perches				"Prefer using the BIT$ull macro\n" . $herecurr) &&
60030ab90191SJoe Perches			    $fix) {
60040ab90191SJoe Perches				$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;
60050ab90191SJoe Perches			}
60060ab90191SJoe Perches		}
60070ab90191SJoe Perches
60082d632745SJoe Perches# check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE
60092d632745SJoe 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*$/) {
60102d632745SJoe Perches			my $config = $1;
60112d632745SJoe Perches			if (WARN("PREFER_IS_ENABLED",
60122d632745SJoe Perches				 "Prefer IS_ENABLED(<FOO>) to CONFIG_<FOO> || CONFIG_<FOO>_MODULE\n" . $herecurr) &&
60132d632745SJoe Perches			    $fix) {
60142d632745SJoe Perches				$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";
60152d632745SJoe Perches			}
60162d632745SJoe Perches		}
60172d632745SJoe Perches
6018e81f239bSJoe Perches# check for case / default statements not preceded by break/fallthrough/switch
6019c34c09a8SJoe Perches		if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
6020c34c09a8SJoe Perches			my $has_break = 0;
6021c34c09a8SJoe Perches			my $has_statement = 0;
6022c34c09a8SJoe Perches			my $count = 0;
6023c34c09a8SJoe Perches			my $prevline = $linenr;
6024e81f239bSJoe Perches			while ($prevline > 1 && ($file || $count < 3) && !$has_break) {
6025c34c09a8SJoe Perches				$prevline--;
6026c34c09a8SJoe Perches				my $rline = $rawlines[$prevline - 1];
6027c34c09a8SJoe Perches				my $fline = $lines[$prevline - 1];
6028c34c09a8SJoe Perches				last if ($fline =~ /^\@\@/);
6029c34c09a8SJoe Perches				next if ($fline =~ /^\-/);
6030c34c09a8SJoe Perches				next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/);
6031c34c09a8SJoe Perches				$has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i);
6032c34c09a8SJoe Perches				next if ($fline =~ /^.[\s$;]*$/);
6033c34c09a8SJoe Perches				$has_statement = 1;
6034c34c09a8SJoe Perches				$count++;
6035c34c09a8SJoe Perches				$has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/);
6036c34c09a8SJoe Perches			}
6037c34c09a8SJoe Perches			if (!$has_break && $has_statement) {
6038c34c09a8SJoe Perches				WARN("MISSING_BREAK",
6039224236d9SAndrew Morton				     "Possible switch case/default not preceded by break or fallthrough comment\n" . $herecurr);
6040c34c09a8SJoe Perches			}
6041c34c09a8SJoe Perches		}
6042c34c09a8SJoe Perches
6043d1e2ad07SJoe Perches# check for switch/default statements without a break;
6044d1e2ad07SJoe Perches		if ($^V && $^V ge 5.10.0 &&
6045d1e2ad07SJoe Perches		    defined $stat &&
6046d1e2ad07SJoe Perches		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
6047d1e2ad07SJoe Perches			my $ctx = '';
6048d1e2ad07SJoe Perches			my $herectx = $here . "\n";
6049d1e2ad07SJoe Perches			my $cnt = statement_rawlines($stat);
6050d1e2ad07SJoe Perches			for (my $n = 0; $n < $cnt; $n++) {
6051d1e2ad07SJoe Perches				$herectx .= raw_line($linenr, $n) . "\n";
6052d1e2ad07SJoe Perches			}
6053d1e2ad07SJoe Perches			WARN("DEFAULT_NO_BREAK",
6054d1e2ad07SJoe Perches			     "switch default: should use break\n" . $herectx);
6055caf2a54fSJoe Perches		}
6056caf2a54fSJoe Perches
605713214adfSAndy Whitcroft# check for gcc specific __FUNCTION__
6058d5e616fcSJoe Perches		if ($line =~ /\b__FUNCTION__\b/) {
6059d5e616fcSJoe Perches			if (WARN("USE_FUNC",
6060d5e616fcSJoe Perches				 "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr) &&
6061d5e616fcSJoe Perches			    $fix) {
6062194f66fcSJoe Perches				$fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;
6063d5e616fcSJoe Perches			}
606413214adfSAndy Whitcroft		}
6065773647a0SAndy Whitcroft
606662ec818fSJoe Perches# check for uses of __DATE__, __TIME__, __TIMESTAMP__
606762ec818fSJoe Perches		while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {
606862ec818fSJoe Perches			ERROR("DATE_TIME",
606962ec818fSJoe Perches			      "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);
607062ec818fSJoe Perches		}
607162ec818fSJoe Perches
60722c92488aSJoe Perches# check for use of yield()
60732c92488aSJoe Perches		if ($line =~ /\byield\s*\(\s*\)/) {
60742c92488aSJoe Perches			WARN("YIELD",
60752c92488aSJoe Perches			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);
60762c92488aSJoe Perches		}
60772c92488aSJoe Perches
6078179f8f40SJoe Perches# check for comparisons against true and false
6079179f8f40SJoe Perches		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
6080179f8f40SJoe Perches			my $lead = $1;
6081179f8f40SJoe Perches			my $arg = $2;
6082179f8f40SJoe Perches			my $test = $3;
6083179f8f40SJoe Perches			my $otype = $4;
6084179f8f40SJoe Perches			my $trail = $5;
6085179f8f40SJoe Perches			my $op = "!";
6086179f8f40SJoe Perches
6087179f8f40SJoe Perches			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
6088179f8f40SJoe Perches
6089179f8f40SJoe Perches			my $type = lc($otype);
6090179f8f40SJoe Perches			if ($type =~ /^(?:true|false)$/) {
6091179f8f40SJoe Perches				if (("$test" eq "==" && "$type" eq "true") ||
6092179f8f40SJoe Perches				    ("$test" eq "!=" && "$type" eq "false")) {
6093179f8f40SJoe Perches					$op = "";
6094179f8f40SJoe Perches				}
6095179f8f40SJoe Perches
6096179f8f40SJoe Perches				CHK("BOOL_COMPARISON",
6097179f8f40SJoe Perches				    "Using comparison to $otype is error prone\n" . $herecurr);
6098179f8f40SJoe Perches
6099179f8f40SJoe Perches## maybe suggesting a correct construct would better
6100179f8f40SJoe Perches##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
6101179f8f40SJoe Perches
6102179f8f40SJoe Perches			}
6103179f8f40SJoe Perches		}
6104179f8f40SJoe Perches
61054882720bSThomas Gleixner# check for semaphores initialized locked
61064882720bSThomas Gleixner		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
6107000d1cc1SJoe Perches			WARN("CONSIDER_COMPLETION",
6108000d1cc1SJoe Perches			     "consider using a completion\n" . $herecurr);
6109773647a0SAndy Whitcroft		}
61106712d858SJoe Perches
611167d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto*
611267d0a075SJoe Perches		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {
6113000d1cc1SJoe Perches			WARN("CONSIDER_KSTRTO",
611467d0a075SJoe Perches			     "$1 is obsolete, use k$3 instead\n" . $herecurr);
6115773647a0SAndy Whitcroft		}
61166712d858SJoe Perches
6117ae3ccc46SFabian Frederick# check for __initcall(), use device_initcall() explicitly or more appropriate function please
6118f3db6639SMichael Ellerman		if ($line =~ /^.\s*__initcall\s*\(/) {
6119000d1cc1SJoe Perches			WARN("USE_DEVICE_INITCALL",
6120ae3ccc46SFabian Frederick			     "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
6121f3db6639SMichael Ellerman		}
61226712d858SJoe Perches
61230f3c5aabSJoe Perches# check for various structs that are normally const (ops, kgdb, device_tree)
6124d9190e4eSJoe Perches# and avoid what seem like struct definitions 'struct foo {'
61256903ffb2SAndy Whitcroft		if ($line !~ /\bconst\b/ &&
6126d9190e4eSJoe Perches		    $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {
6127000d1cc1SJoe Perches			WARN("CONST_STRUCT",
6128d9190e4eSJoe Perches			     "struct $1 should normally be const\n" . $herecurr);
61292b6db5cbSAndy Whitcroft		}
6130773647a0SAndy Whitcroft
6131773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong
6132773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right
6133773647a0SAndy Whitcroft		if ($line =~ /\bNR_CPUS\b/ &&
6134c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
6135c45dcabdSAndy Whitcroft		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
6136171ae1a4SAndy Whitcroft		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
6137171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
6138171ae1a4SAndy Whitcroft		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/)
6139773647a0SAndy Whitcroft		{
6140000d1cc1SJoe Perches			WARN("NR_CPUS",
6141000d1cc1SJoe Perches			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
6142773647a0SAndy Whitcroft		}
61439c9ba34eSAndy Whitcroft
614452ea8506SJoe Perches# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
614552ea8506SJoe Perches		if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
614652ea8506SJoe Perches			ERROR("DEFINE_ARCH_HAS",
614752ea8506SJoe Perches			      "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
614852ea8506SJoe Perches		}
614952ea8506SJoe Perches
6150acd9362cSJoe Perches# likely/unlikely comparisons similar to "(likely(foo) > 0)"
6151acd9362cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
6152acd9362cSJoe Perches		    $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {
6153acd9362cSJoe Perches			WARN("LIKELY_MISUSE",
6154acd9362cSJoe Perches			     "Using $1 should generally have parentheses around the comparison\n" . $herecurr);
6155acd9362cSJoe Perches		}
6156acd9362cSJoe Perches
6157691d77b6SAndy Whitcroft# whine mightly about in_atomic
6158691d77b6SAndy Whitcroft		if ($line =~ /\bin_atomic\s*\(/) {
6159691d77b6SAndy Whitcroft			if ($realfile =~ m@^drivers/@) {
6160000d1cc1SJoe Perches				ERROR("IN_ATOMIC",
6161000d1cc1SJoe Perches				      "do not use in_atomic in drivers\n" . $herecurr);
6162f4a87736SAndy Whitcroft			} elsif ($realfile !~ m@^kernel/@) {
6163000d1cc1SJoe Perches				WARN("IN_ATOMIC",
6164000d1cc1SJoe Perches				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
6165691d77b6SAndy Whitcroft			}
6166691d77b6SAndy Whitcroft		}
61671704f47bSPeter Zijlstra
6168481aea5cSJoe Perches# whine about ACCESS_ONCE
6169481aea5cSJoe Perches		if ($^V && $^V ge 5.10.0 &&
6170481aea5cSJoe Perches		    $line =~ /\bACCESS_ONCE\s*$balanced_parens\s*(=(?!=))?\s*($FuncArg)?/) {
6171481aea5cSJoe Perches			my $par = $1;
6172481aea5cSJoe Perches			my $eq = $2;
6173481aea5cSJoe Perches			my $fun = $3;
6174481aea5cSJoe Perches			$par =~ s/^\(\s*(.*)\s*\)$/$1/;
6175481aea5cSJoe Perches			if (defined($eq)) {
6176481aea5cSJoe Perches				if (WARN("PREFER_WRITE_ONCE",
6177481aea5cSJoe Perches					 "Prefer WRITE_ONCE(<FOO>, <BAR>) over ACCESS_ONCE(<FOO>) = <BAR>\n" . $herecurr) &&
6178481aea5cSJoe Perches				    $fix) {
6179481aea5cSJoe Perches					$fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)\s*$eq\s*\Q$fun\E/WRITE_ONCE($par, $fun)/;
6180481aea5cSJoe Perches				}
6181481aea5cSJoe Perches			} else {
6182481aea5cSJoe Perches				if (WARN("PREFER_READ_ONCE",
6183481aea5cSJoe Perches					 "Prefer READ_ONCE(<FOO>) over ACCESS_ONCE(<FOO>)\n" . $herecurr) &&
6184481aea5cSJoe Perches				    $fix) {
6185481aea5cSJoe Perches					$fixed[$fixlinenr] =~ s/\bACCESS_ONCE\s*\(\s*\Q$par\E\s*\)/READ_ONCE($par)/;
6186481aea5cSJoe Perches				}
6187481aea5cSJoe Perches			}
6188481aea5cSJoe Perches		}
6189481aea5cSJoe Perches
61900f5225b0SPeter Zijlstra# check for mutex_trylock_recursive usage
61910f5225b0SPeter Zijlstra		if ($line =~ /mutex_trylock_recursive/) {
61920f5225b0SPeter Zijlstra			ERROR("LOCKING",
61930f5225b0SPeter Zijlstra			      "recursive locking is bad, do not use this ever.\n" . $herecurr);
61940f5225b0SPeter Zijlstra		}
61950f5225b0SPeter Zijlstra
61961704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class
61971704f47bSPeter Zijlstra		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
61981704f47bSPeter Zijlstra		    $line =~ /__lockdep_no_validate__\s*\)/ ) {
61991704f47bSPeter Zijlstra			if ($realfile !~ m@^kernel/lockdep@ &&
62001704f47bSPeter Zijlstra			    $realfile !~ m@^include/linux/lockdep@ &&
62011704f47bSPeter Zijlstra			    $realfile !~ m@^drivers/base/core@) {
6202000d1cc1SJoe Perches				ERROR("LOCKDEP",
6203000d1cc1SJoe Perches				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
62041704f47bSPeter Zijlstra			}
62051704f47bSPeter Zijlstra		}
620688f8831cSDave Jones
6207b392c64fSJoe Perches		if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||
6208b392c64fSJoe Perches		    $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {
6209000d1cc1SJoe Perches			WARN("EXPORTED_WORLD_WRITABLE",
6210000d1cc1SJoe Perches			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
621188f8831cSDave Jones		}
62122435880fSJoe Perches
6213515a235eSJoe Perches# Mode permission misuses where it seems decimal should be octal
6214515a235eSJoe Perches# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
6215515a235eSJoe Perches		if ($^V && $^V ge 5.10.0 &&
6216459cf0aeSJoe Perches		    defined $stat &&
6217515a235eSJoe Perches		    $line =~ /$mode_perms_search/) {
62182435880fSJoe Perches			foreach my $entry (@mode_permission_funcs) {
62192435880fSJoe Perches				my $func = $entry->[0];
62202435880fSJoe Perches				my $arg_pos = $entry->[1];
62212435880fSJoe Perches
6222459cf0aeSJoe Perches				my $lc = $stat =~ tr@\n@@;
6223459cf0aeSJoe Perches				$lc = $lc + $linenr;
6224459cf0aeSJoe Perches				my $stat_real = raw_line($linenr, 0);
6225459cf0aeSJoe Perches				for (my $count = $linenr + 1; $count <= $lc; $count++) {
6226459cf0aeSJoe Perches					$stat_real = $stat_real . "\n" . raw_line($count, 0);
6227459cf0aeSJoe Perches				}
6228459cf0aeSJoe Perches
62292435880fSJoe Perches				my $skip_args = "";
62302435880fSJoe Perches				if ($arg_pos > 1) {
62312435880fSJoe Perches					$arg_pos--;
62322435880fSJoe Perches					$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
62332435880fSJoe Perches				}
6234f90774e1SJoe Perches				my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";
6235459cf0aeSJoe Perches				if ($stat =~ /$test/) {
62362435880fSJoe Perches					my $val = $1;
62372435880fSJoe Perches					$val = $6 if ($skip_args ne "");
6238f90774e1SJoe Perches					if (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
6239f90774e1SJoe Perches					    ($val =~ /^$Octal$/ && length($val) ne 4)) {
62402435880fSJoe Perches						ERROR("NON_OCTAL_PERMISSIONS",
6241459cf0aeSJoe Perches						      "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);
6242f90774e1SJoe Perches					}
6243f90774e1SJoe Perches					if ($val =~ /^$Octal$/ && (oct($val) & 02)) {
6244c0a5c898SJoe Perches						ERROR("EXPORTED_WORLD_WRITABLE",
6245459cf0aeSJoe Perches						      "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);
62462435880fSJoe Perches					}
6247459cf0aeSJoe Perches				}
6248459cf0aeSJoe Perches			}
6249459cf0aeSJoe Perches		}
6250459cf0aeSJoe Perches
6251459cf0aeSJoe Perches# check for uses of S_<PERMS> that could be octal for readability
6252459cf0aeSJoe Perches		if ($line =~ /\b$mode_perms_string_search\b/) {
6253459cf0aeSJoe Perches			my $val = "";
6254459cf0aeSJoe Perches			my $oval = "";
6255f90774e1SJoe Perches			my $to = 0;
6256459cf0aeSJoe Perches			my $curpos = 0;
6257459cf0aeSJoe Perches			my $lastpos = 0;
6258459cf0aeSJoe Perches			while ($line =~ /\b(($mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
6259459cf0aeSJoe Perches				$curpos = pos($line);
6260459cf0aeSJoe Perches				my $match = $2;
6261459cf0aeSJoe Perches				my $omatch = $1;
6262459cf0aeSJoe Perches				last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
6263459cf0aeSJoe Perches				$lastpos = $curpos;
6264459cf0aeSJoe Perches				$to |= $mode_permission_string_types{$match};
6265459cf0aeSJoe Perches				$val .= '\s*\|\s*' if ($val ne "");
6266459cf0aeSJoe Perches				$val .= $match;
6267459cf0aeSJoe Perches				$oval .= $omatch;
6268f90774e1SJoe Perches			}
6269459cf0aeSJoe Perches			$oval =~ s/^\s*\|\s*//;
6270459cf0aeSJoe Perches			$oval =~ s/\s*\|\s*$//;
6271459cf0aeSJoe Perches			my $octal = sprintf("%04o", $to);
6272f90774e1SJoe Perches			if (WARN("SYMBOLIC_PERMS",
6273459cf0aeSJoe Perches				 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&
6274f90774e1SJoe Perches			    $fix) {
6275459cf0aeSJoe Perches				$fixed[$fixlinenr] =~ s/$val/$octal/;
62762435880fSJoe Perches			}
627713214adfSAndy Whitcroft		}
62785a6d20ceSBjorn Andersson
62795a6d20ceSBjorn Andersson# validate content of MODULE_LICENSE against list from include/linux/module.h
62805a6d20ceSBjorn Andersson		if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {
62815a6d20ceSBjorn Andersson			my $extracted_string = get_quoted_string($line, $rawline);
62825a6d20ceSBjorn Andersson			my $valid_licenses = qr{
62835a6d20ceSBjorn Andersson						GPL|
62845a6d20ceSBjorn Andersson						GPL\ v2|
62855a6d20ceSBjorn Andersson						GPL\ and\ additional\ rights|
62865a6d20ceSBjorn Andersson						Dual\ BSD/GPL|
62875a6d20ceSBjorn Andersson						Dual\ MIT/GPL|
62885a6d20ceSBjorn Andersson						Dual\ MPL/GPL|
62895a6d20ceSBjorn Andersson						Proprietary
62905a6d20ceSBjorn Andersson					}x;
62915a6d20ceSBjorn Andersson			if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {
62925a6d20ceSBjorn Andersson				WARN("MODULE_LICENSE",
62935a6d20ceSBjorn Andersson				     "unknown module license " . $extracted_string . "\n" . $herecurr);
62945a6d20ceSBjorn Andersson			}
62955a6d20ceSBjorn Andersson		}
6296515a235eSJoe Perches	}
629713214adfSAndy Whitcroft
629813214adfSAndy Whitcroft	# If we have no input at all, then there is nothing to report on
629913214adfSAndy Whitcroft	# so just keep quiet.
630013214adfSAndy Whitcroft	if ($#rawlines == -1) {
630113214adfSAndy Whitcroft		exit(0);
63020a920b5bSAndy Whitcroft	}
63030a920b5bSAndy Whitcroft
63048905a67cSAndy Whitcroft	# In mailback mode only produce a report in the negative, for
63058905a67cSAndy Whitcroft	# things that appear to be patches.
63068905a67cSAndy Whitcroft	if ($mailback && ($clean == 1 || !$is_patch)) {
63078905a67cSAndy Whitcroft		exit(0);
63088905a67cSAndy Whitcroft	}
63098905a67cSAndy Whitcroft
63108905a67cSAndy Whitcroft	# This is not a patch, and we are are in 'no-patch' mode so
63118905a67cSAndy Whitcroft	# just keep quiet.
63128905a67cSAndy Whitcroft	if (!$chk_patch && !$is_patch) {
63138905a67cSAndy Whitcroft		exit(0);
63148905a67cSAndy Whitcroft	}
63158905a67cSAndy Whitcroft
631606330fc4SJoe Perches	if (!$is_patch && $file !~ /cover-letter\.patch$/) {
6317000d1cc1SJoe Perches		ERROR("NOT_UNIFIED_DIFF",
6318000d1cc1SJoe Perches		      "Does not appear to be a unified-diff format patch\n");
63190a920b5bSAndy Whitcroft	}
6320ed43c4e5SAllen Hubbe	if ($is_patch && $has_commit_log && $chk_signoff && $signoff == 0) {
6321000d1cc1SJoe Perches		ERROR("MISSING_SIGN_OFF",
6322000d1cc1SJoe Perches		      "Missing Signed-off-by: line(s)\n");
63230a920b5bSAndy Whitcroft	}
63240a920b5bSAndy Whitcroft
6325f0a594c1SAndy Whitcroft	print report_dump();
632613214adfSAndy Whitcroft	if ($summary && !($clean == 1 && $quiet == 1)) {
632713214adfSAndy Whitcroft		print "$filename " if ($summary_file);
63286c72ffaaSAndy Whitcroft		print "total: $cnt_error errors, $cnt_warn warnings, " .
63296c72ffaaSAndy Whitcroft			(($check)? "$cnt_chk checks, " : "") .
63306c72ffaaSAndy Whitcroft			"$cnt_lines lines checked\n";
63316c72ffaaSAndy Whitcroft	}
63328905a67cSAndy Whitcroft
6333d2c0a235SAndy Whitcroft	if ($quiet == 0) {
6334ef212196SJoe Perches		# If there were any defects found and not already fixing them
6335ef212196SJoe Perches		if (!$clean and !$fix) {
6336ef212196SJoe Perches			print << "EOM"
6337ef212196SJoe Perches
6338ef212196SJoe PerchesNOTE: For some of the reported defects, checkpatch may be able to
6339ef212196SJoe Perches      mechanically convert to the typical style using --fix or --fix-inplace.
6340ef212196SJoe PerchesEOM
6341ef212196SJoe Perches		}
6342d2c0a235SAndy Whitcroft		# If there were whitespace errors which cleanpatch can fix
6343d2c0a235SAndy Whitcroft		# then suggest that.
6344d2c0a235SAndy Whitcroft		if ($rpt_cleaners) {
6345b0781216SMike Frysinger			$rpt_cleaners = 0;
6346d8469f16SJoe Perches			print << "EOM"
6347d8469f16SJoe Perches
6348d8469f16SJoe PerchesNOTE: Whitespace errors detected.
6349d8469f16SJoe Perches      You may wish to use scripts/cleanpatch or scripts/cleanfile
6350d8469f16SJoe PerchesEOM
6351d2c0a235SAndy Whitcroft		}
6352d2c0a235SAndy Whitcroft	}
6353d2c0a235SAndy Whitcroft
6354d752fcc8SJoe Perches	if ($clean == 0 && $fix &&
6355d752fcc8SJoe Perches	    ("@rawlines" ne "@fixed" ||
6356d752fcc8SJoe Perches	     $#fixed_inserted >= 0 || $#fixed_deleted >= 0)) {
63579624b8d6SJoe Perches		my $newfile = $filename;
63589624b8d6SJoe Perches		$newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
63593705ce5bSJoe Perches		my $linecount = 0;
63603705ce5bSJoe Perches		my $f;
63613705ce5bSJoe Perches
6362d752fcc8SJoe Perches		@fixed = fix_inserted_deleted_lines(\@fixed, \@fixed_inserted, \@fixed_deleted);
6363d752fcc8SJoe Perches
63643705ce5bSJoe Perches		open($f, '>', $newfile)
63653705ce5bSJoe Perches		    or die "$P: Can't open $newfile for write\n";
63663705ce5bSJoe Perches		foreach my $fixed_line (@fixed) {
63673705ce5bSJoe Perches			$linecount++;
63683705ce5bSJoe Perches			if ($file) {
63693705ce5bSJoe Perches				if ($linecount > 3) {
63703705ce5bSJoe Perches					$fixed_line =~ s/^\+//;
63713705ce5bSJoe Perches					print $f $fixed_line . "\n";
63723705ce5bSJoe Perches				}
63733705ce5bSJoe Perches			} else {
63743705ce5bSJoe Perches				print $f $fixed_line . "\n";
63753705ce5bSJoe Perches			}
63763705ce5bSJoe Perches		}
63773705ce5bSJoe Perches		close($f);
63783705ce5bSJoe Perches
63793705ce5bSJoe Perches		if (!$quiet) {
63803705ce5bSJoe Perches			print << "EOM";
6381d8469f16SJoe Perches
63823705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile'
63833705ce5bSJoe Perches
63843705ce5bSJoe PerchesDo _NOT_ trust the results written to this file.
63853705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness.
63863705ce5bSJoe Perches
63873705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches.
63883705ce5bSJoe PerchesNo warranties, expressed or implied...
63893705ce5bSJoe PerchesEOM
63903705ce5bSJoe Perches		}
63913705ce5bSJoe Perches	}
63923705ce5bSJoe Perches
6393d8469f16SJoe Perches	if ($quiet == 0) {
6394d8469f16SJoe Perches		print "\n";
6395d8469f16SJoe Perches		if ($clean == 1) {
6396d8469f16SJoe Perches			print "$vname has no obvious style problems and is ready for submission.\n";
6397d8469f16SJoe Perches		} else {
6398d8469f16SJoe Perches			print "$vname has style problems, please review.\n";
63990a920b5bSAndy Whitcroft		}
64000a920b5bSAndy Whitcroft	}
64010a920b5bSAndy Whitcroft	return $clean;
64020a920b5bSAndy Whitcroft}
6403