10a920b5bSAndy Whitcroft#!/usr/bin/perl -w 2dbf004d7SDave Jones# (c) 2001, Dave Jones. (the file handling bit) 300df344fSAndy Whitcroft# (c) 2005, Joel Schopp <[email protected]> (the ugly bit) 42a5a2c25SAndy Whitcroft# (c) 2007,2008, Andy Whitcroft <[email protected]> (new conditions, test suite) 5015830beSAndy Whitcroft# (c) 2008-2010 Andy Whitcroft <[email protected]> 60a920b5bSAndy Whitcroft# Licensed under the terms of the GNU GPL License version 2 70a920b5bSAndy Whitcroft 80a920b5bSAndy Whitcroftuse strict; 90a920b5bSAndy Whitcroft 100a920b5bSAndy Whitcroftmy $P = $0; 1100df344fSAndy Whitcroft$P =~ s@.*/@@g; 120a920b5bSAndy Whitcroft 13000d1cc1SJoe Perchesmy $V = '0.32'; 140a920b5bSAndy Whitcroft 150a920b5bSAndy Whitcroftuse Getopt::Long qw(:config no_auto_abbrev); 160a920b5bSAndy Whitcroft 170a920b5bSAndy Whitcroftmy $quiet = 0; 180a920b5bSAndy Whitcroftmy $tree = 1; 190a920b5bSAndy Whitcroftmy $chk_signoff = 1; 200a920b5bSAndy Whitcroftmy $chk_patch = 1; 21773647a0SAndy Whitcroftmy $tst_only; 226c72ffaaSAndy Whitcroftmy $emacs = 0; 238905a67cSAndy Whitcroftmy $terse = 0; 246c72ffaaSAndy Whitcroftmy $file = 0; 256c72ffaaSAndy Whitcroftmy $check = 0; 268905a67cSAndy Whitcroftmy $summary = 1; 278905a67cSAndy Whitcroftmy $mailback = 0; 2813214adfSAndy Whitcroftmy $summary_file = 0; 29000d1cc1SJoe Perchesmy $show_types = 0; 30*3705ce5bSJoe Perchesmy $fix = 0; 316c72ffaaSAndy Whitcroftmy $root; 32c2fdda0dSAndy Whitcroftmy %debug; 33000d1cc1SJoe Perchesmy %ignore_type = (); 34000d1cc1SJoe Perchesmy @ignore = (); 3577f5b10aSHannes Edermy $help = 0; 36000d1cc1SJoe Perchesmy $configuration_file = ".checkpatch.conf"; 376cd7f386SJoe Perchesmy $max_line_length = 80; 3877f5b10aSHannes Eder 3977f5b10aSHannes Edersub help { 4077f5b10aSHannes Eder my ($exitcode) = @_; 4177f5b10aSHannes Eder 4277f5b10aSHannes Eder print << "EOM"; 4377f5b10aSHannes EderUsage: $P [OPTION]... [FILE]... 4477f5b10aSHannes EderVersion: $V 4577f5b10aSHannes Eder 4677f5b10aSHannes EderOptions: 4777f5b10aSHannes Eder -q, --quiet quiet 4877f5b10aSHannes Eder --no-tree run without a kernel tree 4977f5b10aSHannes Eder --no-signoff do not check for 'Signed-off-by' line 5077f5b10aSHannes Eder --patch treat FILE as patchfile (default) 5177f5b10aSHannes Eder --emacs emacs compile window format 5277f5b10aSHannes Eder --terse one line per report 5377f5b10aSHannes Eder -f, --file treat FILE as regular source file 5477f5b10aSHannes Eder --subjective, --strict enable more subjective tests 55000d1cc1SJoe Perches --ignore TYPE(,TYPE2...) ignore various comma separated message types 566cd7f386SJoe Perches --max-line-length=n set the maximum line length, if exceeded, warn 57000d1cc1SJoe Perches --show-types show the message "types" in the output 5877f5b10aSHannes Eder --root=PATH PATH to the kernel tree root 5977f5b10aSHannes Eder --no-summary suppress the per-file summary 6077f5b10aSHannes Eder --mailback only produce a report in case of warnings/errors 6177f5b10aSHannes Eder --summary-file include the filename in summary 6277f5b10aSHannes Eder --debug KEY=[0|1] turn on/off debugging of KEY, where KEY is one of 6377f5b10aSHannes Eder 'values', 'possible', 'type', and 'attr' (default 6477f5b10aSHannes Eder is all off) 6577f5b10aSHannes Eder --test-only=WORD report only warnings/errors containing WORD 6677f5b10aSHannes Eder literally 67*3705ce5bSJoe Perches --fix EXPERIMENTAL - may create horrible results 68*3705ce5bSJoe Perches If correctable single-line errors exist, create 69*3705ce5bSJoe Perches "<inputfile>.EXPERIMENTAL-checkpatch-fixes" 70*3705ce5bSJoe Perches with potential errors corrected to the preferred 71*3705ce5bSJoe Perches checkpatch style 7277f5b10aSHannes Eder -h, --help, --version display this help and exit 7377f5b10aSHannes Eder 7477f5b10aSHannes EderWhen FILE is - read standard input. 7577f5b10aSHannes EderEOM 7677f5b10aSHannes Eder 7777f5b10aSHannes Eder exit($exitcode); 7877f5b10aSHannes Eder} 7977f5b10aSHannes Eder 80000d1cc1SJoe Perchesmy $conf = which_conf($configuration_file); 81000d1cc1SJoe Perchesif (-f $conf) { 82000d1cc1SJoe Perches my @conf_args; 83000d1cc1SJoe Perches open(my $conffile, '<', "$conf") 84000d1cc1SJoe Perches or warn "$P: Can't find a readable $configuration_file file $!\n"; 85000d1cc1SJoe Perches 86000d1cc1SJoe Perches while (<$conffile>) { 87000d1cc1SJoe Perches my $line = $_; 88000d1cc1SJoe Perches 89000d1cc1SJoe Perches $line =~ s/\s*\n?$//g; 90000d1cc1SJoe Perches $line =~ s/^\s*//g; 91000d1cc1SJoe Perches $line =~ s/\s+/ /g; 92000d1cc1SJoe Perches 93000d1cc1SJoe Perches next if ($line =~ m/^\s*#/); 94000d1cc1SJoe Perches next if ($line =~ m/^\s*$/); 95000d1cc1SJoe Perches 96000d1cc1SJoe Perches my @words = split(" ", $line); 97000d1cc1SJoe Perches foreach my $word (@words) { 98000d1cc1SJoe Perches last if ($word =~ m/^#/); 99000d1cc1SJoe Perches push (@conf_args, $word); 100000d1cc1SJoe Perches } 101000d1cc1SJoe Perches } 102000d1cc1SJoe Perches close($conffile); 103000d1cc1SJoe Perches unshift(@ARGV, @conf_args) if @conf_args; 104000d1cc1SJoe Perches} 105000d1cc1SJoe Perches 1060a920b5bSAndy WhitcroftGetOptions( 1076c72ffaaSAndy Whitcroft 'q|quiet+' => \$quiet, 1080a920b5bSAndy Whitcroft 'tree!' => \$tree, 1090a920b5bSAndy Whitcroft 'signoff!' => \$chk_signoff, 1100a920b5bSAndy Whitcroft 'patch!' => \$chk_patch, 1116c72ffaaSAndy Whitcroft 'emacs!' => \$emacs, 1128905a67cSAndy Whitcroft 'terse!' => \$terse, 11377f5b10aSHannes Eder 'f|file!' => \$file, 1146c72ffaaSAndy Whitcroft 'subjective!' => \$check, 1156c72ffaaSAndy Whitcroft 'strict!' => \$check, 116000d1cc1SJoe Perches 'ignore=s' => \@ignore, 117000d1cc1SJoe Perches 'show-types!' => \$show_types, 1186cd7f386SJoe Perches 'max-line-length=i' => \$max_line_length, 1196c72ffaaSAndy Whitcroft 'root=s' => \$root, 1208905a67cSAndy Whitcroft 'summary!' => \$summary, 1218905a67cSAndy Whitcroft 'mailback!' => \$mailback, 12213214adfSAndy Whitcroft 'summary-file!' => \$summary_file, 123*3705ce5bSJoe Perches 'fix!' => \$fix, 124c2fdda0dSAndy Whitcroft 'debug=s' => \%debug, 125773647a0SAndy Whitcroft 'test-only=s' => \$tst_only, 12677f5b10aSHannes Eder 'h|help' => \$help, 12777f5b10aSHannes Eder 'version' => \$help 12877f5b10aSHannes Eder) or help(1); 12977f5b10aSHannes Eder 13077f5b10aSHannes Ederhelp(0) if ($help); 1310a920b5bSAndy Whitcroft 1320a920b5bSAndy Whitcroftmy $exit = 0; 1330a920b5bSAndy Whitcroft 1340a920b5bSAndy Whitcroftif ($#ARGV < 0) { 13577f5b10aSHannes Eder print "$P: no input files\n"; 1360a920b5bSAndy Whitcroft exit(1); 1370a920b5bSAndy Whitcroft} 1380a920b5bSAndy Whitcroft 139000d1cc1SJoe Perches@ignore = split(/,/, join(',',@ignore)); 140000d1cc1SJoe Perchesforeach my $word (@ignore) { 141000d1cc1SJoe Perches $word =~ s/\s*\n?$//g; 142000d1cc1SJoe Perches $word =~ s/^\s*//g; 143000d1cc1SJoe Perches $word =~ s/\s+/ /g; 144000d1cc1SJoe Perches $word =~ tr/[a-z]/[A-Z]/; 145000d1cc1SJoe Perches 146000d1cc1SJoe Perches next if ($word =~ m/^\s*#/); 147000d1cc1SJoe Perches next if ($word =~ m/^\s*$/); 148000d1cc1SJoe Perches 149000d1cc1SJoe Perches $ignore_type{$word}++; 150000d1cc1SJoe Perches} 151000d1cc1SJoe Perches 152c2fdda0dSAndy Whitcroftmy $dbg_values = 0; 153c2fdda0dSAndy Whitcroftmy $dbg_possible = 0; 1547429c690SAndy Whitcroftmy $dbg_type = 0; 155a1ef277eSAndy Whitcroftmy $dbg_attr = 0; 156c2fdda0dSAndy Whitcroftfor my $key (keys %debug) { 15721caa13cSAndy Whitcroft ## no critic 15821caa13cSAndy Whitcroft eval "\${dbg_$key} = '$debug{$key}';"; 15921caa13cSAndy Whitcroft die "$@" if ($@); 160c2fdda0dSAndy Whitcroft} 161c2fdda0dSAndy Whitcroft 162d2c0a235SAndy Whitcroftmy $rpt_cleaners = 0; 163d2c0a235SAndy Whitcroft 1648905a67cSAndy Whitcroftif ($terse) { 1658905a67cSAndy Whitcroft $emacs = 1; 1668905a67cSAndy Whitcroft $quiet++; 1678905a67cSAndy Whitcroft} 1688905a67cSAndy Whitcroft 1696c72ffaaSAndy Whitcroftif ($tree) { 1706c72ffaaSAndy Whitcroft if (defined $root) { 1716c72ffaaSAndy Whitcroft if (!top_of_kernel_tree($root)) { 1726c72ffaaSAndy Whitcroft die "$P: $root: --root does not point at a valid tree\n"; 1736c72ffaaSAndy Whitcroft } 1746c72ffaaSAndy Whitcroft } else { 1756c72ffaaSAndy Whitcroft if (top_of_kernel_tree('.')) { 1766c72ffaaSAndy Whitcroft $root = '.'; 1776c72ffaaSAndy Whitcroft } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && 1786c72ffaaSAndy Whitcroft top_of_kernel_tree($1)) { 1796c72ffaaSAndy Whitcroft $root = $1; 1806c72ffaaSAndy Whitcroft } 1816c72ffaaSAndy Whitcroft } 1826c72ffaaSAndy Whitcroft 1836c72ffaaSAndy Whitcroft if (!defined $root) { 1840a920b5bSAndy Whitcroft print "Must be run from the top-level dir. of a kernel tree\n"; 1850a920b5bSAndy Whitcroft exit(2); 1860a920b5bSAndy Whitcroft } 1876c72ffaaSAndy Whitcroft} 1886c72ffaaSAndy Whitcroft 1896c72ffaaSAndy Whitcroftmy $emitted_corrupt = 0; 1906c72ffaaSAndy Whitcroft 1912ceb532bSAndy Whitcroftour $Ident = qr{ 1922ceb532bSAndy Whitcroft [A-Za-z_][A-Za-z\d_]* 1932ceb532bSAndy Whitcroft (?:\s*\#\#\s*[A-Za-z_][A-Za-z\d_]*)* 1942ceb532bSAndy Whitcroft }x; 1956c72ffaaSAndy Whitcroftour $Storage = qr{extern|static|asmlinkage}; 1966c72ffaaSAndy Whitcroftour $Sparse = qr{ 1976c72ffaaSAndy Whitcroft __user| 1986c72ffaaSAndy Whitcroft __kernel| 1996c72ffaaSAndy Whitcroft __force| 2006c72ffaaSAndy Whitcroft __iomem| 2016c72ffaaSAndy Whitcroft __must_check| 2026c72ffaaSAndy Whitcroft __init_refok| 203417495edSAndy Whitcroft __kprobes| 204165e72a6SSven Eckelmann __ref| 205165e72a6SSven Eckelmann __rcu 2066c72ffaaSAndy Whitcroft }x; 20752131292SWolfram Sang 20852131292SWolfram Sang# Notes to $Attribute: 20952131292SWolfram Sang# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check 2106c72ffaaSAndy Whitcroftour $Attribute = qr{ 2116c72ffaaSAndy Whitcroft const| 21203f1df7dSJoe Perches __percpu| 21303f1df7dSJoe Perches __nocast| 21403f1df7dSJoe Perches __safe| 21503f1df7dSJoe Perches __bitwise__| 21603f1df7dSJoe Perches __packed__| 21703f1df7dSJoe Perches __packed2__| 21803f1df7dSJoe Perches __naked| 21903f1df7dSJoe Perches __maybe_unused| 22003f1df7dSJoe Perches __always_unused| 22103f1df7dSJoe Perches __noreturn| 22203f1df7dSJoe Perches __used| 22303f1df7dSJoe Perches __cold| 22403f1df7dSJoe Perches __noclone| 22503f1df7dSJoe Perches __deprecated| 2266c72ffaaSAndy Whitcroft __read_mostly| 2276c72ffaaSAndy Whitcroft __kprobes| 22852131292SWolfram Sang __(?:mem|cpu|dev|)(?:initdata|initconst|init\b)| 22924e1d81aSAndy Whitcroft ____cacheline_aligned| 23024e1d81aSAndy Whitcroft ____cacheline_aligned_in_smp| 2315fe3af11SAndy Whitcroft ____cacheline_internodealigned_in_smp| 2325fe3af11SAndy Whitcroft __weak 2336c72ffaaSAndy Whitcroft }x; 234c45dcabdSAndy Whitcroftour $Modifier; 2356c72ffaaSAndy Whitcroftour $Inline = qr{inline|__always_inline|noinline}; 2366c72ffaaSAndy Whitcroftour $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; 2376c72ffaaSAndy Whitcroftour $Lval = qr{$Ident(?:$Member)*}; 2386c72ffaaSAndy Whitcroft 23995e2c602SJoe Perchesour $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u}; 24095e2c602SJoe Perchesour $Binary = qr{(?i)0b[01]+$Int_type?}; 24195e2c602SJoe Perchesour $Hex = qr{(?i)0x[0-9a-f]+$Int_type?}; 24295e2c602SJoe Perchesour $Int = qr{[0-9]+$Int_type?}; 243326b1ffcSJoe Perchesour $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?}; 244326b1ffcSJoe Perchesour $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?}; 245326b1ffcSJoe Perchesour $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?}; 24674349bccSJoe Perchesour $Float = qr{$Float_hex|$Float_dec|$Float_int}; 24795e2c602SJoe Perchesour $Constant = qr{$Float|$Binary|$Hex|$Int}; 248326b1ffcSJoe Perchesour $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=}; 24986f9d059SAndy Whitcroftour $Compare = qr{<=|>=|==|!=|<|>}; 25023f780c9SJoe Perchesour $Arithmetic = qr{\+|-|\*|\/|%}; 2516c72ffaaSAndy Whitcroftour $Operators = qr{ 2526c72ffaaSAndy Whitcroft <=|>=|==|!=| 2536c72ffaaSAndy Whitcroft =>|->|<<|>>|<|>|!|~| 25423f780c9SJoe Perches &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic 2556c72ffaaSAndy Whitcroft }x; 2566c72ffaaSAndy Whitcroft 2578905a67cSAndy Whitcroftour $NonptrType; 2588905a67cSAndy Whitcroftour $Type; 2598905a67cSAndy Whitcroftour $Declare; 2608905a67cSAndy Whitcroft 26115662b3eSJoe Perchesour $NON_ASCII_UTF8 = qr{ 26215662b3eSJoe Perches [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte 263171ae1a4SAndy Whitcroft | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs 264171ae1a4SAndy Whitcroft | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte 265171ae1a4SAndy Whitcroft | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates 266171ae1a4SAndy Whitcroft | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 267171ae1a4SAndy Whitcroft | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 268171ae1a4SAndy Whitcroft | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 269171ae1a4SAndy Whitcroft}x; 270171ae1a4SAndy Whitcroft 27115662b3eSJoe Perchesour $UTF8 = qr{ 27215662b3eSJoe Perches [\x09\x0A\x0D\x20-\x7E] # ASCII 27315662b3eSJoe Perches | $NON_ASCII_UTF8 27415662b3eSJoe Perches}x; 27515662b3eSJoe Perches 2768ed22cadSAndy Whitcroftour $typeTypedefs = qr{(?x: 277fb9e9096SAndy Whitcroft (?:__)?(?:u|s|be|le)(?:8|16|32|64)| 2788ed22cadSAndy Whitcroft atomic_t 2798ed22cadSAndy Whitcroft)}; 2808ed22cadSAndy Whitcroft 281691e669bSJoe Perchesour $logFunctions = qr{(?x: 2826e60c02eSJoe Perches printk(?:_ratelimited|_once|)| 2836e60c02eSJoe Perches [a-z0-9]+_(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| 2846e60c02eSJoe Perches WARN(?:_RATELIMIT|_ONCE|)| 285b0531722SJoe Perches panic| 286b0531722SJoe Perches MODULE_[A-Z_]+ 287691e669bSJoe Perches)}; 288691e669bSJoe Perches 28920112475SJoe Perchesour $signature_tags = qr{(?xi: 29020112475SJoe Perches Signed-off-by:| 29120112475SJoe Perches Acked-by:| 29220112475SJoe Perches Tested-by:| 29320112475SJoe Perches Reviewed-by:| 29420112475SJoe Perches Reported-by:| 2958543ae12SMugunthan V N Suggested-by:| 29620112475SJoe Perches To:| 29720112475SJoe Perches Cc: 29820112475SJoe Perches)}; 29920112475SJoe Perches 3008905a67cSAndy Whitcroftour @typeList = ( 3018905a67cSAndy Whitcroft qr{void}, 302c45dcabdSAndy Whitcroft qr{(?:unsigned\s+)?char}, 303c45dcabdSAndy Whitcroft qr{(?:unsigned\s+)?short}, 304c45dcabdSAndy Whitcroft qr{(?:unsigned\s+)?int}, 305c45dcabdSAndy Whitcroft qr{(?:unsigned\s+)?long}, 306c45dcabdSAndy Whitcroft qr{(?:unsigned\s+)?long\s+int}, 307c45dcabdSAndy Whitcroft qr{(?:unsigned\s+)?long\s+long}, 308c45dcabdSAndy Whitcroft qr{(?:unsigned\s+)?long\s+long\s+int}, 3098905a67cSAndy Whitcroft qr{unsigned}, 3108905a67cSAndy Whitcroft qr{float}, 3118905a67cSAndy Whitcroft qr{double}, 3128905a67cSAndy Whitcroft qr{bool}, 3138905a67cSAndy Whitcroft qr{struct\s+$Ident}, 3148905a67cSAndy Whitcroft qr{union\s+$Ident}, 3158905a67cSAndy Whitcroft qr{enum\s+$Ident}, 3168905a67cSAndy Whitcroft qr{${Ident}_t}, 3178905a67cSAndy Whitcroft qr{${Ident}_handler}, 3188905a67cSAndy Whitcroft qr{${Ident}_handler_fn}, 3198905a67cSAndy Whitcroft); 320c45dcabdSAndy Whitcroftour @modifierList = ( 321c45dcabdSAndy Whitcroft qr{fastcall}, 322c45dcabdSAndy Whitcroft); 3238905a67cSAndy Whitcroft 3247840a94cSWolfram Sangour $allowed_asm_includes = qr{(?x: 3257840a94cSWolfram Sang irq| 3267840a94cSWolfram Sang memory 3277840a94cSWolfram Sang)}; 3287840a94cSWolfram Sang# memory.h: ARM has a custom one 3297840a94cSWolfram Sang 3308905a67cSAndy Whitcroftsub build_types { 331d2172eb5SAndy Whitcroft my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)"; 332d2172eb5SAndy Whitcroft my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)"; 333c8cb2ca3SAndy Whitcroft $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; 3348905a67cSAndy Whitcroft $NonptrType = qr{ 335d2172eb5SAndy Whitcroft (?:$Modifier\s+|const\s+)* 336cf655043SAndy Whitcroft (?: 3376b48db24SAndy Whitcroft (?:typeof|__typeof__)\s*\([^\)]*\)| 3388ed22cadSAndy Whitcroft (?:$typeTypedefs\b)| 339c45dcabdSAndy Whitcroft (?:${all}\b) 340cf655043SAndy Whitcroft ) 341c8cb2ca3SAndy Whitcroft (?:\s+$Modifier|\s+const)* 3428905a67cSAndy Whitcroft }x; 3438905a67cSAndy Whitcroft $Type = qr{ 344c45dcabdSAndy Whitcroft $NonptrType 345b337d8b8SAndy Whitcroft (?:(?:\s|\*|\[\])+\s*const|(?:\s|\*|\[\])+|(?:\s*\[\s*\])+)? 346c8cb2ca3SAndy Whitcroft (?:\s+$Inline|\s+$Modifier)* 3478905a67cSAndy Whitcroft }x; 3488905a67cSAndy Whitcroft $Declare = qr{(?:$Storage\s+)?$Type}; 3498905a67cSAndy Whitcroft} 3508905a67cSAndy Whitcroftbuild_types(); 3516c72ffaaSAndy Whitcroft 3527d2367afSJoe Perches 3537d2367afSJoe Perchesour $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; 354d1fe9c09SJoe Perches 355d1fe9c09SJoe Perches# Using $balanced_parens, $LvalOrFunc, or $FuncArg 356d1fe9c09SJoe Perches# requires at least perl version v5.10.0 357d1fe9c09SJoe Perches# Any use must be runtime checked with $^V 358d1fe9c09SJoe Perches 359d1fe9c09SJoe Perchesour $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/; 360d1fe9c09SJoe Perchesour $LvalOrFunc = qr{($Lval)\s*($balanced_parens{0,1})\s*}; 361d7c76ba7SJoe Perchesour $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant)}; 3627d2367afSJoe Perches 3637d2367afSJoe Perchessub deparenthesize { 3647d2367afSJoe Perches my ($string) = @_; 3657d2367afSJoe Perches return "" if (!defined($string)); 3667d2367afSJoe Perches $string =~ s@^\s*\(\s*@@g; 3677d2367afSJoe Perches $string =~ s@\s*\)\s*$@@g; 3687d2367afSJoe Perches $string =~ s@\s+@ @g; 3697d2367afSJoe Perches return $string; 3707d2367afSJoe Perches} 3717d2367afSJoe Perches 3726c72ffaaSAndy Whitcroft$chk_signoff = 0 if ($file); 3730a920b5bSAndy Whitcroft 37400df344fSAndy Whitcroftmy @rawlines = (); 375c2fdda0dSAndy Whitcroftmy @lines = (); 376*3705ce5bSJoe Perchesmy @fixed = (); 377c2fdda0dSAndy Whitcroftmy $vname; 3786c72ffaaSAndy Whitcroftfor my $filename (@ARGV) { 37921caa13cSAndy Whitcroft my $FILE; 3806c72ffaaSAndy Whitcroft if ($file) { 38121caa13cSAndy Whitcroft open($FILE, '-|', "diff -u /dev/null $filename") || 3826c72ffaaSAndy Whitcroft die "$P: $filename: diff failed - $!\n"; 38321caa13cSAndy Whitcroft } elsif ($filename eq '-') { 38421caa13cSAndy Whitcroft open($FILE, '<&STDIN'); 3856c72ffaaSAndy Whitcroft } else { 38621caa13cSAndy Whitcroft open($FILE, '<', "$filename") || 3876c72ffaaSAndy Whitcroft die "$P: $filename: open failed - $!\n"; 3886c72ffaaSAndy Whitcroft } 389c2fdda0dSAndy Whitcroft if ($filename eq '-') { 390c2fdda0dSAndy Whitcroft $vname = 'Your patch'; 391c2fdda0dSAndy Whitcroft } else { 392c2fdda0dSAndy Whitcroft $vname = $filename; 393c2fdda0dSAndy Whitcroft } 39421caa13cSAndy Whitcroft while (<$FILE>) { 3950a920b5bSAndy Whitcroft chomp; 39600df344fSAndy Whitcroft push(@rawlines, $_); 3976c72ffaaSAndy Whitcroft } 39821caa13cSAndy Whitcroft close($FILE); 399c2fdda0dSAndy Whitcroft if (!process($filename)) { 4000a920b5bSAndy Whitcroft $exit = 1; 4010a920b5bSAndy Whitcroft } 40200df344fSAndy Whitcroft @rawlines = (); 40313214adfSAndy Whitcroft @lines = (); 404*3705ce5bSJoe Perches @fixed = (); 4050a920b5bSAndy Whitcroft} 4060a920b5bSAndy Whitcroft 4070a920b5bSAndy Whitcroftexit($exit); 4080a920b5bSAndy Whitcroft 4090a920b5bSAndy Whitcroftsub top_of_kernel_tree { 4106c72ffaaSAndy Whitcroft my ($root) = @_; 4116c72ffaaSAndy Whitcroft 4126c72ffaaSAndy Whitcroft my @tree_check = ( 4136c72ffaaSAndy Whitcroft "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", 4146c72ffaaSAndy Whitcroft "README", "Documentation", "arch", "include", "drivers", 4156c72ffaaSAndy Whitcroft "fs", "init", "ipc", "kernel", "lib", "scripts", 4166c72ffaaSAndy Whitcroft ); 4176c72ffaaSAndy Whitcroft 4186c72ffaaSAndy Whitcroft foreach my $check (@tree_check) { 4196c72ffaaSAndy Whitcroft if (! -e $root . '/' . $check) { 4200a920b5bSAndy Whitcroft return 0; 4210a920b5bSAndy Whitcroft } 4226c72ffaaSAndy Whitcroft } 4236c72ffaaSAndy Whitcroft return 1; 4246c72ffaaSAndy Whitcroft} 4250a920b5bSAndy Whitcroft 42620112475SJoe Perchessub parse_email { 42720112475SJoe Perches my ($formatted_email) = @_; 42820112475SJoe Perches 42920112475SJoe Perches my $name = ""; 43020112475SJoe Perches my $address = ""; 43120112475SJoe Perches my $comment = ""; 43220112475SJoe Perches 43320112475SJoe Perches if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { 43420112475SJoe Perches $name = $1; 43520112475SJoe Perches $address = $2; 43620112475SJoe Perches $comment = $3 if defined $3; 43720112475SJoe Perches } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { 43820112475SJoe Perches $address = $1; 43920112475SJoe Perches $comment = $2 if defined $2; 44020112475SJoe Perches } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { 44120112475SJoe Perches $address = $1; 44220112475SJoe Perches $comment = $2 if defined $2; 44320112475SJoe Perches $formatted_email =~ s/$address.*$//; 44420112475SJoe Perches $name = $formatted_email; 445*3705ce5bSJoe Perches $name = trim($name); 44620112475SJoe Perches $name =~ s/^\"|\"$//g; 44720112475SJoe Perches # If there's a name left after stripping spaces and 44820112475SJoe Perches # leading quotes, and the address doesn't have both 44920112475SJoe Perches # leading and trailing angle brackets, the address 45020112475SJoe Perches # is invalid. ie: 45120112475SJoe Perches # "joe smith [email protected]" bad 45220112475SJoe Perches # "joe smith <[email protected]" bad 45320112475SJoe Perches if ($name ne "" && $address !~ /^<[^>]+>$/) { 45420112475SJoe Perches $name = ""; 45520112475SJoe Perches $address = ""; 45620112475SJoe Perches $comment = ""; 45720112475SJoe Perches } 45820112475SJoe Perches } 45920112475SJoe Perches 460*3705ce5bSJoe Perches $name = trim($name); 46120112475SJoe Perches $name =~ s/^\"|\"$//g; 462*3705ce5bSJoe Perches $address = trim($address); 46320112475SJoe Perches $address =~ s/^\<|\>$//g; 46420112475SJoe Perches 46520112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 46620112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 46720112475SJoe Perches $name = "\"$name\""; 46820112475SJoe Perches } 46920112475SJoe Perches 47020112475SJoe Perches return ($name, $address, $comment); 47120112475SJoe Perches} 47220112475SJoe Perches 47320112475SJoe Perchessub format_email { 47420112475SJoe Perches my ($name, $address) = @_; 47520112475SJoe Perches 47620112475SJoe Perches my $formatted_email; 47720112475SJoe Perches 478*3705ce5bSJoe Perches $name = trim($name); 47920112475SJoe Perches $name =~ s/^\"|\"$//g; 480*3705ce5bSJoe Perches $address = trim($address); 48120112475SJoe Perches 48220112475SJoe Perches if ($name =~ /[^\w \-]/i) { ##has "must quote" chars 48320112475SJoe Perches $name =~ s/(?<!\\)"/\\"/g; ##escape quotes 48420112475SJoe Perches $name = "\"$name\""; 48520112475SJoe Perches } 48620112475SJoe Perches 48720112475SJoe Perches if ("$name" eq "") { 48820112475SJoe Perches $formatted_email = "$address"; 48920112475SJoe Perches } else { 49020112475SJoe Perches $formatted_email = "$name <$address>"; 49120112475SJoe Perches } 49220112475SJoe Perches 49320112475SJoe Perches return $formatted_email; 49420112475SJoe Perches} 49520112475SJoe Perches 496000d1cc1SJoe Perchessub which_conf { 497000d1cc1SJoe Perches my ($conf) = @_; 498000d1cc1SJoe Perches 499000d1cc1SJoe Perches foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { 500000d1cc1SJoe Perches if (-e "$path/$conf") { 501000d1cc1SJoe Perches return "$path/$conf"; 502000d1cc1SJoe Perches } 503000d1cc1SJoe Perches } 504000d1cc1SJoe Perches 505000d1cc1SJoe Perches return ""; 506000d1cc1SJoe Perches} 507000d1cc1SJoe Perches 5080a920b5bSAndy Whitcroftsub expand_tabs { 5090a920b5bSAndy Whitcroft my ($str) = @_; 5100a920b5bSAndy Whitcroft 5110a920b5bSAndy Whitcroft my $res = ''; 5120a920b5bSAndy Whitcroft my $n = 0; 5130a920b5bSAndy Whitcroft for my $c (split(//, $str)) { 5140a920b5bSAndy Whitcroft if ($c eq "\t") { 5150a920b5bSAndy Whitcroft $res .= ' '; 5160a920b5bSAndy Whitcroft $n++; 5170a920b5bSAndy Whitcroft for (; ($n % 8) != 0; $n++) { 5180a920b5bSAndy Whitcroft $res .= ' '; 5190a920b5bSAndy Whitcroft } 5200a920b5bSAndy Whitcroft next; 5210a920b5bSAndy Whitcroft } 5220a920b5bSAndy Whitcroft $res .= $c; 5230a920b5bSAndy Whitcroft $n++; 5240a920b5bSAndy Whitcroft } 5250a920b5bSAndy Whitcroft 5260a920b5bSAndy Whitcroft return $res; 5270a920b5bSAndy Whitcroft} 5286c72ffaaSAndy Whitcroftsub copy_spacing { 529773647a0SAndy Whitcroft (my $res = shift) =~ tr/\t/ /c; 5306c72ffaaSAndy Whitcroft return $res; 5316c72ffaaSAndy Whitcroft} 5320a920b5bSAndy Whitcroft 5334a0df2efSAndy Whitcroftsub line_stats { 5344a0df2efSAndy Whitcroft my ($line) = @_; 5354a0df2efSAndy Whitcroft 5364a0df2efSAndy Whitcroft # Drop the diff line leader and expand tabs 5374a0df2efSAndy Whitcroft $line =~ s/^.//; 5384a0df2efSAndy Whitcroft $line = expand_tabs($line); 5394a0df2efSAndy Whitcroft 5404a0df2efSAndy Whitcroft # Pick the indent from the front of the line. 5414a0df2efSAndy Whitcroft my ($white) = ($line =~ /^(\s*)/); 5424a0df2efSAndy Whitcroft 5434a0df2efSAndy Whitcroft return (length($line), length($white)); 5444a0df2efSAndy Whitcroft} 5454a0df2efSAndy Whitcroft 546773647a0SAndy Whitcroftmy $sanitise_quote = ''; 547773647a0SAndy Whitcroft 548773647a0SAndy Whitcroftsub sanitise_line_reset { 549773647a0SAndy Whitcroft my ($in_comment) = @_; 550773647a0SAndy Whitcroft 551773647a0SAndy Whitcroft if ($in_comment) { 552773647a0SAndy Whitcroft $sanitise_quote = '*/'; 553773647a0SAndy Whitcroft } else { 554773647a0SAndy Whitcroft $sanitise_quote = ''; 555773647a0SAndy Whitcroft } 556773647a0SAndy Whitcroft} 55700df344fSAndy Whitcroftsub sanitise_line { 55800df344fSAndy Whitcroft my ($line) = @_; 55900df344fSAndy Whitcroft 56000df344fSAndy Whitcroft my $res = ''; 56100df344fSAndy Whitcroft my $l = ''; 56200df344fSAndy Whitcroft 563c2fdda0dSAndy Whitcroft my $qlen = 0; 564773647a0SAndy Whitcroft my $off = 0; 565773647a0SAndy Whitcroft my $c; 56600df344fSAndy Whitcroft 567773647a0SAndy Whitcroft # Always copy over the diff marker. 568773647a0SAndy Whitcroft $res = substr($line, 0, 1); 569773647a0SAndy Whitcroft 570773647a0SAndy Whitcroft for ($off = 1; $off < length($line); $off++) { 571773647a0SAndy Whitcroft $c = substr($line, $off, 1); 572773647a0SAndy Whitcroft 573773647a0SAndy Whitcroft # Comments we are wacking completly including the begin 574773647a0SAndy Whitcroft # and end, all to $;. 575773647a0SAndy Whitcroft if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') { 576773647a0SAndy Whitcroft $sanitise_quote = '*/'; 577773647a0SAndy Whitcroft 578773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 579773647a0SAndy Whitcroft $off++; 58000df344fSAndy Whitcroft next; 581773647a0SAndy Whitcroft } 58281bc0e02SAndy Whitcroft if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') { 583773647a0SAndy Whitcroft $sanitise_quote = ''; 584773647a0SAndy Whitcroft substr($res, $off, 2, "$;$;"); 585773647a0SAndy Whitcroft $off++; 586773647a0SAndy Whitcroft next; 587773647a0SAndy Whitcroft } 588113f04a8SDaniel Walker if ($sanitise_quote eq '' && substr($line, $off, 2) eq '//') { 589113f04a8SDaniel Walker $sanitise_quote = '//'; 590113f04a8SDaniel Walker 591113f04a8SDaniel Walker substr($res, $off, 2, $sanitise_quote); 592113f04a8SDaniel Walker $off++; 593113f04a8SDaniel Walker next; 594113f04a8SDaniel Walker } 595773647a0SAndy Whitcroft 596773647a0SAndy Whitcroft # A \ in a string means ignore the next character. 597773647a0SAndy Whitcroft if (($sanitise_quote eq "'" || $sanitise_quote eq '"') && 598773647a0SAndy Whitcroft $c eq "\\") { 599773647a0SAndy Whitcroft substr($res, $off, 2, 'XX'); 600773647a0SAndy Whitcroft $off++; 601773647a0SAndy Whitcroft next; 602773647a0SAndy Whitcroft } 603773647a0SAndy Whitcroft # Regular quotes. 604773647a0SAndy Whitcroft if ($c eq "'" || $c eq '"') { 605773647a0SAndy Whitcroft if ($sanitise_quote eq '') { 606773647a0SAndy Whitcroft $sanitise_quote = $c; 607773647a0SAndy Whitcroft 608773647a0SAndy Whitcroft substr($res, $off, 1, $c); 609773647a0SAndy Whitcroft next; 610773647a0SAndy Whitcroft } elsif ($sanitise_quote eq $c) { 611773647a0SAndy Whitcroft $sanitise_quote = ''; 61200df344fSAndy Whitcroft } 61300df344fSAndy Whitcroft } 614773647a0SAndy Whitcroft 615fae17daeSAndy Whitcroft #print "c<$c> SQ<$sanitise_quote>\n"; 616773647a0SAndy Whitcroft if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") { 617773647a0SAndy Whitcroft substr($res, $off, 1, $;); 618113f04a8SDaniel Walker } elsif ($off != 0 && $sanitise_quote eq '//' && $c ne "\t") { 619113f04a8SDaniel Walker substr($res, $off, 1, $;); 620773647a0SAndy Whitcroft } elsif ($off != 0 && $sanitise_quote && $c ne "\t") { 621773647a0SAndy Whitcroft substr($res, $off, 1, 'X'); 62200df344fSAndy Whitcroft } else { 623773647a0SAndy Whitcroft substr($res, $off, 1, $c); 62400df344fSAndy Whitcroft } 625c2fdda0dSAndy Whitcroft } 626c2fdda0dSAndy Whitcroft 627113f04a8SDaniel Walker if ($sanitise_quote eq '//') { 628113f04a8SDaniel Walker $sanitise_quote = ''; 629113f04a8SDaniel Walker } 630113f04a8SDaniel Walker 631c2fdda0dSAndy Whitcroft # The pathname on a #include may be surrounded by '<' and '>'. 632c45dcabdSAndy Whitcroft if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { 633c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 634c2fdda0dSAndy Whitcroft $res =~ s@\<.*\>@<$clean>@; 635c2fdda0dSAndy Whitcroft 636c2fdda0dSAndy Whitcroft # The whole of a #error is a string. 637c45dcabdSAndy Whitcroft } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { 638c2fdda0dSAndy Whitcroft my $clean = 'X' x length($1); 639c45dcabdSAndy Whitcroft $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; 640c2fdda0dSAndy Whitcroft } 641c2fdda0dSAndy Whitcroft 64200df344fSAndy Whitcroft return $res; 64300df344fSAndy Whitcroft} 64400df344fSAndy Whitcroft 645a6962d72SJoe Perchessub get_quoted_string { 646a6962d72SJoe Perches my ($line, $rawline) = @_; 647a6962d72SJoe Perches 648a6962d72SJoe Perches return "" if ($line !~ m/(\"[X]+\")/g); 649a6962d72SJoe Perches return substr($rawline, $-[0], $+[0] - $-[0]); 650a6962d72SJoe Perches} 651a6962d72SJoe Perches 6528905a67cSAndy Whitcroftsub ctx_statement_block { 6538905a67cSAndy Whitcroft my ($linenr, $remain, $off) = @_; 6548905a67cSAndy Whitcroft my $line = $linenr - 1; 6558905a67cSAndy Whitcroft my $blk = ''; 6568905a67cSAndy Whitcroft my $soff = $off; 6578905a67cSAndy Whitcroft my $coff = $off - 1; 658773647a0SAndy Whitcroft my $coff_set = 0; 6598905a67cSAndy Whitcroft 66013214adfSAndy Whitcroft my $loff = 0; 66113214adfSAndy Whitcroft 6628905a67cSAndy Whitcroft my $type = ''; 6638905a67cSAndy Whitcroft my $level = 0; 664a2750645SAndy Whitcroft my @stack = (); 665cf655043SAndy Whitcroft my $p; 6668905a67cSAndy Whitcroft my $c; 6678905a67cSAndy Whitcroft my $len = 0; 66813214adfSAndy Whitcroft 66913214adfSAndy Whitcroft my $remainder; 6708905a67cSAndy Whitcroft while (1) { 671a2750645SAndy Whitcroft @stack = (['', 0]) if ($#stack == -1); 672a2750645SAndy Whitcroft 673773647a0SAndy Whitcroft #warn "CSB: blk<$blk> remain<$remain>\n"; 6748905a67cSAndy Whitcroft # If we are about to drop off the end, pull in more 6758905a67cSAndy Whitcroft # context. 6768905a67cSAndy Whitcroft if ($off >= $len) { 6778905a67cSAndy Whitcroft for (; $remain > 0; $line++) { 678dea33496SAndy Whitcroft last if (!defined $lines[$line]); 679c2fdda0dSAndy Whitcroft next if ($lines[$line] =~ /^-/); 6808905a67cSAndy Whitcroft $remain--; 68113214adfSAndy Whitcroft $loff = $len; 682c2fdda0dSAndy Whitcroft $blk .= $lines[$line] . "\n"; 6838905a67cSAndy Whitcroft $len = length($blk); 6848905a67cSAndy Whitcroft $line++; 6858905a67cSAndy Whitcroft last; 6868905a67cSAndy Whitcroft } 6878905a67cSAndy Whitcroft # Bail if there is no further context. 6888905a67cSAndy Whitcroft #warn "CSB: blk<$blk> off<$off> len<$len>\n"; 68913214adfSAndy Whitcroft if ($off >= $len) { 6908905a67cSAndy Whitcroft last; 6918905a67cSAndy Whitcroft } 692f74bd194SAndy Whitcroft if ($level == 0 && substr($blk, $off) =~ /^.\s*#\s*define/) { 693f74bd194SAndy Whitcroft $level++; 694f74bd194SAndy Whitcroft $type = '#'; 695f74bd194SAndy Whitcroft } 6968905a67cSAndy Whitcroft } 697cf655043SAndy Whitcroft $p = $c; 6988905a67cSAndy Whitcroft $c = substr($blk, $off, 1); 69913214adfSAndy Whitcroft $remainder = substr($blk, $off); 7008905a67cSAndy Whitcroft 701773647a0SAndy Whitcroft #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n"; 7024635f4fbSAndy Whitcroft 7034635f4fbSAndy Whitcroft # Handle nested #if/#else. 7044635f4fbSAndy Whitcroft if ($remainder =~ /^#\s*(?:ifndef|ifdef|if)\s/) { 7054635f4fbSAndy Whitcroft push(@stack, [ $type, $level ]); 7064635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*(?:else|elif)\b/) { 7074635f4fbSAndy Whitcroft ($type, $level) = @{$stack[$#stack - 1]}; 7084635f4fbSAndy Whitcroft } elsif ($remainder =~ /^#\s*endif\b/) { 7094635f4fbSAndy Whitcroft ($type, $level) = @{pop(@stack)}; 7104635f4fbSAndy Whitcroft } 7114635f4fbSAndy Whitcroft 7128905a67cSAndy Whitcroft # Statement ends at the ';' or a close '}' at the 7138905a67cSAndy Whitcroft # outermost level. 7148905a67cSAndy Whitcroft if ($level == 0 && $c eq ';') { 7158905a67cSAndy Whitcroft last; 7168905a67cSAndy Whitcroft } 7178905a67cSAndy Whitcroft 71813214adfSAndy Whitcroft # An else is really a conditional as long as its not else if 719773647a0SAndy Whitcroft if ($level == 0 && $coff_set == 0 && 720773647a0SAndy Whitcroft (!defined($p) || $p =~ /(?:\s|\}|\+)/) && 721773647a0SAndy Whitcroft $remainder =~ /^(else)(?:\s|{)/ && 722773647a0SAndy Whitcroft $remainder !~ /^else\s+if\b/) { 723773647a0SAndy Whitcroft $coff = $off + length($1) - 1; 724773647a0SAndy Whitcroft $coff_set = 1; 725773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n"; 726773647a0SAndy Whitcroft #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n"; 72713214adfSAndy Whitcroft } 72813214adfSAndy Whitcroft 7298905a67cSAndy Whitcroft if (($type eq '' || $type eq '(') && $c eq '(') { 7308905a67cSAndy Whitcroft $level++; 7318905a67cSAndy Whitcroft $type = '('; 7328905a67cSAndy Whitcroft } 7338905a67cSAndy Whitcroft if ($type eq '(' && $c eq ')') { 7348905a67cSAndy Whitcroft $level--; 7358905a67cSAndy Whitcroft $type = ($level != 0)? '(' : ''; 7368905a67cSAndy Whitcroft 7378905a67cSAndy Whitcroft if ($level == 0 && $coff < $soff) { 7388905a67cSAndy Whitcroft $coff = $off; 739773647a0SAndy Whitcroft $coff_set = 1; 740773647a0SAndy Whitcroft #warn "CSB: mark coff<$coff>\n"; 7418905a67cSAndy Whitcroft } 7428905a67cSAndy Whitcroft } 7438905a67cSAndy Whitcroft if (($type eq '' || $type eq '{') && $c eq '{') { 7448905a67cSAndy Whitcroft $level++; 7458905a67cSAndy Whitcroft $type = '{'; 7468905a67cSAndy Whitcroft } 7478905a67cSAndy Whitcroft if ($type eq '{' && $c eq '}') { 7488905a67cSAndy Whitcroft $level--; 7498905a67cSAndy Whitcroft $type = ($level != 0)? '{' : ''; 7508905a67cSAndy Whitcroft 7518905a67cSAndy Whitcroft if ($level == 0) { 752b998e001SPatrick Pannuto if (substr($blk, $off + 1, 1) eq ';') { 753b998e001SPatrick Pannuto $off++; 754b998e001SPatrick Pannuto } 7558905a67cSAndy Whitcroft last; 7568905a67cSAndy Whitcroft } 7578905a67cSAndy Whitcroft } 758f74bd194SAndy Whitcroft # Preprocessor commands end at the newline unless escaped. 759f74bd194SAndy Whitcroft if ($type eq '#' && $c eq "\n" && $p ne "\\") { 760f74bd194SAndy Whitcroft $level--; 761f74bd194SAndy Whitcroft $type = ''; 762f74bd194SAndy Whitcroft $off++; 763f74bd194SAndy Whitcroft last; 764f74bd194SAndy Whitcroft } 7658905a67cSAndy Whitcroft $off++; 7668905a67cSAndy Whitcroft } 767a3bb97a7SAndy Whitcroft # We are truly at the end, so shuffle to the next line. 76813214adfSAndy Whitcroft if ($off == $len) { 769a3bb97a7SAndy Whitcroft $loff = $len + 1; 77013214adfSAndy Whitcroft $line++; 77113214adfSAndy Whitcroft $remain--; 77213214adfSAndy Whitcroft } 7738905a67cSAndy Whitcroft 7748905a67cSAndy Whitcroft my $statement = substr($blk, $soff, $off - $soff + 1); 7758905a67cSAndy Whitcroft my $condition = substr($blk, $soff, $coff - $soff + 1); 7768905a67cSAndy Whitcroft 7778905a67cSAndy Whitcroft #warn "STATEMENT<$statement>\n"; 7788905a67cSAndy Whitcroft #warn "CONDITION<$condition>\n"; 7798905a67cSAndy Whitcroft 780773647a0SAndy Whitcroft #print "coff<$coff> soff<$off> loff<$loff>\n"; 78113214adfSAndy Whitcroft 78213214adfSAndy Whitcroft return ($statement, $condition, 78313214adfSAndy Whitcroft $line, $remain + 1, $off - $loff + 1, $level); 78413214adfSAndy Whitcroft} 78513214adfSAndy Whitcroft 786cf655043SAndy Whitcroftsub statement_lines { 787cf655043SAndy Whitcroft my ($stmt) = @_; 788cf655043SAndy Whitcroft 789cf655043SAndy Whitcroft # Strip the diff line prefixes and rip blank lines at start and end. 790cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 791cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 792cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 793cf655043SAndy Whitcroft 794cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 795cf655043SAndy Whitcroft 796cf655043SAndy Whitcroft return $#stmt_lines + 2; 797cf655043SAndy Whitcroft} 798cf655043SAndy Whitcroft 799cf655043SAndy Whitcroftsub statement_rawlines { 800cf655043SAndy Whitcroft my ($stmt) = @_; 801cf655043SAndy Whitcroft 802cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 803cf655043SAndy Whitcroft 804cf655043SAndy Whitcroft return $#stmt_lines + 2; 805cf655043SAndy Whitcroft} 806cf655043SAndy Whitcroft 807cf655043SAndy Whitcroftsub statement_block_size { 808cf655043SAndy Whitcroft my ($stmt) = @_; 809cf655043SAndy Whitcroft 810cf655043SAndy Whitcroft $stmt =~ s/(^|\n)./$1/g; 811cf655043SAndy Whitcroft $stmt =~ s/^\s*{//; 812cf655043SAndy Whitcroft $stmt =~ s/}\s*$//; 813cf655043SAndy Whitcroft $stmt =~ s/^\s*//; 814cf655043SAndy Whitcroft $stmt =~ s/\s*$//; 815cf655043SAndy Whitcroft 816cf655043SAndy Whitcroft my @stmt_lines = ($stmt =~ /\n/g); 817cf655043SAndy Whitcroft my @stmt_statements = ($stmt =~ /;/g); 818cf655043SAndy Whitcroft 819cf655043SAndy Whitcroft my $stmt_lines = $#stmt_lines + 2; 820cf655043SAndy Whitcroft my $stmt_statements = $#stmt_statements + 1; 821cf655043SAndy Whitcroft 822cf655043SAndy Whitcroft if ($stmt_lines > $stmt_statements) { 823cf655043SAndy Whitcroft return $stmt_lines; 824cf655043SAndy Whitcroft } else { 825cf655043SAndy Whitcroft return $stmt_statements; 826cf655043SAndy Whitcroft } 827cf655043SAndy Whitcroft} 828cf655043SAndy Whitcroft 82913214adfSAndy Whitcroftsub ctx_statement_full { 83013214adfSAndy Whitcroft my ($linenr, $remain, $off) = @_; 83113214adfSAndy Whitcroft my ($statement, $condition, $level); 83213214adfSAndy Whitcroft 83313214adfSAndy Whitcroft my (@chunks); 83413214adfSAndy Whitcroft 835cf655043SAndy Whitcroft # Grab the first conditional/block pair. 83613214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 83713214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 838773647a0SAndy Whitcroft #print "F: c<$condition> s<$statement> remain<$remain>\n"; 83913214adfSAndy Whitcroft push(@chunks, [ $condition, $statement ]); 840cf655043SAndy Whitcroft if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) { 841cf655043SAndy Whitcroft return ($level, $linenr, @chunks); 842cf655043SAndy Whitcroft } 843cf655043SAndy Whitcroft 844cf655043SAndy Whitcroft # Pull in the following conditional/block pairs and see if they 845cf655043SAndy Whitcroft # could continue the statement. 846cf655043SAndy Whitcroft for (;;) { 84713214adfSAndy Whitcroft ($statement, $condition, $linenr, $remain, $off, $level) = 84813214adfSAndy Whitcroft ctx_statement_block($linenr, $remain, $off); 849cf655043SAndy Whitcroft #print "C: c<$condition> s<$statement> remain<$remain>\n"; 850773647a0SAndy Whitcroft last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s)); 851cf655043SAndy Whitcroft #print "C: push\n"; 852cf655043SAndy Whitcroft push(@chunks, [ $condition, $statement ]); 85313214adfSAndy Whitcroft } 85413214adfSAndy Whitcroft 85513214adfSAndy Whitcroft return ($level, $linenr, @chunks); 8568905a67cSAndy Whitcroft} 8578905a67cSAndy Whitcroft 8584a0df2efSAndy Whitcroftsub ctx_block_get { 859f0a594c1SAndy Whitcroft my ($linenr, $remain, $outer, $open, $close, $off) = @_; 8604a0df2efSAndy Whitcroft my $line; 8614a0df2efSAndy Whitcroft my $start = $linenr - 1; 8624a0df2efSAndy Whitcroft my $blk = ''; 8634a0df2efSAndy Whitcroft my @o; 8644a0df2efSAndy Whitcroft my @c; 8654a0df2efSAndy Whitcroft my @res = (); 8664a0df2efSAndy Whitcroft 867f0a594c1SAndy Whitcroft my $level = 0; 8684635f4fbSAndy Whitcroft my @stack = ($level); 86900df344fSAndy Whitcroft for ($line = $start; $remain > 0; $line++) { 87000df344fSAndy Whitcroft next if ($rawlines[$line] =~ /^-/); 87100df344fSAndy Whitcroft $remain--; 87200df344fSAndy Whitcroft 87300df344fSAndy Whitcroft $blk .= $rawlines[$line]; 8744635f4fbSAndy Whitcroft 8754635f4fbSAndy Whitcroft # Handle nested #if/#else. 87601464f30SAndy Whitcroft if ($lines[$line] =~ /^.\s*#\s*(?:ifndef|ifdef|if)\s/) { 8774635f4fbSAndy Whitcroft push(@stack, $level); 87801464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*(?:else|elif)\b/) { 8794635f4fbSAndy Whitcroft $level = $stack[$#stack - 1]; 88001464f30SAndy Whitcroft } elsif ($lines[$line] =~ /^.\s*#\s*endif\b/) { 8814635f4fbSAndy Whitcroft $level = pop(@stack); 8824635f4fbSAndy Whitcroft } 8834635f4fbSAndy Whitcroft 88401464f30SAndy Whitcroft foreach my $c (split(//, $lines[$line])) { 885f0a594c1SAndy Whitcroft ##print "C<$c>L<$level><$open$close>O<$off>\n"; 886f0a594c1SAndy Whitcroft if ($off > 0) { 887f0a594c1SAndy Whitcroft $off--; 888f0a594c1SAndy Whitcroft next; 889f0a594c1SAndy Whitcroft } 8904a0df2efSAndy Whitcroft 891f0a594c1SAndy Whitcroft if ($c eq $close && $level > 0) { 892f0a594c1SAndy Whitcroft $level--; 893f0a594c1SAndy Whitcroft last if ($level == 0); 894f0a594c1SAndy Whitcroft } elsif ($c eq $open) { 895f0a594c1SAndy Whitcroft $level++; 896f0a594c1SAndy Whitcroft } 897f0a594c1SAndy Whitcroft } 8984a0df2efSAndy Whitcroft 899f0a594c1SAndy Whitcroft if (!$outer || $level <= 1) { 90000df344fSAndy Whitcroft push(@res, $rawlines[$line]); 9014a0df2efSAndy Whitcroft } 9024a0df2efSAndy Whitcroft 903f0a594c1SAndy Whitcroft last if ($level == 0); 9044a0df2efSAndy Whitcroft } 9054a0df2efSAndy Whitcroft 906f0a594c1SAndy Whitcroft return ($level, @res); 9074a0df2efSAndy Whitcroft} 9084a0df2efSAndy Whitcroftsub ctx_block_outer { 9094a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 9104a0df2efSAndy Whitcroft 911f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 1, '{', '}', 0); 912f0a594c1SAndy Whitcroft return @r; 9134a0df2efSAndy Whitcroft} 9144a0df2efSAndy Whitcroftsub ctx_block { 9154a0df2efSAndy Whitcroft my ($linenr, $remain) = @_; 9164a0df2efSAndy Whitcroft 917f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '{', '}', 0); 918f0a594c1SAndy Whitcroft return @r; 919653d4876SAndy Whitcroft} 920653d4876SAndy Whitcroftsub ctx_statement { 921f0a594c1SAndy Whitcroft my ($linenr, $remain, $off) = @_; 922f0a594c1SAndy Whitcroft 923f0a594c1SAndy Whitcroft my ($level, @r) = ctx_block_get($linenr, $remain, 0, '(', ')', $off); 924f0a594c1SAndy Whitcroft return @r; 925f0a594c1SAndy Whitcroft} 926f0a594c1SAndy Whitcroftsub ctx_block_level { 927653d4876SAndy Whitcroft my ($linenr, $remain) = @_; 928653d4876SAndy Whitcroft 929f0a594c1SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '{', '}', 0); 9304a0df2efSAndy Whitcroft} 9319c0ca6f9SAndy Whitcroftsub ctx_statement_level { 9329c0ca6f9SAndy Whitcroft my ($linenr, $remain, $off) = @_; 9339c0ca6f9SAndy Whitcroft 9349c0ca6f9SAndy Whitcroft return ctx_block_get($linenr, $remain, 0, '(', ')', $off); 9359c0ca6f9SAndy Whitcroft} 9364a0df2efSAndy Whitcroft 9374a0df2efSAndy Whitcroftsub ctx_locate_comment { 9384a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 9394a0df2efSAndy Whitcroft 9404a0df2efSAndy Whitcroft # Catch a comment on the end of the line itself. 941beae6332SAndy Whitcroft my ($current_comment) = ($rawlines[$end_line - 1] =~ m@.*(/\*.*\*/)\s*(?:\\\s*)?$@); 9424a0df2efSAndy Whitcroft return $current_comment if (defined $current_comment); 9434a0df2efSAndy Whitcroft 9444a0df2efSAndy Whitcroft # Look through the context and try and figure out if there is a 9454a0df2efSAndy Whitcroft # comment. 9464a0df2efSAndy Whitcroft my $in_comment = 0; 9474a0df2efSAndy Whitcroft $current_comment = ''; 9484a0df2efSAndy Whitcroft for (my $linenr = $first_line; $linenr < $end_line; $linenr++) { 94900df344fSAndy Whitcroft my $line = $rawlines[$linenr - 1]; 95000df344fSAndy Whitcroft #warn " $line\n"; 9514a0df2efSAndy Whitcroft if ($linenr == $first_line and $line =~ m@^.\s*\*@) { 9524a0df2efSAndy Whitcroft $in_comment = 1; 9534a0df2efSAndy Whitcroft } 9544a0df2efSAndy Whitcroft if ($line =~ m@/\*@) { 9554a0df2efSAndy Whitcroft $in_comment = 1; 9564a0df2efSAndy Whitcroft } 9574a0df2efSAndy Whitcroft if (!$in_comment && $current_comment ne '') { 9584a0df2efSAndy Whitcroft $current_comment = ''; 9594a0df2efSAndy Whitcroft } 9604a0df2efSAndy Whitcroft $current_comment .= $line . "\n" if ($in_comment); 9614a0df2efSAndy Whitcroft if ($line =~ m@\*/@) { 9624a0df2efSAndy Whitcroft $in_comment = 0; 9634a0df2efSAndy Whitcroft } 9644a0df2efSAndy Whitcroft } 9654a0df2efSAndy Whitcroft 9664a0df2efSAndy Whitcroft chomp($current_comment); 9674a0df2efSAndy Whitcroft return($current_comment); 9684a0df2efSAndy Whitcroft} 9694a0df2efSAndy Whitcroftsub ctx_has_comment { 9704a0df2efSAndy Whitcroft my ($first_line, $end_line) = @_; 9714a0df2efSAndy Whitcroft my $cmt = ctx_locate_comment($first_line, $end_line); 9724a0df2efSAndy Whitcroft 97300df344fSAndy Whitcroft ##print "LINE: $rawlines[$end_line - 1 ]\n"; 9744a0df2efSAndy Whitcroft ##print "CMMT: $cmt\n"; 9754a0df2efSAndy Whitcroft 9764a0df2efSAndy Whitcroft return ($cmt ne ''); 9774a0df2efSAndy Whitcroft} 9784a0df2efSAndy Whitcroft 9794d001e4dSAndy Whitcroftsub raw_line { 9804d001e4dSAndy Whitcroft my ($linenr, $cnt) = @_; 9814d001e4dSAndy Whitcroft 9824d001e4dSAndy Whitcroft my $offset = $linenr - 1; 9834d001e4dSAndy Whitcroft $cnt++; 9844d001e4dSAndy Whitcroft 9854d001e4dSAndy Whitcroft my $line; 9864d001e4dSAndy Whitcroft while ($cnt) { 9874d001e4dSAndy Whitcroft $line = $rawlines[$offset++]; 9884d001e4dSAndy Whitcroft next if (defined($line) && $line =~ /^-/); 9894d001e4dSAndy Whitcroft $cnt--; 9904d001e4dSAndy Whitcroft } 9914d001e4dSAndy Whitcroft 9924d001e4dSAndy Whitcroft return $line; 9934d001e4dSAndy Whitcroft} 9944d001e4dSAndy Whitcroft 9950a920b5bSAndy Whitcroftsub cat_vet { 9960a920b5bSAndy Whitcroft my ($vet) = @_; 9979c0ca6f9SAndy Whitcroft my ($res, $coded); 9980a920b5bSAndy Whitcroft 9999c0ca6f9SAndy Whitcroft $res = ''; 10006c72ffaaSAndy Whitcroft while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { 10016c72ffaaSAndy Whitcroft $res .= $1; 10026c72ffaaSAndy Whitcroft if ($2 ne '') { 10039c0ca6f9SAndy Whitcroft $coded = sprintf("^%c", unpack('C', $2) + 64); 10046c72ffaaSAndy Whitcroft $res .= $coded; 10056c72ffaaSAndy Whitcroft } 10069c0ca6f9SAndy Whitcroft } 10079c0ca6f9SAndy Whitcroft $res =~ s/$/\$/; 10080a920b5bSAndy Whitcroft 10099c0ca6f9SAndy Whitcroft return $res; 10100a920b5bSAndy Whitcroft} 10110a920b5bSAndy Whitcroft 1012c2fdda0dSAndy Whitcroftmy $av_preprocessor = 0; 1013cf655043SAndy Whitcroftmy $av_pending; 1014c2fdda0dSAndy Whitcroftmy @av_paren_type; 10151f65f947SAndy Whitcroftmy $av_pend_colon; 1016c2fdda0dSAndy Whitcroft 1017c2fdda0dSAndy Whitcroftsub annotate_reset { 1018c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 1019cf655043SAndy Whitcroft $av_pending = '_'; 1020cf655043SAndy Whitcroft @av_paren_type = ('E'); 10211f65f947SAndy Whitcroft $av_pend_colon = 'O'; 1022c2fdda0dSAndy Whitcroft} 1023c2fdda0dSAndy Whitcroft 10246c72ffaaSAndy Whitcroftsub annotate_values { 10256c72ffaaSAndy Whitcroft my ($stream, $type) = @_; 10266c72ffaaSAndy Whitcroft 10276c72ffaaSAndy Whitcroft my $res; 10281f65f947SAndy Whitcroft my $var = '_' x length($stream); 10296c72ffaaSAndy Whitcroft my $cur = $stream; 10306c72ffaaSAndy Whitcroft 1031c2fdda0dSAndy Whitcroft print "$stream\n" if ($dbg_values > 1); 10326c72ffaaSAndy Whitcroft 10336c72ffaaSAndy Whitcroft while (length($cur)) { 1034773647a0SAndy Whitcroft @av_paren_type = ('E') if ($#av_paren_type < 0); 1035cf655043SAndy Whitcroft print " <" . join('', @av_paren_type) . 1036171ae1a4SAndy Whitcroft "> <$type> <$av_pending>" if ($dbg_values > 1); 10376c72ffaaSAndy Whitcroft if ($cur =~ /^(\s+)/o) { 1038c2fdda0dSAndy Whitcroft print "WS($1)\n" if ($dbg_values > 1); 1039c2fdda0dSAndy Whitcroft if ($1 =~ /\n/ && $av_preprocessor) { 1040cf655043SAndy Whitcroft $type = pop(@av_paren_type); 1041c2fdda0dSAndy Whitcroft $av_preprocessor = 0; 10426c72ffaaSAndy Whitcroft } 10436c72ffaaSAndy Whitcroft 1044c023e473SFlorian Mickler } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') { 10459446ef56SAndy Whitcroft print "CAST($1)\n" if ($dbg_values > 1); 10469446ef56SAndy Whitcroft push(@av_paren_type, $type); 1047addcdceaSAndy Whitcroft $type = 'c'; 10489446ef56SAndy Whitcroft 1049e91b6e26SAndy Whitcroft } elsif ($cur =~ /^($Type)\s*(?:$Ident|,|\)|\(|\s*$)/) { 1050c2fdda0dSAndy Whitcroft print "DECLARE($1)\n" if ($dbg_values > 1); 10516c72ffaaSAndy Whitcroft $type = 'T'; 10526c72ffaaSAndy Whitcroft 1053389a2fe5SAndy Whitcroft } elsif ($cur =~ /^($Modifier)\s*/) { 1054389a2fe5SAndy Whitcroft print "MODIFIER($1)\n" if ($dbg_values > 1); 1055389a2fe5SAndy Whitcroft $type = 'T'; 1056389a2fe5SAndy Whitcroft 1057c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { 1058171ae1a4SAndy Whitcroft print "DEFINE($1,$2)\n" if ($dbg_values > 1); 1059c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 1060171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 1061171ae1a4SAndy Whitcroft if ($2 ne '') { 1062cf655043SAndy Whitcroft $av_pending = 'N'; 1063171ae1a4SAndy Whitcroft } 1064171ae1a4SAndy Whitcroft $type = 'E'; 1065171ae1a4SAndy Whitcroft 1066c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { 1067171ae1a4SAndy Whitcroft print "UNDEF($1)\n" if ($dbg_values > 1); 1068171ae1a4SAndy Whitcroft $av_preprocessor = 1; 1069171ae1a4SAndy Whitcroft push(@av_paren_type, $type); 10706c72ffaaSAndy Whitcroft 1071c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { 1072cf655043SAndy Whitcroft print "PRE_START($1)\n" if ($dbg_values > 1); 1073c2fdda0dSAndy Whitcroft $av_preprocessor = 1; 1074cf655043SAndy Whitcroft 1075cf655043SAndy Whitcroft push(@av_paren_type, $type); 1076cf655043SAndy Whitcroft push(@av_paren_type, $type); 1077171ae1a4SAndy Whitcroft $type = 'E'; 1078cf655043SAndy Whitcroft 1079c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { 1080cf655043SAndy Whitcroft print "PRE_RESTART($1)\n" if ($dbg_values > 1); 1081cf655043SAndy Whitcroft $av_preprocessor = 1; 1082cf655043SAndy Whitcroft 1083cf655043SAndy Whitcroft push(@av_paren_type, $av_paren_type[$#av_paren_type]); 1084cf655043SAndy Whitcroft 1085171ae1a4SAndy Whitcroft $type = 'E'; 1086cf655043SAndy Whitcroft 1087c45dcabdSAndy Whitcroft } elsif ($cur =~ /^(\#\s*(?:endif))/o) { 1088cf655043SAndy Whitcroft print "PRE_END($1)\n" if ($dbg_values > 1); 1089cf655043SAndy Whitcroft 1090cf655043SAndy Whitcroft $av_preprocessor = 1; 1091cf655043SAndy Whitcroft 1092cf655043SAndy Whitcroft # Assume all arms of the conditional end as this 1093cf655043SAndy Whitcroft # one does, and continue as if the #endif was not here. 1094cf655043SAndy Whitcroft pop(@av_paren_type); 1095cf655043SAndy Whitcroft push(@av_paren_type, $type); 1096171ae1a4SAndy Whitcroft $type = 'E'; 10976c72ffaaSAndy Whitcroft 10986c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\\\n)/o) { 1099c2fdda0dSAndy Whitcroft print "PRECONT($1)\n" if ($dbg_values > 1); 11006c72ffaaSAndy Whitcroft 1101171ae1a4SAndy Whitcroft } elsif ($cur =~ /^(__attribute__)\s*\(?/o) { 1102171ae1a4SAndy Whitcroft print "ATTR($1)\n" if ($dbg_values > 1); 1103171ae1a4SAndy Whitcroft $av_pending = $type; 1104171ae1a4SAndy Whitcroft $type = 'N'; 1105171ae1a4SAndy Whitcroft 11066c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { 1107c2fdda0dSAndy Whitcroft print "SIZEOF($1)\n" if ($dbg_values > 1); 11086c72ffaaSAndy Whitcroft if (defined $2) { 1109cf655043SAndy Whitcroft $av_pending = 'V'; 11106c72ffaaSAndy Whitcroft } 11116c72ffaaSAndy Whitcroft $type = 'N'; 11126c72ffaaSAndy Whitcroft 111314b111c1SAndy Whitcroft } elsif ($cur =~ /^(if|while|for)\b/o) { 1114c2fdda0dSAndy Whitcroft print "COND($1)\n" if ($dbg_values > 1); 111514b111c1SAndy Whitcroft $av_pending = 'E'; 11166c72ffaaSAndy Whitcroft $type = 'N'; 11176c72ffaaSAndy Whitcroft 11181f65f947SAndy Whitcroft } elsif ($cur =~/^(case)/o) { 11191f65f947SAndy Whitcroft print "CASE($1)\n" if ($dbg_values > 1); 11201f65f947SAndy Whitcroft $av_pend_colon = 'C'; 11211f65f947SAndy Whitcroft $type = 'N'; 11221f65f947SAndy Whitcroft 112314b111c1SAndy Whitcroft } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) { 1124c2fdda0dSAndy Whitcroft print "KEYWORD($1)\n" if ($dbg_values > 1); 11256c72ffaaSAndy Whitcroft $type = 'N'; 11266c72ffaaSAndy Whitcroft 11276c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\()/o) { 1128c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 1129cf655043SAndy Whitcroft push(@av_paren_type, $av_pending); 1130cf655043SAndy Whitcroft $av_pending = '_'; 11316c72ffaaSAndy Whitcroft $type = 'N'; 11326c72ffaaSAndy Whitcroft 11336c72ffaaSAndy Whitcroft } elsif ($cur =~ /^(\))/o) { 1134cf655043SAndy Whitcroft my $new_type = pop(@av_paren_type); 1135cf655043SAndy Whitcroft if ($new_type ne '_') { 1136cf655043SAndy Whitcroft $type = $new_type; 1137c2fdda0dSAndy Whitcroft print "PAREN('$1') -> $type\n" 1138c2fdda0dSAndy Whitcroft if ($dbg_values > 1); 11396c72ffaaSAndy Whitcroft } else { 1140c2fdda0dSAndy Whitcroft print "PAREN('$1')\n" if ($dbg_values > 1); 11416c72ffaaSAndy Whitcroft } 11426c72ffaaSAndy Whitcroft 1143c8cb2ca3SAndy Whitcroft } elsif ($cur =~ /^($Ident)\s*\(/o) { 1144c2fdda0dSAndy Whitcroft print "FUNC($1)\n" if ($dbg_values > 1); 1145c8cb2ca3SAndy Whitcroft $type = 'V'; 1146cf655043SAndy Whitcroft $av_pending = 'V'; 11476c72ffaaSAndy Whitcroft 11488e761b04SAndy Whitcroft } elsif ($cur =~ /^($Ident\s*):(?:\s*\d+\s*(,|=|;))?/) { 11498e761b04SAndy Whitcroft if (defined $2 && $type eq 'C' || $type eq 'T') { 11501f65f947SAndy Whitcroft $av_pend_colon = 'B'; 11518e761b04SAndy Whitcroft } elsif ($type eq 'E') { 11528e761b04SAndy Whitcroft $av_pend_colon = 'L'; 11531f65f947SAndy Whitcroft } 11541f65f947SAndy Whitcroft print "IDENT_COLON($1,$type>$av_pend_colon)\n" if ($dbg_values > 1); 11551f65f947SAndy Whitcroft $type = 'V'; 11561f65f947SAndy Whitcroft 11576c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Ident|$Constant)/o) { 1158c2fdda0dSAndy Whitcroft print "IDENT($1)\n" if ($dbg_values > 1); 11596c72ffaaSAndy Whitcroft $type = 'V'; 11606c72ffaaSAndy Whitcroft 11616c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Assignment)/o) { 1162c2fdda0dSAndy Whitcroft print "ASSIGN($1)\n" if ($dbg_values > 1); 11636c72ffaaSAndy Whitcroft $type = 'N'; 11646c72ffaaSAndy Whitcroft 1165cf655043SAndy Whitcroft } elsif ($cur =~/^(;|{|})/) { 1166c2fdda0dSAndy Whitcroft print "END($1)\n" if ($dbg_values > 1); 116713214adfSAndy Whitcroft $type = 'E'; 11681f65f947SAndy Whitcroft $av_pend_colon = 'O'; 116913214adfSAndy Whitcroft 11708e761b04SAndy Whitcroft } elsif ($cur =~/^(,)/) { 11718e761b04SAndy Whitcroft print "COMMA($1)\n" if ($dbg_values > 1); 11728e761b04SAndy Whitcroft $type = 'C'; 11738e761b04SAndy Whitcroft 11741f65f947SAndy Whitcroft } elsif ($cur =~ /^(\?)/o) { 11751f65f947SAndy Whitcroft print "QUESTION($1)\n" if ($dbg_values > 1); 11761f65f947SAndy Whitcroft $type = 'N'; 11771f65f947SAndy Whitcroft 11781f65f947SAndy Whitcroft } elsif ($cur =~ /^(:)/o) { 11791f65f947SAndy Whitcroft print "COLON($1,$av_pend_colon)\n" if ($dbg_values > 1); 11801f65f947SAndy Whitcroft 11811f65f947SAndy Whitcroft substr($var, length($res), 1, $av_pend_colon); 11821f65f947SAndy Whitcroft if ($av_pend_colon eq 'C' || $av_pend_colon eq 'L') { 11831f65f947SAndy Whitcroft $type = 'E'; 11841f65f947SAndy Whitcroft } else { 11851f65f947SAndy Whitcroft $type = 'N'; 11861f65f947SAndy Whitcroft } 11871f65f947SAndy Whitcroft $av_pend_colon = 'O'; 11881f65f947SAndy Whitcroft 11898e761b04SAndy Whitcroft } elsif ($cur =~ /^(\[)/o) { 119013214adfSAndy Whitcroft print "CLOSE($1)\n" if ($dbg_values > 1); 11916c72ffaaSAndy Whitcroft $type = 'N'; 11926c72ffaaSAndy Whitcroft 11930d413866SAndy Whitcroft } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) { 119474048ed8SAndy Whitcroft my $variant; 119574048ed8SAndy Whitcroft 119674048ed8SAndy Whitcroft print "OPV($1)\n" if ($dbg_values > 1); 119774048ed8SAndy Whitcroft if ($type eq 'V') { 119874048ed8SAndy Whitcroft $variant = 'B'; 119974048ed8SAndy Whitcroft } else { 120074048ed8SAndy Whitcroft $variant = 'U'; 120174048ed8SAndy Whitcroft } 120274048ed8SAndy Whitcroft 120374048ed8SAndy Whitcroft substr($var, length($res), 1, $variant); 120474048ed8SAndy Whitcroft $type = 'N'; 120574048ed8SAndy Whitcroft 12066c72ffaaSAndy Whitcroft } elsif ($cur =~ /^($Operators)/o) { 1207c2fdda0dSAndy Whitcroft print "OP($1)\n" if ($dbg_values > 1); 12086c72ffaaSAndy Whitcroft if ($1 ne '++' && $1 ne '--') { 12096c72ffaaSAndy Whitcroft $type = 'N'; 12106c72ffaaSAndy Whitcroft } 12116c72ffaaSAndy Whitcroft 12126c72ffaaSAndy Whitcroft } elsif ($cur =~ /(^.)/o) { 1213c2fdda0dSAndy Whitcroft print "C($1)\n" if ($dbg_values > 1); 12146c72ffaaSAndy Whitcroft } 12156c72ffaaSAndy Whitcroft if (defined $1) { 12166c72ffaaSAndy Whitcroft $cur = substr($cur, length($1)); 12176c72ffaaSAndy Whitcroft $res .= $type x length($1); 12186c72ffaaSAndy Whitcroft } 12196c72ffaaSAndy Whitcroft } 12206c72ffaaSAndy Whitcroft 12211f65f947SAndy Whitcroft return ($res, $var); 12226c72ffaaSAndy Whitcroft} 12236c72ffaaSAndy Whitcroft 12248905a67cSAndy Whitcroftsub possible { 122513214adfSAndy Whitcroft my ($possible, $line) = @_; 12269a974fdbSAndy Whitcroft my $notPermitted = qr{(?: 12270776e594SAndy Whitcroft ^(?: 12280776e594SAndy Whitcroft $Modifier| 12290776e594SAndy Whitcroft $Storage| 12300776e594SAndy Whitcroft $Type| 12319a974fdbSAndy Whitcroft DEFINE_\S+ 12329a974fdbSAndy Whitcroft )$| 12339a974fdbSAndy Whitcroft ^(?: 12340776e594SAndy Whitcroft goto| 12350776e594SAndy Whitcroft return| 12360776e594SAndy Whitcroft case| 12370776e594SAndy Whitcroft else| 12380776e594SAndy Whitcroft asm|__asm__| 123989a88353SAndy Whitcroft do| 124089a88353SAndy Whitcroft \#| 124189a88353SAndy Whitcroft \#\#| 12429a974fdbSAndy Whitcroft )(?:\s|$)| 12430776e594SAndy Whitcroft ^(?:typedef|struct|enum)\b 12449a974fdbSAndy Whitcroft )}x; 12459a974fdbSAndy Whitcroft warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); 12469a974fdbSAndy Whitcroft if ($possible !~ $notPermitted) { 1247c45dcabdSAndy Whitcroft # Check for modifiers. 1248c45dcabdSAndy Whitcroft $possible =~ s/\s*$Storage\s*//g; 1249c45dcabdSAndy Whitcroft $possible =~ s/\s*$Sparse\s*//g; 1250c45dcabdSAndy Whitcroft if ($possible =~ /^\s*$/) { 1251c45dcabdSAndy Whitcroft 1252c45dcabdSAndy Whitcroft } elsif ($possible =~ /\s/) { 1253c45dcabdSAndy Whitcroft $possible =~ s/\s*$Type\s*//g; 1254d2506586SAndy Whitcroft for my $modifier (split(' ', $possible)) { 12559a974fdbSAndy Whitcroft if ($modifier !~ $notPermitted) { 1256d2506586SAndy Whitcroft warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); 1257d2506586SAndy Whitcroft push(@modifierList, $modifier); 1258d2506586SAndy Whitcroft } 12599a974fdbSAndy Whitcroft } 1260c45dcabdSAndy Whitcroft 1261c45dcabdSAndy Whitcroft } else { 126213214adfSAndy Whitcroft warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); 12638905a67cSAndy Whitcroft push(@typeList, $possible); 1264c45dcabdSAndy Whitcroft } 12658905a67cSAndy Whitcroft build_types(); 12660776e594SAndy Whitcroft } else { 12670776e594SAndy Whitcroft warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1); 12688905a67cSAndy Whitcroft } 12698905a67cSAndy Whitcroft} 12708905a67cSAndy Whitcroft 12716c72ffaaSAndy Whitcroftmy $prefix = ''; 12726c72ffaaSAndy Whitcroft 1273000d1cc1SJoe Perchessub show_type { 1274000d1cc1SJoe Perches return !defined $ignore_type{$_[0]}; 1275000d1cc1SJoe Perches} 1276000d1cc1SJoe Perches 1277f0a594c1SAndy Whitcroftsub report { 1278000d1cc1SJoe Perches if (!show_type($_[1]) || 1279000d1cc1SJoe Perches (defined $tst_only && $_[2] !~ /\Q$tst_only\E/)) { 1280773647a0SAndy Whitcroft return 0; 1281773647a0SAndy Whitcroft } 1282000d1cc1SJoe Perches my $line; 1283000d1cc1SJoe Perches if ($show_types) { 1284000d1cc1SJoe Perches $line = "$prefix$_[0]:$_[1]: $_[2]\n"; 1285000d1cc1SJoe Perches } else { 1286000d1cc1SJoe Perches $line = "$prefix$_[0]: $_[2]\n"; 1287000d1cc1SJoe Perches } 12888905a67cSAndy Whitcroft $line = (split('\n', $line))[0] . "\n" if ($terse); 12898905a67cSAndy Whitcroft 129013214adfSAndy Whitcroft push(our @report, $line); 1291773647a0SAndy Whitcroft 1292773647a0SAndy Whitcroft return 1; 1293f0a594c1SAndy Whitcroft} 1294f0a594c1SAndy Whitcroftsub report_dump { 129513214adfSAndy Whitcroft our @report; 1296f0a594c1SAndy Whitcroft} 1297000d1cc1SJoe Perches 1298de7d4f0eSAndy Whitcroftsub ERROR { 1299000d1cc1SJoe Perches if (report("ERROR", $_[0], $_[1])) { 1300de7d4f0eSAndy Whitcroft our $clean = 0; 13016c72ffaaSAndy Whitcroft our $cnt_error++; 1302*3705ce5bSJoe Perches return 1; 1303de7d4f0eSAndy Whitcroft } 1304*3705ce5bSJoe Perches return 0; 1305773647a0SAndy Whitcroft} 1306de7d4f0eSAndy Whitcroftsub WARN { 1307000d1cc1SJoe Perches if (report("WARNING", $_[0], $_[1])) { 1308de7d4f0eSAndy Whitcroft our $clean = 0; 13096c72ffaaSAndy Whitcroft our $cnt_warn++; 1310*3705ce5bSJoe Perches return 1; 1311de7d4f0eSAndy Whitcroft } 1312*3705ce5bSJoe Perches return 0; 1313773647a0SAndy Whitcroft} 1314de7d4f0eSAndy Whitcroftsub CHK { 1315000d1cc1SJoe Perches if ($check && report("CHECK", $_[0], $_[1])) { 1316de7d4f0eSAndy Whitcroft our $clean = 0; 13176c72ffaaSAndy Whitcroft our $cnt_chk++; 1318*3705ce5bSJoe Perches return 1; 13196c72ffaaSAndy Whitcroft } 1320*3705ce5bSJoe Perches return 0; 1321de7d4f0eSAndy Whitcroft} 1322de7d4f0eSAndy Whitcroft 13236ecd9674SAndy Whitcroftsub check_absolute_file { 13246ecd9674SAndy Whitcroft my ($absolute, $herecurr) = @_; 13256ecd9674SAndy Whitcroft my $file = $absolute; 13266ecd9674SAndy Whitcroft 13276ecd9674SAndy Whitcroft ##print "absolute<$absolute>\n"; 13286ecd9674SAndy Whitcroft 13296ecd9674SAndy Whitcroft # See if any suffix of this path is a path within the tree. 13306ecd9674SAndy Whitcroft while ($file =~ s@^[^/]*/@@) { 13316ecd9674SAndy Whitcroft if (-f "$root/$file") { 13326ecd9674SAndy Whitcroft ##print "file<$file>\n"; 13336ecd9674SAndy Whitcroft last; 13346ecd9674SAndy Whitcroft } 13356ecd9674SAndy Whitcroft } 13366ecd9674SAndy Whitcroft if (! -f _) { 13376ecd9674SAndy Whitcroft return 0; 13386ecd9674SAndy Whitcroft } 13396ecd9674SAndy Whitcroft 13406ecd9674SAndy Whitcroft # It is, so see if the prefix is acceptable. 13416ecd9674SAndy Whitcroft my $prefix = $absolute; 13426ecd9674SAndy Whitcroft substr($prefix, -length($file)) = ''; 13436ecd9674SAndy Whitcroft 13446ecd9674SAndy Whitcroft ##print "prefix<$prefix>\n"; 13456ecd9674SAndy Whitcroft if ($prefix ne ".../") { 1346000d1cc1SJoe Perches WARN("USE_RELATIVE_PATH", 1347000d1cc1SJoe Perches "use relative pathname instead of absolute in changelog text\n" . $herecurr); 13486ecd9674SAndy Whitcroft } 13496ecd9674SAndy Whitcroft} 13506ecd9674SAndy Whitcroft 1351*3705ce5bSJoe Perchessub trim { 1352*3705ce5bSJoe Perches my ($string) = @_; 1353*3705ce5bSJoe Perches 1354*3705ce5bSJoe Perches $string =~ s/(^\s+|\s+$)//g; 1355*3705ce5bSJoe Perches 1356*3705ce5bSJoe Perches return $string; 1357*3705ce5bSJoe Perches} 1358*3705ce5bSJoe Perches 1359*3705ce5bSJoe Perchessub tabify { 1360*3705ce5bSJoe Perches my ($leading) = @_; 1361*3705ce5bSJoe Perches 1362*3705ce5bSJoe Perches my $source_indent = 8; 1363*3705ce5bSJoe Perches my $max_spaces_before_tab = $source_indent - 1; 1364*3705ce5bSJoe Perches my $spaces_to_tab = " " x $source_indent; 1365*3705ce5bSJoe Perches 1366*3705ce5bSJoe Perches #convert leading spaces to tabs 1367*3705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g; 1368*3705ce5bSJoe Perches #Remove spaces before a tab 1369*3705ce5bSJoe Perches 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g; 1370*3705ce5bSJoe Perches 1371*3705ce5bSJoe Perches return "$leading"; 1372*3705ce5bSJoe Perches} 1373*3705ce5bSJoe Perches 1374d1fe9c09SJoe Perchessub pos_last_openparen { 1375d1fe9c09SJoe Perches my ($line) = @_; 1376d1fe9c09SJoe Perches 1377d1fe9c09SJoe Perches my $pos = 0; 1378d1fe9c09SJoe Perches 1379d1fe9c09SJoe Perches my $opens = $line =~ tr/\(/\(/; 1380d1fe9c09SJoe Perches my $closes = $line =~ tr/\)/\)/; 1381d1fe9c09SJoe Perches 1382d1fe9c09SJoe Perches my $last_openparen = 0; 1383d1fe9c09SJoe Perches 1384d1fe9c09SJoe Perches if (($opens == 0) || ($closes >= $opens)) { 1385d1fe9c09SJoe Perches return -1; 1386d1fe9c09SJoe Perches } 1387d1fe9c09SJoe Perches 1388d1fe9c09SJoe Perches my $len = length($line); 1389d1fe9c09SJoe Perches 1390d1fe9c09SJoe Perches for ($pos = 0; $pos < $len; $pos++) { 1391d1fe9c09SJoe Perches my $string = substr($line, $pos); 1392d1fe9c09SJoe Perches if ($string =~ /^($FuncArg|$balanced_parens)/) { 1393d1fe9c09SJoe Perches $pos += length($1) - 1; 1394d1fe9c09SJoe Perches } elsif (substr($line, $pos, 1) eq '(') { 1395d1fe9c09SJoe Perches $last_openparen = $pos; 1396d1fe9c09SJoe Perches } elsif (index($string, '(') == -1) { 1397d1fe9c09SJoe Perches last; 1398d1fe9c09SJoe Perches } 1399d1fe9c09SJoe Perches } 1400d1fe9c09SJoe Perches 1401d1fe9c09SJoe Perches return $last_openparen + 1; 1402d1fe9c09SJoe Perches} 1403d1fe9c09SJoe Perches 14040a920b5bSAndy Whitcroftsub process { 14050a920b5bSAndy Whitcroft my $filename = shift; 14060a920b5bSAndy Whitcroft 14070a920b5bSAndy Whitcroft my $linenr=0; 14080a920b5bSAndy Whitcroft my $prevline=""; 1409c2fdda0dSAndy Whitcroft my $prevrawline=""; 14100a920b5bSAndy Whitcroft my $stashline=""; 1411c2fdda0dSAndy Whitcroft my $stashrawline=""; 14120a920b5bSAndy Whitcroft 14134a0df2efSAndy Whitcroft my $length; 14140a920b5bSAndy Whitcroft my $indent; 14150a920b5bSAndy Whitcroft my $previndent=0; 14160a920b5bSAndy Whitcroft my $stashindent=0; 14170a920b5bSAndy Whitcroft 1418de7d4f0eSAndy Whitcroft our $clean = 1; 14190a920b5bSAndy Whitcroft my $signoff = 0; 14200a920b5bSAndy Whitcroft my $is_patch = 0; 14210a920b5bSAndy Whitcroft 142215662b3eSJoe Perches my $in_header_lines = 1; 142315662b3eSJoe Perches my $in_commit_log = 0; #Scanning lines before patch 142415662b3eSJoe Perches 1425fa64205dSPasi Savanainen my $non_utf8_charset = 0; 1426fa64205dSPasi Savanainen 142713214adfSAndy Whitcroft our @report = (); 14286c72ffaaSAndy Whitcroft our $cnt_lines = 0; 14296c72ffaaSAndy Whitcroft our $cnt_error = 0; 14306c72ffaaSAndy Whitcroft our $cnt_warn = 0; 14316c72ffaaSAndy Whitcroft our $cnt_chk = 0; 14326c72ffaaSAndy Whitcroft 14330a920b5bSAndy Whitcroft # Trace the real file/line as we go. 14340a920b5bSAndy Whitcroft my $realfile = ''; 14350a920b5bSAndy Whitcroft my $realline = 0; 14360a920b5bSAndy Whitcroft my $realcnt = 0; 14370a920b5bSAndy Whitcroft my $here = ''; 14380a920b5bSAndy Whitcroft my $in_comment = 0; 1439c2fdda0dSAndy Whitcroft my $comment_edge = 0; 14400a920b5bSAndy Whitcroft my $first_line = 0; 14411e855726SWolfram Sang my $p1_prefix = ''; 14420a920b5bSAndy Whitcroft 144313214adfSAndy Whitcroft my $prev_values = 'E'; 144413214adfSAndy Whitcroft 144513214adfSAndy Whitcroft # suppression flags 1446773647a0SAndy Whitcroft my %suppress_ifbraces; 1447170d3a22SAndy Whitcroft my %suppress_whiletrailers; 14482b474a1aSAndy Whitcroft my %suppress_export; 14493e469cdcSAndy Whitcroft my $suppress_statement = 0; 1450653d4876SAndy Whitcroft 1451323c1260SJoe Perches my %camelcase = (); 1452323c1260SJoe Perches 1453c2fdda0dSAndy Whitcroft # Pre-scan the patch sanitizing the lines. 1454de7d4f0eSAndy Whitcroft # Pre-scan the patch looking for any __setup documentation. 1455c2fdda0dSAndy Whitcroft # 1456de7d4f0eSAndy Whitcroft my @setup_docs = (); 1457de7d4f0eSAndy Whitcroft my $setup_docs = 0; 1458773647a0SAndy Whitcroft 1459773647a0SAndy Whitcroft sanitise_line_reset(); 1460c2fdda0dSAndy Whitcroft my $line; 1461c2fdda0dSAndy Whitcroft foreach my $rawline (@rawlines) { 1462773647a0SAndy Whitcroft $linenr++; 1463773647a0SAndy Whitcroft $line = $rawline; 1464c2fdda0dSAndy Whitcroft 1465*3705ce5bSJoe Perches push(@fixed, $rawline) if ($fix); 1466*3705ce5bSJoe Perches 1467773647a0SAndy Whitcroft if ($rawline=~/^\+\+\+\s+(\S+)/) { 1468de7d4f0eSAndy Whitcroft $setup_docs = 0; 1469de7d4f0eSAndy Whitcroft if ($1 =~ m@Documentation/kernel-parameters.txt$@) { 1470de7d4f0eSAndy Whitcroft $setup_docs = 1; 1471de7d4f0eSAndy Whitcroft } 1472773647a0SAndy Whitcroft #next; 1473de7d4f0eSAndy Whitcroft } 1474773647a0SAndy Whitcroft if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 1475773647a0SAndy Whitcroft $realline=$1-1; 1476773647a0SAndy Whitcroft if (defined $2) { 1477773647a0SAndy Whitcroft $realcnt=$3+1; 1478773647a0SAndy Whitcroft } else { 1479773647a0SAndy Whitcroft $realcnt=1+1; 1480773647a0SAndy Whitcroft } 1481c45dcabdSAndy Whitcroft $in_comment = 0; 1482773647a0SAndy Whitcroft 1483773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. Run 1484773647a0SAndy Whitcroft # the context looking for a comment "edge". If this 1485773647a0SAndy Whitcroft # edge is a close comment then we must be in a comment 1486773647a0SAndy Whitcroft # at context start. 1487773647a0SAndy Whitcroft my $edge; 148801fa9147SAndy Whitcroft my $cnt = $realcnt; 148901fa9147SAndy Whitcroft for (my $ln = $linenr + 1; $cnt > 0; $ln++) { 149001fa9147SAndy Whitcroft next if (defined $rawlines[$ln - 1] && 149101fa9147SAndy Whitcroft $rawlines[$ln - 1] =~ /^-/); 149201fa9147SAndy Whitcroft $cnt--; 149301fa9147SAndy Whitcroft #print "RAW<$rawlines[$ln - 1]>\n"; 1494721c1cb6SAndy Whitcroft last if (!defined $rawlines[$ln - 1]); 1495fae17daeSAndy Whitcroft if ($rawlines[$ln - 1] =~ m@(/\*|\*/)@ && 1496fae17daeSAndy Whitcroft $rawlines[$ln - 1] !~ m@"[^"]*(?:/\*|\*/)[^"]*"@) { 1497fae17daeSAndy Whitcroft ($edge) = $1; 1498fae17daeSAndy Whitcroft last; 1499fae17daeSAndy Whitcroft } 1500773647a0SAndy Whitcroft } 1501773647a0SAndy Whitcroft if (defined $edge && $edge eq '*/') { 1502773647a0SAndy Whitcroft $in_comment = 1; 1503773647a0SAndy Whitcroft } 1504773647a0SAndy Whitcroft 1505773647a0SAndy Whitcroft # Guestimate if this is a continuing comment. If this 1506773647a0SAndy Whitcroft # is the start of a diff block and this line starts 1507773647a0SAndy Whitcroft # ' *' then it is very likely a comment. 1508773647a0SAndy Whitcroft if (!defined $edge && 150983242e0cSAndy Whitcroft $rawlines[$linenr] =~ m@^.\s*(?:\*\*+| \*)(?:\s|$)@) 1510773647a0SAndy Whitcroft { 1511773647a0SAndy Whitcroft $in_comment = 1; 1512773647a0SAndy Whitcroft } 1513773647a0SAndy Whitcroft 1514773647a0SAndy Whitcroft ##print "COMMENT:$in_comment edge<$edge> $rawline\n"; 1515773647a0SAndy Whitcroft sanitise_line_reset($in_comment); 1516773647a0SAndy Whitcroft 1517171ae1a4SAndy Whitcroft } elsif ($realcnt && $rawline =~ /^(?:\+| |$)/) { 1518773647a0SAndy Whitcroft # Standardise the strings and chars within the input to 1519171ae1a4SAndy Whitcroft # simplify matching -- only bother with positive lines. 1520773647a0SAndy Whitcroft $line = sanitise_line($rawline); 1521773647a0SAndy Whitcroft } 1522773647a0SAndy Whitcroft push(@lines, $line); 1523773647a0SAndy Whitcroft 1524773647a0SAndy Whitcroft if ($realcnt > 1) { 1525773647a0SAndy Whitcroft $realcnt-- if ($line =~ /^(?:\+| |$)/); 1526773647a0SAndy Whitcroft } else { 1527773647a0SAndy Whitcroft $realcnt = 0; 1528773647a0SAndy Whitcroft } 1529773647a0SAndy Whitcroft 1530773647a0SAndy Whitcroft #print "==>$rawline\n"; 1531773647a0SAndy Whitcroft #print "-->$line\n"; 1532de7d4f0eSAndy Whitcroft 1533de7d4f0eSAndy Whitcroft if ($setup_docs && $line =~ /^\+/) { 1534de7d4f0eSAndy Whitcroft push(@setup_docs, $line); 1535de7d4f0eSAndy Whitcroft } 1536de7d4f0eSAndy Whitcroft } 1537de7d4f0eSAndy Whitcroft 15386c72ffaaSAndy Whitcroft $prefix = ''; 15396c72ffaaSAndy Whitcroft 1540773647a0SAndy Whitcroft $realcnt = 0; 1541773647a0SAndy Whitcroft $linenr = 0; 15420a920b5bSAndy Whitcroft foreach my $line (@lines) { 15430a920b5bSAndy Whitcroft $linenr++; 15440a920b5bSAndy Whitcroft 1545c2fdda0dSAndy Whitcroft my $rawline = $rawlines[$linenr - 1]; 15466c72ffaaSAndy Whitcroft 15470a920b5bSAndy Whitcroft#extract the line range in the file after the patch is applied 15486c72ffaaSAndy Whitcroft if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { 15490a920b5bSAndy Whitcroft $is_patch = 1; 15504a0df2efSAndy Whitcroft $first_line = $linenr + 1; 15510a920b5bSAndy Whitcroft $realline=$1-1; 15520a920b5bSAndy Whitcroft if (defined $2) { 15530a920b5bSAndy Whitcroft $realcnt=$3+1; 15540a920b5bSAndy Whitcroft } else { 15550a920b5bSAndy Whitcroft $realcnt=1+1; 15560a920b5bSAndy Whitcroft } 1557c2fdda0dSAndy Whitcroft annotate_reset(); 155813214adfSAndy Whitcroft $prev_values = 'E'; 155913214adfSAndy Whitcroft 1560773647a0SAndy Whitcroft %suppress_ifbraces = (); 1561170d3a22SAndy Whitcroft %suppress_whiletrailers = (); 15622b474a1aSAndy Whitcroft %suppress_export = (); 15633e469cdcSAndy Whitcroft $suppress_statement = 0; 15640a920b5bSAndy Whitcroft next; 15650a920b5bSAndy Whitcroft 15664a0df2efSAndy Whitcroft# track the line number as we move through the hunk, note that 15674a0df2efSAndy Whitcroft# new versions of GNU diff omit the leading space on completely 15684a0df2efSAndy Whitcroft# blank context lines so we need to count that too. 1569773647a0SAndy Whitcroft } elsif ($line =~ /^( |\+|$)/) { 15700a920b5bSAndy Whitcroft $realline++; 1571d8aaf121SAndy Whitcroft $realcnt-- if ($realcnt != 0); 15720a920b5bSAndy Whitcroft 15734a0df2efSAndy Whitcroft # Measure the line length and indent. 1574c2fdda0dSAndy Whitcroft ($length, $indent) = line_stats($rawline); 15750a920b5bSAndy Whitcroft 15760a920b5bSAndy Whitcroft # Track the previous line. 15770a920b5bSAndy Whitcroft ($prevline, $stashline) = ($stashline, $line); 15780a920b5bSAndy Whitcroft ($previndent, $stashindent) = ($stashindent, $indent); 1579c2fdda0dSAndy Whitcroft ($prevrawline, $stashrawline) = ($stashrawline, $rawline); 1580c2fdda0dSAndy Whitcroft 1581773647a0SAndy Whitcroft #warn "line<$line>\n"; 15826c72ffaaSAndy Whitcroft 1583d8aaf121SAndy Whitcroft } elsif ($realcnt == 1) { 1584d8aaf121SAndy Whitcroft $realcnt--; 15850a920b5bSAndy Whitcroft } 15860a920b5bSAndy Whitcroft 1587cc77cdcaSAndy Whitcroft my $hunk_line = ($realcnt != 0); 1588cc77cdcaSAndy Whitcroft 15890a920b5bSAndy Whitcroft#make up the handle for any error we report on this line 1590773647a0SAndy Whitcroft $prefix = "$filename:$realline: " if ($emacs && $file); 1591773647a0SAndy Whitcroft $prefix = "$filename:$linenr: " if ($emacs && !$file); 1592773647a0SAndy Whitcroft 15936c72ffaaSAndy Whitcroft $here = "#$linenr: " if (!$file); 15946c72ffaaSAndy Whitcroft $here = "#$realline: " if ($file); 1595773647a0SAndy Whitcroft 1596773647a0SAndy Whitcroft # extract the filename as it passes 15973bf9a009SRabin Vincent if ($line =~ /^diff --git.*?(\S+)$/) { 15983bf9a009SRabin Vincent $realfile = $1; 15993bf9a009SRabin Vincent $realfile =~ s@^([^/]*)/@@; 1600270c49a0SJoe Perches $in_commit_log = 0; 16013bf9a009SRabin Vincent } elsif ($line =~ /^\+\+\+\s+(\S+)/) { 1602773647a0SAndy Whitcroft $realfile = $1; 16031e855726SWolfram Sang $realfile =~ s@^([^/]*)/@@; 1604270c49a0SJoe Perches $in_commit_log = 0; 16051e855726SWolfram Sang 16061e855726SWolfram Sang $p1_prefix = $1; 1607e2f7aa4bSAndy Whitcroft if (!$file && $tree && $p1_prefix ne '' && 1608e2f7aa4bSAndy Whitcroft -e "$root/$p1_prefix") { 1609000d1cc1SJoe Perches WARN("PATCH_PREFIX", 1610000d1cc1SJoe Perches "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); 16111e855726SWolfram Sang } 1612773647a0SAndy Whitcroft 1613c1ab3326SAndy Whitcroft if ($realfile =~ m@^include/asm/@) { 1614000d1cc1SJoe Perches ERROR("MODIFIED_INCLUDE_ASM", 1615000d1cc1SJoe Perches "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); 1616773647a0SAndy Whitcroft } 1617773647a0SAndy Whitcroft next; 1618773647a0SAndy Whitcroft } 1619773647a0SAndy Whitcroft 1620389834b6SRandy Dunlap $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); 16210a920b5bSAndy Whitcroft 1622c2fdda0dSAndy Whitcroft my $hereline = "$here\n$rawline\n"; 1623c2fdda0dSAndy Whitcroft my $herecurr = "$here\n$rawline\n"; 1624c2fdda0dSAndy Whitcroft my $hereprev = "$here\n$prevrawline\n$rawline\n"; 16250a920b5bSAndy Whitcroft 16266c72ffaaSAndy Whitcroft $cnt_lines++ if ($realcnt != 0); 16276c72ffaaSAndy Whitcroft 16283bf9a009SRabin Vincent# Check for incorrect file permissions 16293bf9a009SRabin Vincent if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { 16303bf9a009SRabin Vincent my $permhere = $here . "FILE: $realfile\n"; 163104db4d25SJoe Perches if ($realfile !~ m@scripts/@ && 163204db4d25SJoe Perches $realfile !~ /\.(py|pl|awk|sh)$/) { 1633000d1cc1SJoe Perches ERROR("EXECUTE_PERMISSIONS", 1634000d1cc1SJoe Perches "do not set execute permissions for source files\n" . $permhere); 16353bf9a009SRabin Vincent } 16363bf9a009SRabin Vincent } 16373bf9a009SRabin Vincent 163820112475SJoe Perches# Check the patch for a signoff: 1639d8aaf121SAndy Whitcroft if ($line =~ /^\s*signed-off-by:/i) { 16404a0df2efSAndy Whitcroft $signoff++; 164115662b3eSJoe Perches $in_commit_log = 0; 16420a920b5bSAndy Whitcroft } 164320112475SJoe Perches 164420112475SJoe Perches# Check signature styles 1645270c49a0SJoe Perches if (!$in_header_lines && 1646ce0338dfSJoe Perches $line =~ /^(\s*)([a-z0-9_-]+by:|$signature_tags)(\s*)(.*)/i) { 164720112475SJoe Perches my $space_before = $1; 164820112475SJoe Perches my $sign_off = $2; 164920112475SJoe Perches my $space_after = $3; 165020112475SJoe Perches my $email = $4; 165120112475SJoe Perches my $ucfirst_sign_off = ucfirst(lc($sign_off)); 165220112475SJoe Perches 1653ce0338dfSJoe Perches if ($sign_off !~ /$signature_tags/) { 1654ce0338dfSJoe Perches WARN("BAD_SIGN_OFF", 1655ce0338dfSJoe Perches "Non-standard signature: $sign_off\n" . $herecurr); 1656ce0338dfSJoe Perches } 165720112475SJoe Perches if (defined $space_before && $space_before ne "") { 1658*3705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 1659*3705ce5bSJoe Perches "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) && 1660*3705ce5bSJoe Perches $fix) { 1661*3705ce5bSJoe Perches $fixed[$linenr - 1] = 1662*3705ce5bSJoe Perches "$ucfirst_sign_off $email"; 1663*3705ce5bSJoe Perches } 166420112475SJoe Perches } 166520112475SJoe Perches if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { 1666*3705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 1667*3705ce5bSJoe Perches "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) && 1668*3705ce5bSJoe Perches $fix) { 1669*3705ce5bSJoe Perches $fixed[$linenr - 1] = 1670*3705ce5bSJoe Perches "$ucfirst_sign_off $email"; 1671*3705ce5bSJoe Perches } 1672*3705ce5bSJoe Perches 167320112475SJoe Perches } 167420112475SJoe Perches if (!defined $space_after || $space_after ne " ") { 1675*3705ce5bSJoe Perches if (WARN("BAD_SIGN_OFF", 1676*3705ce5bSJoe Perches "Use a single space after $ucfirst_sign_off\n" . $herecurr) && 1677*3705ce5bSJoe Perches $fix) { 1678*3705ce5bSJoe Perches $fixed[$linenr - 1] = 1679*3705ce5bSJoe Perches "$ucfirst_sign_off $email"; 1680*3705ce5bSJoe Perches } 168120112475SJoe Perches } 168220112475SJoe Perches 168320112475SJoe Perches my ($email_name, $email_address, $comment) = parse_email($email); 168420112475SJoe Perches my $suggested_email = format_email(($email_name, $email_address)); 168520112475SJoe Perches if ($suggested_email eq "") { 1686000d1cc1SJoe Perches ERROR("BAD_SIGN_OFF", 1687000d1cc1SJoe Perches "Unrecognized email address: '$email'\n" . $herecurr); 168820112475SJoe Perches } else { 168920112475SJoe Perches my $dequoted = $suggested_email; 169020112475SJoe Perches $dequoted =~ s/^"//; 169120112475SJoe Perches $dequoted =~ s/" </ </; 169220112475SJoe Perches # Don't force email to have quotes 169320112475SJoe Perches # Allow just an angle bracketed address 169420112475SJoe Perches if ("$dequoted$comment" ne $email && 169520112475SJoe Perches "<$email_address>$comment" ne $email && 169620112475SJoe Perches "$suggested_email$comment" ne $email) { 1697000d1cc1SJoe Perches WARN("BAD_SIGN_OFF", 1698000d1cc1SJoe Perches "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr); 169920112475SJoe Perches } 17000a920b5bSAndy Whitcroft } 17010a920b5bSAndy Whitcroft } 17020a920b5bSAndy Whitcroft 170300df344fSAndy Whitcroft# Check for wrappage within a valid hunk of the file 17048905a67cSAndy Whitcroft if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { 1705000d1cc1SJoe Perches ERROR("CORRUPTED_PATCH", 1706000d1cc1SJoe Perches "patch seems to be corrupt (line wrapped?)\n" . 17076c72ffaaSAndy Whitcroft $herecurr) if (!$emitted_corrupt++); 1708de7d4f0eSAndy Whitcroft } 1709de7d4f0eSAndy Whitcroft 17106ecd9674SAndy Whitcroft# Check for absolute kernel paths. 17116ecd9674SAndy Whitcroft if ($tree) { 17126ecd9674SAndy Whitcroft while ($line =~ m{(?:^|\s)(/\S*)}g) { 17136ecd9674SAndy Whitcroft my $file = $1; 17146ecd9674SAndy Whitcroft 17156ecd9674SAndy Whitcroft if ($file =~ m{^(.*?)(?::\d+)+:?$} && 17166ecd9674SAndy Whitcroft check_absolute_file($1, $herecurr)) { 17176ecd9674SAndy Whitcroft # 17186ecd9674SAndy Whitcroft } else { 17196ecd9674SAndy Whitcroft check_absolute_file($file, $herecurr); 17206ecd9674SAndy Whitcroft } 17216ecd9674SAndy Whitcroft } 17226ecd9674SAndy Whitcroft } 17236ecd9674SAndy Whitcroft 1724de7d4f0eSAndy Whitcroft# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php 1725de7d4f0eSAndy Whitcroft if (($realfile =~ /^$/ || $line =~ /^\+/) && 1726171ae1a4SAndy Whitcroft $rawline !~ m/^$UTF8*$/) { 1727171ae1a4SAndy Whitcroft my ($utf8_prefix) = ($rawline =~ /^($UTF8*)/); 1728171ae1a4SAndy Whitcroft 1729171ae1a4SAndy Whitcroft my $blank = copy_spacing($rawline); 1730171ae1a4SAndy Whitcroft my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; 1731171ae1a4SAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 1732171ae1a4SAndy Whitcroft 173334d99219SJoe Perches CHK("INVALID_UTF8", 1734000d1cc1SJoe Perches "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); 173500df344fSAndy Whitcroft } 17360a920b5bSAndy Whitcroft 173715662b3eSJoe Perches# Check if it's the start of a commit log 173815662b3eSJoe Perches# (not a header line and we haven't seen the patch filename) 173915662b3eSJoe Perches if ($in_header_lines && $realfile =~ /^$/ && 1740270c49a0SJoe Perches $rawline !~ /^(commit\b|from\b|[\w-]+:).+$/i) { 174115662b3eSJoe Perches $in_header_lines = 0; 174215662b3eSJoe Perches $in_commit_log = 1; 174315662b3eSJoe Perches } 174415662b3eSJoe Perches 1745fa64205dSPasi Savanainen# Check if there is UTF-8 in a commit log when a mail header has explicitly 1746fa64205dSPasi Savanainen# declined it, i.e defined some charset where it is missing. 1747fa64205dSPasi Savanainen if ($in_header_lines && 1748fa64205dSPasi Savanainen $rawline =~ /^Content-Type:.+charset="(.+)".*$/ && 1749fa64205dSPasi Savanainen $1 !~ /utf-8/i) { 1750fa64205dSPasi Savanainen $non_utf8_charset = 1; 1751fa64205dSPasi Savanainen } 1752fa64205dSPasi Savanainen 1753fa64205dSPasi Savanainen if ($in_commit_log && $non_utf8_charset && $realfile =~ /^$/ && 175415662b3eSJoe Perches $rawline =~ /$NON_ASCII_UTF8/) { 1755fa64205dSPasi Savanainen WARN("UTF8_BEFORE_PATCH", 175615662b3eSJoe Perches "8-bit UTF-8 used in possible commit log\n" . $herecurr); 175715662b3eSJoe Perches } 175815662b3eSJoe Perches 175930670854SAndy Whitcroft# ignore non-hunk lines and lines being removed 176030670854SAndy Whitcroft next if (!$hunk_line || $line =~ /^-/); 176100df344fSAndy Whitcroft 17620a920b5bSAndy Whitcroft#trailing whitespace 17639c0ca6f9SAndy Whitcroft if ($line =~ /^\+.*\015/) { 1764c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1765000d1cc1SJoe Perches ERROR("DOS_LINE_ENDINGS", 1766000d1cc1SJoe Perches "DOS line endings\n" . $herevet); 17679c0ca6f9SAndy Whitcroft 1768c2fdda0dSAndy Whitcroft } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { 1769c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1770*3705ce5bSJoe Perches if (ERROR("TRAILING_WHITESPACE", 1771*3705ce5bSJoe Perches "trailing whitespace\n" . $herevet) && 1772*3705ce5bSJoe Perches $fix) { 1773*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ s/^(\+.*?)\s+$/$1/; 1774*3705ce5bSJoe Perches } 1775*3705ce5bSJoe Perches 1776d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 17770a920b5bSAndy Whitcroft } 17785368df20SAndy Whitcroft 17793354957aSAndi Kleen# check for Kconfig help text having a real description 17809fe287d7SAndy Whitcroft# Only applies when adding the entry originally, after that we do not have 17819fe287d7SAndy Whitcroft# sufficient context to determine whether it is indeed long enough. 17823354957aSAndi Kleen if ($realfile =~ /Kconfig/ && 1783a1385803SAndy Whitcroft $line =~ /.\s*config\s+/) { 17843354957aSAndi Kleen my $length = 0; 17859fe287d7SAndy Whitcroft my $cnt = $realcnt; 17869fe287d7SAndy Whitcroft my $ln = $linenr + 1; 17879fe287d7SAndy Whitcroft my $f; 1788a1385803SAndy Whitcroft my $is_start = 0; 17899fe287d7SAndy Whitcroft my $is_end = 0; 1790a1385803SAndy Whitcroft for (; $cnt > 0 && defined $lines[$ln - 1]; $ln++) { 17919fe287d7SAndy Whitcroft $f = $lines[$ln - 1]; 17929fe287d7SAndy Whitcroft $cnt-- if ($lines[$ln - 1] !~ /^-/); 17939fe287d7SAndy Whitcroft $is_end = $lines[$ln - 1] =~ /^\+/; 17949fe287d7SAndy Whitcroft 17959fe287d7SAndy Whitcroft next if ($f =~ /^-/); 1796a1385803SAndy Whitcroft 1797a1385803SAndy Whitcroft if ($lines[$ln - 1] =~ /.\s*(?:bool|tristate)\s*\"/) { 1798a1385803SAndy Whitcroft $is_start = 1; 1799a1385803SAndy Whitcroft } elsif ($lines[$ln - 1] =~ /.\s*(?:---)?help(?:---)?$/) { 1800a1385803SAndy Whitcroft $length = -1; 1801a1385803SAndy Whitcroft } 1802a1385803SAndy Whitcroft 18039fe287d7SAndy Whitcroft $f =~ s/^.//; 18043354957aSAndi Kleen $f =~ s/#.*//; 18053354957aSAndi Kleen $f =~ s/^\s+//; 18063354957aSAndi Kleen next if ($f =~ /^$/); 18079fe287d7SAndy Whitcroft if ($f =~ /^\s*config\s/) { 18089fe287d7SAndy Whitcroft $is_end = 1; 18099fe287d7SAndy Whitcroft last; 18109fe287d7SAndy Whitcroft } 18113354957aSAndi Kleen $length++; 18123354957aSAndi Kleen } 1813000d1cc1SJoe Perches WARN("CONFIG_DESCRIPTION", 1814a1385803SAndy Whitcroft "please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_start && $is_end && $length < 4); 1815a1385803SAndy Whitcroft #print "is_start<$is_start> is_end<$is_end> length<$length>\n"; 18163354957aSAndi Kleen } 18173354957aSAndi Kleen 18181ba8dfd1SKees Cook# discourage the addition of CONFIG_EXPERIMENTAL in Kconfig. 18191ba8dfd1SKees Cook if ($realfile =~ /Kconfig/ && 18201ba8dfd1SKees Cook $line =~ /.\s*depends on\s+.*\bEXPERIMENTAL\b/) { 18211ba8dfd1SKees Cook WARN("CONFIG_EXPERIMENTAL", 18221ba8dfd1SKees Cook "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n"); 18231ba8dfd1SKees Cook } 18241ba8dfd1SKees Cook 1825c68e5878SArnaud Lacombe if (($realfile =~ /Makefile.*/ || $realfile =~ /Kbuild.*/) && 1826c68e5878SArnaud Lacombe ($line =~ /\+(EXTRA_[A-Z]+FLAGS).*/)) { 1827c68e5878SArnaud Lacombe my $flag = $1; 1828c68e5878SArnaud Lacombe my $replacement = { 1829c68e5878SArnaud Lacombe 'EXTRA_AFLAGS' => 'asflags-y', 1830c68e5878SArnaud Lacombe 'EXTRA_CFLAGS' => 'ccflags-y', 1831c68e5878SArnaud Lacombe 'EXTRA_CPPFLAGS' => 'cppflags-y', 1832c68e5878SArnaud Lacombe 'EXTRA_LDFLAGS' => 'ldflags-y', 1833c68e5878SArnaud Lacombe }; 1834c68e5878SArnaud Lacombe 1835c68e5878SArnaud Lacombe WARN("DEPRECATED_VARIABLE", 1836c68e5878SArnaud Lacombe "Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag}); 1837c68e5878SArnaud Lacombe } 1838c68e5878SArnaud Lacombe 18395368df20SAndy Whitcroft# check we are in a valid source file if not then ignore this hunk 18405368df20SAndy Whitcroft next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/); 18415368df20SAndy Whitcroft 18426cd7f386SJoe Perches#line length limit 1843c45dcabdSAndy Whitcroft if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && 1844f4c014c0SAndy Whitcroft $rawline !~ /^.\s*\*\s*\@$Ident\s/ && 18450fccc622SJoe Perches !($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:|,|\)\s*;)\s*$/ || 18468bbea968SJoe Perches $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) && 18476cd7f386SJoe Perches $length > $max_line_length) 1848c45dcabdSAndy Whitcroft { 1849000d1cc1SJoe Perches WARN("LONG_LINE", 18506cd7f386SJoe Perches "line over $max_line_length characters\n" . $herecurr); 18510a920b5bSAndy Whitcroft } 18520a920b5bSAndy Whitcroft 1853ca56dc09SJosh Triplett# Check for user-visible strings broken across lines, which breaks the ability 1854ca56dc09SJosh Triplett# to grep for the string. Limited to strings used as parameters (those 1855ca56dc09SJosh Triplett# following an open parenthesis), which almost completely eliminates false 1856ca56dc09SJosh Triplett# positives, as well as warning only once per parameter rather than once per 1857ca56dc09SJosh Triplett# line of the string. Make an exception when the previous string ends in a 1858ca56dc09SJosh Triplett# newline (multiple lines in one string constant) or \n\t (common in inline 1859ca56dc09SJosh Triplett# assembly to indent the instruction on the following line). 1860ca56dc09SJosh Triplett if ($line =~ /^\+\s*"/ && 1861ca56dc09SJosh Triplett $prevline =~ /"\s*$/ && 1862ca56dc09SJosh Triplett $prevline =~ /\(/ && 1863ca56dc09SJosh Triplett $prevrawline !~ /\\n(?:\\t)*"\s*$/) { 1864ca56dc09SJosh Triplett WARN("SPLIT_STRING", 1865ca56dc09SJosh Triplett "quoted string split across lines\n" . $hereprev); 1866ca56dc09SJosh Triplett } 1867ca56dc09SJosh Triplett 18685e79d96eSJoe Perches# check for spaces before a quoted newline 18695e79d96eSJoe Perches if ($rawline =~ /^.*\".*\s\\n/) { 1870*3705ce5bSJoe Perches if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", 1871*3705ce5bSJoe Perches "unnecessary whitespace before a quoted newline\n" . $herecurr) && 1872*3705ce5bSJoe Perches $fix) { 1873*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ s/^(\+.*\".*)\s+\\n/$1\\n/; 1874*3705ce5bSJoe Perches } 1875*3705ce5bSJoe Perches 18765e79d96eSJoe Perches } 18775e79d96eSJoe Perches 18788905a67cSAndy Whitcroft# check for adding lines without a newline. 18798905a67cSAndy Whitcroft if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { 1880000d1cc1SJoe Perches WARN("MISSING_EOF_NEWLINE", 1881000d1cc1SJoe Perches "adding a line without newline at end of file\n" . $herecurr); 18828905a67cSAndy Whitcroft } 18838905a67cSAndy Whitcroft 188442e41c54SMike Frysinger# Blackfin: use hi/lo macros 188542e41c54SMike Frysinger if ($realfile =~ m@arch/blackfin/.*\.S$@) { 188642e41c54SMike Frysinger if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) { 188742e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 1888000d1cc1SJoe Perches ERROR("LO_MACRO", 1889000d1cc1SJoe Perches "use the LO() macro, not (... & 0xFFFF)\n" . $herevet); 189042e41c54SMike Frysinger } 189142e41c54SMike Frysinger if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) { 189242e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 1893000d1cc1SJoe Perches ERROR("HI_MACRO", 1894000d1cc1SJoe Perches "use the HI() macro, not (... >> 16)\n" . $herevet); 189542e41c54SMike Frysinger } 189642e41c54SMike Frysinger } 189742e41c54SMike Frysinger 1898b9ea10d6SAndy Whitcroft# check we are in a valid source file C or perl if not then ignore this hunk 1899b9ea10d6SAndy Whitcroft next if ($realfile !~ /\.(h|c|pl)$/); 19000a920b5bSAndy Whitcroft 19010a920b5bSAndy Whitcroft# at the beginning of a line any tabs must come first and anything 19020a920b5bSAndy Whitcroft# more than 8 must use tabs. 1903c2fdda0dSAndy Whitcroft if ($rawline =~ /^\+\s* \t\s*\S/ || 1904c2fdda0dSAndy Whitcroft $rawline =~ /^\+\s* \s*/) { 1905c2fdda0dSAndy Whitcroft my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1906d2c0a235SAndy Whitcroft $rpt_cleaners = 1; 1907*3705ce5bSJoe Perches if (ERROR("CODE_INDENT", 1908*3705ce5bSJoe Perches "code indent should use tabs where possible\n" . $herevet) && 1909*3705ce5bSJoe Perches $fix) { 1910*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 1911*3705ce5bSJoe Perches } 19120a920b5bSAndy Whitcroft } 19130a920b5bSAndy Whitcroft 191408e44365SAlberto Panizzo# check for space before tabs. 191508e44365SAlberto Panizzo if ($rawline =~ /^\+/ && $rawline =~ / \t/) { 191608e44365SAlberto Panizzo my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 1917*3705ce5bSJoe Perches if (WARN("SPACE_BEFORE_TAB", 1918*3705ce5bSJoe Perches "please, no space before tabs\n" . $herevet) && 1919*3705ce5bSJoe Perches $fix) { 1920*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ 1921*3705ce5bSJoe Perches s/(^\+.*) +\t/$1\t/; 1922*3705ce5bSJoe Perches } 192308e44365SAlberto Panizzo } 192408e44365SAlberto Panizzo 1925d1fe9c09SJoe Perches# check for && or || at the start of a line 1926d1fe9c09SJoe Perches if ($rawline =~ /^\+\s*(&&|\|\|)/) { 1927d1fe9c09SJoe Perches CHK("LOGICAL_CONTINUATIONS", 1928d1fe9c09SJoe Perches "Logical continuations should be on the previous line\n" . $hereprev); 1929d1fe9c09SJoe Perches } 1930d1fe9c09SJoe Perches 1931d1fe9c09SJoe Perches# check multi-line statement indentation matches previous line 1932d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 1933d1fe9c09SJoe Perches $prevline =~ /^\+(\t*)(if \(|$Ident\().*(\&\&|\|\||,)\s*$/) { 1934d1fe9c09SJoe Perches $prevline =~ /^\+(\t*)(.*)$/; 1935d1fe9c09SJoe Perches my $oldindent = $1; 1936d1fe9c09SJoe Perches my $rest = $2; 1937d1fe9c09SJoe Perches 1938d1fe9c09SJoe Perches my $pos = pos_last_openparen($rest); 1939d1fe9c09SJoe Perches if ($pos >= 0) { 1940b34a26f3SJoe Perches $line =~ /^(\+| )([ \t]*)/; 1941b34a26f3SJoe Perches my $newindent = $2; 1942d1fe9c09SJoe Perches 1943d1fe9c09SJoe Perches my $goodtabindent = $oldindent . 1944d1fe9c09SJoe Perches "\t" x ($pos / 8) . 1945d1fe9c09SJoe Perches " " x ($pos % 8); 1946d1fe9c09SJoe Perches my $goodspaceindent = $oldindent . " " x $pos; 1947d1fe9c09SJoe Perches 1948d1fe9c09SJoe Perches if ($newindent ne $goodtabindent && 1949d1fe9c09SJoe Perches $newindent ne $goodspaceindent) { 1950*3705ce5bSJoe Perches 1951*3705ce5bSJoe Perches if (CHK("PARENTHESIS_ALIGNMENT", 1952*3705ce5bSJoe Perches "Alignment should match open parenthesis\n" . $hereprev) && 1953*3705ce5bSJoe Perches $fix && $line =~ /^\+/) { 1954*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ 1955*3705ce5bSJoe Perches s/^\+[ \t]*/\+$goodtabindent/; 1956*3705ce5bSJoe Perches } 1957d1fe9c09SJoe Perches } 1958d1fe9c09SJoe Perches } 1959d1fe9c09SJoe Perches } 1960d1fe9c09SJoe Perches 196123f780c9SJoe Perches if ($line =~ /^\+.*\*[ \t]*\)[ \t]+(?!$Assignment|$Arithmetic)/) { 1962*3705ce5bSJoe Perches if (CHK("SPACING", 1963*3705ce5bSJoe Perches "No space is necessary after a cast\n" . $hereprev) && 1964*3705ce5bSJoe Perches $fix) { 1965*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ 1966*3705ce5bSJoe Perches s/^(\+.*\*[ \t]*\))[ \t]+/$1/; 1967*3705ce5bSJoe Perches } 1968aad4f614SJoe Perches } 1969aad4f614SJoe Perches 197005880600SJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 1971fdb4bcd6SJoe Perches $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ && 1972fdb4bcd6SJoe Perches $rawline =~ /^\+[ \t]*\*/) { 197305880600SJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 197405880600SJoe Perches "networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev); 197505880600SJoe Perches } 197605880600SJoe Perches 197705880600SJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 1978a605e32eSJoe Perches $prevrawline =~ /^\+[ \t]*\/\*/ && #starting /* 1979a605e32eSJoe Perches $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */ 1980a605e32eSJoe Perches $rawline !~ /^\+[ \t]*\*/) { #no leading * 1981a605e32eSJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 1982a605e32eSJoe Perches "networking block comments start with * on subsequent lines\n" . $hereprev); 1983a605e32eSJoe Perches } 1984a605e32eSJoe Perches 1985a605e32eSJoe Perches if ($realfile =~ m@^(drivers/net/|net/)@ && 1986c24f9f19SJoe Perches $rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */ 1987c24f9f19SJoe Perches $rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/ 1988c24f9f19SJoe Perches $rawline !~ m@^\+.*\*{2,}/[ \t]*$@ && #trailing **/ 1989c24f9f19SJoe Perches $rawline =~ m@^\+[ \t]*.+\*\/[ \t]*$@) { #non blank */ 199005880600SJoe Perches WARN("NETWORKING_BLOCK_COMMENT_STYLE", 199105880600SJoe Perches "networking block comments put the trailing */ on a separate line\n" . $herecurr); 199205880600SJoe Perches } 199305880600SJoe Perches 19945f7ddae6SRaffaele Recalcati# check for spaces at the beginning of a line. 19956b4c5bebSAndy Whitcroft# Exceptions: 19966b4c5bebSAndy Whitcroft# 1) within comments 19976b4c5bebSAndy Whitcroft# 2) indented preprocessor commands 19986b4c5bebSAndy Whitcroft# 3) hanging labels 1999*3705ce5bSJoe Perches if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) { 20005f7ddae6SRaffaele Recalcati my $herevet = "$here\n" . cat_vet($rawline) . "\n"; 2001*3705ce5bSJoe Perches if (WARN("LEADING_SPACE", 2002*3705ce5bSJoe Perches "please, no spaces at the start of a line\n" . $herevet) && 2003*3705ce5bSJoe Perches $fix) { 2004*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e; 2005*3705ce5bSJoe Perches } 20065f7ddae6SRaffaele Recalcati } 20075f7ddae6SRaffaele Recalcati 2008b9ea10d6SAndy Whitcroft# check we are in a valid C source file if not then ignore this hunk 2009b9ea10d6SAndy Whitcroft next if ($realfile !~ /\.(h|c)$/); 2010b9ea10d6SAndy Whitcroft 20111ba8dfd1SKees Cook# discourage the addition of CONFIG_EXPERIMENTAL in #if(def). 20121ba8dfd1SKees Cook if ($line =~ /^\+\s*\#\s*if.*\bCONFIG_EXPERIMENTAL\b/) { 20131ba8dfd1SKees Cook WARN("CONFIG_EXPERIMENTAL", 20141ba8dfd1SKees Cook "Use of CONFIG_EXPERIMENTAL is deprecated. For alternatives, see https://lkml.org/lkml/2012/10/23/580\n"); 20151ba8dfd1SKees Cook } 20161ba8dfd1SKees Cook 2017c2fdda0dSAndy Whitcroft# check for RCS/CVS revision markers 2018cf655043SAndy Whitcroft if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { 2019000d1cc1SJoe Perches WARN("CVS_KEYWORD", 2020000d1cc1SJoe Perches "CVS style keyword markers, these will _not_ be updated\n". $herecurr); 2021c2fdda0dSAndy Whitcroft } 202222f2a2efSAndy Whitcroft 202342e41c54SMike Frysinger# Blackfin: don't use __builtin_bfin_[cs]sync 202442e41c54SMike Frysinger if ($line =~ /__builtin_bfin_csync/) { 202542e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 2026000d1cc1SJoe Perches ERROR("CSYNC", 2027000d1cc1SJoe Perches "use the CSYNC() macro in asm/blackfin.h\n" . $herevet); 202842e41c54SMike Frysinger } 202942e41c54SMike Frysinger if ($line =~ /__builtin_bfin_ssync/) { 203042e41c54SMike Frysinger my $herevet = "$here\n" . cat_vet($line) . "\n"; 2031000d1cc1SJoe Perches ERROR("SSYNC", 2032000d1cc1SJoe Perches "use the SSYNC() macro in asm/blackfin.h\n" . $herevet); 203342e41c54SMike Frysinger } 203442e41c54SMike Frysinger 203556e77d70SJoe Perches# check for old HOTPLUG __dev<foo> section markings 203656e77d70SJoe Perches if ($line =~ /\b(__dev(init|exit)(data|const|))\b/) { 203756e77d70SJoe Perches WARN("HOTPLUG_SECTION", 203856e77d70SJoe Perches "Using $1 is unnecessary\n" . $herecurr); 203956e77d70SJoe Perches } 204056e77d70SJoe Perches 20419c0ca6f9SAndy Whitcroft# Check for potential 'bare' types 20422b474a1aSAndy Whitcroft my ($stat, $cond, $line_nr_next, $remain_next, $off_next, 20432b474a1aSAndy Whitcroft $realline_next); 20443e469cdcSAndy Whitcroft#print "LINE<$line>\n"; 20453e469cdcSAndy Whitcroft if ($linenr >= $suppress_statement && 20463e469cdcSAndy Whitcroft $realcnt && $line =~ /.\s*\S/) { 2047170d3a22SAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 2048f5fe35ddSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 2049171ae1a4SAndy Whitcroft $stat =~ s/\n./\n /g; 2050171ae1a4SAndy Whitcroft $cond =~ s/\n./\n /g; 2051171ae1a4SAndy Whitcroft 20523e469cdcSAndy Whitcroft#print "linenr<$linenr> <$stat>\n"; 20533e469cdcSAndy Whitcroft # If this statement has no statement boundaries within 20543e469cdcSAndy Whitcroft # it there is no point in retrying a statement scan 20553e469cdcSAndy Whitcroft # until we hit end of it. 20563e469cdcSAndy Whitcroft my $frag = $stat; $frag =~ s/;+\s*$//; 20573e469cdcSAndy Whitcroft if ($frag !~ /(?:{|;)/) { 20583e469cdcSAndy Whitcroft#print "skip<$line_nr_next>\n"; 20593e469cdcSAndy Whitcroft $suppress_statement = $line_nr_next; 20603e469cdcSAndy Whitcroft } 2061f74bd194SAndy Whitcroft 20622b474a1aSAndy Whitcroft # Find the real next line. 20632b474a1aSAndy Whitcroft $realline_next = $line_nr_next; 20642b474a1aSAndy Whitcroft if (defined $realline_next && 20652b474a1aSAndy Whitcroft (!defined $lines[$realline_next - 1] || 20662b474a1aSAndy Whitcroft substr($lines[$realline_next - 1], $off_next) =~ /^\s*$/)) { 20672b474a1aSAndy Whitcroft $realline_next++; 20682b474a1aSAndy Whitcroft } 20692b474a1aSAndy Whitcroft 2070171ae1a4SAndy Whitcroft my $s = $stat; 2071171ae1a4SAndy Whitcroft $s =~ s/{.*$//s; 2072cf655043SAndy Whitcroft 2073c2fdda0dSAndy Whitcroft # Ignore goto labels. 2074171ae1a4SAndy Whitcroft if ($s =~ /$Ident:\*$/s) { 2075c2fdda0dSAndy Whitcroft 2076c2fdda0dSAndy Whitcroft # Ignore functions being called 2077171ae1a4SAndy Whitcroft } elsif ($s =~ /^.\s*$Ident\s*\(/s) { 2078c2fdda0dSAndy Whitcroft 2079463f2864SAndy Whitcroft } elsif ($s =~ /^.\s*else\b/s) { 2080463f2864SAndy Whitcroft 2081c45dcabdSAndy Whitcroft # declarations always start with types 2082d2506586SAndy Whitcroft } elsif ($prev_values eq 'E' && $s =~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?((?:\s*$Ident)+?)\b(?:\s+$Sparse)?\s*\**\s*(?:$Ident|\(\*[^\)]*\))(?:\s*$Modifier)?\s*(?:;|=|,|\()/s) { 2083c45dcabdSAndy Whitcroft my $type = $1; 2084c45dcabdSAndy Whitcroft $type =~ s/\s+/ /g; 2085c45dcabdSAndy Whitcroft possible($type, "A:" . $s); 2086c45dcabdSAndy Whitcroft 20876c72ffaaSAndy Whitcroft # definitions in global scope can only start with types 2088a6a84062SAndy Whitcroft } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) { 2089c45dcabdSAndy Whitcroft possible($1, "B:" . $s); 2090c2fdda0dSAndy Whitcroft } 20918905a67cSAndy Whitcroft 20926c72ffaaSAndy Whitcroft # any (foo ... *) is a pointer cast, and foo is a type 209365863862SAndy Whitcroft while ($s =~ /\(($Ident)(?:\s+$Sparse)*[\s\*]+\s*\)/sg) { 2094c45dcabdSAndy Whitcroft possible($1, "C:" . $s); 20959c0ca6f9SAndy Whitcroft } 20968905a67cSAndy Whitcroft 20978905a67cSAndy Whitcroft # Check for any sort of function declaration. 20988905a67cSAndy Whitcroft # int foo(something bar, other baz); 20998905a67cSAndy Whitcroft # void (*store_gdt)(x86_descr_ptr *); 2100171ae1a4SAndy Whitcroft if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/s) { 21018905a67cSAndy Whitcroft my ($name_len) = length($1); 21028905a67cSAndy Whitcroft 2103cf655043SAndy Whitcroft my $ctx = $s; 2104773647a0SAndy Whitcroft substr($ctx, 0, $name_len + 1, ''); 21058905a67cSAndy Whitcroft $ctx =~ s/\)[^\)]*$//; 2106cf655043SAndy Whitcroft 21078905a67cSAndy Whitcroft for my $arg (split(/\s*,\s*/, $ctx)) { 2108c45dcabdSAndy Whitcroft if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { 21098905a67cSAndy Whitcroft 2110c45dcabdSAndy Whitcroft possible($1, "D:" . $s); 21118905a67cSAndy Whitcroft } 21128905a67cSAndy Whitcroft } 21138905a67cSAndy Whitcroft } 21148905a67cSAndy Whitcroft 21159c0ca6f9SAndy Whitcroft } 21169c0ca6f9SAndy Whitcroft 211700df344fSAndy Whitcroft# 211800df344fSAndy Whitcroft# Checks which may be anchored in the context. 211900df344fSAndy Whitcroft# 212000df344fSAndy Whitcroft 212100df344fSAndy Whitcroft# Check for switch () and associated case and default 212200df344fSAndy Whitcroft# statements should be at the same indent. 212300df344fSAndy Whitcroft if ($line=~/\bswitch\s*\(.*\)/) { 212400df344fSAndy Whitcroft my $err = ''; 212500df344fSAndy Whitcroft my $sep = ''; 212600df344fSAndy Whitcroft my @ctx = ctx_block_outer($linenr, $realcnt); 212700df344fSAndy Whitcroft shift(@ctx); 212800df344fSAndy Whitcroft for my $ctx (@ctx) { 212900df344fSAndy Whitcroft my ($clen, $cindent) = line_stats($ctx); 213000df344fSAndy Whitcroft if ($ctx =~ /^\+\s*(case\s+|default:)/ && 213100df344fSAndy Whitcroft $indent != $cindent) { 213200df344fSAndy Whitcroft $err .= "$sep$ctx\n"; 213300df344fSAndy Whitcroft $sep = ''; 213400df344fSAndy Whitcroft } else { 213500df344fSAndy Whitcroft $sep = "[...]\n"; 213600df344fSAndy Whitcroft } 213700df344fSAndy Whitcroft } 213800df344fSAndy Whitcroft if ($err ne '') { 2139000d1cc1SJoe Perches ERROR("SWITCH_CASE_INDENT_LEVEL", 2140000d1cc1SJoe Perches "switch and case should be at the same indent\n$hereline$err"); 2141de7d4f0eSAndy Whitcroft } 2142de7d4f0eSAndy Whitcroft } 2143de7d4f0eSAndy Whitcroft 2144de7d4f0eSAndy Whitcroft# if/while/etc brace do not go on next line, unless defining a do while loop, 2145de7d4f0eSAndy Whitcroft# or if that brace on the next line is for something else 2146c45dcabdSAndy Whitcroft if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { 2147773647a0SAndy Whitcroft my $pre_ctx = "$1$2"; 2148773647a0SAndy Whitcroft 21499c0ca6f9SAndy Whitcroft my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); 21508eef05ddSJoe Perches 21518eef05ddSJoe Perches if ($line =~ /^\+\t{6,}/) { 21528eef05ddSJoe Perches WARN("DEEP_INDENTATION", 21538eef05ddSJoe Perches "Too many leading tabs - consider code refactoring\n" . $herecurr); 21548eef05ddSJoe Perches } 21558eef05ddSJoe Perches 2156de7d4f0eSAndy Whitcroft my $ctx_cnt = $realcnt - $#ctx - 1; 2157de7d4f0eSAndy Whitcroft my $ctx = join("\n", @ctx); 2158de7d4f0eSAndy Whitcroft 2159548596d5SAndy Whitcroft my $ctx_ln = $linenr; 2160548596d5SAndy Whitcroft my $ctx_skip = $realcnt; 2161de7d4f0eSAndy Whitcroft 2162548596d5SAndy Whitcroft while ($ctx_skip > $ctx_cnt || ($ctx_skip == $ctx_cnt && 2163548596d5SAndy Whitcroft defined $lines[$ctx_ln - 1] && 2164548596d5SAndy Whitcroft $lines[$ctx_ln - 1] =~ /^-/)) { 2165548596d5SAndy Whitcroft ##print "SKIP<$ctx_skip> CNT<$ctx_cnt>\n"; 2166548596d5SAndy Whitcroft $ctx_skip-- if (!defined $lines[$ctx_ln - 1] || $lines[$ctx_ln - 1] !~ /^-/); 2167773647a0SAndy Whitcroft $ctx_ln++; 2168773647a0SAndy Whitcroft } 2169548596d5SAndy Whitcroft 217053210168SAndy Whitcroft #print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n"; 217153210168SAndy Whitcroft #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; 2172773647a0SAndy Whitcroft 2173773647a0SAndy Whitcroft if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { 2174000d1cc1SJoe Perches ERROR("OPEN_BRACE", 2175000d1cc1SJoe Perches "that open brace { should be on the previous line\n" . 217601464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 217700df344fSAndy Whitcroft } 2178773647a0SAndy Whitcroft if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && 2179773647a0SAndy Whitcroft $ctx =~ /\)\s*\;\s*$/ && 2180773647a0SAndy Whitcroft defined $lines[$ctx_ln - 1]) 2181773647a0SAndy Whitcroft { 21829c0ca6f9SAndy Whitcroft my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); 21839c0ca6f9SAndy Whitcroft if ($nindent > $indent) { 2184000d1cc1SJoe Perches WARN("TRAILING_SEMICOLON", 2185000d1cc1SJoe Perches "trailing semicolon indicates no statements, indent implies otherwise\n" . 218601464f30SAndy Whitcroft "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); 21879c0ca6f9SAndy Whitcroft } 21889c0ca6f9SAndy Whitcroft } 218900df344fSAndy Whitcroft } 219000df344fSAndy Whitcroft 21914d001e4dSAndy Whitcroft# Check relative indent for conditionals and blocks. 21924d001e4dSAndy Whitcroft if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) { 21933e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 21943e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 21953e469cdcSAndy Whitcroft if (!defined $stat); 21964d001e4dSAndy Whitcroft my ($s, $c) = ($stat, $cond); 21974d001e4dSAndy Whitcroft 21984d001e4dSAndy Whitcroft substr($s, 0, length($c), ''); 21994d001e4dSAndy Whitcroft 22004d001e4dSAndy Whitcroft # Make sure we remove the line prefixes as we have 22014d001e4dSAndy Whitcroft # none on the first line, and are going to readd them 22024d001e4dSAndy Whitcroft # where necessary. 22034d001e4dSAndy Whitcroft $s =~ s/\n./\n/gs; 22044d001e4dSAndy Whitcroft 22054d001e4dSAndy Whitcroft # Find out how long the conditional actually is. 22066f779c18SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 22076f779c18SAndy Whitcroft my $cond_lines = 1 + $#newlines; 22084d001e4dSAndy Whitcroft 22094d001e4dSAndy Whitcroft # We want to check the first line inside the block 22104d001e4dSAndy Whitcroft # starting at the end of the conditional, so remove: 22114d001e4dSAndy Whitcroft # 1) any blank line termination 22124d001e4dSAndy Whitcroft # 2) any opening brace { on end of the line 22134d001e4dSAndy Whitcroft # 3) any do (...) { 22144d001e4dSAndy Whitcroft my $continuation = 0; 22154d001e4dSAndy Whitcroft my $check = 0; 22164d001e4dSAndy Whitcroft $s =~ s/^.*\bdo\b//; 22174d001e4dSAndy Whitcroft $s =~ s/^\s*{//; 22184d001e4dSAndy Whitcroft if ($s =~ s/^\s*\\//) { 22194d001e4dSAndy Whitcroft $continuation = 1; 22204d001e4dSAndy Whitcroft } 22219bd49efeSAndy Whitcroft if ($s =~ s/^\s*?\n//) { 22224d001e4dSAndy Whitcroft $check = 1; 22234d001e4dSAndy Whitcroft $cond_lines++; 22244d001e4dSAndy Whitcroft } 22254d001e4dSAndy Whitcroft 22264d001e4dSAndy Whitcroft # Also ignore a loop construct at the end of a 22274d001e4dSAndy Whitcroft # preprocessor statement. 22284d001e4dSAndy Whitcroft if (($prevline =~ /^.\s*#\s*define\s/ || 22294d001e4dSAndy Whitcroft $prevline =~ /\\\s*$/) && $continuation == 0) { 22304d001e4dSAndy Whitcroft $check = 0; 22314d001e4dSAndy Whitcroft } 22324d001e4dSAndy Whitcroft 22339bd49efeSAndy Whitcroft my $cond_ptr = -1; 2234740504c6SAndy Whitcroft $continuation = 0; 22359bd49efeSAndy Whitcroft while ($cond_ptr != $cond_lines) { 22369bd49efeSAndy Whitcroft $cond_ptr = $cond_lines; 22374d001e4dSAndy Whitcroft 2238f16fa28fSAndy Whitcroft # If we see an #else/#elif then the code 2239f16fa28fSAndy Whitcroft # is not linear. 2240f16fa28fSAndy Whitcroft if ($s =~ /^\s*\#\s*(?:else|elif)/) { 2241f16fa28fSAndy Whitcroft $check = 0; 2242f16fa28fSAndy Whitcroft } 2243f16fa28fSAndy Whitcroft 22449bd49efeSAndy Whitcroft # Ignore: 22459bd49efeSAndy Whitcroft # 1) blank lines, they should be at 0, 22469bd49efeSAndy Whitcroft # 2) preprocessor lines, and 22479bd49efeSAndy Whitcroft # 3) labels. 2248740504c6SAndy Whitcroft if ($continuation || 2249740504c6SAndy Whitcroft $s =~ /^\s*?\n/ || 22509bd49efeSAndy Whitcroft $s =~ /^\s*#\s*?/ || 22519bd49efeSAndy Whitcroft $s =~ /^\s*$Ident\s*:/) { 2252740504c6SAndy Whitcroft $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0; 225330dad6ebSAndy Whitcroft if ($s =~ s/^.*?\n//) { 22549bd49efeSAndy Whitcroft $cond_lines++; 22559bd49efeSAndy Whitcroft } 22564d001e4dSAndy Whitcroft } 225730dad6ebSAndy Whitcroft } 22584d001e4dSAndy Whitcroft 22594d001e4dSAndy Whitcroft my (undef, $sindent) = line_stats("+" . $s); 22604d001e4dSAndy Whitcroft my $stat_real = raw_line($linenr, $cond_lines); 22614d001e4dSAndy Whitcroft 22624d001e4dSAndy Whitcroft # Check if either of these lines are modified, else 22634d001e4dSAndy Whitcroft # this is not this patch's fault. 22644d001e4dSAndy Whitcroft if (!defined($stat_real) || 22654d001e4dSAndy Whitcroft $stat !~ /^\+/ && $stat_real !~ /^\+/) { 22664d001e4dSAndy Whitcroft $check = 0; 22674d001e4dSAndy Whitcroft } 22684d001e4dSAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 22694d001e4dSAndy Whitcroft $stat_real = "[...]\n$stat_real"; 22704d001e4dSAndy Whitcroft } 22714d001e4dSAndy Whitcroft 22729bd49efeSAndy Whitcroft #print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n"; 22734d001e4dSAndy Whitcroft 22744d001e4dSAndy Whitcroft if ($check && (($sindent % 8) != 0 || 22754d001e4dSAndy Whitcroft ($sindent <= $indent && $s ne ''))) { 2276000d1cc1SJoe Perches WARN("SUSPECT_CODE_INDENT", 2277000d1cc1SJoe Perches "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); 22784d001e4dSAndy Whitcroft } 22794d001e4dSAndy Whitcroft } 22804d001e4dSAndy Whitcroft 22816c72ffaaSAndy Whitcroft # Track the 'values' across context and added lines. 22826c72ffaaSAndy Whitcroft my $opline = $line; $opline =~ s/^./ /; 22831f65f947SAndy Whitcroft my ($curr_values, $curr_vars) = 22841f65f947SAndy Whitcroft annotate_values($opline . "\n", $prev_values); 22856c72ffaaSAndy Whitcroft $curr_values = $prev_values . $curr_values; 2286c2fdda0dSAndy Whitcroft if ($dbg_values) { 2287c2fdda0dSAndy Whitcroft my $outline = $opline; $outline =~ s/\t/ /g; 2288cf655043SAndy Whitcroft print "$linenr > .$outline\n"; 2289cf655043SAndy Whitcroft print "$linenr > $curr_values\n"; 22901f65f947SAndy Whitcroft print "$linenr > $curr_vars\n"; 2291c2fdda0dSAndy Whitcroft } 22926c72ffaaSAndy Whitcroft $prev_values = substr($curr_values, -1); 22936c72ffaaSAndy Whitcroft 229400df344fSAndy Whitcroft#ignore lines not being added 2295*3705ce5bSJoe Perches next if ($line =~ /^[^\+]/); 229600df344fSAndy Whitcroft 2297653d4876SAndy Whitcroft# TEST: allow direct testing of the type matcher. 22987429c690SAndy Whitcroft if ($dbg_type) { 22997429c690SAndy Whitcroft if ($line =~ /^.\s*$Declare\s*$/) { 2300000d1cc1SJoe Perches ERROR("TEST_TYPE", 2301000d1cc1SJoe Perches "TEST: is type\n" . $herecurr); 23027429c690SAndy Whitcroft } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { 2303000d1cc1SJoe Perches ERROR("TEST_NOT_TYPE", 2304000d1cc1SJoe Perches "TEST: is not type ($1 is)\n". $herecurr); 23057429c690SAndy Whitcroft } 2306653d4876SAndy Whitcroft next; 2307653d4876SAndy Whitcroft } 2308a1ef277eSAndy Whitcroft# TEST: allow direct testing of the attribute matcher. 2309a1ef277eSAndy Whitcroft if ($dbg_attr) { 23109360b0e5SAndy Whitcroft if ($line =~ /^.\s*$Modifier\s*$/) { 2311000d1cc1SJoe Perches ERROR("TEST_ATTR", 2312000d1cc1SJoe Perches "TEST: is attr\n" . $herecurr); 23139360b0e5SAndy Whitcroft } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { 2314000d1cc1SJoe Perches ERROR("TEST_NOT_ATTR", 2315000d1cc1SJoe Perches "TEST: is not attr ($1 is)\n". $herecurr); 2316a1ef277eSAndy Whitcroft } 2317a1ef277eSAndy Whitcroft next; 2318a1ef277eSAndy Whitcroft } 2319653d4876SAndy Whitcroft 2320f0a594c1SAndy Whitcroft# check for initialisation to aggregates open brace on the next line 232199423c20SAndy Whitcroft if ($line =~ /^.\s*{/ && 232299423c20SAndy Whitcroft $prevline =~ /(?:^|[^=])=\s*$/) { 2323000d1cc1SJoe Perches ERROR("OPEN_BRACE", 2324000d1cc1SJoe Perches "that open brace { should be on the previous line\n" . $hereprev); 2325f0a594c1SAndy Whitcroft } 2326f0a594c1SAndy Whitcroft 232700df344fSAndy Whitcroft# 232800df344fSAndy Whitcroft# Checks which are anchored on the added line. 232900df344fSAndy Whitcroft# 233000df344fSAndy Whitcroft 2331653d4876SAndy Whitcroft# check for malformed paths in #include statements (uses RAW line) 2332c45dcabdSAndy Whitcroft if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { 2333653d4876SAndy Whitcroft my $path = $1; 2334653d4876SAndy Whitcroft if ($path =~ m{//}) { 2335000d1cc1SJoe Perches ERROR("MALFORMED_INCLUDE", 2336495e9d84SJoe Perches "malformed #include filename\n" . $herecurr); 2337495e9d84SJoe Perches } 2338495e9d84SJoe Perches if ($path =~ "^uapi/" && $realfile =~ m@\binclude/uapi/@) { 2339495e9d84SJoe Perches ERROR("UAPI_INCLUDE", 2340495e9d84SJoe Perches "No #include in ...include/uapi/... should use a uapi/ path prefix\n" . $herecurr); 2341653d4876SAndy Whitcroft } 2342653d4876SAndy Whitcroft } 2343653d4876SAndy Whitcroft 234400df344fSAndy Whitcroft# no C99 // comments 234500df344fSAndy Whitcroft if ($line =~ m{//}) { 2346*3705ce5bSJoe Perches if (ERROR("C99_COMMENTS", 2347*3705ce5bSJoe Perches "do not use C99 // comments\n" . $herecurr) && 2348*3705ce5bSJoe Perches $fix) { 2349*3705ce5bSJoe Perches my $line = $fixed[$linenr - 1]; 2350*3705ce5bSJoe Perches if ($line =~ /\/\/(.*)$/) { 2351*3705ce5bSJoe Perches my $comment = trim($1); 2352*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ s@\/\/(.*)$@/\* $comment \*/@; 2353*3705ce5bSJoe Perches } 2354*3705ce5bSJoe Perches } 235500df344fSAndy Whitcroft } 235600df344fSAndy Whitcroft # Remove C99 comments. 23570a920b5bSAndy Whitcroft $line =~ s@//.*@@; 23586c72ffaaSAndy Whitcroft $opline =~ s@//.*@@; 23590a920b5bSAndy Whitcroft 23602b474a1aSAndy Whitcroft# EXPORT_SYMBOL should immediately follow the thing it is exporting, consider 23612b474a1aSAndy Whitcroft# the whole statement. 23622b474a1aSAndy Whitcroft#print "APW <$lines[$realline_next - 1]>\n"; 23632b474a1aSAndy Whitcroft if (defined $realline_next && 23642b474a1aSAndy Whitcroft exists $lines[$realline_next - 1] && 23652b474a1aSAndy Whitcroft !defined $suppress_export{$realline_next} && 23662b474a1aSAndy Whitcroft ($lines[$realline_next - 1] =~ /EXPORT_SYMBOL.*\((.*)\)/ || 23672b474a1aSAndy Whitcroft $lines[$realline_next - 1] =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 23683cbf62dfSAndy Whitcroft # Handle definitions which produce identifiers with 23693cbf62dfSAndy Whitcroft # a prefix: 23703cbf62dfSAndy Whitcroft # XXX(foo); 23713cbf62dfSAndy Whitcroft # EXPORT_SYMBOL(something_foo); 2372653d4876SAndy Whitcroft my $name = $1; 237387a53877SAndy Whitcroft if ($stat =~ /^(?:.\s*}\s*\n)?.([A-Z_]+)\s*\(\s*($Ident)/ && 23743cbf62dfSAndy Whitcroft $name =~ /^${Ident}_$2/) { 23753cbf62dfSAndy Whitcroft#print "FOO C name<$name>\n"; 23763cbf62dfSAndy Whitcroft $suppress_export{$realline_next} = 1; 23773cbf62dfSAndy Whitcroft 23783cbf62dfSAndy Whitcroft } elsif ($stat !~ /(?: 23792b474a1aSAndy Whitcroft \n.}\s*$| 238048012058SAndy Whitcroft ^.DEFINE_$Ident\(\Q$name\E\)| 238148012058SAndy Whitcroft ^.DECLARE_$Ident\(\Q$name\E\)| 238248012058SAndy Whitcroft ^.LIST_HEAD\(\Q$name\E\)| 23832b474a1aSAndy Whitcroft ^.(?:$Storage\s+)?$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(| 23842b474a1aSAndy Whitcroft \b\Q$name\E(?:\s+$Attribute)*\s*(?:;|=|\[|\() 238548012058SAndy Whitcroft )/x) { 23862b474a1aSAndy Whitcroft#print "FOO A<$lines[$realline_next - 1]> stat<$stat> name<$name>\n"; 23872b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 2; 23882b474a1aSAndy Whitcroft } else { 23892b474a1aSAndy Whitcroft $suppress_export{$realline_next} = 1; 23900a920b5bSAndy Whitcroft } 23910a920b5bSAndy Whitcroft } 23922b474a1aSAndy Whitcroft if (!defined $suppress_export{$linenr} && 23932b474a1aSAndy Whitcroft $prevline =~ /^.\s*$/ && 23942b474a1aSAndy Whitcroft ($line =~ /EXPORT_SYMBOL.*\((.*)\)/ || 23952b474a1aSAndy Whitcroft $line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) { 23962b474a1aSAndy Whitcroft#print "FOO B <$lines[$linenr - 1]>\n"; 23972b474a1aSAndy Whitcroft $suppress_export{$linenr} = 2; 23982b474a1aSAndy Whitcroft } 23992b474a1aSAndy Whitcroft if (defined $suppress_export{$linenr} && 24002b474a1aSAndy Whitcroft $suppress_export{$linenr} == 2) { 2401000d1cc1SJoe Perches WARN("EXPORT_SYMBOL", 2402000d1cc1SJoe Perches "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); 24032b474a1aSAndy Whitcroft } 24040a920b5bSAndy Whitcroft 24055150bda4SJoe Eloff# check for global initialisers. 2406c45dcabdSAndy Whitcroft if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) { 2407000d1cc1SJoe Perches ERROR("GLOBAL_INITIALISERS", 2408000d1cc1SJoe Perches "do not initialise globals to 0 or NULL\n" . 2409f0a594c1SAndy Whitcroft $herecurr); 2410f0a594c1SAndy Whitcroft } 24110a920b5bSAndy Whitcroft# check for static initialisers. 24122d1bafd7SAndy Whitcroft if ($line =~ /\bstatic\s.*=\s*(0|NULL|false)\s*;/) { 2413000d1cc1SJoe Perches ERROR("INITIALISED_STATIC", 2414000d1cc1SJoe Perches "do not initialise statics to 0 or NULL\n" . 2415de7d4f0eSAndy Whitcroft $herecurr); 24160a920b5bSAndy Whitcroft } 24170a920b5bSAndy Whitcroft 2418cb710ecaSJoe Perches# check for static const char * arrays. 2419cb710ecaSJoe Perches if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { 2420000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 2421000d1cc1SJoe Perches "static const char * array should probably be static const char * const\n" . 2422cb710ecaSJoe Perches $herecurr); 2423cb710ecaSJoe Perches } 2424cb710ecaSJoe Perches 2425cb710ecaSJoe Perches# check for static char foo[] = "bar" declarations. 2426cb710ecaSJoe Perches if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { 2427000d1cc1SJoe Perches WARN("STATIC_CONST_CHAR_ARRAY", 2428000d1cc1SJoe Perches "static char array declaration should probably be static const char\n" . 2429cb710ecaSJoe Perches $herecurr); 2430cb710ecaSJoe Perches } 2431cb710ecaSJoe Perches 243293ed0e2dSJoe Perches# check for declarations of struct pci_device_id 243393ed0e2dSJoe Perches if ($line =~ /\bstruct\s+pci_device_id\s+\w+\s*\[\s*\]\s*\=\s*\{/) { 2434000d1cc1SJoe Perches WARN("DEFINE_PCI_DEVICE_TABLE", 2435000d1cc1SJoe Perches "Use DEFINE_PCI_DEVICE_TABLE for struct pci_device_id\n" . $herecurr); 243693ed0e2dSJoe Perches } 243793ed0e2dSJoe Perches 2438653d4876SAndy Whitcroft# check for new typedefs, only function parameters and sparse annotations 2439653d4876SAndy Whitcroft# make sense. 2440653d4876SAndy Whitcroft if ($line =~ /\btypedef\s/ && 24418054576dSAndy Whitcroft $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && 2442c45dcabdSAndy Whitcroft $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && 24438ed22cadSAndy Whitcroft $line !~ /\b$typeTypedefs\b/ && 2444653d4876SAndy Whitcroft $line !~ /\b__bitwise(?:__|)\b/) { 2445000d1cc1SJoe Perches WARN("NEW_TYPEDEFS", 2446000d1cc1SJoe Perches "do not add new typedefs\n" . $herecurr); 24470a920b5bSAndy Whitcroft } 24480a920b5bSAndy Whitcroft 24490a920b5bSAndy Whitcroft# * goes on variable not on type 245065863862SAndy Whitcroft # (char*[ const]) 2451bfcb2cc7SAndy Whitcroft while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) { 2452bfcb2cc7SAndy Whitcroft #print "AA<$1>\n"; 2453*3705ce5bSJoe Perches my ($ident, $from, $to) = ($1, $2, $2); 2454d8aaf121SAndy Whitcroft 245565863862SAndy Whitcroft # Should start with a space. 245665863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 245765863862SAndy Whitcroft # Should not end with a space. 245865863862SAndy Whitcroft $to =~ s/\s+$//; 245965863862SAndy Whitcroft # '*'s should not have spaces between. 2460f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 246165863862SAndy Whitcroft } 2462d8aaf121SAndy Whitcroft 2463*3705ce5bSJoe Perches## print "1: from<$from> to<$to> ident<$ident>\n"; 246465863862SAndy Whitcroft if ($from ne $to) { 2465*3705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 2466*3705ce5bSJoe Perches "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) && 2467*3705ce5bSJoe Perches $fix) { 2468*3705ce5bSJoe Perches my $sub_from = $ident; 2469*3705ce5bSJoe Perches my $sub_to = $ident; 2470*3705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 2471*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ 2472*3705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 2473*3705ce5bSJoe Perches } 247465863862SAndy Whitcroft } 2475bfcb2cc7SAndy Whitcroft } 2476bfcb2cc7SAndy Whitcroft while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) { 2477bfcb2cc7SAndy Whitcroft #print "BB<$1>\n"; 2478*3705ce5bSJoe Perches my ($match, $from, $to, $ident) = ($1, $2, $2, $3); 2479d8aaf121SAndy Whitcroft 248065863862SAndy Whitcroft # Should start with a space. 248165863862SAndy Whitcroft $to =~ s/^(\S)/ $1/; 248265863862SAndy Whitcroft # Should not end with a space. 248365863862SAndy Whitcroft $to =~ s/\s+$//; 248465863862SAndy Whitcroft # '*'s should not have spaces between. 2485f9a0b3d1SAndy Whitcroft while ($to =~ s/\*\s+\*/\*\*/) { 248665863862SAndy Whitcroft } 248765863862SAndy Whitcroft # Modifiers should have spaces. 248865863862SAndy Whitcroft $to =~ s/(\b$Modifier$)/$1 /; 248965863862SAndy Whitcroft 2490*3705ce5bSJoe Perches## print "2: from<$from> to<$to> ident<$ident>\n"; 2491667026e7SAndy Whitcroft if ($from ne $to && $ident !~ /^$Modifier$/) { 2492*3705ce5bSJoe Perches if (ERROR("POINTER_LOCATION", 2493*3705ce5bSJoe Perches "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) && 2494*3705ce5bSJoe Perches $fix) { 2495*3705ce5bSJoe Perches 2496*3705ce5bSJoe Perches my $sub_from = $match; 2497*3705ce5bSJoe Perches my $sub_to = $match; 2498*3705ce5bSJoe Perches $sub_to =~ s/\Q$from\E/$to/; 2499*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ 2500*3705ce5bSJoe Perches s@\Q$sub_from\E@$sub_to@; 2501*3705ce5bSJoe Perches } 250265863862SAndy Whitcroft } 25030a920b5bSAndy Whitcroft } 25040a920b5bSAndy Whitcroft 25050a920b5bSAndy Whitcroft# # no BUG() or BUG_ON() 25060a920b5bSAndy Whitcroft# if ($line =~ /\b(BUG|BUG_ON)\b/) { 25070a920b5bSAndy Whitcroft# print "Try to use WARN_ON & Recovery code rather than BUG() or BUG_ON()\n"; 25080a920b5bSAndy Whitcroft# print "$herecurr"; 25090a920b5bSAndy Whitcroft# $clean = 0; 25100a920b5bSAndy Whitcroft# } 25110a920b5bSAndy Whitcroft 25128905a67cSAndy Whitcroft if ($line =~ /\bLINUX_VERSION_CODE\b/) { 2513000d1cc1SJoe Perches WARN("LINUX_VERSION_CODE", 2514000d1cc1SJoe Perches "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); 25158905a67cSAndy Whitcroft } 25168905a67cSAndy Whitcroft 251717441227SJoe Perches# check for uses of printk_ratelimit 251817441227SJoe Perches if ($line =~ /\bprintk_ratelimit\s*\(/) { 2519000d1cc1SJoe Perches WARN("PRINTK_RATELIMITED", 2520000d1cc1SJoe Perches"Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); 252117441227SJoe Perches } 252217441227SJoe Perches 252300df344fSAndy Whitcroft# printk should use KERN_* levels. Note that follow on printk's on the 252400df344fSAndy Whitcroft# same line do not need a level, so we use the current block context 252500df344fSAndy Whitcroft# to try and find and validate the current printk. In summary the current 252625985edcSLucas De Marchi# printk includes all preceding printk's which have no newline on the end. 252700df344fSAndy Whitcroft# we assume the first bad printk is the one to report. 2528f0a594c1SAndy Whitcroft if ($line =~ /\bprintk\((?!KERN_)\s*"/) { 252900df344fSAndy Whitcroft my $ok = 0; 253000df344fSAndy Whitcroft for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) { 253100df344fSAndy Whitcroft #print "CHECK<$lines[$ln - 1]\n"; 253225985edcSLucas De Marchi # we have a preceding printk if it ends 253300df344fSAndy Whitcroft # with "\n" ignore it, else it is to blame 253400df344fSAndy Whitcroft if ($lines[$ln - 1] =~ m{\bprintk\(}) { 253500df344fSAndy Whitcroft if ($rawlines[$ln - 1] !~ m{\\n"}) { 253600df344fSAndy Whitcroft $ok = 1; 253700df344fSAndy Whitcroft } 253800df344fSAndy Whitcroft last; 253900df344fSAndy Whitcroft } 254000df344fSAndy Whitcroft } 254100df344fSAndy Whitcroft if ($ok == 0) { 2542000d1cc1SJoe Perches WARN("PRINTK_WITHOUT_KERN_LEVEL", 2543000d1cc1SJoe Perches "printk() should include KERN_ facility level\n" . $herecurr); 25440a920b5bSAndy Whitcroft } 254500df344fSAndy Whitcroft } 25460a920b5bSAndy Whitcroft 2547243f3803SJoe Perches if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { 2548243f3803SJoe Perches my $orig = $1; 2549243f3803SJoe Perches my $level = lc($orig); 2550243f3803SJoe Perches $level = "warn" if ($level eq "warning"); 25518f26b837SJoe Perches my $level2 = $level; 25528f26b837SJoe Perches $level2 = "dbg" if ($level eq "debug"); 2553243f3803SJoe Perches WARN("PREFER_PR_LEVEL", 25548f26b837SJoe Perches "Prefer netdev_$level2(netdev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr); 2555243f3803SJoe Perches } 2556243f3803SJoe Perches 2557243f3803SJoe Perches if ($line =~ /\bpr_warning\s*\(/) { 2558243f3803SJoe Perches WARN("PREFER_PR_LEVEL", 2559243f3803SJoe Perches "Prefer pr_warn(... to pr_warning(...\n" . $herecurr); 2560243f3803SJoe Perches } 2561243f3803SJoe Perches 2562dc139313SJoe Perches if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) { 2563dc139313SJoe Perches my $orig = $1; 2564dc139313SJoe Perches my $level = lc($orig); 2565dc139313SJoe Perches $level = "warn" if ($level eq "warning"); 2566dc139313SJoe Perches $level = "dbg" if ($level eq "debug"); 2567dc139313SJoe Perches WARN("PREFER_DEV_LEVEL", 2568dc139313SJoe Perches "Prefer dev_$level(... to dev_printk(KERN_$orig, ...\n" . $herecurr); 2569dc139313SJoe Perches } 2570dc139313SJoe Perches 2571653d4876SAndy Whitcroft# function brace can't be on same line, except for #defines of do while, 2572653d4876SAndy Whitcroft# or if closed on same line 2573c45dcabdSAndy Whitcroft if (($line=~/$Type\s*$Ident\(.*\).*\s{/) and 2574c45dcabdSAndy Whitcroft !($line=~/\#\s*define.*do\s{/) and !($line=~/}/)) { 2575000d1cc1SJoe Perches ERROR("OPEN_BRACE", 2576000d1cc1SJoe Perches "open brace '{' following function declarations go on the next line\n" . $herecurr); 25770a920b5bSAndy Whitcroft } 2578653d4876SAndy Whitcroft 25798905a67cSAndy Whitcroft# open braces for enum, union and struct go on the same line. 25808905a67cSAndy Whitcroft if ($line =~ /^.\s*{/ && 25818905a67cSAndy Whitcroft $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { 2582000d1cc1SJoe Perches ERROR("OPEN_BRACE", 2583000d1cc1SJoe Perches "open brace '{' following $1 go on the same line\n" . $hereprev); 25848905a67cSAndy Whitcroft } 25858905a67cSAndy Whitcroft 25860c73b4ebSAndy Whitcroft# missing space after union, struct or enum definition 2587*3705ce5bSJoe Perches if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) { 2588*3705ce5bSJoe Perches if (WARN("SPACING", 2589*3705ce5bSJoe Perches "missing space after $1 definition\n" . $herecurr) && 2590*3705ce5bSJoe Perches $fix) { 2591*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ 2592*3705ce5bSJoe Perches s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/; 2593*3705ce5bSJoe Perches } 25940c73b4ebSAndy Whitcroft } 25950c73b4ebSAndy Whitcroft 25968d31cfceSAndy Whitcroft# check for spacing round square brackets; allowed: 25978d31cfceSAndy Whitcroft# 1. with a type on the left -- int [] a; 2598fe2a7dbcSAndy Whitcroft# 2. at the beginning of a line for slice initialisers -- [0...10] = 5, 2599fe2a7dbcSAndy Whitcroft# 3. inside a curly brace -- = { [0...10] = 5 } 26008d31cfceSAndy Whitcroft while ($line =~ /(.*?\s)\[/g) { 26018d31cfceSAndy Whitcroft my ($where, $prefix) = ($-[1], $1); 26028d31cfceSAndy Whitcroft if ($prefix !~ /$Type\s+$/ && 2603fe2a7dbcSAndy Whitcroft ($where != 0 || $prefix !~ /^.\s+$/) && 2604daebc534SAndy Whitcroft $prefix !~ /[{,]\s+$/) { 2605*3705ce5bSJoe Perches if (ERROR("BRACKET_SPACE", 2606*3705ce5bSJoe Perches "space prohibited before open square bracket '['\n" . $herecurr) && 2607*3705ce5bSJoe Perches $fix) { 2608*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ 2609*3705ce5bSJoe Perches s/^(\+.*?)\s+\[/$1\[/; 2610*3705ce5bSJoe Perches } 26118d31cfceSAndy Whitcroft } 26128d31cfceSAndy Whitcroft } 26138d31cfceSAndy Whitcroft 2614f0a594c1SAndy Whitcroft# check for spaces between functions and their parentheses. 26156c72ffaaSAndy Whitcroft while ($line =~ /($Ident)\s+\(/g) { 2616c2fdda0dSAndy Whitcroft my $name = $1; 2617773647a0SAndy Whitcroft my $ctx_before = substr($line, 0, $-[1]); 2618773647a0SAndy Whitcroft my $ctx = "$ctx_before$name"; 2619c2fdda0dSAndy Whitcroft 2620c2fdda0dSAndy Whitcroft # Ignore those directives where spaces _are_ permitted. 2621773647a0SAndy Whitcroft if ($name =~ /^(?: 2622773647a0SAndy Whitcroft if|for|while|switch|return|case| 2623773647a0SAndy Whitcroft volatile|__volatile__| 2624773647a0SAndy Whitcroft __attribute__|format|__extension__| 2625773647a0SAndy Whitcroft asm|__asm__)$/x) 2626773647a0SAndy Whitcroft { 2627c2fdda0dSAndy Whitcroft # cpp #define statements have non-optional spaces, ie 2628c2fdda0dSAndy Whitcroft # if there is a space between the name and the open 2629c2fdda0dSAndy Whitcroft # parenthesis it is simply not a parameter group. 2630c45dcabdSAndy Whitcroft } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { 2631773647a0SAndy Whitcroft 2632773647a0SAndy Whitcroft # cpp #elif statement condition may start with a ( 2633c45dcabdSAndy Whitcroft } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { 2634c2fdda0dSAndy Whitcroft 2635c2fdda0dSAndy Whitcroft # If this whole things ends with a type its most 2636c2fdda0dSAndy Whitcroft # likely a typedef for a function. 2637773647a0SAndy Whitcroft } elsif ($ctx =~ /$Type$/) { 2638c2fdda0dSAndy Whitcroft 2639c2fdda0dSAndy Whitcroft } else { 2640*3705ce5bSJoe Perches if (WARN("SPACING", 2641*3705ce5bSJoe Perches "space prohibited between function name and open parenthesis '('\n" . $herecurr) && 2642*3705ce5bSJoe Perches $fix) { 2643*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ 2644*3705ce5bSJoe Perches s/\b$name\s+\(/$name\(/; 2645*3705ce5bSJoe Perches } 2646f0a594c1SAndy Whitcroft } 26476c72ffaaSAndy Whitcroft } 26489a4cad4eSEric Nelson 26499a4cad4eSEric Nelson# check for whitespace before a non-naked semicolon 26509a4cad4eSEric Nelson if ($line =~ /^\+.*\S\s+;/) { 2651*3705ce5bSJoe Perches if (WARN("SPACING", 2652*3705ce5bSJoe Perches "space prohibited before semicolon\n" . $herecurr) && 2653*3705ce5bSJoe Perches $fix) { 2654*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ 2655*3705ce5bSJoe Perches s/^(\+.*\S)\s+;/$1;/; 2656*3705ce5bSJoe Perches } 26579a4cad4eSEric Nelson } 26589a4cad4eSEric Nelson 2659653d4876SAndy Whitcroft# Check operator spacing. 26600a920b5bSAndy Whitcroft if (!($line=~/\#\s*include/)) { 2661*3705ce5bSJoe Perches my $fixed_line = ""; 2662*3705ce5bSJoe Perches my $line_fixed = 0; 2663*3705ce5bSJoe Perches 26649c0ca6f9SAndy Whitcroft my $ops = qr{ 26659c0ca6f9SAndy Whitcroft <<=|>>=|<=|>=|==|!=| 26669c0ca6f9SAndy Whitcroft \+=|-=|\*=|\/=|%=|\^=|\|=|&=| 26679c0ca6f9SAndy Whitcroft =>|->|<<|>>|<|>|=|!|~| 26681f65f947SAndy Whitcroft &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%| 26691f65f947SAndy Whitcroft \?|: 26709c0ca6f9SAndy Whitcroft }x; 2671cf655043SAndy Whitcroft my @elements = split(/($ops|;)/, $opline); 2672*3705ce5bSJoe Perches 2673*3705ce5bSJoe Perches## print("element count: <" . $#elements . ">\n"); 2674*3705ce5bSJoe Perches## foreach my $el (@elements) { 2675*3705ce5bSJoe Perches## print("el: <$el>\n"); 2676*3705ce5bSJoe Perches## } 2677*3705ce5bSJoe Perches 2678*3705ce5bSJoe Perches my @fix_elements = (); 267900df344fSAndy Whitcroft my $off = 0; 26806c72ffaaSAndy Whitcroft 2681*3705ce5bSJoe Perches foreach my $el (@elements) { 2682*3705ce5bSJoe Perches push(@fix_elements, substr($rawline, $off, length($el))); 2683*3705ce5bSJoe Perches $off += length($el); 2684*3705ce5bSJoe Perches } 2685*3705ce5bSJoe Perches 2686*3705ce5bSJoe Perches $off = 0; 2687*3705ce5bSJoe Perches 26886c72ffaaSAndy Whitcroft my $blank = copy_spacing($opline); 26896c72ffaaSAndy Whitcroft 26900a920b5bSAndy Whitcroft for (my $n = 0; $n < $#elements; $n += 2) { 2691*3705ce5bSJoe Perches 2692*3705ce5bSJoe Perches my $good = $fix_elements[$n] . $fix_elements[$n + 1]; 2693*3705ce5bSJoe Perches 2694*3705ce5bSJoe Perches## print("n: <$n> good: <$good>\n"); 2695*3705ce5bSJoe Perches 26964a0df2efSAndy Whitcroft $off += length($elements[$n]); 26974a0df2efSAndy Whitcroft 269825985edcSLucas De Marchi # Pick up the preceding and succeeding characters. 2699773647a0SAndy Whitcroft my $ca = substr($opline, 0, $off); 2700773647a0SAndy Whitcroft my $cc = ''; 2701773647a0SAndy Whitcroft if (length($opline) >= ($off + length($elements[$n + 1]))) { 2702773647a0SAndy Whitcroft $cc = substr($opline, $off + length($elements[$n + 1])); 2703773647a0SAndy Whitcroft } 2704773647a0SAndy Whitcroft my $cb = "$ca$;$cc"; 2705773647a0SAndy Whitcroft 27064a0df2efSAndy Whitcroft my $a = ''; 27074a0df2efSAndy Whitcroft $a = 'V' if ($elements[$n] ne ''); 27084a0df2efSAndy Whitcroft $a = 'W' if ($elements[$n] =~ /\s$/); 2709cf655043SAndy Whitcroft $a = 'C' if ($elements[$n] =~ /$;$/); 27104a0df2efSAndy Whitcroft $a = 'B' if ($elements[$n] =~ /(\[|\()$/); 27114a0df2efSAndy Whitcroft $a = 'O' if ($elements[$n] eq ''); 2712773647a0SAndy Whitcroft $a = 'E' if ($ca =~ /^\s*$/); 27134a0df2efSAndy Whitcroft 27140a920b5bSAndy Whitcroft my $op = $elements[$n + 1]; 27154a0df2efSAndy Whitcroft 27164a0df2efSAndy Whitcroft my $c = ''; 27170a920b5bSAndy Whitcroft if (defined $elements[$n + 2]) { 27184a0df2efSAndy Whitcroft $c = 'V' if ($elements[$n + 2] ne ''); 27194a0df2efSAndy Whitcroft $c = 'W' if ($elements[$n + 2] =~ /^\s/); 2720cf655043SAndy Whitcroft $c = 'C' if ($elements[$n + 2] =~ /^$;/); 27214a0df2efSAndy Whitcroft $c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/); 27224a0df2efSAndy Whitcroft $c = 'O' if ($elements[$n + 2] eq ''); 27238b1b3378SAndy Whitcroft $c = 'E' if ($elements[$n + 2] =~ /^\s*\\$/); 27244a0df2efSAndy Whitcroft } else { 27254a0df2efSAndy Whitcroft $c = 'E'; 27260a920b5bSAndy Whitcroft } 27270a920b5bSAndy Whitcroft 27284a0df2efSAndy Whitcroft my $ctx = "${a}x${c}"; 27294a0df2efSAndy Whitcroft 27304a0df2efSAndy Whitcroft my $at = "(ctx:$ctx)"; 27314a0df2efSAndy Whitcroft 27326c72ffaaSAndy Whitcroft my $ptr = substr($blank, 0, $off) . "^"; 2733de7d4f0eSAndy Whitcroft my $hereptr = "$hereline$ptr\n"; 27340a920b5bSAndy Whitcroft 273574048ed8SAndy Whitcroft # Pull out the value of this operator. 27366c72ffaaSAndy Whitcroft my $op_type = substr($curr_values, $off + 1, 1); 27370a920b5bSAndy Whitcroft 27381f65f947SAndy Whitcroft # Get the full operator variant. 27391f65f947SAndy Whitcroft my $opv = $op . substr($curr_vars, $off, 1); 27401f65f947SAndy Whitcroft 274113214adfSAndy Whitcroft # Ignore operators passed as parameters. 274213214adfSAndy Whitcroft if ($op_type ne 'V' && 274313214adfSAndy Whitcroft $ca =~ /\s$/ && $cc =~ /^\s*,/) { 274413214adfSAndy Whitcroft 2745cf655043SAndy Whitcroft# # Ignore comments 2746cf655043SAndy Whitcroft# } elsif ($op =~ /^$;+$/) { 274713214adfSAndy Whitcroft 2748d8aaf121SAndy Whitcroft # ; should have either the end of line or a space or \ after it 274913214adfSAndy Whitcroft } elsif ($op eq ';') { 2750cf655043SAndy Whitcroft if ($ctx !~ /.x[WEBC]/ && 2751cf655043SAndy Whitcroft $cc !~ /^\\/ && $cc !~ /^;/) { 2752*3705ce5bSJoe Perches if (ERROR("SPACING", 2753*3705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 2754*3705ce5bSJoe Perches $good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 2755*3705ce5bSJoe Perches $line_fixed = 1; 2756*3705ce5bSJoe Perches } 2757d8aaf121SAndy Whitcroft } 2758d8aaf121SAndy Whitcroft 2759d8aaf121SAndy Whitcroft # // is a comment 2760d8aaf121SAndy Whitcroft } elsif ($op eq '//') { 27610a920b5bSAndy Whitcroft 27621f65f947SAndy Whitcroft # No spaces for: 27631f65f947SAndy Whitcroft # -> 27641f65f947SAndy Whitcroft # : when part of a bitfield 27651f65f947SAndy Whitcroft } elsif ($op eq '->' || $opv eq ':B') { 27664a0df2efSAndy Whitcroft if ($ctx =~ /Wx.|.xW/) { 2767*3705ce5bSJoe Perches if (ERROR("SPACING", 2768*3705ce5bSJoe Perches "spaces prohibited around that '$op' $at\n" . $hereptr)) { 2769*3705ce5bSJoe Perches $good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 2770*3705ce5bSJoe Perches $line_fixed = 1; 2771*3705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 2772*3705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 2773*3705ce5bSJoe Perches } 2774*3705ce5bSJoe Perches } 27750a920b5bSAndy Whitcroft } 27760a920b5bSAndy Whitcroft 27770a920b5bSAndy Whitcroft # , must have a space on the right. 27780a920b5bSAndy Whitcroft } elsif ($op eq ',') { 2779cf655043SAndy Whitcroft if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { 2780*3705ce5bSJoe Perches if (ERROR("SPACING", 2781*3705ce5bSJoe Perches "space required after that '$op' $at\n" . $hereptr)) { 2782*3705ce5bSJoe Perches $good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]) . " "; 2783*3705ce5bSJoe Perches $line_fixed = 1; 2784*3705ce5bSJoe Perches } 27850a920b5bSAndy Whitcroft } 27860a920b5bSAndy Whitcroft 27879c0ca6f9SAndy Whitcroft # '*' as part of a type definition -- reported already. 278874048ed8SAndy Whitcroft } elsif ($opv eq '*_') { 27899c0ca6f9SAndy Whitcroft #warn "'*' is part of type\n"; 27909c0ca6f9SAndy Whitcroft 27919c0ca6f9SAndy Whitcroft # unary operators should have a space before and 27929c0ca6f9SAndy Whitcroft # none after. May be left adjacent to another 27939c0ca6f9SAndy Whitcroft # unary operator, or a cast 27949c0ca6f9SAndy Whitcroft } elsif ($op eq '!' || $op eq '~' || 279574048ed8SAndy Whitcroft $opv eq '*U' || $opv eq '-U' || 27960d413866SAndy Whitcroft $opv eq '&U' || $opv eq '&&U') { 2797cf655043SAndy Whitcroft if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { 2798*3705ce5bSJoe Perches if (ERROR("SPACING", 2799*3705ce5bSJoe Perches "space required before that '$op' $at\n" . $hereptr)) { 2800*3705ce5bSJoe Perches $good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]); 2801*3705ce5bSJoe Perches $line_fixed = 1; 2802*3705ce5bSJoe Perches } 28030a920b5bSAndy Whitcroft } 2804a3340b35SAndy Whitcroft if ($op eq '*' && $cc =~/\s*$Modifier\b/) { 2805171ae1a4SAndy Whitcroft # A unary '*' may be const 2806171ae1a4SAndy Whitcroft 2807171ae1a4SAndy Whitcroft } elsif ($ctx =~ /.xW/) { 2808*3705ce5bSJoe Perches if (ERROR("SPACING", 2809*3705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 2810*3705ce5bSJoe Perches $fixed_line =~ s/\s+$//; 2811*3705ce5bSJoe Perches $good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 2812*3705ce5bSJoe Perches $line_fixed = 1; 2813*3705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 2814*3705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 2815*3705ce5bSJoe Perches } 2816*3705ce5bSJoe Perches } 28170a920b5bSAndy Whitcroft } 28180a920b5bSAndy Whitcroft 28190a920b5bSAndy Whitcroft # unary ++ and unary -- are allowed no space on one side. 28200a920b5bSAndy Whitcroft } elsif ($op eq '++' or $op eq '--') { 2821773647a0SAndy Whitcroft if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { 2822*3705ce5bSJoe Perches if (ERROR("SPACING", 2823*3705ce5bSJoe Perches "space required one side of that '$op' $at\n" . $hereptr)) { 2824*3705ce5bSJoe Perches $fixed_line =~ s/\s+$//; 2825*3705ce5bSJoe Perches $good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]) . " "; 2826*3705ce5bSJoe Perches $line_fixed = 1; 2827*3705ce5bSJoe Perches } 28280a920b5bSAndy Whitcroft } 2829773647a0SAndy Whitcroft if ($ctx =~ /Wx[BE]/ || 2830773647a0SAndy Whitcroft ($ctx =~ /Wx./ && $cc =~ /^;/)) { 2831*3705ce5bSJoe Perches if (ERROR("SPACING", 2832*3705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 2833*3705ce5bSJoe Perches $fixed_line =~ s/\s+$//; 2834*3705ce5bSJoe Perches $good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 2835*3705ce5bSJoe Perches $line_fixed = 1; 2836*3705ce5bSJoe Perches } 2837653d4876SAndy Whitcroft } 2838773647a0SAndy Whitcroft if ($ctx =~ /ExW/) { 2839*3705ce5bSJoe Perches if (ERROR("SPACING", 2840*3705ce5bSJoe Perches "space prohibited after that '$op' $at\n" . $hereptr)) { 2841*3705ce5bSJoe Perches $fixed_line =~ s/\s+$//; 2842*3705ce5bSJoe Perches $good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 2843*3705ce5bSJoe Perches $line_fixed = 1; 2844*3705ce5bSJoe Perches if (defined $fix_elements[$n + 2]) { 2845*3705ce5bSJoe Perches $fix_elements[$n + 2] =~ s/^\s+//; 2846773647a0SAndy Whitcroft } 2847*3705ce5bSJoe Perches } 2848*3705ce5bSJoe Perches } 28490a920b5bSAndy Whitcroft 28500a920b5bSAndy Whitcroft # << and >> may either have or not have spaces both sides 28519c0ca6f9SAndy Whitcroft } elsif ($op eq '<<' or $op eq '>>' or 28529c0ca6f9SAndy Whitcroft $op eq '&' or $op eq '^' or $op eq '|' or 28539c0ca6f9SAndy Whitcroft $op eq '+' or $op eq '-' or 2854c2fdda0dSAndy Whitcroft $op eq '*' or $op eq '/' or 2855c2fdda0dSAndy Whitcroft $op eq '%') 28560a920b5bSAndy Whitcroft { 2857773647a0SAndy Whitcroft if ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { 2858*3705ce5bSJoe Perches if (ERROR("SPACING", 2859*3705ce5bSJoe Perches "need consistent spacing around '$op' $at\n" . $hereptr)) { 2860*3705ce5bSJoe Perches $fixed_line =~ s/\s+$//; 2861*3705ce5bSJoe Perches $good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 2862*3705ce5bSJoe Perches $line_fixed = 1; 2863*3705ce5bSJoe Perches } 28640a920b5bSAndy Whitcroft } 28650a920b5bSAndy Whitcroft 28661f65f947SAndy Whitcroft # A colon needs no spaces before when it is 28671f65f947SAndy Whitcroft # terminating a case value or a label. 28681f65f947SAndy Whitcroft } elsif ($opv eq ':C' || $opv eq ':L') { 28691f65f947SAndy Whitcroft if ($ctx =~ /Wx./) { 2870*3705ce5bSJoe Perches if (ERROR("SPACING", 2871*3705ce5bSJoe Perches "space prohibited before that '$op' $at\n" . $hereptr)) { 2872*3705ce5bSJoe Perches $good = trim($fix_elements[$n]) . trim($fix_elements[$n + 1]); 2873*3705ce5bSJoe Perches $line_fixed = 1; 2874*3705ce5bSJoe Perches } 28751f65f947SAndy Whitcroft } 28761f65f947SAndy Whitcroft 28770a920b5bSAndy Whitcroft # All the others need spaces both sides. 2878cf655043SAndy Whitcroft } elsif ($ctx !~ /[EWC]x[CWE]/) { 28791f65f947SAndy Whitcroft my $ok = 0; 28801f65f947SAndy Whitcroft 288122f2a2efSAndy Whitcroft # Ignore email addresses <foo@bar> 28821f65f947SAndy Whitcroft if (($op eq '<' && 28831f65f947SAndy Whitcroft $cc =~ /^\S+\@\S+>/) || 28841f65f947SAndy Whitcroft ($op eq '>' && 28851f65f947SAndy Whitcroft $ca =~ /<\S+\@\S+$/)) 28861f65f947SAndy Whitcroft { 28871f65f947SAndy Whitcroft $ok = 1; 28881f65f947SAndy Whitcroft } 28891f65f947SAndy Whitcroft 28901f65f947SAndy Whitcroft # Ignore ?: 28911f65f947SAndy Whitcroft if (($opv eq ':O' && $ca =~ /\?$/) || 28921f65f947SAndy Whitcroft ($op eq '?' && $cc =~ /^:/)) { 28931f65f947SAndy Whitcroft $ok = 1; 28941f65f947SAndy Whitcroft } 28951f65f947SAndy Whitcroft 28961f65f947SAndy Whitcroft if ($ok == 0) { 2897*3705ce5bSJoe Perches if (ERROR("SPACING", 2898*3705ce5bSJoe Perches "spaces required around that '$op' $at\n" . $hereptr)) { 2899*3705ce5bSJoe Perches $good = trim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " "; 2900*3705ce5bSJoe Perches $good = $fix_elements[$n] . " " . trim($fix_elements[$n + 1]) . " "; 2901*3705ce5bSJoe Perches $line_fixed = 1; 2902*3705ce5bSJoe Perches } 29030a920b5bSAndy Whitcroft } 290422f2a2efSAndy Whitcroft } 29054a0df2efSAndy Whitcroft $off += length($elements[$n + 1]); 2906*3705ce5bSJoe Perches 2907*3705ce5bSJoe Perches## print("n: <$n> GOOD: <$good>\n"); 2908*3705ce5bSJoe Perches 2909*3705ce5bSJoe Perches $fixed_line = $fixed_line . $good; 29100a920b5bSAndy Whitcroft } 2911*3705ce5bSJoe Perches 2912*3705ce5bSJoe Perches if (($#elements % 2) == 0) { 2913*3705ce5bSJoe Perches $fixed_line = $fixed_line . $fix_elements[$#elements]; 2914*3705ce5bSJoe Perches } 2915*3705ce5bSJoe Perches 2916*3705ce5bSJoe Perches if ($fix && $line_fixed && $fixed_line ne $fixed[$linenr - 1]) { 2917*3705ce5bSJoe Perches $fixed[$linenr - 1] = $fixed_line; 2918*3705ce5bSJoe Perches } 2919*3705ce5bSJoe Perches 2920*3705ce5bSJoe Perches 29210a920b5bSAndy Whitcroft } 29220a920b5bSAndy Whitcroft 2923f0a594c1SAndy Whitcroft# check for multiple assignments 2924f0a594c1SAndy Whitcroft if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { 2925000d1cc1SJoe Perches CHK("MULTIPLE_ASSIGNMENTS", 2926000d1cc1SJoe Perches "multiple assignments should be avoided\n" . $herecurr); 2927f0a594c1SAndy Whitcroft } 2928f0a594c1SAndy Whitcroft 292922f2a2efSAndy Whitcroft## # check for multiple declarations, allowing for a function declaration 293022f2a2efSAndy Whitcroft## # continuation. 293122f2a2efSAndy Whitcroft## if ($line =~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Ident.*/ && 293222f2a2efSAndy Whitcroft## $line !~ /^.\s*$Type\s+$Ident(?:\s*=[^,{]*)?\s*,\s*$Type\s*$Ident.*/) { 293322f2a2efSAndy Whitcroft## 293422f2a2efSAndy Whitcroft## # Remove any bracketed sections to ensure we do not 293522f2a2efSAndy Whitcroft## # falsly report the parameters of functions. 293622f2a2efSAndy Whitcroft## my $ln = $line; 293722f2a2efSAndy Whitcroft## while ($ln =~ s/\([^\(\)]*\)//g) { 293822f2a2efSAndy Whitcroft## } 293922f2a2efSAndy Whitcroft## if ($ln =~ /,/) { 2940000d1cc1SJoe Perches## WARN("MULTIPLE_DECLARATION", 2941000d1cc1SJoe Perches## "declaring multiple variables together should be avoided\n" . $herecurr); 294222f2a2efSAndy Whitcroft## } 294322f2a2efSAndy Whitcroft## } 2944f0a594c1SAndy Whitcroft 29450a920b5bSAndy Whitcroft#need space before brace following if, while, etc 294622f2a2efSAndy Whitcroft if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) || 294722f2a2efSAndy Whitcroft $line =~ /do{/) { 2948*3705ce5bSJoe Perches if (ERROR("SPACING", 2949*3705ce5bSJoe Perches "space required before the open brace '{'\n" . $herecurr) && 2950*3705ce5bSJoe Perches $fix) { 2951*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ 2952*3705ce5bSJoe Perches s/^(\+.*(?:do|\))){/$1 {/; 2953*3705ce5bSJoe Perches } 2954de7d4f0eSAndy Whitcroft } 2955de7d4f0eSAndy Whitcroft 2956c4a62ef9SJoe Perches## # check for blank lines before declarations 2957c4a62ef9SJoe Perches## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ && 2958c4a62ef9SJoe Perches## $prevrawline =~ /^.\s*$/) { 2959c4a62ef9SJoe Perches## WARN("SPACING", 2960c4a62ef9SJoe Perches## "No blank lines before declarations\n" . $hereprev); 2961c4a62ef9SJoe Perches## } 2962c4a62ef9SJoe Perches## 2963c4a62ef9SJoe Perches 2964de7d4f0eSAndy Whitcroft# closing brace should have a space following it when it has anything 2965de7d4f0eSAndy Whitcroft# on the line 2966de7d4f0eSAndy Whitcroft if ($line =~ /}(?!(?:,|;|\)))\S/) { 2967000d1cc1SJoe Perches ERROR("SPACING", 2968000d1cc1SJoe Perches "space required after that close brace '}'\n" . $herecurr); 29690a920b5bSAndy Whitcroft } 29700a920b5bSAndy Whitcroft 297122f2a2efSAndy Whitcroft# check spacing on square brackets 297222f2a2efSAndy Whitcroft if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { 2973*3705ce5bSJoe Perches if (ERROR("SPACING", 2974*3705ce5bSJoe Perches "space prohibited after that open square bracket '['\n" . $herecurr) && 2975*3705ce5bSJoe Perches $fix) { 2976*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ 2977*3705ce5bSJoe Perches s/\[\s+/\[/; 2978*3705ce5bSJoe Perches } 297922f2a2efSAndy Whitcroft } 298022f2a2efSAndy Whitcroft if ($line =~ /\s\]/) { 2981*3705ce5bSJoe Perches if (ERROR("SPACING", 2982*3705ce5bSJoe Perches "space prohibited before that close square bracket ']'\n" . $herecurr) && 2983*3705ce5bSJoe Perches $fix) { 2984*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ 2985*3705ce5bSJoe Perches s/\s+\]/\]/; 2986*3705ce5bSJoe Perches } 298722f2a2efSAndy Whitcroft } 298822f2a2efSAndy Whitcroft 2989c45dcabdSAndy Whitcroft# check spacing on parentheses 29909c0ca6f9SAndy Whitcroft if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && 29919c0ca6f9SAndy Whitcroft $line !~ /for\s*\(\s+;/) { 2992*3705ce5bSJoe Perches if (ERROR("SPACING", 2993*3705ce5bSJoe Perches "space prohibited after that open parenthesis '('\n" . $herecurr) && 2994*3705ce5bSJoe Perches $fix) { 2995*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ 2996*3705ce5bSJoe Perches s/\(\s+/\(/; 2997*3705ce5bSJoe Perches } 299822f2a2efSAndy Whitcroft } 299913214adfSAndy Whitcroft if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && 3000c45dcabdSAndy Whitcroft $line !~ /for\s*\(.*;\s+\)/ && 3001c45dcabdSAndy Whitcroft $line !~ /:\s+\)/) { 3002*3705ce5bSJoe Perches if (ERROR("SPACING", 3003*3705ce5bSJoe Perches "space prohibited before that close parenthesis ')'\n" . $herecurr) && 3004*3705ce5bSJoe Perches $fix) { 3005*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ 3006*3705ce5bSJoe Perches s/\s+\)/\)/; 3007*3705ce5bSJoe Perches } 300822f2a2efSAndy Whitcroft } 300922f2a2efSAndy Whitcroft 30100a920b5bSAndy Whitcroft#goto labels aren't indented, allow a single space however 30114a0df2efSAndy Whitcroft if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and 30120a920b5bSAndy Whitcroft !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { 3013*3705ce5bSJoe Perches if (WARN("INDENTED_LABEL", 3014*3705ce5bSJoe Perches "labels should not be indented\n" . $herecurr) && 3015*3705ce5bSJoe Perches $fix) { 3016*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ 3017*3705ce5bSJoe Perches s/^(.)\s+/$1/; 3018*3705ce5bSJoe Perches } 30190a920b5bSAndy Whitcroft } 30200a920b5bSAndy Whitcroft 3021c45dcabdSAndy Whitcroft# Return is not a function. 3022c45dcabdSAndy Whitcroft if (defined($stat) && $stat =~ /^.\s*return(\s*)(\(.*);/s) { 3023c45dcabdSAndy Whitcroft my $spacing = $1; 3024c45dcabdSAndy Whitcroft my $value = $2; 3025c45dcabdSAndy Whitcroft 302686f9d059SAndy Whitcroft # Flatten any parentheses 3027fb2d2c1bSAndy Whitcroft $value =~ s/\(/ \(/g; 3028fb2d2c1bSAndy Whitcroft $value =~ s/\)/\) /g; 3029e01886adSAndy Whitcroft while ($value =~ s/\[[^\[\]]*\]/1/ || 303063f17f89SAndy Whitcroft $value !~ /(?:$Ident|-?$Constant)\s* 303163f17f89SAndy Whitcroft $Compare\s* 303263f17f89SAndy Whitcroft (?:$Ident|-?$Constant)/x && 303363f17f89SAndy Whitcroft $value =~ s/\([^\(\)]*\)/1/) { 3034c45dcabdSAndy Whitcroft } 3035fb2d2c1bSAndy Whitcroft#print "value<$value>\n"; 3036fb2d2c1bSAndy Whitcroft if ($value =~ /^\s*(?:$Ident|-?$Constant)\s*$/) { 3037000d1cc1SJoe Perches ERROR("RETURN_PARENTHESES", 3038000d1cc1SJoe Perches "return is not a function, parentheses are not required\n" . $herecurr); 3039c45dcabdSAndy Whitcroft 3040c45dcabdSAndy Whitcroft } elsif ($spacing !~ /\s+/) { 3041000d1cc1SJoe Perches ERROR("SPACING", 3042000d1cc1SJoe Perches "space required before the open parenthesis '('\n" . $herecurr); 3043c45dcabdSAndy Whitcroft } 3044c45dcabdSAndy Whitcroft } 304553a3c448SAndy Whitcroft# Return of what appears to be an errno should normally be -'ve 304653a3c448SAndy Whitcroft if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) { 304753a3c448SAndy Whitcroft my $name = $1; 304853a3c448SAndy Whitcroft if ($name ne 'EOF' && $name ne 'ERROR') { 3049000d1cc1SJoe Perches WARN("USE_NEGATIVE_ERRNO", 3050000d1cc1SJoe Perches "return of an errno should typically be -ve (return -$1)\n" . $herecurr); 305153a3c448SAndy Whitcroft } 305253a3c448SAndy Whitcroft } 3053c45dcabdSAndy Whitcroft 30540a920b5bSAndy Whitcroft# Need a space before open parenthesis after if, while etc 30554a0df2efSAndy Whitcroft if ($line =~ /\b(if|while|for|switch)\(/) { 3056*3705ce5bSJoe Perches if (ERROR("SPACING", 3057*3705ce5bSJoe Perches "space required before the open parenthesis '('\n" . $herecurr) && 3058*3705ce5bSJoe Perches $fix) { 3059*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ 3060*3705ce5bSJoe Perches s/\b(if|while|for|switch)\(/$1 \(/; 3061*3705ce5bSJoe Perches } 30620a920b5bSAndy Whitcroft } 30630a920b5bSAndy Whitcroft 3064f5fe35ddSAndy Whitcroft# Check for illegal assignment in if conditional -- and check for trailing 3065f5fe35ddSAndy Whitcroft# statements after the conditional. 3066170d3a22SAndy Whitcroft if ($line =~ /do\s*(?!{)/) { 30673e469cdcSAndy Whitcroft ($stat, $cond, $line_nr_next, $remain_next, $off_next) = 30683e469cdcSAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0) 30693e469cdcSAndy Whitcroft if (!defined $stat); 3070170d3a22SAndy Whitcroft my ($stat_next) = ctx_statement_block($line_nr_next, 3071170d3a22SAndy Whitcroft $remain_next, $off_next); 3072170d3a22SAndy Whitcroft $stat_next =~ s/\n./\n /g; 3073170d3a22SAndy Whitcroft ##print "stat<$stat> stat_next<$stat_next>\n"; 3074170d3a22SAndy Whitcroft 3075170d3a22SAndy Whitcroft if ($stat_next =~ /^\s*while\b/) { 3076170d3a22SAndy Whitcroft # If the statement carries leading newlines, 3077170d3a22SAndy Whitcroft # then count those as offsets. 3078170d3a22SAndy Whitcroft my ($whitespace) = 3079170d3a22SAndy Whitcroft ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s); 3080170d3a22SAndy Whitcroft my $offset = 3081170d3a22SAndy Whitcroft statement_rawlines($whitespace) - 1; 3082170d3a22SAndy Whitcroft 3083170d3a22SAndy Whitcroft $suppress_whiletrailers{$line_nr_next + 3084170d3a22SAndy Whitcroft $offset} = 1; 3085170d3a22SAndy Whitcroft } 3086170d3a22SAndy Whitcroft } 3087170d3a22SAndy Whitcroft if (!defined $suppress_whiletrailers{$linenr} && 3088170d3a22SAndy Whitcroft $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) { 3089171ae1a4SAndy Whitcroft my ($s, $c) = ($stat, $cond); 30908905a67cSAndy Whitcroft 3091b53c8e10SAndy Whitcroft if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { 3092000d1cc1SJoe Perches ERROR("ASSIGN_IN_IF", 3093000d1cc1SJoe Perches "do not use assignment in if condition\n" . $herecurr); 30948905a67cSAndy Whitcroft } 30958905a67cSAndy Whitcroft 30968905a67cSAndy Whitcroft # Find out what is on the end of the line after the 30978905a67cSAndy Whitcroft # conditional. 3098773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 30998905a67cSAndy Whitcroft $s =~ s/\n.*//g; 310013214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 310153210168SAndy Whitcroft if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ && 310253210168SAndy Whitcroft $c !~ /}\s*while\s*/) 3103773647a0SAndy Whitcroft { 3104bb44ad39SAndy Whitcroft # Find out how long the conditional actually is. 3105bb44ad39SAndy Whitcroft my @newlines = ($c =~ /\n/gs); 3106bb44ad39SAndy Whitcroft my $cond_lines = 1 + $#newlines; 310742bdf74cSHidetoshi Seto my $stat_real = ''; 3108bb44ad39SAndy Whitcroft 310942bdf74cSHidetoshi Seto $stat_real = raw_line($linenr, $cond_lines) 311042bdf74cSHidetoshi Seto . "\n" if ($cond_lines); 3111bb44ad39SAndy Whitcroft if (defined($stat_real) && $cond_lines > 1) { 3112bb44ad39SAndy Whitcroft $stat_real = "[...]\n$stat_real"; 3113bb44ad39SAndy Whitcroft } 3114bb44ad39SAndy Whitcroft 3115000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 3116000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr . $stat_real); 31178905a67cSAndy Whitcroft } 31188905a67cSAndy Whitcroft } 31198905a67cSAndy Whitcroft 312013214adfSAndy Whitcroft# Check for bitwise tests written as boolean 312113214adfSAndy Whitcroft if ($line =~ / 312213214adfSAndy Whitcroft (?: 312313214adfSAndy Whitcroft (?:\[|\(|\&\&|\|\|) 312413214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 312513214adfSAndy Whitcroft (?:\&\&|\|\|) 312613214adfSAndy Whitcroft | 312713214adfSAndy Whitcroft (?:\&\&|\|\|) 312813214adfSAndy Whitcroft \s*0[xX][0-9]+\s* 312913214adfSAndy Whitcroft (?:\&\&|\|\||\)|\]) 313013214adfSAndy Whitcroft )/x) 313113214adfSAndy Whitcroft { 3132000d1cc1SJoe Perches WARN("HEXADECIMAL_BOOLEAN_TEST", 3133000d1cc1SJoe Perches "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); 313413214adfSAndy Whitcroft } 313513214adfSAndy Whitcroft 31368905a67cSAndy Whitcroft# if and else should not have general statements after it 313713214adfSAndy Whitcroft if ($line =~ /^.\s*(?:}\s*)?else\b(.*)/) { 313813214adfSAndy Whitcroft my $s = $1; 313913214adfSAndy Whitcroft $s =~ s/$;//g; # Remove any comments 314013214adfSAndy Whitcroft if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { 3141000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 3142000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 31430a920b5bSAndy Whitcroft } 314413214adfSAndy Whitcroft } 314539667782SAndy Whitcroft# if should not continue a brace 314639667782SAndy Whitcroft if ($line =~ /}\s*if\b/) { 3147000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 3148000d1cc1SJoe Perches "trailing statements should be on next line\n" . 314939667782SAndy Whitcroft $herecurr); 315039667782SAndy Whitcroft } 3151a1080bf8SAndy Whitcroft# case and default should not have general statements after them 3152a1080bf8SAndy Whitcroft if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g && 3153a1080bf8SAndy Whitcroft $line !~ /\G(?: 31543fef12d6SAndy Whitcroft (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$| 3155a1080bf8SAndy Whitcroft \s*return\s+ 3156a1080bf8SAndy Whitcroft )/xg) 3157a1080bf8SAndy Whitcroft { 3158000d1cc1SJoe Perches ERROR("TRAILING_STATEMENTS", 3159000d1cc1SJoe Perches "trailing statements should be on next line\n" . $herecurr); 3160a1080bf8SAndy Whitcroft } 31610a920b5bSAndy Whitcroft 31620a920b5bSAndy Whitcroft # Check for }<nl>else {, these must be at the same 31630a920b5bSAndy Whitcroft # indent level to be relevant to each other. 31640a920b5bSAndy Whitcroft if ($prevline=~/}\s*$/ and $line=~/^.\s*else\s*/ and 31650a920b5bSAndy Whitcroft $previndent == $indent) { 3166000d1cc1SJoe Perches ERROR("ELSE_AFTER_BRACE", 3167000d1cc1SJoe Perches "else should follow close brace '}'\n" . $hereprev); 31680a920b5bSAndy Whitcroft } 31690a920b5bSAndy Whitcroft 3170c2fdda0dSAndy Whitcroft if ($prevline=~/}\s*$/ and $line=~/^.\s*while\s*/ and 3171c2fdda0dSAndy Whitcroft $previndent == $indent) { 3172c2fdda0dSAndy Whitcroft my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0); 3173c2fdda0dSAndy Whitcroft 3174c2fdda0dSAndy Whitcroft # Find out what is on the end of the line after the 3175c2fdda0dSAndy Whitcroft # conditional. 3176773647a0SAndy Whitcroft substr($s, 0, length($c), ''); 3177c2fdda0dSAndy Whitcroft $s =~ s/\n.*//g; 3178c2fdda0dSAndy Whitcroft 3179c2fdda0dSAndy Whitcroft if ($s =~ /^\s*;/) { 3180000d1cc1SJoe Perches ERROR("WHILE_AFTER_BRACE", 3181000d1cc1SJoe Perches "while should follow close brace '}'\n" . $hereprev); 3182c2fdda0dSAndy Whitcroft } 3183c2fdda0dSAndy Whitcroft } 3184c2fdda0dSAndy Whitcroft 318595e2c602SJoe Perches#Specific variable tests 3186323c1260SJoe Perches while ($line =~ m{($Constant|$Lval)}g) { 3187323c1260SJoe Perches my $var = $1; 318895e2c602SJoe Perches 318995e2c602SJoe Perches#gcc binary extension 319095e2c602SJoe Perches if ($var =~ /^$Binary$/) { 319195e2c602SJoe Perches WARN("GCC_BINARY_CONSTANT", 319295e2c602SJoe Perches "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr); 319395e2c602SJoe Perches } 319495e2c602SJoe Perches 319595e2c602SJoe Perches#CamelCase 3196807bd26cSJoe Perches if ($var !~ /^$Constant$/ && 3197be79794bSJoe Perches $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && 3198807bd26cSJoe Perches $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ && 3199323c1260SJoe Perches !defined $camelcase{$var}) { 3200323c1260SJoe Perches $camelcase{$var} = 1; 3201be79794bSJoe Perches CHK("CAMELCASE", 3202323c1260SJoe Perches "Avoid CamelCase: <$var>\n" . $herecurr); 3203323c1260SJoe Perches } 3204323c1260SJoe Perches } 32050a920b5bSAndy Whitcroft 32060a920b5bSAndy Whitcroft#no spaces allowed after \ in define 3207c45dcabdSAndy Whitcroft if ($line=~/\#\s*define.*\\\s$/) { 3208000d1cc1SJoe Perches WARN("WHITESPACE_AFTER_LINE_CONTINUATION", 3209000d1cc1SJoe Perches "Whitepspace after \\ makes next lines useless\n" . $herecurr); 32100a920b5bSAndy Whitcroft } 32110a920b5bSAndy Whitcroft 3212653d4876SAndy Whitcroft#warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line) 3213c45dcabdSAndy Whitcroft if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) { 3214e09dec48SAndy Whitcroft my $file = "$1.h"; 3215e09dec48SAndy Whitcroft my $checkfile = "include/linux/$file"; 3216e09dec48SAndy Whitcroft if (-f "$root/$checkfile" && 3217e09dec48SAndy Whitcroft $realfile ne $checkfile && 32187840a94cSWolfram Sang $1 !~ /$allowed_asm_includes/) 3219c45dcabdSAndy Whitcroft { 3220e09dec48SAndy Whitcroft if ($realfile =~ m{^arch/}) { 3221000d1cc1SJoe Perches CHK("ARCH_INCLUDE_LINUX", 3222000d1cc1SJoe Perches "Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 3223e09dec48SAndy Whitcroft } else { 3224000d1cc1SJoe Perches WARN("INCLUDE_LINUX", 3225000d1cc1SJoe Perches "Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr); 3226e09dec48SAndy Whitcroft } 32270a920b5bSAndy Whitcroft } 32280a920b5bSAndy Whitcroft } 32290a920b5bSAndy Whitcroft 3230653d4876SAndy Whitcroft# multi-statement macros should be enclosed in a do while loop, grab the 3231653d4876SAndy Whitcroft# first statement and ensure its the whole macro if its not enclosed 3232cf655043SAndy Whitcroft# in a known good container 3233b8f96a31SAndy Whitcroft if ($realfile !~ m@/vmlinux.lds.h$@ && 3234b8f96a31SAndy Whitcroft $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 3235d8aaf121SAndy Whitcroft my $ln = $linenr; 3236d8aaf121SAndy Whitcroft my $cnt = $realcnt; 3237c45dcabdSAndy Whitcroft my ($off, $dstat, $dcond, $rest); 3238c45dcabdSAndy Whitcroft my $ctx = ''; 3239c45dcabdSAndy Whitcroft ($dstat, $dcond, $ln, $cnt, $off) = 3240f74bd194SAndy Whitcroft ctx_statement_block($linenr, $realcnt, 0); 3241f74bd194SAndy Whitcroft $ctx = $dstat; 3242c45dcabdSAndy Whitcroft #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; 3243a3bb97a7SAndy Whitcroft #print "LINE<$lines[$ln-1]> len<" . length($lines[$ln-1]) . "\n"; 3244c45dcabdSAndy Whitcroft 3245f74bd194SAndy Whitcroft $dstat =~ s/^.\s*\#\s*define\s+$Ident(?:\([^\)]*\))?\s*//; 3246292f1a9bSAndy Whitcroft $dstat =~ s/$;//g; 3247c45dcabdSAndy Whitcroft $dstat =~ s/\\\n.//g; 3248c45dcabdSAndy Whitcroft $dstat =~ s/^\s*//s; 3249c45dcabdSAndy Whitcroft $dstat =~ s/\s*$//s; 3250c45dcabdSAndy Whitcroft 3251c45dcabdSAndy Whitcroft # Flatten any parentheses and braces 3252bf30d6edSAndy Whitcroft while ($dstat =~ s/\([^\(\)]*\)/1/ || 3253bf30d6edSAndy Whitcroft $dstat =~ s/\{[^\{\}]*\}/1/ || 3254c81769fdSAndy Whitcroft $dstat =~ s/\[[^\[\]]*\]/1/) 3255bf30d6edSAndy Whitcroft { 3256c45dcabdSAndy Whitcroft } 3257c45dcabdSAndy Whitcroft 3258e45bab8eSAndy Whitcroft # Flatten any obvious string concatentation. 3259e45bab8eSAndy Whitcroft while ($dstat =~ s/("X*")\s*$Ident/$1/ || 3260e45bab8eSAndy Whitcroft $dstat =~ s/$Ident\s*("X*")/$1/) 3261e45bab8eSAndy Whitcroft { 3262e45bab8eSAndy Whitcroft } 3263e45bab8eSAndy Whitcroft 3264c45dcabdSAndy Whitcroft my $exceptions = qr{ 3265c45dcabdSAndy Whitcroft $Declare| 3266c45dcabdSAndy Whitcroft module_param_named| 3267a0a0a7a9SKees Cook MODULE_PARM_DESC| 3268c45dcabdSAndy Whitcroft DECLARE_PER_CPU| 3269c45dcabdSAndy Whitcroft DEFINE_PER_CPU| 3270383099fdSAndy Whitcroft __typeof__\(| 327122fd2d3eSStefani Seibold union| 327222fd2d3eSStefani Seibold struct| 3273ea71a0a0SAndy Whitcroft \.$Ident\s*=\s*| 3274ea71a0a0SAndy Whitcroft ^\"|\"$ 3275c45dcabdSAndy Whitcroft }x; 32765eaa20b9SAndy Whitcroft #print "REST<$rest> dstat<$dstat> ctx<$ctx>\n"; 3277f74bd194SAndy Whitcroft if ($dstat ne '' && 3278f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(), 3279f74bd194SAndy Whitcroft $dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo(); 32803cc4b1c3SJoe Perches $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz 3281b9df76acSAndy Whitcroft $dstat !~ /^'X'$/ && # character constants 3282f74bd194SAndy Whitcroft $dstat !~ /$exceptions/ && 3283f74bd194SAndy Whitcroft $dstat !~ /^\.$Ident\s*=/ && # .foo = 3284e942e2c3SJoe Perches $dstat !~ /^(?:\#\s*$Ident|\#\s*$Constant)\s*$/ && # stringification #foo 328572f115f9SAndy Whitcroft $dstat !~ /^do\s*$Constant\s*while\s*$Constant;?$/ && # do {...} while (...); // do {...} while (...) 3286f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant$/ && # for (...) 3287f74bd194SAndy Whitcroft $dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar() 3288f74bd194SAndy Whitcroft $dstat !~ /^do\s*{/ && # do {... 3289f74bd194SAndy Whitcroft $dstat !~ /^\({/) # ({... 3290c45dcabdSAndy Whitcroft { 3291f74bd194SAndy Whitcroft $ctx =~ s/\n*$//; 3292f74bd194SAndy Whitcroft my $herectx = $here . "\n"; 3293f74bd194SAndy Whitcroft my $cnt = statement_rawlines($ctx); 3294f74bd194SAndy Whitcroft 3295f74bd194SAndy Whitcroft for (my $n = 0; $n < $cnt; $n++) { 3296f74bd194SAndy Whitcroft $herectx .= raw_line($linenr, $n) . "\n"; 3297c45dcabdSAndy Whitcroft } 3298c45dcabdSAndy Whitcroft 3299f74bd194SAndy Whitcroft if ($dstat =~ /;/) { 3300f74bd194SAndy Whitcroft ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 3301f74bd194SAndy Whitcroft "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); 3302f74bd194SAndy Whitcroft } else { 3303000d1cc1SJoe Perches ERROR("COMPLEX_MACRO", 3304f74bd194SAndy Whitcroft "Macros with complex values should be enclosed in parenthesis\n" . "$herectx"); 3305d8aaf121SAndy Whitcroft } 33060a920b5bSAndy Whitcroft } 33075023d347SJoe Perches 3308481eb486SJoe Perches# check for line continuations outside of #defines, preprocessor #, and asm 33095023d347SJoe Perches 33105023d347SJoe Perches } else { 33115023d347SJoe Perches if ($prevline !~ /^..*\\$/ && 3312481eb486SJoe Perches $line !~ /^\+\s*\#.*\\$/ && # preprocessor 3313481eb486SJoe Perches $line !~ /^\+.*\b(__asm__|asm)\b.*\\$/ && # asm 33145023d347SJoe Perches $line =~ /^\+.*\\$/) { 33155023d347SJoe Perches WARN("LINE_CONTINUATIONS", 33165023d347SJoe Perches "Avoid unnecessary line continuations\n" . $herecurr); 33175023d347SJoe Perches } 3318653d4876SAndy Whitcroft } 33190a920b5bSAndy Whitcroft 3320b13edf7fSJoe Perches# do {} while (0) macro tests: 3321b13edf7fSJoe Perches# single-statement macros do not need to be enclosed in do while (0) loop, 3322b13edf7fSJoe Perches# macro should not end with a semicolon 3323b13edf7fSJoe Perches if ($^V && $^V ge 5.10.0 && 3324b13edf7fSJoe Perches $realfile !~ m@/vmlinux.lds.h$@ && 3325b13edf7fSJoe Perches $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { 3326b13edf7fSJoe Perches my $ln = $linenr; 3327b13edf7fSJoe Perches my $cnt = $realcnt; 3328b13edf7fSJoe Perches my ($off, $dstat, $dcond, $rest); 3329b13edf7fSJoe Perches my $ctx = ''; 3330b13edf7fSJoe Perches ($dstat, $dcond, $ln, $cnt, $off) = 3331b13edf7fSJoe Perches ctx_statement_block($linenr, $realcnt, 0); 3332b13edf7fSJoe Perches $ctx = $dstat; 3333b13edf7fSJoe Perches 3334b13edf7fSJoe Perches $dstat =~ s/\\\n.//g; 3335b13edf7fSJoe Perches 3336b13edf7fSJoe Perches if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) { 3337b13edf7fSJoe Perches my $stmts = $2; 3338b13edf7fSJoe Perches my $semis = $3; 3339b13edf7fSJoe Perches 3340b13edf7fSJoe Perches $ctx =~ s/\n*$//; 3341b13edf7fSJoe Perches my $cnt = statement_rawlines($ctx); 3342b13edf7fSJoe Perches my $herectx = $here . "\n"; 3343b13edf7fSJoe Perches 3344b13edf7fSJoe Perches for (my $n = 0; $n < $cnt; $n++) { 3345b13edf7fSJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 3346b13edf7fSJoe Perches } 3347b13edf7fSJoe Perches 3348ac8e97f8SJoe Perches if (($stmts =~ tr/;/;/) == 1 && 3349ac8e97f8SJoe Perches $stmts !~ /^\s*(if|while|for|switch)\b/) { 3350b13edf7fSJoe Perches WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", 3351b13edf7fSJoe Perches "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); 3352b13edf7fSJoe Perches } 3353b13edf7fSJoe Perches if (defined $semis && $semis ne "") { 3354b13edf7fSJoe Perches WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON", 3355b13edf7fSJoe Perches "do {} while (0) macros should not be semicolon terminated\n" . "$herectx"); 3356b13edf7fSJoe Perches } 3357b13edf7fSJoe Perches } 3358b13edf7fSJoe Perches } 3359b13edf7fSJoe Perches 3360080ba929SMike Frysinger# make sure symbols are always wrapped with VMLINUX_SYMBOL() ... 3361080ba929SMike Frysinger# all assignments may have only one of the following with an assignment: 3362080ba929SMike Frysinger# . 3363080ba929SMike Frysinger# ALIGN(...) 3364080ba929SMike Frysinger# VMLINUX_SYMBOL(...) 3365080ba929SMike Frysinger if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) { 3366000d1cc1SJoe Perches WARN("MISSING_VMLINUX_SYMBOL", 3367000d1cc1SJoe Perches "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr); 3368080ba929SMike Frysinger } 3369080ba929SMike Frysinger 3370f0a594c1SAndy Whitcroft# check for redundant bracing round if etc 337113214adfSAndy Whitcroft if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { 337213214adfSAndy Whitcroft my ($level, $endln, @chunks) = 3373cf655043SAndy Whitcroft ctx_statement_full($linenr, $realcnt, 1); 337413214adfSAndy Whitcroft #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n"; 3375cf655043SAndy Whitcroft #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"; 3376cf655043SAndy Whitcroft if ($#chunks > 0 && $level == 0) { 3377aad4f614SJoe Perches my @allowed = (); 3378aad4f614SJoe Perches my $allow = 0; 337913214adfSAndy Whitcroft my $seen = 0; 3380773647a0SAndy Whitcroft my $herectx = $here . "\n"; 3381cf655043SAndy Whitcroft my $ln = $linenr - 1; 338213214adfSAndy Whitcroft for my $chunk (@chunks) { 338313214adfSAndy Whitcroft my ($cond, $block) = @{$chunk}; 338413214adfSAndy Whitcroft 3385773647a0SAndy Whitcroft # If the condition carries leading newlines, then count those as offsets. 3386773647a0SAndy Whitcroft my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s); 3387773647a0SAndy Whitcroft my $offset = statement_rawlines($whitespace) - 1; 3388773647a0SAndy Whitcroft 3389aad4f614SJoe Perches $allowed[$allow] = 0; 3390773647a0SAndy Whitcroft #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n"; 3391773647a0SAndy Whitcroft 3392773647a0SAndy Whitcroft # We have looked at and allowed this specific line. 3393773647a0SAndy Whitcroft $suppress_ifbraces{$ln + $offset} = 1; 3394773647a0SAndy Whitcroft 3395773647a0SAndy Whitcroft $herectx .= "$rawlines[$ln + $offset]\n[...]\n"; 3396cf655043SAndy Whitcroft $ln += statement_rawlines($block) - 1; 3397cf655043SAndy Whitcroft 3398773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 339913214adfSAndy Whitcroft 340013214adfSAndy Whitcroft $seen++ if ($block =~ /^\s*{/); 340113214adfSAndy Whitcroft 3402aad4f614SJoe Perches #print "cond<$cond> block<$block> allowed<$allowed[$allow]>\n"; 3403cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 3404cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 3405aad4f614SJoe Perches $allowed[$allow] = 1; 340613214adfSAndy Whitcroft } 340713214adfSAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 3408cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 3409aad4f614SJoe Perches $allowed[$allow] = 1; 341013214adfSAndy Whitcroft } 3411cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 3412cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 3413aad4f614SJoe Perches $allowed[$allow] = 1; 341413214adfSAndy Whitcroft } 3415aad4f614SJoe Perches $allow++; 341613214adfSAndy Whitcroft } 3417aad4f614SJoe Perches if ($seen) { 3418aad4f614SJoe Perches my $sum_allowed = 0; 3419aad4f614SJoe Perches foreach (@allowed) { 3420aad4f614SJoe Perches $sum_allowed += $_; 3421aad4f614SJoe Perches } 3422aad4f614SJoe Perches if ($sum_allowed == 0) { 3423000d1cc1SJoe Perches WARN("BRACES", 3424000d1cc1SJoe Perches "braces {} are not necessary for any arm of this statement\n" . $herectx); 3425aad4f614SJoe Perches } elsif ($sum_allowed != $allow && 3426aad4f614SJoe Perches $seen != $allow) { 3427aad4f614SJoe Perches CHK("BRACES", 3428aad4f614SJoe Perches "braces {} should be used on all arms of this statement\n" . $herectx); 3429aad4f614SJoe Perches } 343013214adfSAndy Whitcroft } 343113214adfSAndy Whitcroft } 343213214adfSAndy Whitcroft } 3433773647a0SAndy Whitcroft if (!defined $suppress_ifbraces{$linenr - 1} && 343413214adfSAndy Whitcroft $line =~ /\b(if|while|for|else)\b/) { 3435cf655043SAndy Whitcroft my $allowed = 0; 3436f0a594c1SAndy Whitcroft 3437cf655043SAndy Whitcroft # Check the pre-context. 3438cf655043SAndy Whitcroft if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) { 3439cf655043SAndy Whitcroft #print "APW: ALLOWED: pre<$1>\n"; 3440cf655043SAndy Whitcroft $allowed = 1; 3441f0a594c1SAndy Whitcroft } 3442773647a0SAndy Whitcroft 3443773647a0SAndy Whitcroft my ($level, $endln, @chunks) = 3444773647a0SAndy Whitcroft ctx_statement_full($linenr, $realcnt, $-[0]); 3445773647a0SAndy Whitcroft 3446cf655043SAndy Whitcroft # Check the condition. 3447cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[0]}; 3448773647a0SAndy Whitcroft #print "CHECKING<$linenr> cond<$cond> block<$block>\n"; 3449cf655043SAndy Whitcroft if (defined $cond) { 3450773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 3451cf655043SAndy Whitcroft } 3452cf655043SAndy Whitcroft if (statement_lines($cond) > 1) { 3453cf655043SAndy Whitcroft #print "APW: ALLOWED: cond<$cond>\n"; 3454cf655043SAndy Whitcroft $allowed = 1; 3455cf655043SAndy Whitcroft } 3456cf655043SAndy Whitcroft if ($block =~/\b(?:if|for|while)\b/) { 3457cf655043SAndy Whitcroft #print "APW: ALLOWED: block<$block>\n"; 3458cf655043SAndy Whitcroft $allowed = 1; 3459cf655043SAndy Whitcroft } 3460cf655043SAndy Whitcroft if (statement_block_size($block) > 1) { 3461cf655043SAndy Whitcroft #print "APW: ALLOWED: lines block<$block>\n"; 3462cf655043SAndy Whitcroft $allowed = 1; 3463cf655043SAndy Whitcroft } 3464cf655043SAndy Whitcroft # Check the post-context. 3465cf655043SAndy Whitcroft if (defined $chunks[1]) { 3466cf655043SAndy Whitcroft my ($cond, $block) = @{$chunks[1]}; 3467cf655043SAndy Whitcroft if (defined $cond) { 3468773647a0SAndy Whitcroft substr($block, 0, length($cond), ''); 3469cf655043SAndy Whitcroft } 3470cf655043SAndy Whitcroft if ($block =~ /^\s*\{/) { 3471cf655043SAndy Whitcroft #print "APW: ALLOWED: chunk-1 block<$block>\n"; 3472cf655043SAndy Whitcroft $allowed = 1; 3473cf655043SAndy Whitcroft } 3474cf655043SAndy Whitcroft } 3475cf655043SAndy Whitcroft if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) { 347669932487SJustin P. Mattock my $herectx = $here . "\n"; 3477f055663cSAndy Whitcroft my $cnt = statement_rawlines($block); 3478cf655043SAndy Whitcroft 3479f055663cSAndy Whitcroft for (my $n = 0; $n < $cnt; $n++) { 348069932487SJustin P. Mattock $herectx .= raw_line($linenr, $n) . "\n"; 3481cf655043SAndy Whitcroft } 3482cf655043SAndy Whitcroft 3483000d1cc1SJoe Perches WARN("BRACES", 3484000d1cc1SJoe Perches "braces {} are not necessary for single statement blocks\n" . $herectx); 3485f0a594c1SAndy Whitcroft } 3486f0a594c1SAndy Whitcroft } 3487f0a594c1SAndy Whitcroft 34880979ae66SJoe Perches# check for unnecessary blank lines around braces 348977b9a53aSJoe Perches if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) { 34900979ae66SJoe Perches CHK("BRACES", 34910979ae66SJoe Perches "Blank lines aren't necessary before a close brace '}'\n" . $hereprev); 34920979ae66SJoe Perches } 349377b9a53aSJoe Perches if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) { 34940979ae66SJoe Perches CHK("BRACES", 34950979ae66SJoe Perches "Blank lines aren't necessary after an open brace '{'\n" . $hereprev); 34960979ae66SJoe Perches } 34970979ae66SJoe Perches 34984a0df2efSAndy Whitcroft# no volatiles please 34996c72ffaaSAndy Whitcroft my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; 35006c72ffaaSAndy Whitcroft if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { 3501000d1cc1SJoe Perches WARN("VOLATILE", 3502000d1cc1SJoe Perches "Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr); 35034a0df2efSAndy Whitcroft } 35044a0df2efSAndy Whitcroft 350500df344fSAndy Whitcroft# warn about #if 0 3506c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*if\s+0\b/) { 3507000d1cc1SJoe Perches CHK("REDUNDANT_CODE", 3508000d1cc1SJoe Perches "if this code is redundant consider removing it\n" . 3509de7d4f0eSAndy Whitcroft $herecurr); 35104a0df2efSAndy Whitcroft } 35114a0df2efSAndy Whitcroft 351203df4b51SAndy Whitcroft# check for needless "if (<foo>) fn(<foo>)" uses 351303df4b51SAndy Whitcroft if ($prevline =~ /\bif\s*\(\s*($Lval)\s*\)/) { 351403df4b51SAndy Whitcroft my $expr = '\s*\(\s*' . quotemeta($1) . '\s*\)\s*;'; 351503df4b51SAndy Whitcroft if ($line =~ /\b(kfree|usb_free_urb|debugfs_remove(?:_recursive)?)$expr/) { 351603df4b51SAndy Whitcroft WARN('NEEDLESS_IF', 351703df4b51SAndy Whitcroft "$1(NULL) is safe this check is probably not required\n" . $hereprev); 35184c432a8fSGreg Kroah-Hartman } 35194c432a8fSGreg Kroah-Hartman } 3520f0a594c1SAndy Whitcroft 35211a15a250SPatrick Pannuto# prefer usleep_range over udelay 352237581c28SBruce Allan if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) { 35231a15a250SPatrick Pannuto # ignore udelay's < 10, however 352437581c28SBruce Allan if (! ($1 < 10) ) { 3525000d1cc1SJoe Perches CHK("USLEEP_RANGE", 3526000d1cc1SJoe Perches "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $line); 35271a15a250SPatrick Pannuto } 35281a15a250SPatrick Pannuto } 35291a15a250SPatrick Pannuto 353009ef8725SPatrick Pannuto# warn about unexpectedly long msleep's 353109ef8725SPatrick Pannuto if ($line =~ /\bmsleep\s*\((\d+)\);/) { 353209ef8725SPatrick Pannuto if ($1 < 20) { 3533000d1cc1SJoe Perches WARN("MSLEEP", 3534000d1cc1SJoe Perches "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $line); 353509ef8725SPatrick Pannuto } 353609ef8725SPatrick Pannuto } 353709ef8725SPatrick Pannuto 353836ec1939SJoe Perches# check for comparisons of jiffies 353936ec1939SJoe Perches if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) { 354036ec1939SJoe Perches WARN("JIFFIES_COMPARISON", 354136ec1939SJoe Perches "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr); 354236ec1939SJoe Perches } 354336ec1939SJoe Perches 35449d7a34a5SJoe Perches# check for comparisons of get_jiffies_64() 35459d7a34a5SJoe Perches if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) { 35469d7a34a5SJoe Perches WARN("JIFFIES_COMPARISON", 35479d7a34a5SJoe Perches "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr); 35489d7a34a5SJoe Perches } 35499d7a34a5SJoe Perches 355000df344fSAndy Whitcroft# warn about #ifdefs in C files 3551c45dcabdSAndy Whitcroft# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { 355200df344fSAndy Whitcroft# print "#ifdef in C files should be avoided\n"; 355300df344fSAndy Whitcroft# print "$herecurr"; 355400df344fSAndy Whitcroft# $clean = 0; 355500df344fSAndy Whitcroft# } 355600df344fSAndy Whitcroft 355722f2a2efSAndy Whitcroft# warn about spacing in #ifdefs 3558c45dcabdSAndy Whitcroft if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { 3559*3705ce5bSJoe Perches if (ERROR("SPACING", 3560*3705ce5bSJoe Perches "exactly one space required after that #$1\n" . $herecurr) && 3561*3705ce5bSJoe Perches $fix) { 3562*3705ce5bSJoe Perches $fixed[$linenr - 1] =~ 3563*3705ce5bSJoe Perches s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /; 3564*3705ce5bSJoe Perches } 3565*3705ce5bSJoe Perches 356622f2a2efSAndy Whitcroft } 356722f2a2efSAndy Whitcroft 35684a0df2efSAndy Whitcroft# check for spinlock_t definitions without a comment. 3569171ae1a4SAndy Whitcroft if ($line =~ /^.\s*(struct\s+mutex|spinlock_t)\s+\S+;/ || 3570171ae1a4SAndy Whitcroft $line =~ /^.\s*(DEFINE_MUTEX)\s*\(/) { 35714a0df2efSAndy Whitcroft my $which = $1; 35724a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 3573000d1cc1SJoe Perches CHK("UNCOMMENTED_DEFINITION", 3574000d1cc1SJoe Perches "$1 definition without comment\n" . $herecurr); 35754a0df2efSAndy Whitcroft } 35764a0df2efSAndy Whitcroft } 35774a0df2efSAndy Whitcroft# check for memory barriers without a comment. 35784a0df2efSAndy Whitcroft if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) { 35794a0df2efSAndy Whitcroft if (!ctx_has_comment($first_line, $linenr)) { 3580000d1cc1SJoe Perches CHK("MEMORY_BARRIER", 3581000d1cc1SJoe Perches "memory barrier without comment\n" . $herecurr); 35824a0df2efSAndy Whitcroft } 35834a0df2efSAndy Whitcroft } 35844a0df2efSAndy Whitcroft# check of hardware specific defines 3585c45dcabdSAndy Whitcroft if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { 3586000d1cc1SJoe Perches CHK("ARCH_DEFINES", 3587000d1cc1SJoe Perches "architecture specific defines should be avoided\n" . $herecurr); 35880a920b5bSAndy Whitcroft } 3589653d4876SAndy Whitcroft 3590d4977c78STobias Klauser# Check that the storage class is at the beginning of a declaration 3591d4977c78STobias Klauser if ($line =~ /\b$Storage\b/ && $line !~ /^.\s*$Storage\b/) { 3592000d1cc1SJoe Perches WARN("STORAGE_CLASS", 3593000d1cc1SJoe Perches "storage class should be at the beginning of the declaration\n" . $herecurr) 3594d4977c78STobias Klauser } 3595d4977c78STobias Klauser 3596de7d4f0eSAndy Whitcroft# check the location of the inline attribute, that it is between 3597de7d4f0eSAndy Whitcroft# storage class and type. 35989c0ca6f9SAndy Whitcroft if ($line =~ /\b$Type\s+$Inline\b/ || 35999c0ca6f9SAndy Whitcroft $line =~ /\b$Inline\s+$Storage\b/) { 3600000d1cc1SJoe Perches ERROR("INLINE_LOCATION", 3601000d1cc1SJoe Perches "inline keyword should sit between storage class and type\n" . $herecurr); 3602de7d4f0eSAndy Whitcroft } 3603de7d4f0eSAndy Whitcroft 36048905a67cSAndy Whitcroft# Check for __inline__ and __inline, prefer inline 36058905a67cSAndy Whitcroft if ($line =~ /\b(__inline__|__inline)\b/) { 3606000d1cc1SJoe Perches WARN("INLINE", 3607000d1cc1SJoe Perches "plain inline is preferred over $1\n" . $herecurr); 36088905a67cSAndy Whitcroft } 36098905a67cSAndy Whitcroft 36103d130fd0SJoe Perches# Check for __attribute__ packed, prefer __packed 36113d130fd0SJoe Perches if ($line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) { 3612000d1cc1SJoe Perches WARN("PREFER_PACKED", 3613000d1cc1SJoe Perches "__packed is preferred over __attribute__((packed))\n" . $herecurr); 36143d130fd0SJoe Perches } 36153d130fd0SJoe Perches 361639b7e287SJoe Perches# Check for __attribute__ aligned, prefer __aligned 361739b7e287SJoe Perches if ($line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { 3618000d1cc1SJoe Perches WARN("PREFER_ALIGNED", 3619000d1cc1SJoe Perches "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); 362039b7e287SJoe Perches } 362139b7e287SJoe Perches 36225f14d3bdSJoe Perches# Check for __attribute__ format(printf, prefer __printf 36235f14d3bdSJoe Perches if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { 36245f14d3bdSJoe Perches WARN("PREFER_PRINTF", 36255f14d3bdSJoe Perches "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr); 36265f14d3bdSJoe Perches } 36275f14d3bdSJoe Perches 36286061d949SJoe Perches# Check for __attribute__ format(scanf, prefer __scanf 36296061d949SJoe Perches if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { 36306061d949SJoe Perches WARN("PREFER_SCANF", 36316061d949SJoe Perches "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr); 36326061d949SJoe Perches } 36336061d949SJoe Perches 36348f53a9b8SJoe Perches# check for sizeof(&) 36358f53a9b8SJoe Perches if ($line =~ /\bsizeof\s*\(\s*\&/) { 3636000d1cc1SJoe Perches WARN("SIZEOF_ADDRESS", 3637000d1cc1SJoe Perches "sizeof(& should be avoided\n" . $herecurr); 36388f53a9b8SJoe Perches } 36398f53a9b8SJoe Perches 364066c80b60SJoe Perches# check for sizeof without parenthesis 364166c80b60SJoe Perches if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) { 364266c80b60SJoe Perches WARN("SIZEOF_PARENTHESIS", 364366c80b60SJoe Perches "sizeof $1 should be sizeof($1)\n" . $herecurr); 364466c80b60SJoe Perches } 364566c80b60SJoe Perches 3646428e2fdcSJoe Perches# check for line continuations in quoted strings with odd counts of " 3647428e2fdcSJoe Perches if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) { 3648000d1cc1SJoe Perches WARN("LINE_CONTINUATIONS", 3649000d1cc1SJoe Perches "Avoid line continuations in quoted strings\n" . $herecurr); 3650428e2fdcSJoe Perches } 3651428e2fdcSJoe Perches 365288982feaSJoe Perches# check for struct spinlock declarations 365388982feaSJoe Perches if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) { 365488982feaSJoe Perches WARN("USE_SPINLOCK_T", 365588982feaSJoe Perches "struct spinlock should be spinlock_t\n" . $herecurr); 365688982feaSJoe Perches } 365788982feaSJoe Perches 3658a6962d72SJoe Perches# check for seq_printf uses that could be seq_puts 3659a6962d72SJoe Perches if ($line =~ /\bseq_printf\s*\(/) { 3660a6962d72SJoe Perches my $fmt = get_quoted_string($line, $rawline); 3661a6962d72SJoe Perches if ($fmt !~ /[^\\]\%/) { 3662a6962d72SJoe Perches WARN("PREFER_SEQ_PUTS", 3663a6962d72SJoe Perches "Prefer seq_puts to seq_printf\n" . $herecurr); 3664a6962d72SJoe Perches } 3665a6962d72SJoe Perches } 3666a6962d72SJoe Perches 3667554e165cSAndy Whitcroft# Check for misused memsets 3668d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 3669d1fe9c09SJoe Perches defined $stat && 3670d7c76ba7SJoe Perches $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/s) { 3671554e165cSAndy Whitcroft 3672d7c76ba7SJoe Perches my $ms_addr = $2; 3673d1fe9c09SJoe Perches my $ms_val = $7; 3674d1fe9c09SJoe Perches my $ms_size = $12; 3675d7c76ba7SJoe Perches 3676554e165cSAndy Whitcroft if ($ms_size =~ /^(0x|)0$/i) { 3677554e165cSAndy Whitcroft ERROR("MEMSET", 3678d7c76ba7SJoe Perches "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n"); 3679554e165cSAndy Whitcroft } elsif ($ms_size =~ /^(0x|)1$/i) { 3680554e165cSAndy Whitcroft WARN("MEMSET", 3681d7c76ba7SJoe Perches "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n"); 3682d7c76ba7SJoe Perches } 3683d7c76ba7SJoe Perches } 3684d7c76ba7SJoe Perches 3685d7c76ba7SJoe Perches# typecasts on min/max could be min_t/max_t 3686d1fe9c09SJoe Perches if ($^V && $^V ge 5.10.0 && 3687d1fe9c09SJoe Perches defined $stat && 3688d7c76ba7SJoe Perches $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { 3689d1fe9c09SJoe Perches if (defined $2 || defined $7) { 3690d7c76ba7SJoe Perches my $call = $1; 3691d7c76ba7SJoe Perches my $cast1 = deparenthesize($2); 3692d7c76ba7SJoe Perches my $arg1 = $3; 3693d1fe9c09SJoe Perches my $cast2 = deparenthesize($7); 3694d1fe9c09SJoe Perches my $arg2 = $8; 3695d7c76ba7SJoe Perches my $cast; 3696d7c76ba7SJoe Perches 3697d1fe9c09SJoe Perches if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) { 3698d7c76ba7SJoe Perches $cast = "$cast1 or $cast2"; 3699d7c76ba7SJoe Perches } elsif ($cast1 ne "") { 3700d7c76ba7SJoe Perches $cast = $cast1; 3701d7c76ba7SJoe Perches } else { 3702d7c76ba7SJoe Perches $cast = $cast2; 3703d7c76ba7SJoe Perches } 3704d7c76ba7SJoe Perches WARN("MINMAX", 3705d7c76ba7SJoe Perches "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n"); 3706554e165cSAndy Whitcroft } 3707554e165cSAndy Whitcroft } 3708554e165cSAndy Whitcroft 37094a273195SJoe Perches# check usleep_range arguments 37104a273195SJoe Perches if ($^V && $^V ge 5.10.0 && 37114a273195SJoe Perches defined $stat && 37124a273195SJoe Perches $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { 37134a273195SJoe Perches my $min = $1; 37144a273195SJoe Perches my $max = $7; 37154a273195SJoe Perches if ($min eq $max) { 37164a273195SJoe Perches WARN("USLEEP_RANGE", 37174a273195SJoe Perches "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); 37184a273195SJoe Perches } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && 37194a273195SJoe Perches $min > $max) { 37204a273195SJoe Perches WARN("USLEEP_RANGE", 37214a273195SJoe Perches "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); 37224a273195SJoe Perches } 37234a273195SJoe Perches } 37244a273195SJoe Perches 3725de7d4f0eSAndy Whitcroft# check for new externs in .c files. 3726171ae1a4SAndy Whitcroft if ($realfile =~ /\.c$/ && defined $stat && 3727c45dcabdSAndy Whitcroft $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) 3728171ae1a4SAndy Whitcroft { 3729c45dcabdSAndy Whitcroft my $function_name = $1; 3730c45dcabdSAndy Whitcroft my $paren_space = $2; 3731171ae1a4SAndy Whitcroft 3732171ae1a4SAndy Whitcroft my $s = $stat; 3733171ae1a4SAndy Whitcroft if (defined $cond) { 3734171ae1a4SAndy Whitcroft substr($s, 0, length($cond), ''); 3735171ae1a4SAndy Whitcroft } 3736c45dcabdSAndy Whitcroft if ($s =~ /^\s*;/ && 3737c45dcabdSAndy Whitcroft $function_name ne 'uninitialized_var') 3738c45dcabdSAndy Whitcroft { 3739000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 3740000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 3741de7d4f0eSAndy Whitcroft } 3742de7d4f0eSAndy Whitcroft 3743171ae1a4SAndy Whitcroft if ($paren_space =~ /\n/) { 3744000d1cc1SJoe Perches WARN("FUNCTION_ARGUMENTS", 3745000d1cc1SJoe Perches "arguments for function declarations should follow identifier\n" . $herecurr); 3746171ae1a4SAndy Whitcroft } 37479c9ba34eSAndy Whitcroft 37489c9ba34eSAndy Whitcroft } elsif ($realfile =~ /\.c$/ && defined $stat && 37499c9ba34eSAndy Whitcroft $stat =~ /^.\s*extern\s+/) 37509c9ba34eSAndy Whitcroft { 3751000d1cc1SJoe Perches WARN("AVOID_EXTERNS", 3752000d1cc1SJoe Perches "externs should be avoided in .c files\n" . $herecurr); 3753171ae1a4SAndy Whitcroft } 3754171ae1a4SAndy Whitcroft 3755de7d4f0eSAndy Whitcroft# checks for new __setup's 3756de7d4f0eSAndy Whitcroft if ($rawline =~ /\b__setup\("([^"]*)"/) { 3757de7d4f0eSAndy Whitcroft my $name = $1; 3758de7d4f0eSAndy Whitcroft 3759de7d4f0eSAndy Whitcroft if (!grep(/$name/, @setup_docs)) { 3760000d1cc1SJoe Perches CHK("UNDOCUMENTED_SETUP", 3761000d1cc1SJoe Perches "__setup appears un-documented -- check Documentation/kernel-parameters.txt\n" . $herecurr); 3762de7d4f0eSAndy Whitcroft } 3763653d4876SAndy Whitcroft } 37649c0ca6f9SAndy Whitcroft 37659c0ca6f9SAndy Whitcroft# check for pointless casting of kmalloc return 3766caf2a54fSJoe Perches if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) { 3767000d1cc1SJoe Perches WARN("UNNECESSARY_CASTS", 3768000d1cc1SJoe Perches "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); 37699c0ca6f9SAndy Whitcroft } 377013214adfSAndy Whitcroft 3771a640d25cSJoe Perches# alloc style 3772a640d25cSJoe Perches# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) 3773a640d25cSJoe Perches if ($^V && $^V ge 5.10.0 && 3774a640d25cSJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { 3775a640d25cSJoe Perches CHK("ALLOC_SIZEOF_STRUCT", 3776a640d25cSJoe Perches "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); 3777a640d25cSJoe Perches } 3778a640d25cSJoe Perches 3779972fdea2SJoe Perches# check for krealloc arg reuse 3780972fdea2SJoe Perches if ($^V && $^V ge 5.10.0 && 3781972fdea2SJoe Perches $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) { 3782972fdea2SJoe Perches WARN("KREALLOC_ARG_REUSE", 3783972fdea2SJoe Perches "Reusing the krealloc arg is almost always a bug\n" . $herecurr); 3784972fdea2SJoe Perches } 3785972fdea2SJoe Perches 37865ce59ae0SJoe Perches# check for alloc argument mismatch 37875ce59ae0SJoe Perches if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) { 37885ce59ae0SJoe Perches WARN("ALLOC_ARRAY_ARGS", 37895ce59ae0SJoe Perches "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr); 37905ce59ae0SJoe Perches } 37915ce59ae0SJoe Perches 3792caf2a54fSJoe Perches# check for multiple semicolons 3793caf2a54fSJoe Perches if ($line =~ /;\s*;\s*$/) { 3794000d1cc1SJoe Perches WARN("ONE_SEMICOLON", 3795000d1cc1SJoe Perches "Statements terminations use 1 semicolon\n" . $herecurr); 3796d1e2ad07SJoe Perches } 3797d1e2ad07SJoe Perches 3798d1e2ad07SJoe Perches# check for switch/default statements without a break; 3799d1e2ad07SJoe Perches if ($^V && $^V ge 5.10.0 && 3800d1e2ad07SJoe Perches defined $stat && 3801d1e2ad07SJoe Perches $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { 3802d1e2ad07SJoe Perches my $ctx = ''; 3803d1e2ad07SJoe Perches my $herectx = $here . "\n"; 3804d1e2ad07SJoe Perches my $cnt = statement_rawlines($stat); 3805d1e2ad07SJoe Perches for (my $n = 0; $n < $cnt; $n++) { 3806d1e2ad07SJoe Perches $herectx .= raw_line($linenr, $n) . "\n"; 3807d1e2ad07SJoe Perches } 3808d1e2ad07SJoe Perches WARN("DEFAULT_NO_BREAK", 3809d1e2ad07SJoe Perches "switch default: should use break\n" . $herectx); 3810caf2a54fSJoe Perches } 3811caf2a54fSJoe Perches 381213214adfSAndy Whitcroft# check for gcc specific __FUNCTION__ 381313214adfSAndy Whitcroft if ($line =~ /__FUNCTION__/) { 3814000d1cc1SJoe Perches WARN("USE_FUNC", 3815000d1cc1SJoe Perches "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr); 381613214adfSAndy Whitcroft } 3817773647a0SAndy Whitcroft 38182c92488aSJoe Perches# check for use of yield() 38192c92488aSJoe Perches if ($line =~ /\byield\s*\(\s*\)/) { 38202c92488aSJoe Perches WARN("YIELD", 38212c92488aSJoe Perches "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr); 38222c92488aSJoe Perches } 38232c92488aSJoe Perches 3824179f8f40SJoe Perches# check for comparisons against true and false 3825179f8f40SJoe Perches if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) { 3826179f8f40SJoe Perches my $lead = $1; 3827179f8f40SJoe Perches my $arg = $2; 3828179f8f40SJoe Perches my $test = $3; 3829179f8f40SJoe Perches my $otype = $4; 3830179f8f40SJoe Perches my $trail = $5; 3831179f8f40SJoe Perches my $op = "!"; 3832179f8f40SJoe Perches 3833179f8f40SJoe Perches ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); 3834179f8f40SJoe Perches 3835179f8f40SJoe Perches my $type = lc($otype); 3836179f8f40SJoe Perches if ($type =~ /^(?:true|false)$/) { 3837179f8f40SJoe Perches if (("$test" eq "==" && "$type" eq "true") || 3838179f8f40SJoe Perches ("$test" eq "!=" && "$type" eq "false")) { 3839179f8f40SJoe Perches $op = ""; 3840179f8f40SJoe Perches } 3841179f8f40SJoe Perches 3842179f8f40SJoe Perches CHK("BOOL_COMPARISON", 3843179f8f40SJoe Perches "Using comparison to $otype is error prone\n" . $herecurr); 3844179f8f40SJoe Perches 3845179f8f40SJoe Perches## maybe suggesting a correct construct would better 3846179f8f40SJoe Perches## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); 3847179f8f40SJoe Perches 3848179f8f40SJoe Perches } 3849179f8f40SJoe Perches } 3850179f8f40SJoe Perches 38514882720bSThomas Gleixner# check for semaphores initialized locked 38524882720bSThomas Gleixner if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) { 3853000d1cc1SJoe Perches WARN("CONSIDER_COMPLETION", 3854000d1cc1SJoe Perches "consider using a completion\n" . $herecurr); 3855773647a0SAndy Whitcroft } 38566712d858SJoe Perches 385767d0a075SJoe Perches# recommend kstrto* over simple_strto* and strict_strto* 385867d0a075SJoe Perches if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) { 3859000d1cc1SJoe Perches WARN("CONSIDER_KSTRTO", 386067d0a075SJoe Perches "$1 is obsolete, use k$3 instead\n" . $herecurr); 3861773647a0SAndy Whitcroft } 38626712d858SJoe Perches 3863f3db6639SMichael Ellerman# check for __initcall(), use device_initcall() explicitly please 3864f3db6639SMichael Ellerman if ($line =~ /^.\s*__initcall\s*\(/) { 3865000d1cc1SJoe Perches WARN("USE_DEVICE_INITCALL", 3866000d1cc1SJoe Perches "please use device_initcall() instead of __initcall()\n" . $herecurr); 3867f3db6639SMichael Ellerman } 38686712d858SJoe Perches 386979404849SEmese Revfy# check for various ops structs, ensure they are const. 387079404849SEmese Revfy my $struct_ops = qr{acpi_dock_ops| 387179404849SEmese Revfy address_space_operations| 387279404849SEmese Revfy backlight_ops| 387379404849SEmese Revfy block_device_operations| 387479404849SEmese Revfy dentry_operations| 387579404849SEmese Revfy dev_pm_ops| 387679404849SEmese Revfy dma_map_ops| 387779404849SEmese Revfy extent_io_ops| 387879404849SEmese Revfy file_lock_operations| 387979404849SEmese Revfy file_operations| 388079404849SEmese Revfy hv_ops| 388179404849SEmese Revfy ide_dma_ops| 388279404849SEmese Revfy intel_dvo_dev_ops| 388379404849SEmese Revfy item_operations| 388479404849SEmese Revfy iwl_ops| 388579404849SEmese Revfy kgdb_arch| 388679404849SEmese Revfy kgdb_io| 388779404849SEmese Revfy kset_uevent_ops| 388879404849SEmese Revfy lock_manager_operations| 388979404849SEmese Revfy microcode_ops| 389079404849SEmese Revfy mtrr_ops| 389179404849SEmese Revfy neigh_ops| 389279404849SEmese Revfy nlmsvc_binding| 389379404849SEmese Revfy pci_raw_ops| 389479404849SEmese Revfy pipe_buf_operations| 389579404849SEmese Revfy platform_hibernation_ops| 389679404849SEmese Revfy platform_suspend_ops| 389779404849SEmese Revfy proto_ops| 389879404849SEmese Revfy rpc_pipe_ops| 389979404849SEmese Revfy seq_operations| 390079404849SEmese Revfy snd_ac97_build_ops| 390179404849SEmese Revfy soc_pcmcia_socket_ops| 390279404849SEmese Revfy stacktrace_ops| 390379404849SEmese Revfy sysfs_ops| 390479404849SEmese Revfy tty_operations| 390579404849SEmese Revfy usb_mon_operations| 390679404849SEmese Revfy wd_ops}x; 39076903ffb2SAndy Whitcroft if ($line !~ /\bconst\b/ && 390879404849SEmese Revfy $line =~ /\bstruct\s+($struct_ops)\b/) { 3909000d1cc1SJoe Perches WARN("CONST_STRUCT", 3910000d1cc1SJoe Perches "struct $1 should normally be const\n" . 39116903ffb2SAndy Whitcroft $herecurr); 39122b6db5cbSAndy Whitcroft } 3913773647a0SAndy Whitcroft 3914773647a0SAndy Whitcroft# use of NR_CPUS is usually wrong 3915773647a0SAndy Whitcroft# ignore definitions of NR_CPUS and usage to define arrays as likely right 3916773647a0SAndy Whitcroft if ($line =~ /\bNR_CPUS\b/ && 3917c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && 3918c45dcabdSAndy Whitcroft $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && 3919171ae1a4SAndy Whitcroft $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && 3920171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && 3921171ae1a4SAndy Whitcroft $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) 3922773647a0SAndy Whitcroft { 3923000d1cc1SJoe Perches WARN("NR_CPUS", 3924000d1cc1SJoe Perches "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr); 3925773647a0SAndy Whitcroft } 39269c9ba34eSAndy Whitcroft 39279c9ba34eSAndy Whitcroft# check for %L{u,d,i} in strings 39289c9ba34eSAndy Whitcroft my $string; 39299c9ba34eSAndy Whitcroft while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) { 39309c9ba34eSAndy Whitcroft $string = substr($rawline, $-[1], $+[1] - $-[1]); 39312a1bc5d5SAndy Whitcroft $string =~ s/%%/__/g; 39329c9ba34eSAndy Whitcroft if ($string =~ /(?<!%)%L[udi]/) { 3933000d1cc1SJoe Perches WARN("PRINTF_L", 3934000d1cc1SJoe Perches "\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr); 39359c9ba34eSAndy Whitcroft last; 39369c9ba34eSAndy Whitcroft } 39379c9ba34eSAndy Whitcroft } 3938691d77b6SAndy Whitcroft 3939691d77b6SAndy Whitcroft# whine mightly about in_atomic 3940691d77b6SAndy Whitcroft if ($line =~ /\bin_atomic\s*\(/) { 3941691d77b6SAndy Whitcroft if ($realfile =~ m@^drivers/@) { 3942000d1cc1SJoe Perches ERROR("IN_ATOMIC", 3943000d1cc1SJoe Perches "do not use in_atomic in drivers\n" . $herecurr); 3944f4a87736SAndy Whitcroft } elsif ($realfile !~ m@^kernel/@) { 3945000d1cc1SJoe Perches WARN("IN_ATOMIC", 3946000d1cc1SJoe Perches "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr); 3947691d77b6SAndy Whitcroft } 3948691d77b6SAndy Whitcroft } 39491704f47bSPeter Zijlstra 39501704f47bSPeter Zijlstra# check for lockdep_set_novalidate_class 39511704f47bSPeter Zijlstra if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ || 39521704f47bSPeter Zijlstra $line =~ /__lockdep_no_validate__\s*\)/ ) { 39531704f47bSPeter Zijlstra if ($realfile !~ m@^kernel/lockdep@ && 39541704f47bSPeter Zijlstra $realfile !~ m@^include/linux/lockdep@ && 39551704f47bSPeter Zijlstra $realfile !~ m@^drivers/base/core@) { 3956000d1cc1SJoe Perches ERROR("LOCKDEP", 3957000d1cc1SJoe Perches "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr); 39581704f47bSPeter Zijlstra } 39591704f47bSPeter Zijlstra } 396088f8831cSDave Jones 396188f8831cSDave Jones if ($line =~ /debugfs_create_file.*S_IWUGO/ || 396288f8831cSDave Jones $line =~ /DEVICE_ATTR.*S_IWUGO/ ) { 3963000d1cc1SJoe Perches WARN("EXPORTED_WORLD_WRITABLE", 3964000d1cc1SJoe Perches "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); 396588f8831cSDave Jones } 396613214adfSAndy Whitcroft } 396713214adfSAndy Whitcroft 396813214adfSAndy Whitcroft # If we have no input at all, then there is nothing to report on 396913214adfSAndy Whitcroft # so just keep quiet. 397013214adfSAndy Whitcroft if ($#rawlines == -1) { 397113214adfSAndy Whitcroft exit(0); 39720a920b5bSAndy Whitcroft } 39730a920b5bSAndy Whitcroft 39748905a67cSAndy Whitcroft # In mailback mode only produce a report in the negative, for 39758905a67cSAndy Whitcroft # things that appear to be patches. 39768905a67cSAndy Whitcroft if ($mailback && ($clean == 1 || !$is_patch)) { 39778905a67cSAndy Whitcroft exit(0); 39788905a67cSAndy Whitcroft } 39798905a67cSAndy Whitcroft 39808905a67cSAndy Whitcroft # This is not a patch, and we are are in 'no-patch' mode so 39818905a67cSAndy Whitcroft # just keep quiet. 39828905a67cSAndy Whitcroft if (!$chk_patch && !$is_patch) { 39838905a67cSAndy Whitcroft exit(0); 39848905a67cSAndy Whitcroft } 39858905a67cSAndy Whitcroft 39868905a67cSAndy Whitcroft if (!$is_patch) { 3987000d1cc1SJoe Perches ERROR("NOT_UNIFIED_DIFF", 3988000d1cc1SJoe Perches "Does not appear to be a unified-diff format patch\n"); 39890a920b5bSAndy Whitcroft } 39900a920b5bSAndy Whitcroft if ($is_patch && $chk_signoff && $signoff == 0) { 3991000d1cc1SJoe Perches ERROR("MISSING_SIGN_OFF", 3992000d1cc1SJoe Perches "Missing Signed-off-by: line(s)\n"); 39930a920b5bSAndy Whitcroft } 39940a920b5bSAndy Whitcroft 3995f0a594c1SAndy Whitcroft print report_dump(); 399613214adfSAndy Whitcroft if ($summary && !($clean == 1 && $quiet == 1)) { 399713214adfSAndy Whitcroft print "$filename " if ($summary_file); 39986c72ffaaSAndy Whitcroft print "total: $cnt_error errors, $cnt_warn warnings, " . 39996c72ffaaSAndy Whitcroft (($check)? "$cnt_chk checks, " : "") . 40006c72ffaaSAndy Whitcroft "$cnt_lines lines checked\n"; 40018905a67cSAndy Whitcroft print "\n" if ($quiet == 0); 40026c72ffaaSAndy Whitcroft } 40038905a67cSAndy Whitcroft 4004d2c0a235SAndy Whitcroft if ($quiet == 0) { 4005d1fe9c09SJoe Perches 4006d1fe9c09SJoe Perches if ($^V lt 5.10.0) { 4007d1fe9c09SJoe Perches print("NOTE: perl $^V is not modern enough to detect all possible issues.\n"); 4008d1fe9c09SJoe Perches print("An upgrade to at least perl v5.10.0 is suggested.\n\n"); 4009d1fe9c09SJoe Perches } 4010d1fe9c09SJoe Perches 4011d2c0a235SAndy Whitcroft # If there were whitespace errors which cleanpatch can fix 4012d2c0a235SAndy Whitcroft # then suggest that. 4013d2c0a235SAndy Whitcroft if ($rpt_cleaners) { 4014d2c0a235SAndy Whitcroft print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n"; 4015d2c0a235SAndy Whitcroft print " scripts/cleanfile\n\n"; 4016b0781216SMike Frysinger $rpt_cleaners = 0; 4017d2c0a235SAndy Whitcroft } 4018d2c0a235SAndy Whitcroft } 4019d2c0a235SAndy Whitcroft 402011232688SArtem Bityutskiy if ($quiet == 0 && keys %ignore_type) { 4021000d1cc1SJoe Perches print "NOTE: Ignored message types:"; 4022000d1cc1SJoe Perches foreach my $ignore (sort keys %ignore_type) { 4023000d1cc1SJoe Perches print " $ignore"; 4024000d1cc1SJoe Perches } 402511232688SArtem Bityutskiy print "\n\n"; 4026000d1cc1SJoe Perches } 4027000d1cc1SJoe Perches 4028*3705ce5bSJoe Perches if ($clean == 0 && $fix && "@rawlines" ne "@fixed") { 4029*3705ce5bSJoe Perches my $newfile = $filename . ".EXPERIMENTAL-checkpatch-fixes"; 4030*3705ce5bSJoe Perches my $linecount = 0; 4031*3705ce5bSJoe Perches my $f; 4032*3705ce5bSJoe Perches 4033*3705ce5bSJoe Perches open($f, '>', $newfile) 4034*3705ce5bSJoe Perches or die "$P: Can't open $newfile for write\n"; 4035*3705ce5bSJoe Perches foreach my $fixed_line (@fixed) { 4036*3705ce5bSJoe Perches $linecount++; 4037*3705ce5bSJoe Perches if ($file) { 4038*3705ce5bSJoe Perches if ($linecount > 3) { 4039*3705ce5bSJoe Perches $fixed_line =~ s/^\+//; 4040*3705ce5bSJoe Perches print $f $fixed_line. "\n"; 4041*3705ce5bSJoe Perches } 4042*3705ce5bSJoe Perches } else { 4043*3705ce5bSJoe Perches print $f $fixed_line . "\n"; 4044*3705ce5bSJoe Perches } 4045*3705ce5bSJoe Perches } 4046*3705ce5bSJoe Perches close($f); 4047*3705ce5bSJoe Perches 4048*3705ce5bSJoe Perches if (!$quiet) { 4049*3705ce5bSJoe Perches print << "EOM"; 4050*3705ce5bSJoe PerchesWrote EXPERIMENTAL --fix correction(s) to '$newfile' 4051*3705ce5bSJoe Perches 4052*3705ce5bSJoe PerchesDo _NOT_ trust the results written to this file. 4053*3705ce5bSJoe PerchesDo _NOT_ submit these changes without inspecting them for correctness. 4054*3705ce5bSJoe Perches 4055*3705ce5bSJoe PerchesThis EXPERIMENTAL file is simply a convenience to help rewrite patches. 4056*3705ce5bSJoe PerchesNo warranties, expressed or implied... 4057*3705ce5bSJoe Perches 4058*3705ce5bSJoe PerchesEOM 4059*3705ce5bSJoe Perches } 4060*3705ce5bSJoe Perches } 4061*3705ce5bSJoe Perches 40620a920b5bSAndy Whitcroft if ($clean == 1 && $quiet == 0) { 4063c2fdda0dSAndy Whitcroft print "$vname has no obvious style problems and is ready for submission.\n" 40640a920b5bSAndy Whitcroft } 40650a920b5bSAndy Whitcroft if ($clean == 0 && $quiet == 0) { 4066000d1cc1SJoe Perches print << "EOM"; 4067000d1cc1SJoe Perches$vname has style problems, please review. 4068000d1cc1SJoe Perches 4069000d1cc1SJoe PerchesIf any of these errors are false positives, please report 4070000d1cc1SJoe Perchesthem to the maintainer, see CHECKPATCH in MAINTAINERS. 4071000d1cc1SJoe PerchesEOM 40720a920b5bSAndy Whitcroft } 407313214adfSAndy Whitcroft 40740a920b5bSAndy Whitcroft return $clean; 40750a920b5bSAndy Whitcroft} 4076