2 # SPDX-License-Identifier: GPL-2.0
4 # (c) 2001, Dave Jones. (the file handling bit)
5 # (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
6 # (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite)
7 # (c) 2008-2010 Andy Whitcroft <apw@canonical.com>
8 # (c) 2010-2018 Joe Perches <joe@perches.com>
15 use Term::ANSIColor qw(:constants);
16 use Encode qw(decode encode);
19 my $D = dirname(abs_path($P));
23 use Getopt::Long qw(:config no_auto_abbrev);
53 my $configuration_file = ".checkpatch.conf";
54 my $max_line_length = 80;
55 my $ignore_perl_version = 0;
56 my $minimum_perl_version = 5.10.0;
57 my $min_conf_desc_length = 4;
58 my $spelling_file = "$D/spelling.txt";
60 my $codespellfile = "/usr/share/codespell/dictionary.txt";
61 my $conststructsfile = "$D/const_structs.checkpatch";
62 my $typedefsfile = "";
64 my $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE
70 Usage: $P [OPTION]... [FILE]...
75 --no-tree run without a kernel tree
76 --no-signoff do not check for 'Signed-off-by' line
77 --patch treat FILE as patchfile (default)
78 --emacs emacs compile window format
79 --terse one line per report
80 --showfile emit diffed file position, not input file position
81 -g, --git treat FILE as a single commit or git revision range
82 single git commit with:
86 multiple git commits with:
90 git merges are ignored
91 -f, --file treat FILE as regular source file
92 --subjective, --strict enable more subjective tests
93 --list-types list the possible message types
94 --types TYPE(,TYPE2...) show only these comma separated message types
95 --ignore TYPE(,TYPE2...) ignore various comma separated message types
96 --show-types show the specific message type in the output
97 --max-line-length=n set the maximum line length, if exceeded, warn
98 --min-conf-desc-length=n set the min description length, if shorter, warn
99 --root=PATH PATH to the kernel tree root
100 --no-summary suppress the per-file summary
101 --mailback only produce a report in case of warnings/errors
102 --summary-file include the filename in summary
103 --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of
104 'values', 'possible', 'type', and 'attr' (default
106 --test-only=WORD report only warnings/errors containing WORD
108 --fix EXPERIMENTAL - may create horrible results
109 If correctable single-line errors exist, create
110 "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
111 with potential errors corrected to the preferred
113 --fix-inplace EXPERIMENTAL - may create horrible results
114 Is the same as --fix, but overwrites the input
115 file. It's your fault if there's no backup or git
116 --ignore-perl-version override checking of perl version. expect
118 --codespell Use the codespell dictionary for spelling/typos
119 (default:/usr/share/codespell/dictionary.txt)
120 --codespellfile Use this codespell dictionary
121 --typedefsfile Read additional types from this file
122 --color[=WHEN] Use colors 'always', 'never', or only when output
123 is a terminal ('auto'). Default is 'auto'.
124 -h, --help, --version display this help and exit
126 When FILE is - read standard input.
134 return grep { !$seen{$_}++ } @_;
144 open(my $script, '<', abs_path($P)) or
145 die "$P: Can't read '$P' $!\n";
147 my $text = <$script>;
151 # Also catch when type or level is passed through a variable
152 for ($text =~ /(?:(?:\bCHK|\bWARN|\bERROR|&\{\$msg_level})\s*\(|\$msg_type\s*=)\s*"([^"]+)"/g) {
155 @types = sort(uniq(@types));
156 print("#\tMessage type\n\n");
157 foreach my $type (@types) {
158 print(++$count . "\t" . $type . "\n");
164 my $conf = which_conf($configuration_file);
167 open(my $conffile, '<', "$conf")
168 or warn "$P: Can't find a readable $configuration_file file $!\n";
170 while (<$conffile>) {
173 $line =~ s/\s*\n?$//g;
177 next if ($line =~ m/^\s*#/);
178 next if ($line =~ m/^\s*$/);
180 my @words = split(" ", $line);
181 foreach my $word (@words) {
182 last if ($word =~ m/^#/);
183 push (@conf_args, $word);
187 unshift(@ARGV, @conf_args) if @conf_args;
190 # Perl's Getopt::Long allows options to take optional arguments after a space.
191 # Prevent --color by itself from consuming other arguments
193 if ($_ eq "--color" || $_ eq "-color") {
194 $_ = "--color=$color";
199 'q|quiet+' => \$quiet,
201 'signoff!' => \$chk_signoff,
202 'patch!' => \$chk_patch,
205 'showfile!' => \$showfile,
208 'subjective!' => \$check,
209 'strict!' => \$check,
210 'ignore=s' => \@ignore,
212 'show-types!' => \$show_types,
213 'list-types!' => \$list_types,
214 'max-line-length=i' => \$max_line_length,
215 'min-conf-desc-length=i' => \$min_conf_desc_length,
217 'summary!' => \$summary,
218 'mailback!' => \$mailback,
219 'summary-file!' => \$summary_file,
221 'fix-inplace!' => \$fix_inplace,
222 'ignore-perl-version!' => \$ignore_perl_version,
223 'debug=s' => \%debug,
224 'test-only=s' => \$tst_only,
225 'codespell!' => \$codespell,
226 'codespellfile=s' => \$codespellfile,
227 'typedefsfile=s' => \$typedefsfile,
228 'color=s' => \$color,
229 'no-color' => \$color, #keep old behaviors of -nocolor
230 'nocolor' => \$color, #keep old behaviors of -nocolor
237 list_types(0) if ($list_types);
239 $fix = 1 if ($fix_inplace);
240 $check_orig = $check;
244 my $perl_version_ok = 1;
245 if ($^V && $^V lt $minimum_perl_version) {
246 $perl_version_ok = 0;
247 printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
248 exit(1) if (!$ignore_perl_version);
251 #if no filenames are given, push '-' to read patch from stdin
256 if ($color =~ /^[01]$/) {
258 } elsif ($color =~ /^always$/i) {
260 } elsif ($color =~ /^never$/i) {
262 } elsif ($color =~ /^auto$/i) {
263 $color = (-t STDOUT);
265 die "Invalid color mode: $color\n";
268 sub hash_save_array_words {
269 my ($hashRef, $arrayRef) = @_;
271 my @array = split(/,/, join(',', @$arrayRef));
272 foreach my $word (@array) {
273 $word =~ s/\s*\n?$//g;
276 $word =~ tr/[a-z]/[A-Z]/;
278 next if ($word =~ m/^\s*#/);
279 next if ($word =~ m/^\s*$/);
285 sub hash_show_words {
286 my ($hashRef, $prefix) = @_;
288 if (keys %$hashRef) {
289 print "\nNOTE: $prefix message types:";
290 foreach my $word (sort keys %$hashRef) {
297 hash_save_array_words(\%ignore_type, \@ignore);
298 hash_save_array_words(\%use_type, \@use);
301 my $dbg_possible = 0;
304 for my $key (keys %debug) {
306 eval "\${dbg_$key} = '$debug{$key}';";
310 my $rpt_cleaners = 0;
319 if (!top_of_kernel_tree($root)) {
320 die "$P: $root: --root does not point at a valid tree\n";
323 if (top_of_kernel_tree('.')) {
325 } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ &&
326 top_of_kernel_tree($1)) {
331 if (!defined $root) {
332 print "Must be run from the top-level dir. of a kernel tree\n";
337 my $emitted_corrupt = 0;
340 [A-Za-z_][A-Za-z\d_]*
341 (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)*
343 our $Storage = qr{extern|static|asmlinkage};
357 our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
358 our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
359 our $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
360 our $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
361 our $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
363 # Notes to $Attribute:
364 # We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
386 ____cacheline_aligned|
387 ____cacheline_aligned_in_smp|
388 ____cacheline_internodealigned_in_smp|
392 our $Inline = qr{inline|__always_inline|noinline|__inline|__inline__};
393 our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]};
394 our $Lval = qr{$Ident(?:$Member)*};
396 our $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u};
397 our $Binary = qr{(?i)0b[01]+$Int_type?};
398 our $Hex = qr{(?i)0x[0-9a-f]+$Int_type?};
399 our $Int = qr{[0-9]+$Int_type?};
400 our $Octal = qr{0[0-7]+$Int_type?};
401 our $String = qr{"[X\t]*"};
402 our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
403 our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
404 our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?};
405 our $Float = qr{$Float_hex|$Float_dec|$Float_int};
406 our $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int};
407 our $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
408 our $Compare = qr{<=|>=|==|!=|<|(?<!-)>};
409 our $Arithmetic = qr{\+|-|\*|\/|%};
413 &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
416 our $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
420 our $NonptrTypeMisordered;
421 our $NonptrTypeWithAttr;
425 our $DeclareMisordered;
427 our $NON_ASCII_UTF8 = qr{
428 [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
429 | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
430 | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
431 | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
432 | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
433 | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
434 | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
438 [\x09\x0A\x0D\x20-\x7E] # ASCII
442 our $typeC99Typedefs = qr{(?:__)?(?:[us]_?)?int_?(?:8|16|32|64)_t};
443 our $typeOtherOSTypedefs = qr{(?x:
444 u_(?:char|short|int|long) | # bsd
445 u(?:nchar|short|int|long) # sysv
447 our $typeKernelTypedefs = qr{(?x:
448 (?:__)?(?:u|s|be|le)(?:8|16|32|64)|
451 our $typeTypedefs = qr{(?x:
453 $typeOtherOSTypedefs\b|
454 $typeKernelTypedefs\b
457 our $zero_initializer = qr{(?:(?:0[xX])?0+$Int_type?|NULL|false)\b};
459 our $logFunctions = qr{(?x:
460 printk(?:_ratelimited|_once|_deferred_once|_deferred|)|
461 (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
463 WARN(?:_RATELIMIT|_ONCE|)|
466 seq_vprintf|seq_printf|seq_puts
469 our $allocFunctions = qr{(?x:
471 (?:kv|k|v)[czm]alloc(?:_node|_array)? |
474 (?:\w+)?alloc_skb(?:ip_align)? |
475 # dev_alloc_skb/netdev_alloc_skb, et al
479 our $signature_tags = qr{(?xi:
491 our @typeListMisordered = (
492 qr{char\s+(?:un)?signed},
493 qr{int\s+(?:(?:un)?signed\s+)?short\s},
494 qr{int\s+short(?:\s+(?:un)?signed)},
495 qr{short\s+int(?:\s+(?:un)?signed)},
496 qr{(?:un)?signed\s+int\s+short},
497 qr{short\s+(?:un)?signed},
498 qr{long\s+int\s+(?:un)?signed},
499 qr{int\s+long\s+(?:un)?signed},
500 qr{long\s+(?:un)?signed\s+int},
501 qr{int\s+(?:un)?signed\s+long},
502 qr{int\s+(?:un)?signed},
503 qr{int\s+long\s+long\s+(?:un)?signed},
504 qr{long\s+long\s+int\s+(?:un)?signed},
505 qr{long\s+long\s+(?:un)?signed\s+int},
506 qr{long\s+long\s+(?:un)?signed},
507 qr{long\s+(?:un)?signed},
512 qr{(?:(?:un)?signed\s+)?char},
513 qr{(?:(?:un)?signed\s+)?short\s+int},
514 qr{(?:(?:un)?signed\s+)?short},
515 qr{(?:(?:un)?signed\s+)?int},
516 qr{(?:(?:un)?signed\s+)?long\s+int},
517 qr{(?:(?:un)?signed\s+)?long\s+long\s+int},
518 qr{(?:(?:un)?signed\s+)?long\s+long},
519 qr{(?:(?:un)?signed\s+)?long},
528 qr{${Ident}_handler},
529 qr{${Ident}_handler_fn},
533 our $C90_int_types = qr{(?x:
534 long\s+long\s+int\s+(?:un)?signed|
535 long\s+long\s+(?:un)?signed\s+int|
536 long\s+long\s+(?:un)?signed|
537 (?:(?:un)?signed\s+)?long\s+long\s+int|
538 (?:(?:un)?signed\s+)?long\s+long|
539 int\s+long\s+long\s+(?:un)?signed|
540 int\s+(?:(?:un)?signed\s+)?long\s+long|
542 long\s+int\s+(?:un)?signed|
543 long\s+(?:un)?signed\s+int|
544 long\s+(?:un)?signed|
545 (?:(?:un)?signed\s+)?long\s+int|
546 (?:(?:un)?signed\s+)?long|
547 int\s+long\s+(?:un)?signed|
548 int\s+(?:(?:un)?signed\s+)?long|
551 (?:(?:un)?signed\s+)?int
554 our @typeListFile = ();
555 our @typeListWithAttr = (
557 qr{struct\s+$InitAttribute\s+$Ident},
558 qr{union\s+$InitAttribute\s+$Ident},
561 our @modifierList = (
564 our @modifierListFile = ();
566 our @mode_permission_funcs = (
568 ["module_param_(?:array|named|string)", 4],
569 ["module_param_array_named", 5],
570 ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
571 ["proc_create(?:_data|)", 2],
572 ["(?:CLASS|DEVICE|SENSOR|SENSOR_DEVICE|IIO_DEVICE)_ATTR", 2],
573 ["IIO_DEV_ATTR_[A-Z_]+", 1],
574 ["SENSOR_(?:DEVICE_|)ATTR_2", 2],
575 ["SENSOR_TEMPLATE(?:_2|)", 3],
579 #Create a search pattern for all these functions to speed up a loop below
580 our $mode_perms_search = "";
581 foreach my $entry (@mode_permission_funcs) {
582 $mode_perms_search .= '|' if ($mode_perms_search ne "");
583 $mode_perms_search .= $entry->[0];
585 $mode_perms_search = "(?:${mode_perms_search})";
587 our %deprecated_apis = (
588 "synchronize_rcu_bh" => "synchronize_rcu",
589 "synchronize_rcu_bh_expedited" => "synchronize_rcu_expedited",
590 "call_rcu_bh" => "call_rcu",
591 "rcu_barrier_bh" => "rcu_barrier",
592 "synchronize_sched" => "synchronize_rcu",
593 "synchronize_sched_expedited" => "synchronize_rcu_expedited",
594 "call_rcu_sched" => "call_rcu",
595 "rcu_barrier_sched" => "rcu_barrier",
596 "get_state_synchronize_sched" => "get_state_synchronize_rcu",
597 "cond_synchronize_sched" => "cond_synchronize_rcu",
600 #Create a search pattern for all these strings to speed up a loop below
601 our $deprecated_apis_search = "";
602 foreach my $entry (keys %deprecated_apis) {
603 $deprecated_apis_search .= '|' if ($deprecated_apis_search ne "");
604 $deprecated_apis_search .= $entry;
606 $deprecated_apis_search = "(?:${deprecated_apis_search})";
608 our $mode_perms_world_writable = qr{
616 our %mode_permission_string_types = (
635 #Create a search pattern for all these strings to speed up a loop below
636 our $mode_perms_string_search = "";
637 foreach my $entry (keys %mode_permission_string_types) {
638 $mode_perms_string_search .= '|' if ($mode_perms_string_search ne "");
639 $mode_perms_string_search .= $entry;
641 our $single_mode_perms_string_search = "(?:${mode_perms_string_search})";
642 our $multi_mode_perms_string_search = qr{
643 ${single_mode_perms_string_search}
644 (?:\s*\|\s*${single_mode_perms_string_search})*
650 return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/);
657 while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) {
658 $curpos = pos($string);
661 last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos));
663 $to |= $mode_permission_string_types{$match};
664 $val .= '\s*\|\s*' if ($val ne "");
668 $oval =~ s/^\s*\|\s*//;
669 $oval =~ s/\s*\|\s*$//;
670 return sprintf("%04o", $to);
673 our $allowed_asm_includes = qr{(?x:
679 # memory.h: ARM has a custom one
681 # Load common spelling mistakes and build regular expression list.
685 if (open(my $spelling, '<', $spelling_file)) {
686 while (<$spelling>) {
689 $line =~ s/\s*\n?$//g;
692 next if ($line =~ m/^\s*#/);
693 next if ($line =~ m/^\s*$/);
695 my ($suspect, $fix) = split(/\|\|/, $line);
697 $spelling_fix{$suspect} = $fix;
701 warn "No typos will be found - file '$spelling_file': $!\n";
705 if (open(my $spelling, '<', $codespellfile)) {
706 while (<$spelling>) {
709 $line =~ s/\s*\n?$//g;
712 next if ($line =~ m/^\s*#/);
713 next if ($line =~ m/^\s*$/);
714 next if ($line =~ m/, disabled/i);
718 my ($suspect, $fix) = split(/->/, $line);
720 $spelling_fix{$suspect} = $fix;
724 warn "No codespell typos will be found - file '$codespellfile': $!\n";
728 $misspellings = join("|", sort keys %spelling_fix) if keys %spelling_fix;
731 my ($wordsRef, $file) = @_;
733 if (open(my $words, '<', $file)) {
737 $line =~ s/\s*\n?$//g;
740 next if ($line =~ m/^\s*#/);
741 next if ($line =~ m/^\s*$/);
743 print("$file: '$line' invalid - ignored\n");
747 $$wordsRef .= '|' if ($$wordsRef ne "");
757 my $const_structs = "";
758 read_words(\$const_structs, $conststructsfile)
759 or warn "No structs that should be const will be found - file '$conststructsfile': $!\n";
761 my $typeOtherTypedefs = "";
762 if (length($typedefsfile)) {
763 read_words(\$typeOtherTypedefs, $typedefsfile)
764 or warn "No additional types will be considered - file '$typedefsfile': $!\n";
766 $typeTypedefs .= '|' . $typeOtherTypedefs if ($typeOtherTypedefs ne "");
769 my $mods = "(?x: \n" . join("|\n ", (@modifierList, @modifierListFile)) . "\n)";
770 my $all = "(?x: \n" . join("|\n ", (@typeList, @typeListFile)) . "\n)";
771 my $Misordered = "(?x: \n" . join("|\n ", @typeListMisordered) . "\n)";
772 my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)";
773 $Modifier = qr{(?:$Attribute|$Sparse|$mods)};
779 (?:$Modifier\s+|const\s+)*
781 (?:typeof|__typeof__)\s*\([^\)]*\)|
785 (?:\s+$Modifier|\s+const)*
787 $NonptrTypeMisordered = qr{
788 (?:$Modifier\s+|const\s+)*
792 (?:\s+$Modifier|\s+const)*
794 $NonptrTypeWithAttr = qr{
795 (?:$Modifier\s+|const\s+)*
797 (?:typeof|__typeof__)\s*\([^\)]*\)|
801 (?:\s+$Modifier|\s+const)*
805 (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
806 (?:\s+$Inline|\s+$Modifier)*
808 $TypeMisordered = qr{
809 $NonptrTypeMisordered
810 (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*\s*(?:const\s*)?|\[\])+|(?:\s*\[\s*\])+)?
811 (?:\s+$Inline|\s+$Modifier)*
813 $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
814 $DeclareMisordered = qr{(?:$Storage\s+(?:$Inline\s+)?)?$TypeMisordered};
818 our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
820 # Using $balanced_parens, $LvalOrFunc, or $FuncArg
821 # requires at least perl version v5.10.0
822 # Any use must be runtime checked with $^V
824 our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
825 our $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
826 our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant|$String)};
828 our $declaration_macros = qr{(?x:
829 (?:$Storage\s+)?(?:[A-Z_][A-Z0-9]*_){0,2}(?:DEFINE|DECLARE)(?:_[A-Z0-9]+){1,6}\s*\(|
830 (?:$Storage\s+)?[HLP]?LIST_HEAD\s*\(|
831 (?:$Storage\s+)?${Type}\s+uninitialized_var\s*\(|
832 (?:SKCIPHER_REQUEST|SHASH_DESC|AHASH_REQUEST)_ON_STACK\s*\(
837 return "" if (!defined($string));
839 while ($string =~ /^\s*\(.*\)\s*$/) {
840 $string =~ s@^\s*\(\s*@@;
841 $string =~ s@\s*\)\s*$@@;
844 $string =~ s@\s+@ @g;
849 sub seed_camelcase_file {
852 return if (!(-f $file));
856 open(my $include_file, '<', "$file")
857 or warn "$P: Can't read '$file' $!\n";
858 my $text = <$include_file>;
859 close($include_file);
861 my @lines = split('\n', $text);
863 foreach my $line (@lines) {
864 next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
865 if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
867 } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
869 } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
875 sub is_maintained_obsolete {
878 return 0 if (!$tree || !(-e "$root/scripts/get_maintainer.pl"));
880 my $status = `perl $root/scripts/get_maintainer.pl --status --nom --nol --nogit --nogit-fallback -f $filename 2>&1`;
882 return $status =~ /obsolete/i;
885 sub is_SPDX_License_valid {
888 return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$root/.git"));
890 my $root_path = abs_path($root);
891 my $status = `cd "$root_path"; echo "$license" | python scripts/spdxcheck.py -`;
892 return 0 if ($status ne "");
896 my $camelcase_seeded = 0;
897 sub seed_camelcase_includes {
898 return if ($camelcase_seeded);
901 my $camelcase_cache = "";
902 my @include_files = ();
904 $camelcase_seeded = 1;
907 my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`;
908 chomp $git_last_include_commit;
909 $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
911 my $last_mod_date = 0;
912 $files = `find $root/include -name "*.h"`;
913 @include_files = split('\n', $files);
914 foreach my $file (@include_files) {
915 my $date = POSIX::strftime("%Y%m%d%H%M",
916 localtime((stat $file)[9]));
917 $last_mod_date = $date if ($last_mod_date < $date);
919 $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
922 if ($camelcase_cache ne "" && -f $camelcase_cache) {
923 open(my $camelcase_file, '<', "$camelcase_cache")
924 or warn "$P: Can't read '$camelcase_cache' $!\n";
925 while (<$camelcase_file>) {
929 close($camelcase_file);
935 $files = `git ls-files "include/*.h"`;
936 @include_files = split('\n', $files);
939 foreach my $file (@include_files) {
940 seed_camelcase_file($file);
943 if ($camelcase_cache ne "") {
944 unlink glob ".checkpatch-camelcase.*";
945 open(my $camelcase_file, '>', "$camelcase_cache")
946 or warn "$P: Can't write '$camelcase_cache' $!\n";
947 foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
948 print $camelcase_file ("$_\n");
950 close($camelcase_file);
954 sub git_commit_info {
955 my ($commit, $id, $desc) = @_;
957 return ($id, $desc) if ((which("git") eq "") || !(-e ".git"));
959 my $output = `git log --no-color --format='%H %s' -1 $commit 2>&1`;
960 $output =~ s/^\s*//gm;
961 my @lines = split("\n", $output);
963 return ($id, $desc) if ($#lines < 0);
965 if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous\./) {
966 # Maybe one day convert this block of bash into something that returns
967 # all matching commit ids, but it's very slow...
969 # echo "checking commits $1..."
970 # git rev-list --remotes | grep -i "^$1" |
971 # while read line ; do
972 # git log --format='%H %s' -1 $line |
973 # echo "commit $(cut -c 1-12,41-)"
975 } elsif ($lines[0] =~ /^fatal: ambiguous argument '$commit': unknown revision or path not in the working tree\./) {
978 $id = substr($lines[0], 0, 12);
979 $desc = substr($lines[0], 41);
985 $chk_signoff = 0 if ($file);
990 my @fixed_inserted = ();
991 my @fixed_deleted = ();
994 # If input is git commits, extract all commits from the commit expressions.
995 # For example, HEAD-3 means we need check 'HEAD, HEAD~1, HEAD~2'.
996 die "$P: No git repository found\n" if ($git && !-e ".git");
1000 foreach my $commit_expr (@ARGV) {
1002 if ($commit_expr =~ m/^(.*)-(\d+)$/) {
1003 $git_range = "-$2 $1";
1004 } elsif ($commit_expr =~ m/\.\./) {
1005 $git_range = "$commit_expr";
1007 $git_range = "-1 $commit_expr";
1009 my $lines = `git log --no-color --no-merges --pretty=format:'%H %s' $git_range`;
1010 foreach my $line (split(/\n/, $lines)) {
1011 $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/;
1012 next if (!defined($1) || !defined($2));
1015 unshift(@commits, $sha1);
1016 $git_commits{$sha1} = $subject;
1019 die "$P: no git commits after extraction!\n" if (@commits == 0);
1024 $allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"};
1025 for my $filename (@ARGV) {
1028 open($FILE, '-|', "git format-patch -M --stdout -1 $filename") ||
1029 die "$P: $filename: git format-patch failed - $!\n";
1031 open($FILE, '-|', "diff -u /dev/null $filename") ||
1032 die "$P: $filename: diff failed - $!\n";
1033 } elsif ($filename eq '-') {
1034 open($FILE, '<&STDIN');
1036 open($FILE, '<', "$filename") ||
1037 die "$P: $filename: open failed - $!\n";
1039 if ($filename eq '-') {
1040 $vname = 'Your patch';
1042 $vname = "Commit " . substr($filename, 0, 12) . ' ("' . $git_commits{$filename} . '")';
1048 push(@rawlines, $_);
1052 if ($#ARGV > 0 && $quiet == 0) {
1053 print '-' x length($vname) . "\n";
1055 print '-' x length($vname) . "\n";
1058 if (!process($filename)) {
1064 @fixed_inserted = ();
1065 @fixed_deleted = ();
1067 @modifierListFile = ();
1073 hash_show_words(\%use_type, "Used");
1074 hash_show_words(\%ignore_type, "Ignored");
1076 if (!$perl_version_ok) {
1079 NOTE: perl $^V is not modern enough to detect all possible issues.
1080 An upgrade to at least perl $minimum_perl_version is suggested.
1086 NOTE: If any of the errors are false positives, please report
1087 them to the maintainer, see CHECKPATCH in MAINTAINERS.
1094 sub top_of_kernel_tree {
1098 "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
1099 "README", "Documentation", "arch", "include", "drivers",
1100 "fs", "init", "ipc", "kernel", "lib", "scripts",
1103 foreach my $check (@tree_check) {
1104 if (! -e $root . '/' . $check) {
1112 my ($formatted_email) = @_;
1118 if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) {
1121 $comment = $3 if defined $3;
1122 } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) {
1124 $comment = $2 if defined $2;
1125 } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) {
1127 $comment = $2 if defined $2;
1128 $formatted_email =~ s/\Q$address\E.*$//;
1129 $name = $formatted_email;
1130 $name = trim($name);
1131 $name =~ s/^\"|\"$//g;
1132 # If there's a name left after stripping spaces and
1133 # leading quotes, and the address doesn't have both
1134 # leading and trailing angle brackets, the address
1136 # "joe smith joe@smith.com" bad
1137 # "joe smith <joe@smith.com" bad
1138 if ($name ne "" && $address !~ /^<[^>]+>$/) {
1145 $name = trim($name);
1146 $name =~ s/^\"|\"$//g;
1147 $address = trim($address);
1148 $address =~ s/^\<|\>$//g;
1150 if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
1151 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
1152 $name = "\"$name\"";
1155 return ($name, $address, $comment);
1159 my ($name, $address) = @_;
1161 my $formatted_email;
1163 $name = trim($name);
1164 $name =~ s/^\"|\"$//g;
1165 $address = trim($address);
1167 if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
1168 $name =~ s/(?<!\\)"/\\"/g; ##escape quotes
1169 $name = "\"$name\"";
1172 if ("$name" eq "") {
1173 $formatted_email = "$address";
1175 $formatted_email = "$name <$address>";
1178 return $formatted_email;
1184 foreach my $path (split(/:/, $ENV{PATH})) {
1185 if (-e "$path/$bin") {
1186 return "$path/$bin";
1196 foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
1197 if (-e "$path/$conf") {
1198 return "$path/$conf";
1210 for my $c (split(//, $str)) {
1214 for (; ($n % 8) != 0; $n++) {
1226 (my $res = shift) =~ tr/\t/ /c;
1233 # Drop the diff line leader and expand tabs
1235 $line = expand_tabs($line);
1237 # Pick the indent from the front of the line.
1238 my ($white) = ($line =~ /^(\s*)/);
1240 return (length($line), length($white));
1243 my $sanitise_quote = '';
1245 sub sanitise_line_reset {
1246 my ($in_comment) = @_;
1249 $sanitise_quote = '*/';
1251 $sanitise_quote = '';
1264 # Always copy over the diff marker.
1265 $res = substr($line, 0, 1);
1267 for ($off = 1; $off < length($line); $off++) {
1268 $c = substr($line, $off, 1);
1270 # Comments we are whacking completely including the begin
1271 # and end, all to $;.
1272 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
1273 $sanitise_quote = '*/';
1275 substr($res, $off, 2, "$;$;");
1279 if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
1280 $sanitise_quote = '';
1281 substr($res, $off, 2, "$;$;");
1285 if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') {
1286 $sanitise_quote = '//';
1288 substr($res, $off, 2, $sanitise_quote);
1293 # A \ in a string means ignore the next character.
1294 if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
1296 substr($res, $off, 2, 'XX');
1301 if ($c eq "'" || $c eq '"') {
1302 if ($sanitise_quote eq '') {
1303 $sanitise_quote = $c;
1305 substr($res, $off, 1, $c);
1307 } elsif ($sanitise_quote eq $c) {
1308 $sanitise_quote = '';
1312 #print "c<$c> SQ<$sanitise_quote>\n";
1313 if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
1314 substr($res, $off, 1, $;);
1315 } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") {
1316 substr($res, $off, 1, $;);
1317 } elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
1318 substr($res, $off, 1, 'X');
1320 substr($res, $off, 1, $c);
1324 if ($sanitise_quote eq '//') {
1325 $sanitise_quote = '';
1328 # The pathname on a #include may be surrounded by '<' and '>'.
1329 if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) {
1330 my $clean = 'X' x length($1);
1331 $res =~ s@\<.*\>@<$clean>@;
1333 # The whole of a #error is a string.
1334 } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) {
1335 my $clean = 'X' x length($1);
1336 $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
1339 if ($allow_c99_comments && $res =~ m@(//.*$)@) {
1341 $res =~ s/\Q$match\E/"$;" x length($match)/e;
1347 sub get_quoted_string {
1348 my ($line, $rawline) = @_;
1350 return "" if (!defined($line) || !defined($rawline));
1351 return "" if ($line !~ m/($String)/g);
1352 return substr($rawline, $-[0], $+[0] - $-[0]);
1355 sub ctx_statement_block {
1356 my ($linenr, $remain, $off) = @_;
1357 my $line = $linenr - 1;
1360 my $coff = $off - 1;
1374 @stack = (['', 0]) if ($#stack == -1);
1376 #warn "CSB: blk<$blk> remain<$remain>\n";
1377 # If we are about to drop off the end, pull in more
1380 for (; $remain > 0; $line++) {
1381 last if (!defined $lines[$line]);
1382 next if ($lines[$line] =~ /^-/);
1385 $blk .= $lines[$line] . "\n";
1386 $len = length($blk);
1390 # Bail if there is no further context.
1391 #warn "CSB: blk<$blk> off<$off> len<$len>\n";
1395 if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) {
1401 $c = substr($blk, $off, 1);
1402 $remainder = substr($blk, $off);
1404 #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
1406 # Handle nested #if/#else.
1407 if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) {
1408 push(@stack, [ $type, $level ]);
1409 } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) {
1410 ($type, $level) = @{$stack[$#stack - 1]};
1411 } elsif ($remainder =~ /^#\s*endif\b/) {
1412 ($type, $level) = @{pop(@stack)};
1415 # Statement ends at the ';' or a close '}' at the
1417 if ($level == 0 && $c eq ';') {
1421 # An else is really a conditional as long as its not else if
1422 if ($level == 0 && $coff_set == 0 &&
1423 (!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
1424 $remainder =~ /^(else)(?:\s|{)/ &&
1425 $remainder !~ /^else\s+if\b/) {
1426 $coff = $off + length($1) - 1;
1428 #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
1429 #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
1432 if (($type eq '' || $type eq '(') && $c eq '(') {
1436 if ($type eq '(' && $c eq ')') {
1438 $type = ($level != 0)? '(' : '';
1440 if ($level == 0 && $coff < $soff) {
1443 #warn "CSB: mark coff<$coff>\n";
1446 if (($type eq '' || $type eq '{') && $c eq '{') {
1450 if ($type eq '{' && $c eq '}') {
1452 $type = ($level != 0)? '{' : '';
1455 if (substr($blk, $off + 1, 1) eq ';') {
1461 # Preprocessor commands end at the newline unless escaped.
1462 if ($type eq '#' && $c eq "\n" && $p ne "\\") {
1470 # We are truly at the end, so shuffle to the next line.
1477 my $statement = substr($blk, $soff, $off - $soff + 1);
1478 my $condition = substr($blk, $soff, $coff - $soff + 1);
1480 #warn "STATEMENT<$statement>\n";
1481 #warn "CONDITION<$condition>\n";
1483 #print "coff<$coff> soff<$off> loff<$loff>\n";
1485 return ($statement, $condition,
1486 $line, $remain + 1, $off - $loff + 1, $level);
1489 sub statement_lines {
1492 # Strip the diff line prefixes and rip blank lines at start and end.
1493 $stmt =~ s/(^|\n)./$1/g;
1497 my @stmt_lines = ($stmt =~ /\n/g);
1499 return $#stmt_lines + 2;
1502 sub statement_rawlines {
1505 my @stmt_lines = ($stmt =~ /\n/g);
1507 return $#stmt_lines + 2;
1510 sub statement_block_size {
1513 $stmt =~ s/(^|\n)./$1/g;
1519 my @stmt_lines = ($stmt =~ /\n/g);
1520 my @stmt_statements = ($stmt =~ /;/g);
1522 my $stmt_lines = $#stmt_lines + 2;
1523 my $stmt_statements = $#stmt_statements + 1;
1525 if ($stmt_lines > $stmt_statements) {
1528 return $stmt_statements;
1532 sub ctx_statement_full {
1533 my ($linenr, $remain, $off) = @_;
1534 my ($statement, $condition, $level);
1538 # Grab the first conditional/block pair.
1539 ($statement, $condition, $linenr, $remain, $off, $level) =
1540 ctx_statement_block($linenr, $remain, $off);
1541 #print "F: c<$condition> s<$statement> remain<$remain>\n";
1542 push(@chunks, [ $condition, $statement ]);
1543 if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
1544 return ($level, $linenr, @chunks);
1547 # Pull in the following conditional/block pairs and see if they
1548 # could continue the statement.
1550 ($statement, $condition, $linenr, $remain, $off, $level) =
1551 ctx_statement_block($linenr, $remain, $off);
1552 #print "C: c<$condition> s<$statement> remain<$remain>\n";
1553 last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
1555 push(@chunks, [ $condition, $statement ]);
1558 return ($level, $linenr, @chunks);
1562 my ($linenr, $remain, $outer, $open, $close, $off) = @_;
1564 my $start = $linenr - 1;
1571 my @stack = ($level);
1572 for ($line = $start; $remain > 0; $line++) {
1573 next if ($rawlines[$line] =~ /^-/);
1576 $blk .= $rawlines[$line];
1578 # Handle nested #if/#else.
1579 if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) {
1580 push(@stack, $level);
1581 } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) {
1582 $level = $stack[$#stack - 1];
1583 } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) {
1584 $level = pop(@stack);
1587 foreach my $c (split(//, $lines[$line])) {
1588 ##print "C<$c>L<$level><$open$close>O<$off>\n";
1594 if ($c eq $close && $level > 0) {
1596 last if ($level == 0);
1597 } elsif ($c eq $open) {
1602 if (!$outer || $level <= 1) {
1603 push(@res, $rawlines[$line]);
1606 last if ($level == 0);
1609 return ($level, @res);
1611 sub ctx_block_outer {
1612 my ($linenr, $remain) = @_;
1614 my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0);
1618 my ($linenr, $remain) = @_;
1620 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1624 my ($linenr, $remain, $off) = @_;
1626 my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1629 sub ctx_block_level {
1630 my ($linenr, $remain) = @_;
1632 return ctx_block_get($linenr, $remain, 0, '{', '}', 0);
1634 sub ctx_statement_level {
1635 my ($linenr, $remain, $off) = @_;
1637 return ctx_block_get($linenr, $remain, 0, '(', ')', $off);
1640 sub ctx_locate_comment {
1641 my ($first_line, $end_line) = @_;
1643 # Catch a comment on the end of the line itself.
1644 my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@);
1645 return $current_comment if (defined $current_comment);
1647 # Look through the context and try and figure out if there is a
1650 $current_comment = '';
1651 for (my $linenr = $first_line; $linenr < $end_line; $linenr++) {
1652 my $line = $rawlines[$linenr - 1];
1654 if ($linenr == $first_line and $line =~ m@^.\s*\*@) {
1657 if ($line =~ m@/\*@) {
1660 if (!$in_comment && $current_comment ne '') {
1661 $current_comment = '';
1663 $current_comment .= $line . "\n" if ($in_comment);
1664 if ($line =~ m@\*/@) {
1669 chomp($current_comment);
1670 return($current_comment);
1672 sub ctx_has_comment {
1673 my ($first_line, $end_line) = @_;
1674 my $cmt = ctx_locate_comment($first_line, $end_line);
1676 ##print "LINE: $rawlines[$end_line - 1 ]\n";
1677 ##print "CMMT: $cmt\n";
1679 return ($cmt ne '');
1683 my ($linenr, $cnt) = @_;
1685 my $offset = $linenr - 1;
1690 $line = $rawlines[$offset++];
1691 next if (defined($line) && $line =~ /^-/);
1699 my ($linenr, $lc) = @_;
1701 my $stat_real = raw_line($linenr, 0);
1702 for (my $count = $linenr + 1; $count <= $lc; $count++) {
1703 $stat_real = $stat_real . "\n" . raw_line($count, 0);
1710 my ($linenr, $cnt, $here) = @_;
1712 my $herectx = $here . "\n";
1713 for (my $n = 0; $n < $cnt; $n++) {
1714 $herectx .= raw_line($linenr, $n) . "\n";
1725 while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) {
1728 $coded = sprintf("^%c", unpack('C', $2) + 64);
1737 my $av_preprocessor = 0;
1742 sub annotate_reset {
1743 $av_preprocessor = 0;
1745 @av_paren_type = ('E');
1746 $av_pend_colon = 'O';
1749 sub annotate_values {
1750 my ($stream, $type) = @_;
1753 my $var = '_' x length($stream);
1756 print "$stream\n" if ($dbg_values > 1);
1758 while (length($cur)) {
1759 @av_paren_type = ('E') if ($#av_paren_type < 0);
1760 print " <" . join('', @av_paren_type) .
1761 "> <$type> <$av_pending>" if ($dbg_values > 1);
1762 if ($cur =~ /^(\s+)/o) {
1763 print "WS($1)\n" if ($dbg_values > 1);
1764 if ($1 =~ /\n/ && $av_preprocessor) {
1765 $type = pop(@av_paren_type);
1766 $av_preprocessor = 0;
1769 } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
1770 print "CAST($1)\n" if ($dbg_values > 1);
1771 push(@av_paren_type, $type);
1774 } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) {
1775 print "DECLARE($1)\n" if ($dbg_values > 1);
1778 } elsif ($cur =~ /^($Modifier)\s*/) {
1779 print "MODIFIER($1)\n" if ($dbg_values > 1);
1782 } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) {
1783 print "DEFINE($1,$2)\n" if ($dbg_values > 1);
1784 $av_preprocessor = 1;
1785 push(@av_paren_type, $type);
1791 } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) {
1792 print "UNDEF($1)\n" if ($dbg_values > 1);
1793 $av_preprocessor = 1;
1794 push(@av_paren_type, $type);
1796 } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) {
1797 print "PRE_START($1)\n" if ($dbg_values > 1);
1798 $av_preprocessor = 1;
1800 push(@av_paren_type, $type);
1801 push(@av_paren_type, $type);
1804 } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) {
1805 print "PRE_RESTART($1)\n" if ($dbg_values > 1);
1806 $av_preprocessor = 1;
1808 push(@av_paren_type, $av_paren_type[$#av_paren_type]);
1812 } elsif ($cur =~ /^(\#\s*(?:endif))/o) {
1813 print "PRE_END($1)\n" if ($dbg_values > 1);
1815 $av_preprocessor = 1;
1817 # Assume all arms of the conditional end as this
1818 # one does, and continue as if the #endif was not here.
1819 pop(@av_paren_type);
1820 push(@av_paren_type, $type);
1823 } elsif ($cur =~ /^(\\\n)/o) {
1824 print "PRECONT($1)\n" if ($dbg_values > 1);
1826 } elsif ($cur =~ /^(__attribute__)\s*\(?/o) {
1827 print "ATTR($1)\n" if ($dbg_values > 1);
1828 $av_pending = $type;
1831 } elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
1832 print "SIZEOF($1)\n" if ($dbg_values > 1);
1838 } elsif ($cur =~ /^(if|while|for)\b/o) {
1839 print "COND($1)\n" if ($dbg_values > 1);
1843 } elsif ($cur =~/^(case)/o) {
1844 print "CASE($1)\n" if ($dbg_values > 1);
1845 $av_pend_colon = 'C';
1848 } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
1849 print "KEYWORD($1)\n" if ($dbg_values > 1);
1852 } elsif ($cur =~ /^(\()/o) {
1853 print "PAREN('$1')\n" if ($dbg_values > 1);
1854 push(@av_paren_type, $av_pending);
1858 } elsif ($cur =~ /^(\))/o) {
1859 my $new_type = pop(@av_paren_type);
1860 if ($new_type ne '_') {
1862 print "PAREN('$1') -> $type\n"
1863 if ($dbg_values > 1);
1865 print "PAREN('$1')\n" if ($dbg_values > 1);
1868 } elsif ($cur =~ /^($Ident)\s*\(/o) {
1869 print "FUNC($1)\n" if ($dbg_values > 1);
1873 } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) {
1874 if (defined $2 && $type eq 'C' || $type eq 'T') {
1875 $av_pend_colon = 'B';
1876 } elsif ($type eq 'E') {
1877 $av_pend_colon = 'L';
1879 print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1);
1882 } elsif ($cur =~ /^($Ident|$Constant)/o) {
1883 print "IDENT($1)\n" if ($dbg_values > 1);
1886 } elsif ($cur =~ /^($Assignment)/o) {
1887 print "ASSIGN($1)\n" if ($dbg_values > 1);
1890 } elsif ($cur =~/^(;|{|})/) {
1891 print "END($1)\n" if ($dbg_values > 1);
1893 $av_pend_colon = 'O';
1895 } elsif ($cur =~/^(,)/) {
1896 print "COMMA($1)\n" if ($dbg_values > 1);
1899 } elsif ($cur =~ /^(\?)/o) {
1900 print "QUESTION($1)\n" if ($dbg_values > 1);
1903 } elsif ($cur =~ /^(:)/o) {
1904 print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1);
1906 substr($var, length($res), 1, $av_pend_colon);
1907 if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') {
1912 $av_pend_colon = 'O';
1914 } elsif ($cur =~ /^(\[)/o) {
1915 print "CLOSE($1)\n" if ($dbg_values > 1);
1918 } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
1921 print "OPV($1)\n" if ($dbg_values > 1);
1928 substr($var, length($res), 1, $variant);
1931 } elsif ($cur =~ /^($Operators)/o) {
1932 print "OP($1)\n" if ($dbg_values > 1);
1933 if ($1 ne '++' && $1 ne '--') {
1937 } elsif ($cur =~ /(^.)/o) {
1938 print "C($1)\n" if ($dbg_values > 1);
1941 $cur = substr($cur, length($1));
1942 $res .= $type x length($1);
1946 return ($res, $var);
1950 my ($possible, $line) = @_;
1951 my $notPermitted = qr{(?:
1968 ^(?:typedef|struct|enum)\b
1970 warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
1971 if ($possible !~ $notPermitted) {
1972 # Check for modifiers.
1973 $possible =~ s/\s*$Storage\s*//g;
1974 $possible =~ s/\s*$Sparse\s*//g;
1975 if ($possible =~ /^\s*$/) {
1977 } elsif ($possible =~ /\s/) {
1978 $possible =~ s/\s*$Type\s*//g;
1979 for my $modifier (split(' ', $possible)) {
1980 if ($modifier !~ $notPermitted) {
1981 warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible);
1982 push(@modifierListFile, $modifier);
1987 warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible);
1988 push(@typeListFile, $possible);
1992 warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
2001 $type =~ tr/[a-z]/[A-Z]/;
2003 return defined $use_type{$type} if (scalar keys %use_type > 0);
2005 return !defined $ignore_type{$type};
2009 my ($level, $type, $msg) = @_;
2011 if (!show_type($type) ||
2012 (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
2017 if ($level eq 'ERROR') {
2019 } elsif ($level eq 'WARNING') {
2025 $output .= $prefix . $level . ':';
2027 $output .= BLUE if ($color);
2028 $output .= "$type:";
2030 $output .= RESET if ($color);
2031 $output .= ' ' . $msg . "\n";
2034 my @lines = split("\n", $output, -1);
2035 splice(@lines, 1, 1);
2036 $output = join("\n", @lines);
2038 $output = (split('\n', $output))[0] . "\n" if ($terse);
2040 push(our @report, $output);
2049 sub fixup_current_range {
2050 my ($lineRef, $offset, $length) = @_;
2052 if ($$lineRef =~ /^\@\@ -\d+,\d+ \+(\d+),(\d+) \@\@/) {
2055 my $no = $o + $offset;
2056 my $nl = $l + $length;
2057 $$lineRef =~ s/\+$o,$l \@\@/\+$no,$nl \@\@/;
2061 sub fix_inserted_deleted_lines {
2062 my ($linesRef, $insertedRef, $deletedRef) = @_;
2064 my $range_last_linenr = 0;
2065 my $delta_offset = 0;
2070 my $next_insert = 0;
2071 my $next_delete = 0;
2075 my $inserted = @{$insertedRef}[$next_insert++];
2076 my $deleted = @{$deletedRef}[$next_delete++];
2078 foreach my $old_line (@{$linesRef}) {
2080 my $line = $old_line; #don't modify the array
2081 if ($line =~ /^(?:\+\+\+|\-\-\-)\s+\S+/) { #new filename
2083 } elsif ($line =~ /^\@\@ -\d+,\d+ \+\d+,\d+ \@\@/) { #new hunk
2084 $range_last_linenr = $new_linenr;
2085 fixup_current_range(\$line, $delta_offset, 0);
2088 while (defined($deleted) && ${$deleted}{'LINENR'} == $old_linenr) {
2089 $deleted = @{$deletedRef}[$next_delete++];
2091 fixup_current_range(\$lines[$range_last_linenr], $delta_offset--, -1);
2094 while (defined($inserted) && ${$inserted}{'LINENR'} == $old_linenr) {
2095 push(@lines, ${$inserted}{'LINE'});
2096 $inserted = @{$insertedRef}[$next_insert++];
2098 fixup_current_range(\$lines[$range_last_linenr], $delta_offset++, 1);
2102 push(@lines, $line);
2112 sub fix_insert_line {
2113 my ($linenr, $line) = @_;
2119 push(@fixed_inserted, $inserted);
2122 sub fix_delete_line {
2123 my ($linenr, $line) = @_;
2130 push(@fixed_deleted, $deleted);
2134 my ($type, $msg) = @_;
2136 if (report("ERROR", $type, $msg)) {
2144 my ($type, $msg) = @_;
2146 if (report("WARNING", $type, $msg)) {
2154 my ($type, $msg) = @_;
2156 if ($check && report("CHECK", $type, $msg)) {
2164 sub check_absolute_file {
2165 my ($absolute, $herecurr) = @_;
2166 my $file = $absolute;
2168 ##print "absolute<$absolute>\n";
2170 # See if any suffix of this path is a path within the tree.
2171 while ($file =~ s@^[^/]*/@@) {
2172 if (-f "$root/$file") {
2173 ##print "file<$file>\n";
2181 # It is, so see if the prefix is acceptable.
2182 my $prefix = $absolute;
2183 substr($prefix, -length($file)) = '';
2185 ##print "prefix<$prefix>\n";
2186 if ($prefix ne ".../") {
2187 WARN("USE_RELATIVE_PATH",
2188 "use relative pathname instead of absolute in changelog text\n" . $herecurr);
2195 $string =~ s/^\s+|\s+$//g;
2203 $string =~ s/^\s+//;
2211 $string =~ s/\s+$//;
2216 sub string_find_replace {
2217 my ($string, $find, $replace) = @_;
2219 $string =~ s/$find/$replace/g;
2227 my $source_indent = 8;
2228 my $max_spaces_before_tab = $source_indent - 1;
2229 my $spaces_to_tab = " " x $source_indent;
2231 #convert leading spaces to tabs
2232 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
2233 #Remove spaces before a tab
2234 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
2239 sub pos_last_openparen {
2244 my $opens = $line =~ tr/\(/\(/;
2245 my $closes = $line =~ tr/\)/\)/;
2247 my $last_openparen = 0;
2249 if (($opens == 0) || ($closes >= $opens)) {
2253 my $len = length($line);
2255 for ($pos = 0; $pos < $len; $pos++) {
2256 my $string = substr($line, $pos);
2257 if ($string =~ /^($FuncArg|$balanced_parens)/) {
2258 $pos += length($1) - 1;
2259 } elsif (substr($line, $pos, 1) eq '(') {
2260 $last_openparen = $pos;
2261 } elsif (index($string, '(') == -1) {
2266 return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
2270 my $filename = shift;
2276 my $stashrawline="";
2286 my $authorsignoff = 0;
2288 my $is_binding_patch = -1;
2289 my $in_header_lines = $file ? 0 : 1;
2290 my $in_commit_log = 0; #Scanning lines before patch
2291 my $has_commit_log = 0; #Encountered lines before patch
2292 my $commit_log_lines = 0; #Number of commit log lines
2293 my $commit_log_possible_stack_dump = 0;
2294 my $commit_log_long_line = 0;
2295 my $commit_log_has_diff = 0;
2296 my $reported_maintainer_file = 0;
2297 my $non_utf8_charset = 0;
2299 my $last_blank_line = 0;
2300 my $last_coalesced_string_linenr = -1;
2308 # Trace the real file/line as we go.
2313 my $context_function; #undef'd unless there's a known function
2315 my $comment_edge = 0;
2319 my $prev_values = 'E';
2322 my %suppress_ifbraces;
2323 my %suppress_whiletrailers;
2324 my %suppress_export;
2325 my $suppress_statement = 0;
2327 my %signatures = ();
2329 # Pre-scan the patch sanitizing the lines.
2330 # Pre-scan the patch looking for any __setup documentation.
2332 my @setup_docs = ();
2335 my $camelcase_file_seeded = 0;
2337 my $checklicenseline = 1;
2339 sanitise_line_reset();
2341 foreach my $rawline (@rawlines) {
2345 push(@fixed, $rawline) if ($fix);
2347 if ($rawline=~/^\+\+\+\s+(\S+)/) {
2349 if ($1 =~ m@Documentation/admin-guide/kernel-parameters.rst$@) {
2354 if ($rawline =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
2363 # Guestimate if this is a continuing comment. Run
2364 # the context looking for a comment "edge". If this
2365 # edge is a close comment then we must be in a comment
2369 for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
2370 next if (defined $rawlines[$ln - 1] &&
2371 $rawlines[$ln - 1] =~ /^-/);
2373 #print "RAW<$rawlines[$ln - 1]>\n";
2374 last if (!defined $rawlines[$ln - 1]);
2375 if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ &&
2376 $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) {
2381 if (defined $edge && $edge eq '*/') {
2385 # Guestimate if this is a continuing comment. If this
2386 # is the start of a diff block and this line starts
2387 # ' *' then it is very likely a comment.
2388 if (!defined $edge &&
2389 $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@)
2394 ##print "COMMENT:$in_comment edge<$edge> $rawline\n";
2395 sanitise_line_reset($in_comment);
2397 } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) {
2398 # Standardise the strings and chars within the input to
2399 # simplify matching -- only bother with positive lines.
2400 $line = sanitise_line($rawline);
2402 push(@lines, $line);
2405 $realcnt-- if ($line =~ /^(?:\+| |$)/);
2410 #print "==>$rawline\n";
2411 #print "-->$line\n";
2413 if ($setup_docs && $line =~ /^\+/) {
2414 push(@setup_docs, $line);
2423 foreach my $line (@lines) {
2426 my $sline = $line; #copy of $line
2427 $sline =~ s/$;/ /g; #with comments as spaces
2429 my $rawline = $rawlines[$linenr - 1];
2431 # check if it's a mode change, rename or start of a patch
2432 if (!$in_commit_log &&
2433 ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ ||
2434 ($line =~ /^rename (?:from|to) \S+\s*$/ ||
2435 $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) {
2439 #extract the line range in the file after the patch is applied
2440 if (!$in_commit_log &&
2441 $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) {
2444 $first_line = $linenr + 1;
2454 %suppress_ifbraces = ();
2455 %suppress_whiletrailers = ();
2456 %suppress_export = ();
2457 $suppress_statement = 0;
2458 if ($context =~ /\b(\w+)\s*\(/) {
2459 $context_function = $1;
2461 undef $context_function;
2465 # track the line number as we move through the hunk, note that
2466 # new versions of GNU diff omit the leading space on completely
2467 # blank context lines so we need to count that too.
2468 } elsif ($line =~ /^( |\+|$)/) {
2470 $realcnt-- if ($realcnt != 0);
2472 # Measure the line length and indent.
2473 ($length, $indent) = line_stats($rawline);
2475 # Track the previous line.
2476 ($prevline, $stashline) = ($stashline, $line);
2477 ($previndent, $stashindent) = ($stashindent, $indent);
2478 ($prevrawline, $stashrawline) = ($stashrawline, $rawline);
2480 #warn "line<$line>\n";
2482 } elsif ($realcnt == 1) {
2486 my $hunk_line = ($realcnt != 0);
2488 $here = "#$linenr: " if (!$file);
2489 $here = "#$realline: " if ($file);
2492 # extract the filename as it passes
2493 if ($line =~ /^diff --git.*?(\S+)$/) {
2495 $realfile =~ s@^([^/]*)/@@ if (!$file);
2498 } elsif ($line =~ /^\+\+\+\s+(\S+)/) {
2500 $realfile =~ s@^([^/]*)/@@ if (!$file);
2504 if (!$file && $tree && $p1_prefix ne '' &&
2505 -e "$root/$p1_prefix") {
2506 WARN("PATCH_PREFIX",
2507 "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n");
2510 if ($realfile =~ m@^include/asm/@) {
2511 ERROR("MODIFIED_INCLUDE_ASM",
2512 "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
2517 #make up the handle for any error we report on this line
2519 $prefix = "$realfile:$realline: "
2522 $prefix = "$filename:$realline: ";
2524 $prefix = "$filename:$linenr: ";
2529 if (is_maintained_obsolete($realfile)) {
2531 "$realfile is marked as 'obsolete' in the MAINTAINERS hierarchy. No unnecessary modifications please.\n");
2533 if ($realfile =~ m@^(?:drivers/net/|net/|drivers/staging/)@) {
2536 $check = $check_orig;
2538 $checklicenseline = 1;
2540 if ($realfile !~ /^MAINTAINERS/) {
2541 my $last_binding_patch = $is_binding_patch;
2543 $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@;
2545 if (($last_binding_patch != -1) &&
2546 ($last_binding_patch ^ $is_binding_patch)) {
2547 WARN("DT_SPLIT_BINDING_PATCH",
2548 "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.txt\n");
2555 $here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
2557 my $hereline = "$here\n$rawline\n";
2558 my $herecurr = "$here\n$rawline\n";
2559 my $hereprev = "$here\n$prevrawline\n$rawline\n";
2561 $cnt_lines++ if ($realcnt != 0);
2563 # Verify the existence of a commit log if appropriate
2564 # 2 is used because a $signature is counted in $commit_log_lines
2565 if ($in_commit_log) {
2566 if ($line !~ /^\s*$/) {
2567 $commit_log_lines++; #could be a $signature
2569 } elsif ($has_commit_log && $commit_log_lines < 2) {
2570 WARN("COMMIT_MESSAGE",
2571 "Missing commit description - Add an appropriate one\n");
2572 $commit_log_lines = 2; #warn only once
2575 # Check if the commit log has what seems like a diff which can confuse patch
2576 if ($in_commit_log && !$commit_log_has_diff &&
2577 (($line =~ m@^\s+diff\b.*a/[\w/]+@ &&
2578 $line =~ m@^\s+diff\b.*a/([\w/]+)\s+b/$1\b@) ||
2579 $line =~ m@^\s*(?:\-\-\-\s+a/|\+\+\+\s+b/)@ ||
2580 $line =~ m/^\s*\@\@ \-\d+,\d+ \+\d+,\d+ \@\@/)) {
2581 ERROR("DIFF_IN_COMMIT_MSG",
2582 "Avoid using diff content in the commit message - patch(1) might not work\n" . $herecurr);
2583 $commit_log_has_diff = 1;
2586 # Check for incorrect file permissions
2587 if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
2588 my $permhere = $here . "FILE: $realfile\n";
2589 if ($realfile !~ m@scripts/@ &&
2590 $realfile !~ /\.(py|pl|awk|sh)$/) {
2591 ERROR("EXECUTE_PERMISSIONS",
2592 "do not set execute permissions for source files\n" . $permhere);
2596 # Check the patch for a From:
2597 if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) {
2599 $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i);
2603 # Check the patch for a signoff:
2604 if ($line =~ /^\s*signed-off-by:/i) {
2607 if ($author ne '') {
2610 if ($l =~ /^\s*signed-off-by:\s*\Q$author\E/i) {
2616 # Check if MAINTAINERS is being updated. If so, there's probably no need to
2617 # emit the "does MAINTAINERS need updating?" message on file add/move/delete
2618 if ($line =~ /^\s*MAINTAINERS\s*\|/) {
2619 $reported_maintainer_file = 1;
2622 # Check signature styles
2623 if (!$in_header_lines &&
2624 $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) {
2625 my $space_before = $1;
2627 my $space_after = $3;
2629 my $ucfirst_sign_off = ucfirst(lc($sign_off));
2631 if ($sign_off !~ /$signature_tags/) {
2632 WARN("BAD_SIGN_OFF",
2633 "Non-standard signature: $sign_off\n" . $herecurr);
2635 if (defined $space_before && $space_before ne "") {
2636 if (WARN("BAD_SIGN_OFF",
2637 "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
2639 $fixed[$fixlinenr] =
2640 "$ucfirst_sign_off $email";
2643 if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
2644 if (WARN("BAD_SIGN_OFF",
2645 "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
2647 $fixed[$fixlinenr] =
2648 "$ucfirst_sign_off $email";
2652 if (!defined $space_after || $space_after ne " ") {
2653 if (WARN("BAD_SIGN_OFF",
2654 "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
2656 $fixed[$fixlinenr] =
2657 "$ucfirst_sign_off $email";
2661 my ($email_name, $email_address, $comment) = parse_email($email);
2662 my $suggested_email = format_email(($email_name, $email_address));
2663 if ($suggested_email eq "") {
2664 ERROR("BAD_SIGN_OFF",
2665 "Unrecognized email address: '$email'\n" . $herecurr);
2667 my $dequoted = $suggested_email;
2668 $dequoted =~ s/^"//;
2669 $dequoted =~ s/" </ </;
2670 # Don't force email to have quotes
2671 # Allow just an angle bracketed address
2672 if ("$dequoted$comment" ne $email &&
2673 "<$email_address>$comment" ne $email &&
2674 "$suggested_email$comment" ne $email) {
2675 WARN("BAD_SIGN_OFF",
2676 "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
2680 # Check for duplicate signatures
2681 my $sig_nospace = $line;
2682 $sig_nospace =~ s/\s//g;
2683 $sig_nospace = lc($sig_nospace);
2684 if (defined $signatures{$sig_nospace}) {
2685 WARN("BAD_SIGN_OFF",
2686 "Duplicate signature\n" . $herecurr);
2688 $signatures{$sig_nospace} = 1;
2692 # Check email subject for common tools that don't need to be mentioned
2693 if ($in_header_lines &&
2694 $line =~ /^Subject:.*\b(?:checkpatch|sparse|smatch)\b[^:]/i) {
2695 WARN("EMAIL_SUBJECT",
2696 "A patch subject line should describe the change not the tool that found it\n" . $herecurr);
2699 # Check for unwanted Gerrit info
2700 if ($in_commit_log && $line =~ /^\s*change-id:/i) {
2701 ERROR("GERRIT_CHANGE_ID",
2702 "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr);
2705 # Check if the commit log is in a possible stack dump
2706 if ($in_commit_log && !$commit_log_possible_stack_dump &&
2707 ($line =~ /^\s*(?:WARNING:|BUG:)/ ||
2708 $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ ||
2710 $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) {
2711 # stack dump address
2712 $commit_log_possible_stack_dump = 1;
2715 # Check for line lengths > 75 in commit log, warn once
2716 if ($in_commit_log && !$commit_log_long_line &&
2717 length($line) > 75 &&
2718 !($line =~ /^\s*[a-zA-Z0-9_\/\.]+\s+\|\s+\d+/ ||
2719 # file delta changes
2720 $line =~ /^\s*(?:[\w\.\-]+\/)++[\w\.\-]+:/ ||
2722 $line =~ /^\s*(?:Fixes:|Link:)/i ||
2723 # A Fixes: or Link: line
2724 $commit_log_possible_stack_dump)) {
2725 WARN("COMMIT_LOG_LONG_LINE",
2726 "Possible unwrapped commit description (prefer a maximum 75 chars per line)\n" . $herecurr);
2727 $commit_log_long_line = 1;
2730 # Reset possible stack dump if a blank line is found
2731 if ($in_commit_log && $commit_log_possible_stack_dump &&
2733 $commit_log_possible_stack_dump = 0;
2736 # Check for git id commit length and improperly formed commit descriptions
2737 if ($in_commit_log && !$commit_log_possible_stack_dump &&
2738 $line !~ /^\s*(?:Link|Patchwork|http|https|BugLink):/i &&
2739 $line !~ /^This reverts commit [0-9a-f]{7,40}/ &&
2740 ($line =~ /\bcommit\s+[0-9a-f]{5,}\b/i ||
2741 ($line =~ /(?:\s|^)[0-9a-f]{12,40}(?:[\s"'\(\[]|$)/i &&
2742 $line !~ /[\<\[][0-9a-f]{12,40}[\>\]]/i &&
2743 $line !~ /\bfixes:\s*[0-9a-f]{12,40}/i))) {
2744 my $init_char = "c";
2745 my $orig_commit = "";
2752 my $id = '0123456789ab';
2753 my $orig_desc = "commit description";
2754 my $description = "";
2756 if ($line =~ /\b(c)ommit\s+([0-9a-f]{5,})\b/i) {
2758 $orig_commit = lc($2);
2759 } elsif ($line =~ /\b([0-9a-f]{12,40})\b/i) {
2760 $orig_commit = lc($1);
2763 $short = 0 if ($line =~ /\bcommit\s+[0-9a-f]{12,40}/i);
2764 $long = 1 if ($line =~ /\bcommit\s+[0-9a-f]{41,}/i);
2765 $space = 0 if ($line =~ /\bcommit [0-9a-f]/i);
2766 $case = 0 if ($line =~ /\b[Cc]ommit\s+[0-9a-f]{5,40}[^A-F]/);
2767 if ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)"\)/i) {
2770 } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s*$/i &&
2771 defined $rawlines[$linenr] &&
2772 $rawlines[$linenr] =~ /^\s*\("([^"]+)"\)/) {
2775 } elsif ($line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("[^"]+$/i &&
2776 defined $rawlines[$linenr] &&
2777 $rawlines[$linenr] =~ /^\s*[^"]+"\)/) {
2778 $line =~ /\bcommit\s+[0-9a-f]{5,}\s+\("([^"]+)$/i;
2780 $rawlines[$linenr] =~ /^\s*([^"]+)"\)/;
2781 $orig_desc .= " " . $1;
2785 ($id, $description) = git_commit_info($orig_commit,
2789 ($short || $long || $space || $case || ($orig_desc ne $description) || !$hasparens)) {
2790 ERROR("GIT_COMMIT_ID",
2791 "Please use git commit description style 'commit <12+ chars of sha1> (\"<title line>\")' - ie: '${init_char}ommit $id (\"$description\")'\n" . $herecurr);
2795 # Check for added, moved or deleted files
2796 if (!$reported_maintainer_file && !$in_commit_log &&
2797 ($line =~ /^(?:new|deleted) file mode\s*\d+\s*$/ ||
2798 $line =~ /^rename (?:from|to) [\w\/\.\-]+\s*$/ ||
2799 ($line =~ /\{\s*([\w\/\.\-]*)\s*\=\>\s*([\w\/\.\-]*)\s*\}/ &&
2800 (defined($1) || defined($2))))) {
2802 $reported_maintainer_file = 1;
2803 WARN("FILE_PATH_CHANGES",
2804 "added, moved or deleted file(s), does MAINTAINERS need updating?\n" . $herecurr);
2807 # Check for wrappage within a valid hunk of the file
2808 if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) {
2809 ERROR("CORRUPTED_PATCH",
2810 "patch seems to be corrupt (line wrapped?)\n" .
2811 $herecurr) if (!$emitted_corrupt++);
2814 # UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
2815 if (($realfile =~ /^$/ || $line =~ /^\+/) &&
2816 $rawline !~ m/^$UTF8*$/) {
2817 my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/);
2819 my $blank = copy_spacing($rawline);
2820 my $ptr = substr($blank, 0, length($utf8_prefix)) . "^";
2821 my $hereptr = "$hereline$ptr\n";
2824 "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
2827 # Check if it's the start of a commit log
2828 # (not a header line and we haven't seen the patch filename)
2829 if ($in_header_lines && $realfile =~ /^$/ &&
2830 !($rawline =~ /^\s+(?:\S|$)/ ||
2831 $rawline =~ /^(?:commit\b|from\b|[\w-]+:)/i)) {
2832 $in_header_lines = 0;
2834 $has_commit_log = 1;
2837 # Check if there is UTF-8 in a commit log when a mail header has explicitly
2838 # declined it, i.e defined some charset where it is missing.
2839 if ($in_header_lines &&
2840 $rawline =~ /^Content-Type:.+charset="(.+)".*$/ &&
2842 $non_utf8_charset = 1;
2845 if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ &&
2846 $rawline =~ /$NON_ASCII_UTF8/) {
2847 WARN("UTF8_BEFORE_PATCH",
2848 "8-bit UTF-8 used in possible commit log\n" . $herecurr);
2851 # Check for absolute kernel paths in commit message
2852 if ($tree && $in_commit_log) {
2853 while ($line =~ m{(?:^|\s)(/\S*)}g) {
2856 if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
2857 check_absolute_file($1, $herecurr)) {
2860 check_absolute_file($file, $herecurr);
2865 # Check for various typo / spelling mistakes
2866 if (defined($misspellings) &&
2867 ($in_commit_log || $line =~ /^(?:\+|Subject:)/i)) {
2868 while ($rawline =~ /(?:^|[^a-z@])($misspellings)(?:\b|$|[^a-z@])/gi) {
2870 my $typo_fix = $spelling_fix{lc($typo)};
2871 $typo_fix = ucfirst($typo_fix) if ($typo =~ /^[A-Z]/);
2872 $typo_fix = uc($typo_fix) if ($typo =~ /^[A-Z]+$/);
2873 my $msg_level = \&WARN;
2874 $msg_level = \&CHK if ($file);
2875 if (&{$msg_level}("TYPO_SPELLING",
2876 "'$typo' may be misspelled - perhaps '$typo_fix'?\n" . $herecurr) &&
2878 $fixed[$fixlinenr] =~ s/(^|[^A-Za-z@])($typo)($|[^A-Za-z@])/$1$typo_fix$3/;
2883 # ignore non-hunk lines and lines being removed
2884 next if (!$hunk_line || $line =~ /^-/);
2886 #trailing whitespace
2887 if ($line =~ /^\+.*\015/) {
2888 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2889 if (ERROR("DOS_LINE_ENDINGS",
2890 "DOS line endings\n" . $herevet) &&
2892 $fixed[$fixlinenr] =~ s/[\s\015]+$//;
2894 } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
2895 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2896 if (ERROR("TRAILING_WHITESPACE",
2897 "trailing whitespace\n" . $herevet) &&
2899 $fixed[$fixlinenr] =~ s/\s+$//;
2905 # Check for FSF mailing addresses.
2906 if ($rawline =~ /\bwrite to the Free/i ||
2907 $rawline =~ /\b675\s+Mass\s+Ave/i ||
2908 $rawline =~ /\b59\s+Temple\s+Pl/i ||
2909 $rawline =~ /\b51\s+Franklin\s+St/i) {
2910 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
2911 my $msg_level = \&ERROR;
2912 $msg_level = \&CHK if ($file);
2913 &{$msg_level}("FSF_MAILING_ADDRESS",
2914 "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet)
2917 # check for Kconfig help text having a real description
2918 # Only applies when adding the entry originally, after that we do not have
2919 # sufficient context to determine whether it is indeed long enough.
2920 if ($realfile =~ /Kconfig/ &&
2921 # 'choice' is usually the last thing on the line (though
2922 # Kconfig supports named choices), so use a word boundary
2923 # (\b) rather than a whitespace character (\s)
2924 $line =~ /^\+\s*(?:config|menuconfig|choice)\b/) {
2927 my $ln = $linenr + 1;
2931 for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) {
2932 $f = $lines[$ln - 1];
2933 $cnt-- if ($lines[$ln - 1] !~ /^-/);
2934 $is_end = $lines[$ln - 1] =~ /^\+/;
2936 next if ($f =~ /^-/);
2937 last if (!$file && $f =~ /^\@\@/);
2939 if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
2941 } elsif ($lines[$ln - 1] =~ /^\+\s*(?:help|---help---)\s*$/) {
2942 if ($lines[$ln - 1] =~ "---help---") {
2943 WARN("CONFIG_DESCRIPTION",
2944 "prefer 'help' over '---help---' for new help texts\n" . $herecurr);
2952 next if ($f =~ /^$/);
2954 # This only checks context lines in the patch
2955 # and so hopefully shouldn't trigger false
2956 # positives, even though some of these are
2957 # common words in help texts
2958 if ($f =~ /^\s*(?:config|menuconfig|choice|endchoice|
2959 if|endif|menu|endmenu|source)\b/x) {
2965 if ($is_start && $is_end && $length < $min_conf_desc_length) {
2966 WARN("CONFIG_DESCRIPTION",
2967 "please write a paragraph that describes the config symbol fully\n" . $herecurr);
2969 #print "is_start<$is_start> is_end<$is_end> length<$length>\n";
2972 # check for MAINTAINERS entries that don't have the right form
2973 if ($realfile =~ /^MAINTAINERS$/ &&
2974 $rawline =~ /^\+[A-Z]:/ &&
2975 $rawline !~ /^\+[A-Z]:\t\S/) {
2976 if (WARN("MAINTAINERS_STYLE",
2977 "MAINTAINERS entries use one tab after TYPE:\n" . $herecurr) &&
2979 $fixed[$fixlinenr] =~ s/^(\+[A-Z]):\s*/$1:\t/;
2983 # discourage the use of boolean for type definition attributes of Kconfig options
2984 if ($realfile =~ /Kconfig/ &&
2985 $line =~ /^\+\s*\bboolean\b/) {
2986 WARN("CONFIG_TYPE_BOOLEAN",
2987 "Use of boolean is deprecated, please use bool instead.\n" . $herecurr);
2990 if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) &&
2991 ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) {
2994 'EXTRA_AFLAGS' => 'asflags-y',
2995 'EXTRA_CFLAGS' => 'ccflags-y',
2996 'EXTRA_CPPFLAGS' => 'cppflags-y',
2997 'EXTRA_LDFLAGS' => 'ldflags-y',
3000 WARN("DEPRECATED_VARIABLE",
3001 "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
3004 # check for DT compatible documentation
3005 if (defined $root &&
3006 (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
3007 ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
3009 my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
3011 my $dt_path = $root . "/Documentation/devicetree/bindings/";
3012 my $vp_file = $dt_path . "vendor-prefixes.txt";
3014 foreach my $compat (@compats) {
3015 my $compat2 = $compat;
3016 $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
3017 my $compat3 = $compat;
3018 $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
3019 `grep -Erq "$compat|$compat2|$compat3" $dt_path`;
3021 WARN("UNDOCUMENTED_DT_STRING",
3022 "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
3025 next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
3027 `grep -Eq "^$vendor\\b" $vp_file`;
3029 WARN("UNDOCUMENTED_DT_STRING",
3030 "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
3035 # check for using SPDX license tag at beginning of files
3036 if ($realline == $checklicenseline) {
3037 if ($rawline =~ /^[ \+]\s*\#\!\s*\//) {
3038 $checklicenseline = 2;
3039 } elsif ($rawline =~ /^\+/) {
3041 if ($realfile =~ /\.(h|s|S)$/) {
3043 } elsif ($realfile =~ /\.(c|dts|dtsi)$/) {
3045 } elsif (($checklicenseline == 2) || $realfile =~ /\.(sh|pl|py|awk|tc)$/) {
3047 } elsif ($realfile =~ /\.rst$/) {
3051 # check SPDX comment style for .[chsS] files
3052 if ($realfile =~ /\.[chsS]$/ &&
3053 $rawline =~ /SPDX-License-Identifier:/ &&
3054 $rawline !~ /^\+\s*\Q$comment\E\s*/) {
3055 WARN("SPDX_LICENSE_TAG",
3056 "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr);
3059 if ($comment !~ /^$/ &&
3060 $rawline !~ /^\+\Q$comment\E SPDX-License-Identifier: /) {
3061 WARN("SPDX_LICENSE_TAG",
3062 "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr);
3063 } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) {
3064 my $spdx_license = $1;
3065 if (!is_SPDX_License_valid($spdx_license)) {
3066 WARN("SPDX_LICENSE_TAG",
3067 "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr);
3073 # check we are in a valid source file if not then ignore this hunk
3074 next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/);
3076 # check for using SPDX-License-Identifier on the wrong line number
3077 if ($realline != $checklicenseline &&
3078 $rawline =~ /\bSPDX-License-Identifier:/ &&
3079 substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) {
3080 WARN("SPDX_LICENSE_TAG",
3081 "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr);
3084 # line length limit (with some exclusions)
3086 # There are a few types of lines that may extend beyond $max_line_length:
3087 # logging functions like pr_info that end in a string
3088 # lines with a single string
3089 # #defines that are a single string
3090 # lines with an RFC3986 like URL
3092 # There are 3 different line length message types:
3093 # LONG_LINE_COMMENT a comment starts before but extends beyond $max_line_length
3094 # LONG_LINE_STRING a string starts before but extends beyond $max_line_length
3095 # LONG_LINE all other lines longer than $max_line_length
3097 # if LONG_LINE is ignored, the other 2 types are also ignored
3100 if ($line =~ /^\+/ && $length > $max_line_length) {
3101 my $msg_type = "LONG_LINE";
3103 # Check the allowed long line types first
3105 # logging functions that end in a string that starts
3106 # before $max_line_length
3107 if ($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(?:KERN_\S+\s*|[^"]*))?($String\s*(?:|,|\)\s*;)\s*)$/ &&
3108 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
3111 # lines with only strings (w/ possible termination)
3112 # #defines with only strings
3113 } elsif ($line =~ /^\+\s*$String\s*(?:\s*|,|\)\s*;)\s*$/ ||
3114 $line =~ /^\+\s*#\s*define\s+\w+\s+$String$/) {
3117 # More special cases
3118 } elsif ($line =~ /^\+.*\bEFI_GUID\s*\(/ ||
3119 $line =~ /^\+\s*(?:\w+)?\s*DEFINE_PER_CPU/) {
3122 # URL ($rawline is used in case the URL is in a comment)
3123 } elsif ($rawline =~ /^\+.*\b[a-z][\w\.\+\-]*:\/\/\S+/i) {
3126 # Otherwise set the alternate message types
3128 # a comment starts before $max_line_length
3129 } elsif ($line =~ /($;[\s$;]*)$/ &&
3130 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
3131 $msg_type = "LONG_LINE_COMMENT"
3133 # a quoted string starts before $max_line_length
3134 } elsif ($sline =~ /\s*($String(?:\s*(?:\\|,\s*|\)\s*;\s*))?)$/ &&
3135 length(expand_tabs(substr($line, 1, length($line) - length($1) - 1))) <= $max_line_length) {
3136 $msg_type = "LONG_LINE_STRING"
3139 if ($msg_type ne "" &&
3140 (show_type("LONG_LINE") || show_type($msg_type))) {
3142 "line over $max_line_length characters\n" . $herecurr);
3146 # check for adding lines without a newline.
3147 if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) {
3148 WARN("MISSING_EOF_NEWLINE",
3149 "adding a line without newline at end of file\n" . $herecurr);
3152 # check we are in a valid source file C or perl if not then ignore this hunk
3153 next if ($realfile !~ /\.(h|c|pl|dtsi|dts)$/);
3155 # at the beginning of a line any tabs must come first and anything
3156 # more than 8 must use tabs.
3157 if ($rawline =~ /^\+\s* \t\s*\S/ ||
3158 $rawline =~ /^\+\s* \s*/) {
3159 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3161 if (ERROR("CODE_INDENT",
3162 "code indent should use tabs where possible\n" . $herevet) &&
3164 $fixed[$fixlinenr] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
3168 # check for space before tabs.
3169 if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
3170 my $herevet = "$here\n" . cat_vet($rawline) . "\n";
3171 if (WARN("SPACE_BEFORE_TAB",
3172 "please, no space before tabs\n" . $herevet) &&
3174 while ($fixed[$fixlinenr] =~
3175 s/(^\+.*) {8,8}\t/$1\t\t/) {}
3176 while ($fixed[$fixlinenr] =~
3177 s/(^\+.*) +\t/$1\t/) {}
3181 # check for assignments on the start of a line
3182 if ($sline =~ /^\+\s+($Assignment)[^=]/) {
3183 CHK("ASSIGNMENT_CONTINUATIONS",
3184 "Assignment operator '$1' should be on the previous line\n" . $hereprev);