mirror of
https://github.com/torvalds/linux.git
synced 2024-12-27 05:11:48 +00:00
kernel-doc: check for extra kernel-doc notations
Add functionality to check for function parameters or structure (or union/typedef/enum) field members that are described in kernel-doc but are not part of the expected (declared) parameters or structure. These generate warnings that are called "Excess" descriptions. Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com> Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
This commit is contained in:
parent
179efcb47d
commit
a1d94aa556
@ -289,6 +289,8 @@ my %parameterdescs;
|
||||
my @parameterlist;
|
||||
my %sections;
|
||||
my @sectionlist;
|
||||
my $sectcheck;
|
||||
my $struct_actual;
|
||||
|
||||
my $contents = "";
|
||||
my $section_default = "Description"; # default section
|
||||
@ -378,10 +380,12 @@ sub dump_section {
|
||||
# print STDERR "parameter def '$1' = '$contents'\n";
|
||||
$name = $1;
|
||||
$parameterdescs{$name} = $contents;
|
||||
$sectcheck = $sectcheck . $name . " ";
|
||||
} elsif ($name eq "@\.\.\.") {
|
||||
# print STDERR "parameter def '...' = '$contents'\n";
|
||||
$name = "...";
|
||||
$parameterdescs{$name} = $contents;
|
||||
$sectcheck = $sectcheck . $name . " ";
|
||||
} else {
|
||||
# print STDERR "other section '$name' = '$contents'\n";
|
||||
if (defined($sections{$name}) && ($sections{$name} ne "")) {
|
||||
@ -1405,21 +1409,25 @@ sub dump_union($$) {
|
||||
sub dump_struct($$) {
|
||||
my $x = shift;
|
||||
my $file = shift;
|
||||
my $nested;
|
||||
|
||||
if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) {
|
||||
$declaration_name = $2;
|
||||
my $members = $3;
|
||||
|
||||
# ignore embedded structs or unions
|
||||
$members =~ s/{.*}//g;
|
||||
$members =~ s/({.*})//g;
|
||||
$nested = $1;
|
||||
|
||||
# ignore members marked private:
|
||||
$members =~ s/\/\*.*?private:.*?public:.*?\*\///gos;
|
||||
$members =~ s/\/\*.*?private:.*//gos;
|
||||
# strip comments:
|
||||
$members =~ s/\/\*.*?\*\///gos;
|
||||
$nested =~ s/\/\*.*?\*\///gos;
|
||||
|
||||
create_parameterlist($members, ';', $file);
|
||||
check_sections($file, $declaration_name, "struct", $sectcheck, $struct_actual, $nested);
|
||||
|
||||
output_declaration($declaration_name,
|
||||
'struct',
|
||||
@ -1505,6 +1513,14 @@ sub dump_typedef($$) {
|
||||
}
|
||||
}
|
||||
|
||||
sub save_struct_actual($) {
|
||||
my $actual = shift;
|
||||
|
||||
# strip all spaces from the actual param so that it looks like one string item
|
||||
$actual =~ s/\s*//g;
|
||||
$struct_actual = $struct_actual . $actual . " ";
|
||||
}
|
||||
|
||||
sub create_parameterlist($$$) {
|
||||
my $args = shift;
|
||||
my $splitter = shift;
|
||||
@ -1537,6 +1553,7 @@ sub create_parameterlist($$$) {
|
||||
$param = $1;
|
||||
$type = $arg;
|
||||
$type =~ s/([^\(]+\(\*?)\s*$param/$1/;
|
||||
save_struct_actual($param);
|
||||
push_parameter($param, $type, $file);
|
||||
} elsif ($arg) {
|
||||
$arg =~ s/\s*:\s*/:/g;
|
||||
@ -1561,14 +1578,17 @@ sub create_parameterlist($$$) {
|
||||
|
||||
foreach $param (@args) {
|
||||
if ($param =~ m/^(\*+)\s*(.*)/) {
|
||||
save_struct_actual($2);
|
||||
push_parameter($2, "$type $1", $file);
|
||||
}
|
||||
elsif ($param =~ m/(.*?):(\d+)/) {
|
||||
if ($type ne "") { # skip unnamed bit-fields
|
||||
save_struct_actual($1);
|
||||
push_parameter($1, "$type:$2", $file)
|
||||
}
|
||||
}
|
||||
else {
|
||||
save_struct_actual($param);
|
||||
push_parameter($param, $type, $file);
|
||||
}
|
||||
}
|
||||
@ -1634,6 +1654,46 @@ sub push_parameter($$$) {
|
||||
$parametertypes{$param} = $type;
|
||||
}
|
||||
|
||||
sub check_sections($$$$$$) {
|
||||
my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck, $nested) = @_;
|
||||
my @sects = split ' ', $sectcheck;
|
||||
my @prms = split ' ', $prmscheck;
|
||||
my $err;
|
||||
my ($px, $sx);
|
||||
my $prm_clean; # strip trailing "[array size]" and/or beginning "*"
|
||||
|
||||
foreach $sx (0 .. $#sects) {
|
||||
$err = 1;
|
||||
foreach $px (0 .. $#prms) {
|
||||
$prm_clean = $prms[$px];
|
||||
$prm_clean =~ s/\[.*\]//;
|
||||
$prm_clean =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//;
|
||||
##$prm_clean =~ s/^\**//;
|
||||
if ($prm_clean eq $sects[$sx]) {
|
||||
$err = 0;
|
||||
last;
|
||||
}
|
||||
}
|
||||
if ($err) {
|
||||
if ($decl_type eq "function") {
|
||||
print STDERR "Warning(${file}:$.): " .
|
||||
"Excess function parameter " .
|
||||
"'$sects[$sx]' " .
|
||||
"description in '$decl_name'\n";
|
||||
++$warnings;
|
||||
} else {
|
||||
if ($nested !~ m/\Q$sects[$sx]\E/) {
|
||||
print STDERR "Warning(${file}:$.): " .
|
||||
"Excess struct/union/enum/typedef member " .
|
||||
"'$sects[$sx]' " .
|
||||
"description in '$decl_name'\n";
|
||||
++$warnings;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
##
|
||||
# takes a function prototype and the name of the current file being
|
||||
# processed and spits out all the details stored in the global
|
||||
@ -1699,6 +1759,9 @@ sub dump_function($$) {
|
||||
return;
|
||||
}
|
||||
|
||||
my $prms = join " ", @parameterlist;
|
||||
check_sections($file, $declaration_name, "function", $sectcheck, $prms, "");
|
||||
|
||||
output_declaration($declaration_name,
|
||||
'function',
|
||||
{'function' => $declaration_name,
|
||||
@ -1757,6 +1820,8 @@ sub reset_state {
|
||||
@parameterlist = ();
|
||||
%sections = ();
|
||||
@sectionlist = ();
|
||||
$sectcheck = "";
|
||||
$struct_actual = "";
|
||||
$prototype = "";
|
||||
|
||||
$state = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user