xref: /linux-6.15/scripts/checkpatch.pl (revision 0a920b5b)
1*0a920b5bSAndy Whitcroft#!/usr/bin/perl -w
2*0a920b5bSAndy Whitcroft# (c) 2001, Dave Jones. <[email protected]> (the file handling bit)
3*0a920b5bSAndy Whitcroft# (c) 2005, Joel Scohpp <[email protected]> (the ugly bit)
4*0a920b5bSAndy Whitcroft# (c) 2007, Andy Whitcroft <[email protected]> (new conditions, test suite, etc)
5*0a920b5bSAndy Whitcroft# Licensed under the terms of the GNU GPL License version 2
6*0a920b5bSAndy Whitcroft
7*0a920b5bSAndy Whitcroftuse strict;
8*0a920b5bSAndy Whitcroft
9*0a920b5bSAndy Whitcroftmy $P = $0;
10*0a920b5bSAndy Whitcroft
11*0a920b5bSAndy Whitcroftmy $V = '0.01';
12*0a920b5bSAndy Whitcroft
13*0a920b5bSAndy Whitcroftuse Getopt::Long qw(:config no_auto_abbrev);
14*0a920b5bSAndy Whitcroft
15*0a920b5bSAndy Whitcroftmy $quiet = 0;
16*0a920b5bSAndy Whitcroftmy $tree = 1;
17*0a920b5bSAndy Whitcroftmy $chk_signoff = 1;
18*0a920b5bSAndy Whitcroftmy $chk_patch = 1;
19*0a920b5bSAndy WhitcroftGetOptions(
20*0a920b5bSAndy Whitcroft	'q|quiet'	=> \$quiet,
21*0a920b5bSAndy Whitcroft	'tree!'		=> \$tree,
22*0a920b5bSAndy Whitcroft	'signoff!'	=> \$chk_signoff,
23*0a920b5bSAndy Whitcroft	'patch!'	=> \$chk_patch,
24*0a920b5bSAndy Whitcroft) or exit;
25*0a920b5bSAndy Whitcroft
26*0a920b5bSAndy Whitcroftmy $exit = 0;
27*0a920b5bSAndy Whitcroft
28*0a920b5bSAndy Whitcroftif ($#ARGV < 0) {
29*0a920b5bSAndy Whitcroft	print "usage: patchstylecheckemail.pl [options] patchfile\n";
30*0a920b5bSAndy Whitcroft	print "version: $V\n";
31*0a920b5bSAndy Whitcroft	print "options: -q           => quiet\n";
32*0a920b5bSAndy Whitcroft	print "         --no-tree    => run without a kernel tree\n";
33*0a920b5bSAndy Whitcroft	exit(1);
34*0a920b5bSAndy Whitcroft}
35*0a920b5bSAndy Whitcroft
36*0a920b5bSAndy Whitcroftif ($tree && !top_of_kernel_tree()) {
37*0a920b5bSAndy Whitcroft	print "Must be run from the top-level dir. of a kernel tree\n";
38*0a920b5bSAndy Whitcroft	exit(2);
39*0a920b5bSAndy Whitcroft}
40*0a920b5bSAndy Whitcroft
41*0a920b5bSAndy Whitcroftmy @deprecated = ();
42*0a920b5bSAndy Whitcroftmy $removal = 'Documentation/feature-removal-schedule.txt';
43*0a920b5bSAndy Whitcroftif ($tree && -f $removal) {
44*0a920b5bSAndy Whitcroft	open(REMOVE, "<$removal") || die "$P: $removal: open failed - $!\n";
45*0a920b5bSAndy Whitcroft	while (<REMOVE>) {
46*0a920b5bSAndy Whitcroft		if (/^Files:\s+(.*\S)/) {
47*0a920b5bSAndy Whitcroft			for my $file (split(/[, ]+/, $1)) {
48*0a920b5bSAndy Whitcroft				if ($file =~ m@include/(.*)@) {
49*0a920b5bSAndy Whitcroft					push(@deprecated, $1);
50*0a920b5bSAndy Whitcroft				}
51*0a920b5bSAndy Whitcroft			}
52*0a920b5bSAndy Whitcroft		}
53*0a920b5bSAndy Whitcroft	}
54*0a920b5bSAndy Whitcroft}
55*0a920b5bSAndy Whitcroft
56*0a920b5bSAndy Whitcroftmy @lines = ();
57*0a920b5bSAndy Whitcroftwhile (<>) {
58*0a920b5bSAndy Whitcroft	chomp;
59*0a920b5bSAndy Whitcroft	push(@lines, $_);
60*0a920b5bSAndy Whitcroft	if (eof(ARGV)) {
61*0a920b5bSAndy Whitcroft		if (!process($ARGV, @lines)) {
62*0a920b5bSAndy Whitcroft			$exit = 1;
63*0a920b5bSAndy Whitcroft		}
64*0a920b5bSAndy Whitcroft		@lines = ();
65*0a920b5bSAndy Whitcroft	}
66*0a920b5bSAndy Whitcroft}
67*0a920b5bSAndy Whitcroft
68*0a920b5bSAndy Whitcroftexit($exit);
69*0a920b5bSAndy Whitcroft
70*0a920b5bSAndy Whitcroftsub top_of_kernel_tree {
71*0a920b5bSAndy Whitcroft	if ((-f "COPYING") && (-f "CREDITS") && (-f "Kbuild") &&
72*0a920b5bSAndy Whitcroft	    (-f "MAINTAINERS") && (-f "Makefile") && (-f "README") &&
73*0a920b5bSAndy Whitcroft	    (-d "Documentation") && (-d "arch") && (-d "include") &&
74*0a920b5bSAndy Whitcroft	    (-d "drivers") && (-d "fs") && (-d "init") && (-d "ipc") &&
75*0a920b5bSAndy Whitcroft	    (-d "kernel") && (-d "lib") && (-d "scripts")) {
76*0a920b5bSAndy Whitcroft		return 1;
77*0a920b5bSAndy Whitcroft	}
78*0a920b5bSAndy Whitcroft	return 0;
79*0a920b5bSAndy Whitcroft}
80*0a920b5bSAndy Whitcroft
81*0a920b5bSAndy Whitcroftsub expand_tabs {
82*0a920b5bSAndy Whitcroft	my ($str) = @_;
83*0a920b5bSAndy Whitcroft
84*0a920b5bSAndy Whitcroft	my $res = '';
85*0a920b5bSAndy Whitcroft	my $n = 0;
86*0a920b5bSAndy Whitcroft	for my $c (split(//, $str)) {
87*0a920b5bSAndy Whitcroft		if ($c eq "\t") {
88*0a920b5bSAndy Whitcroft			$res .= ' ';
89*0a920b5bSAndy Whitcroft			$n++;
90*0a920b5bSAndy Whitcroft			for (; ($n % 8) != 0; $n++) {
91*0a920b5bSAndy Whitcroft				$res .= ' ';
92*0a920b5bSAndy Whitcroft			}
93*0a920b5bSAndy Whitcroft			next;
94*0a920b5bSAndy Whitcroft		}
95*0a920b5bSAndy Whitcroft		$res .= $c;
96*0a920b5bSAndy Whitcroft		$n++;
97*0a920b5bSAndy Whitcroft	}
98*0a920b5bSAndy Whitcroft
99*0a920b5bSAndy Whitcroft	return $res;
100*0a920b5bSAndy Whitcroft}
101*0a920b5bSAndy Whitcroft
102*0a920b5bSAndy Whitcroftsub cat_vet {
103*0a920b5bSAndy Whitcroft	my ($vet) = @_;
104*0a920b5bSAndy Whitcroft
105*0a920b5bSAndy Whitcroft	$vet =~ s/\t/^I/;
106*0a920b5bSAndy Whitcroft	$vet =~ s/$/\$/;
107*0a920b5bSAndy Whitcroft
108*0a920b5bSAndy Whitcroft	return $vet;
109*0a920b5bSAndy Whitcroft}
110*0a920b5bSAndy Whitcroft
111*0a920b5bSAndy Whitcroftsub process {
112*0a920b5bSAndy Whitcroft	my $filename = shift;
113*0a920b5bSAndy Whitcroft	my @lines = @_;
114*0a920b5bSAndy Whitcroft
115*0a920b5bSAndy Whitcroft	my $linenr=0;
116*0a920b5bSAndy Whitcroft	my $prevline="";
117*0a920b5bSAndy Whitcroft	my $stashline="";
118*0a920b5bSAndy Whitcroft
119*0a920b5bSAndy Whitcroft	my $lineforcounting='';
120*0a920b5bSAndy Whitcroft	my $indent;
121*0a920b5bSAndy Whitcroft	my $previndent=0;
122*0a920b5bSAndy Whitcroft	my $stashindent=0;
123*0a920b5bSAndy Whitcroft
124*0a920b5bSAndy Whitcroft	my $clean = 1;
125*0a920b5bSAndy Whitcroft	my $signoff = 0;
126*0a920b5bSAndy Whitcroft	my $is_patch = 0;
127*0a920b5bSAndy Whitcroft
128*0a920b5bSAndy Whitcroft	# Trace the real file/line as we go.
129*0a920b5bSAndy Whitcroft	my $realfile = '';
130*0a920b5bSAndy Whitcroft	my $realline = 0;
131*0a920b5bSAndy Whitcroft	my $realcnt = 0;
132*0a920b5bSAndy Whitcroft	my $here = '';
133*0a920b5bSAndy Whitcroft	my $in_comment = 0;
134*0a920b5bSAndy Whitcroft	my $first_line = 0;
135*0a920b5bSAndy Whitcroft
136*0a920b5bSAndy Whitcroft	foreach my $line (@lines) {
137*0a920b5bSAndy Whitcroft		$linenr++;
138*0a920b5bSAndy Whitcroft
139*0a920b5bSAndy Whitcroft#extract the filename as it passes
140*0a920b5bSAndy Whitcroft		if ($line=~/^\+\+\+\s+(\S+)/) {
141*0a920b5bSAndy Whitcroft			$realfile=$1;
142*0a920b5bSAndy Whitcroft			$in_comment = 0;
143*0a920b5bSAndy Whitcroft			next;
144*0a920b5bSAndy Whitcroft		}
145*0a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied
146*0a920b5bSAndy Whitcroft		if ($line=~/^\@\@ -\d+,\d+ \+(\d+)(,(\d+))? \@\@/) {
147*0a920b5bSAndy Whitcroft			$is_patch = 1;
148*0a920b5bSAndy Whitcroft			$first_line = 1;
149*0a920b5bSAndy Whitcroft			$in_comment = 0;
150*0a920b5bSAndy Whitcroft			$realline=$1-1;
151*0a920b5bSAndy Whitcroft			if (defined $2) {
152*0a920b5bSAndy Whitcroft				$realcnt=$3+1;
153*0a920b5bSAndy Whitcroft			} else {
154*0a920b5bSAndy Whitcroft				$realcnt=1+1;
155*0a920b5bSAndy Whitcroft			}
156*0a920b5bSAndy Whitcroft			next;
157*0a920b5bSAndy Whitcroft		}
158*0a920b5bSAndy Whitcroft
159*0a920b5bSAndy Whitcroft#track the line number as we move through the hunk
160*0a920b5bSAndy Whitcroft		if ($line=~/^[ \+]/) {
161*0a920b5bSAndy Whitcroft			$realline++;
162*0a920b5bSAndy Whitcroft			$realcnt-- if ($realcnt != 0);
163*0a920b5bSAndy Whitcroft
164*0a920b5bSAndy Whitcroft			# track any sort of multi-line comment.  Obviously if
165*0a920b5bSAndy Whitcroft			# the added text or context do not include the whole
166*0a920b5bSAndy Whitcroft			# comment we will not see it. Such is life.
167*0a920b5bSAndy Whitcroft			#
168*0a920b5bSAndy Whitcroft			# Guestimate if this is a continuing comment.  If this
169*0a920b5bSAndy Whitcroft			# is the start of a diff block and this line starts
170*0a920b5bSAndy Whitcroft			# ' *' then it is very likely a comment.
171*0a920b5bSAndy Whitcroft			if ($first_line and $line =~ m@^.\s*\*@) {
172*0a920b5bSAndy Whitcroft				$in_comment = 1;
173*0a920b5bSAndy Whitcroft			}
174*0a920b5bSAndy Whitcroft			if ($line =~ m@/\*@) {
175*0a920b5bSAndy Whitcroft				$in_comment = 1;
176*0a920b5bSAndy Whitcroft			}
177*0a920b5bSAndy Whitcroft			if ($line =~ m@\*/@) {
178*0a920b5bSAndy Whitcroft				$in_comment = 0;
179*0a920b5bSAndy Whitcroft			}
180*0a920b5bSAndy Whitcroft
181*0a920b5bSAndy Whitcroft			$lineforcounting = $line;
182*0a920b5bSAndy Whitcroft			$lineforcounting =~ s/^\+//;
183*0a920b5bSAndy Whitcroft			$lineforcounting = expand_tabs($lineforcounting);
184*0a920b5bSAndy Whitcroft
185*0a920b5bSAndy Whitcroft			my ($white) = ($lineforcounting =~ /^(\s*)/);
186*0a920b5bSAndy Whitcroft			$indent = length($white);
187*0a920b5bSAndy Whitcroft
188*0a920b5bSAndy Whitcroft			# Track the previous line.
189*0a920b5bSAndy Whitcroft			($prevline, $stashline) = ($stashline, $line);
190*0a920b5bSAndy Whitcroft			($previndent, $stashindent) = ($stashindent, $indent);
191*0a920b5bSAndy Whitcroft			$first_line = 0;
192*0a920b5bSAndy Whitcroft		}
193*0a920b5bSAndy Whitcroft
194*0a920b5bSAndy Whitcroft#make up the handle for any error we report on this line
195*0a920b5bSAndy Whitcroft		$here = "PATCH: $ARGV:$linenr:";
196*0a920b5bSAndy Whitcroft		$here .= "\nFILE: $realfile:$realline:" if ($realcnt != 0);
197*0a920b5bSAndy Whitcroft
198*0a920b5bSAndy Whitcroft		my $herecurr = "$here\n$line\n\n";
199*0a920b5bSAndy Whitcroft		my $hereprev = "$here\n$prevline\n$line\n\n";
200*0a920b5bSAndy Whitcroft
201*0a920b5bSAndy Whitcroft#check the patch for a signoff:
202*0a920b5bSAndy Whitcroft		if ($line =~ /^\s*Signed-off-by:\s/) {
203*0a920b5bSAndy Whitcroft			$signoff++;
204*0a920b5bSAndy Whitcroft
205*0a920b5bSAndy Whitcroft		} elsif ($line =~ /^\s*signed-off-by:/i) {
206*0a920b5bSAndy Whitcroft			if (!($line =~ /^\s*Signed-off-by:/)) {
207*0a920b5bSAndy Whitcroft				print "use Signed-off-by:\n";
208*0a920b5bSAndy Whitcroft				print "$herecurr";
209*0a920b5bSAndy Whitcroft				$clean = 0;
210*0a920b5bSAndy Whitcroft			}
211*0a920b5bSAndy Whitcroft			if ($line =~ /^\s*signed-off-by:\S/i) {
212*0a920b5bSAndy Whitcroft				print "need space after Signed-off-by:\n";
213*0a920b5bSAndy Whitcroft				print "$herecurr";
214*0a920b5bSAndy Whitcroft				$clean = 0;
215*0a920b5bSAndy Whitcroft			}
216*0a920b5bSAndy Whitcroft		}
217*0a920b5bSAndy Whitcroft
218*0a920b5bSAndy Whitcroft#ignore lines not being added
219*0a920b5bSAndy Whitcroft		if ($line=~/^[^\+]/) {next;}
220*0a920b5bSAndy Whitcroft
221*0a920b5bSAndy Whitcroft# check we are in a valid source file *.[hcsS] if not then ignore this hunk
222*0a920b5bSAndy Whitcroft		next if ($realfile !~ /\.[hcsS]$/);
223*0a920b5bSAndy Whitcroft
224*0a920b5bSAndy Whitcroft#trailing whitespace
225*0a920b5bSAndy Whitcroft		if ($line=~/\S\s+$/) {
226*0a920b5bSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($line) . "\n\n";
227*0a920b5bSAndy Whitcroft			print "trailing whitespace\n";
228*0a920b5bSAndy Whitcroft			print "$herevet";
229*0a920b5bSAndy Whitcroft			$clean = 0;
230*0a920b5bSAndy Whitcroft		}
231*0a920b5bSAndy Whitcroft#80 column limit
232*0a920b5bSAndy Whitcroft		if (!($prevline=~/\/\*\*/) && length($lineforcounting) > 80) {
233*0a920b5bSAndy Whitcroft			print "line over 80 characters\n";
234*0a920b5bSAndy Whitcroft			print "$herecurr";
235*0a920b5bSAndy Whitcroft			$clean = 0;
236*0a920b5bSAndy Whitcroft		}
237*0a920b5bSAndy Whitcroft
238*0a920b5bSAndy Whitcroft# check we are in a valid source file *.[hc] if not then ignore this hunk
239*0a920b5bSAndy Whitcroft		next if ($realfile !~ /\.[hc]$/);
240*0a920b5bSAndy Whitcroft
241*0a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything
242*0a920b5bSAndy Whitcroft# more than 8 must use tabs.
243*0a920b5bSAndy Whitcroft		if ($line=~/^\+\s* \t\s*\S/ or $line=~/^\+\s*        \s*/) {
244*0a920b5bSAndy Whitcroft			my $herevet = "$here\n" . cat_vet($line) . "\n\n";
245*0a920b5bSAndy Whitcroft			print "use tabs not spaces\n";
246*0a920b5bSAndy Whitcroft			print "$herevet";
247*0a920b5bSAndy Whitcroft			$clean = 0;
248*0a920b5bSAndy Whitcroft		}
249*0a920b5bSAndy Whitcroft
250*0a920b5bSAndy Whitcroft		#
251*0a920b5bSAndy Whitcroft		# The rest of our checks refer specifically to C style
252*0a920b5bSAndy Whitcroft		# only apply those _outside_ comments.
253*0a920b5bSAndy Whitcroft		#
254*0a920b5bSAndy Whitcroft		next if ($in_comment);
255*0a920b5bSAndy Whitcroft
256*0a920b5bSAndy Whitcroft# no C99 // comments
257*0a920b5bSAndy Whitcroft		if ($line =~ m@//@ and !($line =~ m@\".*//.*\"@)) {
258*0a920b5bSAndy Whitcroft			print "do not use C99 // comments\n";
259*0a920b5bSAndy Whitcroft			print "$herecurr";
260*0a920b5bSAndy Whitcroft			$clean = 0;
261*0a920b5bSAndy Whitcroft		}
262*0a920b5bSAndy Whitcroft
263*0a920b5bSAndy Whitcroft		# Remove comments from the line before processing.
264*0a920b5bSAndy Whitcroft		$line =~ s@/\*.*\*/@@g;
265*0a920b5bSAndy Whitcroft		$line =~ s@/\*.*@@;
266*0a920b5bSAndy Whitcroft		$line =~ s@.*\*/@@;
267*0a920b5bSAndy Whitcroft		$line =~ s@//.*@@;
268*0a920b5bSAndy Whitcroft
269*0a920b5bSAndy Whitcroft#EXPORT_SYMBOL should immediately follow its function closing }.
270*0a920b5bSAndy Whitcroft		if (($line =~ /EXPORT_SYMBOL.*\(.*\)/) ||
271*0a920b5bSAndy Whitcroft		    ($line =~ /EXPORT_UNUSED_SYMBOL.*\(.*\)/)) {
272*0a920b5bSAndy Whitcroft			if (($prevline !~ /^}/) &&
273*0a920b5bSAndy Whitcroft			   ($prevline !~ /^\+}/) &&
274*0a920b5bSAndy Whitcroft			   ($prevline !~ /^ }/)) {
275*0a920b5bSAndy Whitcroft				print "EXPORT_SYMBOL(func); should immediately follow its function\n";
276*0a920b5bSAndy Whitcroft				print "$herecurr";
277*0a920b5bSAndy Whitcroft				$clean = 0;
278*0a920b5bSAndy Whitcroft			}
279*0a920b5bSAndy Whitcroft		}
280*0a920b5bSAndy Whitcroft
281*0a920b5bSAndy Whitcroft		# check for static initialisers.
282*0a920b5bSAndy Whitcroft		if ($line=~/\s*static\s.*=\s+(0|NULL);/) {
283*0a920b5bSAndy Whitcroft			print "do not initialise statics to 0 or NULL\n";
284*0a920b5bSAndy Whitcroft			print "$herecurr";
285*0a920b5bSAndy Whitcroft			$clean = 0;
286*0a920b5bSAndy Whitcroft		}
287*0a920b5bSAndy Whitcroft
288*0a920b5bSAndy Whitcroft		# check for new typedefs.
289*0a920b5bSAndy Whitcroft		if ($line=~/\s*typedef\s/) {
290*0a920b5bSAndy Whitcroft			print "do not add new typedefs\n";
291*0a920b5bSAndy Whitcroft			print "$herecurr";
292*0a920b5bSAndy Whitcroft			$clean = 0;
293*0a920b5bSAndy Whitcroft		}
294*0a920b5bSAndy Whitcroft
295*0a920b5bSAndy Whitcroft# * goes on variable not on type
296*0a920b5bSAndy Whitcroft		if ($line=~/[A-Za-z\d_]+\* [A-Za-z\d_]+/) {
297*0a920b5bSAndy Whitcroft			print "\"foo* bar\" should be \"foo *bar\"\n";
298*0a920b5bSAndy Whitcroft			print "$herecurr";
299*0a920b5bSAndy Whitcroft			$clean = 0;
300*0a920b5bSAndy Whitcroft		}
301*0a920b5bSAndy Whitcroft
302*0a920b5bSAndy Whitcroft# # no BUG() or BUG_ON()
303*0a920b5bSAndy Whitcroft# 		if ($line =~ /\b(BUG|BUG_ON)\b/) {
304*0a920b5bSAndy Whitcroft# 			print "Try to use WARN_ON & Recovery code rather than BUG() or BUG_ON()\n";
305*0a920b5bSAndy Whitcroft# 			print "$herecurr";
306*0a920b5bSAndy Whitcroft# 			$clean = 0;
307*0a920b5bSAndy Whitcroft# 		}
308*0a920b5bSAndy Whitcroft
309*0a920b5bSAndy Whitcroft# printk should use KERN_* levels
310*0a920b5bSAndy Whitcroft		if ($line =~ /\bprintk\((?!KERN_)/) {
311*0a920b5bSAndy Whitcroft			print "printk() should include KERN_ facility level\n";
312*0a920b5bSAndy Whitcroft			print "$herecurr";
313*0a920b5bSAndy Whitcroft			$clean = 0;
314*0a920b5bSAndy Whitcroft		}
315*0a920b5bSAndy Whitcroft
316*0a920b5bSAndy Whitcroft#function brace can't be on same line, except for #defines of do while, or if closed on same line
317*0a920b5bSAndy Whitcroft		if (($line=~/[A-Za-z\d_]+\**\s+\**[A-Za-z\d_]+\(.*\).* {/) and
318*0a920b5bSAndy Whitcroft		    !($line=~/\#define.*do\s{/) and !($line=~/}/)) {
319*0a920b5bSAndy Whitcroft			print "braces following function declarations go on the next line\n";
320*0a920b5bSAndy Whitcroft			print "$herecurr";
321*0a920b5bSAndy Whitcroft			$clean = 0;
322*0a920b5bSAndy Whitcroft		}
323*0a920b5bSAndy Whitcroft		my $opline = $line;
324*0a920b5bSAndy Whitcroft		$opline =~ s/^.//;
325*0a920b5bSAndy Whitcroft		if (!($line=~/\#\s*include/)) {
326*0a920b5bSAndy Whitcroft			# Check operator spacing.
327*0a920b5bSAndy Whitcroft			my @elements = split(/(<<=|>>=|<=|>=|==|!=|\+=|-=|\*=|\/=|%=|\^=|\|=|&=|->|<<|>>|<|>|=|!|~|&&|\|\||,|\^|\+\+|--|;|&|\||\+|-|\*|\/\/|\/)/, $opline);
328*0a920b5bSAndy Whitcroft			for (my $n = 0; $n < $#elements; $n += 2) {
329*0a920b5bSAndy Whitcroft				# $wN says we have white-space before or after
330*0a920b5bSAndy Whitcroft				# $sN says we have a separator before or after
331*0a920b5bSAndy Whitcroft				# $oN says we have another operator before or after
332*0a920b5bSAndy Whitcroft				my $w1 = $elements[$n] =~ /\s$/;
333*0a920b5bSAndy Whitcroft				my $s1 = $elements[$n] =~ /(\[|\(|\s)$/;
334*0a920b5bSAndy Whitcroft				my $o1 = $elements[$n] eq '';
335*0a920b5bSAndy Whitcroft				my $op = $elements[$n + 1];
336*0a920b5bSAndy Whitcroft				my $w2 = 1;
337*0a920b5bSAndy Whitcroft				my $s2 = 1;
338*0a920b5bSAndy Whitcroft				my $o2 = 0;
339*0a920b5bSAndy Whitcroft				# If we have something after the operator handle it.
340*0a920b5bSAndy Whitcroft				if (defined $elements[$n + 2]) {
341*0a920b5bSAndy Whitcroft					$w2 = $elements[$n + 2] =~ /^\s/;
342*0a920b5bSAndy Whitcroft					$s2 = $elements[$n + 2] =~ /^(\s|\)|\]|;)/;
343*0a920b5bSAndy Whitcroft					$o2 = $elements[$n + 2] eq '';
344*0a920b5bSAndy Whitcroft				}
345*0a920b5bSAndy Whitcroft
346*0a920b5bSAndy Whitcroft				# Generate the context.
347*0a920b5bSAndy Whitcroft				my $at = "here: ";
348*0a920b5bSAndy Whitcroft				for (my $m = $n; $m >= 0; $m--) {
349*0a920b5bSAndy Whitcroft					if ($elements[$m] ne '') {
350*0a920b5bSAndy Whitcroft						$at .= $elements[$m];
351*0a920b5bSAndy Whitcroft						last;
352*0a920b5bSAndy Whitcroft					}
353*0a920b5bSAndy Whitcroft				}
354*0a920b5bSAndy Whitcroft				$at .= $op;
355*0a920b5bSAndy Whitcroft				for (my $m = $n + 2; defined $elements[$m]; $m++) {
356*0a920b5bSAndy Whitcroft					if ($elements[$m] ne '') {
357*0a920b5bSAndy Whitcroft						$at .= $elements[$m];
358*0a920b5bSAndy Whitcroft						last;
359*0a920b5bSAndy Whitcroft					}
360*0a920b5bSAndy Whitcroft				}
361*0a920b5bSAndy Whitcroft
362*0a920b5bSAndy Whitcroft				##print "<$s1:$op:$s2> <$elements[$n]:$elements[$n + 1]:$elements[$n + 2]>\n";
363*0a920b5bSAndy Whitcroft				# Skip things apparently in quotes.
364*0a920b5bSAndy Whitcroft				next if ($line=~/\".*\Q$op\E.*\"/ or $line=~/\'\Q$op\E\'/);
365*0a920b5bSAndy Whitcroft
366*0a920b5bSAndy Whitcroft				# We need ; as an operator.  // is a comment.
367*0a920b5bSAndy Whitcroft				if ($op eq ';' or $op eq '//') {
368*0a920b5bSAndy Whitcroft
369*0a920b5bSAndy Whitcroft				# -> should have no spaces
370*0a920b5bSAndy Whitcroft				} elsif ($op eq '->') {
371*0a920b5bSAndy Whitcroft					if ($s1 or $s2) {
372*0a920b5bSAndy Whitcroft						print "no spaces around that '$op' $at\n";
373*0a920b5bSAndy Whitcroft						print "$herecurr";
374*0a920b5bSAndy Whitcroft						$clean = 0;
375*0a920b5bSAndy Whitcroft					}
376*0a920b5bSAndy Whitcroft
377*0a920b5bSAndy Whitcroft				# , must have a space on the right.
378*0a920b5bSAndy Whitcroft				} elsif ($op eq ',') {
379*0a920b5bSAndy Whitcroft					if (!$s2) {
380*0a920b5bSAndy Whitcroft						print "need space after that '$op' $at\n";
381*0a920b5bSAndy Whitcroft						print "$herecurr";
382*0a920b5bSAndy Whitcroft						$clean = 0;
383*0a920b5bSAndy Whitcroft					}
384*0a920b5bSAndy Whitcroft
385*0a920b5bSAndy Whitcroft				# unary ! and unary ~ are allowed no space on the right
386*0a920b5bSAndy Whitcroft				} elsif ($op eq '!' or $op eq '~') {
387*0a920b5bSAndy Whitcroft					if (!$s1 && !$o1) {
388*0a920b5bSAndy Whitcroft						print "need space before that '$op' $at\n";
389*0a920b5bSAndy Whitcroft						print "$herecurr";
390*0a920b5bSAndy Whitcroft						$clean = 0;
391*0a920b5bSAndy Whitcroft					}
392*0a920b5bSAndy Whitcroft					if ($s2) {
393*0a920b5bSAndy Whitcroft						print "no space after that '$op' $at\n";
394*0a920b5bSAndy Whitcroft						print "$herecurr";
395*0a920b5bSAndy Whitcroft						$clean = 0;
396*0a920b5bSAndy Whitcroft					}
397*0a920b5bSAndy Whitcroft
398*0a920b5bSAndy Whitcroft				# unary ++ and unary -- are allowed no space on one side.
399*0a920b5bSAndy Whitcroft				} elsif ($op eq '++' or $op eq '--') {
400*0a920b5bSAndy Whitcroft					if (($s1 && $s2) || ((!$s1 && !$o1) && (!$s2 && !$o2))) {
401*0a920b5bSAndy Whitcroft						print "need space one side of that '$op' $at\n";
402*0a920b5bSAndy Whitcroft						print "$herecurr";
403*0a920b5bSAndy Whitcroft						$clean = 0;
404*0a920b5bSAndy Whitcroft					}
405*0a920b5bSAndy Whitcroft
406*0a920b5bSAndy Whitcroft				# & is both unary and binary
407*0a920b5bSAndy Whitcroft				# unary:
408*0a920b5bSAndy Whitcroft				# 	a &b
409*0a920b5bSAndy Whitcroft				# binary (consistent spacing):
410*0a920b5bSAndy Whitcroft				#	a&b		OK
411*0a920b5bSAndy Whitcroft				#	a & b		OK
412*0a920b5bSAndy Whitcroft				#
413*0a920b5bSAndy Whitcroft				# boiling down to: if there is a space on the right then there
414*0a920b5bSAndy Whitcroft				# should be one on the left.
415*0a920b5bSAndy Whitcroft				#
416*0a920b5bSAndy Whitcroft				# - is the same
417*0a920b5bSAndy Whitcroft				#
418*0a920b5bSAndy Whitcroft				# * is the same only adding:
419*0a920b5bSAndy Whitcroft				# type:
420*0a920b5bSAndy Whitcroft				# 	(foo *)
421*0a920b5bSAndy Whitcroft				#	(foo **)
422*0a920b5bSAndy Whitcroft				#
423*0a920b5bSAndy Whitcroft				} elsif ($op eq '&' or $op eq '-' or $op eq '*') {
424*0a920b5bSAndy Whitcroft					if ($w2 and !$w1) {
425*0a920b5bSAndy Whitcroft						print "need space before that '$op' $at\n";
426*0a920b5bSAndy Whitcroft						print "$herecurr";
427*0a920b5bSAndy Whitcroft						$clean = 0;
428*0a920b5bSAndy Whitcroft					}
429*0a920b5bSAndy Whitcroft
430*0a920b5bSAndy Whitcroft				# << and >> may either have or not have spaces both sides
431*0a920b5bSAndy Whitcroft				} elsif ($op eq '<<' or $op eq '>>' or $op eq '+' or $op eq '/' or
432*0a920b5bSAndy Whitcroft					 $op eq '^' or $op eq '|')
433*0a920b5bSAndy Whitcroft				{
434*0a920b5bSAndy Whitcroft					if ($s1 != $s2) {
435*0a920b5bSAndy Whitcroft						print "need consistent spacing around '$op' $at\n";
436*0a920b5bSAndy Whitcroft						print "$herecurr";
437*0a920b5bSAndy Whitcroft						$clean = 0;
438*0a920b5bSAndy Whitcroft					}
439*0a920b5bSAndy Whitcroft
440*0a920b5bSAndy Whitcroft				# All the others need spaces both sides.
441*0a920b5bSAndy Whitcroft				} elsif (!$s1 or !$s2) {
442*0a920b5bSAndy Whitcroft					print "need spaces around that '$op' $at\n";
443*0a920b5bSAndy Whitcroft					print "$herecurr";
444*0a920b5bSAndy Whitcroft					$clean = 0;
445*0a920b5bSAndy Whitcroft				}
446*0a920b5bSAndy Whitcroft			}
447*0a920b5bSAndy Whitcroft		}
448*0a920b5bSAndy Whitcroft
449*0a920b5bSAndy Whitcroft#need space before brace following if, while, etc
450*0a920b5bSAndy Whitcroft		if ($line=~/\(.*\){/) {
451*0a920b5bSAndy Whitcroft			print "need a space before the brace\n";
452*0a920b5bSAndy Whitcroft			print "$herecurr";
453*0a920b5bSAndy Whitcroft			$clean = 0;
454*0a920b5bSAndy Whitcroft		}
455*0a920b5bSAndy Whitcroft
456*0a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however
457*0a920b5bSAndy Whitcroft		if ($line=~/^.\s+[A-Za-z\d_]+:/ and
458*0a920b5bSAndy Whitcroft		   !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
459*0a920b5bSAndy Whitcroft			print "labels should not be indented\n";
460*0a920b5bSAndy Whitcroft			print "$herecurr";
461*0a920b5bSAndy Whitcroft			$clean = 0;
462*0a920b5bSAndy Whitcroft		}
463*0a920b5bSAndy Whitcroft
464*0a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc
465*0a920b5bSAndy Whitcroft		if ($line=~/(if|while|for|switch)\(/) {
466*0a920b5bSAndy Whitcroft			print "need a space before the open parenthesis\n";
467*0a920b5bSAndy Whitcroft			print "$herecurr";
468*0a920b5bSAndy Whitcroft			$clean = 0;
469*0a920b5bSAndy Whitcroft		}
470*0a920b5bSAndy Whitcroft
471*0a920b5bSAndy Whitcroft# Check for illegal assignment in if conditional.
472*0a920b5bSAndy Whitcroft		if ($line=~/(if|while)\s*\(.*[^<>!=]=[^=].*\)/) {
473*0a920b5bSAndy Whitcroft			print "do not use assignment in if condition\n";
474*0a920b5bSAndy Whitcroft			print "$herecurr";
475*0a920b5bSAndy Whitcroft			$clean = 0;
476*0a920b5bSAndy Whitcroft		}
477*0a920b5bSAndy Whitcroft
478*0a920b5bSAndy Whitcroft		# Check for }<nl>else {, these must be at the same
479*0a920b5bSAndy Whitcroft		# indent level to be relevant to each other.
480*0a920b5bSAndy Whitcroft		if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and
481*0a920b5bSAndy Whitcroft						$previndent == $indent) {
482*0a920b5bSAndy Whitcroft			print "else should follow close brace\n";
483*0a920b5bSAndy Whitcroft			print "$hereprev";
484*0a920b5bSAndy Whitcroft			$clean = 0;
485*0a920b5bSAndy Whitcroft		}
486*0a920b5bSAndy Whitcroft
487*0a920b5bSAndy Whitcroft		# Check for switch () {<nl>case, these must be at the
488*0a920b5bSAndy Whitcroft		# same indent.  We will only catch the first one, as our
489*0a920b5bSAndy Whitcroft		# context is very small but people tend to be consistent
490*0a920b5bSAndy Whitcroft		# so we will catch them out more often than not.
491*0a920b5bSAndy Whitcroft		if ($prevline=~/\s*switch\s*\(.*\)/ and $line=~/\s*case\s+/
492*0a920b5bSAndy Whitcroft						and $previndent != $indent) {
493*0a920b5bSAndy Whitcroft			print "switch and case should be at the same indent\n";
494*0a920b5bSAndy Whitcroft			print "$hereprev";
495*0a920b5bSAndy Whitcroft			$clean = 0;
496*0a920b5bSAndy Whitcroft		}
497*0a920b5bSAndy Whitcroft
498*0a920b5bSAndy Whitcroft#studly caps, commented out until figure out how to distinguish between use of existing and adding new
499*0a920b5bSAndy Whitcroft#		if (($line=~/[\w_][a-z\d]+[A-Z]/) and !($line=~/print/)) {
500*0a920b5bSAndy Whitcroft#		    print "No studly caps, use _\n";
501*0a920b5bSAndy Whitcroft#		    print "$herecurr";
502*0a920b5bSAndy Whitcroft#		    $clean = 0;
503*0a920b5bSAndy Whitcroft#		}
504*0a920b5bSAndy Whitcroft
505*0a920b5bSAndy Whitcroft#no spaces allowed after \ in define
506*0a920b5bSAndy Whitcroft		if ($line=~/\#define.*\\\s$/) {
507*0a920b5bSAndy Whitcroft			print("Whitepspace after \\ makes next lines useless\n");
508*0a920b5bSAndy Whitcroft			print "$herecurr";
509*0a920b5bSAndy Whitcroft			$clean = 0;
510*0a920b5bSAndy Whitcroft		}
511*0a920b5bSAndy Whitcroft
512*0a920b5bSAndy Whitcroft#warn if <asm/foo.h> is #included and <linux/foo.h> is available.
513*0a920b5bSAndy Whitcroft		if ($tree && $line =~ qr|\s*\#\s*include\s*\<asm\/(.*)\.h\>|) {
514*0a920b5bSAndy Whitcroft			my $checkfile = "include/linux/$1.h";
515*0a920b5bSAndy Whitcroft			if (-f $checkfile) {
516*0a920b5bSAndy Whitcroft				print "Use #include <linux/$1.h> instead of <asm/$1.h>\n";
517*0a920b5bSAndy Whitcroft				print $herecurr;
518*0a920b5bSAndy Whitcroft				$clean = 0;
519*0a920b5bSAndy Whitcroft			}
520*0a920b5bSAndy Whitcroft		}
521*0a920b5bSAndy Whitcroft
522*0a920b5bSAndy Whitcroft#if/while/etc brace do not go on next line, unless #defining a do while loop, or if that brace on the next line is for something else
523*0a920b5bSAndy Whitcroft		if ($prevline=~/(if|while|for|switch)\s*\(/) {
524*0a920b5bSAndy Whitcroft			my @opened = $prevline=~/\(/g;
525*0a920b5bSAndy Whitcroft			my @closed = $prevline=~/\)/g;
526*0a920b5bSAndy Whitcroft			my $nr_line = $linenr;
527*0a920b5bSAndy Whitcroft			my $remaining = $realcnt;
528*0a920b5bSAndy Whitcroft			my $next_line = $line;
529*0a920b5bSAndy Whitcroft			my $extra_lines = 0;
530*0a920b5bSAndy Whitcroft			my $display_segment = $prevline;
531*0a920b5bSAndy Whitcroft
532*0a920b5bSAndy Whitcroft			while ($remaining > 0 && scalar @opened > scalar @closed) {
533*0a920b5bSAndy Whitcroft				$prevline .= $next_line;
534*0a920b5bSAndy Whitcroft				$display_segment .= "\n" . $next_line;
535*0a920b5bSAndy Whitcroft				$next_line = $lines[$nr_line];
536*0a920b5bSAndy Whitcroft				$nr_line++;
537*0a920b5bSAndy Whitcroft				$remaining--;
538*0a920b5bSAndy Whitcroft
539*0a920b5bSAndy Whitcroft				@opened = $prevline=~/\(/g;
540*0a920b5bSAndy Whitcroft				@closed = $prevline=~/\)/g;
541*0a920b5bSAndy Whitcroft			}
542*0a920b5bSAndy Whitcroft
543*0a920b5bSAndy Whitcroft			if (($prevline=~/(if|while|for|switch)\s*\(.*\)\s*$/) and ($next_line=~/{/) and
544*0a920b5bSAndy Whitcroft			   !($next_line=~/(if|while|for)/) and !($next_line=~/\#define.*do.*while/)) {
545*0a920b5bSAndy Whitcroft				print "That { should be on the previous line\n";
546*0a920b5bSAndy Whitcroft				print "$display_segment\n$next_line\n\n";
547*0a920b5bSAndy Whitcroft				$clean = 0;
548*0a920b5bSAndy Whitcroft			}
549*0a920b5bSAndy Whitcroft		}
550*0a920b5bSAndy Whitcroft
551*0a920b5bSAndy Whitcroft#multiline macros should be enclosed in a do while loop
552*0a920b5bSAndy Whitcroft		if (($prevline=~/\#define.*\\/) and !($prevline=~/do\s+{/) and
553*0a920b5bSAndy Whitcroft		   !($prevline=~/\(\{/) and ($line=~/;\s*\\/) and
554*0a920b5bSAndy Whitcroft		   !($line=~/do.*{/) and !($line=~/\(\{/)) {
555*0a920b5bSAndy Whitcroft			print "Macros with multiple statements should be enclosed in a do - while loop\n";
556*0a920b5bSAndy Whitcroft			print "$hereprev";
557*0a920b5bSAndy Whitcroft			$clean = 0;
558*0a920b5bSAndy Whitcroft		}
559*0a920b5bSAndy Whitcroft
560*0a920b5bSAndy Whitcroft# don't include deprecated include files
561*0a920b5bSAndy Whitcroft		for my $inc (@deprecated) {
562*0a920b5bSAndy Whitcroft			if ($line =~ m@\#\s*include\s*\<$inc>@) {
563*0a920b5bSAndy Whitcroft				print "Don't use <$inc>: see Documentation/feature-removal-schedule.txt\n";
564*0a920b5bSAndy Whitcroft				print "$herecurr";
565*0a920b5bSAndy Whitcroft				$clean = 0;
566*0a920b5bSAndy Whitcroft			}
567*0a920b5bSAndy Whitcroft		}
568*0a920b5bSAndy Whitcroft
569*0a920b5bSAndy Whitcroft# don't use kernel_thread()
570*0a920b5bSAndy Whitcroft		if ($line =~ /\bkernel_thread\b/) {
571*0a920b5bSAndy Whitcroft			print "Don't use kernel_thread(), use kthread(): see Documentation/feature-removal-schedule.txt\n";
572*0a920b5bSAndy Whitcroft			print "$herecurr";
573*0a920b5bSAndy Whitcroft			$clean = 0;
574*0a920b5bSAndy Whitcroft		}
575*0a920b5bSAndy Whitcroft	}
576*0a920b5bSAndy Whitcroft
577*0a920b5bSAndy Whitcroft	if ($chk_patch && !$is_patch) {
578*0a920b5bSAndy Whitcroft		$clean = 0;
579*0a920b5bSAndy Whitcroft		print "Does not appear to be a unified-diff format patch\n";
580*0a920b5bSAndy Whitcroft	}
581*0a920b5bSAndy Whitcroft	if ($is_patch && $chk_signoff && $signoff == 0) {
582*0a920b5bSAndy Whitcroft		$clean = 0;
583*0a920b5bSAndy Whitcroft		print "Missing Signed-off-by: line(s)\n";
584*0a920b5bSAndy Whitcroft	}
585*0a920b5bSAndy Whitcroft
586*0a920b5bSAndy Whitcroft	if ($clean == 1 && $quiet == 0) {
587*0a920b5bSAndy Whitcroft		print "Your patch has no obvious style problems and is ready for submission.\n"
588*0a920b5bSAndy Whitcroft	}
589*0a920b5bSAndy Whitcroft	if ($clean == 0 && $quiet == 0) {
590*0a920b5bSAndy Whitcroft		print "Your patch has style problems, please review.  If any of these errors\n";
591*0a920b5bSAndy Whitcroft		print "are false positives report them to the maintainer, see\n";
592*0a920b5bSAndy Whitcroft		print "CHECKPATCH in MAINTAINERS.\n";
593*0a920b5bSAndy Whitcroft	}
594*0a920b5bSAndy Whitcroft	return $clean;
595*0a920b5bSAndy Whitcroft}
596