aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorRandy Dunlap <randy.dunlap@oracle.com>2008-12-19 11:49:30 -0500
committerSam Ravnborg <sam@ravnborg.org>2008-12-19 12:27:19 -0500
commita1d94aa5560dc6b06baf30ae477115b51dc25461 (patch)
tree78ae044ebcb632f095c0b682a0941b87e3597480 /scripts
parent179efcb47d5a5dd34a45be3f0eca4bffa717c6b4 (diff)
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>
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/kernel-doc67
1 files changed, 66 insertions, 1 deletions
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index d27aad78e1d8..8bb83a100edb 100755
--- a/scripts/kernel-doc
+++ b/scripts/kernel-doc
@@ -289,6 +289,8 @@ my %parameterdescs;
289my @parameterlist; 289my @parameterlist;
290my %sections; 290my %sections;
291my @sectionlist; 291my @sectionlist;
292my $sectcheck;
293my $struct_actual;
292 294
293my $contents = ""; 295my $contents = "";
294my $section_default = "Description"; # default section 296my $section_default = "Description"; # default section
@@ -378,10 +380,12 @@ sub dump_section {
378# print STDERR "parameter def '$1' = '$contents'\n"; 380# print STDERR "parameter def '$1' = '$contents'\n";
379 $name = $1; 381 $name = $1;
380 $parameterdescs{$name} = $contents; 382 $parameterdescs{$name} = $contents;
383 $sectcheck = $sectcheck . $name . " ";
381 } elsif ($name eq "@\.\.\.") { 384 } elsif ($name eq "@\.\.\.") {
382# print STDERR "parameter def '...' = '$contents'\n"; 385# print STDERR "parameter def '...' = '$contents'\n";
383 $name = "..."; 386 $name = "...";
384 $parameterdescs{$name} = $contents; 387 $parameterdescs{$name} = $contents;
388 $sectcheck = $sectcheck . $name . " ";
385 } else { 389 } else {
386# print STDERR "other section '$name' = '$contents'\n"; 390# print STDERR "other section '$name' = '$contents'\n";
387 if (defined($sections{$name}) && ($sections{$name} ne "")) { 391 if (defined($sections{$name}) && ($sections{$name} ne "")) {
@@ -1405,21 +1409,25 @@ sub dump_union($$) {
1405sub dump_struct($$) { 1409sub dump_struct($$) {
1406 my $x = shift; 1410 my $x = shift;
1407 my $file = shift; 1411 my $file = shift;
1412 my $nested;
1408 1413
1409 if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) { 1414 if ($x =~/(struct|union)\s+(\w+)\s*{(.*)}/) {
1410 $declaration_name = $2; 1415 $declaration_name = $2;
1411 my $members = $3; 1416 my $members = $3;
1412 1417
1413 # ignore embedded structs or unions 1418 # ignore embedded structs or unions
1414 $members =~ s/{.*}//g; 1419 $members =~ s/({.*})//g;
1420 $nested = $1;
1415 1421
1416 # ignore members marked private: 1422 # ignore members marked private:
1417 $members =~ s/\/\*.*?private:.*?public:.*?\*\///gos; 1423 $members =~ s/\/\*.*?private:.*?public:.*?\*\///gos;
1418 $members =~ s/\/\*.*?private:.*//gos; 1424 $members =~ s/\/\*.*?private:.*//gos;
1419 # strip comments: 1425 # strip comments:
1420 $members =~ s/\/\*.*?\*\///gos; 1426 $members =~ s/\/\*.*?\*\///gos;
1427 $nested =~ s/\/\*.*?\*\///gos;
1421 1428
1422 create_parameterlist($members, ';', $file); 1429 create_parameterlist($members, ';', $file);
1430 check_sections($file, $declaration_name, "struct", $sectcheck, $struct_actual, $nested);
1423 1431
1424 output_declaration($declaration_name, 1432 output_declaration($declaration_name,
1425 'struct', 1433 'struct',
@@ -1505,6 +1513,14 @@ sub dump_typedef($$) {
1505 } 1513 }
1506} 1514}
1507 1515
1516sub save_struct_actual($) {
1517 my $actual = shift;
1518
1519 # strip all spaces from the actual param so that it looks like one string item
1520 $actual =~ s/\s*//g;
1521 $struct_actual = $struct_actual . $actual . " ";
1522}
1523
1508sub create_parameterlist($$$) { 1524sub create_parameterlist($$$) {
1509 my $args = shift; 1525 my $args = shift;
1510 my $splitter = shift; 1526 my $splitter = shift;
@@ -1537,6 +1553,7 @@ sub create_parameterlist($$$) {
1537 $param = $1; 1553 $param = $1;
1538 $type = $arg; 1554 $type = $arg;
1539 $type =~ s/([^\(]+\(\*?)\s*$param/$1/; 1555 $type =~ s/([^\(]+\(\*?)\s*$param/$1/;
1556 save_struct_actual($param);
1540 push_parameter($param, $type, $file); 1557 push_parameter($param, $type, $file);
1541 } elsif ($arg) { 1558 } elsif ($arg) {
1542 $arg =~ s/\s*:\s*/:/g; 1559 $arg =~ s/\s*:\s*/:/g;
@@ -1561,14 +1578,17 @@ sub create_parameterlist($$$) {
1561 1578
1562 foreach $param (@args) { 1579 foreach $param (@args) {
1563 if ($param =~ m/^(\*+)\s*(.*)/) { 1580 if ($param =~ m/^(\*+)\s*(.*)/) {
1581 save_struct_actual($2);
1564 push_parameter($2, "$type $1", $file); 1582 push_parameter($2, "$type $1", $file);
1565 } 1583 }
1566 elsif ($param =~ m/(.*?):(\d+)/) { 1584 elsif ($param =~ m/(.*?):(\d+)/) {
1567 if ($type ne "") { # skip unnamed bit-fields 1585 if ($type ne "") { # skip unnamed bit-fields
1586 save_struct_actual($1);
1568 push_parameter($1, "$type:$2", $file) 1587 push_parameter($1, "$type:$2", $file)
1569 } 1588 }
1570 } 1589 }
1571 else { 1590 else {
1591 save_struct_actual($param);
1572 push_parameter($param, $type, $file); 1592 push_parameter($param, $type, $file);
1573 } 1593 }
1574 } 1594 }
@@ -1634,6 +1654,46 @@ sub push_parameter($$$) {
1634 $parametertypes{$param} = $type; 1654 $parametertypes{$param} = $type;
1635} 1655}
1636 1656
1657sub check_sections($$$$$$) {
1658 my ($file, $decl_name, $decl_type, $sectcheck, $prmscheck, $nested) = @_;
1659 my @sects = split ' ', $sectcheck;
1660 my @prms = split ' ', $prmscheck;
1661 my $err;
1662 my ($px, $sx);
1663 my $prm_clean; # strip trailing "[array size]" and/or beginning "*"
1664
1665 foreach $sx (0 .. $#sects) {
1666 $err = 1;
1667 foreach $px (0 .. $#prms) {
1668 $prm_clean = $prms[$px];
1669 $prm_clean =~ s/\[.*\]//;
1670 $prm_clean =~ s/__attribute__\s*\(\([a-z,_\*\s\(\)]*\)\)//;
1671 ##$prm_clean =~ s/^\**//;
1672 if ($prm_clean eq $sects[$sx]) {
1673 $err = 0;
1674 last;
1675 }
1676 }
1677 if ($err) {
1678 if ($decl_type eq "function") {
1679 print STDERR "Warning(${file}:$.): " .
1680 "Excess function parameter " .
1681 "'$sects[$sx]' " .
1682 "description in '$decl_name'\n";
1683 ++$warnings;
1684 } else {
1685 if ($nested !~ m/\Q$sects[$sx]\E/) {
1686 print STDERR "Warning(${file}:$.): " .
1687 "Excess struct/union/enum/typedef member " .
1688 "'$sects[$sx]' " .
1689 "description in '$decl_name'\n";
1690 ++$warnings;
1691 }
1692 }
1693 }
1694 }
1695}
1696
1637## 1697##
1638# takes a function prototype and the name of the current file being 1698# takes a function prototype and the name of the current file being
1639# processed and spits out all the details stored in the global 1699# processed and spits out all the details stored in the global
@@ -1699,6 +1759,9 @@ sub dump_function($$) {
1699 return; 1759 return;
1700 } 1760 }
1701 1761
1762 my $prms = join " ", @parameterlist;
1763 check_sections($file, $declaration_name, "function", $sectcheck, $prms, "");
1764
1702 output_declaration($declaration_name, 1765 output_declaration($declaration_name,
1703 'function', 1766 'function',
1704 {'function' => $declaration_name, 1767 {'function' => $declaration_name,
@@ -1757,6 +1820,8 @@ sub reset_state {
1757 @parameterlist = (); 1820 @parameterlist = ();
1758 %sections = (); 1821 %sections = ();
1759 @sectionlist = (); 1822 @sectionlist = ();
1823 $sectcheck = "";
1824 $struct_actual = "";
1760 $prototype = ""; 1825 $prototype = "";
1761 1826
1762 $state = 0; 1827 $state = 0;