diff options
Diffstat (limited to 'scripts/kernel-doc')
| -rwxr-xr-x | scripts/kernel-doc | 666 |
1 files changed, 365 insertions, 301 deletions
diff --git a/scripts/kernel-doc b/scripts/kernel-doc index dc68d76f21ab..ae3cac118a11 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | #!/usr/bin/env perl | 1 | #!/usr/bin/env perl |
| 2 | # SPDX-License-Identifier: GPL-2.0 | ||
| 2 | 3 | ||
| 3 | use warnings; | 4 | use warnings; |
| 4 | use strict; | 5 | use strict; |
| @@ -328,13 +329,15 @@ my $lineprefix=""; | |||
| 328 | use constant { | 329 | use constant { |
| 329 | STATE_NORMAL => 0, # normal code | 330 | STATE_NORMAL => 0, # normal code |
| 330 | STATE_NAME => 1, # looking for function name | 331 | STATE_NAME => 1, # looking for function name |
| 331 | STATE_FIELD => 2, # scanning field start | 332 | STATE_BODY_MAYBE => 2, # body - or maybe more description |
| 332 | STATE_PROTO => 3, # scanning prototype | 333 | STATE_BODY => 3, # the body of the comment |
| 333 | STATE_DOCBLOCK => 4, # documentation block | 334 | STATE_PROTO => 4, # scanning prototype |
| 334 | STATE_INLINE => 5, # gathering documentation outside main block | 335 | STATE_DOCBLOCK => 5, # documentation block |
| 336 | STATE_INLINE => 6, # gathering documentation outside main block | ||
| 335 | }; | 337 | }; |
| 336 | my $state; | 338 | my $state; |
| 337 | my $in_doc_sect; | 339 | my $in_doc_sect; |
| 340 | my $leading_space; | ||
| 338 | 341 | ||
| 339 | # Inline documentation state | 342 | # Inline documentation state |
| 340 | use constant { | 343 | use constant { |
| @@ -553,10 +556,9 @@ sub output_highlight { | |||
| 553 | } | 556 | } |
| 554 | if ($line eq ""){ | 557 | if ($line eq ""){ |
| 555 | if (! $output_preformatted) { | 558 | if (! $output_preformatted) { |
| 556 | print $lineprefix, local_unescape($blankline); | 559 | print $lineprefix, $blankline; |
| 557 | } | 560 | } |
| 558 | } else { | 561 | } else { |
| 559 | $line =~ s/\\\\\\/\&/g; | ||
| 560 | if ($output_mode eq "man" && substr($line, 0, 1) eq ".") { | 562 | if ($output_mode eq "man" && substr($line, 0, 1) eq ".") { |
| 561 | print "\\&$line"; | 563 | print "\\&$line"; |
| 562 | } else { | 564 | } else { |
| @@ -747,17 +749,73 @@ sub output_blockhead_rst(%) { | |||
| 747 | } | 749 | } |
| 748 | } | 750 | } |
| 749 | 751 | ||
| 750 | sub output_highlight_rst { | 752 | # |
| 751 | my $contents = join "\n",@_; | 753 | # Apply the RST highlights to a sub-block of text. |
| 752 | my $line; | 754 | # |
| 753 | 755 | sub highlight_block($) { | |
| 754 | # undo the evil effects of xml_escape() earlier | 756 | # The dohighlight kludge requires the text be called $contents |
| 755 | $contents = xml_unescape($contents); | 757 | my $contents = shift; |
| 756 | |||
| 757 | eval $dohighlight; | 758 | eval $dohighlight; |
| 758 | die $@ if $@; | 759 | die $@ if $@; |
| 760 | return $contents; | ||
| 761 | } | ||
| 759 | 762 | ||
| 760 | foreach $line (split "\n", $contents) { | 763 | # |
| 764 | # Regexes used only here. | ||
| 765 | # | ||
| 766 | my $sphinx_literal = '^[^.].*::$'; | ||
| 767 | my $sphinx_cblock = '^\.\.\ +code-block::'; | ||
| 768 | |||
| 769 | sub output_highlight_rst { | ||
| 770 | my $input = join "\n",@_; | ||
| 771 | my $output = ""; | ||
| 772 | my $line; | ||
| 773 | my $in_literal = 0; | ||
| 774 | my $litprefix; | ||
| 775 | my $block = ""; | ||
| 776 | |||
| 777 | foreach $line (split "\n",$input) { | ||
| 778 | # | ||
| 779 | # If we're in a literal block, see if we should drop out | ||
| 780 | # of it. Otherwise pass the line straight through unmunged. | ||
| 781 | # | ||
| 782 | if ($in_literal) { | ||
| 783 | if (! ($line =~ /^\s*$/)) { | ||
| 784 | # | ||
| 785 | # If this is the first non-blank line in a literal | ||
| 786 | # block we need to figure out what the proper indent is. | ||
| 787 | # | ||
| 788 | if ($litprefix eq "") { | ||
| 789 | $line =~ /^(\s*)/; | ||
| 790 | $litprefix = '^' . $1; | ||
| 791 | $output .= $line . "\n"; | ||
| 792 | } elsif (! ($line =~ /$litprefix/)) { | ||
| 793 | $in_literal = 0; | ||
| 794 | } else { | ||
| 795 | $output .= $line . "\n"; | ||
| 796 | } | ||
| 797 | } else { | ||
| 798 | $output .= $line . "\n"; | ||
| 799 | } | ||
| 800 | } | ||
| 801 | # | ||
| 802 | # Not in a literal block (or just dropped out) | ||
| 803 | # | ||
| 804 | if (! $in_literal) { | ||
| 805 | $block .= $line . "\n"; | ||
| 806 | if (($line =~ /$sphinx_literal/) || ($line =~ /$sphinx_cblock/)) { | ||
| 807 | $in_literal = 1; | ||
| 808 | $litprefix = ""; | ||
| 809 | $output .= highlight_block($block); | ||
| 810 | $block = "" | ||
| 811 | } | ||
| 812 | } | ||
| 813 | } | ||
| 814 | |||
| 815 | if ($block) { | ||
| 816 | $output .= highlight_block($block); | ||
| 817 | } | ||
| 818 | foreach $line (split "\n", $output) { | ||
| 761 | print $lineprefix . $line . "\n"; | 819 | print $lineprefix . $line . "\n"; |
| 762 | } | 820 | } |
| 763 | } | 821 | } |
| @@ -1422,8 +1480,6 @@ sub push_parameter($$$$) { | |||
| 1422 | } | 1480 | } |
| 1423 | } | 1481 | } |
| 1424 | 1482 | ||
| 1425 | $param = xml_escape($param); | ||
| 1426 | |||
| 1427 | # strip spaces from $param so that it is one continuous string | 1483 | # strip spaces from $param so that it is one continuous string |
| 1428 | # on @parameterlist; | 1484 | # on @parameterlist; |
| 1429 | # this fixes a problem where check_sections() cannot find | 1485 | # this fixes a problem where check_sections() cannot find |
| @@ -1748,47 +1804,6 @@ sub process_proto_type($$) { | |||
| 1748 | } | 1804 | } |
| 1749 | } | 1805 | } |
| 1750 | 1806 | ||
| 1751 | # xml_escape: replace <, >, and & in the text stream; | ||
| 1752 | # | ||
| 1753 | # however, formatting controls that are generated internally/locally in the | ||
| 1754 | # kernel-doc script are not escaped here; instead, they begin life like | ||
| 1755 | # $blankline_html (4 of '\' followed by a mnemonic + ':'), then these strings | ||
| 1756 | # are converted to their mnemonic-expected output, without the 4 * '\' & ':', | ||
| 1757 | # just before actual output; (this is done by local_unescape()) | ||
| 1758 | sub xml_escape($) { | ||
| 1759 | my $text = shift; | ||
| 1760 | if ($output_mode eq "man") { | ||
| 1761 | return $text; | ||
| 1762 | } | ||
| 1763 | $text =~ s/\&/\\\\\\amp;/g; | ||
| 1764 | $text =~ s/\</\\\\\\lt;/g; | ||
| 1765 | $text =~ s/\>/\\\\\\gt;/g; | ||
| 1766 | return $text; | ||
| 1767 | } | ||
| 1768 | |||
| 1769 | # xml_unescape: reverse the effects of xml_escape | ||
| 1770 | sub xml_unescape($) { | ||
| 1771 | my $text = shift; | ||
| 1772 | if ($output_mode eq "man") { | ||
| 1773 | return $text; | ||
| 1774 | } | ||
| 1775 | $text =~ s/\\\\\\amp;/\&/g; | ||
| 1776 | $text =~ s/\\\\\\lt;/</g; | ||
| 1777 | $text =~ s/\\\\\\gt;/>/g; | ||
| 1778 | return $text; | ||
| 1779 | } | ||
| 1780 | |||
| 1781 | # convert local escape strings to html | ||
| 1782 | # local escape strings look like: '\\\\menmonic:' (that's 4 backslashes) | ||
| 1783 | sub local_unescape($) { | ||
| 1784 | my $text = shift; | ||
| 1785 | if ($output_mode eq "man") { | ||
| 1786 | return $text; | ||
| 1787 | } | ||
| 1788 | $text =~ s/\\\\\\\\lt:/</g; | ||
| 1789 | $text =~ s/\\\\\\\\gt:/>/g; | ||
| 1790 | return $text; | ||
| 1791 | } | ||
| 1792 | 1807 | ||
| 1793 | sub map_filename($) { | 1808 | sub map_filename($) { |
| 1794 | my $file; | 1809 | my $file; |
| @@ -1826,15 +1841,291 @@ sub process_export_file($) { | |||
| 1826 | close(IN); | 1841 | close(IN); |
| 1827 | } | 1842 | } |
| 1828 | 1843 | ||
| 1829 | sub process_file($) { | 1844 | # |
| 1830 | my $file; | 1845 | # Parsers for the various processing states. |
| 1846 | # | ||
| 1847 | # STATE_NORMAL: looking for the /** to begin everything. | ||
| 1848 | # | ||
| 1849 | sub process_normal() { | ||
| 1850 | if (/$doc_start/o) { | ||
| 1851 | $state = STATE_NAME; # next line is always the function name | ||
| 1852 | $in_doc_sect = 0; | ||
| 1853 | $declaration_start_line = $. + 1; | ||
| 1854 | } | ||
| 1855 | } | ||
| 1856 | |||
| 1857 | # | ||
| 1858 | # STATE_NAME: Looking for the "name - description" line | ||
| 1859 | # | ||
| 1860 | sub process_name($$) { | ||
| 1861 | my $file = shift; | ||
| 1831 | my $identifier; | 1862 | my $identifier; |
| 1832 | my $func; | ||
| 1833 | my $descr; | 1863 | my $descr; |
| 1834 | my $in_purpose = 0; | 1864 | |
| 1865 | if (/$doc_block/o) { | ||
| 1866 | $state = STATE_DOCBLOCK; | ||
| 1867 | $contents = ""; | ||
| 1868 | $new_start_line = $. + 1; | ||
| 1869 | |||
| 1870 | if ( $1 eq "" ) { | ||
| 1871 | $section = $section_intro; | ||
| 1872 | } else { | ||
| 1873 | $section = $1; | ||
| 1874 | } | ||
| 1875 | } | ||
| 1876 | elsif (/$doc_decl/o) { | ||
| 1877 | $identifier = $1; | ||
| 1878 | if (/\s*([\w\s]+?)(\(\))?\s*-/) { | ||
| 1879 | $identifier = $1; | ||
| 1880 | } | ||
| 1881 | |||
| 1882 | $state = STATE_BODY; | ||
| 1883 | # if there's no @param blocks need to set up default section | ||
| 1884 | # here | ||
| 1885 | $contents = ""; | ||
| 1886 | $section = $section_default; | ||
| 1887 | $new_start_line = $. + 1; | ||
| 1888 | if (/-(.*)/) { | ||
| 1889 | # strip leading/trailing/multiple spaces | ||
| 1890 | $descr= $1; | ||
| 1891 | $descr =~ s/^\s*//; | ||
| 1892 | $descr =~ s/\s*$//; | ||
| 1893 | $descr =~ s/\s+/ /g; | ||
| 1894 | $declaration_purpose = $descr; | ||
| 1895 | $state = STATE_BODY_MAYBE; | ||
| 1896 | } else { | ||
| 1897 | $declaration_purpose = ""; | ||
| 1898 | } | ||
| 1899 | |||
| 1900 | if (($declaration_purpose eq "") && $verbose) { | ||
| 1901 | print STDERR "${file}:$.: warning: missing initial short description on line:\n"; | ||
| 1902 | print STDERR $_; | ||
| 1903 | ++$warnings; | ||
| 1904 | } | ||
| 1905 | |||
| 1906 | if ($identifier =~ m/^struct/) { | ||
| 1907 | $decl_type = 'struct'; | ||
| 1908 | } elsif ($identifier =~ m/^union/) { | ||
| 1909 | $decl_type = 'union'; | ||
| 1910 | } elsif ($identifier =~ m/^enum/) { | ||
| 1911 | $decl_type = 'enum'; | ||
| 1912 | } elsif ($identifier =~ m/^typedef/) { | ||
| 1913 | $decl_type = 'typedef'; | ||
| 1914 | } else { | ||
| 1915 | $decl_type = 'function'; | ||
| 1916 | } | ||
| 1917 | |||
| 1918 | if ($verbose) { | ||
| 1919 | print STDERR "${file}:$.: info: Scanning doc for $identifier\n"; | ||
| 1920 | } | ||
| 1921 | } else { | ||
| 1922 | print STDERR "${file}:$.: warning: Cannot understand $_ on line $.", | ||
| 1923 | " - I thought it was a doc line\n"; | ||
| 1924 | ++$warnings; | ||
| 1925 | $state = STATE_NORMAL; | ||
| 1926 | } | ||
| 1927 | } | ||
| 1928 | |||
| 1929 | |||
| 1930 | # | ||
| 1931 | # STATE_BODY and STATE_BODY_MAYBE: the bulk of a kerneldoc comment. | ||
| 1932 | # | ||
| 1933 | sub process_body($$) { | ||
| 1934 | my $file = shift; | ||
| 1935 | |||
| 1936 | if (/$doc_sect/i) { # case insensitive for supported section names | ||
| 1937 | $newsection = $1; | ||
| 1938 | $newcontents = $2; | ||
| 1939 | |||
| 1940 | # map the supported section names to the canonical names | ||
| 1941 | if ($newsection =~ m/^description$/i) { | ||
| 1942 | $newsection = $section_default; | ||
| 1943 | } elsif ($newsection =~ m/^context$/i) { | ||
| 1944 | $newsection = $section_context; | ||
| 1945 | } elsif ($newsection =~ m/^returns?$/i) { | ||
| 1946 | $newsection = $section_return; | ||
| 1947 | } elsif ($newsection =~ m/^\@return$/) { | ||
| 1948 | # special: @return is a section, not a param description | ||
| 1949 | $newsection = $section_return; | ||
| 1950 | } | ||
| 1951 | |||
| 1952 | if (($contents ne "") && ($contents ne "\n")) { | ||
| 1953 | if (!$in_doc_sect && $verbose) { | ||
| 1954 | print STDERR "${file}:$.: warning: contents before sections\n"; | ||
| 1955 | ++$warnings; | ||
| 1956 | } | ||
| 1957 | dump_section($file, $section, $contents); | ||
| 1958 | $section = $section_default; | ||
| 1959 | } | ||
| 1960 | |||
| 1961 | $in_doc_sect = 1; | ||
| 1962 | $state = STATE_BODY; | ||
| 1963 | $contents = $newcontents; | ||
| 1964 | $new_start_line = $.; | ||
| 1965 | while (substr($contents, 0, 1) eq " ") { | ||
| 1966 | $contents = substr($contents, 1); | ||
| 1967 | } | ||
| 1968 | if ($contents ne "") { | ||
| 1969 | $contents .= "\n"; | ||
| 1970 | } | ||
| 1971 | $section = $newsection; | ||
| 1972 | $leading_space = undef; | ||
| 1973 | } elsif (/$doc_end/) { | ||
| 1974 | if (($contents ne "") && ($contents ne "\n")) { | ||
| 1975 | dump_section($file, $section, $contents); | ||
| 1976 | $section = $section_default; | ||
| 1977 | $contents = ""; | ||
| 1978 | } | ||
| 1979 | # look for doc_com + <text> + doc_end: | ||
| 1980 | if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') { | ||
| 1981 | print STDERR "${file}:$.: warning: suspicious ending line: $_"; | ||
| 1982 | ++$warnings; | ||
| 1983 | } | ||
| 1984 | |||
| 1985 | $prototype = ""; | ||
| 1986 | $state = STATE_PROTO; | ||
| 1987 | $brcount = 0; | ||
| 1988 | } elsif (/$doc_content/) { | ||
| 1989 | # miguel-style comment kludge, look for blank lines after | ||
| 1990 | # @parameter line to signify start of description | ||
| 1991 | if ($1 eq "") { | ||
| 1992 | if ($section =~ m/^@/ || $section eq $section_context) { | ||
| 1993 | dump_section($file, $section, $contents); | ||
| 1994 | $section = $section_default; | ||
| 1995 | $contents = ""; | ||
| 1996 | $new_start_line = $.; | ||
| 1997 | } else { | ||
| 1998 | $contents .= "\n"; | ||
| 1999 | } | ||
| 2000 | $state = STATE_BODY; | ||
| 2001 | } elsif ($state == STATE_BODY_MAYBE) { | ||
| 2002 | # Continued declaration purpose | ||
| 2003 | chomp($declaration_purpose); | ||
| 2004 | $declaration_purpose .= " " . $1; | ||
| 2005 | $declaration_purpose =~ s/\s+/ /g; | ||
| 2006 | } else { | ||
| 2007 | my $cont = $1; | ||
| 2008 | if ($section =~ m/^@/ || $section eq $section_context) { | ||
| 2009 | if (!defined $leading_space) { | ||
| 2010 | if ($cont =~ m/^(\s+)/) { | ||
| 2011 | $leading_space = $1; | ||
| 2012 | } else { | ||
| 2013 | $leading_space = ""; | ||
| 2014 | } | ||
| 2015 | } | ||
| 2016 | $cont =~ s/^$leading_space//; | ||
| 2017 | } | ||
| 2018 | $contents .= $cont . "\n"; | ||
| 2019 | } | ||
| 2020 | } else { | ||
| 2021 | # i dont know - bad line? ignore. | ||
| 2022 | print STDERR "${file}:$.: warning: bad line: $_"; | ||
| 2023 | ++$warnings; | ||
| 2024 | } | ||
| 2025 | } | ||
| 2026 | |||
| 2027 | |||
| 2028 | # | ||
| 2029 | # STATE_PROTO: reading a function/whatever prototype. | ||
| 2030 | # | ||
| 2031 | sub process_proto($$) { | ||
| 2032 | my $file = shift; | ||
| 2033 | |||
| 2034 | if (/$doc_inline_oneline/) { | ||
| 2035 | $section = $1; | ||
| 2036 | $contents = $2; | ||
| 2037 | if ($contents ne "") { | ||
| 2038 | $contents .= "\n"; | ||
| 2039 | dump_section($file, $section, $contents); | ||
| 2040 | $section = $section_default; | ||
| 2041 | $contents = ""; | ||
| 2042 | } | ||
| 2043 | } elsif (/$doc_inline_start/) { | ||
| 2044 | $state = STATE_INLINE; | ||
| 2045 | $inline_doc_state = STATE_INLINE_NAME; | ||
| 2046 | } elsif ($decl_type eq 'function') { | ||
| 2047 | process_proto_function($_, $file); | ||
| 2048 | } else { | ||
| 2049 | process_proto_type($_, $file); | ||
| 2050 | } | ||
| 2051 | } | ||
| 2052 | |||
| 2053 | # | ||
| 2054 | # STATE_DOCBLOCK: within a DOC: block. | ||
| 2055 | # | ||
| 2056 | sub process_docblock($$) { | ||
| 2057 | my $file = shift; | ||
| 2058 | |||
| 2059 | if (/$doc_end/) { | ||
| 2060 | dump_doc_section($file, $section, $contents); | ||
| 2061 | $section = $section_default; | ||
| 2062 | $contents = ""; | ||
| 2063 | $function = ""; | ||
| 2064 | %parameterdescs = (); | ||
| 2065 | %parametertypes = (); | ||
| 2066 | @parameterlist = (); | ||
| 2067 | %sections = (); | ||
| 2068 | @sectionlist = (); | ||
| 2069 | $prototype = ""; | ||
| 2070 | $state = STATE_NORMAL; | ||
| 2071 | } elsif (/$doc_content/) { | ||
| 2072 | if ( $1 eq "" ) { | ||
| 2073 | $contents .= $blankline; | ||
| 2074 | } else { | ||
| 2075 | $contents .= $1 . "\n"; | ||
| 2076 | } | ||
| 2077 | } | ||
| 2078 | } | ||
| 2079 | |||
| 2080 | # | ||
| 2081 | # STATE_INLINE: docbook comments within a prototype. | ||
| 2082 | # | ||
| 2083 | sub process_inline($$) { | ||
| 2084 | my $file = shift; | ||
| 2085 | |||
| 2086 | # First line (state 1) needs to be a @parameter | ||
| 2087 | if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) { | ||
| 2088 | $section = $1; | ||
| 2089 | $contents = $2; | ||
| 2090 | $new_start_line = $.; | ||
| 2091 | if ($contents ne "") { | ||
| 2092 | while (substr($contents, 0, 1) eq " ") { | ||
| 2093 | $contents = substr($contents, 1); | ||
| 2094 | } | ||
| 2095 | $contents .= "\n"; | ||
| 2096 | } | ||
| 2097 | $inline_doc_state = STATE_INLINE_TEXT; | ||
| 2098 | # Documentation block end */ | ||
| 2099 | } elsif (/$doc_inline_end/) { | ||
| 2100 | if (($contents ne "") && ($contents ne "\n")) { | ||
| 2101 | dump_section($file, $section, $contents); | ||
| 2102 | $section = $section_default; | ||
| 2103 | $contents = ""; | ||
| 2104 | } | ||
| 2105 | $state = STATE_PROTO; | ||
| 2106 | $inline_doc_state = STATE_INLINE_NA; | ||
| 2107 | # Regular text | ||
| 2108 | } elsif (/$doc_content/) { | ||
| 2109 | if ($inline_doc_state == STATE_INLINE_TEXT) { | ||
| 2110 | $contents .= $1 . "\n"; | ||
| 2111 | # nuke leading blank lines | ||
| 2112 | if ($contents =~ /^\s*$/) { | ||
| 2113 | $contents = ""; | ||
| 2114 | } | ||
| 2115 | } elsif ($inline_doc_state == STATE_INLINE_NAME) { | ||
| 2116 | $inline_doc_state = STATE_INLINE_ERROR; | ||
| 2117 | print STDERR "${file}:$.: warning: "; | ||
| 2118 | print STDERR "Incorrect use of kernel-doc format: $_"; | ||
| 2119 | ++$warnings; | ||
| 2120 | } | ||
| 2121 | } | ||
| 2122 | } | ||
| 2123 | |||
| 2124 | |||
| 2125 | sub process_file($) { | ||
| 2126 | my $file; | ||
| 1835 | my $initial_section_counter = $section_counter; | 2127 | my $initial_section_counter = $section_counter; |
| 1836 | my ($orig_file) = @_; | 2128 | my ($orig_file) = @_; |
| 1837 | my $leading_space; | ||
| 1838 | 2129 | ||
| 1839 | $file = map_filename($orig_file); | 2130 | $file = map_filename($orig_file); |
| 1840 | 2131 | ||
| @@ -1853,250 +2144,23 @@ sub process_file($) { | |||
| 1853 | } | 2144 | } |
| 1854 | # Replace tabs by spaces | 2145 | # Replace tabs by spaces |
| 1855 | while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}; | 2146 | while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}; |
| 2147 | # Hand this line to the appropriate state handler | ||
| 1856 | if ($state == STATE_NORMAL) { | 2148 | if ($state == STATE_NORMAL) { |
| 1857 | if (/$doc_start/o) { | 2149 | process_normal(); |
| 1858 | $state = STATE_NAME; # next line is always the function name | 2150 | } elsif ($state == STATE_NAME) { |
| 1859 | $in_doc_sect = 0; | 2151 | process_name($file, $_); |
| 1860 | $declaration_start_line = $. + 1; | 2152 | } elsif ($state == STATE_BODY || $state == STATE_BODY_MAYBE) { |
| 1861 | } | 2153 | process_body($file, $_); |
| 1862 | } elsif ($state == STATE_NAME) {# this line is the function name (always) | ||
| 1863 | if (/$doc_block/o) { | ||
| 1864 | $state = STATE_DOCBLOCK; | ||
| 1865 | $contents = ""; | ||
| 1866 | $new_start_line = $. + 1; | ||
| 1867 | |||
| 1868 | if ( $1 eq "" ) { | ||
| 1869 | $section = $section_intro; | ||
| 1870 | } else { | ||
| 1871 | $section = $1; | ||
| 1872 | } | ||
| 1873 | } | ||
| 1874 | elsif (/$doc_decl/o) { | ||
| 1875 | $identifier = $1; | ||
| 1876 | if (/\s*([\w\s]+?)(\(\))?\s*-/) { | ||
| 1877 | $identifier = $1; | ||
| 1878 | } | ||
| 1879 | |||
| 1880 | $state = STATE_FIELD; | ||
| 1881 | # if there's no @param blocks need to set up default section | ||
| 1882 | # here | ||
| 1883 | $contents = ""; | ||
| 1884 | $section = $section_default; | ||
| 1885 | $new_start_line = $. + 1; | ||
| 1886 | if (/-(.*)/) { | ||
| 1887 | # strip leading/trailing/multiple spaces | ||
| 1888 | $descr= $1; | ||
| 1889 | $descr =~ s/^\s*//; | ||
| 1890 | $descr =~ s/\s*$//; | ||
| 1891 | $descr =~ s/\s+/ /g; | ||
| 1892 | $declaration_purpose = xml_escape($descr); | ||
| 1893 | $in_purpose = 1; | ||
| 1894 | } else { | ||
| 1895 | $declaration_purpose = ""; | ||
| 1896 | } | ||
| 1897 | |||
| 1898 | if (($declaration_purpose eq "") && $verbose) { | ||
| 1899 | print STDERR "${file}:$.: warning: missing initial short description on line:\n"; | ||
| 1900 | print STDERR $_; | ||
| 1901 | ++$warnings; | ||
| 1902 | } | ||
| 1903 | |||
| 1904 | if ($identifier =~ m/^struct/) { | ||
| 1905 | $decl_type = 'struct'; | ||
| 1906 | } elsif ($identifier =~ m/^union/) { | ||
| 1907 | $decl_type = 'union'; | ||
| 1908 | } elsif ($identifier =~ m/^enum/) { | ||
| 1909 | $decl_type = 'enum'; | ||
| 1910 | } elsif ($identifier =~ m/^typedef/) { | ||
| 1911 | $decl_type = 'typedef'; | ||
| 1912 | } else { | ||
| 1913 | $decl_type = 'function'; | ||
| 1914 | } | ||
| 1915 | |||
| 1916 | if ($verbose) { | ||
| 1917 | print STDERR "${file}:$.: info: Scanning doc for $identifier\n"; | ||
| 1918 | } | ||
| 1919 | } else { | ||
| 1920 | print STDERR "${file}:$.: warning: Cannot understand $_ on line $.", | ||
| 1921 | " - I thought it was a doc line\n"; | ||
| 1922 | ++$warnings; | ||
| 1923 | $state = STATE_NORMAL; | ||
| 1924 | } | ||
| 1925 | } elsif ($state == STATE_FIELD) { # look for head: lines, and include content | ||
| 1926 | if (/$doc_sect/i) { # case insensitive for supported section names | ||
| 1927 | $newsection = $1; | ||
| 1928 | $newcontents = $2; | ||
| 1929 | |||
| 1930 | # map the supported section names to the canonical names | ||
| 1931 | if ($newsection =~ m/^description$/i) { | ||
| 1932 | $newsection = $section_default; | ||
| 1933 | } elsif ($newsection =~ m/^context$/i) { | ||
| 1934 | $newsection = $section_context; | ||
| 1935 | } elsif ($newsection =~ m/^returns?$/i) { | ||
| 1936 | $newsection = $section_return; | ||
| 1937 | } elsif ($newsection =~ m/^\@return$/) { | ||
| 1938 | # special: @return is a section, not a param description | ||
| 1939 | $newsection = $section_return; | ||
| 1940 | } | ||
| 1941 | |||
| 1942 | if (($contents ne "") && ($contents ne "\n")) { | ||
| 1943 | if (!$in_doc_sect && $verbose) { | ||
| 1944 | print STDERR "${file}:$.: warning: contents before sections\n"; | ||
| 1945 | ++$warnings; | ||
| 1946 | } | ||
| 1947 | dump_section($file, $section, xml_escape($contents)); | ||
| 1948 | $section = $section_default; | ||
| 1949 | } | ||
| 1950 | |||
| 1951 | $in_doc_sect = 1; | ||
| 1952 | $in_purpose = 0; | ||
| 1953 | $contents = $newcontents; | ||
| 1954 | $new_start_line = $.; | ||
| 1955 | while (substr($contents, 0, 1) eq " ") { | ||
| 1956 | $contents = substr($contents, 1); | ||
| 1957 | } | ||
| 1958 | if ($contents ne "") { | ||
| 1959 | $contents .= "\n"; | ||
| 1960 | } | ||
| 1961 | $section = $newsection; | ||
| 1962 | $leading_space = undef; | ||
| 1963 | } elsif (/$doc_end/) { | ||
| 1964 | if (($contents ne "") && ($contents ne "\n")) { | ||
| 1965 | dump_section($file, $section, xml_escape($contents)); | ||
| 1966 | $section = $section_default; | ||
| 1967 | $contents = ""; | ||
| 1968 | } | ||
| 1969 | # look for doc_com + <text> + doc_end: | ||
| 1970 | if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') { | ||
| 1971 | print STDERR "${file}:$.: warning: suspicious ending line: $_"; | ||
| 1972 | ++$warnings; | ||
| 1973 | } | ||
| 1974 | |||
| 1975 | $prototype = ""; | ||
| 1976 | $state = STATE_PROTO; | ||
| 1977 | $brcount = 0; | ||
| 1978 | # print STDERR "end of doc comment, looking for prototype\n"; | ||
| 1979 | } elsif (/$doc_content/) { | ||
| 1980 | # miguel-style comment kludge, look for blank lines after | ||
| 1981 | # @parameter line to signify start of description | ||
| 1982 | if ($1 eq "") { | ||
| 1983 | if ($section =~ m/^@/ || $section eq $section_context) { | ||
| 1984 | dump_section($file, $section, xml_escape($contents)); | ||
| 1985 | $section = $section_default; | ||
| 1986 | $contents = ""; | ||
| 1987 | $new_start_line = $.; | ||
| 1988 | } else { | ||
| 1989 | $contents .= "\n"; | ||
| 1990 | } | ||
| 1991 | $in_purpose = 0; | ||
| 1992 | } elsif ($in_purpose == 1) { | ||
| 1993 | # Continued declaration purpose | ||
| 1994 | chomp($declaration_purpose); | ||
| 1995 | $declaration_purpose .= " " . xml_escape($1); | ||
| 1996 | $declaration_purpose =~ s/\s+/ /g; | ||
| 1997 | } else { | ||
| 1998 | my $cont = $1; | ||
| 1999 | if ($section =~ m/^@/ || $section eq $section_context) { | ||
| 2000 | if (!defined $leading_space) { | ||
| 2001 | if ($cont =~ m/^(\s+)/) { | ||
| 2002 | $leading_space = $1; | ||
| 2003 | } else { | ||
| 2004 | $leading_space = ""; | ||
| 2005 | } | ||
| 2006 | } | ||
| 2007 | |||
| 2008 | $cont =~ s/^$leading_space//; | ||
| 2009 | } | ||
| 2010 | $contents .= $cont . "\n"; | ||
| 2011 | } | ||
| 2012 | } else { | ||
| 2013 | # i dont know - bad line? ignore. | ||
| 2014 | print STDERR "${file}:$.: warning: bad line: $_"; | ||
| 2015 | ++$warnings; | ||
| 2016 | } | ||
| 2017 | } elsif ($state == STATE_INLINE) { # scanning for inline parameters | 2154 | } elsif ($state == STATE_INLINE) { # scanning for inline parameters |
| 2018 | # First line (state 1) needs to be a @parameter | 2155 | process_inline($file, $_); |
| 2019 | if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) { | 2156 | } elsif ($state == STATE_PROTO) { |
| 2020 | $section = $1; | 2157 | process_proto($file, $_); |
| 2021 | $contents = $2; | ||
| 2022 | $new_start_line = $.; | ||
| 2023 | if ($contents ne "") { | ||
| 2024 | while (substr($contents, 0, 1) eq " ") { | ||
| 2025 | $contents = substr($contents, 1); | ||
| 2026 | } | ||
| 2027 | $contents .= "\n"; | ||
| 2028 | } | ||
| 2029 | $inline_doc_state = STATE_INLINE_TEXT; | ||
| 2030 | # Documentation block end */ | ||
| 2031 | } elsif (/$doc_inline_end/) { | ||
| 2032 | if (($contents ne "") && ($contents ne "\n")) { | ||
| 2033 | dump_section($file, $section, xml_escape($contents)); | ||
| 2034 | $section = $section_default; | ||
| 2035 | $contents = ""; | ||
| 2036 | } | ||
| 2037 | $state = STATE_PROTO; | ||
| 2038 | $inline_doc_state = STATE_INLINE_NA; | ||
| 2039 | # Regular text | ||
| 2040 | } elsif (/$doc_content/) { | ||
| 2041 | if ($inline_doc_state == STATE_INLINE_TEXT) { | ||
| 2042 | $contents .= $1 . "\n"; | ||
| 2043 | # nuke leading blank lines | ||
| 2044 | if ($contents =~ /^\s*$/) { | ||
| 2045 | $contents = ""; | ||
| 2046 | } | ||
| 2047 | } elsif ($inline_doc_state == STATE_INLINE_NAME) { | ||
| 2048 | $inline_doc_state = STATE_INLINE_ERROR; | ||
| 2049 | print STDERR "${file}:$.: warning: "; | ||
| 2050 | print STDERR "Incorrect use of kernel-doc format: $_"; | ||
| 2051 | ++$warnings; | ||
| 2052 | } | ||
| 2053 | } | ||
| 2054 | } elsif ($state == STATE_PROTO) { # scanning for function '{' (end of prototype) | ||
| 2055 | if (/$doc_inline_oneline/) { | ||
| 2056 | $section = $1; | ||
| 2057 | $contents = $2; | ||
| 2058 | if ($contents ne "") { | ||
| 2059 | $contents .= "\n"; | ||
| 2060 | dump_section($file, $section, xml_escape($contents)); | ||
| 2061 | $section = $section_default; | ||
| 2062 | $contents = ""; | ||
| 2063 | } | ||
| 2064 | } elsif (/$doc_inline_start/) { | ||
| 2065 | $state = STATE_INLINE; | ||
| 2066 | $inline_doc_state = STATE_INLINE_NAME; | ||
| 2067 | } elsif ($decl_type eq 'function') { | ||
| 2068 | process_proto_function($_, $file); | ||
| 2069 | } else { | ||
| 2070 | process_proto_type($_, $file); | ||
| 2071 | } | ||
| 2072 | } elsif ($state == STATE_DOCBLOCK) { | 2158 | } elsif ($state == STATE_DOCBLOCK) { |
| 2073 | if (/$doc_end/) | 2159 | process_docblock($file, $_); |
| 2074 | { | ||
| 2075 | dump_doc_section($file, $section, xml_escape($contents)); | ||
| 2076 | $section = $section_default; | ||
| 2077 | $contents = ""; | ||
| 2078 | $function = ""; | ||
| 2079 | %parameterdescs = (); | ||
| 2080 | %parametertypes = (); | ||
| 2081 | @parameterlist = (); | ||
| 2082 | %sections = (); | ||
| 2083 | @sectionlist = (); | ||
| 2084 | $prototype = ""; | ||
| 2085 | $state = STATE_NORMAL; | ||
| 2086 | } | ||
| 2087 | elsif (/$doc_content/) | ||
| 2088 | { | ||
| 2089 | if ( $1 eq "" ) | ||
| 2090 | { | ||
| 2091 | $contents .= $blankline; | ||
| 2092 | } | ||
| 2093 | else | ||
| 2094 | { | ||
| 2095 | $contents .= $1 . "\n"; | ||
| 2096 | } | ||
| 2097 | } | ||
| 2098 | } | 2160 | } |
| 2099 | } | 2161 | } |
| 2162 | |||
| 2163 | # Make sure we got something interesting. | ||
| 2100 | if ($initial_section_counter == $section_counter) { | 2164 | if ($initial_section_counter == $section_counter) { |
| 2101 | if ($output_mode ne "none") { | 2165 | if ($output_mode ne "none") { |
| 2102 | print STDERR "${file}:1: warning: no structured comments found\n"; | 2166 | print STDERR "${file}:1: warning: no structured comments found\n"; |
