On Thu, 02 Jun 2016, Daniel Vetter <daniel.vetter@xxxxxxxx> wrote: > Design is pretty simple: kernel-doc inserts breadcrumbs with line > numbers, and sphinx picks them up. At first I went with a sphinx > comment, but inserting those at random places seriously upsets the > parser, and must be filtered. Hence why this version now uses "#define > LINEO " since one of these ever escape into output it's pretty clear > there is a bug. > > It seems to work well, and at least the 2-3 errors where sphinx > complained about something that was not correct in kernel-doc text the > line numbers matched up perfectly. > > v2: Instead of noodling around in the parser state machine, create > a ViewList and parse it ourselves. This seems to be the recommended > way, per Jani's suggestion. > > v3: > - Split out ViewList pach. Splitting the kernel-doc changes from the > sphinx ones isn't possible, since emitting the LINENO lines wreaks > havoc with the rst formatting. We must filter them. Well, I suggested adding a parameter to kernel-doc to request the line numbers, because emitting them unconditionally is not rst. It's conceivable someone might want to consume plain rst as well. BR, Jani. > > - Improve the regex per Jani's suggestions, and compile it just once > for speed. > > - Now that LINENO lines are eaten, also add them to function parameter > descriptions. Much less content and offset than for in-line struct > member descriptions, but still nice to know which exact continuation > line upsets sphinx. > > - Simplify/clarify the line +/-1 business a bit. > > Cc: Jani Nikula <jani.nikula@xxxxxxxxx> > Cc: linux-doc@xxxxxxxxxxxxxxx > Cc: Jonathan Corbet <corbet@xxxxxxx> > Signed-off-by: Daniel Vetter <daniel.vetter@xxxxxxxx> > --- > Documentation/sphinx/kernel-doc.py | 15 ++++++++++++++- > scripts/kernel-doc | 23 +++++++++++++++++++++++ > 2 files changed, 37 insertions(+), 1 deletion(-) > > diff --git a/Documentation/sphinx/kernel-doc.py b/Documentation/sphinx/kernel-doc.py > index bd422870101e..246f49aad022 100644 > --- a/Documentation/sphinx/kernel-doc.py > +++ b/Documentation/sphinx/kernel-doc.py > @@ -30,6 +30,7 @@ > import os > import subprocess > import sys > +import re > > from docutils import nodes, statemachine > from docutils.statemachine import ViewList > @@ -93,7 +94,19 @@ class KernelDocDirective(Directive): > sys.stderr.write(err) > > lines = statemachine.string2lines(out, tab_width, convert_whitespace=True) > - result = ViewList(lines, source) > + result = ViewList() > + > + lineoffset = 0; > + line_regex = re.compile("^#define LINENO ([0-9]+)$") > + for line in lines: > + match = line_regex.search(line) > + if match: > + # sphinx counts lines from 0 > + lineoffset = int(match.group(1)) - 1 > + # we must eat our comments since the upset the markup > + else: > + result.append(line, source, lineoffset) > + lineoffset += 1 > > node = nodes.section() > node.document = self.state.document > diff --git a/scripts/kernel-doc b/scripts/kernel-doc > index 4da6f952d18b..b58264124aba 100755 > --- a/scripts/kernel-doc > +++ b/scripts/kernel-doc > @@ -411,13 +411,16 @@ my $doc_inline_end = '^\s*\*/\s*$'; > my $export_symbol = '^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*;'; > > my %parameterdescs; > +my %parameterdesc_start_lines; > my @parameterlist; > my %sections; > my @sectionlist; > +my %section_start_lines; > my $sectcheck; > my $struct_actual; > > my $contents = ""; > +my $new_start_line = 0; > > # the canonical section names. see also $doc_sect above. > my $section_default = "Description"; # default section > @@ -516,11 +519,15 @@ sub dump_section { > $name = $1; > $parameterdescs{$name} = $contents; > $sectcheck = $sectcheck . $name . " "; > + $parameterdesc_start_lines{$name} = $new_start_line; > + $new_start_line = 0; > } elsif ($name eq "@\.\.\.") { > # print STDERR "parameter def '...' = '$contents'\n"; > $name = "..."; > $parameterdescs{$name} = $contents; > $sectcheck = $sectcheck . $name . " "; > + $parameterdesc_start_lines{$name} = $new_start_line; > + $new_start_line = 0; > } else { > # print STDERR "other section '$name' = '$contents'\n"; > if (defined($sections{$name}) && ($sections{$name} ne "")) { > @@ -530,6 +537,8 @@ sub dump_section { > } else { > $sections{$name} = $contents; > push @sectionlist, $name; > + $section_start_lines{$name} = $new_start_line; > + $new_start_line = 0; > } > } > } > @@ -1775,6 +1784,7 @@ sub output_blockhead_rst(%) { > if ($output_selection != OUTPUT_INCLUDE) { > print "**$section**\n\n"; > } > + print "#define LINENO " . $section_start_lines{$section} . "\n"; > output_highlight_rst($args{'sections'}{$section}); > print "\n"; > } > @@ -1840,6 +1850,11 @@ sub output_function_rst(%) { > } else { > print "``$parameter``\n"; > } > + > + if (defined($parameterdesc_start_lines{$parameter_name})) { > + print "#define LINENO " . $parameterdesc_start_lines{$parameter_name}. "\n"; > + } > + > if (defined($args{'parameterdescs'}{$parameter_name}) && > $args{'parameterdescs'}{$parameter_name} ne $undescribed) { > output_highlight_rst($args{'parameterdescs'}{$parameter_name}); > @@ -1861,6 +1876,7 @@ sub output_section_rst(%) { > > foreach $section (@{$args{'sectionlist'}}) { > print "**$section**\n\n"; > + print "#define LINENO " . $section_start_lines{$section} . "\n"; > output_highlight_rst($args{'sections'}{$section}); > print "\n"; > } > @@ -1958,6 +1974,7 @@ sub output_struct_rst(%) { > > ($args{'parameterdescs'}{$parameter_name} ne $undescribed) || next; > $type = $args{'parametertypes'}{$parameter}; > + print "#define LINENO " . $parameterdesc_start_lines{$parameter_name}. "\n"; > print "``$type $parameter``\n"; > output_highlight_rst($args{'parameterdescs'}{$parameter_name}); > print "\n"; > @@ -2745,11 +2762,14 @@ sub process_file($) { > if (/$doc_start/o) { > $state = STATE_NAME; # next line is always the function name > $in_doc_sect = 0; > + print "#define LINENO " . $. . "\n"; > } > } 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 { > @@ -2833,6 +2853,7 @@ sub process_file($) { > $in_doc_sect = 1; > $in_purpose = 0; > $contents = $newcontents; > + $new_start_line = $.; > while ((substr($contents, 0, 1) eq " ") || > substr($contents, 0, 1) eq "\t") { > $contents = substr($contents, 1); > @@ -2866,6 +2887,7 @@ sub process_file($) { > dump_section($file, $section, xml_escape($contents)); > $section = $section_default; > $contents = ""; > + $new_start_line = $.; > } else { > $contents .= "\n"; > } > @@ -2900,6 +2922,7 @@ sub process_file($) { > 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 " ") || > substr($contents, 0, 1) eq "\t") { -- Jani Nikula, Intel Open Source Technology Center -- To unsubscribe from this list: send the line "unsubscribe linux-doc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html