diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-25 21:00:19 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-25 21:00:19 -0700 |
commit | 45b583b10a8b438b970e95a7d1d4db22c9e35004 (patch) | |
tree | 14fa481598289df0459580c582b48a9d95db51f6 /scripts | |
parent | 154dd78d30b56ffb8b447f629bfcceb14150e5c4 (diff) | |
parent | f19da2ce8ef5e49b8b8ea199c3601dd45d71b262 (diff) |
Merge 'akpm' patch series
* Merge akpm patch series: (122 commits)
drivers/connector/cn_proc.c: remove unused local
Documentation/SubmitChecklist: add RCU debug config options
reiserfs: use hweight_long()
reiserfs: use proper little-endian bitops
pnpacpi: register disabled resources
drivers/rtc/rtc-tegra.c: properly initialize spinlock
drivers/rtc/rtc-twl.c: check return value of twl_rtc_write_u8() in twl_rtc_set_time()
drivers/rtc: add support for Qualcomm PMIC8xxx RTC
drivers/rtc/rtc-s3c.c: support clock gating
drivers/rtc/rtc-mpc5121.c: add support for RTC on MPC5200
init: skip calibration delay if previously done
misc/eeprom: add eeprom access driver for digsy_mtc board
misc/eeprom: add driver for microwire 93xx46 EEPROMs
checkpatch.pl: update $logFunctions
checkpatch: make utf-8 test --strict
checkpatch.pl: add ability to ignore various messages
checkpatch: add a "prefer __aligned" check
checkpatch: validate signature styles and To: and Cc: lines
checkpatch: add __rcu as a sparse modifier
checkpatch: suggest using min_t or max_t
...
Did this as a merge because of (trivial) conflicts in
- Documentation/feature-removal-schedule.txt
- arch/xtensa/include/asm/uaccess.h
that were just easier to fix up in the merge than in the patch series.
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/checkpatch.pl | 656 | ||||
-rwxr-xr-x | scripts/get_maintainer.pl | 9 |
2 files changed, 513 insertions, 152 deletions
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index b0aa2c68059..9d761c95eca 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -10,7 +10,7 @@ use strict; my $P = $0; $P =~ s@.*/@@g; -my $V = '0.31'; +my $V = '0.32'; use Getopt::Long qw(:config no_auto_abbrev); @@ -26,9 +26,13 @@ my $check = 0; my $summary = 1; my $mailback = 0; my $summary_file = 0; +my $show_types = 0; my $root; my %debug; +my %ignore_type = (); +my @ignore = (); my $help = 0; +my $configuration_file = ".checkpatch.conf"; sub help { my ($exitcode) = @_; @@ -46,6 +50,8 @@ Options: --terse one line per report -f, --file treat FILE as regular source file --subjective, --strict enable more subjective tests + --ignore TYPE(,TYPE2...) ignore various comma separated message types + --show-types show the message "types" in the output --root=PATH PATH to the kernel tree root --no-summary suppress the per-file summary --mailback only produce a report in case of warnings/errors @@ -63,6 +69,32 @@ EOM exit($exitcode); } +my $conf = which_conf($configuration_file); +if (-f $conf) { + my @conf_args; + open(my $conffile, '<', "$conf") + or warn "$P: Can't find a readable $configuration_file file $!\n"; + + while (<$conffile>) { + my $line = $_; + + $line =~ s/\s*\n?$//g; + $line =~ s/^\s*//g; + $line =~ s/\s+/ /g; + + next if ($line =~ m/^\s*#/); + next if ($line =~ m/^\s*$/); + + my @words = split(" ", $line); + foreach my $word (@words) { + last if ($word =~ m/^#/); + push (@conf_args, $word); + } + } + close($conffile); + unshift(@ARGV, @conf_args) if @conf_args; +} + GetOptions( 'q|quiet+' => \$quiet, 'tree!' => \$tree, @@ -73,6 +105,8 @@ GetOptions( 'f|file!' => \$file, 'subjective!' => \$check, 'strict!' => \$check, + 'ignore=s' => \@ignore, + 'show-types!' => \$show_types, 'root=s' => \$root, 'summary!' => \$summary, 'mailback!' => \$mailback, @@ -93,6 +127,19 @@ if ($#ARGV < 0) { exit(1); } +@ignore = split(/,/, join(',',@ignore)); +foreach my $word (@ignore) { + $word =~ s/\s*\n?$//g; + $word =~ s/^\s*//g; + $word =~ s/\s+/ /g; + $word =~ tr/[a-z]/[A-Z]/; + + next if ($word =~ m/^\s*#/); + next if ($word =~ m/^\s*$/); + + $ignore_type{$word}++; +} + my $dbg_values = 0; my $dbg_possible = 0; my $dbg_type = 0; @@ -145,7 +192,8 @@ our $Sparse = qr{ __must_check| __init_refok| __kprobes| - __ref + __ref| + __rcu }x; # Notes to $Attribute: @@ -209,13 +257,23 @@ our $typeTypedefs = qr{(?x: )}; our $logFunctions = qr{(?x: - printk| - [a-z]+_(emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)| - WARN| + printk(?:_ratelimited|_once|)| + [a-z0-9]+_(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)| + WARN(?:_RATELIMIT|_ONCE|)| panic| MODULE_[A-Z_]+ )}; +our $signature_tags = qr{(?xi: + Signed-off-by:| + Acked-by:| + Tested-by:| + Reviewed-by:| + Reported-by:| + To:| + Cc: +)}; + our @typeList = ( qr{void}, qr{(?:unsigned\s+)?char}, @@ -268,6 +326,20 @@ sub build_types { } build_types(); +our $match_balanced_parentheses = qr/(\((?:[^\(\)]+|(-1))*\))/; + +our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*}; +our $LvalOrFunc = qr{($Lval)\s*($match_balanced_parentheses{0,1})\s*}; + +sub deparenthesize { + my ($string) = @_; + return "" if (!defined($string)); + $string =~ s@^\s*\(\s*@@g; + $string =~ s@\s*\)\s*$@@g; + $string =~ s@\s+@ @g; + return $string; +} + $chk_signoff = 0 if ($file); my @dep_includes = (); @@ -339,6 +411,88 @@ sub top_of_kernel_tree { } } return 1; + } + +sub parse_email { + my ($formatted_email) = @_; + + my $name = ""; + my $address = ""; + my $comment = ""; + + if ($formatted_email =~ /^(.*)<(\S+\@\S+)>(.*)$/) { + $name = $1; + $address = $2; + $comment = $3 if defined $3; + } elsif ($formatted_email =~ /^\s*<(\S+\@\S+)>(.*)$/) { + $address = $1; + $comment = $2 if defined $2; + } elsif ($formatted_email =~ /(\S+\@\S+)(.*)$/) { + $address = $1; + $comment = $2 if defined $2; + $formatted_email =~ s/$address.*$//; + $name = $formatted_email; + $name =~ s/^\s+|\s+$//g; + $name =~ s/^\"|\"$//g; + # If there's a name left after stripping spaces and + # leading quotes, and the address doesn't have both + # leading and trailing angle brackets, the address + # is invalid. ie: + # "joe smith joe@smith.com" bad + # "joe smith <joe@smith.com" bad + if ($name ne "" && $address !~ /^<[^>]+>$/) { + $name = ""; + $address = ""; + $comment = ""; + } + } + + $name =~ s/^\s+|\s+$//g; + $name =~ s/^\"|\"$//g; + $address =~ s/^\s+|\s+$//g; + $address =~ s/^\<|\>$//g; + + if ($name =~ /[^\w \-]/i) { ##has "must quote" chars + $name =~ s/(?<!\\)"/\\"/g; ##escape quotes + $name = "\"$name\""; + } + + return ($name, $address, $comment); +} + +sub format_email { + my ($name, $address) = @_; + + my $formatted_email; + + $name =~ s/^\s+|\s+$//g; + $name =~ s/^\"|\"$//g; + $address =~ s/^\s+|\s+$//g; + + if ($name =~ /[^\w \-]/i) { ##has "must quote" chars + $name =~ s/(?<!\\)"/\\"/g; ##escape quotes + $name = "\"$name\""; + } + + if ("$name" eq "") { + $formatted_email = "$address"; + } else { + $formatted_email = "$name <$address>"; + } + + return $formatted_email; +} + +sub which_conf { + my ($conf) = @_; + + foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) { + if (-e "$path/$conf") { + return "$path/$conf"; + } + } + + return ""; } sub expand_tabs { @@ -1086,12 +1240,21 @@ sub possible { my $prefix = ''; +sub show_type { + return !defined $ignore_type{$_[0]}; +} + sub report { - if (defined $tst_only && $_[0] !~ /\Q$tst_only\E/) { + if (!show_type($_[1]) || + (defined $tst_only && $_[2] !~ /\Q$tst_only\E/)) { return 0; } - my $line = $prefix . $_[0]; - + my $line; + if ($show_types) { + $line = "$prefix$_[0]:$_[1]: $_[2]\n"; + } else { + $line = "$prefix$_[0]: $_[2]\n"; + } $line = (split('\n', $line))[0] . "\n" if ($terse); push(our @report, $line); @@ -1101,20 +1264,21 @@ sub report { sub report_dump { our @report; } + sub ERROR { - if (report("ERROR: $_[0]\n")) { + if (report("ERROR", $_[0], $_[1])) { our $clean = 0; our $cnt_error++; } } sub WARN { - if (report("WARNING: $_[0]\n")) { + if (report("WARNING", $_[0], $_[1])) { our $clean = 0; our $cnt_warn++; } } sub CHK { - if ($check && report("CHECK: $_[0]\n")) { + if ($check && report("CHECK", $_[0], $_[1])) { our $clean = 0; our $cnt_chk++; } @@ -1143,7 +1307,8 @@ sub check_absolute_file { ##print "prefix<$prefix>\n"; if ($prefix ne ".../") { - WARN("use relative pathname instead of absolute in changelog text\n" . $herecurr); + WARN("USE_RELATIVE_PATH", + "use relative pathname instead of absolute in changelog text\n" . $herecurr); } } @@ -1340,11 +1505,13 @@ sub process { $p1_prefix = $1; if (!$file && $tree && $p1_prefix ne '' && -e "$root/$p1_prefix") { - WARN("patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); + WARN("PATCH_PREFIX", + "patch prefix '$p1_prefix' exists, appears to be a -p0 patch\n"); } if ($realfile =~ m@^include/asm/@) { - ERROR("do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); + ERROR("MODIFIED_INCLUDE_ASM", + "do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n"); } next; } @@ -1361,27 +1528,61 @@ sub process { if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) { my $permhere = $here . "FILE: $realfile\n"; if ($realfile =~ /(Makefile|Kconfig|\.c|\.h|\.S|\.tmpl)$/) { - ERROR("do not set execute permissions for source files\n" . $permhere); + ERROR("EXECUTE_PERMISSIONS", + "do not set execute permissions for source files\n" . $permhere); } } -#check the patch for a signoff: +# Check the patch for a signoff: if ($line =~ /^\s*signed-off-by:/i) { - # This is a signoff, if ugly, so do not double report. $signoff++; - if (!($line =~ /^\s*Signed-off-by:/)) { - WARN("Signed-off-by: is the preferred form\n" . - $herecurr); + } + +# Check signature styles + if ($line =~ /^(\s*)($signature_tags)(\s*)(.*)/) { + my $space_before = $1; + my $sign_off = $2; + my $space_after = $3; + my $email = $4; + my $ucfirst_sign_off = ucfirst(lc($sign_off)); + + if (defined $space_before && $space_before ne "") { + WARN("BAD_SIGN_OFF", + "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr); } - if ($line =~ /^\s*signed-off-by:\S/i) { - WARN("space required after Signed-off-by:\n" . - $herecurr); + if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) { + WARN("BAD_SIGN_OFF", + "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr); + } + if (!defined $space_after || $space_after ne " ") { + WARN("BAD_SIGN_OFF", + "Use a single space after $ucfirst_sign_off\n" . $herecurr); + } + + my ($email_name, $email_address, $comment) = parse_email($email); + my $suggested_email = format_email(($email_name, $email_address)); + if ($suggested_email eq "") { + ERROR("BAD_SIGN_OFF", + "Unrecognized email address: '$email'\n" . $herecurr); + } else { + my $dequoted = $suggested_email; + $dequoted =~ s/^"//; + $dequoted =~ s/" </ </; + # Don't force email to have quotes + # Allow just an angle bracketed address + if ("$dequoted$comment" ne $email && + "<$email_address>$comment" ne $email && + "$suggested_email$comment" ne $email) { + WARN("BAD_SIGN_OFF", + "email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr); + } } } # Check for wrappage within a valid hunk of the file if ($realcnt != 0 && $line !~ m{^(?:\+|-| |\\ No newline|$)}) { - ERROR("patch seems to be corrupt (line wrapped?)\n" . + ERROR("CORRUPTED_PATCH", + "patch seems to be corrupt (line wrapped?)\n" . $herecurr) if (!$emitted_corrupt++); } @@ -1408,7 +1609,8 @@ sub process { my $ptr = substr($blank, 0, length($utf8_prefix)) . "^"; my $hereptr = "$hereline$ptr\n"; - ERROR("Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); + CHK("INVALID_UTF8", + "Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr); } # ignore non-hunk lines and lines being removed @@ -1417,11 +1619,13 @@ sub process { #trailing whitespace if ($line =~ /^\+.*\015/) { my $herevet = "$here\n" . cat_vet($rawline) . "\n"; - ERROR("DOS line endings\n" . $herevet); + ERROR("DOS_LINE_ENDINGS", + "DOS line endings\n" . $herevet); } elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) { my $herevet = "$here\n" . cat_vet($rawline) . "\n"; - ERROR("trailing whitespace\n" . $herevet); + ERROR("TRAILING_WHITESPACE", + "trailing whitespace\n" . $herevet); $rpt_cleaners = 1; } @@ -1452,7 +1656,8 @@ sub process { } $length++; } - WARN("please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_end && $length < 4); + WARN("CONFIG_DESCRIPTION", + "please write a paragraph that describes the config symbol fully\n" . $herecurr) if ($is_end && $length < 4); #print "is_end<$is_end> length<$length>\n"; } @@ -1466,28 +1671,33 @@ sub process { $line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) && $length > 80) { - WARN("line over 80 characters\n" . $herecurr); + WARN("LONG_LINE", + "line over 80 characters\n" . $herecurr); } # check for spaces before a quoted newline if ($rawline =~ /^.*\".*\s\\n/) { - WARN("unnecessary whitespace before a quoted newline\n" . $herecurr); + WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE", + "unnecessary whitespace before a quoted newline\n" . $herecurr); } # check for adding lines without a newline. if ($line =~ /^\+/ && defined $lines[$linenr] && $lines[$linenr] =~ /^\\ No newline at end of file/) { - WARN("adding a line without newline at end of file\n" . $herecurr); + WARN("MISSING_EOF_NEWLINE", + "adding a line without newline at end of file\n" . $herecurr); } # Blackfin: use hi/lo macros if ($realfile =~ m@arch/blackfin/.*\.S$@) { if ($line =~ /\.[lL][[:space:]]*=.*&[[:space:]]*0x[fF][fF][fF][fF]/) { my $herevet = "$here\n" . cat_vet($line) . "\n"; - ERROR("use the LO() macro, not (... & 0xFFFF)\n" . $herevet); + ERROR("LO_MACRO", + "use the LO() macro, not (... & 0xFFFF)\n" . $herevet); } if ($line =~ /\.[hH][[:space:]]*=.*>>[[:space:]]*16/) { my $herevet = "$here\n" . cat_vet($line) . "\n"; - ERROR("use the HI() macro, not (... >> 16)\n" . $herevet); + ERROR("HI_MACRO", + "use the HI() macro, not (... >> 16)\n" . $herevet); } } @@ -1499,14 +1709,16 @@ sub process { if ($rawline =~ /^\+\s* \t\s*\S/ || $rawline =~ /^\+\s* \s*/) { my $herevet = "$here\n" . cat_vet($rawline) . "\n"; - ERROR("code indent should use tabs where possible\n" . $herevet); + ERROR("CODE_INDENT", + "code indent should use tabs where possible\n" . $herevet); $rpt_cleaners = 1; } # check for space before tabs. if ($rawline =~ /^\+/ && $rawline =~ / \t/) { my $herevet = "$here\n" . cat_vet($rawline) . "\n"; - WARN("please, no space before tabs\n" . $herevet); + WARN("SPACE_BEFORE_TAB", + "please, no space before tabs\n" . $herevet); } # check for spaces at the beginning of a line. @@ -1516,7 +1728,8 @@ sub process { # 3) hanging labels if ($rawline =~ /^\+ / && $line !~ /\+ *(?:$;|#|$Ident:)/) { my $herevet = "$here\n" . cat_vet($rawline) . "\n"; - WARN("please, no spaces at the start of a line\n" . $herevet); + WARN("LEADING_SPACE", + "please, no spaces at the start of a line\n" . $herevet); } # check we are in a valid C source file if not then ignore this hunk @@ -1524,17 +1737,20 @@ sub process { # check for RCS/CVS revision markers if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) { - WARN("CVS style keyword markers, these will _not_ be updated\n". $herecurr); + WARN("CVS_KEYWORD", + "CVS style keyword markers, these will _not_ be updated\n". $herecurr); } # Blackfin: don't use __builtin_bfin_[cs]sync if ($line =~ /__builtin_bfin_csync/) { my $herevet = "$here\n" . cat_vet($line) . "\n"; - ERROR("use the CSYNC() macro in asm/blackfin.h\n" . $herevet); + ERROR("CSYNC", + "use the CSYNC() macro in asm/blackfin.h\n" . $herevet); } if ($line =~ /__builtin_bfin_ssync/) { my $herevet = "$here\n" . cat_vet($line) . "\n"; - ERROR("use the SSYNC() macro in asm/blackfin.h\n" . $herevet); + ERROR("SSYNC", + "use the SSYNC() macro in asm/blackfin.h\n" . $herevet); } # Check for potential 'bare' types @@ -1623,7 +1839,8 @@ sub process { } } if ($err ne '') { - ERROR("switch and case should be at the same indent\n$hereline$err"); + ERROR("SWITCH_CASE_INDENT_LEVEL", + "switch and case should be at the same indent\n$hereline$err"); } } @@ -1651,7 +1868,8 @@ sub process { #print "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n"; if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { - ERROR("that open brace { should be on the previous line\n" . + ERROR("OPEN_BRACE", + "that open brace { should be on the previous line\n" . "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); } if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && @@ -1660,7 +1878,8 @@ sub process { { my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); if ($nindent > $indent) { - WARN("trailing semicolon indicates no statements, indent implies otherwise\n" . + WARN("TRAILING_SEMICOLON", + "trailing semicolon indicates no statements, indent implies otherwise\n" . "$here\n$ctx\n$rawlines[$ctx_ln - 1]\n"); } } @@ -1748,7 +1967,8 @@ sub process { if ($check && (($sindent % 8) != 0 || ($sindent <= $indent && $s ne ''))) { - WARN("suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); + WARN("SUSPECT_CODE_INDENT", + "suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n"); } } @@ -1771,18 +1991,22 @@ sub process { # TEST: allow direct testing of the type matcher. if ($dbg_type) { if ($line =~ /^.\s*$Declare\s*$/) { - ERROR("TEST: is type\n" . $herecurr); + ERROR("TEST_TYPE", + "TEST: is type\n" . $herecurr); } elsif ($dbg_type > 1 && $line =~ /^.+($Declare)/) { - ERROR("TEST: is not type ($1 is)\n". $herecurr); + ERROR("TEST_NOT_TYPE", + "TEST: is not type ($1 is)\n". $herecurr); } next; } # TEST: allow direct testing of the attribute matcher. if ($dbg_attr) { if ($line =~ /^.\s*$Modifier\s*$/) { - ERROR("TEST: is attr\n" . $herecurr); + ERROR("TEST_ATTR", + "TEST: is attr\n" . $herecurr); } elsif ($dbg_attr > 1 && $line =~ /^.+($Modifier)/) { - ERROR("TEST: is not attr ($1 is)\n". $herecurr); + ERROR("TEST_NOT_ATTR", + "TEST: is not attr ($1 is)\n". $herecurr); } next; } @@ -1790,7 +2014,8 @@ sub process { # check for initialisation to aggregates open brace on the next line if ($line =~ /^.\s*{/ && $prevline =~ /(?:^|[^=])=\s*$/) { - ERROR("that open brace { should be on the previous line\n" . $hereprev); + ERROR("OPEN_BRACE", + "that open brace { should be on the previous line\n" . $hereprev); } # @@ -1801,14 +2026,16 @@ sub process { if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { my $path = $1; if ($path =~ m{//}) { - ERROR("malformed #include filename\n" . + ERROR("MALFORMED_INCLUDE", + "malformed #include filename\n" . $herecurr); } } # no C99 // comments if ($line =~ m{//}) { - ERROR("do not use C99 // comments\n" . $herecurr); + ERROR("C99_COMMENTS", + "do not use C99 // comments\n" . $herecurr); } # Remove C99 comments. $line =~ s@//.*@@; @@ -1855,35 +2082,41 @@ sub process { } if (defined $suppress_export{$linenr} && $suppress_export{$linenr} == 2) { - WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); + WARN("EXPORT_SYMBOL", + "EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr); } # check for global initialisers. if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) { - ERROR("do not initialise globals to 0 or NULL\n" . + ERROR("GLOBAL_INITIALISERS", + "do not initialise globals to 0 or NULL\n" . $herecurr); } # check for static initialisers. if ($line =~ /\bstatic\s.*=\s*(0|NULL|false)\s*;/) { - ERROR("do not initialise statics to 0 or NULL\n" . + ERROR("INITIALISED_STATIC", + "do not initialise statics to 0 or NULL\n" . $herecurr); } # check for static const char * arrays. if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { - WARN("static const char * array should probably be static const char * const\n" . + WARN("STATIC_CONST_CHAR_ARRAY", + "static const char * array should probably be static const char * const\n" . $herecurr); } # check for static char foo[] = "bar" declarations. if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { - WARN("static char array declaration should probably be static const char\n" . + WARN("STATIC_CONST_CHAR_ARRAY", + "static char array declaration should probably be static const char\n" . $herecurr); } # check for declarations of struct pci_device_id if ($line =~ /\bstruct\s+pci_device_id\s+\w+\s*\[\s*\]\s*\=\s*\{/) { - WARN("Use DEFINE_PCI_DEVICE_TABLE for struct pci_device_id\n" . $herecurr); + WARN("DEFINE_PCI_DEVICE_TABLE", + "Use DEFINE_PCI_DEVICE_TABLE for struct pci_device_id\n" . $herecurr); } # check for new typedefs, only function parameters and sparse annotations @@ -1893,7 +2126,8 @@ sub process { $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && $line !~ /\b$typeTypedefs\b/ && $line !~ /\b__bitwise(?:__|)\b/) { - WARN("do not add new typedefs\n" . $herecurr); + WARN("NEW_TYPEDEFS", + "do not add new typedefs\n" . $herecurr); } # * goes on variable not on type @@ -1911,7 +2145,8 @@ sub process { #print "from<$from> to<$to>\n"; if ($from ne $to) { - ERROR("\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr); + ERROR("POINTER_LOCATION", + "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr); } } elsif ($line =~ m{\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident)}) { my ($from, $to, $ident) = ($1, $1, $2); @@ -1928,7 +2163,8 @@ sub process { #print "from<$from> to<$to> ident<$ident>\n"; if ($from ne $to && $ident !~ /^$Modifier$/) { - ERROR("\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr); + ERROR("POINTER_LOCATION", + "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr); } } @@ -1940,12 +2176,14 @@ sub process { # } if ($line =~ /\bLINUX_VERSION_CODE\b/) { - WARN("LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); + WARN("LINUX_VERSION_CODE", + "LINUX_VERSION_CODE should be avoided, code should be for the version to which it is merged\n" . $herecurr); } # check for uses of printk_ratelimit if ($line =~ /\bprintk_ratelimit\s*\(/) { - WARN("Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); + WARN("PRINTK_RATELIMITED", +"Prefer printk_ratelimited or pr_<level>_ratelimited to printk_ratelimit\n" . $herecurr); } # printk should use KERN_* levels. Note that follow on printk's on the @@ -1967,7 +2205,8 @@ sub process { } } if ($ok == 0) { - WARN("printk() should include KERN_ facility level\n" . $herecurr); + WARN("PRINTK_WITHOUT_KERN_LEVEL", + "printk() should include KERN_ facility level\n" . $herecurr); } } @@ -1975,18 +2214,21 @@ sub process { # or if closed on same line if (($line=~/$Type\s*$Ident\(.*\).*\s{/) and !($line=~/\#\s*define.*do\s{/) and !($line=~/}/)) { - ERROR("open brace '{' following function declarations go on the next line\n" . $herecurr); + ERROR("OPEN_BRACE", + "open brace '{' following function declarations go on the next line\n" . $herecurr); } # open braces for enum, union and struct go on the same line. if ($line =~ /^.\s*{/ && $prevline =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?\s*$/) { - ERROR("open brace '{' following $1 go on the same line\n" . $hereprev); + ERROR("OPEN_BRACE", + "open brace '{' following $1 go on the same line\n" . $hereprev); } # missing space after union, struct or enum definition if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?(?:\s+$Ident)?[=\{]/) { - WARN("missing space after $1 definition\n" . $herecurr); + WARN("SPACING", + "missing space after $1 definition\n" . $herecurr); } # check for spacing round square brackets; allowed: @@ -1998,7 +2240,8 @@ sub process { if ($prefix !~ /$Type\s+$/ && ($where != 0 || $prefix !~ /^.\s+$/) && $prefix !~ /{\s+$/) { - ERROR("space prohibited before open square bracket '['\n" . $herecurr); + ERROR("BRACKET_SPACE", + "space prohibited before open square bracket '['\n" . $herecurr); } } @@ -2029,7 +2272,8 @@ sub process { } elsif ($ctx =~ /$Type$/) { } else { - WARN("space prohibited between function name and open parenthesis '('\n" . $herecurr); + WARN("SPACING", + "space prohibited between function name and open parenthesis '('\n" . $herecurr); } } # Check operator spacing. @@ -2103,7 +2347,8 @@ sub process { } elsif ($op eq ';') { if ($ctx !~ /.x[WEBC]/ && $cc !~ /^\\/ && $cc !~ /^;/) { - ERROR("space required after that '$op' $at\n" . $hereptr); + ERROR("SPACING", + "space required after that '$op' $at\n" . $hereptr); } # // is a comment @@ -2114,13 +2359,15 @@ sub process { # : when part of a bitfield } elsif ($op eq '->' || $opv eq ':B') { if ($ctx =~ /Wx.|.xW/) { - ERROR("spaces prohibited around that '$op' $at\n" . $hereptr); + ERROR("SPACING", + "spaces prohibited around that '$op' $at\n" . $hereptr); } # , must have a space on the right. } elsif ($op eq ',') { if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) { - ERROR("space required after that '$op' $at\n" . $hereptr); + ERROR("SPACING", + "space required after that '$op' $at\n" . $hereptr); } # '*' as part of a type definition -- reported already. @@ -2134,26 +2381,31 @@ sub process { $opv eq '*U' || $opv eq '-U' || $opv eq '&U' || $opv eq '&&U') { if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) { - ERROR("space required before that '$op' $at\n" . $hereptr); + ERROR("SPACING", + "space required before that '$op' $at\n" . $hereptr); } if ($op eq '*' && $cc =~/\s*$Modifier\b/) { # A unary '*' may be const } elsif ($ctx =~ /.xW/) { - ERROR("space prohibited after that '$op' $at\n" . $hereptr); + ERROR("SPACING", + "space prohibited after that '$op' $at\n" . $hereptr); } # unary ++ and unary -- are allowed no space on one side. } elsif ($op eq '++' or $op eq '--') { if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) { - ERROR("space required one side of that '$op' $at\n" . $hereptr); + ERROR("SPACING", + "space required one side of that '$op' $at\n" . $hereptr); } if ($ctx =~ /Wx[BE]/ || ($ctx =~ /Wx./ && $cc =~ /^;/)) { - ERROR("space prohibited before that '$op' $at\n" . $hereptr); + ERROR("SPACING", + "space prohibited before that '$op' $at\n" . $hereptr); } if ($ctx =~ /ExW/) { - ERROR("space prohibited after that '$op' $at\n" . $hereptr); + ERROR("SPACING", + "space prohibited after that '$op' $at\n" . $hereptr); } @@ -2165,7 +2417,8 @@ sub process { $op eq '%') { if ($ctx =~ /Wx[^WCE]|[^WCE]xW/) { - ERROR("need consistent spacing around '$op' $at\n" . + ERROR("SPACING", + "need consistent spacing around '$op' $at\n" . $hereptr); } @@ -2173,7 +2426,8 @@ sub process { # terminating a case value or a label. } elsif ($opv eq ':C' || $opv eq ':L') { if ($ctx =~ /Wx./) { - ERROR("space prohibited before that '$op' $at\n" . $hereptr); + ERROR("SPACING", + "space prohibited before that '$op' $at\n" . $hereptr); } # All the others need spaces both sides. @@ -2196,7 +2450,8 @@ sub process { } if ($ok == 0) { - ERROR("spaces required around that '$op' $at\n" . $hereptr); + ERROR("SPACING", + "spaces required around that '$op' $at\n" . $hereptr); } } $off += length($elements[$n + 1]); @@ -2205,7 +2460,8 @@ sub process { # check for multiple assignments if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { - CHK("multiple assignments should be avoided\n" . $herecurr); + CHK("MULTIPLE_ASSIGNMENTS", + "multiple assignments should be avoided\n" . $herecurr); } ## # check for multiple declarations, allowing for a function declaration @@ -2219,45 +2475,53 @@ sub process { ## while ($ln =~ s/\([^\(\)]*\)//g) { ## } ## if ($ln =~ /,/) { -## WARN("declaring multiple variables together should be avoided\n" . $herecurr); +## WARN("MULTIPLE_DECLARATION", +## "declaring multiple variables together should be avoided\n" . $herecurr); ## } ## } #need space before brace following if, while, etc if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) || $line =~ /do{/) { - ERROR("space required before the open brace '{'\n" . $herecurr); + ERROR("SPACING", + "space required before the open brace '{'\n" . $herecurr); } # closing brace should have a space following it when it has anything # on the line if ($line =~ /}(?!(?:,|;|\)))\S/) { - ERROR("space required after that close brace '}'\n" . $herecurr); + ERROR("SPACING", + "space required after that close brace '}'\n" . $herecurr); } # check spacing on square brackets if ($line =~ /\[\s/ && $line !~ /\[\s*$/) { - ERROR("space prohibited after that open square bracket '['\n" . $herecurr); + ERROR("SPACING", + "space prohibited after that open square bracket '['\n" . $herecurr); } if ($line =~ /\s\]/) { - ERROR("space prohibited before that close square bracket ']'\n" . $herecurr); + ERROR("SPACING", + "space prohibited before that close square bracket ']'\n" . $herecurr); } # check spacing on parentheses if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && $line !~ /for\s*\(\s+;/) { - ERROR("space prohibited after that open parenthesis '('\n" . $herecurr); + ERROR("SPACING", + "space prohibited after that open parenthesis '('\n" . $herecurr); } if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && $line !~ /for\s*\(.*;\s+\)/ && $line !~ /:\s+\)/) { - ERROR("space prohibited before that close parenthesis ')'\n" . $herecurr); + ERROR("SPACING", + "space prohibited before that close parenthesis ')'\n" . $herecurr); } #goto labels aren't indented, allow a single space however if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and !($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) { - WARN("labels should not be indented\n" . $herecurr); + WARN("INDENTED_LABEL", + "labels should not be indented\n" . $herecurr); } # Return is not a function. @@ -2276,23 +2540,47 @@ sub process { } #print "value<$value>\n"; if ($value =~ /^\s*(?:$Ident|-?$Constant)\s*$/) { - ERROR("return is not a function, parentheses are not required\n" . $herecurr); + ERROR("RETURN_PARENTHESES", + "return is not a function, parentheses are not required\n" . $herecurr); } elsif ($spacing !~ /\s+/) { - ERROR("space required before the open parenthesis '('\n" . $herecurr); + ERROR("SPACING", + "space required before the open parenthesis '('\n" . $herecurr); } } # Return of what appears to be an errno should normally be -'ve if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) { my $name = $1; if ($name ne 'EOF' && $name ne 'ERROR') { - WARN("return of an errno should typically be -ve (return -$1)\n" . $herecurr); + WARN("USE_NEGATIVE_ERRNO", + "return of an errno should typically be -ve (return -$1)\n" . $herecurr); + } + } + +# typecasts on min/max could be min_t/max_t + if ($line =~ /^\+(?:.*?)\b(min|max)\s*\($Typecast{0,1}($LvalOrFunc)\s*,\s*$Typecast{0,1}($LvalOrFunc)\s*\)/) { + if (defined $2 || defined $8) { + my $call = $1; + my $cast1 = deparenthesize($2); + my $arg1 = $3; + my $cast2 = deparenthesize($8); + my $arg2 = $9; + my $cast; + + if ($cast1 ne "" && $cast2 ne "") { + $cast = "$cast1 or $cast2"; + } elsif ($cast1 ne "") { + $cast = $cast1; + } else { + $cast = $cast2; + } + WARN("$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . $herecurr); } } # Need a space before open parenthesis after if, while etc if ($line=~/\b(if|while|for|switch)\(/) { - ERROR("space required before the open parenthesis '('\n" . $herecurr); + ERROR("SPACING", "space required before the open parenthesis '('\n" . $herecurr); } # Check for illegal assignment in if conditional -- and check for trailing @@ -2320,7 +2608,8 @@ sub process { my ($s, $c) = ($stat, $cond); if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/s) { - ERROR("do not use assignment in if condition\n" . $herecurr); + ERROR("ASSIGN_IN_IF", + "do not use assignment in if condition\n" . $herecurr); } # Find out what is on the end of the line after the @@ -2342,7 +2631,8 @@ sub process { $stat_real = "[...]\n$stat_real"; } - ERROR("trailing statements should be on next line\n" . $herecurr . $stat_real); + ERROR("TRAILING_STATEMENTS", + "trailing statements should be on next line\n" . $herecurr . $stat_real); } } @@ -2358,7 +2648,8 @@ sub process { (?:\&\&|\|\||\)|\]) )/x) { - WARN("boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); + WARN("HEXADECIMAL_BOOLEAN_TEST", + "boolean test with hexadecimal, perhaps just 1 \& or \|?\n" . $herecurr); } # if and else should not have general statements after it @@ -2366,12 +2657,14 @@ sub process { my $s = $1; $s =~ s/$;//g; # Remove any comments if ($s !~ /^\s*(?:\sif|(?:{|)\s*\\?\s*$)/) { - ERROR("trailing statements should be on next line\n" . $herecurr); + ERROR("TRAILING_STATEMENTS", + "trailing statements should be on next line\n" . $herecurr); } } # if should not continue a brace |