From 0bba924ce99aadf8dcd316b8bf8b98902925ea8a Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Mon, 5 Feb 2018 12:40:15 -0700 Subject: docs: kernel-doc: Get rid of xml_escape() and friends XML escaping is a worry that came with DocBook, which we no longer have any dealings with. So get rid of the useless xml_escape()/xml_unescape() functions. No change to the generated output. Reviewed-by: Jani Nikula Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 65 ++++++++---------------------------------------------- 1 file changed, 9 insertions(+), 56 deletions(-) (limited to 'scripts/kernel-doc') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index fee8952037b1..5aa4ce211fc6 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -553,10 +553,9 @@ sub output_highlight { } if ($line eq ""){ if (! $output_preformatted) { - print $lineprefix, local_unescape($blankline); + print $lineprefix, $blankline; } } else { - $line =~ s/\\\\\\/\&/g; if ($output_mode eq "man" && substr($line, 0, 1) eq ".") { print "\\&$line"; } else { @@ -751,9 +750,6 @@ sub output_highlight_rst { my $contents = join "\n",@_; my $line; - # undo the evil effects of xml_escape() earlier - $contents = xml_unescape($contents); - eval $dohighlight; die $@ if $@; @@ -1422,8 +1418,6 @@ sub push_parameter($$$$) { } } - $param = xml_escape($param); - # strip spaces from $param so that it is one continuous string # on @parameterlist; # this fixes a problem where check_sections() cannot find @@ -1748,47 +1742,6 @@ sub process_proto_type($$) { } } -# xml_escape: replace <, >, and & in the text stream; -# -# however, formatting controls that are generated internally/locally in the -# kernel-doc script are not escaped here; instead, they begin life like -# $blankline_html (4 of '\' followed by a mnemonic + ':'), then these strings -# are converted to their mnemonic-expected output, without the 4 * '\' & ':', -# just before actual output; (this is done by local_unescape()) -sub xml_escape($) { - my $text = shift; - if ($output_mode eq "man") { - return $text; - } - $text =~ s/\&/\\\\\\amp;/g; - $text =~ s/\/\\\\\\gt;/g; - return $text; -} - -# xml_unescape: reverse the effects of xml_escape -sub xml_unescape($) { - my $text = shift; - if ($output_mode eq "man") { - return $text; - } - $text =~ s/\\\\\\amp;/\&/g; - $text =~ s/\\\\\\lt;//g; - return $text; -} - -# convert local escape strings to html -# local escape strings look like: '\\\\menmonic:' (that's 4 backslashes) -sub local_unescape($) { - my $text = shift; - if ($output_mode eq "man") { - return $text; - } - $text =~ s/\\\\\\\\lt://g; - return $text; -} sub map_filename($) { my $file; @@ -1889,7 +1842,7 @@ sub process_file($) { $descr =~ s/^\s*//; $descr =~ s/\s*$//; $descr =~ s/\s+/ /g; - $declaration_purpose = xml_escape($descr); + $declaration_purpose = $descr; $in_purpose = 1; } else { $declaration_purpose = ""; @@ -1944,7 +1897,7 @@ sub process_file($) { print STDERR "${file}:$.: warning: contents before sections\n"; ++$warnings; } - dump_section($file, $section, xml_escape($contents)); + dump_section($file, $section, $contents); $section = $section_default; } @@ -1962,7 +1915,7 @@ sub process_file($) { $leading_space = undef; } elsif (/$doc_end/) { if (($contents ne "") && ($contents ne "\n")) { - dump_section($file, $section, xml_escape($contents)); + dump_section($file, $section, $contents); $section = $section_default; $contents = ""; } @@ -1981,7 +1934,7 @@ sub process_file($) { # @parameter line to signify start of description if ($1 eq "") { if ($section =~ m/^@/ || $section eq $section_context) { - dump_section($file, $section, xml_escape($contents)); + dump_section($file, $section, $contents); $section = $section_default; $contents = ""; $new_start_line = $.; @@ -1992,7 +1945,7 @@ sub process_file($) { } elsif ($in_purpose == 1) { # Continued declaration purpose chomp($declaration_purpose); - $declaration_purpose .= " " . xml_escape($1); + $declaration_purpose .= " " . $1; $declaration_purpose =~ s/\s+/ /g; } else { my $cont = $1; @@ -2030,7 +1983,7 @@ sub process_file($) { # Documentation block end */ } elsif (/$doc_inline_end/) { if (($contents ne "") && ($contents ne "\n")) { - dump_section($file, $section, xml_escape($contents)); + dump_section($file, $section, $contents); $section = $section_default; $contents = ""; } @@ -2057,7 +2010,7 @@ sub process_file($) { $contents = $2; if ($contents ne "") { $contents .= "\n"; - dump_section($file, $section, xml_escape($contents)); + dump_section($file, $section, $contents); $section = $section_default; $contents = ""; } @@ -2072,7 +2025,7 @@ sub process_file($) { } elsif ($state == STATE_DOCBLOCK) { if (/$doc_end/) { - dump_doc_section($file, $section, xml_escape($contents)); + dump_doc_section($file, $section, $contents); $section = $section_default; $contents = ""; $function = ""; -- cgit v1.2.3-59-g8ed1b From 17b787171e693778eb9246978ad6116e52fa692c Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Mon, 5 Feb 2018 13:56:45 -0700 Subject: docs: kernel-doc: Rename and split STATE_FIELD STATE_FIELD describes a parser state that can handle any part of a kerneldoc comment body; rename it to STATE_BODY to reflect that. The $in_purpose variable was a hidden substate of STATE_FIELD; get rid of it and make a proper state (STATE_BODY_MAYBE) instead. This will make the subsequent process_file() splitup easier. Reviewed-by: Jani Nikula Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'scripts/kernel-doc') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 5aa4ce211fc6..ad30c52f91ef 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -328,10 +328,11 @@ my $lineprefix=""; use constant { STATE_NORMAL => 0, # normal code STATE_NAME => 1, # looking for function name - STATE_FIELD => 2, # scanning field start - STATE_PROTO => 3, # scanning prototype - STATE_DOCBLOCK => 4, # documentation block - STATE_INLINE => 5, # gathering documentation outside main block + STATE_BODY_MAYBE => 2, # body - or maybe more description + STATE_BODY => 3, # the body of the comment + STATE_PROTO => 4, # scanning prototype + STATE_DOCBLOCK => 5, # documentation block + STATE_INLINE => 6, # gathering documentation outside main block }; my $state; my $in_doc_sect; @@ -1784,7 +1785,6 @@ sub process_file($) { my $identifier; my $func; my $descr; - my $in_purpose = 0; my $initial_section_counter = $section_counter; my ($orig_file) = @_; my $leading_space; @@ -1830,7 +1830,7 @@ sub process_file($) { $identifier = $1; } - $state = STATE_FIELD; + $state = STATE_BODY; # if there's no @param blocks need to set up default section # here $contents = ""; @@ -1843,7 +1843,7 @@ sub process_file($) { $descr =~ s/\s*$//; $descr =~ s/\s+/ /g; $declaration_purpose = $descr; - $in_purpose = 1; + $state = STATE_BODY_MAYBE; } else { $declaration_purpose = ""; } @@ -1875,7 +1875,7 @@ sub process_file($) { ++$warnings; $state = STATE_NORMAL; } - } elsif ($state == STATE_FIELD) { # look for head: lines, and include content + } elsif ($state == STATE_BODY || $state == STATE_BODY_MAYBE) { if (/$doc_sect/i) { # case insensitive for supported section names $newsection = $1; $newcontents = $2; @@ -1902,7 +1902,7 @@ sub process_file($) { } $in_doc_sect = 1; - $in_purpose = 0; + $state = STATE_BODY; $contents = $newcontents; $new_start_line = $.; while (substr($contents, 0, 1) eq " ") { @@ -1941,8 +1941,8 @@ sub process_file($) { } else { $contents .= "\n"; } - $in_purpose = 0; - } elsif ($in_purpose == 1) { + $state = STATE_BODY; + } elsif ($state == STATE_BODY_MAYBE) { # Continued declaration purpose chomp($declaration_purpose); $declaration_purpose .= " " . $1; -- cgit v1.2.3-59-g8ed1b From 07048d13136bc068efb20e1d3e372577c2ef6906 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Mon, 5 Feb 2018 14:15:19 -0700 Subject: docs: kernel-doc: Move STATE_NORMAL processing into its own function Begin the process of splitting up the nearly 500-line process_file() function by moving STATE_NORMAL processing to a separate function. Reviewed-by: Jani Nikula Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'scripts/kernel-doc') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index ad30c52f91ef..65150b7c8472 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1780,6 +1780,21 @@ sub process_export_file($) { close(IN); } +# +# Parsers for the various processing states. +# +# STATE_NORMAL: looking for the /** to begin everything. +# +sub process_normal() { + if (/$doc_start/o) { + $state = STATE_NAME; # next line is always the function name + $in_doc_sect = 0; + $declaration_start_line = $. + 1; + } +} + + + sub process_file($) { my $file; my $identifier; @@ -1807,11 +1822,7 @@ sub process_file($) { # Replace tabs by spaces while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}; if ($state == STATE_NORMAL) { - if (/$doc_start/o) { - $state = STATE_NAME; # next line is always the function name - $in_doc_sect = 0; - $declaration_start_line = $. + 1; - } + process_normal(); } elsif ($state == STATE_NAME) {# this line is the function name (always) if (/$doc_block/o) { $state = STATE_DOCBLOCK; -- cgit v1.2.3-59-g8ed1b From 3cac2bc41d1b4c51a1f31059bf65f4dc7cfb35f5 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Mon, 5 Feb 2018 14:36:33 -0700 Subject: docs: kernel-doc: Move STATE_NAME processing into its own function Move this code out of process_file() in the name of readability and maintainability. Reviewed-by: Jani Nikula Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 137 ++++++++++++++++++++++++++++------------------------- 1 file changed, 72 insertions(+), 65 deletions(-) (limited to 'scripts/kernel-doc') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 65150b7c8472..a27c7016f72d 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1793,13 +1793,81 @@ sub process_normal() { } } +# +# STATE_NAME: Looking for the "name - description" line +# +sub process_name($$) { + my $file = shift; + my $identifier; + my $descr; + + if (/$doc_block/o) { + $state = STATE_DOCBLOCK; + $contents = ""; + $new_start_line = $. + 1; + + if ( $1 eq "" ) { + $section = $section_intro; + } else { + $section = $1; + } + } + elsif (/$doc_decl/o) { + $identifier = $1; + if (/\s*([\w\s]+?)\s*-/) { + $identifier = $1; + } + $state = STATE_BODY; + # if there's no @param blocks need to set up default section + # here + $contents = ""; + $section = $section_default; + $new_start_line = $. + 1; + if (/-(.*)/) { + # strip leading/trailing/multiple spaces + $descr= $1; + $descr =~ s/^\s*//; + $descr =~ s/\s*$//; + $descr =~ s/\s+/ /g; + $declaration_purpose = $descr; + $state = STATE_BODY_MAYBE; + } else { + $declaration_purpose = ""; + } + + if (($declaration_purpose eq "") && $verbose) { + print STDERR "${file}:$.: warning: missing initial short description on line:\n"; + print STDERR $_; + ++$warnings; + } + + if ($identifier =~ m/^struct/) { + $decl_type = 'struct'; + } elsif ($identifier =~ m/^union/) { + $decl_type = 'union'; + } elsif ($identifier =~ m/^enum/) { + $decl_type = 'enum'; + } elsif ($identifier =~ m/^typedef/) { + $decl_type = 'typedef'; + } else { + $decl_type = 'function'; + } + + if ($verbose) { + print STDERR "${file}:$.: info: Scanning doc for $identifier\n"; + } + } else { + print STDERR "${file}:$.: warning: Cannot understand $_ on line $.", + " - I thought it was a doc line\n"; + ++$warnings; + $state = STATE_NORMAL; + } +} sub process_file($) { my $file; - my $identifier; my $func; - my $descr; my $initial_section_counter = $section_counter; my ($orig_file) = @_; my $leading_space; @@ -1823,69 +1891,8 @@ sub process_file($) { while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}; if ($state == STATE_NORMAL) { process_normal(); - } elsif ($state == STATE_NAME) {# this line is the function name (always) - if (/$doc_block/o) { - $state = STATE_DOCBLOCK; - $contents = ""; - $new_start_line = $. + 1; - - if ( $1 eq "" ) { - $section = $section_intro; - } else { - $section = $1; - } - } - elsif (/$doc_decl/o) { - $identifier = $1; - if (/\s*([\w\s]+?)\s*-/) { - $identifier = $1; - } - - $state = STATE_BODY; - # if there's no @param blocks need to set up default section - # here - $contents = ""; - $section = $section_default; - $new_start_line = $. + 1; - if (/-(.*)/) { - # strip leading/trailing/multiple spaces - $descr= $1; - $descr =~ s/^\s*//; - $descr =~ s/\s*$//; - $descr =~ s/\s+/ /g; - $declaration_purpose = $descr; - $state = STATE_BODY_MAYBE; - } else { - $declaration_purpose = ""; - } - - if (($declaration_purpose eq "") && $verbose) { - print STDERR "${file}:$.: warning: missing initial short description on line:\n"; - print STDERR $_; - ++$warnings; - } - - if ($identifier =~ m/^struct/) { - $decl_type = 'struct'; - } elsif ($identifier =~ m/^union/) { - $decl_type = 'union'; - } elsif ($identifier =~ m/^enum/) { - $decl_type = 'enum'; - } elsif ($identifier =~ m/^typedef/) { - $decl_type = 'typedef'; - } else { - $decl_type = 'function'; - } - - if ($verbose) { - print STDERR "${file}:$.: info: Scanning doc for $identifier\n"; - } - } else { - print STDERR "${file}:$.: warning: Cannot understand $_ on line $.", - " - I thought it was a doc line\n"; - ++$warnings; - $state = STATE_NORMAL; - } + } elsif ($state == STATE_NAME) { + process_name($file, $_); } elsif ($state == STATE_BODY || $state == STATE_BODY_MAYBE) { if (/$doc_sect/i) { # case insensitive for supported section names $newsection = $1; -- cgit v1.2.3-59-g8ed1b From d742f24d6cce67656d93a704563c1594877a4ea0 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Mon, 5 Feb 2018 15:36:05 -0700 Subject: docs: kernel-doc: Move STATE_BODY processing to a separate function Also group the pseudo-global $leading_space variable with its peers. Reviewed-by: Jani Nikula Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 193 ++++++++++++++++++++++++++++------------------------- 1 file changed, 101 insertions(+), 92 deletions(-) (limited to 'scripts/kernel-doc') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index a27c7016f72d..a6a7bb46ea29 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -336,6 +336,7 @@ use constant { }; my $state; my $in_doc_sect; +my $leading_space; # Inline documentation state use constant { @@ -1865,12 +1866,110 @@ sub process_name($$) { } } + +# +# STATE_BODY and STATE_BODY_MAYBE: the bulk of a kerneldoc comment. +# +sub process_body($$) { + my $file = shift; + + if (/$doc_sect/i) { # case insensitive for supported section names + $newsection = $1; + $newcontents = $2; + + # map the supported section names to the canonical names + if ($newsection =~ m/^description$/i) { + $newsection = $section_default; + } elsif ($newsection =~ m/^context$/i) { + $newsection = $section_context; + } elsif ($newsection =~ m/^returns?$/i) { + $newsection = $section_return; + } elsif ($newsection =~ m/^\@return$/) { + # special: @return is a section, not a param description + $newsection = $section_return; + } + + if (($contents ne "") && ($contents ne "\n")) { + if (!$in_doc_sect && $verbose) { + print STDERR "${file}:$.: warning: contents before sections\n"; + ++$warnings; + } + dump_section($file, $section, $contents); + $section = $section_default; + } + + $in_doc_sect = 1; + $state = STATE_BODY; + $contents = $newcontents; + $new_start_line = $.; + while (substr($contents, 0, 1) eq " ") { + $contents = substr($contents, 1); + } + if ($contents ne "") { + $contents .= "\n"; + } + $section = $newsection; + $leading_space = undef; + } elsif (/$doc_end/) { + if (($contents ne "") && ($contents ne "\n")) { + dump_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + } + # look for doc_com + + doc_end: + if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') { + print STDERR "${file}:$.: warning: suspicious ending line: $_"; + ++$warnings; + } + + $prototype = ""; + $state = STATE_PROTO; + $brcount = 0; + } elsif (/$doc_content/) { + # miguel-style comment kludge, look for blank lines after + # @parameter line to signify start of description + if ($1 eq "") { + if ($section =~ m/^@/ || $section eq $section_context) { + dump_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + $new_start_line = $.; + } else { + $contents .= "\n"; + } + $state = STATE_BODY; + } elsif ($state == STATE_BODY_MAYBE) { + # Continued declaration purpose + chomp($declaration_purpose); + $declaration_purpose .= " " . $1; + $declaration_purpose =~ s/\s+/ /g; + } else { + my $cont = $1; + if ($section =~ m/^@/ || $section eq $section_context) { + if (!defined $leading_space) { + if ($cont =~ m/^(\s+)/) { + $leading_space = $1; + } else { + $leading_space = ""; + } + } + $cont =~ s/^$leading_space//; + } + $contents .= $cont . "\n"; + } + } else { + # i dont know - bad line? ignore. + print STDERR "${file}:$.: warning: bad line: $_"; + ++$warnings; + } +} + + sub process_file($) { my $file; my $func; my $initial_section_counter = $section_counter; my ($orig_file) = @_; - my $leading_space; $file = map_filename($orig_file); @@ -1894,97 +1993,7 @@ sub process_file($) { } elsif ($state == STATE_NAME) { process_name($file, $_); } elsif ($state == STATE_BODY || $state == STATE_BODY_MAYBE) { - if (/$doc_sect/i) { # case insensitive for supported section names - $newsection = $1; - $newcontents = $2; - - # map the supported section names to the canonical names - if ($newsection =~ m/^description$/i) { - $newsection = $section_default; - } elsif ($newsection =~ m/^context$/i) { - $newsection = $section_context; - } elsif ($newsection =~ m/^returns?$/i) { - $newsection = $section_return; - } elsif ($newsection =~ m/^\@return$/) { - # special: @return is a section, not a param description - $newsection = $section_return; - } - - if (($contents ne "") && ($contents ne "\n")) { - if (!$in_doc_sect && $verbose) { - print STDERR "${file}:$.: warning: contents before sections\n"; - ++$warnings; - } - dump_section($file, $section, $contents); - $section = $section_default; - } - - $in_doc_sect = 1; - $state = STATE_BODY; - $contents = $newcontents; - $new_start_line = $.; - while (substr($contents, 0, 1) eq " ") { - $contents = substr($contents, 1); - } - if ($contents ne "") { - $contents .= "\n"; - } - $section = $newsection; - $leading_space = undef; - } elsif (/$doc_end/) { - if (($contents ne "") && ($contents ne "\n")) { - dump_section($file, $section, $contents); - $section = $section_default; - $contents = ""; - } - # look for doc_com + + doc_end: - if ($_ =~ m'\s*\*\s*[a-zA-Z_0-9:\.]+\*/') { - print STDERR "${file}:$.: warning: suspicious ending line: $_"; - ++$warnings; - } - - $prototype = ""; - $state = STATE_PROTO; - $brcount = 0; -# print STDERR "end of doc comment, looking for prototype\n"; - } elsif (/$doc_content/) { - # miguel-style comment kludge, look for blank lines after - # @parameter line to signify start of description - if ($1 eq "") { - if ($section =~ m/^@/ || $section eq $section_context) { - dump_section($file, $section, $contents); - $section = $section_default; - $contents = ""; - $new_start_line = $.; - } else { - $contents .= "\n"; - } - $state = STATE_BODY; - } elsif ($state == STATE_BODY_MAYBE) { - # Continued declaration purpose - chomp($declaration_purpose); - $declaration_purpose .= " " . $1; - $declaration_purpose =~ s/\s+/ /g; - } else { - my $cont = $1; - if ($section =~ m/^@/ || $section eq $section_context) { - if (!defined $leading_space) { - if ($cont =~ m/^(\s+)/) { - $leading_space = $1; - } else { - $leading_space = ""; - } - } - - $cont =~ s/^$leading_space//; - } - $contents .= $cont . "\n"; - } - } else { - # i dont know - bad line? ignore. - print STDERR "${file}:$.: warning: bad line: $_"; - ++$warnings; - } + process_body($file, $_); } elsif ($state == STATE_INLINE) { # scanning for inline parameters # First line (state 1) needs to be a @parameter if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) { -- cgit v1.2.3-59-g8ed1b From cc794812eba917f271c6a09ac4cb1750497e404c Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Mon, 5 Feb 2018 15:46:30 -0700 Subject: docs: kernel-doc: Move STATE_PROTO processing into its own function Move the top-level prototype-processing code out of process_file(). Reviewed-by: Jani Nikula Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) (limited to 'scripts/kernel-doc') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index a6a7bb46ea29..2deddb876156 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1965,6 +1965,32 @@ sub process_body($$) { } +# +# STATE_PROTO: reading a function/whatever prototype. +# +sub process_proto($$) { + my $file = shift; + + if (/$doc_inline_oneline/) { + $section = $1; + $contents = $2; + if ($contents ne "") { + $contents .= "\n"; + dump_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + } + } elsif (/$doc_inline_start/) { + $state = STATE_INLINE; + $inline_doc_state = STATE_INLINE_NAME; + } elsif ($decl_type eq 'function') { + process_proto_function($_, $file); + } else { + process_proto_type($_, $file); + } +} + + sub process_file($) { my $file; my $func; @@ -2031,24 +2057,8 @@ sub process_file($) { ++$warnings; } } - } elsif ($state == STATE_PROTO) { # scanning for function '{' (end of prototype) - if (/$doc_inline_oneline/) { - $section = $1; - $contents = $2; - if ($contents ne "") { - $contents .= "\n"; - dump_section($file, $section, $contents); - $section = $section_default; - $contents = ""; - } - } elsif (/$doc_inline_start/) { - $state = STATE_INLINE; - $inline_doc_state = STATE_INLINE_NAME; - } elsif ($decl_type eq 'function') { - process_proto_function($_, $file); - } else { - process_proto_type($_, $file); - } + } elsif ($state == STATE_PROTO) { + process_proto($file, $_); } elsif ($state == STATE_DOCBLOCK) { if (/$doc_end/) { -- cgit v1.2.3-59-g8ed1b From c17add56ca4ee618b07ed9a21e2a29f0a90dc0ba Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Mon, 5 Feb 2018 16:11:47 -0700 Subject: docs: kernel-doc: Finish moving STATE_* code out of process_file() Move STATE_INLINE and STATE_DOCBLOCK code out of process_file(), which now actually fits on a single screen. Delete an unused variable and add a couple of comments while I'm at it. Reviewed-by: Jani Nikula Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 139 +++++++++++++++++++++++++++++------------------------ 1 file changed, 77 insertions(+), 62 deletions(-) (limited to 'scripts/kernel-doc') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 2deddb876156..fb8fbdb25036 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1990,10 +1990,80 @@ sub process_proto($$) { } } +# +# STATE_DOCBLOCK: within a DOC: block. +# +sub process_docblock($$) { + my $file = shift; + + if (/$doc_end/) { + dump_doc_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + $function = ""; + %parameterdescs = (); + %parametertypes = (); + @parameterlist = (); + %sections = (); + @sectionlist = (); + $prototype = ""; + $state = STATE_NORMAL; + } elsif (/$doc_content/) { + if ( $1 eq "" ) { + $contents .= $blankline; + } else { + $contents .= $1 . "\n"; + } + } +} + +# +# STATE_INLINE: docbook comments within a prototype. +# +sub process_inline($$) { + my $file = shift; + + # First line (state 1) needs to be a @parameter + if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) { + $section = $1; + $contents = $2; + $new_start_line = $.; + if ($contents ne "") { + while (substr($contents, 0, 1) eq " ") { + $contents = substr($contents, 1); + } + $contents .= "\n"; + } + $inline_doc_state = STATE_INLINE_TEXT; + # Documentation block end */ + } elsif (/$doc_inline_end/) { + if (($contents ne "") && ($contents ne "\n")) { + dump_section($file, $section, $contents); + $section = $section_default; + $contents = ""; + } + $state = STATE_PROTO; + $inline_doc_state = STATE_INLINE_NA; + # Regular text + } elsif (/$doc_content/) { + if ($inline_doc_state == STATE_INLINE_TEXT) { + $contents .= $1 . "\n"; + # nuke leading blank lines + if ($contents =~ /^\s*$/) { + $contents = ""; + } + } elsif ($inline_doc_state == STATE_INLINE_NAME) { + $inline_doc_state = STATE_INLINE_ERROR; + print STDERR "${file}:$.: warning: "; + print STDERR "Incorrect use of kernel-doc format: $_"; + ++$warnings; + } + } +} + sub process_file($) { my $file; - my $func; my $initial_section_counter = $section_counter; my ($orig_file) = @_; @@ -2014,6 +2084,8 @@ sub process_file($) { } # Replace tabs by spaces while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}; + + # Hand this line to the appropriate state handler if ($state == STATE_NORMAL) { process_normal(); } elsif ($state == STATE_NAME) { @@ -2021,72 +2093,15 @@ sub process_file($) { } elsif ($state == STATE_BODY || $state == STATE_BODY_MAYBE) { process_body($file, $_); } elsif ($state == STATE_INLINE) { # scanning for inline parameters - # First line (state 1) needs to be a @parameter - if ($inline_doc_state == STATE_INLINE_NAME && /$doc_inline_sect/o) { - $section = $1; - $contents = $2; - $new_start_line = $.; - if ($contents ne "") { - while (substr($contents, 0, 1) eq " ") { - $contents = substr($contents, 1); - } - $contents .= "\n"; - } - $inline_doc_state = STATE_INLINE_TEXT; - # Documentation block end */ - } elsif (/$doc_inline_end/) { - if (($contents ne "") && ($contents ne "\n")) { - dump_section($file, $section, $contents); - $section = $section_default; - $contents = ""; - } - $state = STATE_PROTO; - $inline_doc_state = STATE_INLINE_NA; - # Regular text - } elsif (/$doc_content/) { - if ($inline_doc_state == STATE_INLINE_TEXT) { - $contents .= $1 . "\n"; - # nuke leading blank lines - if ($contents =~ /^\s*$/) { - $contents = ""; - } - } elsif ($inline_doc_state == STATE_INLINE_NAME) { - $inline_doc_state = STATE_INLINE_ERROR; - print STDERR "${file}:$.: warning: "; - print STDERR "Incorrect use of kernel-doc format: $_"; - ++$warnings; - } - } + process_inline($file, $_); } elsif ($state == STATE_PROTO) { process_proto($file, $_); } elsif ($state == STATE_DOCBLOCK) { - if (/$doc_end/) - { - dump_doc_section($file, $section, $contents); - $section = $section_default; - $contents = ""; - $function = ""; - %parameterdescs = (); - %parametertypes = (); - @parameterlist = (); - %sections = (); - @sectionlist = (); - $prototype = ""; - $state = STATE_NORMAL; - } - elsif (/$doc_content/) - { - if ( $1 eq "" ) - { - $contents .= $blankline; - } - else - { - $contents .= $1 . "\n"; - } - } + process_docblock($file, $_); } } + + # Make sure we got something interesting. if ($initial_section_counter == $section_counter) { if ($output_mode ne "none") { print STDERR "${file}:1: warning: no structured comments found\n"; -- cgit v1.2.3-59-g8ed1b From af250290430e1e678eef8c5c646a1bfd6af7b68a Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Tue, 6 Feb 2018 15:58:45 -0700 Subject: docs: kernel-doc: Don't mangle literal code blocks in comments It can be useful to put code snippets into kerneldoc comments; that can be done with the "::" operator at the end of a line like this:: if (desperate) run_in_circles(); The ".. code-block::" directive can also be used to this end. kernel-doc currently fails to understand these literal blocks and applies its normal markup to them, which is then treated as literal by sphinx. The result is unsightly markup instead of a useful code snippet. Apply a hack to the output code to recognize literal blocks and avoid performing any special markup on them. It's ugly, but that means it fits in well with the rest of the script. Reviewed-by: Jani Nikula Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 5 deletions(-) (limited to 'scripts/kernel-doc') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index fb8fbdb25036..cbe864e72a2f 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -748,14 +748,73 @@ sub output_blockhead_rst(%) { } } -sub output_highlight_rst { - my $contents = join "\n",@_; - my $line; - +# +# Apply the RST highlights to a sub-block of text. +# +sub highlight_block($) { + # The dohighlight kludge requires the text be called $contents + my $contents = shift; eval $dohighlight; die $@ if $@; + return $contents; +} - foreach $line (split "\n", $contents) { +# +# Regexes used only here. +# +my $sphinx_literal = '^[^.].*::$'; +my $sphinx_cblock = '^\.\.\ +code-block::'; + +sub output_highlight_rst { + my $input = join "\n",@_; + my $output = ""; + my $line; + my $in_literal = 0; + my $litprefix; + my $block = ""; + + foreach $line (split "\n",$input) { + # + # If we're in a literal block, see if we should drop out + # of it. Otherwise pass the line straight through unmunged. + # + if ($in_literal) { + if (! ($line =~ /^\s*$/)) { + # + # If this is the first non-blank line in a literal + # block we need to figure out what the proper indent is. + # + if ($litprefix eq "") { + $line =~ /^(\s*)/; + $litprefix = '^' . $1; + $output .= $line . "\n"; + } elsif (! ($line =~ /$litprefix/)) { + $in_literal = 0; + } else { + $output .= $line . "\n"; + } + } else { + $output .= $line . "\n"; + } + } + # + # Not in a literal block (or just dropped out) + # + if (! $in_literal) { + $block .= $line . "\n"; + if (($line =~ /$sphinx_literal/) || ($line =~ /$sphinx_cblock/)) { + $in_literal = 1; + $litprefix = ""; + $output .= highlight_block($block); + $block = "" + } + } + } + + if ($block) { + $output .= highlight_block($block); + } + foreach $line (split "\n", $output) { print $lineprefix . $line . "\n"; } } -- cgit v1.2.3-59-g8ed1b From 3847637840def5d7c890acecb2a8ee8242d958dc Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Tue, 20 Feb 2018 12:24:23 -0700 Subject: docs: Add an SPDX header to kernel-doc Add the SPDX header while I'm in the neighborhood. The source itself just says "GNU General Public License", but it also refers people to the COPYING file for further information. Since COPYING says 2.0-only, that is what I have put into the header. Signed-off-by: Jonathan Corbet --- scripts/kernel-doc | 1 + 1 file changed, 1 insertion(+) (limited to 'scripts/kernel-doc') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index cbe864e72a2f..b3b992617951 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1,4 +1,5 @@ #!/usr/bin/env perl +# SPDX-License-Identifier: GPL-2.0 use warnings; use strict; -- cgit v1.2.3-59-g8ed1b