Kernel-doc currently expects that the kernel-doc markup to come just before the function/enum/struct/union/typedef prototype. Yet, if it find things like: /** * refcount_add - add a value to a refcount * @i: the value to add to the refcount * @r: the refcount */ static inline void __refcount_add(int i, refcount_t *r, int *oldp); static inline void refcount_add(int i, refcount_t *r); Kernel-doc will do the wrong thing: foobar.h:6: warning: Function parameter or member 'oldp' not described in '__refcount_add' .. c:function:: void __refcount_add (int i, refcount_t *r, int *oldp) add a value to a refcount **Parameters** ``int i`` the value to add to the refcount ``refcount_t *r`` the refcount ``int *oldp`` *undescribed* Basically, it will document "__refcount_add" with the kernel-doc markup for refcount_add. If both functions have the same arguments, this won't even produce any warning! Add a logic to check if the kernel-doc identifier matches the actual name of the C function or data structure that will be documented.
Showing the changes to scripts (1 of 1 file). Show all
Unified · Split
| @@ -382,6 +382,9 @@ my $inline_doc_state; · 381 unmodified lines | ||
| 382 | 382 | # 'function', 'struct', 'union', 'enum', 'typedef' |
| 383 | 383 | my $decl_type; |
| 384 | 384 | |
| 385 | +# Name of the kernel-doc identifier for non-DOC markups | |
| 386 | +my $identifier; | |
| 387 | + | |
| 385 | 388 | my $doc_start = '^/\*\*\s*$'; # Allow whitespace at end of comment start. |
| 386 | 389 | my $doc_end = '\*/'; |
| 387 | 390 | my $doc_com = '\s*\*\s*'; |
| @@ -1203,6 +1206,11 @@ sub dump_struct($$) { · 815 unmodified lines | ||
| 1203 | 1206 | $declaration_name = $2; |
| 1204 | 1207 | my $members = $3; |
| 1205 | 1208 | |
| 1209 | + if ($identifier ne $declaration_name) { | |
| 1210 | + print STDERR "${file}:$.: warning: expecting prototype for $decl_type $identifier. Prototype was for $decl_type $declaration_name instead\n"; | |
| 1211 | + return; | |
| 1212 | + } | |
| 1213 | + | |
| 1206 | 1214 | # ignore members marked private: |
| 1207 | 1215 | $members =~ s/\/\*\s*private:.*?\/\*\s*public:.*?\*\///gosi; |
| 1208 | 1216 | $members =~ s/\/\*\s*private:.*//gosi; |
| @@ -1391,6 +1399,11 @@ sub dump_enum($$) { · 182 unmodified lines | ||
| 1391 | 1399 | } |
| 1392 | 1400 | |
| 1393 | 1401 | if ($members) { |
| 1402 | + if ($identifier ne $declaration_name) { | |
| 1403 | + print STDERR "${file}:$.: warning: expecting prototype for enum $identifier. Prototype was for enum $declaration_name instead\n"; | |
| 1404 | + return; | |
| 1405 | + } | |
| 1406 | + | |
| 1394 | 1407 | my %_members; |
| 1395 | 1408 | |
| 1396 | 1409 | $members =~ s/\s+$//; |
| @@ -1451,6 +1464,11 @@ sub dump_typedef($$) { · 54 unmodified lines | ||
| 1451 | 1464 | my $args = $3; |
| 1452 | 1465 | $return_type =~ s/^\s+//; |
| 1453 | 1466 | |
| 1467 | + if ($identifier ne $declaration_name) { | |
| 1468 | + print STDERR "${file}:$.: warning: expecting prototype for typedef $identifier. Prototype was for typedef $declaration_name instead\n"; | |
| 1469 | + return; | |
| 1470 | + } | |
| 1471 | + | |
| 1454 | 1472 | create_parameterlist($args, ',', $file, $declaration_name); |
| 1455 | 1473 | |
| 1456 | 1474 | output_declaration($declaration_name, |
| @@ -1477,6 +1495,11 @@ sub dump_typedef($$) { · 20 unmodified lines | ||
| 1477 | 1495 | if ($x =~ /typedef.*\s+(\w+)\s*;/) { |
| 1478 | 1496 | $declaration_name = $1; |
| 1479 | 1497 | |
| 1498 | + if ($identifier ne $declaration_name) { | |
| 1499 | + print STDERR "${file}:$.: warning: expecting prototype for typedef $identifier. Prototype was for typedef $declaration_name instead\n"; | |
| 1500 | + return; | |
| 1501 | + } | |
| 1502 | + | |
| 1480 | 1503 | output_declaration($declaration_name, |
| 1481 | 1504 | 'typedef', |
| 1482 | 1505 | {'typedef' => $declaration_name, |
| @@ -1796,6 +1819,11 @@ sub dump_function($$) { · 313 unmodified lines | ||
| 1796 | 1819 | return; |
| 1797 | 1820 | } |
| 1798 | 1821 | |
| 1822 | + if ($identifier ne $declaration_name) { | |
| 1823 | + print STDERR "${file}:$.: warning: expecting prototype for $identifier(). Prototype was for $declaration_name() instead\n"; | |
| 1824 | + return; | |
| 1825 | + } | |
| 1826 | + | |
| 1799 | 1827 | my $prms = join " ", @parameterlist; |
| 1800 | 1828 | check_sections($file, $declaration_name, "function", $sectcheck, $prms); |
| 1801 | 1829 | |
| @@ -1878,6 +1906,7 @@ sub tracepoint_munge($) { · 76 unmodified lines | ||
| 1878 | 1906 | "$prototype\n"; |
| 1879 | 1907 | } else { |
| 1880 | 1908 | $prototype = "static inline void trace_$tracepointname($tracepointargs)"; |
| 1909 | + $identifier = "trace_$identifier"; | |
| 1881 | 1910 | } |
| 1882 | 1911 | } |
| 1883 | 1912 | |
| @@ -2041,7 +2070,6 @@ sub process_normal() { · 157 unmodified lines | ||
| 2041 | 2070 | # |
| 2042 | 2071 | sub process_name($$) { |
| 2043 | 2072 | my $file = shift; |
| 2044 | − my $identifier; | |
| 2045 | 2073 | my $descr; |
| 2046 | 2074 | |
| 2047 | 2075 | if (/$doc_block/o) { |
| @@ -2054,12 +2082,19 @@ sub process_name($$) { · 6 unmodified lines | ||
| 2054 | 2082 | } else { |
| 2055 | 2083 | $section = $1; |
| 2056 | 2084 | } |
| 2057 | − } | |
| 2058 | − elsif (/$doc_decl/o) { | |
| 2085 | + } elsif (/$doc_decl/o) { | |
| 2059 | 2086 | $identifier = $1; |
| 2060 | − if (/\s*([\w\s]+?)(\(\))?\s*-/) { | |
| 2087 | + if (/\s*([\w\s]+?)(\(\))?\s*([-:].*)?$/) { | |
| 2061 | 2088 | $identifier = $1; |
| 2062 | 2089 | } |
| 2090 | + if ($identifier =~ m/^(struct|union|enum|typedef)\b\s*(\S*)/) { | |
| 2091 | + $decl_type = $1; | |
| 2092 | + $identifier = $2; | |
| 2093 | + } else { | |
| 2094 | + $decl_type = 'function'; | |
| 2095 | + $identifier =~ s/^define\s+//; | |
| 2096 | + } | |
| 2097 | + $identifier =~ s/\s+$//; | |
| 2063 | 2098 | |
| 2064 | 2099 | $state = STATE_BODY; |
| 2065 | 2100 | # if there's no @param blocks need to set up default section |
| @@ -2067,7 +2102,7 @@ sub process_name($$) { · 1 unmodified line | ||
| 2067 | 2102 | $contents = ""; |
| 2068 | 2103 | $section = $section_default; |
| 2069 | 2104 | $new_start_line = $. + 1; |
| 2070 | − if (/-(.*)/) { | |
| 2105 | + if (/[-:](.*)/) { | |
| 2071 | 2106 | # strip leading/trailing/multiple spaces |
| 2072 | 2107 | $descr= $1; |
| 2073 | 2108 | $descr =~ s/^\s*//; |
| @@ -2085,20 +2120,15 @@ sub process_name($$) { · 11 unmodified lines | ||
| 2085 | 2120 | ++$warnings; |
| 2086 | 2121 | } |
| 2087 | 2122 | |
| 2088 | − if ($identifier =~ m/^struct\b/) { | |
| 2089 | − $decl_type = 'struct'; | |
| 2090 | − } elsif ($identifier =~ m/^union\b/) { | |
| 2091 | − $decl_type = 'union'; | |
| 2092 | − } elsif ($identifier =~ m/^enum\b/) { | |
| 2093 | − $decl_type = 'enum'; | |
| 2094 | − } elsif ($identifier =~ m/^typedef\b/) { | |
| 2095 | − $decl_type = 'typedef'; | |
| 2096 | − } else { | |
| 2097 | − $decl_type = 'function'; | |
| 2123 | + if ($identifier eq "") { | |
| 2124 | + print STDERR "${file}:$.: warning: wrong kernel-doc identifier on line:\n"; | |
| 2125 | + print STDERR $_; | |
| 2126 | + ++$warnings; | |
| 2127 | + $state = STATE_NORMAL; | |
| 2098 | 2128 | } |
| 2099 | 2129 | |
| 2100 | 2130 | if ($verbose) { |
| 2101 | − print STDERR "${file}:$.: info: Scanning doc for $identifier\n"; | |
| 2131 | + print STDERR "${file}:$.: info: Scanning doc for $decl_type $identifier\n"; | |
| 2102 | 2132 | } |
| 2103 | 2133 | } else { |
| 2104 | 2134 | print STDERR "${file}:$.: warning: Cannot understand $_ on line $.", |