glusterfs

Форк
0
/
checkpatch.pl 
4326 строк · 147.4 Кб
1
#!/usr/bin/perl -w
2
# (c) 2001, Dave Jones. (the file handling 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)
5
# (c) 2008-2010 Andy Whitcroft <apw@canonical.com>
6
# (c) 2014 Gluster Community <gluster-devel@gluster.org>
7
# Licensed under the terms of the GNU GPL License version 2
8

9
use strict;
10
use POSIX;
11

12
my $P = $0;
13
$P =~ s@.*/@@g;
14

15
my $V = '0.32.1';
16

17
use Getopt::Long qw(:config no_auto_abbrev);
18

19
my $quiet = 0;
20
my $tree = 1;
21
my $chk_signoff = 1;
22
my $chk_patch = 1;
23
my $tst_only;
24
my $emacs = 0;
25
my $terse = 0;
26
my $file = 0;
27
my $check = 0;
28
my $check_orig = 0;
29
my $summary = 1;
30
my $mailback = 0;
31
my $summary_file = 0;
32
my $show_types = 0;
33
my $fix = 0;
34
my $fix_inplace = 0;
35
my $root;
36
my %debug;
37
my %camelcase = ();
38
my %use_type = ();
39
my @use = ();
40
my %ignore_type = ();
41
my @ignore = ();
42
my $help = 0;
43
my $configuration_file = ".checkpatch.conf";
44
my $max_line_length = 80;
45
my $ignore_perl_version = 0;
46
my $minimum_perl_version = 5.10.0;
47
my $gerrit_url = $ENV{GERRIT_URL};
48

49
sub help {
50
    my ($exitcode) = @_;
51

52
    print << "EOM";
53
Usage: $P [OPTION]... [FILE]...
54
Version: $V
55

56
Options:
57
  -q, --quiet                quiet
58
  --patch                    treat FILE as patchfile (default)
59
  --emacs                    emacs compile window format
60
  --gerrit-url=STRING        URL the patch was reviewed at
61
  --terse                    one line per report
62
  -f, --file                 treat FILE as regular source file
63
  --subjective, --strict     enable more subjective tests
64
  --types TYPE(,TYPE2...)    show only these comma separated message types
65
  --ignore TYPE(,TYPE2...)   ignore various comma separated message types
66
  --max-line-length=n        set the maximum line length, if exceeded, warn
67
  --show-types               show the message "types" in the output
68
  --root=PATH                PATH to the glusterfs tree root
69
  --no-summary               suppress the per-file summary
70
  --mailback                 only produce a report in case of warnings/errors
71
  --summary-file             include the filename in summary
72
  --debug KEY=[0|1]          turn on/off debugging of KEY, where KEY is one of
73
                             'values', 'possible', 'type', and 'attr' (default
74
                             is all off)
75
  --test-only=WORD           report only warnings/errors containing WORD literally
76
  --fix                      EXPERIMENTAL - may create horrible results
77
                             If correctable single-line errors exist, create
78
                             "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
79
                             with potential errors corrected to the preferred
80
                             checkpatch style
81
  --fix-inplace              EXPERIMENTAL - may create horrible results
82
                             Is the same as --fix, but overwrites the input
83
                             file.  It's your fault if there's no backup or git
84
  --ignore-perl-version      override checking of perl version.  expect
85
                             runtime errors.
86
  -h, --help, --version      display this help and exit
87

88
When FILE is - read standard input.
89
EOM
90

91
exit($exitcode);
92
}
93

94
my $conf = which_conf($configuration_file);
95
if (-f $conf) {
96
    my @conf_args;
97
    open(my $conffile, '<', "$conf")
98
        or warn "$P: Can't find a readable $configuration_file file $!\n";
99

100
    while (<$conffile>) {
101
        my $line = $_;
102

103
        $line =~ s/\s*\n?$//g;
104
        $line =~ s/^\s*//g;
105
        $line =~ s/\s+/ /g;
106

107
        next if ($line =~ m/^\s*#/);
108
        next if ($line =~ m/^\s*$/);
109

110
        my @words = split(" ", $line);
111
        foreach my $word (@words) {
112
            last if ($word =~ m/^#/);
113
            push (@conf_args, $word);
114
        }
115
    }
116
    close($conffile);
117
    unshift(@ARGV, @conf_args) if @conf_args;
118
}
119

120
GetOptions(
121
    'q|quiet+'  => \$quiet,
122
    'patch!'    => \$chk_patch,
123
    'emacs!'    => \$emacs,
124
    'gerrit-url=s' => \$gerrit_url,
125
    'terse!'    => \$terse,
126
    'f|file!'   => \$file,
127
    'subjective!'       => \$check,
128
    'strict!'   => \$check,
129
    'ignore=s'  => \@ignore,
130
    'types=s'   => \@use,
131
    'show-types!'       => \$show_types,
132
    'max-line-length=i' => \$max_line_length,
133
    'root=s'    => \$root,
134
    'summary!'  => \$summary,
135
    'mailback!' => \$mailback,
136
    'summary-file!'     => \$summary_file,
137
    'fix!'              => \$fix,
138
    'fix-inplace!'      => \$fix_inplace,
139
    'ignore-perl-version!' => \$ignore_perl_version,
140
    'debug=s'   => \%debug,
141
    'test-only=s'       => \$tst_only,
142
    'h|help'    => \$help,
143
    'version'   => \$help
144
) or help(1);
145

146
help(0) if ($help);
147

148
$fix = 1 if ($fix_inplace);
149
$check_orig = $check;
150

151
my $exit = 0;
152

153
if ($^V && $^V lt $minimum_perl_version) {
154
    printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
155
    if (!$ignore_perl_version) {
156
        exit(1);
157
    }
158
}
159

160
if ($#ARGV < 0) {
161
    print "$P: no input files\n";
162
    exit(1);
163
}
164

165
sub hash_save_array_words {
166
    my ($hashRef, $arrayRef) = @_;
167

168
    my @array = split(/,/, join(',', @$arrayRef));
169
    foreach my $word (@array) {
170
        $word =~ s/\s*\n?$//g;
171
        $word =~ s/^\s*//g;
172
        $word =~ s/\s+/ /g;
173
        $word =~ tr/[a-z]/[A-Z]/;
174

175
        next if ($word =~ m/^\s*#/);
176
        next if ($word =~ m/^\s*$/);
177

178
        $hashRef->{$word}++;
179
    }
180
}
181

182
sub hash_show_words {
183
    my ($hashRef, $prefix) = @_;
184

185
    if ($quiet == 0 && keys %$hashRef) {
186
        print "NOTE: $prefix message types:";
187
        foreach my $word (sort keys %$hashRef) {
188
            print " $word";
189
        }
190
        print "\n\n";
191
    }
192
}
193

194
hash_save_array_words(\%ignore_type, \@ignore);
195
hash_save_array_words(\%use_type, \@use);
196

197
my $dbg_values = 0;
198
my $dbg_possible = 0;
199
my $dbg_type = 0;
200
my $dbg_attr = 0;
201
for my $key (keys %debug) {
202
    ## no critic
203
    eval "\${dbg_$key} = '$debug{$key}';";
204
    die "$@" if ($@);
205
}
206

207
my $rpt_cleaners = 0;
208

209
if ($terse) {
210
    $emacs = 1;
211
    $quiet++;
212
}
213

214
if ($tree) {
215
    if (defined $root) {
216
        if (!top_of_glusterfs_tree($root)) {
217
            die "$P: $root: --root does not point at a valid tree\n";
218
        }
219
    } else {
220
        if (top_of_glusterfs_tree('.')) {
221
            $root = '.';
222
        } elsif ($0 =~ m@(.*)/extras/[^/]*$@ &&
223
                 top_of_glusterfs_tree($1)) {
224
            $root = $1;
225
        }
226
    }
227

228
    if (!defined $root) {
229
        print "Must be run from the top-level dir. of a GlusterFS tree\n";
230
        exit(2);
231
    }
232
}
233

234
my $emitted_corrupt = 0;
235

236
our $Ident      = qr{
237
                        [A-Za-z_][A-Za-z\d_]*
238
                        (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
239
                }x;
240
our $Storage    = qr{extern|static|asmlinkage};
241
our $Sparse     = qr{
242
                        __user|
243
                        __kernel|
244
                        __force|
245
                        __iomem|
246
                        __must_check|
247
                        __init_refok|
248
                        __kprobes|
249
                        __ref|
250
                        __rcu
251
                }x;
252
our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
253
our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
254
our $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
255
our $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
256
our $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
257

258
# Notes to $Attribute:
259
# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
260
our $Attribute  = qr{
261
                        const|
262
                        __percpu|
263
                        __nocast|
264
                        __safe|
265
                        __bitwise__|
266
                        __packed__|
267
                        __packed2__|
268
                        __naked|
269
                        __maybe_unused|
270
                        __always_unused|
271
                        __noreturn|
272
                        __used|
273
                        __cold|
274
                        __noclone|
275
                        __deprecated|
276
                        __read_mostly|
277
                        __kprobes|
278
                        $InitAttribute|
279
                        ____cacheline_aligned|
280
                        ____cacheline_aligned_in_smp|
281
                        ____cacheline_internodealigned_in_smp|
282
                        __weak
283
                  }x;
284
our $Modifier;
285
our $Inline     = qr{inline|__always_inline|noinline|__inline|__inline__};
286
our $Member     = qr{->$Ident|\.$Ident|\[[^]]*\]};
287
our $Lval       = qr{$Ident(?:$Member)*};
288

289
our $Int_type   = qr{(?i)llu|ull|ll|lu|ul|l|u};
290
our $Binary     = qr{(?i)0b[01]+$Int_type?};
291
our $Hex        = qr{(?i)0x[0-9a-f]+$Int_type?};
292
our $Int        = qr{[0-9]+$Int_type?};
293
our $Octal      = qr{0[0-7]+$Int_type?};
294
our $Float_hex  = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
295
our $Float_dec  = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
296
our $Float_int  = qr{(?i)[0-9]+e-?[0-9]+[fl]?};
297
our $Float      = qr{$Float_hex|$Float_dec|$Float_int};
298
our $Constant   = qr{$Float|$Binary|$Octal|$Hex|$Int};
299
our $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
300
our $Compare    = qr{<=|>=|==|!=|<|(?<!-)>};
301
our $Arithmetic = qr{\+|-|\*|\/|%};
302
our $Operators  = qr{
303
                        <=|>=|==|!=|
304
                        =>|->|<<|>>|<|>|!|~|
305
                        &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
306
                  }x;
307

308
our $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
309

310
our $NonptrType;
311
our $NonptrTypeWithAttr;
312
our $Type;
313
our $Declare;
314

315
our $NON_ASCII_UTF8     = qr{
316
        [\xC2-\xDF][\x80-\xBF]               # non-overlong 2-byte
317
        |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
318
        | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
319
        |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
320
        |  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
321
        | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
322
        |  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
323
}x;
324

325
our $UTF8       = qr{
326
        [\x09\x0A\x0D\x20-\x7E]              # ASCII
327
        | $NON_ASCII_UTF8
328
}x;
329

330
our $typeTypedefs = qr{(?x:
331
        (?:__)?(?:u|s|be|le)(?:8|16|32|64)|
332
        atomic_t
333
)};
334

335
our $logFunctions = qr{(?x:
336
        printk(?:_ratelimited|_once|)|
337
        (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
338
        WARN(?:_RATELIMIT|_ONCE|)|
339
        panic|
340
        MODULE_[A-Z_]+|
341
        seq_vprintf|seq_printf|seq_puts
342
)};
343

344
our $signature_tags = qr{(?xi:
345
        Signed-off-by:|
346
        Acked-by:|
347
        Tested-by:|
348
        Reviewed-by:|
349
        Reviewed-on:|
350
        Reported-by:|
351
        Original-author:|
352
        Original-Author:|
353
        Original-Authors:|
354
        Suggested-by:|
355
        To:|
356
        Cc:
357
)};
358

359
our $url_tags = qr{http:|https:};
360

361
our @typeList = (
362
        qr{void},
363
        qr{(?:unsigned\s+)?char},
364
        qr{(?:unsigned\s+)?short},
365
        qr{(?:unsigned\s+)?int},
366
        qr{(?:unsigned\s+)?long},
367
        qr{(?:unsigned\s+)?long\s+int},
368
        qr{(?:unsigned\s+)?long\s+long},
369
        qr{(?:unsigned\s+)?long\s+long\s+int},
370
        qr{unsigned},
371
        qr{float},
372
        qr{double},
373
        qr{bool},
374
        qr{struct\s+$Ident},
375
        qr{union\s+$Ident},
376
        qr{enum\s+$Ident},
377
        qr{${Ident}_t},
378
        qr{${Ident}_handler},
379
        qr{${Ident}_handler_fn},
380
);
381
our @typeListWithAttr = (
382
        @typeList,
383
        qr{struct\s+$InitAttribute\s+$Ident},
384
        qr{union\s+$InitAttribute\s+$Ident},
385
);
386

387
our @modifierList = (
388
        qr{fastcall},
389
);
390

391
our @mode_permission_funcs = (
392
        ["module_param", 3],
393
        ["module_param_(?:array|named|string)", 4],
394
        ["module_param_array_named", 5],
395
        ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
396
        ["proc_create(?:_data|)", 2],
397
        ["(?:CLASS|DEVICE|SENSOR)_ATTR", 2],
398
);
399

400
#Create a search pattern for all these functions to speed up a loop below
401
our $mode_perms_search = "";
402
foreach my $entry (@mode_permission_funcs) {
403
        $mode_perms_search .= '|' if ($mode_perms_search ne "");
404
        $mode_perms_search .= $entry->[0];
405
}
406

407
our $declaration_macros = qr{(?x:
408
        (?:$Storage\s+)?(?:DECLARE|DEFINE)_[A-Z]+\s*\(|
409
        (?:$Storage\s+)?LIST_HEAD\s*\(
410
)};
411

412
our $allowed_asm_includes = qr{(?x:
413
        irq|
414
        memory
415
)};
416
# memory.h: ARM has a custom one
417

418
sub build_types {
419
    my $mods = "(?x:\n" . join("|\n  ", @modifierList) . "\n)";
420
    my $all = "(?x:\n" . join("|\n  ", @typeList) . "\n)";
421
    my $allWithAttr = "(?x:\n" . join("|\n  ", @typeListWithAttr) . "\n)";
422
    $Modifier   = qr{(?:$Attribute|$Sparse|$mods)};
423
    $NonptrType = qr{
424
                        (?:$Modifier\s+|const\s+)*
425
                        (?:
426
                                (?:typeof|__typeof__)\s*\([^\)]*\)|
427
                                (?:$typeTypedefs\b)|
428
                                (?:${all}\b)
429
                        )
430
                        (?:\s+$Modifier|\s+const)*
431
                  }x;
432
        $NonptrTypeWithAttr     = qr{
433
                        (?:$Modifier\s+|const\s+)*
434
                        (?:
435
                                (?:typeof|__typeof__)\s*\([^\)]*\)|
436
                                (?:$typeTypedefs\b)|
437
                                (?:${allWithAttr}\b)
438
                        )
439
                        (?:\s+$Modifier|\s+const)*
440
                  }x;
441
        $Type   = qr{
442
                        $NonptrType
443
                        (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*|\[\])+|(?:\s*\[\s*\])+)?
444
                        (?:\s+$Inline|\s+$Modifier)*
445
                  }x;
446
        $Declare        = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
447
}
448
build_types();
449

450
our $Typecast   = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
451

452
# Using $balanced_parens, $LvalOrFunc, or $FuncArg
453
# requires at least perl version v5.10.0
454
# Any use must be runtime checked with $^V
455

456
our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
457
our $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
458
our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant)};
459

460
sub deparenthesize {
461
    my ($string) = @_;
462
    return "" if (!defined($string));
463

464
    while ($string =~ /^\s*\(.*\)\s*$/) {
465
        $string =~ s@^\s*\(\s*@@;
466
        $string =~ s@\s*\)\s*$@@;
467
    }
468

469
    $string =~ s@\s+@ @g;
470

471
    return $string;
472
}
473

474
sub seed_camelcase_file {
475
    my ($file) = @_;
476

477
    return if (!(-f $file));
478

479
    local $/;
480

481
    open(my $include_file, '<', "$file")
482
        or warn "$P: Can't read '$file' $!\n";
483
    my $text = <$include_file>;
484
    close($include_file);
485

486
    my @lines = split('\n', $text);
487

488
    foreach my $line (@lines) {
489
        next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
490
        if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
491
            $camelcase{$1} = 1;
492
        } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
493
            $camelcase{$1} = 1;
494
        } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
495
            $camelcase{$1} = 1;
496
        }
497
    }
498
}
499

