aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Makefile.modpost6
-rwxr-xr-xscripts/checkpatch.pl750
-rw-r--r--scripts/kconfig/symbol.c34
-rwxr-xr-xscripts/kernel-doc10
-rw-r--r--scripts/mod/file2alias.c61
-rw-r--r--scripts/mod/modpost.c7
-rw-r--r--scripts/mod/modpost.h1
7 files changed, 554 insertions, 315 deletions
diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost
index cfc004e0441..2d20640854b 100644
--- a/scripts/Makefile.modpost
+++ b/scripts/Makefile.modpost
@@ -58,6 +58,9 @@ modules := $(patsubst %.o,%.ko, $(wildcard $(__modules:.ko=.o)))
# Stop after building .o files if NOFINAL is set. Makes compile tests quicker
_modpost: $(if $(KBUILD_MODPOST_NOFINAL), $(modules:.ko:.o),$(modules))
+ifneq ($(KBUILD_BUILDHOST),$(ARCH))
+ cross_build := 1
+endif
# Step 2), invoke modpost
# Includes step 3,4
@@ -70,7 +73,8 @@ modpost = scripts/mod/modpost \
$(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \
$(if $(CONFIG_MARKERS),-K $(kernelmarkersfile)) \
$(if $(CONFIG_MARKERS),-M $(markersfile)) \
- $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w)
+ $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) \
+ $(if $(cross_build),-c)
quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules
cmd_modpost = $(modpost) -s
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 2086a856400..58a94947d65 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -9,7 +9,7 @@ use strict;
my $P = $0;
$P =~ s@.*/@@g;
-my $V = '0.14';
+my $V = '0.16';
use Getopt::Long qw(:config no_auto_abbrev);
@@ -18,6 +18,7 @@ my $tree = 1;
my $chk_signoff = 1;
my $chk_patch = 1;
my $tst_type = 0;
+my $tst_only;
my $emacs = 0;
my $terse = 0;
my $file = 0;
@@ -44,6 +45,7 @@ GetOptions(
'debug=s' => \%debug,
'test-type!' => \$tst_type,
+ 'test-only=s' => \$tst_only,
) or exit;
my $exit = 0;
@@ -105,8 +107,7 @@ our $Sparse = qr{
__iomem|
__must_check|
__init_refok|
- __kprobes|
- fastcall
+ __kprobes
}x;
our $Attribute = qr{
const|
@@ -158,7 +159,10 @@ sub build_types {
\b
(?:const\s+)?
(?:unsigned\s+)?
- $all
+ (?:
+ $all|
+ (?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\)
+ )
(?:\s+$Sparse|\s+const)*
\b
}x;
@@ -261,17 +265,7 @@ sub expand_tabs {
return $res;
}
sub copy_spacing {
- my ($str) = @_;
-
- my $res = '';
- for my $c (split(//, $str)) {
- if ($c eq "\t") {
- $res .= $c;
- } else {
- $res .= ' ';
- }
- }
-
+ (my $res = shift) =~ tr/\t/ /c;
return $res;
}
@@ -288,53 +282,76 @@ sub line_stats {
return (length($line), length($white));
}
+my $sanitise_quote = '';
+
+sub sanitise_line_reset {
+ my ($in_comment) = @_;
+
+ if ($in_comment) {
+ $sanitise_quote = '*/';
+ } else {
+ $sanitise_quote = '';
+ }
+}
sub sanitise_line {
my ($line) = @_;
my $res = '';
my $l = '';
- my $quote = '';
my $qlen = 0;
+ my $off = 0;
+ my $c;
- foreach my $c (split(//, $line)) {
- # The second backslash of a pair is not a "quote".
- if ($l eq "\\" && $c eq "\\") {
- $c = 'X';
- }
- if ($l ne "\\" && ($c eq "'" || $c eq '"')) {
- if ($quote eq '') {
- $quote = $c;
- $res .= $c;
- $l = $c;
- $qlen = 0;
- next;
- } elsif ($quote eq $c) {
- $quote = '';
- }
+ # Always copy over the diff marker.
+ $res = substr($line, 0, 1);
+
+ for ($off = 1; $off < length($line); $off++) {
+ $c = substr($line, $off, 1);
+
+ # Comments we are wacking completly including the begin
+ # and end, all to $;.
+ if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
+ $sanitise_quote = '*/';
+
+ substr($res, $off, 2, "$;$;");
+ $off++;
+ next;
}
- if ($quote eq "'" && $qlen > 1) {
- $quote = '';
+ if (substr($line, $off, 2) eq $sanitise_quote) {
+ $sanitise_quote = '';
+ substr($res, $off, 2, "$;$;");
+ $off++;
+ next;
}
- if ($quote && $c ne "\t") {
- $res .= "X";
- $qlen++;
- } else {
- $res .= $c;
+
+ # A \ in a string means ignore the next character.
+ if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
+ $c eq "\\") {
+ substr($res, $off, 2, 'XX');
+ $off++;
+ next;
}
+ # Regular quotes.
+ if ($c eq "'" || $c eq '"') {
+ if ($sanitise_quote eq '') {
+ $sanitise_quote = $c;
- $l = $c;
- }
+ substr($res, $off, 1, $c);
+ next;
+ } elsif ($sanitise_quote eq $c) {
+ $sanitise_quote = '';
+ }
+ }
- # Clear out the comments.
- while ($res =~ m@(/\*.*?\*/)@g) {
- substr($res, $-[1], $+[1] - $-[1]) = $; x ($+[1] - $-[1]);
- }
- if ($res =~ m@(/\*.*)@) {
- substr($res, $-[1], $+[1] - $-[1]) = $; x ($+[1] - $-[1]);
- }
- if ($res =~ m@^.(.*\*/)@) {
- substr($res, $-[1], $+[1] - $-[1]) = $; x ($+[1] - $-[1]);
+ #print "SQ:$sanitise_quote\n";
+ if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
+ substr($res, $off, 1, $;);
+ } elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
+ substr($res, $off, 1, 'X');
+ } else {
+ substr($res, $off, 1, $c);
+ }
}
# The pathname on a #include may be surrounded by '<' and '>'.
@@ -357,17 +374,19 @@ sub ctx_statement_block {
my $blk = '';
my $soff = $off;
my $coff = $off - 1;
+ my $coff_set = 0;
my $loff = 0;
my $type = '';
my $level = 0;
+ my $p;
my $c;
my $len = 0;
my $remainder;
while (1) {
- #warn "CSB: blk<$blk>\n";
+ #warn "CSB: blk<$blk> remain<$remain>\n";
# If we are about to drop off the end, pull in more
# context.
if ($off >= $len) {
@@ -386,10 +405,11 @@ sub ctx_statement_block {
last;
}
}
+ $p = $c;
$c = substr($blk, $off, 1);
$remainder = substr($blk, $off);
- #warn "CSB: c<$c> type<$type> level<$level>\n";
+ #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
# Statement ends at the ';' or a close '}' at the
# outermost level.
if ($level == 0 && $c eq ';') {
@@ -397,9 +417,14 @@ sub ctx_statement_block {
}
# An else is really a conditional as long as its not else if
- if ($level == 0 && $remainder =~ /(\s+else)(?:\s|{)/ &&
- $remainder !~ /\s+else\s+if\b/) {
- $coff = $off + length($1);
+ if ($level == 0 && $coff_set == 0 &&
+ (!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
+ $remainder =~ /^(else)(?:\s|{)/ &&
+ $remainder !~ /^else\s+if\b/) {
+ $coff = $off + length($1) - 1;
+ $coff_set = 1;
+ #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
+ #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
}
if (($type eq '' || $type eq '(') && $c eq '(') {
@@ -412,6 +437,8 @@ sub ctx_statement_block {
if ($level == 0 && $coff < $soff) {
$coff = $off;
+ $coff_set = 1;
+ #warn "CSB: mark coff<$coff>\n";
}
}
if (($type eq '' || $type eq '{') && $c eq '{') {
@@ -439,27 +466,79 @@ sub ctx_statement_block {
#warn "STATEMENT<$statement>\n";
#warn "CONDITION<$condition>\n";
- #print "off<$off> loff<$loff>\n";
+ #print "coff<$coff> soff<$off> loff<$loff>\n";
return ($statement, $condition,
$line, $remain + 1, $off - $loff + 1, $level);
}
+sub statement_lines {
+ my ($stmt) = @_;
+
+ # Strip the diff line prefixes and rip blank lines at start and end.
+ $stmt =~ s/(^|\n)./$1/g;
+ $stmt =~ s/^\s*//;
+ $stmt =~ s/\s*$//;
+
+ my @stmt_lines = ($stmt =~ /\n/g);
+
+ return $#stmt_lines + 2;
+}
+
+sub statement_rawlines {
+ my ($stmt) = @_;
+
+ my @stmt_lines = ($stmt =~ /\n/g);
+
+ return $#stmt_lines + 2;
+}
+
+sub statement_block_size {
+ my ($stmt) = @_;
+
+ $stmt =~ s/(^|\n)./$1/g;
+ $stmt =~ s/^\s*{//;
+ $stmt =~ s/}\s*$//;
+ $stmt =~ s/^\s*//;
+ $stmt =~ s/\s*$//;
+
+ my @stmt_lines = ($stmt =~ /\n/g);
+ my @stmt_statements = ($stmt =~ /;/g);
+
+ my $stmt_lines = $#stmt_lines + 2;
+ my $stmt_statements = $#stmt_statements + 1;
+
+ if ($stmt_lines > $stmt_statements) {
+ return $stmt_lines;
+ } else {
+ return $stmt_statements;
+ }
+}
+
sub ctx_statement_full {
my ($linenr, $remain, $off) = @_;
my ($statement, $condition, $level);
my (@chunks);
+ # Grab the first conditional/block pair.
($statement, $condition, $linenr, $remain, $off, $level) =
ctx_statement_block($linenr, $remain, $off);
- #print "F: c<$condition> s<$statement>\n";
+ #print "F: c<$condition> s<$statement> remain<$remain>\n";
+ push(@chunks, [ $condition, $statement ]);
+ if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
+ return ($level, $linenr, @chunks);
+ }
+
+ # Pull in the following conditional/block pairs and see if they
+ # could continue the statement.
for (;;) {
- push(@chunks, [ $condition, $statement ]);
- last if (!($remain > 0 && $condition =~ /^.\s*(?:if|else|do)/));
($statement, $condition, $linenr, $remain, $off, $level) =
ctx_statement_block($linenr, $remain, $off);
- #print "C: c<$condition> s<$statement>\n";
+ #print "C: c<$condition> s<$statement> remain<$remain>\n";
+ last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
+ #print "C: push\n";
+ push(@chunks, [ $condition, $statement ]);
}
return ($level, $linenr, @chunks);
@@ -593,13 +672,13 @@ sub cat_vet {
}
my $av_preprocessor = 0;
-my $av_paren = 0;
+my $av_pending;
my @av_paren_type;
sub annotate_reset {
$av_preprocessor = 0;
- $av_paren = 0;
- @av_paren_type = ();
+ $av_pending = '_';
+ @av_paren_type = ('E');
}
sub annotate_values {
@@ -611,12 +690,14 @@ sub annotate_values {
print "$stream\n" if ($dbg_values > 1);
while (length($cur)) {
- print " <$type> " if ($dbg_values > 1);
+ @av_paren_type = ('E') if ($#av_paren_type < 0);
+ print " <" . join('', @av_paren_type) .
+ "> <$type> " if ($dbg_values > 1);
if ($cur =~ /^(\s+)/o) {
print "WS($1)\n" if ($dbg_values > 1);
if ($1 =~ /\n/ && $av_preprocessor) {
+ $type = pop(@av_paren_type);
$av_preprocessor = 0;
- $type = 'N';
}
} elsif ($cur =~ /^($Type)/) {
@@ -626,11 +707,33 @@ sub annotate_values {
} elsif ($cur =~ /^(#\s*define\s*$Ident)(\(?)/o) {
print "DEFINE($1)\n" if ($dbg_values > 1);
$av_preprocessor = 1;
- $av_paren_type[$av_paren] = 'N';
+ $av_pending = 'N';
- } elsif ($cur =~ /^(#\s*(?:ifdef|ifndef|if|else|elif|endif))/o) {
- print "PRE($1)\n" if ($dbg_values > 1);
+ } elsif ($cur =~ /^(#\s*(?:ifdef|ifndef|if))/o) {
+ print "PRE_START($1)\n" if ($dbg_values > 1);
$av_preprocessor = 1;
+
+ push(@av_paren_type, $type);
+ push(@av_paren_type, $type);
+ $type = 'N';
+
+ } elsif ($cur =~ /^(#\s*(?:else|elif))/o) {
+ print "PRE_RESTART($1)\n" if ($dbg_values > 1);
+ $av_preprocessor = 1;
+
+ push(@av_paren_type, $av_paren_type[$#av_paren_type]);
+
+ $type = 'N';
+
+ } elsif ($cur =~ /^(#\s*(?:endif))/o) {
+ print "PRE_END($1)\n" if ($dbg_values > 1);
+
+ $av_preprocessor = 1;
+
+ # Assume all arms of the conditional end as this
+ # one does, and continue as if the #endif was not here.
+ pop(@av_paren_type);
+ push(@av_paren_type, $type);
$type = 'N';
} elsif ($cur =~ /^(\\\n)/o) {
@@ -639,13 +742,13 @@ sub annotate_values {
} elsif ($cur =~ /^(sizeof)\s*(\()?/o) {
print "SIZEOF($1)\n" if ($dbg_values > 1);
if (defined $2) {
- $av_paren_type[$av_paren] = 'V';
+ $av_pending = 'V';
}
$type = 'N';
} elsif ($cur =~ /^(if|while|typeof|__typeof__|for)\b/o) {
print "COND($1)\n" if ($dbg_values > 1);
- $av_paren_type[$av_paren] = 'N';
+ $av_pending = 'N';
$type = 'N';
} elsif ($cur =~/^(return|case|else)/o) {
@@ -654,14 +757,14 @@ sub annotate_values {
} elsif ($cur =~ /^(\()/o) {
print "PAREN('$1')\n" if ($dbg_values > 1);
- $av_paren++;
+ push(@av_paren_type, $av_pending);
+ $av_pending = '_';
$type = 'N';
} elsif ($cur =~ /^(\))/o) {
- $av_paren-- if ($av_paren > 0);
- if (defined $av_paren_type[$av_paren]) {
- $type = $av_paren_type[$av_paren];
- undef $av_paren_type[$av_paren];
+ my $new_type = pop(@av_paren_type);
+ if ($new_type ne '_') {
+ $type = $new_type;
print "PAREN('$1') -> $type\n"
if ($dbg_values > 1);
} else {
@@ -670,7 +773,7 @@ sub annotate_values {
} elsif ($cur =~ /^($Ident)\(/o) {
print "FUNC($1)\n" if ($dbg_values > 1);
- $av_paren_type[$av_paren] = 'V';
+ $av_pending = 'V';
} elsif ($cur =~ /^($Ident|$Constant)/o) {
print "IDENT($1)\n" if ($dbg_values > 1);
@@ -680,11 +783,11 @@ sub annotate_values {
print "ASSIGN($1)\n" if ($dbg_values > 1);
$type = 'N';
- } elsif ($cur =~/^(;)/) {
+ } elsif ($cur =~/^(;|{|})/) {
print "END($1)\n" if ($dbg_values > 1);
$type = 'E';
- } elsif ($cur =~ /^(;|{|}|\?|:|\[)/o) {
+ } elsif ($cur =~ /^(;|\?|:|\[)/o) {
print "CLOSE($1)\n" if ($dbg_values > 1);
$type = 'N';
@@ -724,28 +827,34 @@ sub possible {
my $prefix = '';
sub report {
+ if (defined $tst_only && $_[0] !~ /\Q$tst_only\E/) {
+ return 0;
+ }
my $line = $prefix . $_[0];
$line = (split('\n', $line))[0] . "\n" if ($terse);
push(our @report, $line);
+
+ return 1;
}
sub report_dump {
our @report;
}
sub ERROR {
- report("ERROR: $_[0]\n");
- our $clean = 0;
- our $cnt_error++;
+ if (report("ERROR: $_[0]\n")) {
+ our $clean = 0;
+ our $cnt_error++;
+ }
}
sub WARN {
- report("WARNING: $_[0]\n");
- our $clean = 0;
- our $cnt_warn++;
+ if (report("WARNING: $_[0]\n")) {
+ our $clean = 0;
+ our $cnt_warn++;
+ }
}
sub CHK {
- if ($check) {
- report("CHECK: $_[0]\n");
+ if ($check && report("CHECK: $_[0]\n")) {
our $clean = 0;
our $cnt_chk++;
}
@@ -787,30 +896,76 @@ sub process {
my $prev_values = 'E';
# suppression flags
- my $suppress_ifbraces = 0;
+ my %suppress_ifbraces;
# Pre-scan the patch sanitizing the lines.
# Pre-scan the patch looking for any __setup documentation.
#
my @setup_docs = ();
my $setup_docs = 0;
+
+ sanitise_line_reset();
my $line;
foreach my $rawline (@rawlines) {
- # Standardise the strings and chars within the input to
- # simplify matching.
- $line = sanitise_line($rawline);
- push(@lines, $line);
-
- ##print "==>$rawline\n";
- ##print "-->$line\n";
+ $linenr++;
+ $line = $rawline;
- if ($line=~/^\+\+\+\s+(\S+)/) {
+ if ($rawline=~/^\+\+\+\s+(\S+)/) {
$setup_docs = 0;
if ($1 =~ m@Documentation/kernel-parameters.txt$@) {
$setup_docs = 1;
}
- next;
+ #next;
+ }
+ if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
+ $realline=$1-1;
+ if (defined $2) {
+ $realcnt=$3+1;
+ } else {
+ $realcnt=1+1;
+ }
+
+ # Guestimate if this is a continuing comment. Run
+ # the context looking for a comment "edge". If this
+ # edge is a close comment then we must be in a comment
+ # at context start.
+ my $edge;
+ for (my $ln = $linenr; $ln < ($linenr + $realcnt); $ln++) {
+ next if ($line =~ /^-/);
+ ($edge) = ($rawlines[$ln - 1] =~ m@(/\*|\*/)@);
+ last if (defined $edge);
+ }
+ if (defined $edge && $edge eq '*/') {
+ $in_comment = 1;
+ }
+
+ # Guestimate if this is a continuing comment. If this
+ # is the start of a diff block and this line starts
+ # ' *' then it is very likely a comment.
+ if (!defined $edge &&
+ $rawlines[$linenr] =~ m@^.\s* \*(?:\s|$)@)
+ {
+ $in_comment = 1;
+ }
+
+ ##print "COMMENT:$in_comment edge<$edge> $rawline\n";
+ sanitise_line_reset($in_comment);
+
+ } elsif ($realcnt) {
+ # Standardise the strings and chars within the input to
+ # simplify matching.
+ $line = sanitise_line($rawline);
}
+ push(@lines, $line);
+
+ if ($realcnt > 1) {
+ $realcnt-- if ($line =~ /^(?:\+| |$)/);
+ } else {
+ $realcnt = 0;
+ }
+
+ #print "==>$rawline\n";
+ #print "-->$line\n";
if ($setup_docs && $line =~ /^\+/) {
push(@setup_docs, $line);
@@ -819,23 +974,17 @@ sub process {
$prefix = '';
+ $realcnt = 0;
+ $linenr = 0;
foreach my $line (@lines) {
$linenr++;
my $rawline = $rawlines[$linenr - 1];
-#extract the filename as it passes
- if ($line=~/^\+\+\+\s+(\S+)/) {
- $realfile=$1;
- $realfile =~ s@^[^/]*/@@;
- $in_comment = 0;
- next;
- }
#extract the line range in the file after the patch is applied
if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
$is_patch = 1;
$first_line = $linenr + 1;
- $in_comment = 0;
$realline=$1-1;
if (defined $2) {
$realcnt=$3+1;
@@ -845,50 +994,16 @@ sub process {
annotate_reset();
$prev_values = 'E';
- $suppress_ifbraces = $linenr - 1;
+ %suppress_ifbraces = ();
next;
- }
# track the line number as we move through the hunk, note that
# new versions of GNU diff omit the leading space on completely
# blank context lines so we need to count that too.
- if ($line =~ /^( |\+|$)/) {
+ } elsif ($line =~ /^( |\+|$)/) {
$realline++;
$realcnt-- if ($realcnt != 0);
- # Guestimate if this is a continuing comment. Run
- # the context looking for a comment "edge". If this
- # edge is a close comment then we must be in a comment
- # at context start.
- if ($linenr == $first_line) {
- my $edge;
- for (my $ln = $first_line; $ln < ($linenr + $realcnt); $ln++) {
- ($edge) = ($rawlines[$ln - 1] =~ m@(/\*|\*/)@);
- last if (defined $edge);
- }
- if (defined $edge && $edge eq '*/') {
- $in_comment = 1;
- }
- }
-
- # Guestimate if this is a continuing comment. If this
- # is the start of a diff block and this line starts
- # ' *' then it is very likely a comment.
- if ($linenr == $first_line and $rawline =~ m@^.\s* \*(?:\s|$)@) {
- $in_comment = 1;
- }
-
- # Find the last comment edge on _this_ line.
- $comment_edge = 0;
- while (($rawline =~ m@(/\*|\*/)@g)) {
- if ($1 eq '/*') {
- $in_comment = 1;
- } else {
- $in_comment = 0;
- }
- $comment_edge = 1;
- }
-
# Measure the line length and indent.
($length, $indent) = line_stats($rawline);
@@ -897,23 +1012,36 @@ sub process {
($previndent, $stashindent) = ($stashindent, $indent);
($prevrawline, $stashrawline) = ($stashrawline, $rawline);
- #warn "ic<$in_comment> ce<$comment_edge> line<$line>\n";
+ #warn "line<$line>\n";
} elsif ($realcnt == 1) {
$realcnt--;
}
#make up the handle for any error we report on this line
+ $prefix = "$filename:$realline: " if ($emacs && $file);
+ $prefix = "$filename:$linenr: " if ($emacs && !$file);
+
$here = "#$linenr: " if (!$file);
$here = "#$realline: " if ($file);
+
+ # extract the filename as it passes
+ if ($line=~/^\+\+\+\s+(\S+)/) {
+ $realfile = $1;
+ $realfile =~ s@^[^/]*/@@;
+
+ 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");
+ }
+ next;
+ }
+
$here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
my $hereline = "$here\n$rawline\n";
my $herecurr = "$here\n$rawline\n";
my $hereprev = "$here\n$prevrawline\n$rawline\n";
- $prefix = "$filename:$realline: " if ($emacs && $file);
- $prefix = "$filename:$linenr: " if ($emacs && !$file);
$cnt_lines++ if ($realcnt != 0);
#check the patch for a signoff:
@@ -925,7 +1053,7 @@ sub process {
$herecurr);
}
if ($line =~ /^\s*signed-off-by:\S/i) {
- WARN("need space after Signed-off-by:\n" .
+ WARN("space required after Signed-off-by:\n" .
$herecurr);
}
}
@@ -988,52 +1116,50 @@ sub process {
}
# check for RCS/CVS revision markers
- if ($rawline =~ /\$(Revision|Log|Id)(?:\$|)/) {
+ if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
WARN("CVS style keyword markers, these will _not_ be updated\n". $herecurr);
}
-# The rest of our checks refer specifically to C style
-# only apply those _outside_ comments. Only skip
-# lines in the middle of comments.
- next if (!$comment_edge && $in_comment);
-
# Check for potential 'bare' types
if ($realcnt) {
+ my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
+ $s =~ s/\n./ /g;
+ $s =~ s/{.*$//;
+
# Ignore goto labels.
- if ($line =~ /$Ident:\*$/) {
+ if ($s =~ /$Ident:\*$/) {
# Ignore functions being called
- } elsif ($line =~ /^.\s*$Ident\s*\(/) {
+ } elsif ($s =~ /^.\s*$Ident\s*\(/) {
# definitions in global scope can only start with types
- } elsif ($line =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b/) {
- possible($1, $line);
+ } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b/) {
+ possible($1, $s);
# declarations always start with types
- } elsif ($prev_values eq 'E' && $line =~ /^.\s*(?:$Storage\s+)?(?:const\s+)?($Ident)\b(:?\s+$Sparse)?\s*\**\s*$Ident\s*(?:;|=|,)/) {
- possible($1);
+ } elsif ($prev_values eq 'E' && $s =~ /^.\s*(?:$Storage\s+)?(?:const\s+)?($Ident)\b(:?\s+$Sparse)?\s*\**\s*$Ident\s*(?:;|=|,)/) {
+ possible($1, $s);
}
# any (foo ... *) is a pointer cast, and foo is a type
- while ($line =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/g) {
- possible($1, $line);
+ while ($s =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/g) {
+ possible($1, $s);
}
# Check for any sort of function declaration.
# int foo(something bar, other baz);
# void (*store_gdt)(x86_descr_ptr *);
- if ($prev_values eq 'E' && $line =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/) {
+ if ($prev_values eq 'E' && $s =~ /^(.(?:typedef\s*)?(?:(?:$Storage|$Inline)\s*)*\s*$Type\s*(?:\b$Ident|\(\*\s*$Ident\))\s*)\(/) {
my ($name_len) = length($1);
- my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, $name_len);
- my $ctx = join("\n", @ctx);
- $ctx =~ s/\n.//;
- substr($ctx, 0, $name_len + 1) = '';
+ my $ctx = $s;
+ substr($ctx, 0, $name_len + 1, '');
$ctx =~ s/\)[^\)]*$//;
+
for my $arg (split(/\s*,\s*/, $ctx)) {
if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/ || $arg =~ /^($Ident)$/) {
- possible($1, $line);
+ possible($1, $s);
}
}
}
@@ -1068,27 +1194,33 @@ sub process {
# if/while/etc brace do not go on next line, unless defining a do while loop,
# or if that brace on the next line is for something else
- if ($line =~ /\b(?:(if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.#/) {
+ if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.#/) {
+ my $pre_ctx = "$1$2";
+
my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
my $ctx_ln = $linenr + $#ctx + 1;
my $ctx_cnt = $realcnt - $#ctx - 1;
my $ctx = join("\n", @ctx);
+ ##warn "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
+
# Skip over any removed lines in the context following statement.
- while ($ctx_cnt > 0 && $lines[$ctx_ln - 1] =~ /^-/) {
+ while (defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^-/) {
$ctx_ln++;
- $ctx_cnt--;
}
- ##warn "line<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>";
+ ##warn "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
- if ($ctx !~ /{\s*/ && $ctx_cnt > 0 && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
- ERROR("That open brace { should be on the previous line\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" .
"$here\n$ctx\n$lines[$ctx_ln - 1]");
}
- if ($level == 0 && $ctx =~ /\)\s*\;\s*$/ && defined $lines[$ctx_ln - 1]) {
+ if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
+ $ctx =~ /\)\s*\;\s*$/ &&
+ defined $lines[$ctx_ln - 1])
+ {
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 indicates no statements, indent implies otherwise\n" .
"$here\n$ctx\n$lines[$ctx_ln - 1]");
}
}
@@ -1100,8 +1232,8 @@ sub process {
$curr_values = $prev_values . $curr_values;
if ($dbg_values) {
my $outline = $opline; $outline =~ s/\t/ /g;
- warn "--> .$outline\n";
- warn "--> $curr_values\n";
+ print "$linenr > .$outline\n";
+ print "$linenr > $curr_values\n";
}
$prev_values = substr($curr_values, -1);
@@ -1117,7 +1249,7 @@ sub process {
# check for initialisation to aggregates open brace on the next line
if ($prevline =~ /$Declare\s*$Ident\s*=\s*$/ &&
$line =~ /^.\s*{/) {
- ERROR("That open brace { should be on the previous line\n" . $hereprev);
+ ERROR("that open brace { should be on the previous line\n" . $hereprev);
}
#
@@ -1148,7 +1280,9 @@ sub process {
if (($prevline !~ /^}/) &&
($prevline !~ /^\+}/) &&
($prevline !~ /^ }/) &&
- ($prevline !~ /\b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=)/)) {
+ ($prevline !~ /^.DECLARE_$Ident\(\Q$name\E\)/) &&
+ ($prevline !~ /^.LIST_HEAD\(\Q$name\E\)/) &&
+ ($prevline !~ /\b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=|\[)/)) {
WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
}
}
@@ -1240,22 +1374,31 @@ sub process {
# check for spaces between functions and their parentheses.
while ($line =~ /($Ident)\s+\(/g) {
my $name = $1;
- my $ctx = substr($line, 0, $-[1]);
+ my $ctx_before = substr($line, 0, $-[1]);
+ my $ctx = "$ctx_before$name";
# Ignore those directives where spaces _are_ permitted.
- if ($name =~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright|case|__asm__)$/) {
+ if ($name =~ /^(?:
+ if|for|while|switch|return|case|
+ volatile|__volatile__|
+ __attribute__|format|__extension__|
+ asm|__asm__)$/x)
+ {
# 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.
- } elsif ($ctx =~ /^.\#\s*define\s*$/) {
+ } elsif ($ctx_before =~ /^.\#\s*define\s*$/) {
+
+ # cpp #elif statement condition may start with a (
+ } elsif ($ctx =~ /^.\#\s*elif\s*$/) {
# If this whole things ends with a type its most
# likely a typedef for a function.
- } elsif ("$ctx$name" =~ /$Type$/) {
+ } elsif ($ctx =~ /$Type$/) {
} else {
- WARN("no space between function name and open parenthesis '('\n" . $herecurr);
+ WARN("space prohibited between function name and open parenthesis '('\n" . $herecurr);
}
}
# Check operator spacing.
@@ -1266,7 +1409,7 @@ sub process {
=>|->|<<|>>|<|>|=|!|~|
&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%
}x;
- my @elements = split(/($;+|$ops|;)/, $opline);
+ my @elements = split(/($ops|;)/, $opline);
my $off = 0;
my $blank = copy_spacing($opline);
@@ -1274,12 +1417,21 @@ sub process {
for (my $n = 0; $n < $#elements; $n += 2) {
$off += length($elements[$n]);
+ # Pick up the preceeding and succeeding characters.
+ my $ca = substr($opline, 0, $off);
+ my $cc = '';
+ if (length($opline) >= ($off + length($elements[$n + 1]))) {
+ $cc = substr($opline, $off + length($elements[$n + 1]));
+ }
+ my $cb = "$ca$;$cc";
+
my $a = '';
$a = 'V' if ($elements[$n] ne '');
$a = 'W' if ($elements[$n] =~ /\s$/);
+ $a = 'C' if ($elements[$n] =~ /$;$/);
$a = 'B' if ($elements[$n] =~ /(\[|\()$/);
$a = 'O' if ($elements[$n] eq '');
- $a = 'E' if ($elements[$n] eq '' && $n == 0);
+ $a = 'E' if ($ca =~ /^\s*$/);
my $op = $elements[$n + 1];
@@ -1287,6 +1439,7 @@ sub process {
if (defined $elements[$n + 2]) {
$c = 'V' if ($elements[$n + 2] ne '');
$c = 'W' if ($elements[$n + 2] =~ /^\s/);
+ $c = 'C' if ($elements[$n + 2] =~ /^$;/);
$c = 'B' if ($elements[$n + 2] =~ /^(\)|\]|;)/);
$c = 'O' if ($elements[$n + 2] eq '');
$c = 'E' if ($elements[$n + 2] =~ /\s*\\$/);
@@ -1294,14 +1447,6 @@ sub process {
$c = 'E';
}
- # Pick up the preceeding and succeeding characters.
- my $ca = substr($opline, 0, $off);
- my $cc = '';
- if (length($opline) >= ($off + length($elements[$n + 1]))) {
- $cc = substr($opline, $off + length($elements[$n + 1]));
- }
- my $cb = "$ca$;$cc";
-
my $ctx = "${a}x${c}";
my $at = "(ctx:$ctx)";
@@ -1330,14 +1475,14 @@ sub process {
if ($op_type ne 'V' &&
$ca =~ /\s$/ && $cc =~ /^\s*,/) {
- # Ignore comments
- } elsif ($op =~ /^$;+$/) {
+# # Ignore comments
+# } elsif ($op =~ /^$;+$/) {
# ; should have either the end of line or a space or \ after it
} elsif ($op eq ';') {
- if ($ctx !~ /.x[WEB]/ && $cc !~ /^\\/ &&
- $cc !~ /^;/) {
- ERROR("need space after that '$op' $at\n" . $hereptr);
+ if ($ctx !~ /.x[WEBC]/ &&
+ $cc !~ /^\\/ && $cc !~ /^;/) {
+ ERROR("space required after that '$op' $at\n" . $hereptr);
}
# // is a comment
@@ -1346,13 +1491,13 @@ sub process {
# -> should have no spaces
} elsif ($op eq '->') {
if ($ctx =~ /Wx.|.xW/) {
- ERROR("no spaces around that '$op' $at\n" . $hereptr);
+ ERROR("spaces prohibited around that '$op' $at\n" . $hereptr);
}
# , must have a space on the right.
} elsif ($op eq ',') {
- if ($ctx !~ /.xW|.xE/ && $cc !~ /^}/) {
- ERROR("need space after that '$op' $at\n" . $hereptr);
+ if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
+ ERROR("space required after that '$op' $at\n" . $hereptr);
}
# '*' as part of a type definition -- reported already.
@@ -1364,21 +1509,26 @@ sub process {
# unary operator, or a cast
} elsif ($op eq '!' || $op eq '~' ||
($is_unary && ($op eq '*' || $op eq '-' || $op eq '&'))) {
- if ($ctx !~ /[WEB]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
- ERROR("need space before that '$op' $at\n" . $hereptr);
+ if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
+ ERROR("space required before that '$op' $at\n" . $hereptr);
}
if ($ctx =~ /.xW/) {
- ERROR("no space after that '$op' $at\n" . $hereptr);
+ ERROR("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 !~ /[WOB]x[^W]/ && $ctx !~ /[^W]x[WOBE]/) {
- ERROR("need space one side of that '$op' $at\n" . $hereptr);
+ if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
+ ERROR("space required one side of that '$op' $at\n" . $hereptr);
}
- if ($ctx =~ /WxB/ || ($ctx =~ /Wx./ && $cc =~ /^;/)) {
- ERROR("no space before that '$op' $at\n" . $hereptr);
+ if ($ctx =~ /Wx[BE]/ ||
+ ($ctx =~ /Wx./ && $cc =~ /^;/)) {
+ ERROR("space prohibited before that '$op' $at\n" . $hereptr);
}
+ if ($ctx =~ /ExW/) {
+ ERROR("space prohibited after that '$op' $at\n" . $hereptr);
+ }
+
# << and >> may either have or not have spaces both sides
} elsif ($op eq '<<' or $op eq '>>' or
@@ -1387,17 +1537,17 @@ sub process {
$op eq '*' or $op eq '/' or
$op eq '%')
{
- if ($ctx !~ /VxV|WxW|VxE|WxE|VxO/) {
+ if ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
ERROR("need consistent spacing around '$op' $at\n" .
$hereptr);
}
# All the others need spaces both sides.
- } elsif ($ctx !~ /[EW]x[WE]/) {
+ } elsif ($ctx !~ /[EWC]x[CWE]/) {
# Ignore email addresses <foo@bar>
if (!($op eq '<' && $cb =~ /$;\S+\@\S+>/) &&
!($op eq '>' && $cb =~ /<\S+\@\S+$;/)) {
- ERROR("need spaces around that '$op' $at\n" . $hereptr);
+ ERROR("spaces required around that '$op' $at\n" . $hereptr);
}
}
$off += length($elements[$n + 1]);
@@ -1427,31 +1577,31 @@ sub process {
#need space before brace following if, while, etc
if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) ||
$line =~ /do{/) {
- ERROR("need a space before the open brace '{'\n" . $herecurr);
+ ERROR("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("need a space after that close brace '}'\n" . $herecurr);
+ ERROR("space required after that close brace '}'\n" . $herecurr);
}
# check spacing on square brackets
if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
- ERROR("no space after that open square bracket '['\n" . $herecurr);
+ ERROR("space prohibited after that open square bracket '['\n" . $herecurr);
}
if ($line =~ /\s\]/) {
- ERROR("no space before that close square bracket ']'\n" . $herecurr);
+ ERROR("space prohibited before that close square bracket ']'\n" . $herecurr);
}
# check spacing on paretheses
if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
$line !~ /for\s*\(\s+;/) {
- ERROR("no space after that open parenthesis '('\n" . $herecurr);
+ ERROR("space prohibited after that open parenthesis '('\n" . $herecurr);
}
if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
$line !~ /for\s*\(.*;\s+\)/) {
- ERROR("no space before that close parenthesis ')'\n" . $herecurr);
+ ERROR("space prohibited before that close parenthesis ')'\n" . $herecurr);
}
#goto labels aren't indented, allow a single space however
@@ -1462,7 +1612,7 @@ sub process {
# Need a space before open parenthesis after if, while etc
if ($line=~/\b(if|while|for|switch)\(/) {
- ERROR("need a space before the open parenthesis '('\n" . $herecurr);
+ ERROR("space required before the open parenthesis '('\n" . $herecurr);
}
# Check for illegal assignment in if conditional.
@@ -1475,10 +1625,12 @@ sub process {
# Find out what is on the end of the line after the
# conditional.
- substr($s, 0, length($c)) = '';
+ substr($s, 0, length($c), '');
$s =~ s/\n.*//g;
$s =~ s/$;//g; # Remove any comments
- if (length($c) && $s !~ /^\s*({|;|)\s*\\*\s*$/) {
+ if (length($c) && $s !~ /^\s*({|;|)\s*\\*\s*$/ &&
+ $c !~ /^.\#\s*if/)
+ {
ERROR("trailing statements should be on next line\n" . $herecurr);
}
}
@@ -1520,7 +1672,7 @@ sub process {
# Find out what is on the end of the line after the
# conditional.
- substr($s, 0, length($c)) = '';
+ substr($s, 0, length($c), '');
$s =~ s/\n.*//g;
if ($s =~ /^\s*;/) {
@@ -1544,14 +1696,14 @@ sub process {
if ($tree && $rawline =~ m{^.\#\s*include\s*\<asm\/(.*)\.h\>}) {
my $checkfile = "$root/include/linux/$1.h";
if (-f $checkfile && $1 ne 'irq.h') {
- CHK("Use #include <linux/$1.h> instead of <asm/$1.h>\n" .
+ WARN("Use #include <linux/$1.h> instead of <asm/$1.h>\n" .
$herecurr);
}
}
# multi-statement macros should be enclosed in a do while loop, grab the
# first statement and ensure its the whole macro if its not enclosed
-# in a known goot container
+# in a known good container
if ($prevline =~ /\#define.*\\/ &&
$prevline !~/(?:do\s+{|\(\{|\{)/ &&
$line !~ /(?:do\s+{|\(\{|\{)/ &&
@@ -1599,84 +1751,103 @@ sub process {
# check for redundant bracing round if etc
if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) {
my ($level, $endln, @chunks) =
- ctx_statement_full($linenr, $realcnt, 0);
+ ctx_statement_full($linenr, $realcnt, 1);
#print "chunks<$#chunks> linenr<$linenr> endln<$endln> level<$level>\n";
- if ($#chunks > 1 && $level == 0) {
+ #print "APW: <<$chunks[1][0]>><<$chunks[1][1]>>\n";
+ if ($#chunks > 0 && $level == 0) {
my $allowed = 0;
my $seen = 0;
+ my $herectx = $here . "\n";
+ my $ln = $linenr - 1;
for my $chunk (@chunks) {
my ($cond, $block) = @{$chunk};
- substr($block, 0, length($cond)) = '';
+ # If the condition carries leading newlines, then count those as offsets.
+ my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
+ my $offset = statement_rawlines($whitespace) - 1;
- $seen++ if ($block =~ /^\s*{/);
+ #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
- $block =~ s/(^|\n)./$1/g;
- $block =~ s/^\s*{//;
- $block =~ s/}\s*$//;
- $block =~ s/^\s*//;
- $block =~ s/\s*$//;
+ # We have looked at and allowed this specific line.
+ $suppress_ifbraces{$ln + $offset} = 1;
- my @lines = ($block =~ /\n/g);
- my @statements = ($block =~ /;/g);
+ $herectx .= "$rawlines[$ln + $offset]\n[...]\n";
+ $ln += statement_rawlines($block) - 1;
- #print "cond<$cond> block<$block> lines<" . scalar(@lines) . "> statements<" . scalar(@statements) . "> seen<$seen> allowed<$allowed>\n";
- if (scalar(@lines) != 0) {
+ substr($block, 0, length($cond), '');
+
+ $seen++ if ($block =~ /^\s*{/);
+
+ #print "cond<$cond> block<$block> allowed<$allowed>\n";
+ if (statement_lines($cond) > 1) {
+ #print "APW: ALLOWED: cond<$cond>\n";
$allowed = 1;
}
if ($block =~/\b(?:if|for|while)\b/) {
+ #print "APW: ALLOWED: block<$block>\n";
$allowed = 1;
}
- if (scalar(@statements) > 1) {
+ if (statement_block_size($block) > 1) {
+ #print "APW: ALLOWED: lines block<$block>\n";
$allowed = 1;
}
}
if ($seen && !$allowed) {
- WARN("braces {} are not necessary for any arm of this statement\n" . $herecurr);
- $suppress_ifbraces = $endln;
+ WARN("braces {} are not necessary for any arm of this statement\n" . $herectx);
}
}
}
- if ($linenr > $suppress_ifbraces &&
+ if (!defined $suppress_ifbraces{$linenr - 1} &&
$line =~ /\b(if|while|for|else)\b/) {
- # Locate the end of the opening statement.
- my @control = ctx_statement($linenr, $realcnt, 0);
- my $nr = $linenr + (scalar(@control) - 1);
- my $cnt = $realcnt - (scalar(@control) - 1);
-
- my $off = $realcnt - $cnt;
- #print "$off: line<$line>end<" . $lines[$nr - 1] . ">\n";
-
- # If this is is a braced statement group check it
- if ($lines[$nr - 1] =~ /{\s*$/) {
- my ($lvl, @block) = ctx_block_level($nr, $cnt);
-
- my $stmt = join("\n", @block);
- # Drop the diff line leader.
- $stmt =~ s/\n./\n/g;
- # Drop the code outside the block.
- $stmt =~ s/(^[^{]*){\s*//;
- my $before = $1;
- $stmt =~ s/\s*}([^}]*$)//;
- my $after = $1;
-
- #print "block<" . join(' ', @block) . "><" . scalar(@block) . ">\n";
- #print "before<$before> stmt<$stmt> after<$after>\n\n";
-
- # Count the newlines, if there is only one
- # then the block should not have {}'s.
- my @lines = ($stmt =~ /\n/g);
- my @statements = ($stmt =~ /;/g);
- #print "lines<" . scalar(@lines) . ">\n";
- #print "statements<" . scalar(@statements) . ">\n";
- if ($lvl == 0 && scalar(@lines) == 0 &&
- scalar(@statements) < 2 &&
- $stmt !~ /{/ && $stmt !~ /\bif\b/ &&
- $before !~ /}/ && $after !~ /{/) {
- my $herectx = "$here\n" . join("\n", @control, @block[1 .. $#block]) . "\n";
- shift(@block);
- WARN("braces {} are not necessary for single statement blocks\n" . $herectx);
+ my $allowed = 0;
+
+ # Check the pre-context.
+ if (substr($line, 0, $-[0]) =~ /(\}\s*)$/) {
+ #print "APW: ALLOWED: pre<$1>\n";
+ $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";
+ if (defined $cond) {
+ substr($block, 0, length($cond), '');
+ }
+ if (statement_lines($cond) > 1) {
+ #print "APW: ALLOWED: cond<$cond>\n";
+ $allowed = 1;
+ }
+ if ($block =~/\b(?:if|for|while)\b/) {
+ #print "APW: ALLOWED: block<$block>\n";
+ $allowed = 1;
+ }
+ if (statement_block_size($block) > 1) {
+ #print "APW: ALLOWED: lines block<$block>\n";
+ $allowed = 1;
+ }
+ # Check the post-context.
+ if (defined $chunks[1]) {
+ my ($cond, $block) = @{$chunks[1]};
+ if (defined $cond) {
+ substr($block, 0, length($cond), '');
}
+ if ($block =~ /^\s*\{/) {
+ #print "APW: ALLOWED: chunk-1 block<$block>\n";
+ $allowed = 1;
+ }
+ }
+ if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
+ my $herectx = $here . "\n";;
+ my $end = $linenr + statement_rawlines($block) - 1;
+
+ for (my $ln = $linenr - 1; $ln < $end; $ln++) {
+ $herectx .= $rawlines[$ln] . "\n";;
+ }
+
+ WARN("braces {} are not necessary for single statement blocks\n" . $herectx);
}
}
@@ -1784,6 +1955,28 @@ sub process {
if ($line =~ /__FUNCTION__/) {
WARN("__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr);
}
+
+# check for semaphores used as mutexes
+ if ($line =~ /\b(DECLARE_MUTEX|init_MUTEX)\s*\(/) {
+ WARN("mutexes are preferred for single holder semaphores\n" . $herecurr);
+ }
+# check for semaphores used as mutexes
+ if ($line =~ /\binit_MUTEX_LOCKED\s*\(/) {
+ WARN("consider using a completion\n" . $herecurr);
+ }
+# recommend strict_strto* over simple_strto*
+ if ($line =~ /\bsimple_(strto.*?)\s*\(/) {
+ WARN("consider using strict_$1 in preference to simple_$1\n" . $herecurr);
+ }
+
+# use of NR_CPUS is usually wrong
+# ignore definitions of NR_CPUS and usage to define arrays as likely right
+ if ($line =~ /\bNR_CPUS\b/ &&
+ $line !~ /^.#\s*define\s+NR_CPUS\s+/ &&
+ $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/)
+ {
+ WARN("usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
+ }
}
# If we have no input at all, then there is nothing to report on
@@ -1828,15 +2021,6 @@ sub process {
print "are false positives report them to the maintainer, see\n";
print "CHECKPATCH in MAINTAINERS.\n";
}
- print <<EOL if ($file == 1 && $quiet == 0);
-
-WARNING: Using --file mode. Please do not send patches to linux-kernel
-that change whole existing files if you did not significantly change most
-of the the file for other reasons anyways or just wrote the file newly
-from scratch. Pure code style patches have a significant cost in a
-quickly changing code base like Linux because they cause rejects
-with other changes.
-EOL
return $clean;
}
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 3929e5b35e7..4a03191ad17 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -298,22 +298,30 @@ void sym_calc_value(struct symbol *sym)
if (sym_is_choice_value(sym) && sym->visible == yes) {
prop = sym_get_choice_prop(sym);
newval.tri = (prop_get_symbol(prop)->curr.val == sym) ? yes : no;
- } else if (EXPR_OR(sym->visible, sym->rev_dep.tri) != no) {
- sym->flags |= SYMBOL_WRITE;
- if (sym_has_value(sym))
- newval.tri = sym->def[S_DEF_USER].tri;
- else if (!sym_is_choice(sym)) {
- prop = sym_get_default_prop(sym);
- if (prop)
- newval.tri = expr_calc_value(prop->expr);
+ } else {
+ if (sym->visible != no) {
+ /* if the symbol is visible use the user value
+ * if available, otherwise try the default value
+ */
+ sym->flags |= SYMBOL_WRITE;
+ if (sym_has_value(sym)) {
+ newval.tri = EXPR_AND(sym->def[S_DEF_USER].tri,
+ sym->visible);
+ goto calc_newval;
+ }
}
- newval.tri = EXPR_OR(EXPR_AND(newval.tri, sym->visible), sym->rev_dep.tri);
- } else if (!sym_is_choice(sym)) {
- prop = sym_get_default_prop(sym);
- if (prop) {
+ if (sym->rev_dep.tri != no)
sym->flags |= SYMBOL_WRITE;
- newval.tri = expr_calc_value(prop->expr);
+ if (!sym_is_choice(sym)) {
+ prop = sym_get_default_prop(sym);
+ if (prop) {
+ sym->flags |= SYMBOL_WRITE;
+ newval.tri = EXPR_AND(expr_calc_value(prop->expr),
+ prop->visible.tri);
+ }
}
+ calc_newval:
+ newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
}
if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
newval.tri = yes;
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 26146cbaa50..263d04ab2d9 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -247,6 +247,10 @@ my ($function, %function_table,%parametertypes,$declaration_purpose);
my ($type,$declaration_name,$return_type);
my ($newsection,$newcontents,$prototype,$filelist, $brcount, %source_map);
+if (defined($ENV{'KBUILD_VERBOSE'})) {
+ $verbose = "$ENV{'KBUILD_VERBOSE'}";
+}
+
# Generated docbook code is inserted in a template at a point where
# docbook v3.1 requires a non-zero sequence of RefEntry's; see:
# http://www.oasis-open.org/docbook/documentation/reference/html/refentry.html
@@ -1512,13 +1516,13 @@ sub create_parameterlist($$$) {
# corresponding data structures "correctly". Catch it later in
# output_* subs.
push_parameter($arg, "", $file);
- } elsif ($arg =~ m/\(.*\*/) {
+ } elsif ($arg =~ m/\(.+\)\s*\(/) {
# pointer-to-function
$arg =~ tr/#/,/;
- $arg =~ m/[^\(]+\(\*\s*([^\)]+)\)/;
+ $arg =~ m/[^\(]+\(\*?\s*(\w*)\s*\)/;
$param = $1;
$type = $arg;
- $type =~ s/([^\(]+\(\*)$param/$1/;
+ $type =~ s/([^\(]+\(\*?)\s*$param/$1/;
push_parameter($param, $type, $file);
} elsif ($arg) {
$arg =~ s/\s*:\s*/:/g;
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 9ddf944cce2..769b69db89c 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -51,11 +51,13 @@ do { \
sprintf(str + strlen(str), "*"); \
} while(0)
+unsigned int cross_build = 0;
/**
* Check that sizeof(device_id type) are consistent with size of section
* in .o file. If in-consistent then userspace and kernel does not agree
* on actual size which is a bug.
* Also verify that the final entry in the table is all zeros.
+ * Ignore both checks if build host differ from target host and size differs.
**/
static void device_id_check(const char *modname, const char *device_id,
unsigned long size, unsigned long id_size,
@@ -64,6 +66,8 @@ static void device_id_check(const char *modname, const char *device_id,
int i;
if (size % id_size || size < id_size) {
+ if (cross_build != 0)
+ return;
fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo "
"of the size of section __mod_%s_device_table=%lu.\n"
"Fix definition of struct %s_device_id "
@@ -324,19 +328,52 @@ static int do_pnp_entry(const char *filename,
return 1;
}
-/* looks like: "pnp:cCdD..." */
-static int do_pnp_card_entry(const char *filename,
- struct pnp_card_device_id *id, char *alias)
+/* looks like: "pnp:dD" for every device of the card */
+static void do_pnp_card_entries(void *symval, unsigned long size,
+ struct module *mod)
{
- int i;
+ const unsigned long id_size = sizeof(struct pnp_card_device_id);
+ const unsigned int count = (size / id_size)-1;
+ const struct pnp_card_device_id *cards = symval;
+ unsigned int i;
- sprintf(alias, "pnp:c%s", id->id);
- for (i = 0; i < PNP_MAX_DEVICES; i++) {
- if (! *id->devs[i].id)
- break;
- sprintf(alias + strlen(alias), "d%s", id->devs[i].id);
+ device_id_check(mod->name, "pnp", size, id_size, symval);
+
+ for (i = 0; i < count; i++) {
+ unsigned int j;
+ const struct pnp_card_device_id *card = &cards[i];
+
+ for (j = 0; j < PNP_MAX_DEVICES; j++) {
+ const char *id = (char *)card->devs[j].id;
+ int i2, j2;
+ int dup = 0;
+
+ if (!id[0])
+ break;
+
+ /* find duplicate, already added value */
+ for (i2 = 0; i2 < i && !dup; i2++) {
+ const struct pnp_card_device_id *card2 = &cards[i2];
+
+ for (j2 = 0; j2 < PNP_MAX_DEVICES; j2++) {
+ const char *id2 = (char *)card2->devs[j2].id;
+
+ if (!id2[0])
+ break;
+
+ if (!strcmp(id, id2)) {
+ dup = 1;
+ break;
+ }
+ }
+ }
+
+ /* add an individual alias for every device entry */
+ if (!dup)
+ buf_printf(&mod->dev_table_buf,
+ "MODULE_ALIAS(\"pnp:d%s*\");\n", id);
+ }
}
- return 1;
}
/* Looks like: pcmcia:mNcNfNfnNpfnNvaNvbNvcNvdN. */
@@ -630,9 +667,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
sizeof(struct pnp_device_id), "pnp",
do_pnp_entry, mod);
else if (sym_is(symname, "__mod_pnp_card_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct pnp_card_device_id), "pnp_card",
- do_pnp_card_entry, mod);
+ do_pnp_card_entries(symval, sym->st_size, mod);
else if (sym_is(symname, "__mod_pcmcia_device_table"))
do_table(symval, sym->st_size,
sizeof(struct pcmcia_device_id), "pcmcia",
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 61742771c65..110cf243fa4 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1200,7 +1200,7 @@ static void report_sec_mismatch(const char *modname, enum mismatch mismatch,
"annotate %s with a matching annotation.\n",
from, sec2annotation(fromsec), fromsym, from_p,
to, sec2annotation(tosec), tosym, to_p,
- fromsym, tosym, fromsym);
+ tosym, fromsym, tosym);
break;
case INIT_TO_EXIT:
fprintf(stderr,
@@ -2026,7 +2026,7 @@ int main(int argc, char **argv)
int opt;
int err;
- while ((opt = getopt(argc, argv, "i:I:msSo:awM:K:")) != -1) {
+ while ((opt = getopt(argc, argv, "i:I:cmsSo:awM:K:")) != -1) {
switch (opt) {
case 'i':
kernel_read = optarg;
@@ -2035,6 +2035,9 @@ int main(int argc, char **argv)
module_read = optarg;
external_module = 1;
break;
+ case 'c':
+ cross_build = 1;
+ break;
case 'm':
modversions = 1;
break;
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
index 565c5872407..09f58e33d22 100644
--- a/scripts/mod/modpost.h
+++ b/scripts/mod/modpost.h
@@ -135,6 +135,7 @@ struct elf_info {
};
/* file2alias.c */
+extern unsigned int cross_build;
void handle_moddevtable(struct module *mod, struct elf_info *info,
Elf_Sym *sym, const char *symname);
void add_moddevtable(struct buffer *buf, struct module *mod);