Commit 0c73b4eb7a825a5aff16d8a9701f6c28056de058

Authored by Andy Whitcroft
Committed by Linus Torvalds
1 parent 8cf6de7145

checkpatch: simplify and consolidate "missing space after" checks

Commonise the code for missing spaces after struct, union, and enum such
that they share the same code.  Ensure we cover all the common cases in
each case.  Check against the sanitised line to ensure we do not report on
comments and strings.

Signed-off-by: Andy Whitcroft <apw@canonical.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 5 additions and 10 deletions Inline Diff

scripts/checkpatch.pl
1 #!/usr/bin/perl -w 1 #!/usr/bin/perl -w
2 # (c) 2001, Dave Jones. (the file handling bit) 2 # (c) 2001, Dave Jones. (the file handling bit)
3 # (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit) 3 # (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
4 # (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite) 4 # (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
5 # (c) 2008,2009, Andy Whitcroft <apw@canonical.com> 5 # (c) 2008,2009, Andy Whitcroft <apw@canonical.com>
6 # Licensed under the terms of the GNU GPL License version 2 6 # Licensed under the terms of the GNU GPL License version 2
7 7
8 use strict; 8 use strict;
9 9
10 my $P = $0; 10 my $P = $0;
11 $P =~ s@.*/@@g; 11 $P =~ s@.*/@@g;
12 12
13 my $V = '0.30'; 13 my $V = '0.30';
14 14
15 use Getopt::Long qw(:config no_auto_abbrev); 15 use Getopt::Long qw(:config no_auto_abbrev);
16 16
17 my $quiet = 0; 17 my $quiet = 0;
18 my $tree = 1; 18 my $tree = 1;
19 my $chk_signoff = 1; 19 my $chk_signoff = 1;
20 my $chk_patch = 1; 20 my $chk_patch = 1;
21 my $tst_only; 21 my $tst_only;
22 my $emacs = 0; 22 my $emacs = 0;
23 my $terse = 0; 23 my $terse = 0;
24 my $file = 0; 24 my $file = 0;
25 my $check = 0; 25 my $check = 0;
26 my $summary = 1; 26 my $summary = 1;
27 my $mailback = 0; 27 my $mailback = 0;
28 my $summary_file = 0; 28 my $summary_file = 0;
29 my $root; 29 my $root;
30 my %debug; 30 my %debug;
31 my $help = 0; 31 my $help = 0;
32 32
33 sub help { 33 sub help {
34 my ($exitcode) = @_; 34 my ($exitcode) = @_;
35 35
36 print << "EOM"; 36 print << "EOM";
37 Usage: $P [OPTION]... [FILE]... 37 Usage: $P [OPTION]... [FILE]...
38 Version: $V 38 Version: $V
39 39
40 Options: 40 Options:
41 -q, --quiet quiet 41 -q, --quiet quiet
42 --no-tree run without a kernel tree 42 --no-tree run without a kernel tree
43 --no-signoff do not check for 'Signed-off-by' line 43 --no-signoff do not check for 'Signed-off-by' line
44 --patch treat FILE as patchfile (default) 44 --patch treat FILE as patchfile (default)
45 --emacs emacs compile window format 45 --emacs emacs compile window format
46 --terse one line per report 46 --terse one line per report
47 -f, --file treat FILE as regular source file 47 -f, --file treat FILE as regular source file
48 --subjective, --strict enable more subjective tests 48 --subjective, --strict enable more subjective tests
49 --root=PATH PATH to the kernel tree root 49 --root=PATH PATH to the kernel tree root
50 --no-summary suppress the per-file summary 50 --no-summary suppress the per-file summary
51 --mailback only produce a report in case of warnings/errors 51 --mailback only produce a report in case of warnings/errors
52 --summary-file include the filename in summary 52 --summary-file include the filename in summary
53 --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of 53 --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of
54 'values', 'possible', 'type', and 'attr' (default 54 'values', 'possible', 'type', and 'attr' (default
55 is all off) 55 is all off)
56 --test-only=WORD report only warnings/errors containing WORD 56 --test-only=WORD report only warnings/errors containing WORD
57 literally 57 literally
58 -h, --help, --version display this help and exit 58 -h, --help, --version display this help and exit
59 59
60 When FILE is - read standard input. 60 When FILE is - read standard input.
61 EOM 61 EOM
62 62
63 exit($exitcode); 63 exit($exitcode);
64 } 64 }
65 65
66 GetOptions( 66 GetOptions(
67 'q|quiet+' => \$quiet, 67 'q|quiet+' => \$quiet,
68 'tree!' => \$tree, 68 'tree!' => \$tree,
69 'signoff!' => \$chk_signoff, 69 'signoff!' => \$chk_signoff,
70 'patch!' => \$chk_patch, 70 'patch!' => \$chk_patch,
71 'emacs!' => \$emacs, 71 'emacs!' => \$emacs,
72 'terse!' => \$terse, 72 'terse!' => \$terse,
73 'f|file!' => \$file, 73 'f|file!' => \$file,
74 'subjective!' => \$check, 74 'subjective!' => \$check,
75 'strict!' => \$check, 75 'strict!' => \$check,
76 'root=s' => \$root, 76 'root=s' => \$root,
77 'summary!' => \$summary, 77 'summary!' => \$summary,
78 'mailback!' => \$mailback, 78 'mailback!' => \$mailback,
79 'summary-file!' => \$summary_file, 79 'summary-file!' => \$summary_file,
80 80
81 'debug=s' => \%debug, 81 'debug=s' => \%debug,
82 'test-only=s' => \$tst_only, 82 'test-only=s' => \$tst_only,
83 'h|help' => \$help, 83 'h|help' => \$help,
84 'version' => \$help 84 'version' => \$help
85 ) or help(1); 85 ) or help(1);
86 86
87 help(0) if ($help); 87 help(0) if ($help);
88 88
89 my $exit = 0; 89 my $exit = 0;
90 90
91 if ($#ARGV < 0) { 91 if ($#ARGV < 0) {
92 print "$P: no input files\n"; 92 print "$P: no input files\n";
93 exit(1); 93 exit(1);
94 } 94 }
95 95
96 my $dbg_values = 0; 96 my $dbg_values = 0;
97 my $dbg_possible = 0; 97 my $dbg_possible = 0;
98 my $dbg_type = 0; 98 my $dbg_type = 0;
99 my $dbg_attr = 0; 99 my $dbg_attr = 0;
100 for my $key (keys %debug) { 100 for my $key (keys %debug) {
101 ## no critic 101 ## no critic
102 eval "\${dbg_$key} = '$debug{$key}';"; 102 eval "\${dbg_$key} = '$debug{$key}';";
103 die "$@" if ($@); 103 die "$@" if ($@);
104 } 104 }
105 105
106 my $rpt_cleaners = 0; 106 my $rpt_cleaners = 0;
107 107
108 if ($terse) { 108 if ($terse) {
109 $emacs = 1; 109 $emacs = 1;
110 $quiet++; 110 $quiet++;
111 } 111 }
112 112
113 if ($tree) { 113 if ($tree) {
114 if (defined $root) { 114 if (defined $root) {
115 if (!top_of_kernel_tree($root)) { 115 if (!top_of_kernel_tree($root)) {
116 die "$P: $root: --root does not point at a valid tree\n"; 116 die "$P: $root: --root does not point at a valid tree\n";
117 } 117 }
118 } else { 118 } else {
119 if (top_of_kernel_tree('.')) { 119 if (top_of_kernel_tree('.')) {
120 $root = '.'; 120 $root = '.';
121 } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && 121 } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
122 top_of_kernel_tree($1)) { 122 top_of_kernel_tree($1)) {
123 $root = $1; 123 $root = $1;
124 } 124 }
125 } 125 }
126 126
127 if (!defined $root) { 127 if (!defined $root) {
128 print "Must be run from the top-level dir. of a kernel tree\n"; 128 print "Must be run from the top-level dir. of a kernel tree\n";
129 exit(2); 129 exit(2);
130 } 130 }
131 } 131 }
132 132
133 my $emitted_corrupt = 0; 133 my $emitted_corrupt = 0;
134 134
135 our $Ident = qr{ 135 our $Ident = qr{
136 [A-Za-z_][A-Za-z\d_]* 136 [A-Za-z_][A-Za-z\d_]*
137 (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* 137 (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
138 }x; 138 }x;
139 our $Storage = qr{extern|static|asmlinkage}; 139 our $Storage = qr{extern|static|asmlinkage};
140 our $Sparse = qr{ 140 our $Sparse = qr{
141 __user| 141 __user|
142 __kernel| 142 __kernel|
143 __force| 143 __force|
144 __iomem| 144 __iomem|
145 __must_check| 145 __must_check|
146 __init_refok| 146 __init_refok|
147 __kprobes| 147 __kprobes|
148 __ref 148 __ref
149 }x; 149 }x;
150 150
151 # Notes to $Attribute: 151 # Notes to $Attribute:
152 # We need \b after 'init' otherwise 'initconst' will cause a false positive in a check 152 # We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
153 our $Attribute = qr{ 153 our $Attribute = qr{
154 const| 154 const|
155 __read_mostly| 155 __read_mostly|
156 __kprobes| 156 __kprobes|
157 __(?:mem|cpu|dev|)(?:initdata|initconst|init\b)| 157 __(?:mem|cpu|dev|)(?:initdata|initconst|init\b)|
158 ____cacheline_aligned| 158 ____cacheline_aligned|
159 ____cacheline_aligned_in_smp| 159 ____cacheline_aligned_in_smp|
160 ____cacheline_internodealigned_in_smp| 160 ____cacheline_internodealigned_in_smp|
161 __weak 161 __weak
162 }x; 162 }x;
163 our $Modifier; 163 our $Modifier;
164 our $Inline = qr{inline|__always_inline|noinline}; 164 our $Inline = qr{inline|__always_inline|noinline};
165 our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; 165 our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]};
166 our $Lval = qr{$Ident(?:$Member)*}; 166 our $Lval = qr{$Ident(?:$Member)*};
167 167
168 our $Constant = qr{(?:[0-9]+|0x[0-9a-fA-F]+)[UL]*}; 168 our $Constant = qr{(?:[0-9]+|0x[0-9a-fA-F]+)[UL]*};
169 our $Assignment = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)}; 169 our $Assignment = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)};
170 our $Compare = qr{<=|>=|==|!=|<|>}; 170 our $Compare = qr{<=|>=|==|!=|<|>};
171 our $Operators = qr{ 171 our $Operators = qr{
172 <=|>=|==|!=| 172 <=|>=|==|!=|
173 =>|->|<<|>>|<|>|!|~| 173 =>|->|<<|>>|<|>|!|~|
174 &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|% 174 &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%
175 }x; 175 }x;
176 176
177 our $NonptrType; 177 our $NonptrType;
178 our $Type; 178 our $Type;
179 our $Declare; 179 our $Declare;
180 180
181 our $UTF8 = qr { 181 our $UTF8 = qr {
182 [\x09\x0A\x0D\x20-\x7E] # ASCII 182 [\x09\x0A\x0D\x20-\x7E] # ASCII
183 | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte 183 | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
184 | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs 184 | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
185 | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 185 | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
186 | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates 186 | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
187 | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 187 | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
188 | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 188 | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
189 | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 189 | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
190 }x; 190 }x;
191 191
192 our $typeTypedefs = qr{(?x: 192 our $typeTypedefs = qr{(?x:
193 (?:__)?(?:u|s|be|le)(?:8|16|32|64)| 193 (?:__)?(?:u|s|be|le)(?:8|16|32|64)|
194 atomic_t 194 atomic_t
195 )}; 195 )};
196 196
197 our $logFunctions = qr{(?x: 197 our $logFunctions = qr{(?x:
198 printk| 198 printk|
199 pr_(debug|dbg|vdbg|devel|info|warning|err|notice|alert|crit|emerg|cont)| 199 pr_(debug|dbg|vdbg|devel|info|warning|err|notice|alert|crit|emerg|cont)|
200 (dev|netdev|netif)_(printk|dbg|vdbg|info|warn|err|notice|alert|crit|emerg|WARN)| 200 (dev|netdev|netif)_(printk|dbg|vdbg|info|warn|err|notice|alert|crit|emerg|WARN)|
201 WARN| 201 WARN|
202 panic 202 panic
203 )}; 203 )};
204 204
205 our @typeList = ( 205 our @typeList = (
206 qr{void}, 206 qr{void},
207 qr{(?:unsigned\s+)?char}, 207 qr{(?:unsigned\s+)?char},
208 qr{(?:unsigned\s+)?short}, 208 qr{(?:unsigned\s+)?short},
209 qr{(?:unsigned\s+)?int}, 209 qr{(?:unsigned\s+)?int},
210 qr{(?:unsigned\s+)?long}, 210 qr{(?:unsigned\s+)?long},
211 qr{(?:unsigned\s+)?long\s+int}, 211 qr{(?:unsigned\s+)?long\s+int},
212 qr{(?:unsigned\s+)?long\s+long}, 212 qr{(?:unsigned\s+)?long\s+long},
213 qr{(?:unsigned\s+)?long\s+long\s+int}, 213 qr{(?:unsigned\s+)?long\s+long\s+int},
214 qr{unsigned}, 214 qr{unsigned},
215 qr{float}, 215 qr{float},
216 qr{double}, 216 qr{double},
217 qr{bool}, 217 qr{bool},
218 qr{struct\s+$Ident}, 218 qr{struct\s+$Ident},
219 qr{union\s+$Ident}, 219 qr{union\s+$Ident},
220 qr{enum\s+$Ident}, 220 qr{enum\s+$Ident},
221 qr{${Ident}_t}, 221 qr{${Ident}_t},
222 qr{${Ident}_handler}, 222 qr{${Ident}_handler},
223 qr{${Ident}_handler_fn}, 223 qr{${Ident}_handler_fn},
224 ); 224 );
225 our @modifierList = ( 225 our @modifierList = (
226 qr{fastcall}, 226 qr{fastcall},
227 ); 227 );
228 228
229 our $allowed_asm_includes = qr{(?x: 229 our $allowed_asm_includes = qr{(?x:
230 irq| 230 irq|
231 memory 231 memory
232 )}; 232 )};
233 # memory.h: ARM has a custom one 233 # memory.h: ARM has a custom one
234 234
235 sub build_types { 235 sub build_types {
236 my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)"; 236 my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)";
237 my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)"; 237 my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)";
238 $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; 238 $Modifier = qr{(?:$Attribute|$Sparse|$mods)};
239 $NonptrType = qr{ 239 $NonptrType = qr{
240 (?:$Modifier\s+|const\s+)* 240 (?:$Modifier\s+|const\s+)*
241 (?: 241 (?:
242 (?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\)| 242 (?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\)|
243 (?:$typeTypedefs\b)| 243 (?:$typeTypedefs\b)|
244 (?:${all}\b) 244 (?:${all}\b)
245 ) 245 )
246 (?:\s+$Modifier|\s+const)* 246 (?:\s+$Modifier|\s+const)*
247 }x; 247 }x;
248 $Type = qr{ 248 $Type = qr{
249 $NonptrType 249 $NonptrType
250 (?:[\s\*]+\s*const|[\s\*]+|(?:\s*\[\s*\])+)? 250 (?:[\s\*]+\s*const|[\s\*]+|(?:\s*\[\s*\])+)?
251 (?:\s+$Inline|\s+$Modifier)* 251 (?:\s+$Inline|\s+$Modifier)*
252 }x; 252 }x;
253 $Declare = qr{(?:$Storage\s+)?$Type}; 253 $Declare = qr{(?:$Storage\s+)?$Type};
254 } 254 }
255 build_types(); 255 build_types();
256 256
257 $chk_signoff = 0 if ($file); 257 $chk_signoff = 0 if ($file);
258 258
259 my @dep_includes = (); 259 my @dep_includes = ();
260 my @dep_functions = (); 260 my @dep_functions = ();
261 my $removal = "Documentation/feature-removal-schedule.txt"; 261 my $removal = "Documentation/feature-removal-schedule.txt";
262 if ($tree && -f "$root/$removal") { 262 if ($tree && -f "$root/$removal") {
263 open(my $REMOVE, '<', "$root/$removal") || 263 open(my $REMOVE, '<', "$root/$removal") ||
264 die "$P: $removal: open failed - $!\n"; 264 die "$P: $removal: open failed - $!\n";
265 while (<$REMOVE>) { 265 while (<$REMOVE>) {
266 if (/^Check:\s+(.*\S)/) { 266 if (/^Check:\s+(.*\S)/) {
267 for my $entry (split(/[, ]+/, $1)) { 267 for my $entry (split(/[, ]+/, $1)) {
268 if ($entry =~ m@include/(.*)@) { 268 if ($entry =~ m@include/(.*)@) {
269 push(@dep_includes, $1); 269 push(@dep_includes, $1);
270 270
271 } elsif ($entry !~ m@/@) { 271 } elsif ($entry !~ m@/@) {
272 push(@dep_functions, $entry); 272 push(@dep_functions, $entry);
273 } 273 }
274 } 274 }
275 } 275 }
276 } 276 }
277 close($REMOVE); 277 close($REMOVE);
278 } 278 }
279 279
280 my @rawlines = (); 280 my @rawlines = ();
281 my @lines = (); 281 my @lines = ();
282 my $vname; 282 my $vname;
283 for my $filename (@ARGV) { 283 for my $filename (@ARGV) {
284 my $FILE; 284 my $FILE;
285 if ($file) { 285 if ($file) {
286 open($FILE, '-|', "diff -u /dev/null $filename") || 286 open($FILE, '-|', "diff -u /dev/null $filename") ||
287 die "$P: $filename: diff failed - $!\n"; 287 die "$P: $filename: diff failed - $!\n";
288 } elsif ($filename eq '-') { 288 } elsif ($filename eq '-') {
289 open($FILE, '<&STDIN'); 289 open($FILE, '<&STDIN');
290 } else { 290 } else {
291 open($FILE, '<', "$filename") || 291 open($FILE, '<', "$filename") ||
292 die "$P: $filename: open failed - $!\n"; 292 die "$P: $filename: open failed - $!\n";
293 } 293 }
294 if ($filename eq '-') { 294 if ($filename eq '-') {
295 $vname = 'Your patch'; 295 $vname = 'Your patch';
296 } else { 296 } else {
297 $vname = $filename; 297 $vname = $filename;
298 } 298 }
299 while (<$FILE>) { 299 while (<$FILE>) {
300 chomp; 300 chomp;
301 push(@rawlines, $_); 301 push(@rawlines, $_);
302 } 302 }
303 close($FILE); 303 close($FILE);
304 if (!process($filename)) { 304 if (!process($filename)) {
305 $exit = 1; 305 $exit = 1;
306 } 306 }
307 @rawlines = (); 307 @rawlines = ();
308 @lines = (); 308 @lines = ();
309 } 309 }
310 310
311 exit($exit); 311 exit($exit);
312 312
313 sub top_of_kernel_tree { 313 sub top_of_kernel_tree {
314 my ($root) = @_; 314 my ($root) = @_;
315 315
316 my @tree_check = ( 316 my @tree_check = (
317 "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", 317 "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
318 "README", "Documentation", "arch", "include", "drivers", 318 "README", "Documentation", "arch", "include", "drivers",
319 "fs", "init", "ipc", "kernel", "lib", "scripts", 319 "fs", "init", "ipc", "kernel", "lib", "scripts",
320 ); 320 );
321 321
322 foreach my $check (@tree_check) { 322 foreach my $check (@tree_check) {
323 if (! -e $root . '/' . $check) { 323 if (! -e $root . '/' . $check) {
324 return 0; 324 return 0;
325 } 325 }
326 } 326 }
327 return 1; 327 return 1;
328 } 328 }
329 329
330 sub expand_tabs { 330 sub expand_tabs {
331 my ($str) = @_; 331 my ($str) = @_;
332 332
333 my $res = ''; 333 my $res = '';
334 my $n = 0; 334 my $n = 0;
335 for my $c (split(//, $str)) { 335 for my $c (split(//, $str)) {
336 if ($c eq "\t") { 336 if ($c eq "\t") {
337 $res .= ' '; 337 $res .= ' ';
338 $n++; 338 $n++;
339 for (; ($n % 8) != 0; $n++) { 339 for (; ($n % 8) != 0; $n++) {
340 $res .= ' '; 340 $res .= ' ';
341 } 341 }
342 next; 342 next;
343 } 343 }
344 $res .= $c; 344 $res .= $c;
345 $n++; 345 $n++;
346 } 346 }
347 347
348 return $res; 348 return $res;
349 } 349 }
350 sub copy_spacing { 350 sub copy_spacing {
351 (my $res = shift) =~ tr/\t/ /c; 351 (my $res = shift) =~ tr/\t/ /c;
352 return $res; 352 return $res;
353 } 353 }
354 354
355 sub line_stats { 355 sub line_stats {
356 my ($line) = @_; 356 my ($line) = @_;
357 357
358 # Drop the diff line leader and expand tabs 358 # Drop the diff line leader and expand tabs
359 $line =~ s/^.//; 359 $line =~ s/^.//;
360 $line = expand_tabs($line); 360 $line = expand_tabs($line);
361 361
362 # Pick the indent from the front of the line. 362 # Pick the indent from the front of the line.
363 my ($white) = ($line =~ /^(\s*)/); 363 my ($white) = ($line =~ /^(\s*)/);
364 364
365 return (length($line), length($white)); 365 return (length($line), length($white));
366 } 366 }
367 367
368 my $sanitise_quote = ''; 368 my $sanitise_quote = '';
369 369
370 sub sanitise_line_reset { 370 sub sanitise_line_reset {
371 my ($in_comment) = @_; 371 my ($in_comment) = @_;
372 372
373 if ($in_comment) { 373 if ($in_comment) {
374 $sanitise_quote = '*/'; 374 $sanitise_quote = '*/';
375 } else { 375 } else {
376 $sanitise_quote = ''; 376 $sanitise_quote = '';
377 } 377 }
378 } 378 }
379 sub sanitise_line { 379 sub sanitise_line {
380 my ($line) = @_; 380 my ($line) = @_;
381 381
382 my $res = ''; 382 my $res = '';
383 my $l = ''; 383 my $l = '';
384 384
385 my $qlen = 0; 385 my $qlen = 0;
386 my $off = 0; 386 my $off = 0;
387 my $c; 387 my $c;
388 388
389 # Always copy over the diff marker. 389 # Always copy over the diff marker.
390 $res = substr($line, 0, 1); 390 $res = substr($line, 0, 1);
391 391
392 for ($off = 1; $off < length($line); $off++) { 392 for ($off = 1; $off < length($line); $off++) {
393 $c = substr($line, $off, 1); 393 $c = substr($line, $off, 1);
394 394
395 # Comments we are wacking completly including the begin 395 # Comments we are wacking completly including the begin
396 # and end, all to $;. 396 # and end, all to $;.
397 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { 397 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
398 $sanitise_quote = '*/'; 398 $sanitise_quote = '*/';
399 399
400 substr($res, $off, 2, "$;$;"); 400 substr($res, $off, 2, "$;$;");
401 $off++; 401 $off++;
402 next; 402 next;
403 } 403 }
404 if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { 404 if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
405 $sanitise_quote = ''; 405 $sanitise_quote = '';
406 substr($res, $off, 2, "$;$;"); 406 substr($res, $off, 2, "$;$;");
407 $off++; 407 $off++;
408 next; 408 next;
409 } 409 }
410 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { 410 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
411 $sanitise_quote = '//'; 411 $sanitise_quote = '//';
412 412
413 substr($res, $off, 2, $sanitise_quote); 413 substr($res, $off, 2, $sanitise_quote);
414 $off++; 414 $off++;
415 next; 415 next;
416 } 416 }
417 417
418 # A \ in a string means ignore the next character. 418 # A \ in a string means ignore the next character.
419 if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && 419 if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
420 $c eq "\\") { 420 $c eq "\\") {
421 substr($res, $off, 2, 'XX'); 421 substr($res, $off, 2, 'XX');
422 $off++; 422 $off++;
423 next; 423 next;
424 } 424 }
425 # Regular quotes. 425 # Regular quotes.
426 if ($c eq "'" || $c eq '"') { 426 if ($c eq "'" || $c eq '"') {
427 if ($sanitise_quote eq '') { 427 if ($sanitise_quote eq '') {
428 $sanitise_quote = $c; 428 $sanitise_quote = $c;
429 429
430 substr($res, $off, 1, $c); 430 substr($res, $off, 1, $c);
431 next; 431 next;
432 } elsif ($sanitise_quote eq $c) { 432 } elsif ($sanitise_quote eq $c) {
433 $sanitise_quote = ''; 433 $sanitise_quote = '';
434 } 434 }
435 } 435 }
436 436
437 #print "c<$c> SQ<$sanitise_quote>\n"; 437 #print "c<$c> SQ<$sanitise_quote>\n";
438 if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { 438 if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
439 substr($res, $off, 1, $;); 439 substr($res, $off, 1, $;);
440 } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { 440 } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
441 substr($res, $off, 1, $;); 441 substr($res, $off, 1, $;);
442 } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { 442 } elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
443 substr($res, $off, 1, 'X'); 443 substr($res, $off, 1, 'X');
444 } else { 444 } else {
445 substr($res, $off, 1, $c); 445 substr($res, $off, 1, $c);
446 } 446 }
447 } 447 }
448 448
449 if ($sanitise_quote eq '//') { 449 if ($sanitise_quote eq '//') {
450 $sanitise_quote = ''; 450 $sanitise_quote = '';
451 } 451 }
452 452
453 # The pathname on a #include may be surrounded by '<' and '>'. 453 # The pathname on a #include may be surrounded by '<' and '>'.
454 if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { 454 if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
455 my $clean = 'X' x length($1); 455 my $clean = 'X' x length($1);
456 $res =~ s@\<.*\>@<$clean>@; 456 $res =~ s@\<.*\>@<$clean>@;
457 457
458 # The whole of a #error is a string. 458 # The whole of a #error is a string.
459 } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { 459 } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
460 my $clean = 'X' x length($1); 460 my $clean = 'X' x length($1);
461 $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; 461 $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
462 } 462 }
463 463
464 return $res; 464 return $res;
465 } 465 }
466 466
467 sub ctx_statement_block { 467 sub ctx_statement_block {
468 my ($linenr, $remain, $off) = @_; 468 my ($linenr, $remain, $off) = @_;
469 my $line = $linenr - 1; 469 my $line = $linenr - 1;
470 my $blk = ''; 470 my $blk = '';
471 my $soff = $off; 471 my $soff = $off;
472 my $coff = $off - 1; 472 my $coff = $off - 1;
473 my $coff_set = 0; 473 my $coff_set = 0;
474 474
475 my $loff = 0; 475 my $loff = 0;
476 476
477 my $type = ''; 477 my $type = '';
478 my $level = 0; 478 my $level = 0;
479 my @stack = (); 479 my @stack = ();
480 my $p; 480 my $p;
481 my $c; 481 my $c;
482 my $len = 0; 482 my $len = 0;
483 483
484 my $remainder; 484 my $remainder;
485 while (1) { 485 while (1) {
486 @stack = (['', 0]) if ($#stack == -1); 486 @stack = (['', 0]) if ($#stack == -1);
487 487
488 #warn "CSB: blk<$blk> remain<$remain>\n"; 488 #warn "CSB: blk<$blk> remain<$remain>\n";
489 # If we are about to drop off the end, pull in more 489 # If we are about to drop off the end, pull in more
490 # context. 490 # context.
491 if ($off >= $len) { 491 if ($off >= $len) {
492 for (; $remain > 0; $line++) { 492 for (; $remain > 0; $line++) {
493 last if (!defined $lines[$line]); 493 last if (!defined $lines[$line]);
494 next if ($lines[$line] =~ /^-/); 494 next if ($lines[$line] =~ /^-/);
495 $remain--; 495 $remain--;
496 $loff = $len; 496 $loff = $len;
497 $blk .= $lines[$line] . "\n"; 497 $blk .= $lines[$line] . "\n";
498 $len = length($blk); 498 $len = length($blk);
499 $line++; 499 $line++;
500 last; 500 last;
501 } 501 }
502 # Bail if there is no further context. 502 # Bail if there is no further context.
503 #warn "CSB: blk<$blk> off<$off> len<$len>\n"; 503 #warn "CSB: blk<$blk> off<$off> len<$len>\n";
504 if ($off >= $len) { 504 if ($off >= $len) {
505 last; 505 last;
506 } 506 }
507 } 507 }
508 $p = $c; 508 $p = $c;
509 $c = substr($blk, $off, 1); 509 $c = substr($blk, $off, 1);
510 $remainder = substr($blk, $off); 510 $remainder = substr($blk, $off);
511 511
512 #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; 512 #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
513 513
514 # Handle nested #if/#else. 514 # Handle nested #if/#else.
515 if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { 515 if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
516 push(@stack, [ $type, $level ]); 516 push(@stack, [ $type, $level ]);
517 } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { 517 } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
518 ($type, $level) = @{$stack[$#stack - 1]}; 518 ($type, $level) = @{$stack[$#stack - 1]};
519 } elsif ($remainder =~ /^#\s*endif\b/) { 519 } elsif ($remainder =~ /^#\s*endif\b/) {
520 ($type, $level) = @{pop(@stack)}; 520 ($type, $level) = @{pop(@stack)};
521 } 521 }
522 522
523 # Statement ends at the ';' or a close '}' at the 523 # Statement ends at the ';' or a close '}' at the
524 # outermost level. 524 # outermost level.
525 if ($level == 0 && $c eq ';') { 525 if ($level == 0 && $c eq ';') {
526 last; 526 last;
527 } 527 }
528 528
529 # An else is really a conditional as long as its not else if 529 # An else is really a conditional as long as its not else if
530 if ($level == 0 && $coff_set == 0 && 530 if ($level == 0 && $coff_set == 0 &&
531 (!defined($p) || $p =~ /(?:\s|\}|\+)/) && 531 (!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
532 $remainder =~ /^(else)(?:\s|{)/ && 532 $remainder =~ /^(else)(?:\s|{)/ &&
533 $remainder !~ /^else\s+if\b/) { 533 $remainder !~ /^else\s+if\b/) {
534 $coff = $off + length($1) - 1; 534 $coff = $off + length($1) - 1;
535 $coff_set = 1; 535 $coff_set = 1;
536 #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; 536 #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
537 #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; 537 #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
538 } 538 }
539 539
540 if (($type eq '' || $type eq '(') && $c eq '(') { 540 if (($type eq '' || $type eq '(') && $c eq '(') {
541 $level++; 541 $level++;
542 $type = '('; 542 $type = '(';
543 } 543 }
544 if ($type eq '(' && $c eq ')') { 544 if ($type eq '(' && $c eq ')') {
545 $level--; 545 $level--;
546 $type = ($level != 0)? '(' : ''; 546 $type = ($level != 0)? '(' : '';
547 547
548 if ($level == 0 && $coff < $soff) { 548 if ($level == 0 && $coff < $soff) {
549 $coff = $off; 549 $coff = $off;
550 $coff_set = 1; 550 $coff_set = 1;
551 #warn "CSB: mark coff<$coff>\n"; 551 #warn "CSB: mark coff<$coff>\n";
552 } 552 }
553 } 553 }
554 if (($type eq '' || $type eq '{') && $c eq '{') { 554 if (($type eq '' || $type eq '{') && $c eq '{') {
555 $level++; 555 $level++;
556 $type = '{'; 556 $type = '{';
557 } 557 }
558 if ($type eq '{' && $c eq '}') { 558 if ($type eq '{' && $c eq '}') {
559 $level--; 559 $level--;
560 $type = ($level != 0)? '{' : ''; 560 $type = ($level != 0)? '{' : '';
561 561
562 if ($level == 0) { 562 if ($level == 0) {
563 if (substr($blk, $off + 1, 1) eq ';') { 563 if (substr($blk, $off + 1, 1) eq ';') {
564 $off++; 564 $off++;
565 } 565 }
566 last; 566 last;
567 } 567 }
568 } 568 }
569 $off++; 569 $off++;
570 } 570 }
571 # We are truly at the end, so shuffle to the next line. 571 # We are truly at the end, so shuffle to the next line.
572 if ($off == $len) { 572 if ($off == $len) {
573 $loff = $len + 1; 573 $loff = $len + 1;
574 $line++; 574 $line++;
575 $remain--; 575 $remain--;
576 } 576 }
577 577
578 my $statement = substr($blk, $soff, $off - $soff + 1); 578 my $statement = substr($blk, $soff, $off - $soff + 1);
579 my $condition = substr($blk, $soff, $coff - $soff + 1); 579 my $condition = substr($blk, $soff, $coff - $soff + 1);
580 580
581 #warn "STATEMENT<$statement>\n"; 581 #warn "STATEMENT<$statement>\n";
582 #warn "CONDITION<$condition>\n"; 582 #warn "CONDITION<$condition>\n";
583 583
584 #print "coff<$coff> soff<$off> loff<$loff>\n"; 584 #print "coff<$coff> soff<$off> loff<$loff>\n";
585 585
586 return ($statement, $condition, 586 return ($statement, $condition,
587 $line, $remain + 1, $off - $loff + 1, $level); 587 $line, $remain + 1, $off - $loff + 1, $level);
588 } 588 }
589 589
590 sub statement_lines { 590 sub statement_lines {
591 my ($stmt) = @_; 591 my ($stmt) = @_;
592 592
593 # Strip the diff line prefixes and rip blank lines at start and end. 593 # Strip the diff line prefixes and rip blank lines at start and end.
594 $stmt =~ s/(^|\n)./$1/g; 594 $stmt =~ s/(^|\n)./$1/g;
595 $stmt =~ s/^\s*//; 595 $stmt =~ s/^\s*//;
596 $stmt =~ s/\s*$//; 596 $stmt =~ s/\s*$//;
597 597
598 my @stmt_lines = ($stmt =~ /\n/g); 598 my @stmt_lines = ($stmt =~ /\n/g);
599 599
600 return $#stmt_lines + 2; 600 return $#stmt_lines + 2;
601 } 601 }
602 602
603 sub statement_rawlines { 603 sub statement_rawlines {
604 my ($stmt) = @_; 604 my ($stmt) = @_;
605 605
606 my @stmt_lines = ($stmt =~ /\n/g); 606 my @stmt_lines = ($stmt =~ /\n/g);
607 607
608 return $#stmt_lines + 2; 608 return $#stmt_lines + 2;
609 } 609 }
610 610
611 sub statement_block_size { 611 sub statement_block_size {
612 my ($stmt) = @_; 612 my ($stmt) = @_;
613 613
614 $stmt =~ s/(^|\n)./$1/g; 614 $stmt =~ s/(^|\n)./$1/g;
615 $stmt =~ s/^\s*{//; 615 $stmt =~ s/^\s*{//;
616 $stmt =~ s/}\s*$//; 616 $stmt =~ s/}\s*$//;
617 $stmt =~ s/^\s*//; 617 $stmt =~ s/^\s*//;
618 $stmt =~ s/\s*$//; 618 $stmt =~ s/\s*$//;
619 619
620 my @stmt_lines = ($stmt =~ /\n/g); 620 my @stmt_lines = ($stmt =~ /\n/g);
621 my @stmt_statements = ($stmt =~ /;/g); 621 my @stmt_statements = ($stmt =~ /;/g);
622 622
623 my $stmt_lines = $#stmt_lines + 2; 623 my $stmt_lines = $#stmt_lines + 2;
624 my $stmt_statements = $#stmt_statements + 1; 624 my $stmt_statements = $#stmt_statements + 1;
625 625
626 if ($stmt_lines > $stmt_statements) { 626 if ($stmt_lines > $stmt_statements) {
627 return $stmt_lines; 627 return $stmt_lines;
628 } else { 628 } else {
629 return $stmt_statements; 629 return $stmt_statements;
630 } 630 }
631 } 631 }
632 632
633 sub ctx_statement_full { 633 sub ctx_statement_full {
634 my ($linenr, $remain, $off) = @_; 634 my ($linenr, $remain, $off) = @_;
635 my ($statement, $condition, $level); 635 my ($statement, $condition, $level);
636 636
637 my (@chunks); 637 my (@chunks);
638 638
639 # Grab the first conditional/block pair. 639 # Grab the first conditional/block pair.
640 ($statement, $condition, $linenr, $remain, $off, $level) = 640 ($statement, $condition, $linenr, $remain, $off, $level) =
641 ctx_statement_block($linenr, $remain, $off); 641 ctx_statement_block($linenr, $remain, $off);
642 #print "F: c<$condition> s<$statement> remain<$remain>\n"; 642 #print "F: c<$condition> s<$statement> remain<$remain>\n";
643 push(@chunks, [ $condition, $statement ]); 643 push(@chunks, [ $condition, $statement ]);
644 if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { 644 if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
645 return ($level, $linenr, @chunks); 645 return ($level, $linenr, @chunks);
646 } 646 }
647 647
648 # Pull in the following conditional/block pairs and see if they 648 # Pull in the following conditional/block pairs and see if they
649 # could continue the statement. 649 # could continue the statement.
650 for (;;) { 650 for (;;) {
651 ($statement, $condition, $linenr, $remain, $off, $level) = 651 ($statement, $condition, $linenr, $remain, $off, $level) =
652 ctx_statement_block($linenr, $remain, $off); 652 ctx_statement_block($linenr, $remain, $off);
653 #print "C: c<$condition> s<$statement> remain<$remain>\n"; 653 #print "C: c<$condition> s<$statement> remain<$remain>\n";
654 last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); 654 last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
655 #print "C: push\n"; 655 #print "C: push\n";
656 push(@chunks, [ $condition, $statement ]); 656 push(@chunks, [ $condition, $statement ]);
657 } 657 }
658 658
659 return ($level, $linenr, @chunks); 659 return ($level, $linenr, @chunks);
660 } 660 }
661 661
662 sub ctx_block_get { 662 sub ctx_block_get {
663 my ($linenr, $remain, $outer, $open, $close, $off) = @_; 663 my ($linenr, $remain, $outer, $open, $close, $off) = @_;
664 my $line; 664 my $line;
665 my $start = $linenr - 1; 665 my $start = $linenr - 1;
666 my $blk = ''; 666 my $blk = '';
667 my @o; 667 my @o;
668 my @c; 668 my @c;
669 my @res = (); 669 my @res = ();
670 670
671 my $level = 0; 671 my $level = 0;
672 my @stack = ($level); 672 my @stack = ($level);
673 for ($line = $start; $remain > 0; $line++) { 673 for ($line = $start; $remain > 0; $line++) {
674 next if ($rawlines[$line] =~ /^-/); 674 next if ($rawlines[$line] =~ /^-/);
675 $remain--; 675 $remain--;
676 676
677 $blk .= $rawlines[$line]; 677 $blk .= $rawlines[$line];
678 678
679 # Handle nested #if/#else. 679 # Handle nested #if/#else.
680 if ($rawlines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { 680 if ($rawlines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
681 push(@stack, $level); 681 push(@stack, $level);
682 } elsif ($rawlines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { 682 } elsif ($rawlines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
683 $level = $stack[$#stack - 1]; 683 $level = $stack[$#stack - 1];
684 } elsif ($rawlines[$line] =~ /^.\s*#\s*endif\b/) { 684 } elsif ($rawlines[$line] =~ /^.\s*#\s*endif\b/) {
685 $level = pop(@stack); 685 $level = pop(@stack);
686 } 686 }
687 687
688 foreach my $c (split(//, $rawlines[$line])) { 688 foreach my $c (split(//, $rawlines[$line])) {
689 ##print "C<$c>L<$level><$open$close>O<$off>\n"; 689 ##print "C<$c>L<$level><$open$close>O<$off>\n";
690 if ($off > 0) { 690 if ($off > 0) {
691 $off--; 691 $off--;
692 next; 692 next;
693 } 693 }
694 694
695 if ($c eq $close && $level > 0) { 695 if ($c eq $close && $level > 0) {
696 $level--; 696 $level--;
697 last if ($level == 0); 697 last if ($level == 0);
698 } elsif ($c eq $open) { 698 } elsif ($c eq $open) {
699 $level++; 699 $level++;
700 } 700 }
701 } 701 }
702 702
703 if (!$outer || $level <= 1) { 703 if (!$outer || $level <= 1) {
704 push(@res, $rawlines[$line]); 704 push(@res, $rawlines[$line]);
705 } 705 }
706 706
707 last if ($level == 0); 707 last if ($level == 0);
708 } 708 }
709 709
710 return ($level, @res); 710 return ($level, @res);
711 } 711 }
712 sub ctx_block_outer { 712 sub ctx_block_outer {
713 my ($linenr, $remain) = @_; 713 my ($linenr, $remain) = @_;
714 714
715 my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); 715 my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
716 return @r; 716 return @r;
717 } 717 }
718 sub ctx_block { 718 sub ctx_block {
719 my ($linenr, $remain) = @_; 719 my ($linenr, $remain) = @_;
720 720
721 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); 721 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
722 return @r; 722 return @r;
723 } 723 }
724 sub ctx_statement { 724 sub ctx_statement {
725 my ($linenr, $remain, $off) = @_; 725 my ($linenr, $remain, $off) = @_;
726 726
727 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); 727 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
728 return @r; 728 return @r;
729 } 729 }
730 sub ctx_block_level { 730 sub ctx_block_level {
731 my ($linenr, $remain) = @_; 731 my ($linenr, $remain) = @_;
732 732
733 return ctx_block_get($linenr, $remain, 0, '{', '}', 0); 733 return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
734 } 734 }
735 sub ctx_statement_level { 735 sub ctx_statement_level {
736 my ($linenr, $remain, $off) = @_; 736 my ($linenr, $remain, $off) = @_;
737 737
738 return ctx_block_get($linenr, $remain, 0, '(', ')', $off); 738 return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
739 } 739 }
740 740
741 sub ctx_locate_comment { 741 sub ctx_locate_comment {
742 my ($first_line, $end_line) = @_; 742 my ($first_line, $end_line) = @_;
743 743
744 # Catch a comment on the end of the line itself. 744 # Catch a comment on the end of the line itself.
745 my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); 745 my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
746 return $current_comment if (defined $current_comment); 746 return $current_comment if (defined $current_comment);
747 747
748 # Look through the context and try and figure out if there is a 748 # Look through the context and try and figure out if there is a
749 # comment. 749 # comment.
750 my $in_comment = 0; 750 my $in_comment = 0;
751 $current_comment = ''; 751 $current_comment = '';
752 for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { 752 for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
753 my $line = $rawlines[$linenr - 1]; 753 my $line = $rawlines[$linenr - 1];
754 #warn " $line\n"; 754 #warn " $line\n";
755 if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 755 if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
756 $in_comment = 1; 756 $in_comment = 1;
757 } 757 }
758 if ($line =~ m@/\*@) { 758 if ($line =~ m@/\*@) {
759 $in_comment = 1; 759 $in_comment = 1;
760 } 760 }
761 if (!$in_comment && $current_comment ne '') { 761 if (!$in_comment && $current_comment ne '') {
762 $current_comment = ''; 762 $current_comment = '';
763 } 763 }
764 $current_comment .= $line . "\n" if ($in_comment); 764 $current_comment .= $line . "\n" if ($in_comment);
765 if ($line =~ m@\*/@) { 765 if ($line =~ m@\*/@) {
766 $in_comment = 0; 766 $in_comment = 0;
767 } 767 }
768 } 768 }
769 769
770 chomp($current_comment); 770 chomp($current_comment);
771 return($current_comment); 771 return($current_comment);
772 } 772 }
773 sub ctx_has_comment { 773 sub ctx_has_comment {
774 my ($first_line, $end_line) = @_; 774 my ($first_line, $end_line) = @_;
775 my $cmt = ctx_locate_comment($first_line, $end_line); 775 my $cmt = ctx_locate_comment($first_line, $end_line);
776 776
777 ##print "LINE: $rawlines[$end_line - 1 ]\n"; 777 ##print "LINE: $rawlines[$end_line - 1 ]\n";
778 ##print "CMMT: $cmt\n"; 778 ##print "CMMT: $cmt\n";
779 779
780 return ($cmt ne ''); 780 return ($cmt ne '');
781 } 781 }
782 782
783 sub raw_line { 783 sub raw_line {
784 my ($linenr, $cnt) = @_; 784 my ($linenr, $cnt) = @_;
785 785
786 my $offset = $linenr - 1; 786 my $offset = $linenr - 1;
787 $cnt++; 787 $cnt++;
788 788
789 my $line; 789 my $line;
790 while ($cnt) { 790 while ($cnt) {
791 $line = $rawlines[$offset++]; 791 $line = $rawlines[$offset++];
792 next if (defined($line) && $line =~ /^-/); 792 next if (defined($line) && $line =~ /^-/);
793 $cnt--; 793 $cnt--;
794 } 794 }
795 795
796 return $line; 796 return $line;
797 } 797 }
798 798
799 sub cat_vet { 799 sub cat_vet {
800 my ($vet) = @_; 800 my ($vet) = @_;
801 my ($res, $coded); 801 my ($res, $coded);
802 802
803 $res = ''; 803 $res = '';
804 while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { 804 while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
805 $res .= $1; 805 $res .= $1;
806 if ($2 ne '') { 806 if ($2 ne '') {
807 $coded = sprintf("^%c", unpack('C', $2) + 64); 807 $coded = sprintf("^%c", unpack('C', $2) + 64);
808 $res .= $coded; 808 $res .= $coded;
809 } 809 }
810 } 810 }
811 $res =~ s/$/\$/; 811 $res =~ s/$/\$/;
812 812
813 return $res; 813 return $res;
814 } 814 }
815 815
816 my $av_preprocessor = 0; 816 my $av_preprocessor = 0;
817 my $av_pending; 817 my $av_pending;
818 my @av_paren_type; 818 my @av_paren_type;
819 my $av_pend_colon; 819 my $av_pend_colon;
820 820
821 sub annotate_reset { 821 sub annotate_reset {
822 $av_preprocessor = 0; 822 $av_preprocessor = 0;
823 $av_pending = '_'; 823 $av_pending = '_';
824 @av_paren_type = ('E'); 824 @av_paren_type = ('E');
825 $av_pend_colon = 'O'; 825 $av_pend_colon = 'O';
826 } 826 }
827 827
828 sub annotate_values { 828 sub annotate_values {
829 my ($stream, $type) = @_; 829 my ($stream, $type) = @_;
830 830
831 my $res; 831 my $res;
832 my $var = '_' x length($stream); 832 my $var = '_' x length($stream);
833 my $cur = $stream; 833 my $cur = $stream;
834 834
835 print "$stream\n" if ($dbg_values > 1); 835 print "$stream\n" if ($dbg_values > 1);
836 836
837 while (length($cur)) { 837 while (length($cur)) {
838 @av_paren_type = ('E') if ($#av_paren_type < 0); 838 @av_paren_type = ('E') if ($#av_paren_type < 0);
839 print " <" . join('', @av_paren_type) . 839 print " <" . join('', @av_paren_type) .
840 "> <$type> <$av_pending>" if ($dbg_values > 1); 840 "> <$type> <$av_pending>" if ($dbg_values > 1);
841 if ($cur =~ /^(\s+)/o) { 841 if ($cur =~ /^(\s+)/o) {
842 print "WS($1)\n" if ($dbg_values > 1); 842 print "WS($1)\n" if ($dbg_values > 1);
843 if ($1 =~ /\n/ && $av_preprocessor) { 843 if ($1 =~ /\n/ && $av_preprocessor) {
844 $type = pop(@av_paren_type); 844 $type = pop(@av_paren_type);
845 $av_preprocessor = 0; 845 $av_preprocessor = 0;
846 } 846 }
847 847
848 } elsif ($cur =~ /^(\(\s*$Type\s*)\)/) { 848 } elsif ($cur =~ /^(\(\s*$Type\s*)\)/) {
849 print "CAST($1)\n" if ($dbg_values > 1); 849 print "CAST($1)\n" if ($dbg_values > 1);
850 push(@av_paren_type, $type); 850 push(@av_paren_type, $type);
851 $type = 'C'; 851 $type = 'C';
852 852
853 } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { 853 } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
854 print "DECLARE($1)\n" if ($dbg_values > 1); 854 print "DECLARE($1)\n" if ($dbg_values > 1);
855 $type = 'T'; 855 $type = 'T';
856 856
857 } elsif ($cur =~ /^($Modifier)\s*/) { 857 } elsif ($cur =~ /^($Modifier)\s*/) {
858 print "MODIFIER($1)\n" if ($dbg_values > 1); 858 print "MODIFIER($1)\n" if ($dbg_values > 1);
859 $type = 'T'; 859 $type = 'T';
860 860
861 } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { 861 } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
862 print "DEFINE($1,$2)\n" if ($dbg_values > 1); 862 print "DEFINE($1,$2)\n" if ($dbg_values > 1);
863 $av_preprocessor = 1; 863 $av_preprocessor = 1;
864 push(@av_paren_type, $type); 864 push(@av_paren_type, $type);
865 if ($2 ne '') { 865 if ($2 ne '') {
866 $av_pending = 'N'; 866 $av_pending = 'N';
867 } 867 }
868 $type = 'E'; 868 $type = 'E';
869 869
870 } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { 870 } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
871 print "UNDEF($1)\n" if ($dbg_values > 1); 871 print "UNDEF($1)\n" if ($dbg_values > 1);
872 $av_preprocessor = 1; 872 $av_preprocessor = 1;
873 push(@av_paren_type, $type); 873 push(@av_paren_type, $type);
874 874
875 } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { 875 } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
876 print "PRE_START($1)\n" if ($dbg_values > 1); 876 print "PRE_START($1)\n" if ($dbg_values > 1);
877 $av_preprocessor = 1; 877 $av_preprocessor = 1;
878 878
879 push(@av_paren_type, $type); 879 push(@av_paren_type, $type);
880 push(@av_paren_type, $type); 880 push(@av_paren_type, $type);
881 $type = 'E'; 881 $type = 'E';
882 882
883 } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { 883 } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
884 print "PRE_RESTART($1)\n" if ($dbg_values > 1); 884 print "PRE_RESTART($1)\n" if ($dbg_values > 1);
885 $av_preprocessor = 1; 885 $av_preprocessor = 1;
886 886
887 push(@av_paren_type, $av_paren_type[$#av_paren_type]); 887 push(@av_paren_type, $av_paren_type[$#av_paren_type]);
888 888
889 $type = 'E'; 889 $type = 'E';
890 890
891 } elsif ($cur =~ /^(\#\s*(?:endif))/o) { 891 } elsif ($cur =~ /^(\#\s*(?:endif))/o) {
892 print "PRE_END($1)\n" if ($dbg_values > 1); 892 print "PRE_END($1)\n" if ($dbg_values > 1);
893 893
894 $av_preprocessor = 1; 894 $av_preprocessor = 1;
895 895
896 # Assume all arms of the conditional end as this 896 # Assume all arms of the conditional end as this
897 # one does, and continue as if the #endif was not here. 897 # one does, and continue as if the #endif was not here.
898 pop(@av_paren_type); 898 pop(@av_paren_type);
899 push(@av_paren_type, $type); 899 push(@av_paren_type, $type);
900 $type = 'E'; 900 $type = 'E';
901 901
902 } elsif ($cur =~ /^(\\\n)/o) { 902 } elsif ($cur =~ /^(\\\n)/o) {
903 print "PRECONT($1)\n" if ($dbg_values > 1); 903 print "PRECONT($1)\n" if ($dbg_values > 1);
904 904
905 } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { 905 } elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
906 print "ATTR($1)\n" if ($dbg_values > 1); 906 print "ATTR($1)\n" if ($dbg_values > 1);
907 $av_pending = $type; 907 $av_pending = $type;
908 $type = 'N'; 908 $type = 'N';
909 909
910 } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { 910 } elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
911 print "SIZEOF($1)\n" if ($dbg_values > 1); 911 print "SIZEOF($1)\n" if ($dbg_values > 1);
912 if (defined $2) { 912 if (defined $2) {
913 $av_pending = 'V'; 913 $av_pending = 'V';
914 } 914 }
915 $type = 'N'; 915 $type = 'N';
916 916
917 } elsif ($cur =~ /^(if|while|for)\b/o) { 917 } elsif ($cur =~ /^(if|while|for)\b/o) {
918 print "COND($1)\n" if ($dbg_values > 1); 918 print "COND($1)\n" if ($dbg_values > 1);
919 $av_pending = 'E'; 919 $av_pending = 'E';
920 $type = 'N'; 920 $type = 'N';
921 921
922 } elsif ($cur =~/^(case)/o) { 922 } elsif ($cur =~/^(case)/o) {
923 print "CASE($1)\n" if ($dbg_values > 1); 923 print "CASE($1)\n" if ($dbg_values > 1);
924 $av_pend_colon = 'C'; 924 $av_pend_colon = 'C';
925 $type = 'N'; 925 $type = 'N';
926 926
927 } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { 927 } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
928 print "KEYWORD($1)\n" if ($dbg_values > 1); 928 print "KEYWORD($1)\n" if ($dbg_values > 1);
929 $type = 'N'; 929 $type = 'N';
930 930
931 } elsif ($cur =~ /^(\()/o) { 931 } elsif ($cur =~ /^(\()/o) {
932 print "PAREN('$1')\n" if ($dbg_values > 1); 932 print "PAREN('$1')\n" if ($dbg_values > 1);
933 push(@av_paren_type, $av_pending); 933 push(@av_paren_type, $av_pending);
934 $av_pending = '_'; 934 $av_pending = '_';
935 $type = 'N'; 935 $type = 'N';
936 936
937 } elsif ($cur =~ /^(\))/o) { 937 } elsif ($cur =~ /^(\))/o) {
938 my $new_type = pop(@av_paren_type); 938 my $new_type = pop(@av_paren_type);
939 if ($new_type ne '_') { 939 if ($new_type ne '_') {
940 $type = $new_type; 940 $type = $new_type;
941 print "PAREN('$1') -> $type\n" 941 print "PAREN('$1') -> $type\n"
942 if ($dbg_values > 1); 942 if ($dbg_values > 1);
943 } else { 943 } else {
944 print "PAREN('$1')\n" if ($dbg_values > 1); 944 print "PAREN('$1')\n" if ($dbg_values > 1);
945 } 945 }
946 946
947 } elsif ($cur =~ /^($Ident)\s*\(/o) { 947 } elsif ($cur =~ /^($Ident)\s*\(/o) {
948 print "FUNC($1)\n" if ($dbg_values > 1); 948 print "FUNC($1)\n" if ($dbg_values > 1);
949 $type = 'V'; 949 $type = 'V';
950 $av_pending = 'V'; 950 $av_pending = 'V';
951 951
952 } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { 952 } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
953 if (defined $2 && $type eq 'C' || $type eq 'T') { 953 if (defined $2 && $type eq 'C' || $type eq 'T') {
954 $av_pend_colon = 'B'; 954 $av_pend_colon = 'B';
955 } elsif ($type eq 'E') { 955 } elsif ($type eq 'E') {
956 $av_pend_colon = 'L'; 956 $av_pend_colon = 'L';
957 } 957 }
958 print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); 958 print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
959 $type = 'V'; 959 $type = 'V';
960 960
961 } elsif ($cur =~ /^($Ident|$Constant)/o) { 961 } elsif ($cur =~ /^($Ident|$Constant)/o) {
962 print "IDENT($1)\n" if ($dbg_values > 1); 962 print "IDENT($1)\n" if ($dbg_values > 1);
963 $type = 'V'; 963 $type = 'V';
964 964
965 } elsif ($cur =~ /^($Assignment)/o) { 965 } elsif ($cur =~ /^($Assignment)/o) {
966 print "ASSIGN($1)\n" if ($dbg_values > 1); 966 print "ASSIGN($1)\n" if ($dbg_values > 1);
967 $type = 'N'; 967 $type = 'N';
968 968
969 } elsif ($cur =~/^(;|{|})/) { 969 } elsif ($cur =~/^(;|{|})/) {
970 print "END($1)\n" if ($dbg_values > 1); 970 print "END($1)\n" if ($dbg_values > 1);
971 $type = 'E'; 971 $type = 'E';
972 $av_pend_colon = 'O'; 972 $av_pend_colon = 'O';
973 973
974 } elsif ($cur =~/^(,)/) { 974 } elsif ($cur =~/^(,)/) {
975 print "COMMA($1)\n" if ($dbg_values > 1); 975 print "COMMA($1)\n" if ($dbg_values > 1);
976 $type = 'C'; 976 $type = 'C';
977 977
978 } elsif ($cur =~ /^(\?)/o) { 978 } elsif ($cur =~ /^(\?)/o) {
979 print "QUESTION($1)\n" if ($dbg_values > 1); 979 print "QUESTION($1)\n" if ($dbg_values > 1);
980 $type = 'N'; 980 $type = 'N';
981 981
982 } elsif ($cur =~ /^(:)/o) { 982 } elsif ($cur =~ /^(:)/o) {
983 print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); 983 print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
984 984
985 substr($var, length($res), 1, $av_pend_colon); 985 substr($var, length($res), 1, $av_pend_colon);
986 if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { 986 if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
987 $type = 'E'; 987 $type = 'E';
988 } else { 988 } else {
989 $type = 'N'; 989 $type = 'N';
990 } 990 }
991 $av_pend_colon = 'O'; 991 $av_pend_colon = 'O';
992 992
993 } elsif ($cur =~ /^(\[)/o) { 993 } elsif ($cur =~ /^(\[)/o) {
994 print "CLOSE($1)\n" if ($dbg_values > 1); 994 print "CLOSE($1)\n" if ($dbg_values > 1);
995 $type = 'N'; 995 $type = 'N';
996 996
997 } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { 997 } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
998 my $variant; 998 my $variant;
999 999
1000 print "OPV($1)\n" if ($dbg_values > 1); 1000 print "OPV($1)\n" if ($dbg_values > 1);
1001 if ($type eq 'V') { 1001 if ($type eq 'V') {
1002 $variant = 'B'; 1002 $variant = 'B';
1003 } else { 1003 } else {
1004 $variant = 'U'; 1004 $variant = 'U';
1005 } 1005 }
1006 1006
1007 substr($var, length($res), 1, $variant); 1007 substr($var, length($res), 1, $variant);
1008 $type = 'N'; 1008 $type = 'N';
1009 1009
1010 } elsif ($cur =~ /^($Operators)/o) { 1010 } elsif ($cur =~ /^($Operators)/o) {
1011 print "OP($1)\n" if ($dbg_values > 1); 1011 print "OP($1)\n" if ($dbg_values > 1);
1012 if ($1 ne '++' && $1 ne '--') { 1012 if ($1 ne '++' && $1 ne '--') {
1013 $type = 'N'; 1013 $type = 'N';
1014 } 1014 }
1015 1015
1016 } elsif ($cur =~ /(^.)/o) { 1016 } elsif ($cur =~ /(^.)/o) {
1017 print "C($1)\n" if ($dbg_values > 1); 1017 print "C($1)\n" if ($dbg_values > 1);
1018 } 1018 }
1019 if (defined $1) { 1019 if (defined $1) {
1020 $cur = substr($cur, length($1)); 1020 $cur = substr($cur, length($1));
1021 $res .= $type x length($1); 1021 $res .= $type x length($1);
1022 } 1022 }
1023 } 1023 }
1024 1024
1025 return ($res, $var); 1025 return ($res, $var);
1026 } 1026 }
1027 1027
1028 sub possible { 1028 sub possible {
1029 my ($possible, $line) = @_; 1029 my ($possible, $line) = @_;
1030 my $notPermitted = qr{(?: 1030 my $notPermitted = qr{(?:
1031 ^(?: 1031 ^(?:
1032 $Modifier| 1032 $Modifier|
1033 $Storage| 1033 $Storage|
1034 $Type| 1034 $Type|
1035 DEFINE_\S+ 1035 DEFINE_\S+
1036 )$| 1036 )$|
1037 ^(?: 1037 ^(?:
1038 goto| 1038 goto|
1039 return| 1039 return|
1040 case| 1040 case|
1041 else| 1041 else|
1042 asm|__asm__| 1042 asm|__asm__|
1043 do 1043 do
1044 )(?:\s|$)| 1044 )(?:\s|$)|
1045 ^(?:typedef|struct|enum)\b 1045 ^(?:typedef|struct|enum)\b
1046 )}x; 1046 )}x;
1047 warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); 1047 warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
1048 if ($possible !~ $notPermitted) { 1048 if ($possible !~ $notPermitted) {
1049 # Check for modifiers. 1049 # Check for modifiers.
1050 $possible =~ s/\s*$Storage\s*//g; 1050 $possible =~ s/\s*$Storage\s*//g;
1051 $possible =~ s/\s*$Sparse\s*//g; 1051 $possible =~ s/\s*$Sparse\s*//g;
1052 if ($possible =~ /^\s*$/) { 1052 if ($possible =~ /^\s*$/) {
1053 1053
1054 } elsif ($possible =~ /\s/) { 1054 } elsif ($possible =~ /\s/) {
1055 $possible =~ s/\s*$Type\s*//g; 1055 $possible =~ s/\s*$Type\s*//g;
1056 for my $modifier (split(' ', $possible)) { 1056 for my $modifier (split(' ', $possible)) {
1057 if ($modifier !~ $notPermitted) { 1057 if ($modifier !~ $notPermitted) {
1058 warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); 1058 warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
1059 push(@modifierList, $modifier); 1059 push(@modifierList, $modifier);
1060 } 1060 }
1061 } 1061 }
1062 1062
1063 } else { 1063 } else {
1064 warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); 1064 warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
1065 push(@typeList, $possible); 1065 push(@typeList, $possible);
1066 } 1066 }
1067 build_types(); 1067 build_types();
1068 } else { 1068 } else {
1069 warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); 1069 warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
1070 } 1070 }
1071 } 1071 }
1072 1072
1073 my $prefix = ''; 1073 my $prefix = '';
1074 1074
1075 sub report { 1075 sub report {
1076 if (defined $tst_only && $_[0] !~ /\Q$tst_only\E/) { 1076 if (defined $tst_only && $_[0] !~ /\Q$tst_only\E/) {
1077 return 0; 1077 return 0;
1078 } 1078 }
1079 my $line = $prefix . $_[0]; 1079 my $line = $prefix . $_[0];
1080 1080
1081 $line = (split('\n', $line))[0] . "\n" if ($terse); 1081 $line = (split('\n', $line))[0] . "\n" if ($terse);
1082 1082
1083 push(our @report, $line); 1083 push(our @report, $line);
1084 1084
1085 return 1; 1085 return 1;
1086 } 1086 }
1087 sub report_dump { 1087 sub report_dump {
1088 our @report; 1088 our @report;
1089 } 1089 }
1090 sub ERROR { 1090 sub ERROR {
1091 if (report("ERROR: $_[0]\n")) { 1091 if (report("ERROR: $_[0]\n")) {
1092 our $clean = 0; 1092 our $clean = 0;
1093 our $cnt_error++; 1093 our $cnt_error++;
1094 } 1094 }
1095 } 1095 }
1096 sub WARN { 1096 sub WARN {
1097 if (report("WARNING: $_[0]\n")) { 1097 if (report("WARNING: $_[0]\n")) {
1098 our $clean = 0; 1098 our $clean = 0;
1099 our $cnt_warn++; 1099 our $cnt_warn++;
1100 } 1100 }
1101 } 1101 }
1102 sub CHK { 1102 sub CHK {
1103 if ($check && report("CHECK: $_[0]\n")) { 1103 if ($check && report("CHECK: $_[0]\n")) {
1104 our $clean = 0; 1104 our $clean = 0;
1105 our $cnt_chk++; 1105 our $cnt_chk++;
1106 } 1106 }
1107 } 1107 }
1108 1108
1109 sub check_absolute_file { 1109 sub check_absolute_file {
1110 my ($absolute, $herecurr) = @_; 1110 my ($absolute, $herecurr) = @_;
1111 my $file = $absolute; 1111 my $file = $absolute;
1112 1112
1113 ##print "absolute<$absolute>\n"; 1113 ##print "absolute<$absolute>\n";
1114 1114
1115 # See if any suffix of this path is a path within the tree. 1115 # See if any suffix of this path is a path within the tree.
1116 while ($file =~ s@^[^/]*/@@) { 1116 while ($file =~ s@^[^/]*/@@) {
1117 if (-f "$root/$file") { 1117 if (-f "$root/$file") {
1118 ##print "file<$file>\n"; 1118 ##print "file<$file>\n";
1119 last; 1119 last;
1120 } 1120 }
1121 } 1121 }
1122 if (! -f _) { 1122 if (! -f _) {
1123 return 0; 1123 return 0;
1124 } 1124 }
1125 1125
1126 # It is, so see if the prefix is acceptable. 1126 # It is, so see if the prefix is acceptable.
1127 my $prefix = $absolute; 1127 my $prefix = $absolute;
1128 substr($prefix, -length($file)) = ''; 1128 substr($prefix, -length($file)) = '';
1129 1129
1130 ##print "prefix<$prefix>\n"; 1130 ##print "prefix<$prefix>\n";
1131 if ($prefix ne ".../") { 1131 if ($prefix ne ".../") {
1132 WARN("use relative pathname instead of absolute in changelog text\n" . $herecurr); 1132 WARN("use relative pathname instead of absolute in changelog text\n" . $herecurr);
1133 } 1133 }
1134 } 1134 }
1135 1135
1136 sub process { 1136 sub process {
1137 my $filename = shift; 1137 my $filename = shift;
1138 1138
1139 my $linenr=0; 1139 my $linenr=0;
1140 my $prevline=""; 1140 my $prevline="";
1141 my $prevrawline=""; 1141 my $prevrawline="";
1142 my $stashline=""; 1142 my $stashline="";
1143 my $stashrawline=""; 1143 my $stashrawline="";
1144 1144
1145 my $length; 1145 my $length;
1146 my $indent; 1146 my $indent;
1147 my $previndent=0; 1147 my $previndent=0;
1148 my $stashindent=0; 1148 my $stashindent=0;
1149 1149
1150 our $clean = 1; 1150 our $clean = 1;
1151 my $signoff = 0; 1151 my $signoff = 0;
1152 my $is_patch = 0; 1152 my $is_patch = 0;
1153 1153
1154 our @report = (); 1154 our @report = ();
1155 our $cnt_lines = 0; 1155 our $cnt_lines = 0;
1156 our $cnt_error = 0; 1156 our $cnt_error = 0;
1157 our $cnt_warn = 0; 1157 our $cnt_warn = 0;
1158 our $cnt_chk = 0; 1158 our $cnt_chk = 0;
1159 1159
1160 # Trace the real file/line as we go. 1160 # Trace the real file/line as we go.
1161 my $realfile = ''; 1161 my $realfile = '';
1162 my $realline = 0; 1162 my $realline = 0;
1163 my $realcnt = 0; 1163 my $realcnt = 0;
1164 my $here = ''; 1164 my $here = '';
1165 my $in_comment = 0; 1165 my $in_comment = 0;
1166 my $comment_edge = 0; 1166 my $comment_edge = 0;
1167 my $first_line = 0; 1167 my $first_line = 0;
1168 my $p1_prefix = ''; 1168 my $p1_prefix = '';
1169 1169
1170 my $prev_values = 'E'; 1170 my $prev_values = 'E';
1171 1171
1172 # suppression flags 1172 # suppression flags
1173 my %suppress_ifbraces; 1173 my %suppress_ifbraces;
1174 my %suppress_whiletrailers; 1174 my %suppress_whiletrailers;
1175 my %suppress_export; 1175 my %suppress_export;
1176 1176
1177 # Pre-scan the patch sanitizing the lines. 1177 # Pre-scan the patch sanitizing the lines.
1178 # Pre-scan the patch looking for any __setup documentation. 1178 # Pre-scan the patch looking for any __setup documentation.
1179 # 1179 #
1180 my @setup_docs = (); 1180 my @setup_docs = ();
1181 my $setup_docs = 0; 1181 my $setup_docs = 0;
1182 1182
1183 sanitise_line_reset(); 1183 sanitise_line_reset();
1184 my $line; 1184 my $line;
1185 foreach my $rawline (@rawlines) { 1185 foreach my $rawline (@rawlines) {
1186 $linenr++; 1186 $linenr++;
1187 $line = $rawline; 1187 $line = $rawline;
1188 1188
1189 if ($rawline=~/^\+\+\+\s+(\S+)/) { 1189 if ($rawline=~/^\+\+\+\s+(\S+)/) {
1190 $setup_docs = 0; 1190 $setup_docs = 0;
1191 if ($1 =~ m@Documentation/kernel-parameters.txt$@) { 1191 if ($1 =~ m@Documentation/kernel-parameters.txt$@) {
1192 $setup_docs = 1; 1192 $setup_docs = 1;
1193 } 1193 }
1194 #next; 1194 #next;
1195 } 1195 }
1196 if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 1196 if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
1197 $realline=$1-1; 1197 $realline=$1-1;
1198 if (defined $2) { 1198 if (defined $2) {
1199 $realcnt=$3+1; 1199 $realcnt=$3+1;
1200 } else { 1200 } else {
1201 $realcnt=1+1; 1201 $realcnt=1+1;
1202 } 1202 }
1203 $in_comment = 0; 1203 $in_comment = 0;
1204 1204
1205 # Guestimate if this is a continuing comment. Run 1205 # Guestimate if this is a continuing comment. Run
1206 # the context looking for a comment "edge". If this 1206 # the context looking for a comment "edge". If this
1207 # edge is a close comment then we must be in a comment 1207 # edge is a close comment then we must be in a comment
1208 # at context start. 1208 # at context start.
1209 my $edge; 1209 my $edge;
1210 my $cnt = $realcnt; 1210 my $cnt = $realcnt;
1211 for (my $ln = $linenr + 1; $cnt > 0; $ln++) { 1211 for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
1212 next if (defined $rawlines[$ln - 1] && 1212 next if (defined $rawlines[$ln - 1] &&
1213 $rawlines[$ln - 1] =~ /^-/); 1213 $rawlines[$ln - 1] =~ /^-/);
1214 $cnt--; 1214 $cnt--;
1215 #print "RAW<$rawlines[$ln - 1]>\n"; 1215 #print "RAW<$rawlines[$ln - 1]>\n";
1216 last if (!defined $rawlines[$ln - 1]); 1216 last if (!defined $rawlines[$ln - 1]);
1217 if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && 1217 if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
1218 $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { 1218 $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
1219 ($edge) = $1; 1219 ($edge) = $1;
1220 last; 1220 last;
1221 } 1221 }
1222 } 1222 }
1223 if (defined $edge && $edge eq '*/') { 1223 if (defined $edge && $edge eq '*/') {
1224 $in_comment = 1; 1224 $in_comment = 1;
1225 } 1225 }
1226 1226
1227 # Guestimate if this is a continuing comment. If this 1227 # Guestimate if this is a continuing comment. If this
1228 # is the start of a diff block and this line starts 1228 # is the start of a diff block and this line starts
1229 # ' *' then it is very likely a comment. 1229 # ' *' then it is very likely a comment.
1230 if (!defined $edge && 1230 if (!defined $edge &&
1231 $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) 1231 $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
1232 { 1232 {
1233 $in_comment = 1; 1233 $in_comment = 1;
1234 } 1234 }
1235 1235
1236 ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; 1236 ##print "COMMENT:$in_comment edge<$edge> $rawline\n";
1237 sanitise_line_reset($in_comment); 1237 sanitise_line_reset($in_comment);
1238 1238
1239 } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { 1239 } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
1240 # Standardise the strings and chars within the input to 1240 # Standardise the strings and chars within the input to
1241 # simplify matching -- only bother with positive lines. 1241 # simplify matching -- only bother with positive lines.
1242 $line = sanitise_line($rawline); 1242 $line = sanitise_line($rawline);
1243 } 1243 }
1244 push(@lines, $line); 1244 push(@lines, $line);
1245 1245
1246 if ($realcnt > 1) { 1246 if ($realcnt > 1) {
1247 $realcnt-- if ($line =~ /^(?:\+| |$)/); 1247 $realcnt-- if ($line =~ /^(?:\+| |$)/);
1248 } else { 1248 } else {
1249 $realcnt = 0; 1249 $realcnt = 0;
1250 } 1250 }
1251 1251
1252 #print "==>$rawline\n"; 1252 #print "==>$rawline\n";
1253 #print "-->$line\n"; 1253 #print "-->$line\n";
1254 1254
1255 if ($setup_docs && $line =~ /^\+/) { 1255 if ($setup_docs && $line =~ /^\+/) {
1256 push(@setup_docs, $line); 1256 push(@setup_docs, $line);
1257 } 1257 }
1258 } 1258 }
1259 1259
1260 $prefix = ''; 1260 $prefix = '';
1261 1261
1262 $realcnt = 0; 1262 $realcnt = 0;
1263 $linenr = 0; 1263 $linenr = 0;
1264 foreach my $line (@lines) { 1264 foreach my $line (@lines) {
1265 $linenr++; 1265 $linenr++;
1266 1266
1267 my $rawline = $rawlines[$linenr - 1]; 1267 my $rawline = $rawlines[$linenr - 1];
1268 1268
1269 #extract the line range in the file after the patch is applied 1269 #extract the line range in the file after the patch is applied
1270 if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 1270 if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
1271 $is_patch = 1; 1271 $is_patch = 1;
1272 $first_line = $linenr + 1; 1272 $first_line = $linenr + 1;
1273 $realline=$1-1; 1273 $realline=$1-1;
1274 if (defined $2) { 1274 if (defined $2) {
1275 $realcnt=$3+1; 1275 $realcnt=$3+1;
1276 } else { 1276 } else {
1277 $realcnt=1+1; 1277 $realcnt=1+1;
1278 } 1278 }
1279 annotate_reset(); 1279 annotate_reset();
1280 $prev_values = 'E'; 1280 $prev_values = 'E';
1281 1281
1282 %suppress_ifbraces = (); 1282 %suppress_ifbraces = ();
1283 %suppress_whiletrailers = (); 1283 %suppress_whiletrailers = ();
1284 %suppress_export = (); 1284 %suppress_export = ();
1285 next; 1285 next;
1286 1286
1287 # track the line number as we move through the hunk, note that 1287 # track the line number as we move through the hunk, note that
1288 # new versions of GNU diff omit the leading space on completely 1288 # new versions of GNU diff omit the leading space on completely
1289 # blank context lines so we need to count that too. 1289 # blank context lines so we need to count that too.
1290 } elsif ($line =~ /^( |\+|$)/) { 1290 } elsif ($line =~ /^( |\+|$)/) {
1291 $realline++; 1291 $realline++;
1292 $realcnt-- if ($realcnt != 0); 1292 $realcnt-- if ($realcnt != 0);
1293 1293
1294 # Measure the line length and indent. 1294 # Measure the line length and indent.
1295 ($length, $indent) = line_stats($rawline); 1295 ($length, $indent) = line_stats($rawline);
1296 1296
1297 # Track the previous line. 1297 # Track the previous line.
1298 ($prevline, $stashline) = ($stashline, $line); 1298 ($prevline, $stashline) = ($stashline, $line);
1299 ($previndent, $stashindent) = ($stashindent, $indent); 1299 ($previndent, $stashindent) = ($stashindent, $indent);
1300 ($prevrawline, $stashrawline) = ($stashrawline, $rawline); 1300 ($prevrawline, $stashrawline) = ($stashrawline, $rawline);
1301 1301
1302 #warn "line<$line>\n"; 1302 #warn "line<$line>\n";
1303 1303
1304 } elsif ($realcnt == 1) { 1304 } elsif ($realcnt == 1) {
1305 $realcnt--; 1305 $realcnt--;
1306 } 1306 }
1307 1307
1308 my $hunk_line = ($realcnt != 0); 1308 my $hunk_line = ($realcnt != 0);
1309 1309
1310 #make up the handle for any error we report on this line 1310 #make up the handle for any error we report on this line
1311 $prefix = "$filename:$realline: " if ($emacs && $file); 1311 $prefix = "$filename:$realline: " if ($emacs && $file);
1312 $prefix = "$filename:$linenr: " if ($emacs && !$file); 1312 $prefix = "$filename:$linenr: " if ($emacs && !$file);
1313 1313
1314 $here = "#$linenr: " if (!$file); 1314 $here = "#$linenr: " if (!$file);
1315 $here = "#$realline: " if ($file); 1315 $here = "#$realline: " if ($file);
1316 1316
1317 # extract the filename as it passes 1317 # extract the filename as it passes
1318 if ($line=~/^\+\+\+\s+(\S+)/) { 1318 if ($line=~/^\+\+\+\s+(\S+)/) {
1319 $realfile = $1; 1319 $realfile = $1;
1320 $realfile =~ s@^([^/]*)/@@; 1320 $realfile =~ s@^([^/]*)/@@;
1321 1321
1322 $p1_prefix = $1; 1322 $p1_prefix = $1;
1323 if (!$file && $tree && $p1_prefix ne '' && 1323 if (!$file && $tree && $p1_prefix ne '' &&
1324 -e "$root/$p1_prefix") { 1324 -e "$root/$p1_prefix") {
1325 WARN("patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); 1325 WARN("patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
1326 } 1326 }
1327 1327
1328 if ($realfile =~ m@^include/asm/@) { 1328 if ($realfile =~ m@^include/asm/@) {
1329 ERROR("do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); 1329 ERROR("do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
1330 } 1330 }
1331 next; 1331 next;
1332 } 1332 }
1333 1333
1334 $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 1334 $here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
1335 1335
1336 my $hereline = "$here\n$rawline\n"; 1336 my $hereline = "$here\n$rawline\n";
1337 my $herecurr = "$here\n$rawline\n"; 1337 my $herecurr = "$here\n$rawline\n";
1338 my $hereprev = "$here\n$prevrawline\n$rawline\n"; 1338 my $hereprev = "$here\n$prevrawline\n$rawline\n";
1339 1339
1340 $cnt_lines++ if ($realcnt != 0); 1340 $cnt_lines++ if ($realcnt != 0);
1341 1341
1342 #check the patch for a signoff: 1342 #check the patch for a signoff:
1343 if ($line =~ /^\s*signed-off-by:/i) { 1343 if ($line =~ /^\s*signed-off-by:/i) {
1344 # This is a signoff, if ugly, so do not double report. 1344 # This is a signoff, if ugly, so do not double report.
1345 $signoff++; 1345 $signoff++;
1346 if (!($line =~ /^\s*Signed-off-by:/)) { 1346 if (!($line =~ /^\s*Signed-off-by:/)) {
1347 WARN("Signed-off-by: is the preferred form\n" . 1347 WARN("Signed-off-by: is the preferred form\n" .
1348 $herecurr); 1348 $herecurr);
1349 } 1349 }
1350 if ($line =~ /^\s*signed-off-by:\S/i) { 1350 if ($line =~ /^\s*signed-off-by:\S/i) {
1351 WARN("space required after Signed-off-by:\n" . 1351 WARN("space required after Signed-off-by:\n" .
1352 $herecurr); 1352 $herecurr);
1353 } 1353 }
1354 } 1354 }
1355 1355
1356 # Check for wrappage within a valid hunk of the file 1356 # Check for wrappage within a valid hunk of the file
1357 if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { 1357 if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
1358 ERROR("patch seems to be corrupt (line wrapped?)\n" . 1358 ERROR("patch seems to be corrupt (line wrapped?)\n" .
1359 $herecurr) if (!$emitted_corrupt++); 1359 $herecurr) if (!$emitted_corrupt++);
1360 } 1360 }
1361 1361
1362 # Check for absolute kernel paths. 1362 # Check for absolute kernel paths.
1363 if ($tree) { 1363 if ($tree) {
1364 while ($line =~ m{(?:^|\s)(/\S*)}g) { 1364 while ($line =~ m{(?:^|\s)(/\S*)}g) {
1365 my $file = $1; 1365 my $file = $1;
1366 1366
1367 if ($file =~ m{^(.*?)(?::\d+)+:?$} && 1367 if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
1368 check_absolute_file($1, $herecurr)) { 1368 check_absolute_file($1, $herecurr)) {
1369 # 1369 #
1370 } else { 1370 } else {
1371 check_absolute_file($file, $herecurr); 1371 check_absolute_file($file, $herecurr);
1372 } 1372 }
1373 } 1373 }
1374 } 1374 }
1375 1375
1376 # UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 1376 # UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
1377 if (($realfile =~ /^$/ || $line =~ /^\+/) && 1377 if (($realfile =~ /^$/ || $line =~ /^\+/) &&
1378 $rawline !~ m/^$UTF8*$/) { 1378 $rawline !~ m/^$UTF8*$/) {
1379 my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); 1379 my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
1380 1380
1381 my $blank = copy_spacing($rawline); 1381 my $blank = copy_spacing($rawline);
1382 my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; 1382 my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
1383 my $hereptr = "$hereline$ptr\n"; 1383 my $hereptr = "$hereline$ptr\n";
1384 1384
1385 ERROR("Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); 1385 ERROR("Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
1386 } 1386 }
1387 1387
1388 # ignore non-hunk lines and lines being removed 1388 # ignore non-hunk lines and lines being removed
1389 next if (!$hunk_line || $line =~ /^-/); 1389 next if (!$hunk_line || $line =~ /^-/);
1390 1390
1391 #trailing whitespace 1391 #trailing whitespace
1392 if ($line =~ /^\+.*\015/) { 1392 if ($line =~ /^\+.*\015/) {
1393 my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1393 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1394 ERROR("DOS line endings\n" . $herevet); 1394 ERROR("DOS line endings\n" . $herevet);
1395 1395
1396 } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 1396 } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
1397 my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1397 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1398 ERROR("trailing whitespace\n" . $herevet); 1398 ERROR("trailing whitespace\n" . $herevet);
1399 $rpt_cleaners = 1; 1399 $rpt_cleaners = 1;
1400 } 1400 }
1401 1401
1402 # check for Kconfig help text having a real description 1402 # check for Kconfig help text having a real description
1403 if ($realfile =~ /Kconfig/ && 1403 if ($realfile =~ /Kconfig/ &&
1404 $line =~ /\+?\s*(---)?help(---)?$/) { 1404 $line =~ /\+?\s*(---)?help(---)?$/) {
1405 my $length = 0; 1405 my $length = 0;
1406 for (my $l = $linenr; defined($lines[$l]); $l++) { 1406 for (my $l = $linenr; defined($lines[$l]); $l++) {
1407 my $f = $lines[$l]; 1407 my $f = $lines[$l];
1408 $f =~ s/#.*//; 1408 $f =~ s/#.*//;
1409 $f =~ s/^\s+//; 1409 $f =~ s/^\s+//;
1410 next if ($f =~ /^$/); 1410 next if ($f =~ /^$/);
1411 last if ($f =~ /^\s*config\s/); 1411 last if ($f =~ /^\s*config\s/);
1412 $length++; 1412 $length++;
1413 } 1413 }
1414 WARN("please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($length < 4); 1414 WARN("please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($length < 4);
1415 } 1415 }
1416 1416
1417 # check we are in a valid source file if not then ignore this hunk 1417 # check we are in a valid source file if not then ignore this hunk
1418 next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/); 1418 next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
1419 1419
1420 #80 column limit 1420 #80 column limit
1421 if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && 1421 if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
1422 $rawline !~ /^.\s*\*\s*\@$Ident\s/ && 1422 $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
1423 !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:,|\)\s*;)\s*$/ || 1423 !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:,|\)\s*;)\s*$/ ||
1424 $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) && 1424 $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) &&
1425 $length > 80) 1425 $length > 80)
1426 { 1426 {
1427 WARN("line over 80 characters\n" . $herecurr); 1427 WARN("line over 80 characters\n" . $herecurr);
1428 } 1428 }
1429 1429
1430 # check for spaces before a quoted newline 1430 # check for spaces before a quoted newline
1431 if ($rawline =~ /^.*\".*\s\\n/) { 1431 if ($rawline =~ /^.*\".*\s\\n/) {
1432 WARN("unnecessary whitespace before a quoted newline\n" . $herecurr); 1432 WARN("unnecessary whitespace before a quoted newline\n" . $herecurr);
1433 } 1433 }
1434 1434
1435 # check for adding lines without a newline. 1435 # check for adding lines without a newline.
1436 if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 1436 if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
1437 WARN("adding a line without newline at end of file\n" . $herecurr); 1437 WARN("adding a line without newline at end of file\n" . $herecurr);
1438 } 1438 }
1439 1439
1440 # Blackfin: use hi/lo macros 1440 # Blackfin: use hi/lo macros
1441 if ($realfile =~ m@arch/blackfin/.*\.S$@) { 1441 if ($realfile =~ m@arch/blackfin/.*\.S$@) {
1442 if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) { 1442 if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) {
1443 my $herevet = "$here\n" . cat_vet($line) . "\n"; 1443 my $herevet = "$here\n" . cat_vet($line) . "\n";
1444 ERROR("use the LO() macro, not (... & 0xFFFF)\n" . $herevet); 1444 ERROR("use the LO() macro, not (... & 0xFFFF)\n" . $herevet);
1445 } 1445 }
1446 if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) { 1446 if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) {
1447 my $herevet = "$here\n" . cat_vet($line) . "\n"; 1447 my $herevet = "$here\n" . cat_vet($line) . "\n";
1448 ERROR("use the HI() macro, not (... >> 16)\n" . $herevet); 1448 ERROR("use the HI() macro, not (... >> 16)\n" . $herevet);
1449 } 1449 }
1450 } 1450 }
1451 1451
1452 # check we are in a valid source file C or perl if not then ignore this hunk 1452 # check we are in a valid source file C or perl if not then ignore this hunk
1453 next if ($realfile !~ /\.(h|c|pl)$/); 1453 next if ($realfile !~ /\.(h|c|pl)$/);
1454 1454
1455 # at the beginning of a line any tabs must come first and anything 1455 # at the beginning of a line any tabs must come first and anything
1456 # more than 8 must use tabs. 1456 # more than 8 must use tabs.
1457 if ($rawline =~ /^\+\s* \t\s*\S/ || 1457 if ($rawline =~ /^\+\s* \t\s*\S/ ||
1458 $rawline =~ /^\+\s* \s*/) { 1458 $rawline =~ /^\+\s* \s*/) {
1459 my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1459 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1460 ERROR("code indent should use tabs where possible\n" . $herevet); 1460 ERROR("code indent should use tabs where possible\n" . $herevet);
1461 $rpt_cleaners = 1; 1461 $rpt_cleaners = 1;
1462 } 1462 }
1463 1463
1464 # check for space before tabs. 1464 # check for space before tabs.
1465 if ($rawline =~ /^\+/ && $rawline =~ / \t/) { 1465 if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
1466 my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1466 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1467 WARN("please, no space before tabs\n" . $herevet); 1467 WARN("please, no space before tabs\n" . $herevet);
1468 } 1468 }
1469 1469
1470 # check for spaces at the beginning of a line. 1470 # check for spaces at the beginning of a line.
1471 # Exceptions: 1471 # Exceptions:
1472 # 1) within comments 1472 # 1) within comments
1473 # 2) indented preprocessor commands 1473 # 2) indented preprocessor commands
1474 # 3) hanging labels 1474 # 3) hanging labels
1475 if ($rawline =~ /^\+ / && $line !~ /\+ *(?:$;|#|$Ident:)/) { 1475 if ($rawline =~ /^\+ / && $line !~ /\+ *(?:$;|#|$Ident:)/) {
1476 my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1476 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
1477 WARN("please, no spaces at the start of a line\n" . $herevet); 1477 WARN("please, no spaces at the start of a line\n" . $herevet);
1478 } 1478 }
1479 1479
1480 # check we are in a valid C source file if not then ignore this hunk 1480 # check we are in a valid C source file if not then ignore this hunk
1481 next if ($realfile !~ /\.(h|c)$/); 1481 next if ($realfile !~ /\.(h|c)$/);
1482 1482
1483 # check for RCS/CVS revision markers 1483 # check for RCS/CVS revision markers
1484 if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { 1484 if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
1485 WARN("CVS style keyword markers, these will _not_ be updated\n". $herecurr); 1485 WARN("CVS style keyword markers, these will _not_ be updated\n". $herecurr);
1486 } 1486 }
1487 1487
1488 # Blackfin: don't use __builtin_bfin_[cs]sync 1488 # Blackfin: don't use __builtin_bfin_[cs]sync
1489 if ($line =~ /__builtin_bfin_csync/) { 1489 if ($line =~ /__builtin_bfin_csync/) {
1490 my $herevet = "$here\n" . cat_vet($line) . "\n"; 1490 my $herevet = "$here\n" . cat_vet($line) . "\n";
1491 ERROR("use the CSYNC() macro in asm/blackfin.h\n" . $herevet); 1491 ERROR("use the CSYNC() macro in asm/blackfin.h\n" . $herevet);
1492 } 1492 }
1493 if ($line =~ /__builtin_bfin_ssync/) { 1493 if ($line =~ /__builtin_bfin_ssync/) {
1494 my $herevet = "$here\n" . cat_vet($line) . "\n"; 1494 my $herevet = "$here\n" . cat_vet($line) . "\n";
1495 ERROR("use the SSYNC() macro in asm/blackfin.h\n" . $herevet); 1495 ERROR("use the SSYNC() macro in asm/blackfin.h\n" . $herevet);
1496 } 1496 }
1497 1497
1498 # Check for potential 'bare' types 1498 # Check for potential 'bare' types
1499 my ($stat, $cond, $line_nr_next, $remain_next, $off_next, 1499 my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
1500 $realline_next); 1500 $realline_next);
1501 if ($realcnt && $line =~ /.\s*\S/) { 1501 if ($realcnt && $line =~ /.\s*\S/) {
1502 ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 1502 ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
1503 ctx_statement_block($linenr, $realcnt, 0); 1503 ctx_statement_block($linenr, $realcnt, 0);
1504 $stat =~ s/\n./\n /g; 1504 $stat =~ s/\n./\n /g;
1505 $cond =~ s/\n./\n /g; 1505 $cond =~ s/\n./\n /g;
1506 1506
1507 # Find the real next line. 1507 # Find the real next line.
1508 $realline_next = $line_nr_next; 1508 $realline_next = $line_nr_next;
1509 if (defined $realline_next && 1509 if (defined $realline_next &&
1510 (!defined $lines[$realline_next - 1] || 1510 (!defined $lines[$realline_next - 1] ||
1511 substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { 1511 substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
1512 $realline_next++; 1512 $realline_next++;
1513 } 1513 }
1514 1514
1515 my $s = $stat; 1515 my $s = $stat;
1516 $s =~ s/{.*$//s; 1516 $s =~ s/{.*$//s;
1517 1517
1518 # Ignore goto labels. 1518 # Ignore goto labels.
1519 if ($s =~ /$Ident:\*$/s) { 1519 if ($s =~ /$Ident:\*$/s) {
1520 1520
1521 # Ignore functions being called 1521 # Ignore functions being called
1522 } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 1522 } elsif ($s =~ /^.\s*$Ident\s*\(/s) {
1523 1523
1524 } elsif ($s =~ /^.\s*else\b/s) { 1524 } elsif ($s =~ /^.\s*else\b/s) {
1525 1525
1526 # declarations always start with types 1526 # declarations always start with types
1527 } 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) { 1527 } 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) {
1528 my $type = $1; 1528 my $type = $1;
1529 $type =~ s/\s+/ /g; 1529 $type =~ s/\s+/ /g;
1530 possible($type, "A:" . $s); 1530 possible($type, "A:" . $s);
1531 1531
1532 # definitions in global scope can only start with types 1532 # definitions in global scope can only start with types
1533 } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { 1533 } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
1534 possible($1, "B:" . $s); 1534 possible($1, "B:" . $s);
1535 } 1535 }
1536 1536
1537 # any (foo ... *) is a pointer cast, and foo is a type 1537 # any (foo ... *) is a pointer cast, and foo is a type
1538 while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { 1538 while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
1539 possible($1, "C:" . $s); 1539 possible($1, "C:" . $s);
1540 } 1540 }
1541 1541
1542 # Check for any sort of function declaration. 1542 # Check for any sort of function declaration.
1543 # int foo(something bar, other baz); 1543 # int foo(something bar, other baz);
1544 # void (*store_gdt)(x86_descr_ptr *); 1544 # void (*store_gdt)(x86_descr_ptr *);
1545 if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { 1545 if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
1546 my ($name_len) = length($1); 1546 my ($name_len) = length($1);
1547 1547
1548 my $ctx = $s; 1548 my $ctx = $s;
1549 substr($ctx, 0, $name_len + 1, ''); 1549 substr($ctx, 0, $name_len + 1, '');
1550 $ctx =~ s/\)[^\)]*$//; 1550 $ctx =~ s/\)[^\)]*$//;
1551 1551
1552 for my $arg (split(/\s*,\s*/, $ctx)) { 1552 for my $arg (split(/\s*,\s*/, $ctx)) {
1553 if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { 1553 if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
1554 1554
1555 possible($1, "D:" . $s); 1555 possible($1, "D:" . $s);
1556 } 1556 }
1557 } 1557 }
1558 } 1558 }
1559 1559
1560 } 1560 }
1561 1561
1562 # 1562 #
1563 # Checks which may be anchored in the context. 1563 # Checks which may be anchored in the context.
1564 # 1564 #
1565 1565
1566 # Check for switch () and associated case and default 1566 # Check for switch () and associated case and default
1567 # statements should be at the same indent. 1567 # statements should be at the same indent.
1568 if ($line=~/\bswitch\s*\(.*\)/) { 1568 if ($line=~/\bswitch\s*\(.*\)/) {
1569 my $err = ''; 1569 my $err = '';
1570 my $sep = ''; 1570 my $sep = '';
1571 my @ctx = ctx_block_outer($linenr, $realcnt); 1571 my @ctx = ctx_block_outer($linenr, $realcnt);
1572 shift(@ctx); 1572 shift(@ctx);
1573 for my $ctx (@ctx) { 1573 for my $ctx (@ctx) {
1574 my ($clen, $cindent) = line_stats($ctx); 1574 my ($clen, $cindent) = line_stats($ctx);
1575 if ($ctx =~ /^\+\s*(case\s+|default:)/ && 1575 if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
1576 $indent != $cindent) { 1576 $indent != $cindent) {
1577 $err .= "$sep$ctx\n"; 1577 $err .= "$sep$ctx\n";
1578 $sep = ''; 1578 $sep = '';
1579 } else { 1579 } else {
1580 $sep = "[...]\n"; 1580 $sep = "[...]\n";
1581 } 1581 }
1582 } 1582 }
1583 if ($err ne '') { 1583 if ($err ne '') {
1584 ERROR("switch and case should be at the same indent\n$hereline$err"); 1584 ERROR("switch and case should be at the same indent\n$hereline$err");
1585 } 1585 }
1586 } 1586 }
1587 1587
1588 # if/while/etc brace do not go on next line, unless defining a do while loop, 1588 # if/while/etc brace do not go on next line, unless defining a do while loop,
1589 # or if that brace on the next line is for something else 1589 # or if that brace on the next line is for something else
1590 if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { 1590 if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
1591 my $pre_ctx = "$1$2"; 1591 my $pre_ctx = "$1$2";
1592 1592
1593 my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 1593 my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
1594 my $ctx_cnt = $realcnt - $#ctx - 1; 1594 my $ctx_cnt = $realcnt - $#ctx - 1;
1595 my $ctx = join("\n", @ctx); 1595 my $ctx = join("\n", @ctx);
1596 1596
1597 my $ctx_ln = $linenr; 1597 my $ctx_ln = $linenr;
1598 my $ctx_skip = $realcnt; 1598 my $ctx_skip = $realcnt;
1599 1599
1600 while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && 1600 while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
1601 defined $lines[$ctx_ln - 1] && 1601 defined $lines[$ctx_ln - 1] &&
1602 $lines[$ctx_ln - 1] =~ /^-/)) { 1602 $lines[$ctx_ln - 1] =~ /^-/)) {
1603 ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; 1603 ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
1604 $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); 1604 $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
1605 $ctx_ln++; 1605 $ctx_ln++;
1606 } 1606 }
1607 1607
1608 #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; 1608 #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
1609 #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 1609 #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
1610 1610
1611 if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 1611 if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
1612 ERROR("that open brace { should be on the previous line\n" . 1612 ERROR("that open brace { should be on the previous line\n" .
1613 "$here\n$ctx\n$lines[$ctx_ln - 1]\n"); 1613 "$here\n$ctx\n$lines[$ctx_ln - 1]\n");
1614 } 1614 }
1615 if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 1615 if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
1616 $ctx =~ /\)\s*\;\s*$/ && 1616 $ctx =~ /\)\s*\;\s*$/ &&
1617 defined $lines[$ctx_ln - 1]) 1617 defined $lines[$ctx_ln - 1])
1618 { 1618 {
1619 my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 1619 my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
1620 if ($nindent > $indent) { 1620 if ($nindent > $indent) {
1621 WARN("trailing semicolon indicates no statements, indent implies otherwise\n" . 1621 WARN("trailing semicolon indicates no statements, indent implies otherwise\n" .
1622 "$here\n$ctx\n$lines[$ctx_ln - 1]\n"); 1622 "$here\n$ctx\n$lines[$ctx_ln - 1]\n");
1623 } 1623 }
1624 } 1624 }
1625 } 1625 }
1626 1626
1627 # Check relative indent for conditionals and blocks. 1627 # Check relative indent for conditionals and blocks.
1628 if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { 1628 if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
1629 my ($s, $c) = ($stat, $cond); 1629 my ($s, $c) = ($stat, $cond);
1630 1630
1631 substr($s, 0, length($c), ''); 1631 substr($s, 0, length($c), '');
1632 1632
1633 # Make sure we remove the line prefixes as we have 1633 # Make sure we remove the line prefixes as we have
1634 # none on the first line, and are going to readd them 1634 # none on the first line, and are going to readd them
1635 # where necessary. 1635 # where necessary.
1636 $s =~ s/\n./\n/gs; 1636 $s =~ s/\n./\n/gs;
1637 1637
1638 # Find out how long the conditional actually is. 1638 # Find out how long the conditional actually is.
1639 my @newlines = ($c =~ /\n/gs); 1639 my @newlines = ($c =~ /\n/gs);
1640 my $cond_lines = 1 + $#newlines; 1640 my $cond_lines = 1 + $#newlines;
1641 1641
1642 # We want to check the first line inside the block 1642 # We want to check the first line inside the block
1643 # starting at the end of the conditional, so remove: 1643 # starting at the end of the conditional, so remove:
1644 # 1) any blank line termination 1644 # 1) any blank line termination
1645 # 2) any opening brace { on end of the line 1645 # 2) any opening brace { on end of the line
1646 # 3) any do (...) { 1646 # 3) any do (...) {
1647 my $continuation = 0; 1647 my $continuation = 0;
1648 my $check = 0; 1648 my $check = 0;
1649 $s =~ s/^.*\bdo\b//; 1649 $s =~ s/^.*\bdo\b//;
1650 $s =~ s/^\s*{//; 1650 $s =~ s/^\s*{//;
1651 if ($s =~ s/^\s*\\//) { 1651 if ($s =~ s/^\s*\\//) {
1652 $continuation = 1; 1652 $continuation = 1;
1653 } 1653 }
1654 if ($s =~ s/^\s*?\n//) { 1654 if ($s =~ s/^\s*?\n//) {
1655 $check = 1; 1655 $check = 1;
1656 $cond_lines++; 1656 $cond_lines++;
1657 } 1657 }
1658 1658
1659 # Also ignore a loop construct at the end of a 1659 # Also ignore a loop construct at the end of a
1660 # preprocessor statement. 1660 # preprocessor statement.
1661 if (($prevline =~ /^.\s*#\s*define\s/ || 1661 if (($prevline =~ /^.\s*#\s*define\s/ ||
1662 $prevline =~ /\\\s*$/) && $continuation == 0) { 1662 $prevline =~ /\\\s*$/) && $continuation == 0) {
1663 $check = 0; 1663 $check = 0;
1664 } 1664 }
1665 1665
1666 my $cond_ptr = -1; 1666 my $cond_ptr = -1;
1667 $continuation = 0; 1667 $continuation = 0;
1668 while ($cond_ptr != $cond_lines) { 1668 while ($cond_ptr != $cond_lines) {
1669 $cond_ptr = $cond_lines; 1669 $cond_ptr = $cond_lines;
1670 1670
1671 # If we see an #else/#elif then the code 1671 # If we see an #else/#elif then the code
1672 # is not linear. 1672 # is not linear.
1673 if ($s =~ /^\s*\#\s*(?:else|elif)/) { 1673 if ($s =~ /^\s*\#\s*(?:else|elif)/) {
1674 $check = 0; 1674 $check = 0;
1675 } 1675 }
1676 1676
1677 # Ignore: 1677 # Ignore:
1678 # 1) blank lines, they should be at 0, 1678 # 1) blank lines, they should be at 0,
1679 # 2) preprocessor lines, and 1679 # 2) preprocessor lines, and
1680 # 3) labels. 1680 # 3) labels.
1681 if ($continuation || 1681 if ($continuation ||
1682 $s =~ /^\s*?\n/ || 1682 $s =~ /^\s*?\n/ ||
1683 $s =~ /^\s*#\s*?/ || 1683 $s =~ /^\s*#\s*?/ ||
1684 $s =~ /^\s*$Ident\s*:/) { 1684 $s =~ /^\s*$Ident\s*:/) {
1685 $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 1685 $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
1686 if ($s =~ s/^.*?\n//) { 1686 if ($s =~ s/^.*?\n//) {
1687 $cond_lines++; 1687 $cond_lines++;
1688 } 1688 }
1689 } 1689 }
1690 } 1690 }
1691 1691
1692 my (undef, $sindent) = line_stats("+" . $s); 1692 my (undef, $sindent) = line_stats("+" . $s);
1693 my $stat_real = raw_line($linenr, $cond_lines); 1693 my $stat_real = raw_line($linenr, $cond_lines);
1694 1694
1695 # Check if either of these lines are modified, else 1695 # Check if either of these lines are modified, else
1696 # this is not this patch's fault. 1696 # this is not this patch's fault.
1697 if (!defined($stat_real) || 1697 if (!defined($stat_real) ||
1698 $stat !~ /^\+/ && $stat_real !~ /^\+/) { 1698 $stat !~ /^\+/ && $stat_real !~ /^\+/) {
1699 $check = 0; 1699 $check = 0;
1700 } 1700 }
1701 if (defined($stat_real) && $cond_lines > 1) { 1701 if (defined($stat_real) && $cond_lines > 1) {
1702 $stat_real = "[...]\n$stat_real"; 1702 $stat_real = "[...]\n$stat_real";
1703 } 1703 }
1704 1704
1705 #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"; 1705 #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";
1706 1706
1707 if ($check && (($sindent % 8) != 0 || 1707 if ($check && (($sindent % 8) != 0 ||
1708 ($sindent <= $indent && $s ne ''))) { 1708 ($sindent <= $indent && $s ne ''))) {
1709 WARN("suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 1709 WARN("suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
1710 } 1710 }
1711 } 1711 }
1712 1712
1713 # Track the 'values' across context and added lines. 1713 # Track the 'values' across context and added lines.
1714 my $opline = $line; $opline =~ s/^./ /; 1714 my $opline = $line; $opline =~ s/^./ /;
1715 my ($curr_values, $curr_vars) = 1715 my ($curr_values, $curr_vars) =
1716 annotate_values($opline . "\n", $prev_values); 1716 annotate_values($opline . "\n", $prev_values);
1717 $curr_values = $prev_values . $curr_values; 1717 $curr_values = $prev_values . $curr_values;
1718 if ($dbg_values) { 1718 if ($dbg_values) {
1719 my $outline = $opline; $outline =~ s/\t/ /g; 1719 my $outline = $opline; $outline =~ s/\t/ /g;
1720 print "$linenr > .$outline\n"; 1720 print "$linenr > .$outline\n";
1721 print "$linenr > $curr_values\n"; 1721 print "$linenr > $curr_values\n";
1722 print "$linenr > $curr_vars\n"; 1722 print "$linenr > $curr_vars\n";
1723 } 1723 }
1724 $prev_values = substr($curr_values, -1); 1724 $prev_values = substr($curr_values, -1);
1725 1725
1726 #ignore lines not being added 1726 #ignore lines not being added
1727 if ($line=~/^[^\+]/) {next;} 1727 if ($line=~/^[^\+]/) {next;}
1728 1728
1729 # TEST: allow direct testing of the type matcher. 1729 # TEST: allow direct testing of the type matcher.
1730 if ($dbg_type) { 1730 if ($dbg_type) {
1731 if ($line =~ /^.\s*$Declare\s*$/) { 1731 if ($line =~ /^.\s*$Declare\s*$/) {
1732 ERROR("TEST: is type\n" . $herecurr); 1732 ERROR("TEST: is type\n" . $herecurr);
1733 } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { 1733 } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
1734 ERROR("TEST: is not type ($1 is)\n". $herecurr); 1734 ERROR("TEST: is not type ($1 is)\n". $herecurr);
1735 } 1735 }
1736 next; 1736 next;
1737 } 1737 }
1738 # TEST: allow direct testing of the attribute matcher. 1738 # TEST: allow direct testing of the attribute matcher.
1739 if ($dbg_attr) { 1739 if ($dbg_attr) {
1740 if ($line =~ /^.\s*$Modifier\s*$/) { 1740 if ($line =~ /^.\s*$Modifier\s*$/) {
1741 ERROR("TEST: is attr\n" . $herecurr); 1741 ERROR("TEST: is attr\n" . $herecurr);
1742 } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { 1742 } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
1743 ERROR("TEST: is not attr ($1 is)\n". $herecurr); 1743 ERROR("TEST: is not attr ($1 is)\n". $herecurr);
1744 } 1744 }
1745 next; 1745 next;
1746 } 1746 }
1747 1747
1748 # check for initialisation to aggregates open brace on the next line 1748 # check for initialisation to aggregates open brace on the next line
1749 if ($line =~ /^.\s*{/ && 1749 if ($line =~ /^.\s*{/ &&
1750 $prevline =~ /(?:^|[^=])=\s*$/) { 1750 $prevline =~ /(?:^|[^=])=\s*$/) {
1751 ERROR("that open brace { should be on the previous line\n" . $hereprev); 1751 ERROR("that open brace { should be on the previous line\n" . $hereprev);
1752 } 1752 }
1753 1753
1754 # 1754 #
1755 # Checks which are anchored on the added line. 1755 # Checks which are anchored on the added line.
1756 # 1756 #
1757 1757
1758 # check for malformed paths in #include statements (uses RAW line) 1758 # check for malformed paths in #include statements (uses RAW line)
1759 if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 1759 if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
1760 my $path = $1; 1760 my $path = $1;
1761 if ($path =~ m{//}) { 1761 if ($path =~ m{//}) {
1762 ERROR("malformed #include filename\n" . 1762 ERROR("malformed #include filename\n" .
1763 $herecurr); 1763 $herecurr);
1764 } 1764 }
1765 } 1765 }
1766 1766
1767 # no C99 // comments 1767 # no C99 // comments
1768 if ($line =~ m{//}) { 1768 if ($line =~ m{//}) {
1769 ERROR("do not use C99 // comments\n" . $herecurr); 1769 ERROR("do not use C99 // comments\n" . $herecurr);
1770 } 1770 }
1771 # Remove C99 comments. 1771 # Remove C99 comments.
1772 $line =~ s@//.*@@; 1772 $line =~ s@//.*@@;
1773 $opline =~ s@//.*@@; 1773 $opline =~ s@//.*@@;
1774 1774
1775 # EXPORT_SYMBOL should immediately follow the thing it is exporting, consider 1775 # EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
1776 # the whole statement. 1776 # the whole statement.
1777 #print "APW <$lines[$realline_next - 1]>\n"; 1777 #print "APW <$lines[$realline_next - 1]>\n";
1778 if (defined $realline_next && 1778 if (defined $realline_next &&
1779 exists $lines[$realline_next - 1] && 1779 exists $lines[$realline_next - 1] &&
1780 !defined $suppress_export{$realline_next} && 1780 !defined $suppress_export{$realline_next} &&
1781 ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || 1781 ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
1782 $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 1782 $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
1783 my $name = $1; 1783 my $name = $1;
1784 if ($stat !~ /(?: 1784 if ($stat !~ /(?:
1785 \n.}\s*$| 1785 \n.}\s*$|
1786 ^.DEFINE_$Ident\(\Q$name\E\)| 1786 ^.DEFINE_$Ident\(\Q$name\E\)|
1787 ^.DECLARE_$Ident\(\Q$name\E\)| 1787 ^.DECLARE_$Ident\(\Q$name\E\)|
1788 ^.LIST_HEAD\(\Q$name\E\)| 1788 ^.LIST_HEAD\(\Q$name\E\)|
1789 ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 1789 ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
1790 \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() 1790 \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
1791 )/x) { 1791 )/x) {
1792 #print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; 1792 #print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
1793 $suppress_export{$realline_next} = 2; 1793 $suppress_export{$realline_next} = 2;
1794 } else { 1794 } else {
1795 $suppress_export{$realline_next} = 1; 1795 $suppress_export{$realline_next} = 1;
1796 } 1796 }
1797 } 1797 }
1798 if (!defined $suppress_export{$linenr} && 1798 if (!defined $suppress_export{$linenr} &&
1799 $prevline =~ /^.\s*$/ && 1799 $prevline =~ /^.\s*$/ &&
1800 ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ || 1800 ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
1801 $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 1801 $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
1802 #print "FOO B <$lines[$linenr - 1]>\n"; 1802 #print "FOO B <$lines[$linenr - 1]>\n";
1803 $suppress_export{$linenr} = 2; 1803 $suppress_export{$linenr} = 2;
1804 } 1804 }
1805 if (defined $suppress_export{$linenr} && 1805 if (defined $suppress_export{$linenr} &&
1806 $suppress_export{$linenr} == 2) { 1806 $suppress_export{$linenr} == 2) {
1807 WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 1807 WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
1808 } 1808 }
1809 1809
1810 # check for global initialisers. 1810 # check for global initialisers.
1811 if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) { 1811 if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) {
1812 ERROR("do not initialise globals to 0 or NULL\n" . 1812 ERROR("do not initialise globals to 0 or NULL\n" .
1813 $herecurr); 1813 $herecurr);
1814 } 1814 }
1815 # check for static initialisers. 1815 # check for static initialisers.
1816 if ($line =~ /\bstatic\s.*=\s*(0|NULL|false)\s*;/) { 1816 if ($line =~ /\bstatic\s.*=\s*(0|NULL|false)\s*;/) {
1817 ERROR("do not initialise statics to 0 or NULL\n" . 1817 ERROR("do not initialise statics to 0 or NULL\n" .
1818 $herecurr); 1818 $herecurr);
1819 } 1819 }
1820 1820
1821 # check for new typedefs, only function parameters and sparse annotations 1821 # check for new typedefs, only function parameters and sparse annotations
1822 # make sense. 1822 # make sense.
1823 if ($line =~ /\btypedef\s/ && 1823 if ($line =~ /\btypedef\s/ &&
1824 $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && 1824 $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
1825 $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 1825 $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
1826 $line !~ /\b$typeTypedefs\b/ && 1826 $line !~ /\b$typeTypedefs\b/ &&
1827 $line !~ /\b__bitwise(?:__|)\b/) { 1827 $line !~ /\b__bitwise(?:__|)\b/) {
1828 WARN("do not add new typedefs\n" . $herecurr); 1828 WARN("do not add new typedefs\n" . $herecurr);
1829 } 1829 }
1830 1830
1831 # * goes on variable not on type 1831 # * goes on variable not on type
1832 # (char*[ const]) 1832 # (char*[ const])
1833 if ($line =~ m{\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\)}) { 1833 if ($line =~ m{\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\)}) {
1834 my ($from, $to) = ($1, $1); 1834 my ($from, $to) = ($1, $1);
1835 1835
1836 # Should start with a space. 1836 # Should start with a space.
1837 $to =~ s/^(\S)/ $1/; 1837 $to =~ s/^(\S)/ $1/;
1838 # Should not end with a space. 1838 # Should not end with a space.
1839 $to =~ s/\s+$//; 1839 $to =~ s/\s+$//;
1840 # '*'s should not have spaces between. 1840 # '*'s should not have spaces between.
1841 while ($to =~ s/\*\s+\*/\*\*/) { 1841 while ($to =~ s/\*\s+\*/\*\*/) {
1842 } 1842 }
1843 1843
1844 #print "from<$from> to<$to>\n"; 1844 #print "from<$from> to<$to>\n";
1845 if ($from ne $to) { 1845 if ($from ne $to) {
1846 ERROR("\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr); 1846 ERROR("\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr);
1847 } 1847 }
1848 } elsif ($line =~ m{\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident)}) { 1848 } elsif ($line =~ m{\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident)}) {
1849 my ($from, $to, $ident) = ($1, $1, $2); 1849 my ($from, $to, $ident) = ($1, $1, $2);
1850 1850
1851 # Should start with a space. 1851 # Should start with a space.
1852 $to =~ s/^(\S)/ $1/; 1852 $to =~ s/^(\S)/ $1/;
1853 # Should not end with a space. 1853 # Should not end with a space.
1854 $to =~ s/\s+$//; 1854 $to =~ s/\s+$//;
1855 # '*'s should not have spaces between. 1855 # '*'s should not have spaces between.
1856 while ($to =~ s/\*\s+\*/\*\*/) { 1856 while ($to =~ s/\*\s+\*/\*\*/) {
1857 } 1857 }
1858 # Modifiers should have spaces. 1858 # Modifiers should have spaces.
1859 $to =~ s/(\b$Modifier$)/$1 /; 1859 $to =~ s/(\b$Modifier$)/$1 /;
1860 1860
1861 #print "from<$from> to<$to> ident<$ident>\n"; 1861 #print "from<$from> to<$to> ident<$ident>\n";
1862 if ($from ne $to && $ident !~ /^$Modifier$/) { 1862 if ($from ne $to && $ident !~ /^$Modifier$/) {
1863 ERROR("\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr); 1863 ERROR("\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr);
1864 } 1864 }
1865 } 1865 }
1866 1866
1867 # # no BUG() or BUG_ON() 1867 # # no BUG() or BUG_ON()
1868 # if ($line =~ /\b(BUG|BUG_ON)\b/) { 1868 # if ($line =~ /\b(BUG|BUG_ON)\b/) {
1869 # print "Try to use WARN_ON & Recovery code rather than BUG() or BUG_ON()\n"; 1869 # print "Try to use WARN_ON & Recovery code rather than BUG() or BUG_ON()\n";
1870 # print "$herecurr"; 1870 # print "$herecurr";
1871 # $clean = 0; 1871 # $clean = 0;
1872 # } 1872 # }
1873 1873
1874 if ($line =~ /\bLINUX_VERSION_CODE\b/) { 1874 if ($line =~ /\bLINUX_VERSION_CODE\b/) {
1875 WARN("LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); 1875 WARN("LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr);
1876 } 1876 }
1877 1877
1878 # printk should use KERN_* levels. Note that follow on printk's on the 1878 # printk should use KERN_* levels. Note that follow on printk's on the
1879 # same line do not need a level, so we use the current block context 1879 # same line do not need a level, so we use the current block context
1880 # to try and find and validate the current printk. In summary the current 1880 # to try and find and validate the current printk. In summary the current
1881 # printk includes all preceeding printk's which have no newline on the end. 1881 # printk includes all preceeding printk's which have no newline on the end.
1882 # we assume the first bad printk is the one to report. 1882 # we assume the first bad printk is the one to report.
1883 if ($line =~ /\bprintk\((?!KERN_)\s*"/) { 1883 if ($line =~ /\bprintk\((?!KERN_)\s*"/) {
1884 my $ok = 0; 1884 my $ok = 0;
1885 for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { 1885 for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) {
1886 #print "CHECK<$lines[$ln - 1]\n"; 1886 #print "CHECK<$lines[$ln - 1]\n";
1887 # we have a preceeding printk if it ends 1887 # we have a preceeding printk if it ends
1888 # with "\n" ignore it, else it is to blame 1888 # with "\n" ignore it, else it is to blame
1889 if ($lines[$ln - 1] =~ m{\bprintk\(}) { 1889 if ($lines[$ln - 1] =~ m{\bprintk\(}) {
1890 if ($rawlines[$ln - 1] !~ m{\\n"}) { 1890 if ($rawlines[$ln - 1] !~ m{\\n"}) {
1891 $ok = 1; 1891 $ok = 1;
1892 } 1892 }
1893 last; 1893 last;
1894 } 1894 }
1895 } 1895 }
1896 if ($ok == 0) { 1896 if ($ok == 0) {
1897 WARN("printk() should include KERN_ facility level\n" . $herecurr); 1897 WARN("printk() should include KERN_ facility level\n" . $herecurr);
1898 } 1898 }
1899 } 1899 }
1900 1900
1901 # function brace can't be on same line, except for #defines of do while, 1901 # function brace can't be on same line, except for #defines of do while,
1902 # or if closed on same line 1902 # or if closed on same line
1903 if (($line=~/$Type\s*$Ident\(.*\).*\s{/) and 1903 if (($line=~/$Type\s*$Ident\(.*\).*\s{/) and
1904 !($line=~/\#\s*define.*do\s{/) and !($line=~/}/)) { 1904 !($line=~/\#\s*define.*do\s{/) and !($line=~/}/)) {
1905 ERROR("open brace '{' following function declarations go on the next line\n" . $herecurr); 1905 ERROR("open brace '{' following function declarations go on the next line\n" . $herecurr);
1906 } 1906 }
1907 1907
1908 # missing space after union or struct definition
1909 if ($rawline =~ /^\+\s*(union|struct)\s+$Ident[=\{]/) {
1910 WARN("Missing space after struct or union definition\n" . $herecurr);
1911 }
1912
1913 # missing space after enum definition
1914 if ($rawline =~ /^\+\s*enum\{/) {
1915 WARN("Missing space after enum definition\n" . $herecurr);
1916 }
1917
1918 # open braces for enum, union and struct go on the same line. 1908 # open braces for enum, union and struct go on the same line.
1919 if ($line =~ /^.\s*{/ && 1909 if ($line =~ /^.\s*{/ &&
1920 $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 1910 $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
1921 ERROR("open brace '{' following $1 go on the same line\n" . $hereprev); 1911 ERROR("open brace '{' following $1 go on the same line\n" . $hereprev);
1912 }
1913
1914 # missing space after union, struct or enum definition
1915 if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?(?:\s+$Ident)?[=\{]/) {
1916 WARN("missing space after $1 definition\n" . $herecurr);
1922 } 1917 }
1923 1918
1924 # check for spacing round square brackets; allowed: 1919 # check for spacing round square brackets; allowed:
1925 # 1. with a type on the left -- int [] a; 1920 # 1. with a type on the left -- int [] a;
1926 # 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 1921 # 2. at the beginning of a line for slice initialisers -- [0...10] = 5,
1927 # 3. inside a curly brace -- = { [0...10] = 5 } 1922 # 3. inside a curly brace -- = { [0...10] = 5 }
1928 while ($line =~ /(.*?\s)\[/g) { 1923 while ($line =~ /(.*?\s)\[/g) {
1929 my ($where, $prefix) = ($-[1], $1); 1924 my ($where, $prefix) = ($-[1], $1);
1930 if ($prefix !~ /$Type\s+$/ && 1925 if ($prefix !~ /$Type\s+$/ &&
1931 ($where != 0 || $prefix !~ /^.\s+$/) && 1926 ($where != 0 || $prefix !~ /^.\s+$/) &&
1932 $prefix !~ /{\s+$/) { 1927 $prefix !~ /{\s+$/) {
1933 ERROR("space prohibited before open square bracket '['\n" . $herecurr); 1928 ERROR("space prohibited before open square bracket '['\n" . $herecurr);
1934 } 1929 }
1935 } 1930 }
1936 1931
1937 # check for spaces between functions and their parentheses. 1932 # check for spaces between functions and their parentheses.
1938 while ($line =~ /($Ident)\s+\(/g) { 1933 while ($line =~ /($Ident)\s+\(/g) {
1939 my $name = $1; 1934 my $name = $1;
1940 my $ctx_before = substr($line, 0, $-[1]); 1935 my $ctx_before = substr($line, 0, $-[1]);
1941 my $ctx = "$ctx_before$name"; 1936 my $ctx = "$ctx_before$name";
1942 1937
1943 # Ignore those directives where spaces _are_ permitted. 1938 # Ignore those directives where spaces _are_ permitted.
1944 if ($name =~ /^(?: 1939 if ($name =~ /^(?:
1945 if|for|while|switch|return|case| 1940 if|for|while|switch|return|case|
1946 volatile|__volatile__| 1941 volatile|__volatile__|
1947 __attribute__|format|__extension__| 1942 __attribute__|format|__extension__|
1948 asm|__asm__)$/x) 1943 asm|__asm__)$/x)
1949 { 1944 {
1950 1945
1951 # cpp #define statements have non-optional spaces, ie 1946 # cpp #define statements have non-optional spaces, ie
1952 # if there is a space between the name and the open 1947 # if there is a space between the name and the open
1953 # parenthesis it is simply not a parameter group. 1948 # parenthesis it is simply not a parameter group.
1954 } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 1949 } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) {
1955 1950
1956 # cpp #elif statement condition may start with a ( 1951 # cpp #elif statement condition may start with a (
1957 } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 1952 } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) {
1958 1953
1959 # If this whole things ends with a type its most 1954 # If this whole things ends with a type its most
1960 # likely a typedef for a function. 1955 # likely a typedef for a function.
1961 } elsif ($ctx =~ /$Type$/) { 1956 } elsif ($ctx =~ /$Type$/) {
1962 1957
1963 } else { 1958 } else {
1964 WARN("space prohibited between function name and open parenthesis '('\n" . $herecurr); 1959 WARN("space prohibited between function name and open parenthesis '('\n" . $herecurr);
1965 } 1960 }
1966 } 1961 }
1967 # Check operator spacing. 1962 # Check operator spacing.
1968 if (!($line=~/\#\s*include/)) { 1963 if (!($line=~/\#\s*include/)) {
1969 my $ops = qr{ 1964 my $ops = qr{
1970 <<=|>>=|<=|>=|==|!=| 1965 <<=|>>=|<=|>=|==|!=|
1971 \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 1966 \+=|-=|\*=|\/=|%=|\^=|\|=|&=|
1972 =>|->|<<|>>|<|>|=|!|~| 1967 =>|->|<<|>>|<|>|=|!|~|
1973 &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 1968 &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
1974 \?|: 1969 \?|:
1975 }x; 1970 }x;
1976 my @elements = split(/($ops|;)/, $opline); 1971 my @elements = split(/($ops|;)/, $opline);
1977 my $off = 0; 1972 my $off = 0;
1978 1973
1979 my $blank = copy_spacing($opline); 1974 my $blank = copy_spacing($opline);
1980 1975
1981 for (my $n = 0; $n < $#elements; $n += 2) { 1976 for (my $n = 0; $n < $#elements; $n += 2) {
1982 $off += length($elements[$n]); 1977 $off += length($elements[$n]);
1983 1978
1984 # Pick up the preceeding and succeeding characters. 1979 # Pick up the preceeding and succeeding characters.
1985 my $ca = substr($opline, 0, $off); 1980 my $ca = substr($opline, 0, $off);
1986 my $cc = ''; 1981 my $cc = '';
1987 if (length($opline) >= ($off + length($elements[$n + 1]))) { 1982 if (length($opline) >= ($off + length($elements[$n + 1]))) {
1988 $cc = substr($opline, $off + length($elements[$n + 1])); 1983 $cc = substr($opline, $off + length($elements[$n + 1]));
1989 } 1984 }
1990 my $cb = "$ca$;$cc"; 1985 my $cb = "$ca$;$cc";
1991 1986
1992 my $a = ''; 1987 my $a = '';
1993 $a = 'V' if ($elements[$n] ne ''); 1988 $a = 'V' if ($elements[$n] ne '');
1994 $a = 'W' if ($elements[$n] =~ /\s$/); 1989 $a = 'W' if ($elements[$n] =~ /\s$/);
1995 $a = 'C' if ($elements[$n] =~ /$;$/); 1990 $a = 'C' if ($elements[$n] =~ /$;$/);
1996 $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 1991 $a = 'B' if ($elements[$n] =~ /(\[|\()$/);
1997 $a = 'O' if ($elements[$n] eq ''); 1992 $a = 'O' if ($elements[$n] eq '');
1998 $a = 'E' if ($ca =~ /^\s*$/); 1993 $a = 'E' if ($ca =~ /^\s*$/);
1999 1994
2000 my $op = $elements[$n + 1]; 1995 my $op = $elements[$n + 1];
2001 1996
2002 my $c = ''; 1997 my $c = '';
2003 if (defined $elements[$n + 2]) { 1998 if (defined $elements[$n + 2]) {
2004 $c = 'V' if ($elements[$n + 2] ne ''); 1999 $c = 'V' if ($elements[$n + 2] ne '');
2005 $c = 'W' if ($elements[$n + 2] =~ /^\s/); 2000 $c = 'W' if ($elements[$n + 2] =~ /^\s/);
2006 $c = 'C' if ($elements[$n + 2] =~ /^$;/); 2001 $c = 'C' if ($elements[$n + 2] =~ /^$;/);
2007 $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 2002 $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
2008 $c = 'O' if ($elements[$n + 2] eq ''); 2003 $c = 'O' if ($elements[$n + 2] eq '');
2009 $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 2004 $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
2010 } else { 2005 } else {
2011 $c = 'E'; 2006 $c = 'E';
2012 } 2007 }
2013 2008
2014 my $ctx = "${a}x${c}"; 2009 my $ctx = "${a}x${c}";
2015 2010
2016 my $at = "(ctx:$ctx)"; 2011 my $at = "(ctx:$ctx)";
2017 2012
2018 my $ptr = substr($blank, 0, $off) . "^"; 2013 my $ptr = substr($blank, 0, $off) . "^";
2019 my $hereptr = "$hereline$ptr\n"; 2014 my $hereptr = "$hereline$ptr\n";
2020 2015
2021 # Pull out the value of this operator. 2016 # Pull out the value of this operator.
2022 my $op_type = substr($curr_values, $off + 1, 1); 2017 my $op_type = substr($curr_values, $off + 1, 1);
2023 2018
2024 # Get the full operator variant. 2019 # Get the full operator variant.
2025 my $opv = $op . substr($curr_vars, $off, 1); 2020 my $opv = $op . substr($curr_vars, $off, 1);
2026 2021
2027 # Ignore operators passed as parameters. 2022 # Ignore operators passed as parameters.
2028 if ($op_type ne 'V' && 2023 if ($op_type ne 'V' &&
2029 $ca =~ /\s$/ && $cc =~ /^\s*,/) { 2024 $ca =~ /\s$/ && $cc =~ /^\s*,/) {
2030 2025
2031 # # Ignore comments 2026 # # Ignore comments
2032 # } elsif ($op =~ /^$;+$/) { 2027 # } elsif ($op =~ /^$;+$/) {
2033 2028
2034 # ; should have either the end of line or a space or \ after it 2029 # ; should have either the end of line or a space or \ after it
2035 } elsif ($op eq ';') { 2030 } elsif ($op eq ';') {
2036 if ($ctx !~ /.x[WEBC]/ && 2031 if ($ctx !~ /.x[WEBC]/ &&
2037 $cc !~ /^\\/ && $cc !~ /^;/) { 2032 $cc !~ /^\\/ && $cc !~ /^;/) {
2038 ERROR("space required after that '$op' $at\n" . $hereptr); 2033 ERROR("space required after that '$op' $at\n" . $hereptr);
2039 } 2034 }
2040 2035
2041 # // is a comment 2036 # // is a comment
2042 } elsif ($op eq '//') { 2037 } elsif ($op eq '//') {
2043 2038
2044 # No spaces for: 2039 # No spaces for:
2045 # -> 2040 # ->
2046 # : when part of a bitfield 2041 # : when part of a bitfield
2047 } elsif ($op eq '->' || $opv eq ':B') { 2042 } elsif ($op eq '->' || $opv eq ':B') {
2048 if ($ctx =~ /Wx.|.xW/) { 2043 if ($ctx =~ /Wx.|.xW/) {
2049 ERROR("spaces prohibited around that '$op' $at\n" . $hereptr); 2044 ERROR("spaces prohibited around that '$op' $at\n" . $hereptr);
2050 } 2045 }
2051 2046
2052 # , must have a space on the right. 2047 # , must have a space on the right.
2053 } elsif ($op eq ',') { 2048 } elsif ($op eq ',') {
2054 if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { 2049 if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
2055 ERROR("space required after that '$op' $at\n" . $hereptr); 2050 ERROR("space required after that '$op' $at\n" . $hereptr);
2056 } 2051 }
2057 2052
2058 # '*' as part of a type definition -- reported already. 2053 # '*' as part of a type definition -- reported already.
2059 } elsif ($opv eq '*_') { 2054 } elsif ($opv eq '*_') {
2060 #warn "'*' is part of type\n"; 2055 #warn "'*' is part of type\n";
2061 2056
2062 # unary operators should have a space before and 2057 # unary operators should have a space before and
2063 # none after. May be left adjacent to another 2058 # none after. May be left adjacent to another
2064 # unary operator, or a cast 2059 # unary operator, or a cast
2065 } elsif ($op eq '!' || $op eq '~' || 2060 } elsif ($op eq '!' || $op eq '~' ||
2066 $opv eq '*U' || $opv eq '-U' || 2061 $opv eq '*U' || $opv eq '-U' ||
2067 $opv eq '&U' || $opv eq '&&U') { 2062 $opv eq '&U' || $opv eq '&&U') {
2068 if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 2063 if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
2069 ERROR("space required before that '$op' $at\n" . $hereptr); 2064 ERROR("space required before that '$op' $at\n" . $hereptr);
2070 } 2065 }
2071 if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 2066 if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
2072 # A unary '*' may be const 2067 # A unary '*' may be const
2073 2068
2074 } elsif ($ctx =~ /.xW/) { 2069 } elsif ($ctx =~ /.xW/) {
2075 ERROR("space prohibited after that '$op' $at\n" . $hereptr); 2070 ERROR("space prohibited after that '$op' $at\n" . $hereptr);
2076 } 2071 }
2077 2072
2078 # unary ++ and unary -- are allowed no space on one side. 2073 # unary ++ and unary -- are allowed no space on one side.
2079 } elsif ($op eq '++' or $op eq '--') { 2074 } elsif ($op eq '++' or $op eq '--') {
2080 if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 2075 if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
2081 ERROR("space required one side of that '$op' $at\n" . $hereptr); 2076 ERROR("space required one side of that '$op' $at\n" . $hereptr);
2082 } 2077 }
2083 if ($ctx =~ /Wx[BE]/ || 2078 if ($ctx =~ /Wx[BE]/ ||
2084 ($ctx =~ /Wx./ && $cc =~ /^;/)) { 2079 ($ctx =~ /Wx./ && $cc =~ /^;/)) {
2085 ERROR("space prohibited before that '$op' $at\n" . $hereptr); 2080 ERROR("space prohibited before that '$op' $at\n" . $hereptr);
2086 } 2081 }
2087 if ($ctx =~ /ExW/) { 2082 if ($ctx =~ /ExW/) {
2088 ERROR("space prohibited after that '$op' $at\n" . $hereptr); 2083 ERROR("space prohibited after that '$op' $at\n" . $hereptr);
2089 } 2084 }
2090 2085
2091 2086
2092 # << and >> may either have or not have spaces both sides 2087 # << and >> may either have or not have spaces both sides
2093 } elsif ($op eq '<<' or $op eq '>>' or 2088 } elsif ($op eq '<<' or $op eq '>>' or
2094 $op eq '&' or $op eq '^' or $op eq '|' or 2089 $op eq '&' or $op eq '^' or $op eq '|' or
2095 $op eq '+' or $op eq '-' or 2090 $op eq '+' or $op eq '-' or
2096 $op eq '*' or $op eq '/' or 2091 $op eq '*' or $op eq '/' or
2097 $op eq '%') 2092 $op eq '%')
2098 { 2093 {
2099 if ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { 2094 if ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
2100 ERROR("need consistent spacing around '$op' $at\n" . 2095 ERROR("need consistent spacing around '$op' $at\n" .
2101 $hereptr); 2096 $hereptr);
2102 } 2097 }
2103 2098
2104 # A colon needs no spaces before when it is 2099 # A colon needs no spaces before when it is
2105 # terminating a case value or a label. 2100 # terminating a case value or a label.
2106 } elsif ($opv eq ':C' || $opv eq ':L') { 2101 } elsif ($opv eq ':C' || $opv eq ':L') {
2107 if ($ctx =~ /Wx./) { 2102 if ($ctx =~ /Wx./) {
2108 ERROR("space prohibited before that '$op' $at\n" . $hereptr); 2103 ERROR("space prohibited before that '$op' $at\n" . $hereptr);
2109 } 2104 }
2110 2105
2111 # All the others need spaces both sides. 2106 # All the others need spaces both sides.
2112 } elsif ($ctx !~ /[EWC]x[CWE]/) { 2107 } elsif ($ctx !~ /[EWC]x[CWE]/) {
2113 my $ok = 0; 2108 my $ok = 0;
2114 2109
2115 # Ignore email addresses <foo@bar> 2110 # Ignore email addresses <foo@bar>
2116 if (($op eq '<' && 2111 if (($op eq '<' &&
2117 $cc =~ /^\S+\@\S+>/) || 2112 $cc =~ /^\S+\@\S+>/) ||
2118 ($op eq '>' && 2113 ($op eq '>' &&
2119 $ca =~ /<\S+\@\S+$/)) 2114 $ca =~ /<\S+\@\S+$/))
2120 { 2115 {
2121 $ok = 1; 2116 $ok = 1;
2122 } 2117 }
2123 2118
2124 # Ignore ?: 2119 # Ignore ?:
2125 if (($opv eq ':O' && $ca =~ /\?$/) || 2120 if (($opv eq ':O' && $ca =~ /\?$/) ||
2126 ($op eq '?' && $cc =~ /^:/)) { 2121 ($op eq '?' && $cc =~ /^:/)) {
2127 $ok = 1; 2122 $ok = 1;
2128 } 2123 }
2129 2124
2130 if ($ok == 0) { 2125 if ($ok == 0) {
2131 ERROR("spaces required around that '$op' $at\n" . $hereptr); 2126 ERROR("spaces required around that '$op' $at\n" . $hereptr);
2132 } 2127 }
2133 } 2128 }
2134 $off += length($elements[$n + 1]); 2129 $off += length($elements[$n + 1]);
2135 } 2130 }
2136 } 2131 }
2137 2132
2138 # check for multiple assignments 2133 # check for multiple assignments
2139 if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 2134 if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
2140 CHK("multiple assignments should be avoided\n" . $herecurr); 2135 CHK("multiple assignments should be avoided\n" . $herecurr);
2141 } 2136 }
2142 2137
2143 ## # check for multiple declarations, allowing for a function declaration 2138 ## # check for multiple declarations, allowing for a function declaration
2144 ## # continuation. 2139 ## # continuation.
2145 ## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 2140 ## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
2146 ## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 2141 ## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
2147 ## 2142 ##
2148 ## # Remove any bracketed sections to ensure we do not 2143 ## # Remove any bracketed sections to ensure we do not
2149 ## # falsly report the parameters of functions. 2144 ## # falsly report the parameters of functions.
2150 ## my $ln = $line; 2145 ## my $ln = $line;
2151 ## while ($ln =~ s/\([^\(\)]*\)//g) { 2146 ## while ($ln =~ s/\([^\(\)]*\)//g) {
2152 ## } 2147 ## }
2153 ## if ($ln =~ /,/) { 2148 ## if ($ln =~ /,/) {
2154 ## WARN("declaring multiple variables together should be avoided\n" . $herecurr); 2149 ## WARN("declaring multiple variables together should be avoided\n" . $herecurr);
2155 ## } 2150 ## }
2156 ## } 2151 ## }
2157 2152
2158 #need space before brace following if, while, etc 2153 #need space before brace following if, while, etc
2159 if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) || 2154 if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) ||
2160 $line =~ /do{/) { 2155 $line =~ /do{/) {
2161 ERROR("space required before the open brace '{'\n" . $herecurr); 2156 ERROR("space required before the open brace '{'\n" . $herecurr);
2162 } 2157 }
2163 2158
2164 # closing brace should have a space following it when it has anything 2159 # closing brace should have a space following it when it has anything
2165 # on the line 2160 # on the line
2166 if ($line =~ /}(?!(?:,|;|\)))\S/) { 2161 if ($line =~ /}(?!(?:,|;|\)))\S/) {
2167 ERROR("space required after that close brace '}'\n" . $herecurr); 2162 ERROR("space required after that close brace '}'\n" . $herecurr);
2168 } 2163 }
2169 2164
2170 # check spacing on square brackets 2165 # check spacing on square brackets
2171 if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 2166 if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
2172 ERROR("space prohibited after that open square bracket '['\n" . $herecurr); 2167 ERROR("space prohibited after that open square bracket '['\n" . $herecurr);
2173 } 2168 }
2174 if ($line =~ /\s\]/) { 2169 if ($line =~ /\s\]/) {
2175 ERROR("space prohibited before that close square bracket ']'\n" . $herecurr); 2170 ERROR("space prohibited before that close square bracket ']'\n" . $herecurr);
2176 } 2171 }
2177 2172
2178 # check spacing on parentheses 2173 # check spacing on parentheses
2179 if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 2174 if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
2180 $line !~ /for\s*\(\s+;/) { 2175 $line !~ /for\s*\(\s+;/) {
2181 ERROR("space prohibited after that open parenthesis '('\n" . $herecurr); 2176 ERROR("space prohibited after that open parenthesis '('\n" . $herecurr);
2182 } 2177 }
2183 if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 2178 if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
2184 $line !~ /for\s*\(.*;\s+\)/ && 2179 $line !~ /for\s*\(.*;\s+\)/ &&
2185 $line !~ /:\s+\)/) { 2180 $line !~ /:\s+\)/) {
2186 ERROR("space prohibited before that close parenthesis ')'\n" . $herecurr); 2181 ERROR("space prohibited before that close parenthesis ')'\n" . $herecurr);
2187 } 2182 }
2188 2183
2189 #goto labels aren't indented, allow a single space however 2184 #goto labels aren't indented, allow a single space however
2190 if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and 2185 if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
2191 !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { 2186 !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
2192 WARN("labels should not be indented\n" . $herecurr); 2187 WARN("labels should not be indented\n" . $herecurr);
2193 } 2188 }
2194 2189
2195 # Return is not a function. 2190 # Return is not a function.
2196 if (defined($stat) && $stat =~ /^.\s*return(\s*)(\(.*);/s) { 2191 if (defined($stat) && $stat =~ /^.\s*return(\s*)(\(.*);/s) {
2197 my $spacing = $1; 2192 my $spacing = $1;
2198 my $value = $2; 2193 my $value = $2;
2199 2194
2200 # Flatten any parentheses 2195 # Flatten any parentheses
2201 $value =~ s/\(/ \(/g; 2196 $value =~ s/\(/ \(/g;
2202 $value =~ s/\)/\) /g; 2197 $value =~ s/\)/\) /g;
2203 while ($value =~ s/\[[^\{\}]*\]/1/ || 2198 while ($value =~ s/\[[^\{\}]*\]/1/ ||
2204 $value !~ /(?:$Ident|-?$Constant)\s* 2199 $value !~ /(?:$Ident|-?$Constant)\s*
2205 $Compare\s* 2200 $Compare\s*
2206 (?:$Ident|-?$Constant)/x && 2201 (?:$Ident|-?$Constant)/x &&
2207 $value =~ s/\([^\(\)]*\)/1/) { 2202 $value =~ s/\([^\(\)]*\)/1/) {
2208 } 2203 }
2209 #print "value<$value>\n"; 2204 #print "value<$value>\n";
2210 if ($value =~ /^\s*(?:$Ident|-?$Constant)\s*$/) { 2205 if ($value =~ /^\s*(?:$Ident|-?$Constant)\s*$/) {
2211 ERROR("return is not a function, parentheses are not required\n" . $herecurr); 2206 ERROR("return is not a function, parentheses are not required\n" . $herecurr);
2212 2207
2213 } elsif ($spacing !~ /\s+/) { 2208 } elsif ($spacing !~ /\s+/) {
2214 ERROR("space required before the open parenthesis '('\n" . $herecurr); 2209 ERROR("space required before the open parenthesis '('\n" . $herecurr);
2215 } 2210 }
2216 } 2211 }
2217 # Return of what appears to be an errno should normally be -'ve 2212 # Return of what appears to be an errno should normally be -'ve
2218 if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) { 2213 if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) {
2219 my $name = $1; 2214 my $name = $1;
2220 if ($name ne 'EOF' && $name ne 'ERROR') { 2215 if ($name ne 'EOF' && $name ne 'ERROR') {
2221 WARN("return of an errno should typically be -ve (return -$1)\n" . $herecurr); 2216 WARN("return of an errno should typically be -ve (return -$1)\n" . $herecurr);
2222 } 2217 }
2223 } 2218 }
2224 2219
2225 # Need a space before open parenthesis after if, while etc 2220 # Need a space before open parenthesis after if, while etc
2226 if ($line=~/\b(if|while|for|switch)\(/) { 2221 if ($line=~/\b(if|while|for|switch)\(/) {
2227 ERROR("space required before the open parenthesis '('\n" . $herecurr); 2222 ERROR("space required before the open parenthesis '('\n" . $herecurr);
2228 } 2223 }
2229 2224
2230 # Check for illegal assignment in if conditional -- and check for trailing 2225 # Check for illegal assignment in if conditional -- and check for trailing
2231 # statements after the conditional. 2226 # statements after the conditional.
2232 if ($line =~ /do\s*(?!{)/) { 2227 if ($line =~ /do\s*(?!{)/) {
2233 my ($stat_next) = ctx_statement_block($line_nr_next, 2228 my ($stat_next) = ctx_statement_block($line_nr_next,
2234 $remain_next, $off_next); 2229 $remain_next, $off_next);
2235 $stat_next =~ s/\n./\n /g; 2230 $stat_next =~ s/\n./\n /g;
2236 ##print "stat<$stat> stat_next<$stat_next>\n"; 2231 ##print "stat<$stat> stat_next<$stat_next>\n";
2237 2232
2238 if ($stat_next =~ /^\s*while\b/) { 2233 if ($stat_next =~ /^\s*while\b/) {
2239 # If the statement carries leading newlines, 2234 # If the statement carries leading newlines,
2240 # then count those as offsets. 2235 # then count those as offsets.
2241 my ($whitespace) = 2236 my ($whitespace) =
2242 ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 2237 ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
2243 my $offset = 2238 my $offset =
2244 statement_rawlines($whitespace) - 1; 2239 statement_rawlines($whitespace) - 1;
2245 2240
2246 $suppress_whiletrailers{$line_nr_next + 2241 $suppress_whiletrailers{$line_nr_next +
2247 $offset} = 1; 2242 $offset} = 1;
2248 } 2243 }
2249 } 2244 }
2250 if (!defined $suppress_whiletrailers{$linenr} && 2245 if (!defined $suppress_whiletrailers{$linenr} &&
2251 $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 2246 $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
2252 my ($s, $c) = ($stat, $cond); 2247 my ($s, $c) = ($stat, $cond);
2253 2248
2254 if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 2249 if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
2255 ERROR("do not use assignment in if condition\n" . $herecurr); 2250 ERROR("do not use assignment in if condition\n" . $herecurr);
2256 } 2251 }
2257 2252
2258 # Find out what is on the end of the line after the 2253 # Find out what is on the end of the line after the
2259 # conditional. 2254 # conditional.
2260 substr($s, 0, length($c), ''); 2255 substr($s, 0, length($c), '');
2261 $s =~ s/\n.*//g; 2256 $s =~ s/\n.*//g;
2262 $s =~ s/$;//g; # Remove any comments 2257 $s =~ s/$;//g; # Remove any comments
2263 if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 2258 if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
2264 $c !~ /}\s*while\s*/) 2259 $c !~ /}\s*while\s*/)
2265 { 2260 {
2266 # Find out how long the conditional actually is. 2261 # Find out how long the conditional actually is.
2267 my @newlines = ($c =~ /\n/gs); 2262 my @newlines = ($c =~ /\n/gs);
2268 my $cond_lines = 1 + $#newlines; 2263 my $cond_lines = 1 + $#newlines;
2269 my $stat_real = ''; 2264 my $stat_real = '';
2270 2265
2271 $stat_real = raw_line($linenr, $cond_lines) 2266 $stat_real = raw_line($linenr, $cond_lines)
2272 . "\n" if ($cond_lines); 2267 . "\n" if ($cond_lines);
2273 if (defined($stat_real) && $cond_lines > 1) { 2268 if (defined($stat_real) && $cond_lines > 1) {
2274 $stat_real = "[...]\n$stat_real"; 2269 $stat_real = "[...]\n$stat_real";
2275 } 2270 }
2276 2271
2277 ERROR("trailing statements should be on next line\n" . $herecurr . $stat_real); 2272 ERROR("trailing statements should be on next line\n" . $herecurr . $stat_real);
2278 } 2273 }
2279 } 2274 }
2280 2275
2281 # Check for bitwise tests written as boolean 2276 # Check for bitwise tests written as boolean
2282 if ($line =~ / 2277 if ($line =~ /
2283 (?: 2278 (?:
2284 (?:\[|\(|\&\&|\|\|) 2279 (?:\[|\(|\&\&|\|\|)
2285 \s*0[xX][0-9]+\s* 2280 \s*0[xX][0-9]+\s*
2286 (?:\&\&|\|\|) 2281 (?:\&\&|\|\|)
2287 | 2282 |
2288 (?:\&\&|\|\|) 2283 (?:\&\&|\|\|)
2289 \s*0[xX][0-9]+\s* 2284 \s*0[xX][0-9]+\s*
2290 (?:\&\&|\|\||\)|\]) 2285 (?:\&\&|\|\||\)|\])
2291 )/x) 2286 )/x)
2292 { 2287 {
2293 WARN("boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 2288 WARN("boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
2294 } 2289 }
2295 2290
2296 # if and else should not have general statements after it 2291 # if and else should not have general statements after it
2297 if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 2292 if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
2298 my $s = $1; 2293 my $s = $1;
2299 $s =~ s/$;//g; # Remove any comments 2294 $s =~ s/$;//g; # Remove any comments
2300 if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 2295 if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
2301 ERROR("trailing statements should be on next line\n" . $herecurr); 2296 ERROR("trailing statements should be on next line\n" . $herecurr);
2302 } 2297 }
2303 } 2298 }
2304 # if should not continue a brace 2299 # if should not continue a brace
2305 if ($line =~ /}\s*if\b/) { 2300 if ($line =~ /}\s*if\b/) {
2306 ERROR("trailing statements should be on next line\n" . 2301 ERROR("trailing statements should be on next line\n" .
2307 $herecurr); 2302 $herecurr);
2308 } 2303 }
2309 # case and default should not have general statements after them 2304 # case and default should not have general statements after them
2310 if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 2305 if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
2311 $line !~ /\G(?: 2306 $line !~ /\G(?:
2312 (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 2307 (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
2313 \s*return\s+ 2308 \s*return\s+
2314 )/xg) 2309 )/xg)
2315 { 2310 {
2316 ERROR("trailing statements should be on next line\n" . $herecurr); 2311 ERROR("trailing statements should be on next line\n" . $herecurr);
2317 } 2312 }
2318 2313
2319 # Check for }<nl>else {, these must be at the same 2314 # Check for }<nl>else {, these must be at the same
2320 # indent level to be relevant to each other. 2315 # indent level to be relevant to each other.
2321 if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and 2316 if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and
2322 $previndent == $indent) { 2317 $previndent == $indent) {
2323 ERROR("else should follow close brace '}'\n" . $hereprev); 2318 ERROR("else should follow close brace '}'\n" . $hereprev);
2324 } 2319 }
2325 2320
2326 if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ and 2321 if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ and
2327 $previndent == $indent) { 2322 $previndent == $indent) {
2328 my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 2323 my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
2329 2324
2330 # Find out what is on the end of the line after the 2325 # Find out what is on the end of the line after the
2331 # conditional. 2326 # conditional.
2332 substr($s, 0, length($c), ''); 2327 substr($s, 0, length($c), '');
2333 $s =~ s/\n.*//g; 2328 $s =~ s/\n.*//g;
2334 2329
2335 if ($s =~ /^\s*;/) { 2330 if ($s =~ /^\s*;/) {
2336 ERROR("while should follow close brace '}'\n" . $hereprev); 2331 ERROR("while should follow close brace '}'\n" . $hereprev);
2337 } 2332 }
2338 } 2333 }
2339 2334
2340 #studly caps, commented out until figure out how to distinguish between use of existing and adding new 2335 #studly caps, commented out until figure out how to distinguish between use of existing and adding new
2341 # if (($line=~/[\w_][a-z\d]+[A-Z]/) and !($line=~/print/)) { 2336 # if (($line=~/[\w_][a-z\d]+[A-Z]/) and !($line=~/print/)) {
2342 # print "No studly caps, use _\n"; 2337 # print "No studly caps, use _\n";
2343 # print "$herecurr"; 2338 # print "$herecurr";
2344 # $clean = 0; 2339 # $clean = 0;
2345 # } 2340 # }
2346 2341
2347 #no spaces allowed after \ in define 2342 #no spaces allowed after \ in define
2348 if ($line=~/\#\s*define.*\\\s$/) { 2343 if ($line=~/\#\s*define.*\\\s$/) {
2349 WARN("Whitepspace after \\ makes next lines useless\n" . $herecurr); 2344 WARN("Whitepspace after \\ makes next lines useless\n" . $herecurr);
2350 } 2345 }
2351 2346
2352 #warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line) 2347 #warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line)
2353 if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { 2348 if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
2354 my $file = "$1.h"; 2349 my $file = "$1.h";
2355 my $checkfile = "include/linux/$file"; 2350 my $checkfile = "include/linux/$file";
2356 if (-f "$root/$checkfile" && 2351 if (-f "$root/$checkfile" &&
2357 $realfile ne $checkfile && 2352 $realfile ne $checkfile &&
2358 $1 !~ /$allowed_asm_includes/) 2353 $1 !~ /$allowed_asm_includes/)
2359 { 2354 {
2360 if ($realfile =~ m{^arch/}) { 2355 if ($realfile =~ m{^arch/}) {
2361 CHK("Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 2356 CHK("Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
2362 } else { 2357 } else {
2363 WARN("Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 2358 WARN("Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
2364 } 2359 }
2365 } 2360 }
2366 } 2361 }
2367 2362
2368 # multi-statement macros should be enclosed in a do while loop, grab the 2363 # multi-statement macros should be enclosed in a do while loop, grab the
2369 # first statement and ensure its the whole macro if its not enclosed 2364 # first statement and ensure its the whole macro if its not enclosed
2370 # in a known good container 2365 # in a known good container
2371 if ($realfile !~ m@/vmlinux.lds.h$@ && 2366 if ($realfile !~ m@/vmlinux.lds.h$@ &&
2372 $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 2367 $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
2373 my $ln = $linenr; 2368 my $ln = $linenr;
2374 my $cnt = $realcnt; 2369 my $cnt = $realcnt;
2375 my ($off, $dstat, $dcond, $rest); 2370 my ($off, $dstat, $dcond, $rest);
2376 my $ctx = ''; 2371 my $ctx = '';
2377 2372
2378 my $args = defined($1); 2373 my $args = defined($1);
2379 2374
2380 # Find the end of the macro and limit our statement 2375 # Find the end of the macro and limit our statement
2381 # search to that. 2376 # search to that.
2382 while ($cnt > 0 && defined $lines[$ln - 1] && 2377 while ($cnt > 0 && defined $lines[$ln - 1] &&
2383 $lines[$ln - 1] =~ /^(?:-|..*\\$)/) 2378 $lines[$ln - 1] =~ /^(?:-|..*\\$)/)
2384 { 2379 {
2385 $ctx .= $rawlines[$ln - 1] . "\n"; 2380 $ctx .= $rawlines[$ln - 1] . "\n";
2386 $cnt-- if ($lines[$ln - 1] !~ /^-/); 2381 $cnt-- if ($lines[$ln - 1] !~ /^-/);
2387 $ln++; 2382 $ln++;
2388 } 2383 }
2389 $ctx .= $rawlines[$ln - 1]; 2384 $ctx .= $rawlines[$ln - 1];
2390 2385
2391 ($dstat, $dcond, $ln, $cnt, $off) = 2386 ($dstat, $dcond, $ln, $cnt, $off) =
2392 ctx_statement_block($linenr, $ln - $linenr + 1, 0); 2387 ctx_statement_block($linenr, $ln - $linenr + 1, 0);
2393 #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 2388 #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
2394 #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 2389 #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
2395 2390
2396 # Extract the remainder of the define (if any) and 2391 # Extract the remainder of the define (if any) and
2397 # rip off surrounding spaces, and trailing \'s. 2392 # rip off surrounding spaces, and trailing \'s.
2398 $rest = ''; 2393 $rest = '';
2399 while ($off != 0 || ($cnt > 0 && $rest =~ /\\\s*$/)) { 2394 while ($off != 0 || ($cnt > 0 && $rest =~ /\\\s*$/)) {
2400 #print "ADDING cnt<$cnt> $off <" . substr($lines[$ln - 1], $off) . "> rest<$rest>\n"; 2395 #print "ADDING cnt<$cnt> $off <" . substr($lines[$ln - 1], $off) . "> rest<$rest>\n";
2401 if ($off != 0 || $lines[$ln - 1] !~ /^-/) { 2396 if ($off != 0 || $lines[$ln - 1] !~ /^-/) {
2402 $rest .= substr($lines[$ln - 1], $off) . "\n"; 2397 $rest .= substr($lines[$ln - 1], $off) . "\n";
2403 $cnt--; 2398 $cnt--;
2404 } 2399 }
2405 $ln++; 2400 $ln++;
2406 $off = 0; 2401 $off = 0;
2407 } 2402 }
2408 $rest =~ s/\\\n.//g; 2403 $rest =~ s/\\\n.//g;
2409 $rest =~ s/^\s*//s; 2404 $rest =~ s/^\s*//s;
2410 $rest =~ s/\s*$//s; 2405 $rest =~ s/\s*$//s;
2411 2406
2412 # Clean up the original statement. 2407 # Clean up the original statement.
2413 if ($args) { 2408 if ($args) {
2414 substr($dstat, 0, length($dcond), ''); 2409 substr($dstat, 0, length($dcond), '');
2415 } else { 2410 } else {
2416 $dstat =~ s/^.\s*\#\s*define\s+$Ident\s*//; 2411 $dstat =~ s/^.\s*\#\s*define\s+$Ident\s*//;
2417 } 2412 }
2418 $dstat =~ s/$;//g; 2413 $dstat =~ s/$;//g;
2419 $dstat =~ s/\\\n.//g; 2414 $dstat =~ s/\\\n.//g;
2420 $dstat =~ s/^\s*//s; 2415 $dstat =~ s/^\s*//s;
2421 $dstat =~ s/\s*$//s; 2416 $dstat =~ s/\s*$//s;
2422 2417
2423 # Flatten any parentheses and braces 2418 # Flatten any parentheses and braces
2424 while ($dstat =~ s/\([^\(\)]*\)/1/ || 2419 while ($dstat =~ s/\([^\(\)]*\)/1/ ||
2425 $dstat =~ s/\{[^\{\}]*\}/1/ || 2420 $dstat =~ s/\{[^\{\}]*\}/1/ ||
2426 $dstat =~ s/\[[^\{\}]*\]/1/) 2421 $dstat =~ s/\[[^\{\}]*\]/1/)
2427 { 2422 {
2428 } 2423 }
2429 2424
2430 my $exceptions = qr{ 2425 my $exceptions = qr{
2431 $Declare| 2426 $Declare|
2432 module_param_named| 2427 module_param_named|
2433 MODULE_PARAM_DESC| 2428 MODULE_PARAM_DESC|
2434 DECLARE_PER_CPU| 2429 DECLARE_PER_CPU|
2435 DEFINE_PER_CPU| 2430 DEFINE_PER_CPU|
2436 __typeof__\(| 2431 __typeof__\(|
2437 union| 2432 union|
2438 struct| 2433 struct|
2439 \.$Ident\s*=\s*| 2434 \.$Ident\s*=\s*|
2440 ^\"|\"$ 2435 ^\"|\"$
2441 }x; 2436 }x;
2442 #print "REST<$rest> dstat<$dstat>\n"; 2437 #print "REST<$rest> dstat<$dstat>\n";
2443 if ($rest ne '') { 2438 if ($rest ne '') {
2444 if ($rest !~ /while\s*\(/ && 2439 if ($rest !~ /while\s*\(/ &&
2445 $dstat !~ /$exceptions/) 2440 $dstat !~ /$exceptions/)
2446 { 2441 {
2447 ERROR("Macros with multiple statements should be enclosed in a do - while loop\n" . "$here\n$ctx\n"); 2442 ERROR("Macros with multiple statements should be enclosed in a do - while loop\n" . "$here\n$ctx\n");
2448 } 2443 }
2449 2444
2450 } elsif ($ctx !~ /;/) { 2445 } elsif ($ctx !~ /;/) {
2451 if ($dstat ne '' && 2446 if ($dstat ne '' &&
2452 $dstat !~ /^(?:$Ident|-?$Constant)$/ && 2447 $dstat !~ /^(?:$Ident|-?$Constant)$/ &&
2453 $dstat !~ /$exceptions/ && 2448 $dstat !~ /$exceptions/ &&
2454 $dstat !~ /^\.$Ident\s*=/ && 2449 $dstat !~ /^\.$Ident\s*=/ &&
2455 $dstat =~ /$Operators/) 2450 $dstat =~ /$Operators/)
2456 { 2451 {
2457 ERROR("Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n"); 2452 ERROR("Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n");
2458 } 2453 }
2459 } 2454 }
2460 } 2455 }
2461 2456
2462 # make sure symbols are always wrapped with VMLINUX_SYMBOL() ... 2457 # make sure symbols are always wrapped with VMLINUX_SYMBOL() ...
2463 # all assignments may have only one of the following with an assignment: 2458 # all assignments may have only one of the following with an assignment:
2464 # . 2459 # .
2465 # ALIGN(...) 2460 # ALIGN(...)
2466 # VMLINUX_SYMBOL(...) 2461 # VMLINUX_SYMBOL(...)
2467 if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) { 2462 if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) {
2468 WARN("vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr); 2463 WARN("vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr);
2469 } 2464 }
2470 2465
2471 # check for redundant bracing round if etc 2466 # check for redundant bracing round if etc
2472 if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 2467 if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
2473 my ($level, $endln, @chunks) = 2468 my ($level, $endln, @chunks) =
2474 ctx_statement_full($linenr, $realcnt, 1); 2469 ctx_statement_full($linenr, $realcnt, 1);
2475 #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 2470 #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
2476 #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; 2471 #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
2477 if ($#chunks > 0 && $level == 0) { 2472 if ($#chunks > 0 && $level == 0) {
2478 my $allowed = 0; 2473 my $allowed = 0;
2479 my $seen = 0; 2474 my $seen = 0;
2480 my $herectx = $here . "\n"; 2475 my $herectx = $here . "\n";
2481 my $ln = $linenr - 1; 2476 my $ln = $linenr - 1;
2482 for my $chunk (@chunks) { 2477 for my $chunk (@chunks) {
2483 my ($cond, $block) = @{$chunk}; 2478 my ($cond, $block) = @{$chunk};
2484 2479
2485 # If the condition carries leading newlines, then count those as offsets. 2480 # If the condition carries leading newlines, then count those as offsets.
2486 my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 2481 my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
2487 my $offset = statement_rawlines($whitespace) - 1; 2482 my $offset = statement_rawlines($whitespace) - 1;
2488 2483
2489 #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 2484 #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
2490 2485
2491 # We have looked at and allowed this specific line. 2486 # We have looked at and allowed this specific line.
2492 $suppress_ifbraces{$ln + $offset} = 1; 2487 $suppress_ifbraces{$ln + $offset} = 1;
2493 2488
2494 $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 2489 $herectx .= "$rawlines[$ln + $offset]\n[...]\n";
2495 $ln += statement_rawlines($block) - 1; 2490 $ln += statement_rawlines($block) - 1;
2496 2491
2497 substr($block, 0, length($cond), ''); 2492 substr($block, 0, length($cond), '');
2498 2493
2499 $seen++ if ($block =~ /^\s*{/); 2494 $seen++ if ($block =~ /^\s*{/);
2500 2495
2501 #print "cond<$cond> block<$block> allowed<$allowed>\n"; 2496 #print "cond<$cond> block<$block> allowed<$allowed>\n";
2502 if (statement_lines($cond) > 1) { 2497 if (statement_lines($cond) > 1) {
2503 #print "APW: ALLOWED: cond<$cond>\n"; 2498 #print "APW: ALLOWED: cond<$cond>\n";
2504 $allowed = 1; 2499 $allowed = 1;
2505 } 2500 }
2506 if ($block =~/\b(?:if|for|while)\b/) { 2501 if ($block =~/\b(?:if|for|while)\b/) {
2507 #print "APW: ALLOWED: block<$block>\n"; 2502 #print "APW: ALLOWED: block<$block>\n";
2508 $allowed = 1; 2503 $allowed = 1;
2509 } 2504 }
2510 if (statement_block_size($block) > 1) { 2505 if (statement_block_size($block) > 1) {
2511 #print "APW: ALLOWED: lines block<$block>\n"; 2506 #print "APW: ALLOWED: lines block<$block>\n";
2512 $allowed = 1; 2507 $allowed = 1;
2513 } 2508 }
2514 } 2509 }
2515 if ($seen && !$allowed) { 2510 if ($seen && !$allowed) {
2516 WARN("braces {} are not necessary for any arm of this statement\n" . $herectx); 2511 WARN("braces {} are not necessary for any arm of this statement\n" . $herectx);
2517 } 2512 }
2518 } 2513 }
2519 } 2514 }
2520 if (!defined $suppress_ifbraces{$linenr - 1} && 2515 if (!defined $suppress_ifbraces{$linenr - 1} &&
2521 $line =~ /\b(if|while|for|else)\b/) { 2516 $line =~ /\b(if|while|for|else)\b/) {
2522 my $allowed = 0; 2517 my $allowed = 0;
2523 2518
2524 # Check the pre-context. 2519 # Check the pre-context.
2525 if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 2520 if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
2526 #print "APW: ALLOWED: pre<$1>\n"; 2521 #print "APW: ALLOWED: pre<$1>\n";
2527 $allowed = 1; 2522 $allowed = 1;
2528 } 2523 }
2529 2524
2530 my ($level, $endln, @chunks) = 2525 my ($level, $endln, @chunks) =
2531 ctx_statement_full($linenr, $realcnt, $-[0]); 2526 ctx_statement_full($linenr, $realcnt, $-[0]);
2532 2527
2533 # Check the condition. 2528 # Check the condition.
2534 my ($cond, $block) = @{$chunks[0]}; 2529 my ($cond, $block) = @{$chunks[0]};
2535 #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; 2530 #print "CHECKING<$linenr> cond<$cond> block<$block>\n";
2536 if (defined $cond) { 2531 if (defined $cond) {
2537 substr($block, 0, length($cond), ''); 2532 substr($block, 0, length($cond), '');
2538 } 2533 }
2539 if (statement_lines($cond) > 1) { 2534 if (statement_lines($cond) > 1) {
2540 #print "APW: ALLOWED: cond<$cond>\n"; 2535 #print "APW: ALLOWED: cond<$cond>\n";
2541 $allowed = 1; 2536 $allowed = 1;
2542 } 2537 }
2543 if ($block =~/\b(?:if|for|while)\b/) { 2538 if ($block =~/\b(?:if|for|while)\b/) {
2544 #print "APW: ALLOWED: block<$block>\n"; 2539 #print "APW: ALLOWED: block<$block>\n";
2545 $allowed = 1; 2540 $allowed = 1;
2546 } 2541 }
2547 if (statement_block_size($block) > 1) { 2542 if (statement_block_size($block) > 1) {
2548 #print "APW: ALLOWED: lines block<$block>\n"; 2543 #print "APW: ALLOWED: lines block<$block>\n";
2549 $allowed = 1; 2544 $allowed = 1;
2550 } 2545 }
2551 # Check the post-context. 2546 # Check the post-context.
2552 if (defined $chunks[1]) { 2547 if (defined $chunks[1]) {
2553 my ($cond, $block) = @{$chunks[1]}; 2548 my ($cond, $block) = @{$chunks[1]};
2554 if (defined $cond) { 2549 if (defined $cond) {
2555 substr($block, 0, length($cond), ''); 2550 substr($block, 0, length($cond), '');
2556 } 2551 }
2557 if ($block =~ /^\s*\{/) { 2552 if ($block =~ /^\s*\{/) {
2558 #print "APW: ALLOWED: chunk-1 block<$block>\n"; 2553 #print "APW: ALLOWED: chunk-1 block<$block>\n";
2559 $allowed = 1; 2554 $allowed = 1;
2560 } 2555 }
2561 } 2556 }
2562 if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 2557 if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
2563 my $herectx = $here . "\n";; 2558 my $herectx = $here . "\n";;
2564 my $cnt = statement_rawlines($block); 2559 my $cnt = statement_rawlines($block);
2565 2560
2566 for (my $n = 0; $n < $cnt; $n++) { 2561 for (my $n = 0; $n < $cnt; $n++) {
2567 $herectx .= raw_line($linenr, $n) . "\n";; 2562 $herectx .= raw_line($linenr, $n) . "\n";;
2568 } 2563 }
2569 2564
2570 WARN("braces {} are not necessary for single statement blocks\n" . $herectx); 2565 WARN("braces {} are not necessary for single statement blocks\n" . $herectx);
2571 } 2566 }
2572 } 2567 }
2573 2568
2574 # don't include deprecated include files (uses RAW line) 2569 # don't include deprecated include files (uses RAW line)
2575 for my $inc (@dep_includes) { 2570 for my $inc (@dep_includes) {
2576 if ($rawline =~ m@^.\s*\#\s*include\s*\<$inc>@) { 2571 if ($rawline =~ m@^.\s*\#\s*include\s*\<$inc>@) {
2577 ERROR("Don't use <$inc>: see Documentation/feature-removal-schedule.txt\n" . $herecurr); 2572 ERROR("Don't use <$inc>: see Documentation/feature-removal-schedule.txt\n" . $herecurr);
2578 } 2573 }
2579 } 2574 }
2580 2575
2581 # don't use deprecated functions 2576 # don't use deprecated functions
2582 for my $func (@dep_functions) { 2577 for my $func (@dep_functions) {
2583 if ($line =~ /\b$func\b/) { 2578 if ($line =~ /\b$func\b/) {
2584 ERROR("Don't use $func(): see Documentation/feature-removal-schedule.txt\n" . $herecurr); 2579 ERROR("Don't use $func(): see Documentation/feature-removal-schedule.txt\n" . $herecurr);
2585 } 2580 }
2586 } 2581 }
2587 2582
2588 # no volatiles please 2583 # no volatiles please
2589 my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 2584 my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
2590 if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 2585 if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
2591 WARN("Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr); 2586 WARN("Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr);
2592 } 2587 }
2593 2588
2594 # SPIN_LOCK_UNLOCKED & RW_LOCK_UNLOCKED are deprecated 2589 # SPIN_LOCK_UNLOCKED & RW_LOCK_UNLOCKED are deprecated
2595 if ($line =~ /\b(SPIN_LOCK_UNLOCKED|RW_LOCK_UNLOCKED)/) { 2590 if ($line =~ /\b(SPIN_LOCK_UNLOCKED|RW_LOCK_UNLOCKED)/) {
2596 ERROR("Use of $1 is deprecated: see Documentation/spinlocks.txt\n" . $herecurr); 2591 ERROR("Use of $1 is deprecated: see Documentation/spinlocks.txt\n" . $herecurr);
2597 } 2592 }
2598 2593
2599 # warn about #if 0 2594 # warn about #if 0
2600 if ($line =~ /^.\s*\#\s*if\s+0\b/) { 2595 if ($line =~ /^.\s*\#\s*if\s+0\b/) {
2601 CHK("if this code is redundant consider removing it\n" . 2596 CHK("if this code is redundant consider removing it\n" .
2602 $herecurr); 2597 $herecurr);
2603 } 2598 }
2604 2599
2605 # check for needless kfree() checks 2600 # check for needless kfree() checks
2606 if ($prevline =~ /\bif\s*\(([^\)]*)\)/) { 2601 if ($prevline =~ /\bif\s*\(([^\)]*)\)/) {
2607 my $expr = $1; 2602 my $expr = $1;
2608 if ($line =~ /\bkfree\(\Q$expr\E\);/) { 2603 if ($line =~ /\bkfree\(\Q$expr\E\);/) {
2609 WARN("kfree(NULL) is safe this check is probably not required\n" . $hereprev); 2604 WARN("kfree(NULL) is safe this check is probably not required\n" . $hereprev);
2610 } 2605 }
2611 } 2606 }
2612 # check for needless usb_free_urb() checks 2607 # check for needless usb_free_urb() checks
2613 if ($prevline =~ /\bif\s*\(([^\)]*)\)/) { 2608 if ($prevline =~ /\bif\s*\(([^\)]*)\)/) {
2614 my $expr = $1; 2609 my $expr = $1;
2615 if ($line =~ /\busb_free_urb\(\Q$expr\E\);/) { 2610 if ($line =~ /\busb_free_urb\(\Q$expr\E\);/) {
2616 WARN("usb_free_urb(NULL) is safe this check is probably not required\n" . $hereprev); 2611 WARN("usb_free_urb(NULL) is safe this check is probably not required\n" . $hereprev);
2617 } 2612 }
2618 } 2613 }
2619 2614
2620 # prefer usleep_range over udelay 2615 # prefer usleep_range over udelay
2621 if ($line =~ /\budelay\s*\(\s*(\w+)\s*\)/) { 2616 if ($line =~ /\budelay\s*\(\s*(\w+)\s*\)/) {
2622 # ignore udelay's < 10, however 2617 # ignore udelay's < 10, however
2623 if (! (($1 =~ /(\d+)/) && ($1 < 10)) ) { 2618 if (! (($1 =~ /(\d+)/) && ($1 < 10)) ) {
2624 CHK("usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $line); 2619 CHK("usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $line);
2625 } 2620 }
2626 } 2621 }
2627 2622
2628 # warn about unexpectedly long msleep's 2623 # warn about unexpectedly long msleep's
2629 if ($line =~ /\bmsleep\s*\((\d+)\);/) { 2624 if ($line =~ /\bmsleep\s*\((\d+)\);/) {
2630 if ($1 < 20) { 2625 if ($1 < 20) {
2631 WARN("msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $line); 2626 WARN("msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $line);
2632 } 2627 }
2633 } 2628 }
2634 2629
2635 # warn about #ifdefs in C files 2630 # warn about #ifdefs in C files
2636 # if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 2631 # if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
2637 # print "#ifdef in C files should be avoided\n"; 2632 # print "#ifdef in C files should be avoided\n";
2638 # print "$herecurr"; 2633 # print "$herecurr";
2639 # $clean = 0; 2634 # $clean = 0;
2640 # } 2635 # }
2641 2636
2642 # warn about spacing in #ifdefs 2637 # warn about spacing in #ifdefs
2643 if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { 2638 if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
2644 ERROR("exactly one space required after that #$1\n" . $herecurr); 2639 ERROR("exactly one space required after that #$1\n" . $herecurr);
2645 } 2640 }
2646 2641
2647 # check for spinlock_t definitions without a comment. 2642 # check for spinlock_t definitions without a comment.
2648 if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || 2643 if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
2649 $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { 2644 $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
2650 my $which = $1; 2645 my $which = $1;
2651 if (!ctx_has_comment($first_line, $linenr)) { 2646 if (!ctx_has_comment($first_line, $linenr)) {
2652 CHK("$1 definition without comment\n" . $herecurr); 2647 CHK("$1 definition without comment\n" . $herecurr);
2653 } 2648 }
2654 } 2649 }
2655 # check for memory barriers without a comment. 2650 # check for memory barriers without a comment.
2656 if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) { 2651 if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) {
2657 if (!ctx_has_comment($first_line, $linenr)) { 2652 if (!ctx_has_comment($first_line, $linenr)) {
2658 CHK("memory barrier without comment\n" . $herecurr); 2653 CHK("memory barrier without comment\n" . $herecurr);
2659 } 2654 }
2660 } 2655 }
2661 # check of hardware specific defines 2656 # check of hardware specific defines
2662 if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 2657 if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
2663 CHK("architecture specific defines should be avoided\n" . $herecurr); 2658 CHK("architecture specific defines should be avoided\n" . $herecurr);
2664 } 2659 }
2665 2660
2666 # Check that the storage class is at the beginning of a declaration 2661 # Check that the storage class is at the beginning of a declaration
2667 if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) { 2662 if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) {
2668 WARN("storage class should be at the beginning of the declaration\n" . $herecurr) 2663 WARN("storage class should be at the beginning of the declaration\n" . $herecurr)
2669 } 2664 }
2670 2665
2671 # check the location of the inline attribute, that it is between 2666 # check the location of the inline attribute, that it is between
2672 # storage class and type. 2667 # storage class and type.
2673 if ($line =~ /\b$Type\s+$Inline\b/ || 2668 if ($line =~ /\b$Type\s+$Inline\b/ ||
2674 $line =~ /\b$Inline\s+$Storage\b/) { 2669 $line =~ /\b$Inline\s+$Storage\b/) {
2675 ERROR("inline keyword should sit between storage class and type\n" . $herecurr); 2670 ERROR("inline keyword should sit between storage class and type\n" . $herecurr);
2676 } 2671 }
2677 2672
2678 # Check for __inline__ and __inline, prefer inline 2673 # Check for __inline__ and __inline, prefer inline
2679 if ($line =~ /\b(__inline__|__inline)\b/) { 2674 if ($line =~ /\b(__inline__|__inline)\b/) {
2680 WARN("plain inline is preferred over $1\n" . $herecurr); 2675 WARN("plain inline is preferred over $1\n" . $herecurr);
2681 } 2676 }
2682 2677
2683 # check for sizeof(&) 2678 # check for sizeof(&)
2684 if ($line =~ /\bsizeof\s*\(\s*\&/) { 2679 if ($line =~ /\bsizeof\s*\(\s*\&/) {
2685 WARN("sizeof(& should be avoided\n" . $herecurr); 2680 WARN("sizeof(& should be avoided\n" . $herecurr);
2686 } 2681 }
2687 2682
2688 # check for new externs in .c files. 2683 # check for new externs in .c files.
2689 if ($realfile =~ /\.c$/ && defined $stat && 2684 if ($realfile =~ /\.c$/ && defined $stat &&
2690 $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 2685 $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
2691 { 2686 {
2692 my $function_name = $1; 2687 my $function_name = $1;
2693 my $paren_space = $2; 2688 my $paren_space = $2;
2694 2689
2695 my $s = $stat; 2690 my $s = $stat;
2696 if (defined $cond) { 2691 if (defined $cond) {
2697 substr($s, 0, length($cond), ''); 2692 substr($s, 0, length($cond), '');
2698 } 2693 }
2699 if ($s =~ /^\s*;/ && 2694 if ($s =~ /^\s*;/ &&
2700 $function_name ne 'uninitialized_var') 2695 $function_name ne 'uninitialized_var')
2701 { 2696 {
2702 WARN("externs should be avoided in .c files\n" . $herecurr); 2697 WARN("externs should be avoided in .c files\n" . $herecurr);
2703 } 2698 }
2704 2699
2705 if ($paren_space =~ /\n/) { 2700 if ($paren_space =~ /\n/) {
2706 WARN("arguments for function declarations should follow identifier\n" . $herecurr); 2701 WARN("arguments for function declarations should follow identifier\n" . $herecurr);
2707 } 2702 }
2708 2703
2709 } elsif ($realfile =~ /\.c$/ && defined $stat && 2704 } elsif ($realfile =~ /\.c$/ && defined $stat &&
2710 $stat =~ /^.\s*extern\s+/) 2705 $stat =~ /^.\s*extern\s+/)
2711 { 2706 {
2712 WARN("externs should be avoided in .c files\n" . $herecurr); 2707 WARN("externs should be avoided in .c files\n" . $herecurr);
2713 } 2708 }
2714 2709
2715 # checks for new __setup's 2710 # checks for new __setup's
2716 if ($rawline =~ /\b__setup\("([^"]*)"/) { 2711 if ($rawline =~ /\b__setup\("([^"]*)"/) {
2717 my $name = $1; 2712 my $name = $1;
2718 2713
2719 if (!grep(/$name/, @setup_docs)) { 2714 if (!grep(/$name/, @setup_docs)) {
2720 CHK("__setup appears un-documented -- check Documentation/kernel-parameters.txt\n" . $herecurr); 2715 CHK("__setup appears un-documented -- check Documentation/kernel-parameters.txt\n" . $herecurr);
2721 } 2716 }
2722 } 2717 }
2723 2718
2724 # check for pointless casting of kmalloc return 2719 # check for pointless casting of kmalloc return
2725 if ($line =~ /\*\s*\)\s*k[czm]alloc\b/) { 2720 if ($line =~ /\*\s*\)\s*k[czm]alloc\b/) {
2726 WARN("unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 2721 WARN("unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
2727 } 2722 }
2728 2723
2729 # check for gcc specific __FUNCTION__ 2724 # check for gcc specific __FUNCTION__
2730 if ($line =~ /__FUNCTION__/) { 2725 if ($line =~ /__FUNCTION__/) {
2731 WARN("__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr); 2726 WARN("__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr);
2732 } 2727 }
2733 2728
2734 # check for semaphores used as mutexes 2729 # check for semaphores used as mutexes
2735 if ($line =~ /^.\s*(DECLARE_MUTEX|init_MUTEX)\s*\(/) { 2730 if ($line =~ /^.\s*(DECLARE_MUTEX|init_MUTEX)\s*\(/) {
2736 WARN("mutexes are preferred for single holder semaphores\n" . $herecurr); 2731 WARN("mutexes are preferred for single holder semaphores\n" . $herecurr);
2737 } 2732 }
2738 # check for semaphores used as mutexes 2733 # check for semaphores used as mutexes
2739 if ($line =~ /^.\s*init_MUTEX_LOCKED\s*\(/) { 2734 if ($line =~ /^.\s*init_MUTEX_LOCKED\s*\(/) {
2740 WARN("consider using a completion\n" . $herecurr); 2735 WARN("consider using a completion\n" . $herecurr);
2741 2736
2742 } 2737 }
2743 # recommend strict_strto* over simple_strto* 2738 # recommend strict_strto* over simple_strto*
2744 if ($line =~ /\bsimple_(strto.*?)\s*\(/) { 2739 if ($line =~ /\bsimple_(strto.*?)\s*\(/) {
2745 WARN("consider using strict_$1 in preference to simple_$1\n" . $herecurr); 2740 WARN("consider using strict_$1 in preference to simple_$1\n" . $herecurr);
2746 } 2741 }
2747 # check for __initcall(), use device_initcall() explicitly please 2742 # check for __initcall(), use device_initcall() explicitly please
2748 if ($line =~ /^.\s*__initcall\s*\(/) { 2743 if ($line =~ /^.\s*__initcall\s*\(/) {
2749 WARN("please use device_initcall() instead of __initcall()\n" . $herecurr); 2744 WARN("please use device_initcall() instead of __initcall()\n" . $herecurr);
2750 } 2745 }
2751 # check for various ops structs, ensure they are const. 2746 # check for various ops structs, ensure they are const.
2752 my $struct_ops = qr{acpi_dock_ops| 2747 my $struct_ops = qr{acpi_dock_ops|
2753 address_space_operations| 2748 address_space_operations|
2754 backlight_ops| 2749 backlight_ops|
2755 block_device_operations| 2750 block_device_operations|
2756 dentry_operations| 2751 dentry_operations|
2757 dev_pm_ops| 2752 dev_pm_ops|
2758 dma_map_ops| 2753 dma_map_ops|
2759 extent_io_ops| 2754 extent_io_ops|
2760 file_lock_operations| 2755 file_lock_operations|
2761 file_operations| 2756 file_operations|
2762 hv_ops| 2757 hv_ops|
2763 ide_dma_ops| 2758 ide_dma_ops|
2764 intel_dvo_dev_ops| 2759 intel_dvo_dev_ops|
2765 item_operations| 2760 item_operations|
2766 iwl_ops| 2761 iwl_ops|
2767 kgdb_arch| 2762 kgdb_arch|
2768 kgdb_io| 2763 kgdb_io|
2769 kset_uevent_ops| 2764 kset_uevent_ops|
2770 lock_manager_operations| 2765 lock_manager_operations|
2771 microcode_ops| 2766 microcode_ops|
2772 mtrr_ops| 2767 mtrr_ops|
2773 neigh_ops| 2768 neigh_ops|
2774 nlmsvc_binding| 2769 nlmsvc_binding|
2775 pci_raw_ops| 2770 pci_raw_ops|
2776 pipe_buf_operations| 2771 pipe_buf_operations|
2777 platform_hibernation_ops| 2772 platform_hibernation_ops|
2778 platform_suspend_ops| 2773 platform_suspend_ops|
2779 proto_ops| 2774 proto_ops|
2780 rpc_pipe_ops| 2775 rpc_pipe_ops|
2781 seq_operations| 2776 seq_operations|
2782 snd_ac97_build_ops| 2777 snd_ac97_build_ops|
2783 soc_pcmcia_socket_ops| 2778 soc_pcmcia_socket_ops|
2784 stacktrace_ops| 2779 stacktrace_ops|
2785 sysfs_ops| 2780 sysfs_ops|
2786 tty_operations| 2781 tty_operations|
2787 usb_mon_operations| 2782 usb_mon_operations|
2788 wd_ops}x; 2783 wd_ops}x;
2789 if ($line !~ /\bconst\b/ && 2784 if ($line !~ /\bconst\b/ &&
2790 $line =~ /\bstruct\s+($struct_ops)\b/) { 2785 $line =~ /\bstruct\s+($struct_ops)\b/) {
2791 WARN("struct $1 should normally be const\n" . 2786 WARN("struct $1 should normally be const\n" .
2792 $herecurr); 2787 $herecurr);
2793 } 2788 }
2794 2789
2795 # use of NR_CPUS is usually wrong 2790 # use of NR_CPUS is usually wrong
2796 # ignore definitions of NR_CPUS and usage to define arrays as likely right 2791 # ignore definitions of NR_CPUS and usage to define arrays as likely right
2797 if ($line =~ /\bNR_CPUS\b/ && 2792 if ($line =~ /\bNR_CPUS\b/ &&
2798 $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && 2793 $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&
2799 $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && 2794 $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&
2800 $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && 2795 $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&
2801 $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && 2796 $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&
2802 $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) 2797 $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/)
2803 { 2798 {
2804 WARN("usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); 2799 WARN("usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
2805 } 2800 }
2806 2801
2807 # check for %L{u,d,i} in strings 2802 # check for %L{u,d,i} in strings
2808 my $string; 2803 my $string;
2809 while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 2804 while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
2810 $string = substr($rawline, $-[1], $+[1] - $-[1]); 2805 $string = substr($rawline, $-[1], $+[1] - $-[1]);
2811 $string =~ s/%%/__/g; 2806 $string =~ s/%%/__/g;
2812 if ($string =~ /(?<!%)%L[udi]/) { 2807 if ($string =~ /(?<!%)%L[udi]/) {
2813 WARN("\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr); 2808 WARN("\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr);
2814 last; 2809 last;
2815 } 2810 }
2816 } 2811 }
2817 2812
2818 # whine mightly about in_atomic 2813 # whine mightly about in_atomic
2819 if ($line =~ /\bin_atomic\s*\(/) { 2814 if ($line =~ /\bin_atomic\s*\(/) {
2820 if ($realfile =~ m@^drivers/@) { 2815 if ($realfile =~ m@^drivers/@) {
2821 ERROR("do not use in_atomic in drivers\n" . $herecurr); 2816 ERROR("do not use in_atomic in drivers\n" . $herecurr);
2822 } elsif ($realfile !~ m@^kernel/@) { 2817 } elsif ($realfile !~ m@^kernel/@) {
2823 WARN("use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 2818 WARN("use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);
2824 } 2819 }
2825 } 2820 }
2826 2821
2827 # check for lockdep_set_novalidate_class 2822 # check for lockdep_set_novalidate_class
2828 if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || 2823 if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||
2829 $line =~ /__lockdep_no_validate__\s*\)/ ) { 2824 $line =~ /__lockdep_no_validate__\s*\)/ ) {
2830 if ($realfile !~ m@^kernel/lockdep@ && 2825 if ($realfile !~ m@^kernel/lockdep@ &&
2831 $realfile !~ m@^include/linux/lockdep@ && 2826 $realfile !~ m@^include/linux/lockdep@ &&
2832 $realfile !~ m@^drivers/base/core@) { 2827 $realfile !~ m@^drivers/base/core@) {
2833 ERROR("lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); 2828 ERROR("lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
2834 } 2829 }
2835 } 2830 }
2836 } 2831 }
2837 2832
2838 # If we have no input at all, then there is nothing to report on 2833 # If we have no input at all, then there is nothing to report on
2839 # so just keep quiet. 2834 # so just keep quiet.
2840 if ($#rawlines == -1) { 2835 if ($#rawlines == -1) {
2841 exit(0); 2836 exit(0);
2842 } 2837 }
2843 2838
2844 # In mailback mode only produce a report in the negative, for 2839 # In mailback mode only produce a report in the negative, for
2845 # things that appear to be patches. 2840 # things that appear to be patches.
2846 if ($mailback && ($clean == 1 || !$is_patch)) { 2841 if ($mailback && ($clean == 1 || !$is_patch)) {
2847 exit(0); 2842 exit(0);
2848 } 2843 }
2849 2844
2850 # This is not a patch, and we are are in 'no-patch' mode so 2845 # This is not a patch, and we are are in 'no-patch' mode so
2851 # just keep quiet. 2846 # just keep quiet.
2852 if (!$chk_patch && !$is_patch) { 2847 if (!$chk_patch && !$is_patch) {
2853 exit(0); 2848 exit(0);
2854 } 2849 }
2855 2850
2856 if (!$is_patch) { 2851 if (!$is_patch) {
2857 ERROR("Does not appear to be a unified-diff format patch\n"); 2852 ERROR("Does not appear to be a unified-diff format patch\n");
2858 } 2853 }
2859 if ($is_patch && $chk_signoff && $signoff == 0) { 2854 if ($is_patch && $chk_signoff && $signoff == 0) {
2860 ERROR("Missing Signed-off-by: line(s)\n"); 2855 ERROR("Missing Signed-off-by: line(s)\n");
2861 } 2856 }
2862 2857
2863 print report_dump(); 2858 print report_dump();
2864 if ($summary && !($clean == 1 && $quiet == 1)) { 2859 if ($summary && !($clean == 1 && $quiet == 1)) {
2865 print "$filename " if ($summary_file); 2860 print "$filename " if ($summary_file);
2866 print "total: $cnt_error errors, $cnt_warn warnings, " . 2861 print "total: $cnt_error errors, $cnt_warn warnings, " .
2867 (($check)? "$cnt_chk checks, " : "") . 2862 (($check)? "$cnt_chk checks, " : "") .
2868 "$cnt_lines lines checked\n"; 2863 "$cnt_lines lines checked\n";
2869 print "\n" if ($quiet == 0); 2864 print "\n" if ($quiet == 0);
2870 } 2865 }
2871 2866
2872 if ($quiet == 0) { 2867 if ($quiet == 0) {
2873 # If there were whitespace errors which cleanpatch can fix 2868 # If there were whitespace errors which cleanpatch can fix
2874 # then suggest that. 2869 # then suggest that.
2875 if ($rpt_cleaners) { 2870 if ($rpt_cleaners) {
2876 print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n"; 2871 print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n";
2877 print " scripts/cleanfile\n\n"; 2872 print " scripts/cleanfile\n\n";
2878 } 2873 }
2879 } 2874 }
2880 2875
2881 if ($clean == 1 && $quiet == 0) { 2876 if ($clean == 1 && $quiet == 0) {
2882 print "$vname has no obvious style problems and is ready for submission.\n" 2877 print "$vname has no obvious style problems and is ready for submission.\n"
2883 } 2878 }
2884 if ($clean == 0 && $quiet == 0) { 2879 if ($clean == 0 && $quiet == 0) {
2885 print "$vname has style problems, please review. If any of these errors\n"; 2880 print "$vname has style problems, please review. If any of these errors\n";
2886 print "are false positives report them to the maintainer, see\n"; 2881 print "are false positives report them to the maintainer, see\n";
2887 print "CHECKPATCH in MAINTAINERS.\n"; 2882 print "CHECKPATCH in MAINTAINERS.\n";