500
my $camelcase_seeded = 0;
501
sub seed_camelcase_includes {
502
    return if ($camelcase_seeded);
503

504
    my $files;
505
    my $camelcase_cache = "";
506
    my @include_files = ();
507

508
    $camelcase_seeded = 1;
509

510
    if (-e ".git") {
511
        my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`;
512
        chomp $git_last_include_commit;
513
        $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
514
    } else {
515
        my $last_mod_date = 0;
516
        $files = `find $root/include -name "*.h"`;
517
        @include_files = split('\n', $files);
518
        foreach my $file (@include_files) {
519
            my $date = POSIX::strftime("%Y%m%d%H%M",
520
                                       localtime((stat $file)[9]));
521
            $last_mod_date = $date if ($last_mod_date < $date);
522
        }
523
        $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
524
    }
525

526
    if ($camelcase_cache ne "" && -f $camelcase_cache) {
527
        open(my $camelcase_file, '<', "$camelcase_cache")
528
            or warn "$P: Can't read '$camelcase_cache' $!\n";
529
        while (<$camelcase_file>) {
530
            chomp;
531
            $camelcase{$_} = 1;
532
        }
533
        close($camelcase_file);
534
        return;
535
    }
536

537
    if (-e ".git") {
538
        $files = `git ls-files "include/*.h"`;
539
        @include_files = split('\n', $files);
540
    }
541

542
    foreach my $file (@include_files) {
543
        seed_camelcase_file($file);
544
    }
545

546
    if ($camelcase_cache ne "") {
547
        unlink glob ".checkpatch-camelcase.*";
548
        open(my $camelcase_file, '>', "$camelcase_cache")
549
            or warn "$P: Can't write '$camelcase_cache' $!\n";
550
        foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
551
            print $camelcase_file ("$_\n");
552
        }
553
        close($camelcase_file);
554
    }
555
}
556

557
$chk_signoff = 0 if ($file);
558

559
my @rawlines = ();
560
my @lines = ();
561
my @fixed = ();
562
my $vname;
563
for my $filename (@ARGV) {
564
    my $FILE;
565
    if ($file) {
566
        open($FILE, '-|', "diff -u /dev/null $filename") ||
567
            die "$P: $filename: diff failed - $!\n";
568
    } elsif ($filename eq '-') {
569
        open($FILE, '<&STDIN');
570
    } else {
571
        open($FILE, '<', "$filename") ||
572
            die "$P: $filename: open failed - $!\n";
573
    }
574
    if ($filename eq '-') {
575
        $vname = 'Your patch';
576
    } else {
577
        $vname = $filename;
578
    }
579
    while (<$FILE>) {
580
        chomp;
581
        push(@rawlines, $_);
582
    }
583
    close($FILE);
584
    if (!process($filename)) {
585
        $exit = 1;
586
    }
587
    @rawlines = ();
588
    @lines = ();
589
    @fixed = ();
590
}
591

592
exit($exit);
593

594
sub top_of_glusterfs_tree {
595
    my ($root) = @_;
596

597
    # Add here if the tree changes
598
    my @tree_check = (
599
        "api",
600
        "AUTHORS",
601
        "autogen.sh",
602
        "build-aux",
603
        "ChangeLog",
604
        "cli",
605
        "configure.ac",
606
        "contrib",
607
        "CONTRIBUTING",
608
        "COPYING-GPLV2",
609
        "COPYING-LGPLV3",
610
        "doc",
611
        "extras",
612
        "geo-replication",
613
        "glusterfs-api.pc.in",
614
        "glusterfsd",
615
        "glusterfs.spec.in",
616
        "heal",
617
        "INSTALL",
618
        "libgfchangelog.pc.in",
619
        "libglusterfs",
620
        "MAINTAINERS",
621
        "Makefile.am",
622
        "NEWS",
623
        "README.md",
624
        "rfc.sh",
625
        "rpc",
626
        "run-tests.sh",
627
        "tests",
628
        "THANKS",
629
        "xlators",
630
        );
631

632
    foreach my $check (@tree_check) {
633
        if (! -e $root . '/' . $check) {
634
            return 0;
635
        }
636
    }
637
    return 1;
638
}
639

640
sub parse_email {
641
    my ($formatted_email) = @_;
642

643
    my $name = "";
644
    my $address = "";
645
    my $comment = "";
646

647
    if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
648
        $name = $1;
649
        $address = $2;
650
        $comment = $3 if defined $3;
651
    } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
652
        $address = $1;
653
        $comment = $2 if defined $2;
654
    } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
655
        $address = $1;
656
        $comment = $2 if defined $2;
657
        $formatted_email =~ s/$address.*$//;
658
        $name = $formatted_email;
659
        $name = trim($name);
660
        $name =~ s/^\"|\"$//g;
661
        # If there's a name left after stripping spaces and
662
        # leading quotes, and the address doesn't have both
663
        # leading and trailing angle brackets, the address
664
        # is invalid. ie:
665
        #   "joe smith joe@smith.com" bad
666
        #   "joe smith <joe@smith.com" bad
667
        if ($name ne "" && $address !~ /^<[^>]+>$/) {
668
            $name = "";
669
            $address = "";
670
            $comment = "";
671
        }
672
    }
673

674
    $name = trim($name);
675
    $name =~ s/^\"|\"$//g;
676
    $address = trim($address);
677
    $address =~ s/^\<|\>$//g;
678

679
    if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
680
        $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
681
        $name = "\"$name\"";
682
    }
683

684
    return ($name, $address, $comment);
685
}
686

687
sub format_email {
688
    my ($name, $address) = @_;
689

690
    my $formatted_email;
691

692
    $name = trim($name);
693
    $name =~ s/^\"|\"$//g;
694
    $address = trim($address);
695

696
    if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
697
        $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
698
        $name = "\"$name\"";
699
    }
700

701
    if ("$name" eq "") {
702
        $formatted_email = "$address";
703
    } else {
704
        $formatted_email = "$name <$address>";
705
    }
706

707
    return $formatted_email;
708
}
709

710
sub which_conf {
711
    my ($conf) = @_;
712

713
    foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
714
        if (-e "$path/$conf") {
715
            return "$path/$conf";
716
        }
717
    }
718

719
    return "";
720
}
721

722
sub expand_tabs {
723
    my ($str) = @_;
724

725
    my $res = '';
726
    my $n = 0;
727
    for my $c (split(//, $str)) {
728
        if ($c eq "\t") {
729
            $res .= ' ';
730
            $n++;
731
            for (; ($n % 8) != 0; $n++) {
732
                $res .= ' ';
733
            }
734
            next;
735
        }
736
        $res .= $c;
737
        $n++;
738
    }
739
    return $res;
740
}
741
sub copy_spacing {
742
    (my $res = shift) =~ tr/\t/ /c;
743
    return $res;
744
}
745

746
sub line_stats {
747
    my ($line) = @_;
748

749
    # Drop the diff line leader and expand tabs
750
    $line =~ s/^.//;
751
    $line = expand_tabs($line);
752

753
    # Pick the indent from the front of the line.
754
    my ($white) = ($line =~ /^(\s*)/);
755

756
    return (length($line), length($white));
757
}
758

759
my $sanitise_quote = '';
760

761
sub sanitise_line_reset {
762
    my ($in_comment) = @_;
763

764
    if ($in_comment) {
765
        $sanitise_quote = '*/';
766
    } else {
767
        $sanitise_quote = '';
768
    }
769
}
770
sub sanitise_line {
771
    my ($line) = @_;
772

773
    my $res = '';
774
    my $l = '';
775

776
    my $qlen = 0;
777
    my $off = 0;
778
    my $c;
779

780
    # Always copy over the diff marker.
781
    $res = substr($line, 0, 1);
782

783
    for ($off = 1; $off < length($line); $off++) {
784
        $c = substr($line, $off, 1);
785

786
        # Comments we are wacking completly including the begin
787
        # and end, all to $;.
788
        if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
789
            $sanitise_quote = '*/';
790

791
            substr($res, $off, 2, "$;$;");
792
            $off++;
793
            next;
794
        }
795
        if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
796
            $sanitise_quote = '';
797
            substr($res, $off, 2, "$;$;");
798
            $off++;
799
            next;
800
        }
801
        if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
802
            $sanitise_quote = '//';
803

804
            substr($res, $off, 2, $sanitise_quote);
805
            $off++;
806
            next;
807
        }
808

809
        # A \ in a string means ignore the next character.
810
        if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
811
            $c eq "\\") {
812
            substr($res, $off, 2, 'XX');
813
            $off++;
814
            next;
815
        }
816
        # Regular quotes.
817
        if ($c eq "'" || $c eq '"') {
818
            if ($sanitise_quote eq '') {
819
                $sanitise_quote = $c;
820

821
                substr($res, $off, 1, $c);
822
                next;
823
            } elsif ($sanitise_quote eq $c) {
824
                $sanitise_quote = '';
825
            }
826
        }
827

828
        #print "c<$c> SQ<$sanitise_quote>\n";
829
        if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
830
            substr($res, $off, 1, $;);
831
        } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
832
            substr($res, $off, 1, $;);
833
        } elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
834
            substr($res, $off, 1, 'X');
835
        } else {
836
            substr($res, $off, 1, $c);
837
        }
838
    }
839

840
    if ($sanitise_quote eq '//') {
841
        $sanitise_quote = '';
842
    }
843

844
    # The pathname on a #include may be surrounded by '<' and '>'.
845
    if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
846
        my $clean = 'X' x length($1);
847
        $res =~ s@\<.*\>@<$clean>@;
848

849
    # The whole of a #error is a string.
850
    } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
851
        my $clean = 'X' x length($1);
852
        $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
853
    }
854

855
    return $res;
856
}
857

858
sub get_quoted_string {
859
    my ($line, $rawline) = @_;
860

861
    return "" if ($line !~ m/(\"[X]+\")/g);
862
    return substr($rawline, $-[0], $+[0] - $-[0]);
863
}
864

865
sub ctx_statement_block {
866
    my ($linenr, $remain, $off) = @_;
867
    my $line = $linenr - 1;
868
    my $blk = '';
869
    my $soff = $off;
870
    my $coff = $off - 1;
871
    my $coff_set = 0;
872

873
    my $loff = 0;
874

875
    my $type = '';
876
    my $level = 0;
877
    my @stack = ();
878
    my $p;
879
    my $c;
880
    my $len = 0;
881

882
    my $remainder;
883
    while (1) {
884
        @stack = (['', 0]) if ($#stack == -1);
885

886
        #warn "CSB: blk<$blk> remain<$remain>\n";
887
        # If we are about to drop off the end, pull in more
888
        # context.
889
        if ($off >= $len) {
890
            for (; $remain > 0; $line++) {
891
                last if (!defined $lines[$line]);
892
                next if ($lines[$line] =~ /^-/);
893
                $remain--;
894
                $loff = $len;
895
                $blk .= $lines[$line] . "\n";
896
                $len = length($blk);
897
                $line++;
898
                last;
899
            }
900
            # Bail if there is no further context.
901
            #warn "CSB: blk<$blk> off<$off> len<$len>\n";
902
            if ($off >= $len) {
903
                last;
904
            }
905
            if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
906
                $level++;
907
                $type = '#';
908
            }
909
        }
910
        $p = $c;
911
        $c = substr($blk, $off, 1);
912
        $remainder = substr($blk, $off);
913

914
        #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
915

916
        # Handle nested #if/#else.
917
        if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
918
            push(@stack, [ $type, $level ]);
919
        } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
920
            ($type, $level) = @{$stack[$#stack - 1]};
921
        } elsif ($remainder =~ /^#\s*endif\b/) {
922
            ($type, $level) = @{pop(@stack)};
923
        }
924

925
        # Statement ends at the ';' or a close '}' at the
926
        # outermost level.
927
        if ($level == 0 && $c eq ';') {
928
            last;
929
        }
930

931
        # An else is really a conditional as long as its not else if
932
        if ($level == 0 && $coff_set == 0 &&
933
            (!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
934
            $remainder =~ /^(else)(?:\s|{)/ &&
935
            $remainder !~ /^else\s+if\b/) {
936
            $coff = $off + length($1) - 1;
937
            $coff_set = 1;
938
            #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
939
            #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
940
        }
941

942
        if (($type eq '' || $type eq '(') && $c eq '(') {
943
            $level++;
944
            $type = '(';
945
        }
946
        if ($type eq '(' && $c eq ')') {
947
            $level--;
948
            $type = ($level != 0)? '(' : '';
949

950
            if ($level == 0 && $coff < $soff) {
951
                $coff = $off;
952
                $coff_set = 1;
953
                #warn "CSB: mark coff<$coff>\n";
954
            }
955
        }
956
        if (($type eq '' || $type eq '{') && $c eq '{') {
957
            $level++;
958
            $type = '{';
959
        }
960
        if ($type eq '{' && $c eq '}') {
961
            $level--;
962
            $type = ($level != 0)? '{' : '';
963

964
            if ($level == 0) {
965
                if (substr($blk, $off + 1, 1) eq ';') {
966
                    $off++;
967
                }
968
                last;
969
            }
970
        }
971
        # Preprocessor commands end at the newline unless escaped.
972
        if ($type eq '#' && $c eq "\n" && $p ne "\\") {
973
            $level--;
974
            $type = '';
975
            $off++;
976
            last;
977
        }
978
        $off++;
979
    }
980
    # We are truly at the end, so shuffle to the next line.
981
    if ($off == $len) {
982
        $loff = $len + 1;
983
        $line++;
984
        $remain--;
985
    }
986

987
    my $statement = substr($blk, $soff, $off - $soff + 1);
988
    my $condition = substr($blk, $soff, $coff - $soff + 1);
989

990
    #warn "STATEMENT<$statement>\n";
991
    #warn "CONDITION<$condition>\n";
992

993
    #print "coff<$coff> soff<$off> loff<$loff>\n";
994

995
    return ($statement, $condition,
996
            $line, $remain + 1, $off - $loff + 1, $level);
997
}
998

999
sub statement_lines {
1000
    my ($stmt) = @_;
1001

1002
    # Strip the diff line prefixes and rip blank lines at start and end.
1003
    $stmt =~ s/(^|\n)./$1/g;
1004
    $stmt =~ s/^\s*//;
1005
    $stmt =~ s/\s*$//;
1006

1007
    my @stmt_lines = ($stmt =~ /\n/g);
1008

1009
    return $#stmt_lines + 2;
1010
}
1011

1012
sub statement_rawlines {
1013
    my ($stmt) = @_;
1014

1015
    my @stmt_lines = ($stmt =~ /\n/g);
1016

1017
    return $#stmt_lines + 2;
1018
}
1019

1020
sub statement_block_size {
1021
    my ($stmt) = @_;
1022

1023
    $stmt =~ s/(^|\n)./$1/g;
1024
    $stmt =~ s/^\s*{//;
1025
    $stmt =~ s/}\s*$//;
1026
    $stmt =~ s/^\s*//;
1027
    $stmt =~ s/\s*$//;
1028

1029
    my @stmt_lines = ($stmt =~ /\n/g);
1030
    my @stmt_statements = ($stmt =~ /;/g);
1031

1032
    my $stmt_lines = $#stmt_lines + 2;
1033
    my $stmt_statements = $#stmt_statements + 1;
1034

1035
    if ($stmt_lines > $stmt_statements) {
1036
        return $stmt_lines;
1037
    } else {
1038
        return $stmt_statements;
1039
    }
1040
}
1041

1042
sub ctx_statement_full {
1043
    my ($linenr, $remain, $off) = @_;
1044
    my ($statement, $condition, $level);
1045

1046
    my (@chunks);
1047

1048
    # Grab the first conditional/block pair.
1049
    ($statement, $condition, $linenr, $remain, $off, $level) =
1050
        ctx_statement_block($linenr, $remain, $off);
1051
    #print "F: c<$condition> s<$statement> remain<$remain>\n";
1052
    push(@chunks, [ $condition, $statement ]);
1053
    if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1054
        return ($level, $linenr, @chunks);
1055
    }
1056

1057
    # Pull in the following conditional/block pairs and see if they
1058
    # could continue the statement.
1059
    for (;;) {
1060
        ($statement, $condition, $linenr, $remain, $off, $level) =
1061
            ctx_statement_block($linenr, $remain, $off);
1062
        #print "C: c<$condition> s<$statement> remain<$remain>\n";
1063
        last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1064
        #print "C: push\n";
1065
        push(@chunks, [ $condition, $statement ]);
1066
    }
1067

1068
    return ($level, $linenr, @chunks);
1069
}
1070

1071
sub ctx_block_get {
1072
    my ($linenr, $remain, $outer, $open, $close, $off) = @_;
1073
    my $line;
1074
    my $start = $linenr - 1;
1075
    my $blk = '';
1076
    my @o;
1077
    my @c;
1078
    my @res = ();
1079

1080
    my $level = 0;
1081
    my @stack = ($level);
1082
    for ($line = $start; $remain > 0; $line++) {
1083
        next if ($rawlines[$line] =~ /^-/);
1084
        $remain--;
1085

1086
        $blk .= $rawlines[$line];
1087

1088
        # Handle nested #if/#else.
1089
        if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
1090
            push(@stack, $level);
1091
        } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
1092
            $level = $stack[$#stack - 1];
1093
        } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
1094
            $level = pop(@stack);
1095
        }
1096

1097
        foreach my $c (split(//, $lines[$line])) {
1098
            ##print "C<$c>L<$level><$open$close>O<$off>\n";
1099
            if ($off > 0) {
1100
                $off--;
1101
                next;
1102
            }
1103

1104
            if ($c eq $close && $level > 0) {
1105
                $level--;
1106
                last if ($level == 0);
1107
            } elsif ($c eq $open) {
1108
                $level++;
1109
            }
1110
        }
1111

1112
        if (!$outer || $level <= 1) {
1113
            push(@res, $rawlines[$line]);
1114
        }
1115

1116
        last if ($level == 0);
1117
    }
1118

1119
    return ($level, @res);
1120
}
1121
sub ctx_block_outer {
1122
    my ($linenr, $remain) = @_;
1123

1124
    my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1125
    return @r;
1126
}
1127
sub ctx_block {
1128
    my ($linenr, $remain) = @_;
1129

1130
    my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1131
    return @r;
1132
}
1133
sub ctx_statement {
1134
    my ($linenr, $remain, $off) = @_;
1135

1136
    my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1137
    return @r;
1138
}
1139
sub ctx_block_level {
1140
    my ($linenr, $remain) = @_;
1141

1142
    return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1143
}
1144
sub ctx_statement_level {
1145
    my ($linenr, $remain, $off) = @_;
1146

1147
    return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1148
}
1149

1150
sub ctx_locate_comment {
1151
    my ($first_line, $end_line) = @_;
1152

1153
    # Catch a comment on the end of the line itself.
1154
    my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
1155
    return $current_comment if (defined $current_comment);
1156

1157
    # Look through the context and try and figure out if there is a
1158
    # comment.
1159
    my $in_comment = 0;
1160
    $current_comment = '';
1161
    for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
1162
        my $line = $rawlines[$linenr - 1];
1163
        #warn "           $line\n";
1164
        if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
1165
            $in_comment = 1;
1166
        }
1167
        if ($line =~ m@/\*@) {
1168
            $in_comment = 1;
1169
        }
1170
        if (!$in_comment && $current_comment ne '') {
1171
            $current_comment = '';
1172
        }
1173
        $current_comment .= $line . "\n" if ($in_comment);
1174
        if ($line =~ m@\*/@) {
1175
            $in_comment = 0;
1176
        }
1177
    }
1178

1179
    chomp($current_comment);
1180
    return($current_comment);
1181
}
1182
sub ctx_has_comment {
1183
    my ($first_line, $end_line) = @_;
1184
    my $cmt = ctx_locate_comment($first_line, $end_line);
1185

1186
    ##print "LINE: $rawlines[$end_line - 1 ]\n";
1187
    ##print "CMMT: $cmt\n";
1188

1189
    return ($cmt ne '');
1190
}
1191

1192
sub raw_line {
1193
    my ($linenr, $cnt) = @_;
1194

1195
    my $offset = $linenr - 1;
1196
    $cnt++;
1197

1198
    my $line;
1199
    while ($cnt) {
1200
        $line = $rawlines[$offset++];
1201
        next if (defined($line) && $line =~ /^-/);
1202
        $cnt--;
1203
    }
1204
    return $line;
1205
}
1206

1207
sub cat_vet {
1208
    my ($vet) = @_;
1209
    my ($res, $coded);
1210

1211
    $res = '';
1212
    while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
1213
        $res .= $1;
1214
        if ($2 ne '') {
1215
            $coded = sprintf("^%c", unpack('C', $2) + 64);
1216
            $res .= $coded;
1217
        }
1218
    }
1219
    $res =~ s/$/\$/;
1220
    return $res;
1221
}
1222

1223
my $av_preprocessor = 0;
1224
my $av_pending;
1225
my @av_paren_type;
1226
my $av_pend_colon;
1227

1228
sub annotate_reset {
1229
    $av_preprocessor = 0;
1230
    $av_pending = '_';
1231
    @av_paren_type = ('E');
1232
    $av_pend_colon = 'O';
1233
}
1234

1235
sub annotate_values {
1236
    my ($stream, $type) = @_;
1237

1238
    my $res;
1239
    my $var = '_' x length($stream);
1240
    my $cur = $stream;
1241

1242
    print "$stream\n" if ($dbg_values > 1);
1243

1244
    while (length($cur)) {
1245
        @av_paren_type = ('E') if ($#av_paren_type < 0);
1246
        print " <" . join('', @av_paren_type) .
1247
            "> <$type> <$av_pending>" if ($dbg_values > 1);
1248
        if ($cur =~ /^(\s+)/o) {
1249
            print "WS($1)\n" if ($dbg_values > 1);
1250
            if ($1 =~ /\n/ && $av_preprocessor) {
1251
                $type = pop(@av_paren_type);
1252
                $av_preprocessor = 0;
1253
            }
1254

1255
        } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
1256
            print "CAST($1)\n" if ($dbg_values > 1);
1257
            push(@av_paren_type, $type);
1258
            $type = 'c';
1259

1260
        } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
1261
            print "DECLARE($1)\n" if ($dbg_values > 1);
1262
            $type = 'T';
1263

1264
        } elsif ($cur =~ /^($Modifier)\s*/) {
1265
            print "MODIFIER($1)\n" if ($dbg_values > 1);
1266
            $type = 'T';
1267

1268
        } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
1269
            print "DEFINE($1,$2)\n" if ($dbg_values > 1);
1270
            $av_preprocessor = 1;
1271
            push(@av_paren_type, $type);
1272
            if ($2 ne '') {
1273
                $av_pending = 'N';
1274
            }
1275
            $type = 'E';
1276

1277
        } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
1278
            print "UNDEF($1)\n" if ($dbg_values > 1);
1279
            $av_preprocessor = 1;
1280
            push(@av_paren_type, $type);
1281

1282
        } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
1283
            print "PRE_START($1)\n" if ($dbg_values > 1);
1284
            $av_preprocessor = 1;
1285

1286
            push(@av_paren_type, $type);
1287
            push(@av_paren_type, $type);
1288
            $type = 'E';
1289

1290
        } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
1291
            print "PRE_RESTART($1)\n" if ($dbg_values > 1);
1292
            $av_preprocessor = 1;
1293

1294
            push(@av_paren_type, $av_paren_type[$#av_paren_type]);
1295

1296
            $type = 'E';
1297

1298
        } elsif ($cur =~ /^(\#\s*(?:endif))/o) {
1299
            print "PRE_END($1)\n" if ($dbg_values > 1);
1300

1301
            $av_preprocessor = 1;
1302

1303
            # Assume all arms of the conditional end as this
1304
            # one does, and continue as if the #endif was not here.
1305
            pop(@av_paren_type);
1306
            push(@av_paren_type, $type);
1307
            $type = 'E';
1308

1309
        } elsif ($cur =~ /^(\\\n)/o) {
1310
            print "PRECONT($1)\n" if ($dbg_values > 1);
1311

1312
        } elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
1313
            print "ATTR($1)\n" if ($dbg_values > 1);
1314
            $av_pending = $type;
1315
            $type = 'N';
1316

1317
        } elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
1318
            print "SIZEOF($1)\n" if ($dbg_values > 1);
1319
            if (defined $2) {
1320
                $av_pending = 'V';
1321
            }
1322
            $type = 'N';
1323

1324
        } elsif ($cur =~ /^(if|while|for)\b/o) {
1325
            print "COND($1)\n" if ($dbg_values > 1);
1326
            $av_pending = 'E';
1327
            $type = 'N';
1328

1329
        } elsif ($cur =~/^(case)/o) {
1330
            print "CASE($1)\n" if ($dbg_values > 1);
1331
            $av_pend_colon = 'C';
1332
            $type = 'N';
1333

1334
        } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
1335
            print "KEYWORD($1)\n" if ($dbg_values > 1);
1336
            $type = 'N';
1337

1338
        } elsif ($cur =~ /^(\()/o) {
1339
            print "PAREN('$1')\n" if ($dbg_values > 1);
1340
            push(@av_paren_type, $av_pending);
1341
            $av_pending = '_';
1342
            $type = 'N';
1343

1344
        } elsif ($cur =~ /^(\))/o) {
1345
            my $new_type = pop(@av_paren_type);
1346
            if ($new_type ne '_') {
1347
                $type = $new_type;
1348
                print "PAREN('$1') -> $type\n"
1349
                    if ($dbg_values > 1);
1350
            } else {
1351
                print "PAREN('$1')\n" if ($dbg_values > 1);
1352
            }
1353

1354
        } elsif ($cur =~ /^($Ident)\s*\(/o) {
1355
            print "FUNC($1)\n" if ($dbg_values > 1);
1356
            $type = 'V';
1357
            $av_pending = 'V';
1358

1359
        } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
1360
            if (defined $2 && $type eq 'C' || $type eq 'T') {
1361
                $av_pend_colon = 'B';
1362
            } elsif ($type eq 'E') {
1363
                $av_pend_colon = 'L';
1364
            }
1365
            print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
1366
            $type = 'V';
1367

1368
        } elsif ($cur =~ /^($Ident|$Constant)/o) {
1369
            print "IDENT($1)\n" if ($dbg_values > 1);
1370
            $type = 'V';
1371

1372
        } elsif ($cur =~ /^($Assignment)/o) {
1373
            print "ASSIGN($1)\n" if ($dbg_values > 1);
1374
            $type = 'N';
1375

1376
        } elsif ($cur =~/^(;|{|})/) {
1377
            print "END($1)\n" if ($dbg_values > 1);
1378
            $type = 'E';
1379
            $av_pend_colon = 'O';
1380

1381
        } elsif ($cur =~/^(,)/) {
1382
            print "COMMA($1)\n" if ($dbg_values > 1);
1383
            $type = 'C';
1384

1385
        } elsif ($cur =~ /^(\?)/o) {
1386
            print "QUESTION($1)\n" if ($dbg_values > 1);
1387
            $type = 'N';
1388

1389
        } elsif ($cur =~ /^(:)/o) {
1390
            print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
1391

1392
            substr($var, length($res), 1, $av_pend_colon);
1393
            if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
1394
                $type = 'E';
1395
            } else {
1396
                $type = 'N';
1397
            }
1398
            $av_pend_colon = 'O';
1399

1400
        } elsif ($cur =~ /^(\[)/o) {
1401
            print "CLOSE($1)\n" if ($dbg_values > 1);
1402
            $type = 'N';
1403

1404
        } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
1405
            my $variant;
1406

1407
            print "OPV($1)\n" if ($dbg_values > 1);
1408
            if ($type eq 'V') {
1409
                $variant = 'B';
1410
            } else {
1411
                $variant = 'U';
1412
            }
1413

1414
            substr($var, length($res), 1, $variant);
1415
            $type = 'N';
1416

1417
        } elsif ($cur =~ /^($Operators)/o) {
1418
            print "OP($1)\n" if ($dbg_values > 1);
1419
            if ($1 ne '++' && $1 ne '--') {
1420
                $type = 'N';
1421
            }
1422

1423
        } elsif ($cur =~ /(^.)/o) {
1424
            print "C($1)\n" if ($dbg_values > 1);
1425
        }
1426
        if (defined $1) {
1427
            $cur = substr($cur, length($1));
1428
            $res .= $type x length($1);
1429
        }
1430
    }
1431

1432
    return ($res, $var);
1433
}
1434

1435
sub possible {
1436
    my ($possible, $line) = @_;
1437
    my $notPermitted = qr{(?:
1438
                ^(?:
1439
                        $Modifier|
1440
                        $Storage|
1441
                        $Type|
1442
                        DEFINE_\S+
1443
                )$|
1444
                ^(?:
1445
                        goto|
1446
                        return|
1447
                        case|
1448
                        else|
1449
                        asm|__asm__|
1450
                        do|
1451
                        \#|
1452
                        \#\#|
1453
                )(?:\s|$)|
1454
                ^(?:typedef|struct|enum)\b
1455
            )}x;
1456
    warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
1457
    if ($possible !~ $notPermitted) {
1458
        # Check for modifiers.
1459
        $possible =~ s/\s*$Storage\s*//g;
1460
        $possible =~ s/\s*$Sparse\s*//g;
1461
        if ($possible =~ /^\s*$/) {
1462

1463
        } elsif ($possible =~ /\s/) {
1464
            $possible =~ s/\s*$Type\s*//g;
1465
            for my $modifier (split(' ', $possible)) {
1466
                if ($modifier !~ $notPermitted) {
1467
                    warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
1468
                    push(@modifierList, $modifier);
1469
                }
1470
            }
1471

1472
        } else {
1473
            warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
1474
            push(@typeList, $possible);
1475
        }
1476
        build_types();
1477
    } else {
1478
        warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
1479
    }
1480
}
1481

1482
my $prefix = '';
1483

1484
sub show_type {
1485
    my ($type) = @_;
1486

1487
    return defined $use_type{$type} if (scalar keys %use_type > 0);
1488

1489
    return !defined $ignore_type{$type};
1490
}
1491

1492
sub report {
1493
    my ($level, $type, $msg) = @_;
1494

1495
    if (!show_type($type) ||
1496
        (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
1497
        return 0;
1498
    }
1499
    my $line;
1500
    if ($show_types) {
1501
        $line = "$prefix$level:$type: $msg\n";
1502
    } else {
1503
        $line = "$prefix$level: $msg\n";
1504
    }
1505
    $line = (split('\n', $line))[0] . "\n" if ($terse);
1506

1507
    if ($quiet == 0) {
1508
        push(our @report, $line);
1509
    }
1510
    return 1;
1511
}
1512

1513
sub report_dump {
1514
    our @report;
1515
}
1516

1517
sub ERROR {
1518
    my ($type, $msg) = @_;
1519

1520
    if (report("ERROR", $type, $msg)) {
1521
        our $clean = 0;
1522
        our $cnt_error++;
1523
        return 1;
1524
    }
1525
    return 0;
1526
}
1527
sub WARN {
1528
    my ($type, $msg) = @_;
1529

1530
    if (report("WARNING", $type, $msg)) {
1531
        ## Warning is okay to submit
1532
        our $clean = 0;
1533
        our $cnt_warn++;
1534
        return 1;
1535
    }
1536
    return 0;
1537
}
1538
sub CHK {
1539
    my ($type, $msg) = @_;
1540

1541
    if ($check && report("CHECK", $type, $msg)) {
1542
        our $clean = 0;
1543
        our $cnt_chk++;
1544
        return 1;
1545
    }
1546
    return 0;
1547
}
1548

1549
sub check_absolute_file {
1550
    my ($absolute, $herecurr) = @_;
1551
    my $file = $absolute;
1552

1553
    ##print "absolute<$absolute>\n";
1554

1555
    # See if any suffix of this path is a path within the tree.
1556
    while ($file =~ s@^[^/]*/@@) {
1557
        if (-f "$root/$file") {
1558
            ##print "file<$file>\n";
1559
            last;
1560
        }
1561
    }
1562
    if (! -f _)  {
1563
        return 0;
1564
    }
1565

1566
    # It is, so see if the prefix is acceptable.
1567
    my $prefix = $absolute;
1568
    substr($prefix, -length($file)) = '';
1569

1570
    ##print "prefix<$prefix>\n";
1571
    if ($prefix ne ".../") {
1572
        WARN("USE_RELATIVE_PATH",
1573
             "use relative pathname instead of absolute in changelog text\n" . $herecurr);
1574
    }
1575
}
1576

1577
sub trim {
1578
    my ($string) = @_;
1579

1580
    $string =~ s/^\s+|\s+$//g;
1581

1582
    return $string;
1583
}
1584

1585
sub ltrim {
1586
    my ($string) = @_;
1587

1588
    $string =~ s/^\s+//;
1589

1590
    return $string;
1591
}
1592

1593
sub rtrim {
1594
    my ($string) = @_;
1595

1596
    $string =~ s/\s+$//;
1597

1598
    return $string;
1599
}
1600

1601
sub string_find_replace {
1602
    my ($string, $find, $replace) = @_;
1603

1604
    $string =~ s/$find/$replace/g;
1605

1606
    return $string;
1607
}
1608

1609
sub tabify {
1610
    my ($leading) = @_;
1611

1612
    my $source_indent = 8;
1613
    my $max_spaces_before_tab = $source_indent - 1;
1614
    my $spaces_to_tab = " " x $source_indent;
1615

1616
    #convert leading spaces to tabs
1617
    1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
1618
    #Remove spaces before a tab
1619
    1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
1620
    return "$leading";
1621
}
1622

1623
sub pos_last_openparen {
1624
    my ($line) = @_;
1625

1626
    my $pos = 0;
1627

1628
    my $opens = $line =~ tr/\(/\(/;
1629
    my $closes = $line =~ tr/\)/\)/;
1630

1631
    my $last_openparen = 0;
1632

1633
    if (($opens == 0) || ($closes >= $opens)) {
1634
        return -1;
1635
    }
1636

1637
    my $len = length($line);
1638

1639
    for ($pos = 0; $pos < $len; $pos++) {
1640
        my $string = substr($line, $pos);
1641
        if ($string =~ /^($FuncArg|$balanced_parens)/) {
1642
            $pos += length($1) - 1;
1643
        } elsif (substr($line, $pos, 1) eq '(') {
1644
            $last_openparen = $pos;
1645
        } elsif (index($string, '(') == -1) {
1646
            last;
1647
        }
1648
    }
1649

1650
    return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
1651
}
1652

1653
sub process {
1654
    my $filename = shift;
1655

1656
    my $linenr=0;
1657
    my $prevline="";
1658
    my $prevrawline="";
1659
    my $stashline="";
1660
    my $stashrawline="";
1661

1662
    my $length;
1663
    my $indent;
1664
    my $previndent=0;
1665
    my $stashindent=0;
1666

1667
    our $clean = 1;
1668
    my $signoff = 0;
1669
    my $subject_trailing_dot = 0;
1670
    my $is_patch = 0;
1671

1672
    my $in_header_lines = 1;
1673
    my $in_commit_log = 0; #Scanning lines before patch
1674

1675
    my $non_utf8_charset = 0;
1676

1677
    our @report = ();
1678
    our $cnt_lines = 0;
1679
    our $cnt_error = 0;
1680
    our $cnt_warn = 0;
1681
    our $cnt_chk = 0;
1682

1683
    # Trace the real file/line as we go.
1684
    my $realfile = '';
1685
    my $realline = 0;
1686
    my $realcnt = 0;
1687
    my $here = '';
1688
    my $in_comment = 0;
1689
    my $comment_edge = 0;
1690
    my $first_line = 0;
1691
    my $p1_prefix = '';
1692

1693
    my $prev_values = 'E';
1694

1695
    # suppression flags
1696
    my %suppress_ifbraces;
1697
    my %suppress_whiletrailers;
1698
    my %suppress_export;
1699
    my $suppress_statement = 0;
1700

1701
    my %signatures = ();
1702

1703
    # Pre-scan the patch sanitizing the lines.
1704
    # Pre-scan the patch looking for any __setup documentation.
1705
    #
1706
    my @setup_docs = ();
1707
    my $setup_docs = 0;
1708

1709
    my $camelcase_file_seeded = 0;
1710

1711
    sanitise_line_reset();
1712
    my $line;
1713
    foreach my $rawline (@rawlines) {
1714
        $linenr++;
1715
        $line = $rawline;
1716

1717
        push(@fixed, $rawline) if ($fix);
1718

1719
        if ($rawline=~/^\+\+\+\s+(\S+)/) {
1720
            $setup_docs = 0;
1721
            if ($1 =~ m@Documentation/kernel-parameters.txt$@) {
1722
                $setup_docs = 1;
1723
            }
1724
            #next;
1725
        }
1726
        if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
1727
            $realline=$1-1;
1728
            if (defined $2) {
1729
                $realcnt=$3+1;
1730
            } else {
1731
                $realcnt=1+1;
1732
            }
1733
            $in_comment = 0;
1734

1735
            # Guestimate if this is a continuing comment.  Run
1736
            # the context looking for a comment "edge".  If this
1737
            # edge is a close comment then we must be in a comment
1738
            # at context start.
1739
            my $edge;
1740
            my $cnt = $realcnt;
1741
            for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
1742
                next if (defined $rawlines[$ln - 1] &&
1743
                         $rawlines[$ln - 1] =~ /^-/);
1744
                $cnt--;
1745
                #print "RAW<$rawlines[$ln - 1]>\n";
1746
                last if (!defined $rawlines[$ln - 1]);
1747
                if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
1748
                    $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
1749
                    ($edge) = $1;
1750
                    last;
1751
                }
1752
            }
1753
            if (defined $edge && $edge eq '*/') {
1754
                $in_comment = 1;
1755
            }
1756

1757
            # Guestimate if this is a continuing comment.  If this
1758
            # is the start of a diff block and this line starts
1759
            # ' *' then it is very likely a comment.
1760
            if (!defined $edge &&
1761
                $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
1762
            {
1763
                $in_comment = 1;
1764
            }
1765

1766
            ##print "COMMENT:$in_comment edge<$edge> $rawline\n";
1767
            sanitise_line_reset($in_comment);
1768

1769
        } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
1770
            # Standardise the strings and chars within the input to
1771
            # simplify matching -- only bother with positive lines.
1772
            $line = sanitise_line($rawline);
1773
        }
1774
        push(@lines, $line);
1775

1776
        if ($realcnt > 1) {
1777
            $realcnt-- if ($line =~ /^(?:\+| |$)/);
1778
        } else {
1779
            $realcnt = 0;
1780
        }
1781

1782
        #print "==>$rawline\n";
1783
        #print "-->$line\n";
1784

1785
        if ($setup_docs && $line =~ /^\+/) {
1786
            push(@setup_docs, $line);
1787
        }
1788
    }
1789

1790
    $prefix = '';
1791

1792
    $realcnt = 0;
1793
    $linenr = 0;
1794
    foreach my $line (@lines) {
1795
        $linenr++;
1796
        my $sline = $line;      #copy of $line
1797
        $sline =~ s/$;/ /g;     #with comments as spaces
1798

1799
        my $rawline = $rawlines[$linenr - 1];
1800

1801
#extract the line range in the file after the patch is applied
1802
        if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
1803
            $is_patch = 1;
1804
            $first_line = $linenr + 1;
1805
            $realline=$1-1;
1806
            if (defined $2) {
1807
                $realcnt=$3+1;
1808
            } else {
1809
                $realcnt=1+1;
1810
            }
1811
            annotate_reset();
1812
            $prev_values = 'E';
1813

1814
            %suppress_ifbraces = ();
1815
            %suppress_whiletrailers = ();
1816
            %suppress_export = ();
1817
            $suppress_statement = 0;
1818
            next;
1819

1820
# track the line number as we move through the hunk, note that
1821
# new versions of GNU diff omit the leading space on completely
1822
# blank context lines so we need to count that too.
1823
        } elsif ($line =~ /^( |\+|$)/) {
1824
            $realline++;
1825
            $realcnt-- if ($realcnt != 0);
1826

1827
            # Measure the line length and indent.
1828
            ($length, $indent) = line_stats($rawline);
1829

1830
            # Track the previous line.
1831
            ($prevline, $stashline) = ($stashline, $line);
1832
            ($previndent, $stashindent) = ($stashindent, $indent);
1833
            ($prevrawline, $stashrawline) = ($stashrawline, $rawline);
1834

1835
            #warn "line<$line>\n";
1836

1837
        } elsif ($realcnt == 1) {
1838
            $realcnt--;
1839
        }
1840

1841
        my $hunk_line = ($realcnt != 0);
1842

1843
#make up the handle for any error we report on this line
1844
        $prefix = "$filename:$realline: " if ($emacs && $file);
1845
        $prefix = "$filename:$linenr: " if ($emacs && !$file);
1846

1847
        $here = "#$linenr: " if (!$file);
1848
        $here = "#$realline: " if ($file);
1849

1850
        my $found_file = 0;
1851
        # extract the filename as it passes
1852
        if ($line =~ /^diff --git.*?(\S+)$/) {
1853
            $realfile = $1;
1854
            $realfile =~ s@^([^/]*)/@@ if (!$file);
1855
            $in_commit_log = 0;
1856
            $found_file = 1;
1857
        } elsif ($line =~ /^\+\+\+\s+(\S+)/) {
1858
            $realfile = $1;
1859
            $realfile =~ s@^([^/]*)/@@ if (!$file);
1860
            $in_commit_log = 0;
1861

1862
            $p1_prefix = $1;
1863
            if (!$file && $tree && $p1_prefix ne '' &&
1864
                -e "$root/$p1_prefix") {
1865
                WARN("PATCH_PREFIX",
1866
                     "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
1867
            }
1868

1869
            $found_file = 1;
1870
        }
1871

1872
        if ($found_file) {
1873
            if ($realfile =~ m@^(drivers/net/|net/)@) {
1874
                $check = 1;
1875
            } else {
1876
                $check = $check_orig;
1877
            }
1878
            next;
1879
        }
1880

1881
        $here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
1882

1883
        my $hereline = "$here\n$rawline\n";
1884
        my $herecurr = "$here\n$rawline\n";
1885
        my $hereprev = "$here\n$prevrawline\n$rawline\n";
1886

1887
        $cnt_lines++ if ($realcnt != 0);
1888

1889
# Check for incorrect file permissions
1890
        if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
1891
            my $permhere = $here . "FILE: $realfile\n";
1892
            if ($realfile !~ m@scripts/@ &&
1893
                $realfile !~ /\.(py|pl|awk|sh|t)$/) {
1894
                ERROR("EXECUTE_PERMISSIONS",
1895
                      "do not set execute permissions for source files\n" . $permhere);
1896
            }
1897
        }
1898

1899
        next if ($realfile =~ /(checkpatch.pl)/);
1900
        next if ($realfile =~ /\.(md|txt|doc|8|pdf|tex)$/);
1901

1902
# Check that the subject does not have a trailing dot
1903
        if ($in_header_lines &&
1904
            $line =~ /^Subject: \[PATCH\] (.+)\.(\s*)$/) {
1905
                $subject_trailing_dot++;
1906
        }
1907

1908
# Check the patch for a signoff:
1909
        if ($line =~ /^\s*signed-off-by:/i) {
1910
            $signoff++;
1911
            $in_commit_log = 0;
1912
        }
1913

1914
# Check signature styles
1915
        if (!$in_header_lines &&
1916
            $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
1917
            my $space_before = $1;
1918
            my $sign_off = $2;
1919
            my $space_after = $3;
1920
            my $email = $4;
1921
            my $ucfirst_sign_off = ucfirst(lc($sign_off));
1922

1923
            if ($sign_off !~ /$signature_tags/) {
1924
                WARN("BAD_SIGN_OFF",
1925
                     "Non-standard signature: $sign_off\n" . $herecurr);
1926
            }
1927
            if (defined $space_before && $space_before ne "") {
1928
                if (WARN("BAD_SIGN_OFF",
1929
                         "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
1930
                    $fix) {
1931
                    $fixed[$linenr - 1] =
1932
                        "$ucfirst_sign_off $email";
1933
                }
1934
            }
1935
            if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
1936
                if (WARN("BAD_SIGN_OFF",
1937
                         "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
1938
                    $fix) {
1939
                    $fixed[$linenr - 1] =
1940
                        "$ucfirst_sign_off $email";
1941
                }
1942

1943
            }
1944
            if (!defined $space_after || $space_after ne " ") {
1945
                if (WARN("BAD_SIGN_OFF",
1946
                         "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
1947
                    $fix) {
1948
                    $fixed[$linenr - 1] =
1949
                        "$ucfirst_sign_off $email";
1950
                }
1951
            }
1952

1953
            # Check if email is really Gerrit URL
1954
            if ($email =~ /^($url_tags)(.*)/) {
1955
                my $uri = $1;
1956
                my $url = $2;
1957
                if ($uri && $url !~ /$gerrit_url/) {
1958
                    ERROR("BAD_URL",
1959
                          "Unrecognized url address: '$email'\n" . $herecurr);
1960
                }
1961
            } else {
1962
                my ($email_name, $email_address, $comment) = parse_email($email);
1963
                my $suggested_email = format_email(($email_name, $email_address));
1964
                if ($suggested_email eq "") {
1965
                    ERROR("BAD_SIGN_OFF",
1966
                          "Unrecognized email address: '$email'\n" . $herecurr);
1967
                } else {
1968
                    my $dequoted = $suggested_email;
1969
                    $dequoted =~ s/^"//;
1970
                    $dequoted =~ s/" </ </;
1971
                    # Don't force email to have quotes
1972
                    # Allow just an angle bracketed address
1973
                    if ("$dequoted$comment" ne $email &&
1974
                        "<$email_address>$comment" ne $email &&
1975
                        "$suggested_email$comment" ne $email) {
1976
                        WARN("BAD_SIGN_OFF",
1977
                             "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
1978
                    }
1979
                }
1980
            }
1981

1982
# Check for duplicate signatures
1983
            my $sig_nospace = $line;
1984
            $sig_nospace =~ s/\s//g;
1985
            $sig_nospace = lc($sig_nospace);
1986
            if (defined $signatures{$sig_nospace}) {
1987
                WARN("BAD_SIGN_OFF",
1988
                     "Duplicate signature\n" . $herecurr);
1989
            } else {
1990
                $signatures{$sig_nospace} = 1;
1991
            }
1992
        }
1993

1994
# Check for wrappage within a valid hunk of the file
1995
        if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
1996
            ERROR("CORRUPTED_PATCH",
1997
                  "patch seems to be corrupt (line wrapped?)\n" .
1998
                  $herecurr) if (!$emitted_corrupt++);
1999
        }
2000

2001
# Check for absolute kernel paths.
2002
        if ($tree) {
2003
            while ($line =~ m{(?:^|\s)(/\S*)}g) {
2004
                my $file = $1;
2005

2006
                if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
2007
                    check_absolute_file($1, $herecurr)) {
2008
                    #
2009
                } else {
2010
                    check_absolute_file($file, $herecurr);
2011
                }
2012
            }
2013
        }
2014

2015
# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
2016
        if (($realfile =~ /^$/ || $line =~ /^\+/) &&
2017
            $rawline !~ m/^$UTF8*$/) {
2018
            my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
2019

2020
            my $blank = copy_spacing($rawline);
2021
            my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
2022
            my $hereptr = "$hereline$ptr\n";
2023

2024
            CHK("INVALID_UTF8",
2025
                "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
2026
        }
2027

2028
# Check if it's the start of a commit log
2029
# (not a header line and we haven't seen the patch filename)
2030
        if ($in_header_lines && $realfile =~ /^$/ &&
2031
            $rawline !~ /^(commit\b|from\b|[\w-]+:).+$/i) {
2032
            $in_header_lines = 0;
2033
            $in_commit_log = 1;
2034
        }
2035

2036
# Check if there is UTF-8 in a commit log when a mail header has explicitly
2037
# declined it, i.e defined some charset where it is missing.
2038
        if ($in_header_lines &&
2039
            $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
2040
            $1 !~ /utf-8/i) {
2041
            $non_utf8_charset = 1;
2042
        }
2043

2044
        if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
2045
            $rawline =~ /$NON_ASCII_UTF8/) {
2046
            WARN("UTF8_BEFORE_PATCH",
2047
                 "8-bit UTF-8 used in possible commit log\n" . $herecurr);
2048
        }
2049

2050
# ignore non-hunk lines and lines being removed
2051
        next if (!$hunk_line || $line =~ /^-/);
2052

2053
#trailing whitespace
2054
        if ($line =~ /^\+.*\015/) {
2055
            my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2056
            if (ERROR("DOS_LINE_ENDINGS",
2057
                      "DOS line endings\n" . $herevet) &&
2058
                $fix) {
2059
                $fixed[$linenr - 1] =~ s/[\s\015]+$//;
2060
            }
2061
        } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
2062
            my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2063
            if (ERROR("TRAILING_WHITESPACE",
2064
                      "trailing whitespace\n" . $herevet) &&
2065
                $fix) {
2066
                $fixed[$linenr - 1] =~ s/\s+$//;
2067
            }
2068

2069
            $rpt_cleaners = 1;
2070
        }
2071

2072
        if (($realfile =~ /Makefile.*/) &&
2073
            ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
2074
            my $flag = $1;
2075
            my $replacement = {
2076
                            'EXTRA_AFLAGS' =>   'asflags-y',
2077
                            'EXTRA_CFLAGS' =>   'ccflags-y',
2078
                            'EXTRA_CPPFLAGS' => 'cppflags-y',
2079
                            'EXTRA_LDFLAGS' =>  'ldflags-y',
2080
            };
2081

2082
            WARN("DEPRECATED_VARIABLE",
2083
                 "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
2084
        }
2085

2086
# check we are in .spec file, then ignore this hunk
2087
        next if ($realfile eq "glusterfs.spec.in");
2088

2089
# check we are in a valid source file if not then ignore this hunk
2090
        next if ($realfile !~ /\.(h|c|pl|py|l|y|sh|in)$/);
2091

2092
#line length limit
2093
        if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
2094
            $rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
2095
            !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:|,|\)\s*;)\s*$/ ||
2096
              $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) &&
2097
            $length > $max_line_length)
2098
        {
2099
            WARN("LONG_LINE",
2100
                 "line over $max_line_length characters\n" . $herecurr);
2101
        }
2102

2103
# check for spaces before a quoted newline
2104
        if ($rawline =~ /^.*\".*\s\\n/) {
2105
            if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
2106
                     "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
2107
                $fix) {
2108
                $fixed[$linenr - 1] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
2109
            }
2110

2111
        }
2112

2113
# check for adding lines without a newline.
2114
        if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
2115
            WARN("MISSING_EOF_NEWLINE",
2116
                 "adding a line without newline at end of file\n" . $herecurr);
2117
        }
2118

2119
# check we are in a valid source file C or perl if not then ignore this hunk
2120
        next if ($realfile !~ /\.(h|c|pl)$/);
2121

2122
# check for space before tabs.
2123
        if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
2124
            my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2125
            if (WARN("SPACE_BEFORE_TAB",
2126
                     "please, no space before tabs\n" . $herevet) &&
2127
                $fix) {
2128
                while ($fixed[$linenr - 1] =~
2129
                       s/(^\+.*) {8,8}\t/$1\t\t/) {}
2130
                while ($fixed[$linenr - 1] =~
2131
                       s/(^\+.*) +\t/$1\t/) {}
2132
            }
2133
        }
2134

2135
# check for && or || at the start of a line
2136
        if ($rawline =~ /^\+\s*(&&|\|\|)/) {
2137
            CHK("LOGICAL_CONTINUATIONS",
2138
                "Logical continuations should be on the previous line\n" . $hereprev);
2139
        }
2140

2141
# check multi-line statement indentation matches previous line
2142
        if ($^V && $^V ge 5.10.0 &&
2143
            $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|$Ident\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
2144
            $prevline =~ /^\+(\t*)(.*)$/;
2145
            my $oldindent = $1;
2146
            my $rest = $2;
2147

2148
            my $pos = pos_last_openparen($rest);
2149
            if ($pos >= 0) {
2150
                $line =~ /^(\+| )([ \t]*)/;
2151
                my $newindent = $2;
2152

2153
                my $goodtabindent = $oldindent .
2154
                    "\t" x ($pos / 8) .
2155
                    " "  x ($pos % 8);
2156
                my $goodspaceindent = $oldindent . " "  x $pos;
2157

2158
                if ($newindent ne $goodtabindent &&
2159
                    $newindent ne $goodspaceindent) {
2160

2161
                    if (CHK("PARENTHESIS_ALIGNMENT",
2162
                            "Alignment should match open parenthesis\n" . $hereprev) &&
2163
                        $fix && $line =~ /^\+/) {
2164
                        $fixed[$linenr - 1] =~
2165
                            s/^\+[ \t]*/\+$goodtabindent/;
2166
                    }
2167
                }
2168
            }
2169
        }
2170

2171
        if ($line =~ /^\+.*\*[ \t]*\)[ \t]+(?!$Assignment|$Arithmetic)/) {
2172
            if (CHK("SPACING",
2173
                    "No space is necessary after a cast\n" . $hereprev) &&
2174
                $fix) {
2175
                $fixed[$linenr - 1] =~
2176
                    s/^(\+.*\*[ \t]*\))[ \t]+/$1/;
2177
            }
2178
        }
2179

2180

2181
# check for missing blank lines after declarations
2182
        if ($sline =~ /^\+\s+\S/ &&  #Not at char 1
2183
            # actual declarations
2184
            ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
2185
             # foo bar; where foo is some local typedef or #define
2186
             $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
2187
             # known declaration macros
2188
             $prevline =~ /^\+\s+$declaration_macros/) &&
2189
            # for "else if" which can look like "$Ident $Ident"
2190
            !($prevline =~ /^\+\s+$c90_Keywords\b/ ||
2191
              # other possible extensions of declaration lines
2192
              $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
2193
              # not starting a section or a macro "\" extended line
2194
              $prevline =~ /(?:\{\s*|\\)$/) &&
2195
            # looks like a declaration
2196
            !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
2197
              # foo bar; where foo is some local typedef or #define
2198
              $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
2199
              # known declaration macros
2200
              $sline =~ /^\+\s+$declaration_macros/ ||
2201
              # start of struct or union or enum
2202
              $sline =~ /^\+\s+(?:union|struct|enum|typedef)\b/ ||
2203
              # start or end of block or continuation of declaration
2204
              $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
2205
              # bitfield continuation
2206
              $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
2207
              # other possible extensions of declaration lines
2208
              $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) &&
2209
            # indentation of previous and current line are the same
2210
            (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) {
2211
            WARN("SPACING",
2212
                 "Missing a blank line after declarations\n" . $hereprev);
2213
        }
2214

2215
# check we are in a valid C source file if not then ignore this hunk
2216
        next if ($realfile !~ /\.(h|c)$/);
2217

2218
# check for RCS/CVS revision markers
2219
        if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
2220
            WARN("CVS_KEYWORD",
2221
                 "CVS style keyword markers, these will _not_ be updated\n". $herecurr);
2222
        }
2223

2224
# Check for potential 'bare' types
2225
        my ($stat, $cond, $line_nr_next, $remain_next, $off_next,
2226
            $realline_next);
2227
#print "LINE<$line>\n";
2228
        if ($linenr >= $suppress_statement &&
2229
            $realcnt && $sline =~ /.\s*\S/) {
2230
            ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
2231
                ctx_statement_block($linenr, $realcnt, 0);
2232
            $stat =~ s/\n./\n /g;
2233
            $cond =~ s/\n./\n /g;
2234

2235
#print "linenr<$linenr> <$stat>\n";
2236
            # If this statement has no statement boundaries within
2237
            # it there is no point in retrying a statement scan
2238
            # until we hit end of it.
2239
            my $frag = $stat; $frag =~ s/;+\s*$//;
2240
            if ($frag !~ /(?:{|;)/) {
2241
#print "skip<$line_nr_next>\n";
2242
                $suppress_statement = $line_nr_next;
2243
            }
2244

2245
            # Find the real next line.
2246
            $realline_next = $line_nr_next;
2247
            if (defined $realline_next &&
2248
                (!defined $lines[$realline_next - 1] ||
2249
                 substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) {
2250
                $realline_next++;
2251
            }
2252

2253
            my $s = $stat;
2254
            $s =~ s/{.*$//s;
2255

2256
            # Ignore goto labels.
2257
            if ($s =~ /$Ident:\*$/s) {
2258

2259
                # Ignore functions being called
2260
            } elsif ($s =~ /^.\s*$Ident\s*\(/s) {
2261

2262
            } elsif ($s =~ /^.\s*else\b/s) {
2263

2264
                # declarations always start with types
2265
            } 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) {
2266
                my $type = $1;
2267
                $type =~ s/\s+/ /g;
2268
                possible($type, "A:" . $s);
2269

2270
                # definitions in global scope can only start with types
2271
            } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
2272
                possible($1, "B:" . $s);
2273
            }
2274

2275
            # any (foo ... *) is a pointer cast, and foo is a type
2276
            while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) {
2277
                possible($1, "C:" . $s);
2278
            }
2279

2280
            # Check for any sort of function declaration.
2281
            # int foo(something bar, other baz);
2282
            # void (*store_gdt)(x86_descr_ptr *);
2283
            if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) {
2284
                my ($name_len) = length($1);
2285

2286
                my $ctx = $s;
2287
                substr($ctx, 0, $name_len + 1, '');
2288
                $ctx =~ s/\)[^\)]*$//;
2289

2290
                for my $arg (split(/\s*,\s*/, $ctx)) {
2291
                    if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) {
2292

2293
                        possible($1, "D:" . $s);
2294
                    }
2295
                }
2296
            }
2297

2298
        }
2299

2300
#
2301
# Checks which may be anchored in the context.
2302
#
2303

2304
# Check for switch () and associated case and default
2305
# statements should be at the same indent.
2306
        if ($line=~/\bswitch\s*\(.*\)/) {
2307
            my $err = '';
2308
            my $sep = '';
2309
            my @ctx = ctx_block_outer($linenr, $realcnt);
2310
            shift(@ctx);
2311
            for my $ctx (@ctx) {
2312
                my ($clen, $cindent) = line_stats($ctx);
2313
                if ($ctx =~ /^\+\s*(case\s+|default:)/ &&
2314
                    $indent != $cindent) {
2315
                    $err .= "$sep$ctx\n";
2316
                    $sep = '';
2317
                } else {
2318
                    $sep = "[...]\n";
2319
                }
2320
            }
2321
            if ($err ne '') {
2322
                ERROR("SWITCH_CASE_INDENT_LEVEL",
2323
                      "switch and case should be at the same indent\n$hereline$err");
2324
            }
2325
        }
2326

2327
# if/while/etc brace do not go on next line, unless defining a do while loop,
2328
# or if that brace on the next line is for something else
2329
        if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) {
2330
            my $pre_ctx = "$1$2";
2331

2332
            my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
2333

2334
            if ($line =~ /^\+\t{6,}/) {
2335
                WARN("DEEP_INDENTATION",
2336
                     "Too many leading tabs - consider code refactoring\n" . $herecurr);
2337
            }
2338

2339
            my $ctx_cnt = $realcnt - $#ctx - 1;
2340
            my $ctx = join("\n", @ctx);
2341

2342
            my $ctx_ln = $linenr;
2343
            my $ctx_skip = $realcnt;
2344

2345
            while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt &&
2346
                                            defined $lines[$ctx_ln - 1] &&
2347
                                            $lines[$ctx_ln - 1] =~ /^-/)) {
2348
                ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n";
2349
                $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/);
2350
                $ctx_ln++;
2351
            }
2352

2353
            #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
2354
            #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
2355

2356
            if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
2357
                ERROR("OPEN_BRACE",
2358
                      "that open brace { should be on the previous line\n" .
2359
                      "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
2360
            }
2361
            if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
2362
                $ctx =~ /\)\s*\;\s*$/ &&
2363
                defined $lines[$ctx_ln - 1])
2364
            {
2365
                my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
2366
                if ($nindent > $indent) {
2367
                    WARN("TRAILING_SEMICOLON",
2368
                         "trailing semicolon indicates no statements, indent implies otherwise\n" .
2369
                         "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
2370
                }
2371
            }
2372
        }
2373

2374
# Check relative indent for conditionals and blocks.
2375
        if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
2376
            ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
2377
                ctx_statement_block($linenr, $realcnt, 0)
2378
                if (!defined $stat);
2379
            my ($s, $c) = ($stat, $cond);
2380

2381
            substr($s, 0, length($c), '');
2382

2383
            # Make sure we remove the line prefixes as we have
2384
            # none on the first line, and are going to readd them
2385
            # where necessary.
2386
            $s =~ s/\n./\n/gs;
2387

2388
            # Find out how long the conditional actually is.
2389
            my @newlines = ($c =~ /\n/gs);
2390
            my $cond_lines = 1 + $#newlines;
2391

2392
            # We want to check the first line inside the block
2393
            # starting at the end of the conditional, so remove:
2394
            #  1) any blank line termination
2395
            #  2) any opening brace { on end of the line
2396
            #  3) any do (...) {
2397
            my $continuation = 0;
2398
            my $check = 0;
2399
            $s =~ s/^.*\bdo\b//;
2400
            $s =~ s/^\s*{//;
2401
            if ($s =~ s/^\s*\\//) {
2402
                $continuation = 1;
2403
            }
2404
            if ($s =~ s/^\s*?\n//) {
2405
                $check = 1;
2406
                $cond_lines++;
2407
            }
2408

2409
            # Also ignore a loop construct at the end of a
2410
            # preprocessor statement.
2411
            if (($prevline =~ /^.\s*#\s*define\s/ ||
2412
                 $prevline =~ /\\\s*$/) && $continuation == 0) {
2413
                $check = 0;
2414
            }
2415

2416
            my $cond_ptr = -1;
2417
            $continuation = 0;
2418
            while ($cond_ptr != $cond_lines) {
2419
                $cond_ptr = $cond_lines;
2420

2421
                # If we see an #else/#elif then the code
2422
                # is not linear.
2423
                if ($s =~ /^\s*\#\s*(?:else|elif)/) {
2424
                    $check = 0;
2425
                }
2426

2427
                # Ignore:
2428
                #  1) blank lines, they should be at 0,
2429
                #  2) preprocessor lines, and
2430
                #  3) labels.
2431
                if ($continuation ||
2432
                    $s =~ /^\s*?\n/ ||
2433
                    $s =~ /^\s*#\s*?/ ||
2434
                    $s =~ /^\s*$Ident\s*:/) {
2435
                    $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
2436
                    if ($s =~ s/^.*?\n//) {
2437
                        $cond_lines++;
2438
                    }
2439
                }
2440
            }
2441

2442
            my (undef, $sindent) = line_stats("+" . $s);
2443
            my $stat_real = raw_line($linenr, $cond_lines);
2444

2445
            # Check if either of these lines are modified, else
2446
            # this is not this patch's fault.
2447
            if (!defined($stat_real) ||
2448
                $stat !~ /^\+/ && $stat_real !~ /^\+/) {
2449
                $check = 0;
2450
            }
2451
            if (defined($stat_real) && $cond_lines > 1) {
2452
                $stat_real = "[...]\n$stat_real";
2453
            }
2454

2455
            #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";
2456

2457
            if ($check && (($sindent % 8) != 0 ||
2458
                           ($sindent <= $indent && $s ne ''))) {
2459
                WARN("SUSPECT_CODE_INDENT",
2460
                     "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
2461
            }
2462
        }
2463

2464
        # Track the 'values' across context and added lines.
2465
        my $opline = $line; $opline =~ s/^./ /;
2466
        my ($curr_values, $curr_vars) =
2467
            annotate_values($opline . "\n", $prev_values);
2468
        $curr_values = $prev_values . $curr_values;
2469
        if ($dbg_values) {
2470
            my $outline = $opline; $outline =~ s/\t/ /g;
2471
            print "$linenr > .$outline\n";
2472
            print "$linenr > $curr_values\n";
2473
            print "$linenr >  $curr_vars\n";
2474
        }
2475
        $prev_values = substr($curr_values, -1);
2476

2477
#ignore lines not being added
2478
        next if ($line =~ /^[^\+]/);
2479

2480
# TEST: allow direct testing of the type matcher.
2481
        if ($dbg_type) {
2482
            if ($line =~ /^.\s*$Declare\s*$/) {
2483
                ERROR("TEST_TYPE",
2484
                      "TEST: is type\n" . $herecurr);
2485
            } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) {
2486
                ERROR("TEST_NOT_TYPE",
2487
                      "TEST: is not type ($1 is)\n". $herecurr);
2488
            }
2489
            next;
2490
        }
2491
# TEST: allow direct testing of the attribute matcher.
2492
        if ($dbg_attr) {
2493
            if ($line =~ /^.\s*$Modifier\s*$/) {
2494
                ERROR("TEST_ATTR",
2495
                      "TEST: is attr\n" . $herecurr);
2496
            } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) {
2497
                ERROR("TEST_NOT_ATTR",
2498
                      "TEST: is not attr ($1 is)\n". $herecurr);
2499
            }
2500
            next;
2501
        }
2502

2503
# check for initialisation to aggregates open brace on the next line
2504
        if ($line =~ /^.\s*{/ &&
2505
            $prevline =~ /(?:^|[^=])=\s*$/) {
2506
            ERROR("OPEN_BRACE",
2507
                  "that open brace { should be on the previous line\n" . $hereprev);
2508
        }
2509

2510
#
2511
# Checks which are anchored on the added line.
2512
#
2513

2514
# check for malformed paths in #include statements (uses RAW line)
2515
        if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) {
2516
            my $path = $1;
2517
            if ($path =~ m{//}) {
2518
                ERROR("MALFORMED_INCLUDE",
2519
                      "malformed #include filename\n" . $herecurr);
2520
            }
2521
            if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) {
2522
                ERROR("UAPI_INCLUDE",
2523
                      "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr);
2524
            }
2525
        }
2526

2527
# no C99 // comments
2528
        if ($line =~ m{//}) {
2529
            if (ERROR("C99_COMMENTS",
2530
                      "do not use C99 // comments\n" . $herecurr) &&
2531
                $fix) {
2532
                my $line = $fixed[$linenr - 1];
2533
                if ($line =~ /\/\/(.*)$/) {
2534
                    my $comment = trim($1);
2535
                    $fixed[$linenr - 1] =~ s@\/\/(.*)$@/\* $comment \*/@;
2536
                }
2537
            }
2538
        }
2539
        # Remove C99 comments.
2540
        $line =~ s@//.*@@;
2541
        $opline =~ s@//.*@@;
2542

2543
# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider
2544
# the whole statement.
2545
#print "APW <$lines[$realline_next - 1]>\n";
2546
        if (defined $realline_next &&
2547
            exists $lines[$realline_next - 1] &&
2548
            !defined $suppress_export{$realline_next} &&
2549
            ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
2550
             $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
2551
            # Handle definitions which produce identifiers with
2552
            # a prefix:
2553
            #   XXX(foo);
2554
            #   EXPORT_SYMBOL(something_foo);
2555
            my $name = $1;
2556
            if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ &&
2557
                $name =~ /^${Ident}_$2/) {
2558
#print "FOO C name<$name>\n";
2559
                $suppress_export{$realline_next} = 1;
2560

2561
            } elsif ($stat !~ /(?:
2562
                                \n.}\s*$|
2563
                                ^.DEFINE_$Ident\(\Q$name\E\)|
2564
                                ^.DECLARE_$Ident\(\Q$name\E\)|
2565
                                ^.LIST_HEAD\(\Q$name\E\)|
2566
                                ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
2567
                                \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\()
2568
                            )/x) {
2569
#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n";
2570
                $suppress_export{$realline_next} = 2;
2571
            } else {
2572
                $suppress_export{$realline_next} = 1;
2573
            }
2574
        }
2575
        if (!defined $suppress_export{$linenr} &&
2576
            $prevline =~ /^.\s*$/ &&
2577
            ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ ||
2578
             $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
2579
#print "FOO B <$lines[$linenr - 1]>\n";
2580
            $suppress_export{$linenr} = 2;
2581
        }
2582
        if (defined $suppress_export{$linenr} &&
2583
            $suppress_export{$linenr} == 2) {
2584
            WARN("EXPORT_SYMBOL",
2585
                 "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
2586
        }
2587

2588
# check for global initialisers.
2589
        if ($line =~ /^\+(\s*$Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/) {
2590
            if (ERROR("GLOBAL_INITIALISERS",
2591
                      "do not initialise globals to 0 or NULL\n" .
2592
                      $herecurr) &&
2593
                $fix) {
2594
                $fixed[$linenr - 1] =~ s/($Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/$1;/;
2595
            }
2596
        }
2597
# check for static initialisers.
2598
        if ($line =~ /^\+.*\bstatic\s.*=\s*(0|NULL|false)\s*;/) {
2599
            if (ERROR("INITIALISED_STATIC",
2600
                      "do not initialise statics to 0 or NULL\n" .
2601
                      $herecurr) &&
2602
                $fix) {
2603
                $fixed[$linenr - 1] =~ s/(\bstatic\s.*?)\s*=\s*(0|NULL|false)\s*;/$1;/;
2604
            }
2605
        }
2606

2607
# check for static const char * arrays.
2608
        if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) {
2609
            WARN("STATIC_CONST_CHAR_ARRAY",
2610
                 "static const char * array should probably be static const char * const\n" .
2611
                 $herecurr);
2612
        }
2613

2614
# check for static char foo[] = "bar" declarations.
2615
        if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) {
2616
            WARN("STATIC_CONST_CHAR_ARRAY",
2617
                 "static char array declaration should probably be static const char\n" .
2618
                 $herecurr);
2619
        }
2620

2621
# check for non-global char *foo[] = {"bar", ...} declarations.
2622
        if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
2623
            WARN("STATIC_CONST_CHAR_ARRAY",
2624
                 "char * array declaration might be better as static const\n" .
2625
                 $herecurr);
2626
        }
2627

2628
# check for function declarations without arguments like "int foo()"
2629
        if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) {
2630
            if (ERROR("FUNCTION_WITHOUT_ARGS",
2631
                      "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
2632
                $fix) {
2633
                $fixed[$linenr - 1] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
2634
            }
2635
        }
2636

2637
# * goes on variable not on type
2638
        # (char*[ const])
2639
        while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
2640
            #print "AA<$1>\n";
2641
            my ($ident, $from, $to) = ($1, $2, $2);
2642

2643
            # Should start with a space.
2644
            $to =~ s/^(\S)/ $1/;
2645
            # Should not end with a space.
2646
            $to =~ s/\s+$//;
2647
            # '*'s should not have spaces between.
2648
            while ($to =~ s/\*\s+\*/\*\*/) {
2649
            }
2650

2651
##   print "1: from<$from> to<$to> ident<$ident>\n";
2652
            if ($from ne $to) {
2653
                if (ERROR("POINTER_LOCATION",
2654
                          "\"(foo$from)\" should be \"(foo$to)\"\n" .  $herecurr) &&
2655
                    $fix) {
2656
                    my $sub_from = $ident;
2657
                    my $sub_to = $ident;
2658
                    $sub_to =~ s/\Q$from\E/$to/;
2659
                    $fixed[$linenr - 1] =~
2660
                        s@\Q$sub_from\E@$sub_to@;
2661
                }
2662
            }
2663
        }
2664
        while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
2665
            #print "BB<$1>\n";
2666
            my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
2667

2668
            # Should start with a space.
2669
            $to =~ s/^(\S)/ $1/;
2670
            # Should not end with a space.
2671
            $to =~ s/\s+$//;
2672
            # '*'s should not have spaces between.
2673
            while ($to =~ s/\*\s+\*/\*\*/) {
2674
            }
2675
            # Modifiers should have spaces.
2676
            $to =~ s/(\b$Modifier$)/$1 /;
2677

2678
##  print "2: from<$from> to<$to> ident<$ident>\n";
2679
            if ($from ne $to && $ident !~ /^$Modifier$/) {
2680
                if (ERROR("POINTER_LOCATION",
2681
                          "\"foo${from}bar\" should be \"foo${to}bar\"\n" .  $herecurr) &&
2682
                    $fix) {
2683

2684
                    my $sub_from = $match;
2685
                    my $sub_to = $match;
2686
                    $sub_to =~ s/\Q$from\E/$to/;
2687
                    $fixed[$linenr - 1] =~
2688
                        s@\Q$sub_from\E@$sub_to@;
2689
                }
2690
            }
2691
        }
2692

2693
# function brace can't be on same line, except for #defines of do while,
2694
# or if closed on same line
2695
        if (($line=~/$Type\s*$Ident\(.*\).*\s\{/) and
2696
            !($line=~/\#\s*define.*do\s\{/) and !($line=~/}/)) {
2697
            ERROR("OPEN_BRACE",
2698
                  "open brace '{' following function declarations go on the next line\n" . $herecurr);
2699
        }
2700

2701
# open braces for enum, union and struct go on the same line.
2702
        if ($line =~ /^.\s*{/ &&
2703
            $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) {
2704
            ERROR("OPEN_BRACE",
2705
                  "open brace '{' following $1 go on the same line\n" . $hereprev);
2706
        }
2707

2708
# missing space after union, struct or enum definition
2709
        if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
2710
            if (WARN("SPACING",
2711
                     "missing space after $1 definition\n" . $herecurr) &&
2712
                $fix) {
2713
                $fixed[$linenr - 1] =~
2714
                    s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
2715
            }
2716
        }
2717

2718
# Function pointer declarations
2719
# check spacing between type, funcptr, and args
2720
# canonical declaration is "type (*funcptr)(args...)"
2721
        if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
2722
            my $declare = $1;
2723
            my $pre_pointer_space = $2;
2724
            my $post_pointer_space = $3;
2725
            my $funcname = $4;
2726
            my $post_funcname_space = $5;
2727
            my $pre_args_space = $6;
2728

2729
# the $Declare variable will capture all spaces after the type
2730
# so check it for a missing trailing missing space but pointer return types
2731
# don't need a space so don't warn for those.
2732
            my $post_declare_space = "";
2733
            if ($declare =~ /(\s+)$/) {
2734
                $post_declare_space = $1;
2735
                $declare = rtrim($declare);
2736
            }
2737
            if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
2738
                WARN("SPACING",
2739
                     "missing space after return type\n" . $herecurr);
2740
                $post_declare_space = " ";
2741
            }
2742

2743
# unnecessary space "type ( *funcptr)(args...)"
2744
            if (defined $pre_pointer_space &&
2745
                $pre_pointer_space =~ /^\s/) {
2746
                WARN("SPACING",
2747
                     "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
2748
            }
2749

2750
# unnecessary space "type (* funcptr)(args...)"
2751
            if (defined $post_pointer_space &&
2752
                $post_pointer_space =~ /^\s/) {
2753
                WARN("SPACING",
2754
                     "Unnecessary space before function pointer name\n" . $herecurr);
2755
            }
2756

2757
# unnecessary space "type (*funcptr )(args...)"
2758
            if (defined $post_funcname_space &&
2759
                $post_funcname_space =~ /^\s/) {
2760
                WARN("SPACING",
2761
                     "Unnecessary space after function pointer name\n" . $herecurr);
2762
            }
2763

2764
# unnecessary space "type (*funcptr) (args...)"
2765
            if (defined $pre_args_space &&
2766
                $pre_args_space =~ /^\s/) {
2767
                WARN("SPACING",
2768
                     "Unnecessary space before function pointer arguments\n" . $herecurr);
2769
            }
2770

2771
            if (show_type("SPACING") && $fix) {
2772
                $fixed[$linenr - 1] =~
2773
                    s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
2774
            }
2775
        }
2776

2777
# check for spacing round square brackets; allowed:
2778
#  1. with a type on the left -- int [] a;
2779
#  2. at the beginning of a line for slice initialisers -- [0...10] = 5,
2780
#  3. inside a curly brace -- = { [0...10] = 5 }
2781
        while ($line =~ /(.*?\s)\[/g) {
2782
            my ($where, $prefix) = ($-[1], $1);
2783
            if ($prefix !~ /$Type\s+$/ &&
2784
                ($where != 0 || $prefix !~ /^.\s+$/) &&
2785
                $prefix !~ /[{,]\s+$/) {
2786
                if (ERROR("BRACKET_SPACE",
2787
                          "space prohibited before open square bracket '['\n" . $herecurr) &&
2788
                    $fix) {
2789
                    $fixed[$linenr - 1] =~
2790
                        s/^(\+.*?)\s+\[/$1\[/;
2791
                }
2792
            }
2793
        }
2794

2795
# Check operator spacing.
2796
        if (!($line=~/\#\s*include/)) {
2797
            my $fixed_line = "";
2798
            my $line_fixed = 0;
2799

2800
            my $ops = qr{
2801
                                <<=|>>=|<=|>=|==|!=|
2802
                                \+=|-=|\*=|\/=|%=|\^=|\|=|&=|
2803
                                =>|->|<<|>>|<|>|=|!|~|
2804
                                &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
2805
                                \?:|\?|:
2806
                        }x;
2807
            my @elements = split(/($ops|;)/, $opline);
2808

2809
##                      print("element count: <" . $#elements . ">\n");
2810
##                      foreach my $el (@elements) {
2811
##                              print("el: <$el>\n");
2812
##                      }
2813

2814
            my @fix_elements = ();
2815
            my $off = 0;
2816

2817
            foreach my $el (@elements) {
2818
                push(@fix_elements, substr($rawline, $off, length($el)));
2819
                $off += length($el);
2820
            }
2821

2822
            $off = 0;
2823

2824
            my $blank = copy_spacing($opline);
2825
            my $last_after = -1;
2826

2827
            for (my $n = 0; $n < $#elements; $n += 2) {
2828

2829
                my $good = $fix_elements[$n] . $fix_elements[$n + 1];
2830

2831
##                              print("n: <$n> good: <$good>\n");
2832

2833
                $off += length($elements[$n]);
2834

2835
                # Pick up the preceding and succeeding characters.
2836
                my $ca = substr($opline, 0, $off);
2837
                my $cc = '';
2838
                if (length($opline) >= ($off + length($elements[$n + 1]))) {
2839
                    $cc = substr($opline, $off + length($elements[$n + 1]));
2840
                }
2841
                my $cb = "$ca$;$cc";
2842

2843
                my $a = '';
2844
                $a = 'V' if ($elements[$n] ne '');
2845
                $a = 'W' if ($elements[$n] =~ /\s$/);
2846
                $a = 'C' if ($elements[$n] =~ /$;$/);
2847
                $a = 'B' if ($elements[$n] =~ /(\[|\()$/);
2848
                $a = 'O' if ($elements[$n] eq '');
2849
                $a = 'E' if ($ca =~ /^\s*$/);
2850

2851
                my $op = $elements[$n + 1];
2852

2853
                my $c = '';
2854
                if (defined $elements[$n + 2]) {
2855
                    $c = 'V' if ($elements[$n + 2] ne '');
2856
                    $c = 'W' if ($elements[$n + 2] =~ /^\s/);
2857
                    $c = 'C' if ($elements[$n + 2] =~ /^$;/);
2858
                    $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
2859
                    $c = 'O' if ($elements[$n + 2] eq '');
2860
                    $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/);
2861
                } else {
2862
                    $c = 'E';
2863
                }
2864

2865
                my $ctx = "${a}x${c}";
2866

2867
                my $at = "(ctx:$ctx)";
2868

2869
                my $ptr = substr($blank, 0, $off) . "^";
2870
                my $hereptr = "$hereline$ptr\n";
2871

2872
                # Pull out the value of this operator.
2873
                my $op_type = substr($curr_values, $off + 1, 1);
2874

2875
                # Get the full operator variant.
2876
                my $opv = $op . substr($curr_vars, $off, 1);
2877

2878
                # Ignore operators passed as parameters.
2879
                if ($op_type ne 'V' &&
2880
                    $ca =~ /\s$/ && $cc =~ /^\s*,/) {
2881

2882
#                               # Ignore comments
2883
#                               } elsif ($op =~ /^$;+$/) {
2884

2885
                    # ; should have either the end of line or a space or \ after it
2886
                } elsif ($op eq ';') {
2887
                    if ($ctx !~ /.x[WEBC]/ &&
2888
                        $cc !~ /^\\/ && $cc !~ /^;/) {
2889
                        if (ERROR("SPACING",
2890
                                  "space required after that '$op' $at\n" . $hereptr)) {
2891
                            $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
2892
                            $line_fixed = 1;
2893
                        }
2894
                    }
2895

2896
                    # // is a comment
2897
                } elsif ($op eq '//') {
2898

2899
                    #   :   when part of a bitfield
2900
                } elsif ($opv eq ':B') {
2901
                    # skip the bitfield test for now
2902

2903
                    # No spaces for:
2904
                    #   ->
2905
                } elsif ($op eq '->') {
2906
                    if ($ctx =~ /Wx.|.xW/) {
2907
                        if (ERROR("SPACING",
2908
                                  "spaces prohibited around that '$op' $at\n" . $hereptr)) {
2909
                            $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
2910
                            if (defined $fix_elements[$n + 2]) {
2911
                                $fix_elements[$n + 2] =~ s/^\s+//;
2912
                            }
2913
                            $line_fixed = 1;
2914
                        }
2915
                    }
2916

2917
                    # , must have a space on the right.
2918
                } elsif ($op eq ',') {
2919
                    if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
2920
                        if (ERROR("SPACING",
2921
                                  "space required after that '$op' $at\n" . $hereptr)) {
2922
                            $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
2923
                            $line_fixed = 1;
2924
                            $last_after = $n;
2925
                        }
2926
                    }
2927

2928
                    # '*' as part of a type definition -- reported already.
2929
                } elsif ($opv eq '*_') {
2930
                    #warn "'*' is part of type\n";
2931

2932
                    # unary operators should have a space before and
2933
                    # none after.  May be left adjacent to another
2934
                    # unary operator, or a cast
2935
                } elsif ($op eq '!' || $op eq '~' ||
2936
                         $opv eq '*U' || $opv eq '-U' ||
2937
                         $opv eq '&U' || $opv eq '&&U') {
2938
                    if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
2939
                        if (ERROR("SPACING",
2940
                                  "space required before that '$op' $at\n" . $hereptr)) {
2941
                            if ($n != $last_after + 2) {
2942
                                $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
2943
                                $line_fixed = 1;
2944
                            }
2945
                        }
2946
                    }
2947
                    if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
2948
                        # A unary '*' may be const
2949

2950
                    } elsif ($ctx =~ /.xW/) {
2951
                        if (ERROR("SPACING",
2952
                                  "space prohibited after that '$op' $at\n" . $hereptr)) {
2953
                            $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
2954
                            if (defined $fix_elements[$n + 2]) {
2955
                                $fix_elements[$n + 2] =~ s/^\s+//;
2956
                            }
2957
                            $line_fixed = 1;
2958
                        }
2959
                    }
2960

2961
                    # unary ++ and unary -- are allowed no space on one side.
2962
                } elsif ($op eq '++' or $op eq '--') {
2963
                    if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
2964
                        if (ERROR("SPACING",
2965
                                  "space required one side of that '$op' $at\n" . $hereptr)) {
2966
                            $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
2967
                            $line_fixed = 1;
2968
                        }
2969
                    }
2970
                    if ($ctx =~ /Wx[BE]/ ||
2971
                        ($ctx =~ /Wx./ && $cc =~ /^;/)) {
2972
                        if (ERROR("SPACING",
2973
                                  "space prohibited before that '$op' $at\n" . $hereptr)) {
2974
                            $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
2975
                            $line_fixed = 1;
2976
                        }
2977
                    }
2978
                    if ($ctx =~ /ExW/) {
2979
                        if (ERROR("SPACING",
2980
                                  "space prohibited after that '$op' $at\n" . $hereptr)) {
2981
                            $good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
2982
                            if (defined $fix_elements[$n + 2]) {
2983
                                $fix_elements[$n + 2] =~ s/^\s+//;
2984
                            }
2985
                            $line_fixed = 1;
2986
                        }
2987
                    }
2988

2989
                    # << and >> may either have or not have spaces both sides
2990
                } elsif ($op eq '<<' or $op eq '>>' or
2991
                         $op eq '&' or $op eq '^' or $op eq '|' or
2992
                         $op eq '+' or $op eq '-' or
2993
                         $op eq '*' or $op eq '/' or
2994
                         $op eq '%')
2995
                {
2996
                    if ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
2997
                        if (ERROR("SPACING",
2998
                                  "need consistent spacing around '$op' $at\n" . $hereptr)) {
2999
                            $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
3000
                            if (defined $fix_elements[$n + 2]) {
3001
                                $fix_elements[$n + 2] =~ s/^\s+//;
3002
                            }
3003
                            $line_fixed = 1;
3004
                        }
3005
                    }
3006

3007
                    # A colon needs no spaces before when it is
3008
                    # terminating a case value or a label.
3009
                } elsif ($opv eq ':C' || $opv eq ':L') {
3010
                    if ($ctx =~ /Wx./) {
3011
                        if (ERROR("SPACING",
3012
                                  "space prohibited before that '$op' $at\n" . $hereptr)) {
3013
                            $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
3014
                            $line_fixed = 1;
3015
                        }
3016
                    }
3017

3018
                    # All the others need spaces both sides.
3019
                } elsif ($ctx !~ /[EWC]x[CWE]/) {
3020
                    my $ok = 0;
3021

3022
                    # Ignore email addresses <foo@bar>
3023
                    if (($op eq '<' &&
3024
                         $cc =~ /^\S+\@\S+>/) ||
3025
                        ($op eq '>' &&
3026
                         $ca =~ /<\S+\@\S+$/))
3027
                    {
3028
                        $ok = 1;
3029
                    }
3030

3031
                    # messages are ERROR, but ?: are CHK
3032
                    if ($ok == 0) {
3033
                        my $msg_type = \&ERROR;
3034
                        $msg_type = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
3035

3036
                        if (&{$msg_type}("SPACING",
3037
                                         "spaces required around that '$op' $at\n" . $hereptr)) {
3038
                            $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
3039
                            if (defined $fix_elements[$n + 2]) {
3040
                                $fix_elements[$n + 2] =~ s/^\s+//;
3041
                            }
3042
                            $line_fixed = 1;
3043
                        }
3044
                    }
3045
                }
3046
                $off += length($elements[$n + 1]);
3047

3048
##                              print("n: <$n> GOOD: <$good>\n");
3049

3050
                $fixed_line = $fixed_line . $good;
3051
            }
3052

3053
            if (($#elements % 2) == 0) {
3054
                $fixed_line = $fixed_line . $fix_elements[$#elements];
3055
            }
3056

3057
            if ($fix && $line_fixed && $fixed_line ne $fixed[$linenr - 1]) {
3058
                $fixed[$linenr - 1] = $fixed_line;
3059
            }
3060

3061

3062
        }
3063

3064
# check for whitespace before a non-naked semicolon
3065
        if ($line =~ /^\+.*\S\s+;\s*$/) {
3066
            if (WARN("SPACING",
3067
                     "space prohibited before semicolon\n" . $herecurr) &&
3068
                $fix) {
3069
                1 while $fixed[$linenr - 1] =~
3070
                    s/^(\+.*\S)\s+;/$1;/;
3071
            }
3072
        }
3073

3074
# check for multiple assignments
3075
        if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) {
3076
            CHK("MULTIPLE_ASSIGNMENTS",
3077
                "multiple assignments should be avoided\n" . $herecurr);
3078
        }
3079

3080
## # check for multiple declarations, allowing for a function declaration
3081
## # continuation.
3082
##              if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ &&
3083
##                  $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) {
3084
##
3085
##                      # Remove any bracketed sections to ensure we do not
3086
##                      # falsly report the parameters of functions.
3087
##                      my $ln = $line;
3088
##                      while ($ln =~ s/\([^\(\)]*\)//g) {
3089
##                      }
3090
##                      if ($ln =~ /,/) {
3091
##                              WARN("MULTIPLE_DECLARATION",
3092
##                                   "declaring multiple variables together should be avoided\n" . $herecurr);
3093
##                      }
3094
##              }
3095

3096
#need space before brace following if, while, etc
3097
        if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) ||
3098
            $line =~ /do\{/) {
3099
            if (ERROR("SPACING",
3100
                      "space required before the open brace '{'\n" . $herecurr) &&
3101
                $fix) {
3102
                $fixed[$linenr - 1] =~ s/^(\+.*(?:do|\)))\{/$1 {/;
3103
            }
3104
        }
3105

3106
## # check for blank lines before declarations
3107
##              if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
3108
##                  $prevrawline =~ /^.\s*$/) {
3109
##                      WARN("SPACING",
3110
##                           "No blank lines before declarations\n" . $hereprev);
3111
##              }
3112
##
3113

3114
# closing brace should have a space following it when it has anything
3115
# on the line
3116
        if ($line =~ /}(?!(?:,|;|\)))\S/) {
3117
            if (ERROR("SPACING",
3118
                      "space required after that close brace '}'\n" . $herecurr) &&
3119
                $fix) {
3120
                $fixed[$linenr - 1] =~
3121
                    s/}((?!(?:,|;|\)))\S)/} $1/;
3122
            }
3123
        }
3124

3125
# check spacing on square brackets
3126
        if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
3127
            if (ERROR("SPACING",
3128
                      "space prohibited after that open square bracket '['\n" . $herecurr) &&
3129
                $fix) {
3130
                $fixed[$linenr - 1] =~
3131
                    s/\[\s+/\[/;
3132
            }
3133
        }
3134
        if ($line =~ /\s\]/) {
3135
            if (ERROR("SPACING",
3136
                      "space prohibited before that close square bracket ']'\n" . $herecurr) &&
3137
                $fix) {
3138
                $fixed[$linenr - 1] =~
3139
                    s/\s+\]/\]/;
3140
            }
3141
        }
3142

3143
# check spacing on parentheses
3144
        if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
3145
            $line !~ /for\s*\(\s+;/) {
3146
            if (ERROR("SPACING",
3147
                      "space prohibited after that open parenthesis '('\n" . $herecurr) &&
3148
                $fix) {
3149
                $fixed[$linenr - 1] =~
3150
                    s/\(\s+/\(/;
3151
            }
3152
        }
3153
        if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
3154
            $line !~ /for\s*\(.*;\s+\)/ &&
3155
            $line !~ /:\s+\)/) {
3156
            if (ERROR("SPACING",
3157
                      "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
3158
                $fix) {
3159
                $fixed[$linenr - 1] =~
3160
                    s/\s+\)/\)/;
3161
            }
3162
        }
3163

3164
#goto labels aren't indented, allow a single space however
3165
        if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
3166
            !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
3167
            if (WARN("INDENTED_LABEL",
3168
                     "labels should not be indented\n" . $herecurr) &&
3169
                $fix) {
3170
                $fixed[$linenr - 1] =~
3171
                    s/^(.)\s+/$1/;
3172
            }
3173
        }
3174

3175
# return is not a function
3176
        if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
3177
            my $spacing = $1;
3178
            if ($^V && $^V ge 5.10.0 &&
3179
                $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
3180
                my $value = $1;
3181
                $value = deparenthesize($value);
3182
                if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
3183
                    ERROR("RETURN_PARENTHESES",
3184
                          "return is not a function, parentheses are not required\n" . $herecurr);
3185
                }
3186
            } elsif ($spacing !~ /\s+/) {
3187
                ERROR("SPACING",
3188
                      "space required before the open parenthesis '('\n" . $herecurr);
3189
            }
3190
        }
3191

3192
# unnecessary return in a void function
3193
# at end-of-function, with the previous line a single leading tab, then return;
3194
# and the line before that not a goto label target like "out:"
3195
        if ($sline =~ /^[ \+]}\s*$/ &&
3196
            $prevline =~ /^\+\treturn\s*;\s*$/ &&
3197
            $linenr >= 3 &&
3198
            $lines[$linenr - 3] =~ /^[ +]/ &&
3199
            $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
3200
            WARN("RETURN_VOID",
3201
                 "void function return statements are not generally useful\n" . $hereprev);
3202
        }
3203

3204
# if statements using unnecessary parentheses - ie: if ((foo == bar))
3205
        if ($^V && $^V ge 5.10.0 &&
3206
            $line =~ /\bif\s*((?:\(\s*){2,})/) {
3207
            my $openparens = $1;
3208
            my $count = $openparens =~ tr@\(@\(@;
3209
            my $msg = "";
3210
            if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
3211
                my $comp = $4;  #Not $1 because of $LvalOrFunc
3212
                $msg = " - maybe == should be = ?" if ($comp eq "==");
3213
                WARN("UNNECESSARY_PARENTHESES",
3214
                     "Unnecessary parentheses$msg\n" . $herecurr);
3215
            }
3216
        }
3217

3218
# Return of what appears to be an errno should normally be -'ve
3219
        if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) {
3220
            my $name = $1;
3221
            if ($name ne 'EOF' && $name ne 'ERROR') {
3222
                WARN("USE_NEGATIVE_ERRNO",
3223
                     "return of an errno should typically be -ve (return -$1)\n" . $herecurr);
3224
            }
3225
        }
3226

3227
# Need a space before open parenthesis after if, while etc
3228
        if ($line =~ /\b(if|while|for|switch)\(/) {
3229
            if (ERROR("SPACING",
3230
                      "space required before the open parenthesis '('\n" . $herecurr) &&
3231
                $fix) {
3232
                $fixed[$linenr - 1] =~
3233
                    s/\b(if|while|for|switch)\(/$1 \(/;
3234
            }
3235
        }
3236

3237
# Check for illegal assignment in if conditional -- and check for trailing
3238
# statements after the conditional.
3239
        if ($line =~ /do\s*(?!{)/) {
3240
            ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
3241
                ctx_statement_block($linenr, $realcnt, 0)
3242
                if (!defined $stat);
3243
            my ($stat_next) = ctx_statement_block($line_nr_next,
3244
                                                  $remain_next, $off_next);
3245
            $stat_next =~ s/\n./\n /g;
3246
            ##print "stat<$stat> stat_next<$stat_next>\n";
3247

3248
            if ($stat_next =~ /^\s*while\b/) {
3249
                # If the statement carries leading newlines,
3250
                # then count those as offsets.
3251
                my ($whitespace) =
3252
                    ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
3253
                my $offset =
3254
                    statement_rawlines($whitespace) - 1;
3255

3256
                $suppress_whiletrailers{$line_nr_next +
3257
                                            $offset} = 1;
3258
            }
3259
        }
3260
        if (!defined $suppress_whiletrailers{$linenr} &&
3261
            defined($stat) && defined($cond) &&
3262
            $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
3263
            my ($s, $c) = ($stat, $cond);
3264

3265
            if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) {
3266
                ERROR("ASSIGN_IN_IF",
3267
                      "do not use assignment in if condition\n" . $herecurr);
3268
            }
3269

3270
            # Find out what is on the end of the line after the
3271
            # conditional.
3272
            substr($s, 0, length($c), '');
3273
            $s =~ s/\n.*//g;
3274
            $s =~ s/$;//g;      # Remove any comments
3275
            if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
3276
                $c !~ /}\s*while\s*/)
3277
            {
3278
                # Find out how long the conditional actually is.
3279
                my @newlines = ($c =~ /\n/gs);
3280
                my $cond_lines = 1 + $#newlines;
3281
                my $stat_real = '';
3282

3283
                $stat_real = raw_line($linenr, $cond_lines)
3284
                    . "\n" if ($cond_lines);
3285
                if (defined($stat_real) && $cond_lines > 1) {
3286
                    $stat_real = "[...]\n$stat_real";
3287
                }
3288

3289
                ERROR("TRAILING_STATEMENTS",
3290
                      "trailing statements should be on next line\n" . $herecurr . $stat_real);
3291
            }
3292
        }
3293

3294
# Check for bitwise tests written as boolean
3295
        if ($line =~ /
3296
                        (?:
3297
                                (?:\[|\(|\&\&|\|\|)
3298
                                \s*0[xX][0-9]+\s*
3299
                                (?:\&\&|\|\|)
3300
                        |
3301
                                (?:\&\&|\|\|)
3302
                                \s*0[xX][0-9]+\s*
3303
                                (?:\&\&|\|\||\)|\])
3304
                        )/x)
3305
        {
3306
            WARN("HEXADECIMAL_BOOLEAN_TEST",
3307
                 "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr);
3308
        }
3309

3310
# if and else should not have general statements after it
3311
        if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) {
3312
            my $s = $1;
3313
            $s =~ s/$;//g;      # Remove any comments
3314
            if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) {
3315
                ERROR("TRAILING_STATEMENTS",
3316
                      "trailing statements should be on next line\n" . $herecurr);
3317
            }
3318
        }
3319
# if should not continue a brace
3320
        if ($line =~ /}\s*if\b/) {
3321
            ERROR("TRAILING_STATEMENTS",
3322
                  "trailing statements should be on next line\n" .
3323
                  $herecurr);
3324
        }
3325
# case and default should not have general statements after them
3326
        if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
3327
            $line !~ /\G(?:
3328
                        (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
3329
                        \s*return\s+
3330
                    )/xg)
3331
        {
3332
            ERROR("TRAILING_STATEMENTS",
3333
                  "trailing statements should be on next line\n" . $herecurr);
3334
        }
3335

3336
        # Check for }<nl>else {, these must be at the same
3337
        # indent level to be relevant to each other.
3338
        if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and
3339
            $previndent == $indent) {
3340
            ERROR("ELSE_AFTER_BRACE",
3341
                  "else should follow close brace '}'\n" . $hereprev);
3342
        }
3343

3344
        if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ and
3345
            $previndent == $indent) {
3346
            my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
3347

3348
            # Find out what is on the end of the line after the
3349
            # conditional.
3350
            substr($s, 0, length($c), '');
3351
            $s =~ s/\n.*//g;
3352

3353
            if ($s =~ /^\s*;/) {
3354
                ERROR("WHILE_AFTER_BRACE",
3355
                      "while should follow close brace '}'\n" . $hereprev);
3356
            }
3357
        }
3358

3359
#Specific variable tests
3360
        while ($line =~ m{($Constant|$Lval)}g) {
3361
            my $var = $1;
3362

3363
#gcc binary extension
3364
            if ($var =~ /^$Binary$/) {
3365
                if (WARN("GCC_BINARY_CONSTANT",
3366
                         "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) &&
3367
                    $fix) {
3368
                    my $hexval = sprintf("0x%x", oct($var));
3369
                    $fixed[$linenr - 1] =~
3370
                        s/\b$var\b/$hexval/;
3371
                }
3372
            }
3373

3374
#CamelCase
3375
            if ($var !~ /^$Constant$/ &&
3376
                $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
3377
#Ignore Page<foo> variants
3378
                $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
3379
#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show)
3380
                $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/) {
3381
                while ($var =~ m{($Ident)}g) {
3382
                    my $word = $1;
3383
                    next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
3384
                    if ($check) {
3385
                        seed_camelcase_includes();
3386
                        if (!$file && !$camelcase_file_seeded) {
3387
                            seed_camelcase_file($realfile);
3388
                            $camelcase_file_seeded = 1;
3389
                        }
3390
                    }
3391
                    if (!defined $camelcase{$word}) {
3392
                        $camelcase{$word} = 1;
3393
                        CHK("CAMELCASE",
3394
                            "Avoid CamelCase: <$word>\n" . $herecurr);
3395
                    }
3396
                }
3397
            }
3398
        }
3399

3400
#no spaces allowed after \ in define
3401
        if ($line =~ /\#\s*define.*\\\s+$/) {
3402
            if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
3403
                     "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
3404
                $fix) {
3405
                $fixed[$linenr - 1] =~ s/\s+$//;
3406
            }
3407
        }
3408

3409
#warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line)
3410
        if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
3411
            my $file = "$1.h";
3412
            my $checkfile = "include/linux/$file";
3413
            if (-f "$root/$checkfile" &&
3414
                $realfile ne $checkfile &&
3415
                $1 !~ /$allowed_asm_includes/)
3416
            {
3417
                if ($realfile =~ m{^arch/}) {
3418
                    CHK("ARCH_INCLUDE_LINUX",
3419
                        "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
3420
                } else {
3421
                    WARN("INCLUDE_LINUX",
3422
                         "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
3423
                }
3424
            }
3425
        }
3426

3427
# multi-statement macros should be enclosed in a do while loop, grab the
3428
# first statement and ensure its the whole macro if its not enclosed
3429
# in a known good container
3430
        if ($realfile !~ m@/vmlinux.lds.h$@ &&
3431
            $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) {
3432
            my $ln = $linenr;
3433
            my $cnt = $realcnt;
3434
            my ($off, $dstat, $dcond, $rest);
3435
            my $ctx = '';
3436
            ($dstat, $dcond, $ln, $cnt, $off) =
3437
                ctx_statement_block($linenr, $realcnt, 0);
3438
            $ctx = $dstat;
3439
            #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n";
3440
            #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n";
3441

3442
            $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//;
3443
            $dstat =~ s/$;//g;
3444
            $dstat =~ s/\\\n.//g;
3445
            $dstat =~ s/^\s*//s;
3446
            $dstat =~ s/\s*$//s;
3447

3448
            # Flatten any parentheses and braces
3449
            while ($dstat =~ s/\([^\(\)]*\)/1/ ||
3450
                   $dstat =~ s/\{[^\{\}]*\}/1/ ||
3451
                   $dstat =~ s/\[[^\[\]]*\]/1/)
3452
            {
3453
            }
3454

3455
            # Flatten any obvious string concatentation.
3456
            while ($dstat =~ s/("X*")\s*$Ident/$1/ ||
3457
                   $dstat =~ s/$Ident\s*("X*")/$1/)
3458
            {
3459
            }
3460

3461
            my $exceptions = qr{
3462
                                $Declare|
3463
                                module_param_named|
3464
                                MODULE_PARM_DESC|
3465
                                DECLARE_PER_CPU|
3466
                                DEFINE_PER_CPU|
3467
                                __typeof__\(|
3468
                                union|
3469
                                struct|
3470
                                \.$Ident\s*=\s*|
3471
                                ^\"|\"$
3472
                        }x;
3473
            #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n";
3474
            if ($dstat ne '' &&
3475
                $dstat !~ /^(?:$Ident|-?$Constant),$/ &&                        # 10, // foo(),
3476
                $dstat !~ /^(?:$Ident|-?$Constant);$/ &&                        # foo();
3477
                $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ &&              # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
3478
                $dstat !~ /^'X'$/ &&                                    # character constants
3479
                $dstat !~ /$exceptions/ &&
3480
                $dstat !~ /^\.$Ident\s*=/ &&                            # .foo =
3481
                $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ &&              # stringification #foo
3482
                $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ &&   # do {...} while (...); // do {...} while (...)
3483
                $dstat !~ /^for\s*$Constant$/ &&                                # for (...)
3484
                $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ &&       # for (...) bar()
3485
                $dstat !~ /^do\s*{/ &&                                  # do {...
3486
                $dstat !~ /^\(\{/ &&                                             # ({...
3487
                $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
3488
            {
3489
                $ctx =~ s/\n*$//;
3490
                my $herectx = $here . "\n";
3491
                my $cnt = statement_rawlines($ctx);
3492

3493
                for (my $n = 0; $n < $cnt; $n++) {
3494
                    $herectx .= raw_line($linenr, $n) . "\n";
3495
                }
3496

3497
                if ($dstat =~ /;/) {
3498
                    ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE",
3499
                          "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx");
3500
                } else {
3501
                    ERROR("COMPLEX_MACRO",
3502
                          "Macros with complex values should be enclosed in parenthesis\n" . "$herectx");
3503
                }
3504
            }
3505

3506
# check for line continuations outside of #defines, preprocessor #, and asm
3507

3508
        } else {
3509
            if ($prevline !~ /^..*\\$/ &&
3510
                $line !~ /^\+\s*\#.*\\$/ &&             # preprocessor
3511
                $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ &&       # asm
3512
                $line =~ /^\+.*\\$/) {
3513
                WARN("LINE_CONTINUATIONS",
3514
                     "Avoid unnecessary line continuations\n" . $herecurr);
3515
            }
3516
        }
3517

3518
# do {} while (0) macro tests:
3519
# single-statement macros do not need to be enclosed in do while (0) loop,
3520
# macro should not end with a semicolon
3521
        if ($^V && $^V ge 5.10.0 &&
3522
            $realfile !~ m@/vmlinux.lds.h$@ &&
3523
            $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
3524
            my $ln = $linenr;
3525
            my $cnt = $realcnt;
3526
            my ($off, $dstat, $dcond, $rest);
3527
            my $ctx = '';
3528
            ($dstat, $dcond, $ln, $cnt, $off) =
3529
                ctx_statement_block($linenr, $realcnt, 0);
3530
            $ctx = $dstat;
3531

3532
            $dstat =~ s/\\\n.//g;
3533

3534
            if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
3535
                my $stmts = $2;
3536
                my $semis = $3;
3537

3538
                $ctx =~ s/\n*$//;
3539
                my $cnt = statement_rawlines($ctx);
3540
                my $herectx = $here . "\n";
3541

3542
                for (my $n = 0; $n < $cnt; $n++) {
3543
                    $herectx .= raw_line($linenr, $n) . "\n";
3544
                }
3545

3546
                if (($stmts =~ tr/;/;/) == 1 &&
3547
                    $stmts !~ /^\s*(if|while|for|switch)\b/) {
3548
                    WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
3549
                         "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
3550
                }
3551
                if (defined $semis && $semis ne "") {
3552
                    WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
3553
                         "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
3554
                }
3555
            } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
3556
                $ctx =~ s/\n*$//;
3557
                my $cnt = statement_rawlines($ctx);
3558
                my $herectx = $here . "\n";
3559

3560
                for (my $n = 0; $n < $cnt; $n++) {
3561
                    $herectx .= raw_line($linenr, $n) . "\n";
3562
                }
3563

3564
                WARN("TRAILING_SEMICOLON",
3565
                     "macros should not use a trailing semicolon\n" . "$herectx");
3566
            }
3567
        }
3568

3569
# make sure symbols are always wrapped with VMLINUX_SYMBOL() ...
3570
# all assignments may have only one of the following with an assignment:
3571
#       .
3572
#       ALIGN(...)
3573
#       VMLINUX_SYMBOL(...)
3574
        if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) {
3575
            WARN("MISSING_VMLINUX_SYMBOL",
3576
                 "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr);
3577
        }
3578

3579
# check for redundant bracing round if etc
3580
        if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
3581
            my ($level, $endln, @chunks) =
3582
                ctx_statement_full($linenr, $realcnt, 1);
3583
            #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
3584
            #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
3585
            if ($#chunks > 0 && $level == 0) {
3586
                my @allowed = ();
3587
                my $allow = 0;
3588
                my $seen = 0;
3589
                my $herectx = $here . "\n";
3590
                my $ln = $linenr - 1;
3591
                for my $chunk (@chunks) {
3592
                    my ($cond, $block) = @{$chunk};
3593

3594
                    # If the condition carries leading newlines, then count those as offsets.
3595
                    my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
3596
                    my $offset = statement_rawlines($whitespace) - 1;
3597

3598
                    $allowed[$allow] = 0;
3599
                    #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
3600

3601
                    # We have looked at and allowed this specific line.
3602
                    $suppress_ifbraces{$ln + $offset} = 1;
3603

3604
                    $herectx .= "$rawlines[$ln + $offset]\n[...]\n";
3605
                    $ln += statement_rawlines($block) - 1;
3606

3607
                    substr($block, 0, length($cond), '');
3608

3609
                    $seen++ if ($block =~ /^\s*{/);
3610

3611
                    #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n";
3612
                    if (statement_lines($cond) > 1) {
3613
                        #print "APW: ALLOWED: cond<$cond>\n";
3614
                        $allowed[$allow] = 1;
3615
                    }
3616
                    if ($block =~/\b(?:if|for|while)\b/) {
3617
                        #print "APW: ALLOWED: block<$block>\n";
3618
                        $allowed[$allow] = 1;
3619
                    }
3620
                    if (statement_block_size($block) > 1) {
3621
                        #print "APW: ALLOWED: lines block<$block>\n";
3622
                        $allowed[$allow] = 1;
3623
                    }
3624
                    $allow++;
3625
                }
3626
                if ($seen) {
3627
                    my $sum_allowed = 0;
3628
                    foreach (@allowed) {
3629
                        $sum_allowed += $_;
3630
                    }
3631
                    if ($sum_allowed != 0 && $sum_allowed != $allow
3632
		    			  && $seen != $allow) {
3633
                        CHK("BRACES",
3634
                            "braces {} should be used on all arms of this statement\n" . $herectx);
3635
                    }
3636
                }
3637
            }
3638
        }
3639
        if (!defined $suppress_ifbraces{$linenr - 1} &&
3640
            $line =~ /\b(if|while|for|else)\b/) {
3641
            my $allowed = 0;
3642

3643
            # Check the pre-context.
3644
            if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
3645
                #print "APW: ALLOWED: pre<$1>\n";
3646
                $allowed = 1;
3647
            }
3648

3649
            my ($level, $endln, @chunks) =
3650
                ctx_statement_full($linenr, $realcnt, $-[0]);
3651

3652
            # Check the condition.
3653
            my ($cond, $block) = @{$chunks[0]};
3654
            #print "CHECKING<$linenr> cond<$cond> block<$block>\n";
3655
            if (defined $cond) {
3656
                substr($block, 0, length($cond), '');
3657
            }
3658
            if (statement_lines($cond) > 1) {
3659
                #print "APW: ALLOWED: cond<$cond>\n";
3660
                $allowed = 1;
3661
            }
3662
            if ($block =~/\b(?:if|for|while)\b/) {
3663
                #print "APW: ALLOWED: block<$block>\n";
3664
                $allowed = 1;
3665
            }
3666
            if (statement_block_size($block) > 1) {
3667
                #print "APW: ALLOWED: lines block<$block>\n";
3668
                $allowed = 1;
3669
            }
3670
            # Check the post-context.
3671
            if (defined $chunks[1]) {
3672
                my ($cond, $block) = @{$chunks[1]};
3673
                if (defined $cond) {
3674
                    substr($block, 0, length($cond), '');
3675
                }
3676
                if ($block =~ /^\s*\{/) {
3677
                    #print "APW: ALLOWED: chunk-1 block<$block>\n";
3678
                    $allowed = 1;
3679
                }
3680
            }
3681
        }
3682

3683
# check for unnecessary blank lines around braces
3684
        if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
3685
            CHK("BRACES",
3686
                "Blank lines aren't necessary before a close brace '}'\n" . $hereprev);
3687
        }
3688
        if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
3689
            CHK("BRACES",
3690
                "Blank lines aren't necessary after an open brace '{'\n" . $hereprev);
3691
        }
3692

3693
# no volatiles please
3694
        my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b};
3695
        if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) {
3696
            WARN("VOLATILE",
3697
                 "Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr);
3698
        }
3699

3700
# warn about #if 0
3701
        if ($line =~ /^.\s*\#\s*if\s+0\b/) {
3702
            CHK("REDUNDANT_CODE",
3703
                "if this code is redundant consider removing it\n" .
3704
                $herecurr);
3705
        }
3706

3707
# check for needless "if (<foo>) fn(<foo>)" uses
3708
        if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) {
3709
            my $expr = '\s*\(\s*' . quotemeta($1) . '\s*\)\s*;';
3710
            if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?)$expr/) {
3711
                WARN('NEEDLESS_IF',
3712
                     "$1(NULL) is safe this check is probably not required\n" . $hereprev);
3713
            }
3714
        }
3715

3716
# check for bad placement of section $InitAttribute (e.g.: __initdata)
3717
        if ($line =~ /(\b$InitAttribute\b)/) {
3718
            my $attr = $1;
3719
            if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
3720
                my $ptr = $1;
3721
                my $var = $2;
3722
                if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
3723
                      ERROR("MISPLACED_INIT",
3724
                            "$attr should be placed after $var\n" . $herecurr)) ||
3725
                     ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
3726
                      WARN("MISPLACED_INIT",
3727
                           "$attr should be placed after $var\n" . $herecurr))) &&
3728
                    $fix) {
3729
                    $fixed[$linenr - 1] =~ s/(\bstatic\s+(?:const\s+)?)(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*([=;])\s*/"$1" . trim(string_find_replace($2, "\\s*$attr\\s*", " ")) . " " . trim(string_find_replace($3, "\\s*$attr\\s*", "")) . " $attr" . ("$4" eq ";" ? ";" : " = ")/e;
3730
                }
3731
            }
3732
        }
3733

3734
# check for $InitAttributeData (ie: __initdata) with const
3735
        if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
3736
            my $attr = $1;
3737
            $attr =~ /($InitAttributePrefix)(.*)/;
3738
            my $attr_prefix = $1;
3739
            my $attr_type = $2;
3740
            if (ERROR("INIT_ATTRIBUTE",
3741
                      "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
3742
                $fix) {
3743
                $fixed[$linenr - 1] =~
3744
                    s/$InitAttributeData/${attr_prefix}initconst/;
3745
            }
3746
        }
3747

3748
# check for $InitAttributeConst (ie: __initconst) without const
3749
        if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
3750
            my $attr = $1;
3751
            if (ERROR("INIT_ATTRIBUTE",
3752
                      "Use of $attr requires a separate use of const\n" . $herecurr) &&
3753
                $fix) {
3754
                my $lead = $fixed[$linenr - 1] =~
3755
                    /(^\+\s*(?:static\s+))/;
3756
                $lead = rtrim($1);
3757
                $lead = "$lead " if ($lead !~ /^\+$/);
3758
                $lead = "${lead}const ";
3759
                $fixed[$linenr - 1] =~ s/(^\+\s*(?:static\s+))/$lead/;
3760
            }
3761
        }
3762

3763
# don't use __constant_<foo> functions outside of include/uapi/
3764
        if ($realfile !~ m@^include/uapi/@ &&
3765
            $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
3766
            my $constant_func = $1;
3767
            my $func = $constant_func;
3768
            $func =~ s/^__constant_//;
3769
            if (WARN("CONSTANT_CONVERSION",
3770
                     "$constant_func should be $func\n" . $herecurr) &&
3771
                $fix) {
3772
                $fixed[$linenr - 1] =~ s/\b$constant_func\b/$func/g;
3773
            }
3774
        }
3775

3776
# prefer usleep_range over udelay
3777
        if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
3778
            my $delay = $1;
3779
            # ignore udelay's < 10, however
3780
            if (! ($delay < 10) ) {
3781
                CHK("USLEEP_RANGE",
3782
                    "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr);
3783
            }
3784
            if ($delay > 2000) {
3785
                WARN("LONG_UDELAY",
3786
                     "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
3787
            }
3788
        }
3789

3790
# warn about unexpectedly long msleep's
3791
        if ($line =~ /\bmsleep\s*\((\d+)\);/) {
3792
            if ($1 < 20) {
3793
                WARN("MSLEEP",
3794
                     "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr);
3795
            }
3796
        }
3797

3798
# check for comparisons of jiffies
3799
        if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
3800
            WARN("JIFFIES_COMPARISON",
3801
                 "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
3802
        }
3803

3804
# check for comparisons of get_jiffies_64()
3805
        if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
3806
            WARN("JIFFIES_COMPARISON",
3807
                 "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
3808
        }
3809

3810
# warn about spacing in #ifdefs
3811
        if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
3812
            if (ERROR("SPACING",
3813
                      "exactly one space required after that #$1\n" . $herecurr) &&
3814
                $fix) {
3815
                $fixed[$linenr - 1] =~
3816
                    s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
3817
            }
3818

3819
        }
3820

3821
# check for spinlock_t definitions without a comment.
3822
        if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ ||
3823
            $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) {
3824
            my $which = $1;
3825
            if (!ctx_has_comment($first_line, $linenr)) {
3826
                CHK("UNCOMMENTED_DEFINITION",
3827
                    "$1 definition without comment\n" . $herecurr);
3828
            }
3829
        }
3830
# check for memory barriers without a comment.
3831
        if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) {
3832
            if (!ctx_has_comment($first_line, $linenr)) {
3833
                WARN("MEMORY_BARRIER",
3834
                     "memory barrier without comment\n" . $herecurr);
3835
            }
3836
        }
3837
# check of hardware specific defines
3838
        if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {
3839
            CHK("ARCH_DEFINES",
3840
                "architecture specific defines should be avoided\n" .  $herecurr);
3841
        }
3842

3843
# Check that the storage class is at the beginning of a declaration
3844
        if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) {
3845
            WARN("STORAGE_CLASS",
3846
                 "storage class should be at the beginning of the declaration\n" . $herecurr)
3847
        }
3848

3849
# check the location of the inline attribute, that it is between
3850
# storage class and type.
3851
        if ($line =~ /\b$Type\s+$Inline\b/ ||
3852
            $line =~ /\b$Inline\s+$Storage\b/) {
3853
            ERROR("INLINE_LOCATION",
3854
                  "inline keyword should sit between storage class and type\n" . $herecurr);
3855
        }
3856

3857
# Check for __inline__ and __inline, prefer inline
3858
        if ($realfile !~ m@\binclude/uapi/@ &&
3859
            $line =~ /\b(__inline__|__inline)\b/) {
3860
            if (WARN("INLINE",
3861
                     "plain inline is preferred over $1\n" . $herecurr) &&
3862
                $fix) {
3863
                $fixed[$linenr - 1] =~ s/\b(__inline__|__inline)\b/inline/;
3864

3865
            }
3866
        }
3867

3868
# Check for __attribute__ packed, prefer __packed
3869
        if ($realfile !~ m@\binclude/uapi/@ &&
3870
            $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
3871
            WARN("PREFER_PACKED",
3872
                 "__packed is preferred over __attribute__((packed))\n" . $herecurr);
3873
        }
3874

3875
# Check for __attribute__ aligned, prefer __aligned
3876
        if ($realfile !~ m@\binclude/uapi/@ &&
3877
            $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
3878
            WARN("PREFER_ALIGNED",
3879
                 "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
3880
        }
3881

3882
# Check for __attribute__ format(printf, prefer __printf
3883
        if ($realfile !~ m@\binclude/uapi/@ &&
3884
            $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
3885
            if (WARN("PREFER_PRINTF",
3886
                     "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
3887
                $fix) {
3888
                $fixed[$linenr - 1] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
3889

3890
            }
3891
        }
3892

3893
# Check for __attribute__ format(scanf, prefer __scanf
3894
        if ($realfile !~ m@\binclude/uapi/@ &&
3895
            $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
3896
            if (WARN("PREFER_SCANF",
3897
                     "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
3898
                $fix) {
3899
                $fixed[$linenr - 1] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
3900
            }
3901
        }
3902

3903
# check for sizeof(&)
3904
        if ($line =~ /\bsizeof\s*\(\s*\&/) {
3905
            WARN("SIZEOF_ADDRESS",
3906
                 "sizeof(& should be avoided\n" . $herecurr);
3907
        }
3908

3909
# check for sizeof without parenthesis
3910
        if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
3911
            if (WARN("SIZEOF_PARENTHESIS",
3912
                     "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
3913
                $fix) {
3914
                $fixed[$linenr - 1] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
3915
            }
3916
        }
3917

3918
# check for line continuations in quoted strings with odd counts of "
3919
        if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) {
3920
            WARN("LINE_CONTINUATIONS",
3921
                 "Avoid line continuations in quoted strings\n" . $herecurr);
3922
        }
3923

3924
# check for struct spinlock declarations
3925
        if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {
3926
            WARN("USE_SPINLOCK_T",
3927
                 "struct spinlock should be spinlock_t\n" . $herecurr);
3928
        }
3929

3930
# check for seq_printf uses that could be seq_puts
3931
        if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
3932
            my $fmt = get_quoted_string($line, $rawline);
3933
            if ($fmt ne "" && $fmt !~ /[^\\]\%/) {
3934
                if (WARN("PREFER_SEQ_PUTS",
3935
                         "Prefer seq_puts to seq_printf\n" . $herecurr) &&
3936
                    $fix) {
3937
                    $fixed[$linenr - 1] =~ s/\bseq_printf\b/seq_puts/;
3938
                }
3939
            }
3940
        }
3941

3942
# Check for misused memsets
3943
        if ($^V && $^V ge 5.10.0 &&
3944
            defined $stat &&
3945
            $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/s) {
3946

3947
            my $ms_addr = $2;
3948
            my $ms_val = $7;
3949
            my $ms_size = $12;
3950

3951
            if ($ms_size =~ /^(0x|)0$/i) {
3952
                ERROR("MEMSET",
3953
                      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");
3954
            } elsif ($ms_size =~ /^(0x|)1$/i) {
3955
                WARN("MEMSET",
3956
                     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");
3957
            }
3958
        }
3959

3960
# typecasts on min/max could be min_t/max_t
3961
        if ($^V && $^V ge 5.10.0 &&
3962
            defined $stat &&
3963
            $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {
3964
            if (defined $2 || defined $7) {
3965
                my $call = $1;
3966
                my $cast1 = deparenthesize($2);
3967
                my $arg1 = $3;
3968
                my $cast2 = deparenthesize($7);
3969
                my $arg2 = $8;
3970
                my $cast;
3971

3972
                if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {
3973
                    $cast = "$cast1 or $cast2";
3974
                } elsif ($cast1 ne "") {
3975
                    $cast = $cast1;
3976
                } else {
3977
                    $cast = $cast2;
3978
                }
3979
                WARN("MINMAX",
3980
                     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");
3981
            }
3982
        }
3983

3984
# check usleep_range arguments
3985
        if ($^V && $^V ge 5.10.0 &&
3986
            defined $stat &&
3987
            $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {
3988
            my $min = $1;
3989
            my $max = $7;
3990
            if ($min eq $max) {
3991
                WARN("USLEEP_RANGE",
3992
                     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
3993
            } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&
3994
                     $min > $max) {
3995
                WARN("USLEEP_RANGE",
3996
                     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n");
3997
            }
3998
        }
3999

4000
# check for naked sscanf
4001
        if ($^V && $^V ge 5.10.0 &&
4002
            defined $stat &&
4003
            $line =~ /\bsscanf\b/ &&
4004
            ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
4005
             $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
4006
             $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
4007
            my $lc = $stat =~ tr@\n@@;
4008
            $lc = $lc + $linenr;
4009
            my $stat_real = raw_line($linenr, 0);
4010
            for (my $count = $linenr + 1; $count <= $lc; $count++) {
4011
                $stat_real = $stat_real . "\n" . raw_line($count, 0);
4012
            }
4013
            WARN("NAKED_SSCANF",
4014
                 "unchecked sscanf return value\n" . "$here\n$stat_real\n");
4015
        }
4016

4017
# check for simple sscanf that should be kstrto<foo>
4018
        if ($^V && $^V ge 5.10.0 &&
4019
            defined $stat &&
4020
            $line =~ /\bsscanf\b/) {
4021
            my $lc = $stat =~ tr@\n@@;
4022
            $lc = $lc + $linenr;
4023
            my $stat_real = raw_line($linenr, 0);
4024
            for (my $count = $linenr + 1; $count <= $lc; $count++) {
4025
                $stat_real = $stat_real . "\n" . raw_line($count, 0);
4026
            }
4027
            if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
4028
                my $format = $6;
4029
                my $count = $format =~ tr@%@%@;
4030
                if ($count == 1 &&
4031
                    $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
4032
                    WARN("SSCANF_TO_KSTRTO",
4033
                         "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
4034
                }
4035
            }
4036
        }
4037

4038
# check for new externs in .h files.
4039
        if ($realfile =~ /\.h$/ &&
4040
            $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
4041
            if (CHK("AVOID_EXTERNS",
4042
                    "extern prototypes should be avoided in .h files\n" . $herecurr) &&
4043
                $fix) {
4044
                $fixed[$linenr - 1] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
4045
            }
4046
        }
4047

4048
# check for new externs in .c files.
4049
        if ($realfile =~ /\.c$/ && defined $stat &&
4050
            $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
4051
        {
4052
            my $function_name = $1;
4053
            my $paren_space = $2;
4054

4055
            my $s = $stat;
4056
            if (defined $cond) {
4057
                substr($s, 0, length($cond), '');
4058
            }
4059
            if ($s =~ /^\s*;/ &&
4060
                $function_name ne 'uninitialized_var')
4061
            {
4062
                WARN("AVOID_EXTERNS",
4063
                     "externs should be avoided in .c files\n" .  $herecurr);
4064
            }
4065

4066
            if ($paren_space =~ /\n/) {
4067
                WARN("FUNCTION_ARGUMENTS",
4068
                     "arguments for function declarations should follow identifier\n" . $herecurr);
4069
            }
4070

4071
        } elsif ($realfile =~ /\.c$/ && defined $stat &&
4072
                 $stat =~ /^.\s*extern\s+/)
4073
        {
4074
            WARN("AVOID_EXTERNS",
4075
                 "externs should be avoided in .c files\n" .  $herecurr);
4076
        }
4077

4078
# check for pointless casting of kmalloc return
4079
        if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) {
4080
            WARN("UNNECESSARY_CASTS",
4081
                 "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
4082
        }
4083

4084
# alloc style
4085
# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
4086
        if ($^V && $^V ge 5.10.0 &&
4087
            $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
4088
            CHK("ALLOC_SIZEOF_STRUCT",
4089
                "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
4090
        }
4091

4092
# check for multiple semicolons
4093
        if ($line =~ /;\s*;\s*$/) {
4094
            if (WARN("ONE_SEMICOLON",
4095
                     "Statements terminations use 1 semicolon\n" . $herecurr) &&
4096
                $fix) {
4097
                $fixed[$linenr - 1] =~ s/(\s*;\s*){2,}$/;/g;
4098
            }
4099
        }
4100

4101
# check for case / default statements not preceeded by break/fallthrough/switch
4102
        if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
4103
            my $has_break = 0;
4104
            my $has_statement = 0;
4105
            my $count = 0;
4106
            my $prevline = $linenr;
4107
            while ($prevline > 1 && $count < 3 && !$has_break) {
4108
                $prevline--;
4109
                my $rline = $rawlines[$prevline - 1];
4110
                my $fline = $lines[$prevline - 1];
4111
                last if ($fline =~ /^\@\@/);
4112
                next if ($fline =~ /^\-/);
4113
                next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/);
4114
                $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i);
4115
                next if ($fline =~ /^.[\s$;]*$/);
4116
                $has_statement = 1;
4117
                $count++;
4118
                $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/);
4119
            }
4120
            if (!$has_break && $has_statement) {
4121
                WARN("MISSING_BREAK",
4122
                     "Possible switch case/default not preceeded by break or fallthrough comment\n" . $herecurr);
4123
            }
4124
        }
4125

4126
# check for switch/default statements without a break;
4127
        if ($^V && $^V ge 5.10.0 &&
4128
            defined $stat &&
4129
            $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {
4130
            my $ctx = '';
4131
            my $herectx = $here . "\n";
4132
            my $cnt = statement_rawlines($stat);
4133
            for (my $n = 0; $n < $cnt; $n++) {
4134
                $herectx .= raw_line($linenr, $n) . "\n";
4135
            }
4136
            WARN("DEFAULT_NO_BREAK",
4137
                 "switch default: should use break\n" . $herectx);
4138
        }
4139

4140
# check for comparisons against true and false
4141
        if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
4142
            my $lead = $1;
4143
            my $arg = $2;
4144
            my $test = $3;
4145
            my $otype = $4;
4146
            my $trail = $5;
4147
            my $op = "!";
4148

4149
            ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
4150

4151
            my $type = lc($otype);
4152
            if ($type =~ /^(?:true|false)$/) {
4153
                if (("$test" eq "==" && "$type" eq "true") ||
4154
                    ("$test" eq "!=" && "$type" eq "false")) {
4155
                    $op = "";
4156
                }
4157

4158
                CHK("BOOL_COMPARISON",
4159
                    "Using comparison to $otype is error prone\n" . $herecurr);
4160
            }
4161
        }
4162

4163
# check for semaphores initialized locked
4164
        if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
4165
            WARN("CONSIDER_COMPLETION",
4166
                 "consider using a completion\n" . $herecurr);
4167
        }
4168

4169
# check for %L{u,d,i} in strings
4170
        my $string;
4171
        while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
4172
            $string = substr($rawline, $-[1], $+[1] - $-[1]);
4173
            $string =~ s/%%/__/g;
4174
            if ($string =~ /(?<!%)%L[udi]/) {
4175
                WARN("PRINTF_L",
4176
                     "\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr);
4177
                last;
4178
            }
4179
        }
4180

4181

4182
# Mode permission misuses where it seems decimal should be octal
4183
# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
4184
        if ($^V && $^V ge 5.10.0 &&
4185
            $line =~ /$mode_perms_search/) {
4186
            foreach my $entry (@mode_permission_funcs) {
4187
                my $func = $entry->[0];
4188
                my $arg_pos = $entry->[1];
4189

4190
                my $skip_args = "";
4191
                if ($arg_pos > 1) {
4192
                    $arg_pos--;
4193
                    $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
4194
                }
4195
                my $test = "\\b$func\\s*\\(${skip_args}([\\d]+)\\s*[,\\)]";
4196
                if ($line =~ /$test/) {
4197
                    my $val = $1;
4198
                    $val = $6 if ($skip_args ne "");
4199

4200
                    if ($val !~ /^0$/ &&
4201
                        (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
4202
                         length($val) ne 4)) {
4203
                        ERROR("NON_OCTAL_PERMISSIONS",
4204
                              "Use 4 digit octal (0777) not decimal permissions\n" . $herecurr);
4205
                    }
4206
                }
4207
            }
4208
        }
4209
    }
4210

4211
    # If we have no input at all, then there is nothing to report on
4212
    # so just keep quiet.
4213
    if ($#rawlines == -1) {
4214
        exit(0);
4215
    }
4216

4217
    # In mailback mode only produce a report in the negative, for
4218
    # things that appear to be patches.
4219
    if ($mailback && ($clean == 1 || !$is_patch)) {
4220
        exit(0);
4221
    }
4222

4223
    # This is not a patch, and we are are in 'no-patch' mode so
4224
    # just keep quiet.
4225
    if (!$chk_patch && !$is_patch) {
4226
        exit(0);
4227
    }
4228

4229
    if (!$is_patch) {
4230
        ERROR("NOT_UNIFIED_DIFF",
4231
              "Does not appear to be a unified-diff format patch\n");
4232
    }
4233
    if ($is_patch && $subject_trailing_dot != 0) {
4234
        ERROR("SUBJECT_TRAILING_DOT",
4235
              "The subject of the patch should not end with a dot.\n");
4236
    }
4237
    if ($is_patch && $chk_signoff && $signoff == 0) {
4238
        ERROR("MISSING_SIGN_OFF",
4239
              "Missing Signed-off-by: line(s)\n");
4240
    }
4241

4242
    print report_dump();
4243
    if ($summary && !($clean == 1 && $quiet == 1)) {
4244
        print "$filename " if ($summary_file);
4245
        if ($cnt_error > 0) {
4246
            print "Patch not according to coding guidelines! please fix.\n";
4247
            print "total: $cnt_error errors, $cnt_warn warnings, " .
4248
                (($check)? "$cnt_chk checks, " : "") .
4249
                "$cnt_lines lines checked\n"; exit 1;
4250
        } else {
4251
            print "total: $cnt_warn warnings, " .
4252
                (($check)? "$cnt_chk checks, " : "") .
4253
                "$cnt_lines lines checked\n";
4254
            print "Patch found to have warnings, please fix if necessary.\n" if ($cnt_warn > 0);
4255
            exit 2;
4256
        }
4257
        print "\n" if ($quiet == 0);
4258
    }
4259

4260
    if ($quiet == 0) {
4261

4262
        if ($^V lt 5.10.0) {
4263
            print("NOTE: perl $^V is not modern enough to detect all possible issues.\n");
4264
            print("An upgrade to at least perl v5.10.0 is suggested.\n\n");
4265
        }
4266

4267
        # If there were whitespace errors which cleanpatch can fix
4268
        # then suggest that.
4269
        if ($rpt_cleaners) {
4270
            print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n";
4271
            print "      scripts/cleanfile\n\n";
4272
            $rpt_cleaners = 0;
4273
        }
4274
    }
4275

4276
    hash_show_words(\%use_type, "Used");
4277
    hash_show_words(\%ignore_type, "Ignored");
4278

4279
    if ($clean == 0 && $fix && "@rawlines" ne "@fixed") {
4280
        my $newfile = $filename;
4281
        $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
4282
        my $linecount = 0;
4283
        my $f;
4284

4285
        open($f, '>', $newfile)
4286
            or die "$P: Can't open $newfile for write\n";
4287
        foreach my $fixed_line (@fixed) {
4288
            $linecount++;
4289
            if ($file) {
4290
                if ($linecount > 3) {
4291
                    $fixed_line =~ s/^\+//;
4292
                    print $f $fixed_line. "\n";
4293
                }
4294
            } else {
4295
                print $f $fixed_line . "\n";
4296
            }
4297
        }
4298
        close($f);
4299

4300
        if (!$quiet) {
4301
            print << "EOM";
4302
Wrote EXPERIMENTAL --fix correction(s) to '$newfile'
4303

4304
Do _NOT_ trust the results written to this file.
4305
Do _NOT_ submit these changes without inspecting them for correctness.
4306

4307
This EXPERIMENTAL file is simply a convenience to help rewrite patches.
4308
No warranties, expressed or implied...
4309
EOM
4310
        }
4311
    }
4312

4313
    if ($clean == 1 && $quiet == 0) {
4314
        print "$vname has no obvious style problems and is ready for submission.\n"
4315
    }
4316
    if ($clean == 0 && $quiet == 0) {
4317
        print << "EOM";
4318
$vname has style problems, please review.
4319

4320
If any of these errors are false positives, please report
4321
them to the maintainer, see MAINTAINERS
4322
EOM
4323
    }
4324

4325
    return $clean;
4326
}
4327

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.