summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-10-16 15:02:21 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2020-10-16 15:02:21 -0700
commit54a4c789ca8091ab8fcd70285caeee2c5bc62997 (patch)
tree1bc7d8b12a9456505fb2cbe708f1c2aabbe69039 /scripts
parent93f3d8f54a22eaa5ae4ec269615729c4f9b1cf1e (diff)
parent3e2ac9798e13ad1f52d735ea2ea1d252cb140ae5 (diff)
Merge tag 'docs/v5.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull documentation updates from Mauro Carvalho Chehab: "A series of patches addressing warnings produced by make htmldocs. This includes: - kernel-doc markup fixes - ReST fixes - Updates at the build system in order to support newer versions of the docs build toolchain (Sphinx) After this series, the number of html build warnings should reduce significantly, and building with Sphinx 3.1 or later should now be supported (although it is still recommended to use Sphinx 2.4.4). As agreed with Jon, I should be sending you a late pull request by the end of the merge window addressing remaining issues with docs build, as there are a number of warning fixes that depends on pull requests that should be happening along the merge window. The end goal is to have a clean htmldocs build on Kernel 5.10. PS. It should be noticed that Sphinx 3.0 is not currently supported, as it lacks support for C domain namespaces. Such feature, needed in order to document uAPI system calls with Sphinx 3.x, was added only on Sphinx 3.1" * tag 'docs/v5.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (75 commits) PM / devfreq: remove a duplicated kernel-doc markup mm/doc: fix a literal block markup workqueue: fix a kernel-doc warning docs: virt: user_mode_linux_howto_v2.rst: fix a literal block markup Input: sparse-keymap: add a description for @sw rcu/tree: docs: document bkvcache new members at struct kfree_rcu_cpu nl80211: docs: add a description for s1g_cap parameter usb: docs: document altmode register/unregister functions kunit: test.h: fix a bad kernel-doc markup drivers: core: fix kernel-doc markup for dev_err_probe() docs: bio: fix a kerneldoc markup kunit: test.h: solve kernel-doc warnings block: bio: fix a warning at the kernel-doc markups docs: powerpc: syscall64-abi.rst: fix a malformed table drivers: net: hamradio: fix document location net: appletalk: Kconfig: Fix docs location dt-bindings: fix references to files converted to yaml memblock: get rid of a :c:type leftover math64.h: kernel-docs: Convert some markups into normal comments media: uAPI: buffer.rst: remove a left-over documentation ...
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/kernel-doc305
1 files changed, 223 insertions, 82 deletions
diff --git a/scripts/kernel-doc b/scripts/kernel-doc
index 724528f4b7d6..c8f6b11d5da1 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()
@@ -66,9 +73,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.
@@ -271,6 +277,8 @@ if ($#ARGV == -1) {
}
my $kernelversion;
+my ($sphinx_major, $sphinx_minor, $sphinx_patch);
+
my $dohighlight = "";
my $verbose = 0;
@@ -286,9 +294,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
@@ -313,6 +320,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);
@@ -432,10 +440,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 = ();
@@ -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();
@@ -465,6 +489,51 @@ 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 $cmd = "sphinx-build";
+ if (!findprog($cmd)) {
+ my $cmd = "sphinx-build3";
+ 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 (<IN>) {
+ if (m/^\s*sphinx-build\s+([\d]+)\.([\d\.]+)(\+\/[\da-f]+)?$/) {
+ $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\.]+)$/) {
+ $sphinx_major = $1;
+ $sphinx_minor = $2;
+ $sphinx_patch = $3;
+ last;
+ }
+ }
+ close IN;
+}
+
# get kernel version from env
sub get_kernel_version() {
my $version = 'unknown kernel version';
@@ -531,11 +600,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,
@@ -618,10 +687,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 = "";
@@ -761,6 +830,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";
}
@@ -846,16 +917,37 @@ sub output_function_rst(%) {
my ($parameter, $section);
my $oldprefix = $lineprefix;
my $start = "";
-
- 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 ``";
+ my $is_macro = 0;
+
+ 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 ``";
+ $is_macro = 1;
+ } else {
+ print ".. c:function:: ";
+ }
} else {
- print ".. c:function:: ";
+ 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);
+ print " **Typedef**: ";
+ $lineprefix = "";
+ output_highlight_rst($args{'purpose'});
+ $start = "\n\n**Syntax**\n\n ``";
+ } else {
+ print "``" if ($is_macro);
+ }
}
if ($args{'functiontype'} ne "") {
$start .= $args{'functiontype'} . " " . $args{'function'} . " (";
@@ -876,13 +968,15 @@ sub output_function_rst(%) {
# pointer-to-function
print $1 . $parameter . ") (" . $2 . ")";
} else {
- print $type . " " . $parameter;
+ print $type;
}
}
- if ($args{'typedef'}) {
- print ");``\n\n";
+ if ($is_macro) {
+ print ")``\n\n";
} else {
print ")\n\n";
+ }
+ if (!$args{'typedef'}) {
print_lineno($declaration_start_line);
$lineprefix = " ";
output_highlight_rst($args{'purpose'});
@@ -897,7 +991,7 @@ sub output_function_rst(%) {
$type = $args{'parametertypes'}{$parameter};
if ($type ne "") {
- print "``$type $parameter``\n";
+ print "``$type``\n";
} else {
print "``$parameter``\n";
}
@@ -938,9 +1032,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 +1065,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 +1086,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'});
@@ -1043,12 +1152,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(@_);
@@ -1229,6 +1340,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) {
@@ -1252,27 +1365,28 @@ 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()");
}
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 +1421,7 @@ sub dump_enum($$) {
'sections' => \%sections,
'purpose' => $declaration_purpose
});
- }
- else {
+ } else {
print STDERR "${file}:$.: error: Cannot parse enum!\n";
++$errors;
}
@@ -1403,7 +1516,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/#/,/;
@@ -1412,7 +1525,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;
@@ -1437,26 +1550,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;
@@ -1520,8 +1635,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($$$$$) {
@@ -1595,7 +1710,7 @@ sub dump_function($$) {
my $file = shift;
my $noret = 0;
- print_lineno($.);
+ print_lineno($new_start_line);
$prototype =~ s/^static +//;
$prototype =~ s/^extern +//;
@@ -1672,30 +1787,48 @@ sub dump_function($$) {
return;
}
- my $prms = join " ", @parameterlist;
- check_sections($file, $declaration_name, "function", $sectcheck, $prms);
+ 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);
- }
+ # 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 {
@@ -1873,6 +2006,7 @@ sub process_export_file($) {
while (<IN>) {
if (/$export_symbol/) {
+ next if (defined($nosymbol_table{$2}));
$function_table{$2} = 1;
}
}
@@ -1904,7 +2038,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;
@@ -1987,6 +2121,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 = "";
}
@@ -2042,6 +2177,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) {
@@ -2189,7 +2325,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;
@@ -2198,9 +2334,9 @@ sub process_file($) {
$. = 1;
$section_counter = 0;
- while (<IN>) {
+ while (<IN_FILE>) {
while (s/\\\s*$//) {
- $_ .= <IN>;
+ $_ .= <IN_FILE>;
}
# Replace tabs by spaces
while ($_ =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e) {};
@@ -2232,9 +2368,14 @@ sub process_file($) {
print STDERR "${file}:1: warning: no structured comments found\n";
}
}
+ close IN_FILE;
}
+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