diff options
author | Randy Dunlap <randy.dunlap@oracle.com> | 2008-12-19 11:49:30 -0500 |
---|---|---|
committer | Sam Ravnborg <sam@ravnborg.org> | 2008-12-19 12:27:19 -0500 |
commit | a1d94aa5560dc6b06baf30ae477115b51dc25461 (patch) | |
tree | 78ae044ebcb632f095c0b682a0941b87e3597480 | |
parent | 179efcb47d5a5dd34a45be3f0eca4bffa717c6b4 (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>
-rwxr-xr-x | scripts/kernel-doc | 67 |
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; | |||
289 | my @parameterlist; | 289 | my @parameterlist; |
290 | my %sections; | 290 | my %sections; |
291 | my @sectionlist; | 291 | my @sectionlist; |
292 | my $sectcheck; | ||
293 | my $struct_actual; | ||
292 | 294 | ||
293 | my $contents = ""; | 295 | my $contents = ""; |
294 | my $section_default = "Description"; # default section | 296 | my $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($$) { | |||
1405 | sub dump_struct($$) { | 1409 | sub 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 | ||
1516 | sub 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 | |||
1508 | sub create_parameterlist($$$) { | 1524 | sub 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 | ||
1657 | sub 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; |