From d38c8cfb057183f619dc8534030bb64b63f78043 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 1 Oct 2020 08:23:52 +0200 Subject: scripts: kernel-doc: add support for typedef enum The PHY kernel-doc markup has gained support for documenting a typedef enum. However, right now the parser was not prepared for it. So, add support for parsing it. Fixes: 4069a572d423 ("net: phy: Document core PHY structures") Signed-off-by: Mauro Carvalho Chehab --- scripts/kernel-doc | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 724528f4b7d6..adc05406c68e 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1265,14 +1265,22 @@ sub show_warnings($$) { sub dump_enum($$) { my $x = shift; my $file = shift; + my $members; + $x =~ s@/\*.*?\*/@@gos; # strip comments. # strip #define macros inside enums $x =~ s@#\s*((define|ifdef)\s+|endif)[^;]*;@@gos; - if ($x =~ /enum\s+(\w*)\s*\{(.*)\}/) { + if ($x =~ /typedef\s+enum\s*\{(.*)\}\s*(\w*)\s*;/) { + $declaration_name = $2; + $members = $1; + } elsif ($x =~ /enum\s+(\w*)\s*\{(.*)\}/) { $declaration_name = $1; - my $members = $2; + $members = $2; + } + + if ($declaration_name) { my %_members; $members =~ s/\s+$//; @@ -1307,8 +1315,7 @@ sub dump_enum($$) { 'sections' => \%sections, 'purpose' => $declaration_purpose }); - } - else { + } else { print STDERR "${file}:$.: error: Cannot parse enum!\n"; ++$errors; } -- cgit v1.2.3 From efa44475b8f5c692be4c5822a659e1a96f16dacb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 24 Sep 2020 15:30:37 +0200 Subject: scripts: kernel-doc: make it more compatible with Sphinx 3.x With Sphinx 3.x, the ".. c:type:" tag was changed to accept either: .. c:type:: typedef-like declaration .. c:type:: name Using it for other types (including functions) don't work anymore. So, there are newer tags for macro, enum, struct, union, and others, which doesn't exist on older versions. Add a check for the Sphinx version and change the produced tags accordingly. Signed-off-by: Mauro Carvalho Chehab --- scripts/kernel-doc | 71 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index adc05406c68e..096317ef2e97 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -271,6 +271,8 @@ if ($#ARGV == -1) { } my $kernelversion; +my $sphinx_major; + my $dohighlight = ""; my $verbose = 0; @@ -465,6 +467,43 @@ while ($ARGV[0] =~ m/^--?(.*)/) { # continue execution near EOF; +# The C domain dialect changed on Sphinx 3. So, we need to check the +# version in order to produce the right tags. +sub findprog($) +{ + foreach(split(/:/, $ENV{PATH})) { + return "$_/$_[0]" if(-x "$_/$_[0]"); + } +} + +sub get_sphinx_version() +{ + my $ver; + my $major = 1; + + my $cmd = "sphinx-build"; + if (!findprog($cmd)) { + my $cmd = "sphinx-build3"; + return $major if (!findprog($cmd)); + } + + open IN, "$cmd --version 2>&1 |"; + while () { + if (m/^\s*sphinx-build\s+([\d]+)\.([\d\.]+)(\+\/[\da-f]+)?$/) { + $major=$1; + last; + } + # Sphinx 1.2.x uses a different format + if (m/^\s*Sphinx.*\s+([\d]+)\.([\d\.]+)$/) { + $major=$1; + last; + } + } + close IN; + + return $major; +} + # get kernel version from env sub get_kernel_version() { my $version = 'unknown kernel version'; @@ -848,7 +887,11 @@ sub output_function_rst(%) { my $start = ""; if ($args{'typedef'}) { - print ".. c:type:: ". $args{'function'} . "\n\n"; + if ($sphinx_major < 3) { + print ".. c:type:: ". $args{'function'} . "\n\n"; + } else { + print ".. c:function:: ". $args{'function'} . "\n\n"; + } print_lineno($declaration_start_line); print " **Typedef**: "; $lineprefix = ""; @@ -938,9 +981,14 @@ sub output_enum_rst(%) { my ($parameter); my $oldprefix = $lineprefix; my $count; - my $name = "enum " . $args{'enum'}; - print "\n\n.. c:type:: " . $name . "\n\n"; + if ($sphinx_major < 3) { + my $name = "enum " . $args{'enum'}; + print "\n\n.. c:type:: " . $name . "\n\n"; + } else { + my $name = $args{'enum'}; + print "\n\n.. c:enum:: " . $name . "\n\n"; + } print_lineno($declaration_start_line); $lineprefix = " "; output_highlight_rst($args{'purpose'}); @@ -966,8 +1014,13 @@ sub output_typedef_rst(%) { my %args = %{$_[0]}; my ($parameter); my $oldprefix = $lineprefix; - my $name = "typedef " . $args{'typedef'}; + my $name; + if ($sphinx_major < 3) { + $name = "typedef " . $args{'typedef'}; + } else { + $name = $args{'typedef'}; + } print "\n\n.. c:type:: " . $name . "\n\n"; print_lineno($declaration_start_line); $lineprefix = " "; @@ -982,9 +1035,14 @@ sub output_struct_rst(%) { my %args = %{$_[0]}; my ($parameter); my $oldprefix = $lineprefix; - my $name = $args{'type'} . " " . $args{'struct'}; - print "\n\n.. c:type:: " . $name . "\n\n"; + if ($sphinx_major < 3) { + my $name = $args{'type'} . " " . $args{'struct'}; + print "\n\n.. c:type:: " . $name . "\n\n"; + } else { + my $name = $args{'struct'}; + print "\n\n.. c:struct:: " . $name . "\n\n"; + } print_lineno($declaration_start_line); $lineprefix = " "; output_highlight_rst($args{'purpose'}); @@ -2242,6 +2300,7 @@ sub process_file($) { } +$sphinx_major = get_sphinx_version(); $kernelversion = get_kernel_version(); # generate a sequence of code that will splice in highlighting information -- cgit v1.2.3 From e3ad05fe6e6ff645aa91e9a555231ff53470daba Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 25 Sep 2020 10:05:40 +0200 Subject: scripts: kernel-doc: use a less pedantic markup for funcs on Sphinx 3.x Unfortunately, Sphinx 3.x parser for c functions is too pedantic: https://github.com/sphinx-doc/sphinx/issues/8241 While it could be relaxed with some configurations, there are several corner cases that it would make it hard to maintain, and will require teaching conf.py about several macros. So, let's instead use the :c:macro notation. This will produce an output that it is not as nice as currently, but it should still be acceptable, and will provide cross-references, removing thousands of warnings when building with newer versions of Sphinx. Signed-off-by: Mauro Carvalho Chehab --- scripts/kernel-doc | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 096317ef2e97..d9783c98f33b 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -886,19 +886,29 @@ sub output_function_rst(%) { my $oldprefix = $lineprefix; my $start = ""; - if ($args{'typedef'}) { - if ($sphinx_major < 3) { + if ($sphinx_major < 3) { + if ($args{'typedef'}) { print ".. c:type:: ". $args{'function'} . "\n\n"; + print_lineno($declaration_start_line); + print " **Typedef**: "; + $lineprefix = ""; + output_highlight_rst($args{'purpose'}); + $start = "\n\n**Syntax**\n\n ``"; } else { - print ".. c:function:: ". $args{'function'} . "\n\n"; + print ".. c:function:: "; } - print_lineno($declaration_start_line); - print " **Typedef**: "; - $lineprefix = ""; - output_highlight_rst($args{'purpose'}); - $start = "\n\n**Syntax**\n\n ``"; } else { - print ".. c:function:: "; + print ".. c:macro:: ". $args{'function'} . "\n\n"; + + if ($args{'typedef'}) { + print_lineno($declaration_start_line); + print " **Typedef**: "; + $lineprefix = ""; + output_highlight_rst($args{'purpose'}); + $start = "\n\n**Syntax**\n\n ``"; + } else { + print "``"; + } } if ($args{'functiontype'} ne "") { $start .= $args{'functiontype'} . " " . $args{'function'} . " ("; @@ -925,7 +935,11 @@ sub output_function_rst(%) { if ($args{'typedef'}) { print ");``\n\n"; } else { - print ")\n\n"; + if ($sphinx_major < 3) { + print ")\n\n"; + } else { + print ")``\n"; + } print_lineno($declaration_start_line); $lineprefix = " "; output_highlight_rst($args{'purpose'}); -- cgit v1.2.3 From dbe8ba00e5adc7573b8a91855f28a383c9728991 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 28 Sep 2020 12:52:34 +0200 Subject: scripts: kernel-doc: fix troubles with line counts There's currently a bug with the way kernel-doc script counts line numbers that can be seen with: $ ./scripts/kernel-doc -rst -enable-lineno include/linux/math64.h >all && ./scripts/kernel-doc -rst -internal -enable-lineno include/linux/math64.h >int && diff -U0 int all --- int 2020-09-28 12:58:08.927486808 +0200 +++ all 2020-09-28 12:58:08.905486845 +0200 @@ -1 +1 @@ -#define LINENO 27 +#define LINENO 26 @@ -3 +3 @@ -#define LINENO 16 +#define LINENO 15 @@ -9 +9 @@ -#define LINENO 17 +#define LINENO 16 ... This is happening with perl version 5.30.3, but I'm not so sure if this is a perl bug, or if this is due to something else. In any case, fixing it is easy. Basically, when "-internal" parameter is used, the process_export_file() function opens the handle "IN". This makes the line number to be incremented, as the handler for the main open is also "IN". Fix the problem by using a different handler for the main open(). While here, add a missing close for it. Signed-off-by: Mauro Carvalho Chehab --- scripts/kernel-doc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index d9783c98f33b..bdd2ebb4ac41 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -2268,7 +2268,7 @@ sub process_file($) { $file = map_filename($orig_file); - if (!open(IN,"<$file")) { + if (!open(IN_FILE,"<$file")) { print STDERR "Error: Cannot open file $file\n"; ++$errors; return; @@ -2277,9 +2277,9 @@ sub process_file($) { $. = 1; $section_counter = 0; - while () { + while () { while (s/\\\s*$//) { - $_ .= ; + $_ .= ; } # Replace tabs by spaces while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {}; @@ -2311,6 +2311,7 @@ sub process_file($) { print STDERR "${file}:1: warning: no structured comments found\n"; } } + close IN_FILE; } -- cgit v1.2.3 From eab795ddd84ffdb1c67250062d01a81be20bb208 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 29 Sep 2020 14:23:39 +0200 Subject: scripts: kernel-doc: reimplement -nofunction argument Right now, the build system doesn't use -nofunction, as it is pretty much useless, because it doesn't consider the other output modes (extern, internal), working only with all. Also, it is limited to exclude functions. Re-implement it in order to allow excluding any symbols from the document output, no matter what mode is used. The parameter was also renamed to "-nosymbol", as it express better its meaning. Signed-off-by: Mauro Carvalho Chehab --- scripts/kernel-doc | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index bdd2ebb4ac41..6a7996c96bbb 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -66,9 +66,8 @@ Output selection (mutually exclusive): -function NAME Only output documentation for the given function(s) or DOC: section title(s). All other functions and DOC: sections are ignored. May be specified multiple times. - -nofunction NAME Do NOT output documentation for the given function(s); - only output documentation for the other functions and - DOC: sections. May be specified multiple times. + -nosymbol NAME Exclude the specified symbols from the output + documentation. May be specified multiple times. Output selection modifiers: -no-doc-sections Do not output DOC: sections. @@ -288,9 +287,8 @@ my $modulename = "Kernel API"; use constant { OUTPUT_ALL => 0, # output all symbols and doc sections OUTPUT_INCLUDE => 1, # output only specified symbols - OUTPUT_EXCLUDE => 2, # output everything except specified symbols - OUTPUT_EXPORTED => 3, # output exported symbols - OUTPUT_INTERNAL => 4, # output non-exported symbols + OUTPUT_EXPORTED => 2, # output exported symbols + OUTPUT_INTERNAL => 3, # output non-exported symbols }; my $output_selection = OUTPUT_ALL; my $show_not_found = 0; # No longer used @@ -315,6 +313,7 @@ my $man_date = ('January', 'February', 'March', 'April', 'May', 'June', # CAVEAT EMPTOR! Some of the others I localised may not want to be, which # could cause "use of undefined value" or other bugs. my ($function, %function_table, %parametertypes, $declaration_purpose); +my %nosymbol_table = (); my $declaration_start_line; my ($type, $declaration_name, $return_type); my ($newsection, $newcontents, $prototype, $brcount, %source_map); @@ -434,10 +433,9 @@ while ($ARGV[0] =~ m/^--?(.*)/) { $output_selection = OUTPUT_INCLUDE; $function = shift @ARGV; $function_table{$function} = 1; - } elsif ($cmd eq "nofunction") { # output all except specific functions - $output_selection = OUTPUT_EXCLUDE; - $function = shift @ARGV; - $function_table{$function} = 1; + } elsif ($cmd eq "nosymbol") { # Exclude specific symbols + my $symbol = shift @ARGV; + $nosymbol_table{$symbol} = 1; } elsif ($cmd eq "export") { # only exported symbols $output_selection = OUTPUT_EXPORTED; %function_table = (); @@ -570,11 +568,11 @@ sub dump_doc_section { return; } + return if (defined($nosymbol_table{$name})); + if (($output_selection == OUTPUT_ALL) || - ($output_selection == OUTPUT_INCLUDE && - defined($function_table{$name})) || - ($output_selection == OUTPUT_EXCLUDE && - !defined($function_table{$name}))) + (($output_selection == OUTPUT_INCLUDE) && + defined($function_table{$name}))) { dump_section($file, $name, $contents); output_blockhead({'sectionlist' => \@sectionlist, @@ -800,6 +798,8 @@ sub output_blockhead_rst(%) { my ($parameter, $section); foreach $section (@{$args{'sectionlist'}}) { + next if (defined($nosymbol_table{$section})); + if ($output_selection != OUTPUT_INCLUDE) { print "**$section**\n\n"; } @@ -1115,12 +1115,14 @@ sub output_declaration { my $name = shift; my $functype = shift; my $func = "output_${functype}_$output_mode"; + + return if (defined($nosymbol_table{$name})); + if (($output_selection == OUTPUT_ALL) || (($output_selection == OUTPUT_INCLUDE || $output_selection == OUTPUT_EXPORTED) && defined($function_table{$name})) || - (($output_selection == OUTPUT_EXCLUDE || - $output_selection == OUTPUT_INTERNAL) && + ($output_selection == OUTPUT_INTERNAL && !($functype eq "function" && defined($function_table{$name})))) { &$func(@_); @@ -1301,6 +1303,8 @@ sub show_warnings($$) { my $functype = shift; my $name = shift; + return 0 if (defined($nosymbol_table{$name})); + return 1 if ($output_selection == OUTPUT_ALL); if ($output_selection == OUTPUT_EXPORTED) { @@ -1324,13 +1328,6 @@ sub show_warnings($$) { return 0; } } - if ($output_selection == OUTPUT_EXCLUDE) { - if (!defined($function_table{$name})) { - return 1; - } else { - return 0; - } - } die("Please add the new output type at show_warnings()"); } @@ -1952,6 +1949,7 @@ sub process_export_file($) { while () { if (/$export_symbol/) { + next if (defined($nosymbol_table{$2})); $function_table{$2} = 1; } } -- cgit v1.2.3 From 47bcacfd2b00e3795eac3faf47eb854eb9675a4f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 30 Sep 2020 09:47:01 +0200 Subject: scripts: kernel-doc: fix typedef identification Some typedef expressions are output as normal functions. As we need to be clearer about the type with Sphinx 3.x, detect such cases. While here, fix a wrongly-indented block. Signed-off-by: Mauro Carvalho Chehab --- scripts/kernel-doc | 64 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 23 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 6a7996c96bbb..33ad3ce66f73 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1748,30 +1748,48 @@ sub dump_function($$) { return; } - my $prms = join " ", @parameterlist; - check_sections($file, $declaration_name, "function", $sectcheck, $prms); - - # This check emits a lot of warnings at the moment, because many - # functions don't have a 'Return' doc section. So until the number - # of warnings goes sufficiently down, the check is only performed in - # verbose mode. - # TODO: always perform the check. - if ($verbose && !$noret) { - check_return_section($file, $declaration_name, $return_type); - } + my $prms = join " ", @parameterlist; + check_sections($file, $declaration_name, "function", $sectcheck, $prms); + + # This check emits a lot of warnings at the moment, because many + # functions don't have a 'Return' doc section. So until the number + # of warnings goes sufficiently down, the check is only performed in + # verbose mode. + # TODO: always perform the check. + if ($verbose && !$noret) { + check_return_section($file, $declaration_name, $return_type); + } - output_declaration($declaration_name, - 'function', - {'function' => $declaration_name, - 'module' => $modulename, - 'functiontype' => $return_type, - 'parameterlist' => \@parameterlist, - 'parameterdescs' => \%parameterdescs, - 'parametertypes' => \%parametertypes, - 'sectionlist' => \@sectionlist, - 'sections' => \%sections, - 'purpose' => $declaration_purpose - }); + # The function parser can be called with a typedef parameter. + # Handle it. + if ($return_type =~ /typedef/) { + output_declaration($declaration_name, + 'function', + {'function' => $declaration_name, + 'typedef' => 1, + 'module' => $modulename, + 'functiontype' => $return_type, + 'parameterlist' => \@parameterlist, + 'parameterdescs' => \%parameterdescs, + 'parametertypes' => \%parametertypes, + 'sectionlist' => \@sectionlist, + 'sections' => \%sections, + 'purpose' => $declaration_purpose + }); + } else { + output_declaration($declaration_name, + 'function', + {'function' => $declaration_name, + 'module' => $modulename, + 'functiontype' => $return_type, + 'parameterlist' => \@parameterlist, + 'parameterdescs' => \%parameterdescs, + 'parametertypes' => \%parametertypes, + 'sectionlist' => \@sectionlist, + 'sections' => \%sections, + 'purpose' => $declaration_purpose + }); + } } sub reset_state { -- cgit v1.2.3 From ed8348e23abce79780f3b679c74a48bcdc47c947 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 30 Sep 2020 12:24:43 +0200 Subject: scripts: kernel-doc: don't mangle with parameter list While kernel-doc needs to parse parameters in order to identify its name, it shouldn't be touching the type, as parsing it is very difficult, and errors happen. One current error is when parsing this parameter: const u32 (*tab)[256] Found at ./lib/crc32.c, on this function: u32 __pure crc32_be_generic (u32 crc, unsigned char const *p, size_t len, const u32 (*tab)[256], u32 polynomial); The current logic mangles it, producing this output: const u32 ( *tab That's something that it is not recognizeable. So, instead, let's push the argument as-is, and use it when printing the function prototype and when describing each argument. Signed-off-by: Mauro Carvalho Chehab --- scripts/kernel-doc | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 33ad3ce66f73..09e3e78b9723 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -655,10 +655,10 @@ sub output_function_man(%) { $type = $args{'parametertypes'}{$parameter}; if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) { # pointer-to-function - print ".BI \"" . $parenth . $1 . "\" " . $parameter . " \") (" . $2 . ")" . $post . "\"\n"; + print ".BI \"" . $parenth . $1 . "\" " . " \") (" . $2 . ")" . $post . "\"\n"; } else { $type =~ s/([^\*])$/$1 /; - print ".BI \"" . $parenth . $type . "\" " . $parameter . " \"" . $post . "\"\n"; + print ".BI \"" . $parenth . $type . "\" " . " \"" . $post . "\"\n"; } $count++; $parenth = ""; @@ -929,7 +929,7 @@ sub output_function_rst(%) { # pointer-to-function print $1 . $parameter . ") (" . $2 . ")"; } else { - print $type . " " . $parameter; + print $type; } } if ($args{'typedef'}) { @@ -954,7 +954,7 @@ sub output_function_rst(%) { $type = $args{'parametertypes'}{$parameter}; if ($type ne "") { - print "``$type $parameter``\n"; + print "``$type``\n"; } else { print "``$parameter``\n"; } @@ -1479,7 +1479,7 @@ sub create_parameterlist($$$$) { # Treat preprocessor directive as a typeless variable just to fill # corresponding data structures "correctly". Catch it later in # output_* subs. - push_parameter($arg, "", $file); + push_parameter($arg, "", "", $file); } elsif ($arg =~ m/\(.+\)\s*\(/) { # pointer-to-function $arg =~ tr/#/,/; @@ -1488,7 +1488,7 @@ sub create_parameterlist($$$$) { $type = $arg; $type =~ s/([^\(]+\(\*?)\s*$param/$1/; save_struct_actual($param); - push_parameter($param, $type, $file, $declaration_name); + push_parameter($param, $type, $arg, $file, $declaration_name); } elsif ($arg) { $arg =~ s/\s*:\s*/:/g; $arg =~ s/\s*\[/\[/g; @@ -1513,26 +1513,28 @@ sub create_parameterlist($$$$) { foreach $param (@args) { if ($param =~ m/^(\*+)\s*(.*)/) { save_struct_actual($2); - push_parameter($2, "$type $1", $file, $declaration_name); + + push_parameter($2, "$type $1", $arg, $file, $declaration_name); } elsif ($param =~ m/(.*?):(\d+)/) { if ($type ne "") { # skip unnamed bit-fields save_struct_actual($1); - push_parameter($1, "$type:$2", $file, $declaration_name) + push_parameter($1, "$type:$2", $arg, $file, $declaration_name) } } else { save_struct_actual($param); - push_parameter($param, $type, $file, $declaration_name); + push_parameter($param, $type, $arg, $file, $declaration_name); } } } } } -sub push_parameter($$$$) { +sub push_parameter($$$$$) { my $param = shift; my $type = shift; + my $org_arg = shift; my $file = shift; my $declaration_name = shift; @@ -1596,8 +1598,8 @@ sub push_parameter($$$$) { # "[blah" in a parameter string; ###$param =~ s/\s*//g; push @parameterlist, $param; - $type =~ s/\s\s+/ /g; - $parametertypes{$param} = $type; + $org_arg =~ s/\s\s+/ /g; + $parametertypes{$param} = $org_arg; } sub check_sections($$$$$) { -- cgit v1.2.3 From 93351d4196802b3ee01074d96df47b73716984ba Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 4 Oct 2020 09:44:28 +0200 Subject: scripts: kernel-doc: allow passing desired Sphinx C domain dialect When kernel-doc is called via kerneldoc.py, there's no need to auto-detect the Sphinx version, as the Sphinx module already knows it. So, add an optional parameter to allow changing the Sphinx dialect. As kernel-doc can also be manually called, keep the auto-detection logic if the parameter was not specified. On such case, emit a warning if sphinx-build can't be found at PATH. I ended using a suggestion from Joe for using a more readable regex, instead of using a complex one with a hidden group like: m/^(\d+)\.(\d+)(?:\.?(\d+)?)/ in order to get the optional argument. Thanks-to: Joe Perches Suggested-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- Documentation/sphinx/kerneldoc.py | 5 ++++ scripts/kernel-doc | 51 +++++++++++++++++++++++++++++++++------ 2 files changed, 48 insertions(+), 8 deletions(-) (limited to 'scripts') diff --git a/Documentation/sphinx/kerneldoc.py b/Documentation/sphinx/kerneldoc.py index 4bcbd6ae01cd..1a1b12242a45 100644 --- a/Documentation/sphinx/kerneldoc.py +++ b/Documentation/sphinx/kerneldoc.py @@ -70,6 +70,11 @@ class KernelDocDirective(Directive): env = self.state.document.settings.env cmd = [env.config.kerneldoc_bin, '-rst', '-enable-lineno'] + # Pass the version string to kernel-doc, as it needs to use a different + # dialect, depending what the C domain supports for each specific + # Sphinx versions + cmd += ['-sphinx-version', sphinx.__version__] + filename = env.config.kerneldoc_srctree + '/' + self.arguments[0] export_file_patterns = [] diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 09e3e78b9723..ed32883c3221 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -56,6 +56,13 @@ Output format selection (mutually exclusive): -rst Output reStructuredText format. -none Do not output documentation, only warnings. +Output format selection modifier (affects only ReST output): + + -sphinx-version Use the ReST C domain dialect compatible with an + specific Sphinx Version. + If not specified, kernel-doc will auto-detect using + the sphinx-build version found on PATH. + Output selection (mutually exclusive): -export Only output documentation for symbols that have been exported using EXPORT_SYMBOL() or EXPORT_SYMBOL_GPL() @@ -270,7 +277,7 @@ if ($#ARGV == -1) { } my $kernelversion; -my $sphinx_major; +my ($sphinx_major, $sphinx_minor, $sphinx_patch); my $dohighlight = ""; @@ -457,6 +464,23 @@ while ($ARGV[0] =~ m/^--?(.*)/) { $enable_lineno = 1; } elsif ($cmd eq 'show-not-found') { $show_not_found = 1; # A no-op but don't fail + } elsif ($cmd eq "sphinx-version") { + my $ver_string = shift @ARGV; + if ($ver_string =~ m/^(\d+)(\.\d+)?(\.\d+)?/) { + $sphinx_major = $1; + if (defined($2)) { + $sphinx_minor = substr($2,1); + } else { + $sphinx_minor = 0; + } + if (defined($3)) { + $sphinx_patch = substr($3,1) + } else { + $sphinx_patch = 0; + } + } else { + die "Sphinx version should either major.minor or major.minor.patch format\n"; + } } else { # Unknown argument usage(); @@ -477,29 +501,37 @@ sub findprog($) sub get_sphinx_version() { my $ver; - my $major = 1; my $cmd = "sphinx-build"; if (!findprog($cmd)) { my $cmd = "sphinx-build3"; - return $major if (!findprog($cmd)); + if (!findprog($cmd)) { + $sphinx_major = 1; + $sphinx_minor = 2; + $sphinx_patch = 0; + printf STDERR "Warning: Sphinx version not found. Using default (Sphinx version %d.%d.%d)\n", + $sphinx_major, $sphinx_minor, $sphinx_patch; + return; + } } open IN, "$cmd --version 2>&1 |"; while () { if (m/^\s*sphinx-build\s+([\d]+)\.([\d\.]+)(\+\/[\da-f]+)?$/) { - $major=$1; + $sphinx_major = $1; + $sphinx_minor = $2; + $sphinx_patch = $3; last; } # Sphinx 1.2.x uses a different format if (m/^\s*Sphinx.*\s+([\d]+)\.([\d\.]+)$/) { - $major=$1; + $sphinx_major = $1; + $sphinx_minor = $2; + $sphinx_patch = $3; last; } } close IN; - - return $major; } # get kernel version from env @@ -2333,7 +2365,10 @@ sub process_file($) { } -$sphinx_major = get_sphinx_version(); +if ($output_mode eq "rst") { + get_sphinx_version() if (!$sphinx_major); +} + $kernelversion = get_kernel_version(); # generate a sequence of code that will splice in highlighting information -- cgit v1.2.3 From 5ef09c96d48b41a55121df1b57404f68d7e4e5f1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 9 Oct 2020 10:15:25 +0200 Subject: scripts: kernel-doc: fix line number handling Address several issues related to pointing to the wrong line number: 1) ensure that line numbers will always be initialized When section is the default (Description), the line number is not initializing, producing this: $ ./scripts/kernel-doc --enable-lineno ./drivers/media/v4l2-core/v4l2-mem2mem.c|less **Description** #define LINENO 0 In case of streamoff or release called on any context, 1] If the context is currently running, then abort job will be called 2] If the context is queued, then the context will be removed from the job_queue Which is not right. Ensure that the line number will always be there. After applied, the result now points to the right location: **Description** #define LINENO 410 In case of streamoff or release called on any context, 1] If the context is currently running, then abort job will be called 2] If the context is queued, then the context will be removed from the job_queue 2) The line numbers for function prototypes are always + 1, because it is taken at the line after handling the prototype. Change the logic to point to the next line after the /** */ block; 3) The "DOC:" line number should point to the same line as this markup is found, and not to the next one. Probably part of the issues were due to a but that was causing the line number offset to be incremented by one, if --export were used. Signed-off-by: Mauro Carvalho Chehab --- scripts/kernel-doc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index ed32883c3221..9496abba9538 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -1705,7 +1705,7 @@ sub dump_function($$) { my $file = shift; my $noret = 0; - print_lineno($.); + print_lineno($new_start_line); $prototype =~ s/^static +//; $prototype =~ s/^extern +//; @@ -2033,7 +2033,7 @@ sub process_name($$) { if (/$doc_block/o) { $state = STATE_DOCBLOCK; $contents = ""; - $new_start_line = $. + 1; + $new_start_line = $.; if ( $1 eq "" ) { $section = $section_intro; @@ -2116,6 +2116,7 @@ sub process_body($$) { if ($state == STATE_BODY_WITH_BLANK_LINE && /^\s*\*\s?\S/) { dump_section($file, $section, $contents); $section = $section_default; + $new_start_line = $.; $contents = ""; } @@ -2171,6 +2172,7 @@ sub process_body($$) { $prototype = ""; $state = STATE_PROTO; $brcount = 0; + $new_start_line = $. + 1; } elsif (/$doc_content/) { if ($1 eq "") { if ($section eq $section_context) { -- cgit v1.2.3 From 6e9e415854c15dbf920481eb1d245988e405bbc0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 30 Sep 2020 09:47:01 +0200 Subject: scripts: kernel-doc: try to use c:function if possible There are a few namespace clashes by using c:macro everywhere: basically, when using it, we can't have something like: .. c:struct:: pwm_capture .. c:macro:: pwm_capture So, we need to use, instead: .. c:function:: int pwm_capture (struct pwm_device * pwm, struct pwm_capture * result, unsigned long timeout) for the function declaration. The kernel-doc change was proposed by Jakob Lykke Andersen here: https://github.com/jakobandersen/linux_docs/commit/6fd2076ec001cca7466857493cd678df4dfe4a65 Although I did a different implementation. Signed-off-by: Mauro Carvalho Chehab --- scripts/kernel-doc | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'scripts') diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 9496abba9538..c8f6b11d5da1 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -917,6 +917,7 @@ sub output_function_rst(%) { my ($parameter, $section); my $oldprefix = $lineprefix; my $start = ""; + my $is_macro = 0; if ($sphinx_major < 3) { if ($args{'typedef'}) { @@ -926,11 +927,17 @@ sub output_function_rst(%) { $lineprefix = ""; output_highlight_rst($args{'purpose'}); $start = "\n\n**Syntax**\n\n ``"; + $is_macro = 1; } else { print ".. c:function:: "; } } else { - print ".. c:macro:: ". $args{'function'} . "\n\n"; + if ($args{'typedef'} || $args{'functiontype'} eq "") { + $is_macro = 1; + print ".. c:macro:: ". $args{'function'} . "\n\n"; + } else { + print ".. c:function:: "; + } if ($args{'typedef'}) { print_lineno($declaration_start_line); @@ -939,7 +946,7 @@ sub output_function_rst(%) { output_highlight_rst($args{'purpose'}); $start = "\n\n**Syntax**\n\n ``"; } else { - print "``"; + print "``" if ($is_macro); } } if ($args{'functiontype'} ne "") { @@ -964,14 +971,12 @@ sub output_function_rst(%) { print $type; } } - if ($args{'typedef'}) { - print ");``\n\n"; + if ($is_macro) { + print ")``\n\n"; } else { - if ($sphinx_major < 3) { - print ")\n\n"; - } else { - print ")``\n"; - } + print ")\n\n"; + } + if (!$args{'typedef'}) { print_lineno($declaration_start_line); $lineprefix = " "; output_highlight_rst($args{'purpose'}); -- cgit v1.2.3