my $dbg_possible = 0;
my $dbg_type = 0;
my $dbg_attr = 0;
+my $dbg_adv_dcs = 0;
+my $dbg_adv_checking = 0;
+my $dbg_adv_apw = 0;
for my $key (keys %debug) {
## no critic
eval "\${dbg_$key} = '$debug{$key}';";
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
}x;
+# There are still some false positives, but this catches most
+# common cases.
our $typeTypedefs = qr{(?x:
- (?:__)?(?:u|s|be|le)(?:8|16|32|64)|
- atomic_t
+ [A-Z][A-Z\d_]*[a-z][A-Za-z\d_]* # camelcase
+ | [A-Z][A-Z\d_]*AIOCB # all uppercase
+ | [A-Z][A-Z\d_]*CPU # all uppercase
+ | QEMUBH # all uppercase
)};
our $logFunctions = qr{(?x:
my ($root) = @_;
my @tree_check = (
- "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile",
- "README", "Documentation", "arch", "include", "drivers",
- "fs", "init", "ipc", "kernel", "lib", "scripts",
+ "COPYING", "MAINTAINERS", "Makefile",
+ "README", "docs", "VERSION",
+ "vl.c"
);
foreach my $check (@tree_check) {
$av_preprocessor = 0;
}
- } elsif ($cur =~ /^(\(\s*$Type\s*)\)/) {
+ } elsif ($cur =~ /^(\(\s*$Type\s*)\)/ && $av_pending eq '_') {
print "CAST($1)\n" if ($dbg_values > 1);
push(@av_paren_type, $type);
$type = 'C';
# Check for incorrect file permissions
if ($line =~ /^new (file )?mode.*[7531]\d{0,2}$/) {
my $permhere = $here . "FILE: $realfile\n";
- if ($realfile =~ /(Makefile|Kconfig|\.c|\.h|\.S|\.tmpl)$/) {
+ if ($realfile =~ /(Makefile|Kconfig|\.c|\.cpp|\.h|\.S|\.tmpl)$/) {
ERROR("do not set execute permissions for source files\n" . $permhere);
}
}
}
# check we are in a valid source file if not then ignore this hunk
- next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
+ next if ($realfile !~ /\.(h|c|cpp|s|S|pl|sh)$/);
#80 column limit
if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
}
# check we are in a valid source file C or perl if not then ignore this hunk
- next if ($realfile !~ /\.(h|c|pl)$/);
+ next if ($realfile !~ /\.(h|c|cpp|pl)$/);
-# at the beginning of a line any tabs must come first and anything
-# more than 8 must use tabs.
- if ($rawline =~ /^\+\s* \t\s*\S/ ||
- $rawline =~ /^\+\s* \s*/) {
+# in QEMU, no tabs are allowed
+ if ($rawline =~ /^\+.*\t/) {
my $herevet = "$here\n" . cat_vet($rawline) . "\n";
- ERROR("code indent should use tabs where possible\n" . $herevet);
+ ERROR("code indent should never use tabs\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);
- }
-
-# check for spaces at the beginning of a line.
-# Exceptions:
-# 1) within comments
-# 2) indented preprocessor commands
-# 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);
- }
-
# check we are in a valid C source file if not then ignore this hunk
- next if ($realfile !~ /\.(h|c)$/);
+ next if ($realfile !~ /\.(h|c|cpp)$/);
# check for RCS/CVS revision markers
if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
#print "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
#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*{/) {
+ # The length of the "previous line" is checked against 80 because it
+ # includes the + at the beginning of the line (if the actual line has
+ # 79 or 80 characters, it is no longer possible to add a space and an
+ # opening brace there)
+ if ($#ctx == 0 && $ctx !~ /{\s*/ &&
+ defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/ &&
+ defined($lines[$ctx_ln - 2]) && length($lines[$ctx_ln - 2]) < 80) {
ERROR("that open brace { should be on the previous line\n" .
"$here\n$ctx\n$rawlines[$ctx_ln - 1]\n");
}
#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";
- if ($check && (($sindent % 8) != 0 ||
+ if ($check && (($sindent % 4) != 0 ||
($sindent <= $indent && $s ne ''))) {
WARN("suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
}
$herecurr);
}
-# check for new typedefs, only function parameters and sparse annotations
-# make sense.
- if ($line =~ /\btypedef\s/ &&
- $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ &&
- $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
- $line !~ /\b$typeTypedefs\b/ &&
- $line !~ /\b__bitwise(?:__|)\b/) {
- WARN("do not add new typedefs\n" . $herecurr);
- }
-
# * goes on variable not on type
# (char*[ const])
if ($line =~ m{\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\)}) {
# printk should use KERN_* levels. Note that follow on printk's on the
# same line do not need a level, so we use the current block context
# to try and find and validate the current printk. In summary the current
-# printk includes all preceeding printk's which have no newline on the end.
+# printk includes all preceding printk's which have no newline on the end.
# we assume the first bad printk is the one to report.
if ($line =~ /\bprintk\((?!KERN_)\s*"/) {
my $ok = 0;
for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) {
#print "CHECK<$lines[$ln - 1]\n";
- # we have a preceeding printk if it ends
+ # we have a preceding printk if it ends
# with "\n" ignore it, else it is to blame
if ($lines[$ln - 1] =~ m{\bprintk\(}) {
if ($rawlines[$ln - 1] !~ m{\\n"}) {
asm|__asm__)$/x)
{
+ # Ignore 'catch (...)' in C++
+ } elsif ($name =~ /^catch$/ && $realfile =~ /(\.cpp|\.h)$/) {
+
# cpp #define statements have non-optional spaces, ie
# if there is a space between the name and the open
# parenthesis it is simply not a parameter group.
\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
=>|->|<<|>>|<|>|=|!|~|
&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
- \?|:
+ \?|::|:
}x;
my @elements = split(/($ops|;)/, $opline);
my $off = 0;
for (my $n = 0; $n < $#elements; $n += 2) {
$off += length($elements[$n]);
- # Pick up the preceeding and succeeding characters.
+ # Pick up the preceding and succeeding characters.
my $ca = substr($opline, 0, $off);
my $cc = '';
if (length($opline) >= ($off + length($elements[$n + 1]))) {
# // is a comment
} elsif ($op eq '//') {
+ # Ignore : used in class declaration in C++
+ } elsif ($opv eq ':B' && $ctx =~ /Wx[WE]/ &&
+ $line =~ /class/ && $realfile =~ /(\.cpp|\.h)$/) {
+
# No spaces for:
# ->
# : when part of a bitfield
}
# , must have a space on the right.
+ # not required when having a single },{ on one line
} elsif ($op eq ',') {
- if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
+ if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/ &&
+ ($elements[$n] . $elements[$n + 2]) !~ " *}{") {
ERROR("space required after that '$op' $at\n" . $hereptr);
}
} elsif ($op eq '!' || $op eq '~' ||
$opv eq '*U' || $opv eq '-U' ||
$opv eq '&U' || $opv eq '&&U') {
- if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
+ if ($op eq '~' && $ca =~ /::$/ && $realfile =~ /(\.cpp|\.h)$/) {
+ # '~' used as a name of Destructor
+
+ } elsif ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
ERROR("space required before that '$op' $at\n" . $hereptr);
}
if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
} elsif ($ctx !~ /[EWC]x[CWE]/) {
my $ok = 0;
+ if ($realfile =~ /\.cpp|\.h$/) {
+ # Ignore template arguments <...> in C++
+ if (($op eq '<' || $op eq '>') && $line =~ /<.*>/) {
+ $ok = 1;
+ }
+
+ # Ignore :: in C++
+ if ($op eq '::') {
+ $ok = 1;
+ }
+ }
+
# Ignore email addresses <foo@bar>
if (($op eq '<' &&
$cc =~ /^\S+\@\S+>/) ||
ERROR("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);
- }
-
# Return is not a function.
if (defined($stat) && $stat =~ /^.\s*return(\s*)(\(.*);/s) {
my $spacing = $1;
WARN("vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr);
}
-# check for redundant bracing round if etc
- if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
+# check for missing bracing round if etc
+ if ($line =~ /(^.*)\bif\b/ && $line !~ /\#\s*if/) {
my ($level, $endln, @chunks) =
ctx_statement_full($linenr, $realcnt, 1);
- #print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
- #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
- if ($#chunks > 0 && $level == 0) {
+ if ($dbg_adv_apw) {
+ print "APW: chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
+ print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n"
+ if $#chunks >= 1;
+ }
+ if ($#chunks >= 0 && $level == 0) {
my $allowed = 0;
my $seen = 0;
my $herectx = $here . "\n";
substr($block, 0, length($cond), '');
- $seen++ if ($block =~ /^\s*{/);
+ my $spaced_block = $block;
+ $spaced_block =~ s/\n\+/ /g;
- #print "cond<$cond> block<$block> allowed<$allowed>\n";
+ $seen++ if ($spaced_block =~ /^\s*{/);
+
+ print "APW: cond<$cond> block<$block> allowed<$allowed>\n"
+ if $dbg_adv_apw;
if (statement_lines($cond) > 1) {
- #print "APW: ALLOWED: cond<$cond>\n";
- $allowed = 1;
+ print "APW: ALLOWED: cond<$cond>\n"
+ if $dbg_adv_apw;
+ $allowed = 1;
}
if ($block =~/\b(?:if|for|while)\b/) {
- #print "APW: ALLOWED: block<$block>\n";
- $allowed = 1;
+ print "APW: ALLOWED: block<$block>\n"
+ if $dbg_adv_apw;
+ $allowed = 1;
}
if (statement_block_size($block) > 1) {
- #print "APW: ALLOWED: lines block<$block>\n";
- $allowed = 1;
+ print "APW: ALLOWED: lines block<$block>\n"
+ if $dbg_adv_apw;
+ $allowed = 1;
}
}
- if ($seen && !$allowed) {
- WARN("braces {} are not necessary for any arm of this statement\n" . $herectx);
+ if ($seen != ($#chunks + 1)) {
+ WARN("braces {} are necessary for all arms of this statement\n" . $herectx);
}
}
}
if (!defined $suppress_ifbraces{$linenr - 1} &&
- $line =~ /\b(if|while|for|else)\b/) {
+ $line =~ /\b(if|while|for|else)\b/ &&
+ $line !~ /\#\s*if/ &&
+ $line !~ /\#\s*else/) {
my $allowed = 0;
- # Check the pre-context.
- if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
- #print "APW: ALLOWED: pre<$1>\n";
- $allowed = 1;
- }
+ # Check the pre-context.
+ if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
+ my $pre = $1;
+
+ if ($line !~ /else/) {
+ print "APW: ALLOWED: pre<$pre> line<$line>\n"
+ if $dbg_adv_apw;
+ $allowed = 1;
+ }
+ }
my ($level, $endln, @chunks) =
ctx_statement_full($linenr, $realcnt, $-[0]);
# Check the condition.
my ($cond, $block) = @{$chunks[0]};
- #print "CHECKING<$linenr> cond<$cond> block<$block>\n";
+ print "CHECKING<$linenr> cond<$cond> block<$block>\n"
+ if $dbg_adv_checking;
if (defined $cond) {
substr($block, 0, length($cond), '');
}
if (statement_lines($cond) > 1) {
- #print "APW: ALLOWED: cond<$cond>\n";
- $allowed = 1;
+ print "APW: ALLOWED: cond<$cond>\n"
+ if $dbg_adv_apw;
+ $allowed = 1;
}
if ($block =~/\b(?:if|for|while)\b/) {
- #print "APW: ALLOWED: block<$block>\n";
- $allowed = 1;
+ print "APW: ALLOWED: block<$block>\n"
+ if $dbg_adv_apw;
+ $allowed = 1;
}
if (statement_block_size($block) > 1) {
- #print "APW: ALLOWED: lines block<$block>\n";
- $allowed = 1;
+ print "APW: ALLOWED: lines block<$block>\n"
+ if $dbg_adv_apw;
+ $allowed = 1;
}
# Check the post-context.
if (defined $chunks[1]) {
substr($block, 0, length($cond), '');
}
if ($block =~ /^\s*\{/) {
- #print "APW: ALLOWED: chunk-1 block<$block>\n";
- $allowed = 1;
+ print "APW: ALLOWED: chunk-1 block<$block>\n"
+ if $dbg_adv_apw;
+ $allowed = 1;
}
}
- if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
+ print "DCS: level=$level block<$block> allowed=$allowed\n"
+ if $dbg_adv_dcs;
+ if ($level == 0 && $block !~ /^\s*\{/ && !$allowed) {
my $herectx = $here . "\n";;
my $cnt = statement_rawlines($block);
$herectx .= raw_line($linenr, $n) . "\n";;
}
- WARN("braces {} are not necessary for single statement blocks\n" . $herectx);
+ WARN("braces {} are necessary even for single statement blocks\n" . $herectx);
}
}
ERROR("lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);
}
}
+
+# QEMU specific tests
+ if ($rawline =~ /\b(?:Qemu|QEmu)\b/) {
+ WARN("use QEMU instead of Qemu or QEmu\n" . $herecurr);
+ }
+
+# check for non-portable ffs() calls that have portable alternatives in QEMU
+ if ($line =~ /\bffs\(/) {
+ ERROR("use ctz32() instead of ffs()\n" . $herecurr);
+ }
+ if ($line =~ /\bffsl\(/) {
+ ERROR("use ctz32() or ctz64() instead of ffsl()\n" . $herecurr);
+ }
+ if ($line =~ /\bffsll\(/) {
+ ERROR("use ctz64() instead of ffsll()\n" . $herecurr);
+ }
}
# If we have no input at all, then there is nothing to report on
if ($quiet == 0) {
# If there were whitespace errors which cleanpatch can fix
# then suggest that.
- if ($rpt_cleaners) {
- print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n";
- print " scripts/cleanfile\n\n";
- }
+# if ($rpt_cleaners) {
+# print "NOTE: whitespace errors detected, you may wish to use scripts/cleanpatch or\n";
+# print " scripts/cleanfile\n\n";
+# }
}
if ($clean == 1 && $quiet == 0) {