doc: update Kernel documentation build system
Update the docomentation build system according to Linux v5.11-rc1. With this patch we can build the HTML documentation using either of Sphinx 2 and Sphinx 3. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Reviewed-by: Simon Glass <sjg@chromium.org> [Fix warning in b4860qds.rst about "Switch Settings"] Signed-off-by: Tom Rini <trini@konsulko.com>
This commit is contained in:
committed by
Tom Rini
parent
4afc4f37c7
commit
10a1df3cd4
@@ -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.
|
||||
@@ -81,6 +87,7 @@ Output selection modifiers:
|
||||
Other parameters:
|
||||
-v Verbose output, more warnings and other information.
|
||||
-h Print this help.
|
||||
-Werror Treat warnings as errors.
|
||||
|
||||
EOF
|
||||
print $message;
|
||||
@@ -213,7 +220,9 @@ my $type_constant = '\b``([^\`]+)``\b';
|
||||
my $type_constant2 = '\%([-_\w]+)';
|
||||
my $type_func = '(\w+)\(\)';
|
||||
my $type_param = '\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)';
|
||||
my $type_param_ref = '([\!]?)\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)';
|
||||
my $type_fp_param = '\@(\w+)\(\)'; # Special RST handling for func ptr params
|
||||
my $type_fp_param2 = '\@(\w+->\S+)\(\)'; # Special RST handling for structs with func ptr params
|
||||
my $type_env = '(\$\w+)';
|
||||
my $type_enum = '\&(enum\s*([_\w]+))';
|
||||
my $type_struct = '\&(struct\s*([_\w]+))';
|
||||
@@ -236,6 +245,7 @@ my @highlights_man = (
|
||||
[$type_typedef, "\\\\fI\$1\\\\fP"],
|
||||
[$type_union, "\\\\fI\$1\\\\fP"],
|
||||
[$type_param, "\\\\fI\$1\\\\fP"],
|
||||
[$type_param_ref, "\\\\fI\$1\$2\\\\fP"],
|
||||
[$type_member, "\\\\fI\$1\$2\$3\\\\fP"],
|
||||
[$type_fallback, "\\\\fI\$1\\\\fP"]
|
||||
);
|
||||
@@ -249,14 +259,15 @@ my @highlights_rst = (
|
||||
[$type_member_func, "\\:c\\:type\\:`\$1\$2\$3\\\\(\\\\) <\$1>`"],
|
||||
[$type_member, "\\:c\\:type\\:`\$1\$2\$3 <\$1>`"],
|
||||
[$type_fp_param, "**\$1\\\\(\\\\)**"],
|
||||
[$type_func, "\\:c\\:func\\:`\$1()`"],
|
||||
[$type_fp_param2, "**\$1\\\\(\\\\)**"],
|
||||
[$type_func, "\$1()"],
|
||||
[$type_enum, "\\:c\\:type\\:`\$1 <\$2>`"],
|
||||
[$type_struct, "\\:c\\:type\\:`\$1 <\$2>`"],
|
||||
[$type_typedef, "\\:c\\:type\\:`\$1 <\$2>`"],
|
||||
[$type_union, "\\:c\\:type\\:`\$1 <\$2>`"],
|
||||
# in rst this can refer to any type
|
||||
[$type_fallback, "\\:c\\:type\\:`\$1`"],
|
||||
[$type_param, "**\$1**"]
|
||||
[$type_param_ref, "**\$1\$2**"]
|
||||
);
|
||||
my $blankline_rst = "\n";
|
||||
|
||||
@@ -266,9 +277,12 @@ if ($#ARGV == -1) {
|
||||
}
|
||||
|
||||
my $kernelversion;
|
||||
my ($sphinx_major, $sphinx_minor, $sphinx_patch);
|
||||
|
||||
my $dohighlight = "";
|
||||
|
||||
my $verbose = 0;
|
||||
my $Werror = 0;
|
||||
my $output_mode = "rst";
|
||||
my $output_preformatted = 0;
|
||||
my $no_doc_sections = 0;
|
||||
@@ -280,12 +294,11 @@ 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;
|
||||
my $show_not_found = 0; # No longer used
|
||||
|
||||
my @export_file_list;
|
||||
|
||||
@@ -307,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);
|
||||
@@ -315,9 +329,21 @@ if (defined($ENV{'KBUILD_VERBOSE'})) {
|
||||
$verbose = "$ENV{'KBUILD_VERBOSE'}";
|
||||
}
|
||||
|
||||
if (defined($ENV{'KDOC_WERROR'})) {
|
||||
$Werror = "$ENV{'KDOC_WERROR'}";
|
||||
}
|
||||
|
||||
if (defined($ENV{'KCFLAGS'})) {
|
||||
my $kcflags = "$ENV{'KCFLAGS'}";
|
||||
|
||||
if ($kcflags =~ /Werror/) {
|
||||
$Werror = 1;
|
||||
}
|
||||
}
|
||||
|
||||
# Generated docbook code is inserted in a template at a point where
|
||||
# docbook v3.1 requires a non-zero sequence of RefEntry's; see:
|
||||
# http://www.oasis-open.org/docbook/documentation/reference/html/refentry.html
|
||||
# https://www.oasis-open.org/docbook/documentation/reference/html/refentry.html
|
||||
# We keep track of number of generated entries and generate a dummy
|
||||
# if needs be to ensure the expanded template can be postprocessed
|
||||
# into html.
|
||||
@@ -327,13 +353,14 @@ my $lineprefix="";
|
||||
|
||||
# Parser states
|
||||
use constant {
|
||||
STATE_NORMAL => 0, # normal code
|
||||
STATE_NAME => 1, # looking for function name
|
||||
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
|
||||
STATE_NORMAL => 0, # normal code
|
||||
STATE_NAME => 1, # looking for function name
|
||||
STATE_BODY_MAYBE => 2, # body - or maybe more description
|
||||
STATE_BODY => 3, # the body of the comment
|
||||
STATE_BODY_WITH_BLANK_LINE => 4, # the body, which has a blank line
|
||||
STATE_PROTO => 5, # scanning prototype
|
||||
STATE_DOCBLOCK => 6, # documentation block
|
||||
STATE_INLINE => 7, # gathering doc outside main block
|
||||
};
|
||||
my $state;
|
||||
my $in_doc_sect;
|
||||
@@ -413,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 = ();
|
||||
@@ -428,6 +454,8 @@ while ($ARGV[0] =~ m/^--?(.*)/) {
|
||||
push(@export_file_list, $file);
|
||||
} elsif ($cmd eq "v") {
|
||||
$verbose = 1;
|
||||
} elsif ($cmd eq "Werror") {
|
||||
$Werror = 1;
|
||||
} elsif (($cmd eq "h") || ($cmd eq "help")) {
|
||||
usage();
|
||||
} elsif ($cmd eq 'no-doc-sections') {
|
||||
@@ -435,7 +463,24 @@ while ($ARGV[0] =~ m/^--?(.*)/) {
|
||||
} elsif ($cmd eq 'enable-lineno') {
|
||||
$enable_lineno = 1;
|
||||
} elsif ($cmd eq 'show-not-found') {
|
||||
$show_not_found = 1;
|
||||
$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();
|
||||
@@ -444,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';
|
||||
@@ -510,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,
|
||||
@@ -597,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 = "";
|
||||
@@ -740,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";
|
||||
}
|
||||
@@ -825,16 +917,37 @@ sub output_function_rst(%) {
|
||||
my ($parameter, $section);
|
||||
my $oldprefix = $lineprefix;
|
||||
my $start = "";
|
||||
my $is_macro = 0;
|
||||
|
||||
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 ``";
|
||||
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'} . " (";
|
||||
@@ -853,15 +966,17 @@ sub output_function_rst(%) {
|
||||
|
||||
if ($type =~ m/([^\(]*\(\*)\s*\)\s*\(([^\)]*)\)/) {
|
||||
# pointer-to-function
|
||||
print $1 . $parameter . ") (" . $2;
|
||||
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'});
|
||||
@@ -876,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";
|
||||
}
|
||||
@@ -917,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'});
|
||||
@@ -945,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 = " ";
|
||||
@@ -961,9 +1086,18 @@ 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'};
|
||||
if ($args{'type'} eq 'union') {
|
||||
print "\n\n.. c:union:: " . $name . "\n\n";
|
||||
} else {
|
||||
print "\n\n.. c:struct:: " . $name . "\n\n";
|
||||
}
|
||||
}
|
||||
print_lineno($declaration_start_line);
|
||||
$lineprefix = " ";
|
||||
output_highlight_rst($args{'purpose'});
|
||||
@@ -1022,12 +1156,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(@_);
|
||||
@@ -1062,7 +1198,7 @@ sub dump_struct($$) {
|
||||
my $x = shift;
|
||||
my $file = shift;
|
||||
|
||||
if ($x =~ /(struct|union)\s+(\w+)\s*\{(.*)\}(\s*(__packed|__aligned|__attribute__\s*\(\([a-z0-9,_\s\(\)]*\)\)))*/) {
|
||||
if ($x =~ /(struct|union)\s+(\w+)\s*\{(.*)\}(\s*(__packed|__aligned|____cacheline_aligned_in_smp|____cacheline_aligned|__attribute__\s*\(\([a-z0-9,_\s\(\)]*\)\)))*/) {
|
||||
my $decl_type = $1;
|
||||
$declaration_name = $2;
|
||||
my $members = $3;
|
||||
@@ -1073,11 +1209,15 @@ sub dump_struct($$) {
|
||||
# strip comments:
|
||||
$members =~ s/\/\*.*?\*\///gos;
|
||||
# strip attributes
|
||||
$members =~ s/\s*__attribute__\s*\(\([a-z0-9,_\*\s\(\)]*\)\)//gi;
|
||||
$members =~ s/\s*__aligned\s*\([^;]*\)//gos;
|
||||
$members =~ s/\s*__packed\s*//gos;
|
||||
$members =~ s/\s*CRYPTO_MINALIGN_ATTR//gos;
|
||||
$members =~ s/\s*__attribute__\s*\(\([a-z0-9,_\*\s\(\)]*\)\)/ /gi;
|
||||
$members =~ s/\s*__aligned\s*\([^;]*\)/ /gos;
|
||||
$members =~ s/\s*__packed\s*/ /gos;
|
||||
$members =~ s/\s*CRYPTO_MINALIGN_ATTR/ /gos;
|
||||
$members =~ s/\s*____cacheline_aligned_in_smp/ /gos;
|
||||
$members =~ s/\s*____cacheline_aligned/ /gos;
|
||||
|
||||
# replace DECLARE_BITMAP
|
||||
$members =~ s/__ETHTOOL_DECLARE_LINK_MODE_MASK\s*\(([^\)]+)\)/DECLARE_BITMAP($1, __ETHTOOL_LINK_MODE_MASK_NBITS)/gos;
|
||||
$members =~ s/DECLARE_BITMAP\s*\(([^,)]+),\s*([^,)]+)\)/unsigned long $1\[BITS_TO_LONGS($2)\]/gos;
|
||||
# replace DECLARE_HASHTABLE
|
||||
$members =~ s/DECLARE_HASHTABLE\s*\(([^,)]+),\s*([^,)]+)\)/unsigned long $1\[1 << (($2) - 1)\]/gos;
|
||||
@@ -1204,6 +1344,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) {
|
||||
@@ -1227,27 +1369,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 ($members) {
|
||||
my %_members;
|
||||
|
||||
$members =~ s/\s+$//;
|
||||
@@ -1282,27 +1425,31 @@ sub dump_enum($$) {
|
||||
'sections' => \%sections,
|
||||
'purpose' => $declaration_purpose
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
print STDERR "${file}:$.: error: Cannot parse enum!\n";
|
||||
++$errors;
|
||||
}
|
||||
}
|
||||
|
||||
my $typedef_type = qr { ((?:\s+[\w\*]+\b){1,8})\s* }x;
|
||||
my $typedef_ident = qr { \*?\s*(\w\S+)\s* }x;
|
||||
my $typedef_args = qr { \s*\((.*)\); }x;
|
||||
|
||||
my $typedef1 = qr { typedef$typedef_type\($typedef_ident\)$typedef_args }x;
|
||||
my $typedef2 = qr { typedef$typedef_type$typedef_ident$typedef_args }x;
|
||||
|
||||
sub dump_typedef($$) {
|
||||
my $x = shift;
|
||||
my $file = shift;
|
||||
|
||||
$x =~ s@/\*.*?\*/@@gos; # strip comments.
|
||||
|
||||
# Parse function prototypes
|
||||
if ($x =~ /typedef\s+(\w+)\s*\(\*\s*(\w\S+)\s*\)\s*\((.*)\);/ ||
|
||||
$x =~ /typedef\s+(\w+)\s*(\w\S+)\s*\s*\((.*)\);/) {
|
||||
|
||||
# Function typedefs
|
||||
# Parse function typedef prototypes
|
||||
if ($x =~ $typedef1 || $x =~ $typedef2) {
|
||||
$return_type = $1;
|
||||
$declaration_name = $2;
|
||||
my $args = $3;
|
||||
$return_type =~ s/^\s+//;
|
||||
|
||||
create_parameterlist($args, ',', $file, $declaration_name);
|
||||
|
||||
@@ -1369,25 +1516,27 @@ sub create_parameterlist($$$$) {
|
||||
foreach my $arg (split($splitter, $args)) {
|
||||
# strip comments
|
||||
$arg =~ s/\/\*.*\*\///;
|
||||
$arg =~ s/\s*EFIAPI\s*/ /g;
|
||||
# strip leading/trailing spaces
|
||||
$arg =~ s/^\s*//;
|
||||
$arg =~ s/\s*$//;
|
||||
$arg =~ s/\s+/ /;
|
||||
|
||||
|
||||
if ($arg =~ /^#/) {
|
||||
# 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/#/,/;
|
||||
$arg =~ m/[^\(]+\([\w\s]*\*?\s*([\w\.]*)\s*\)/;
|
||||
$arg =~ m/[^\(]+\(\s*\*?\s*([\w\.]*)\s*\)/;
|
||||
$param = $1;
|
||||
$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;
|
||||
@@ -1412,26 +1561,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;
|
||||
|
||||
@@ -1449,6 +1600,10 @@ sub push_parameter($$$$) {
|
||||
# handles unnamed variable parameters
|
||||
$param = "...";
|
||||
}
|
||||
elsif ($param =~ /\w\.\.\.$/) {
|
||||
# for named variable parameters of the form `x...`, remove the dots
|
||||
$param =~ s/\.\.\.$//;
|
||||
}
|
||||
if (!defined $parameterdescs{$param} || $parameterdescs{$param} eq "") {
|
||||
$parameterdescs{$param} = "variable arguments";
|
||||
}
|
||||
@@ -1491,8 +1646,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($$$$$) {
|
||||
@@ -1566,6 +1721,8 @@ sub dump_function($$) {
|
||||
my $file = shift;
|
||||
my $noret = 0;
|
||||
|
||||
print_lineno($new_start_line);
|
||||
|
||||
$prototype =~ s/^static +//;
|
||||
$prototype =~ s/^extern +//;
|
||||
$prototype =~ s/^asmlinkage +//;
|
||||
@@ -1580,6 +1737,7 @@ sub dump_function($$) {
|
||||
$prototype =~ s/__must_check +//;
|
||||
$prototype =~ s/__weak +//;
|
||||
$prototype =~ s/__sched +//;
|
||||
$prototype =~ s/__printf\s*\(\s*\d*\s*,\s*\d*\s*\) +//;
|
||||
my $define = $prototype =~ s/^#\s*define\s+//; #ak added
|
||||
$prototype =~ s/__attribute__\s*\(\(
|
||||
(?:
|
||||
@@ -1640,30 +1798,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 {
|
||||
@@ -1758,6 +1934,11 @@ sub process_proto_function($$) {
|
||||
$prototype =~ s@/\*.*?\*/@@gos; # strip comments.
|
||||
$prototype =~ s@[\r\n]+@ @gos; # strip newlines/cr's.
|
||||
$prototype =~ s@^\s+@@gos; # strip leading spaces
|
||||
|
||||
# Handle prototypes for function pointers like:
|
||||
# int (*pcs_config)(struct foo)
|
||||
$prototype =~ s@^(\S+\s+)\(\s*\*(\S+)\)@$1$2@gos;
|
||||
|
||||
if ($prototype =~ /SYSCALL_DEFINE/) {
|
||||
syscall_munge();
|
||||
}
|
||||
@@ -1836,6 +2017,7 @@ sub process_export_file($) {
|
||||
|
||||
while (<IN>) {
|
||||
if (/$export_symbol/) {
|
||||
next if (defined($nosymbol_table{$2}));
|
||||
$function_table{$2} = 1;
|
||||
}
|
||||
}
|
||||
@@ -1867,7 +2049,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;
|
||||
@@ -1935,6 +2117,25 @@ sub process_name($$) {
|
||||
sub process_body($$) {
|
||||
my $file = shift;
|
||||
|
||||
# Until all named variable macro parameters are
|
||||
# documented using the bare name (`x`) rather than with
|
||||
# dots (`x...`), strip the dots:
|
||||
if ($section =~ /\w\.\.\.$/) {
|
||||
$section =~ s/\.\.\.$//;
|
||||
|
||||
if ($verbose) {
|
||||
print STDERR "${file}:$.: warning: Variable macro arguments should be documented without dots\n";
|
||||
++$warnings;
|
||||
}
|
||||
}
|
||||
|
||||
if ($state == STATE_BODY_WITH_BLANK_LINE && /^\s*\*\s?\S/) {
|
||||
dump_section($file, $section, $contents);
|
||||
$section = $section_default;
|
||||
$new_start_line = $.;
|
||||
$contents = "";
|
||||
}
|
||||
|
||||
if (/$doc_sect/i) { # case insensitive for supported section names
|
||||
$newsection = $1;
|
||||
$newcontents = $2;
|
||||
@@ -1987,19 +2188,23 @@ sub process_body($$) {
|
||||
$prototype = "";
|
||||
$state = STATE_PROTO;
|
||||
$brcount = 0;
|
||||
$new_start_line = $. + 1;
|
||||
} 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) {
|
||||
if ($section eq $section_context) {
|
||||
dump_section($file, $section, $contents);
|
||||
$section = $section_default;
|
||||
$contents = "";
|
||||
$new_start_line = $.;
|
||||
$state = STATE_BODY;
|
||||
} else {
|
||||
if ($section ne $section_default) {
|
||||
$state = STATE_BODY_WITH_BLANK_LINE;
|
||||
} else {
|
||||
$state = STATE_BODY;
|
||||
}
|
||||
$contents .= "\n";
|
||||
}
|
||||
$state = STATE_BODY;
|
||||
} elsif ($state == STATE_BODY_MAYBE) {
|
||||
# Continued declaration purpose
|
||||
chomp($declaration_purpose);
|
||||
@@ -2131,7 +2336,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;
|
||||
@@ -2140,9 +2345,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) {};
|
||||
@@ -2151,7 +2356,8 @@ sub process_file($) {
|
||||
process_normal();
|
||||
} elsif ($state == STATE_NAME) {
|
||||
process_name($file, $_);
|
||||
} elsif ($state == STATE_BODY || $state == STATE_BODY_MAYBE) {
|
||||
} elsif ($state == STATE_BODY || $state == STATE_BODY_MAYBE ||
|
||||
$state == STATE_BODY_WITH_BLANK_LINE) {
|
||||
process_body($file, $_);
|
||||
} elsif ($state == STATE_INLINE) { # scanning for inline parameters
|
||||
process_inline($file, $_);
|
||||
@@ -2163,17 +2369,24 @@ sub process_file($) {
|
||||
}
|
||||
|
||||
# Make sure we got something interesting.
|
||||
if ($initial_section_counter == $section_counter) {
|
||||
if ($output_mode ne "none") {
|
||||
if ($initial_section_counter == $section_counter && $
|
||||
output_mode ne "none") {
|
||||
if ($output_selection == OUTPUT_INCLUDE) {
|
||||
print STDERR "${file}:1: warning: '$_' not found\n"
|
||||
for keys %function_table;
|
||||
}
|
||||
else {
|
||||
print STDERR "${file}:1: warning: no structured comments found\n";
|
||||
}
|
||||
if (($output_selection == OUTPUT_INCLUDE) && ($show_not_found == 1)) {
|
||||
print STDERR " Was looking for '$_'.\n" for keys %function_table;
|
||||
}
|
||||
}
|
||||
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
|
||||
@@ -2220,4 +2433,9 @@ if ($verbose && $warnings) {
|
||||
print STDERR "$warnings warnings\n";
|
||||
}
|
||||
|
||||
exit($output_mode eq "none" ? 0 : $errors);
|
||||
if ($Werror && $warnings) {
|
||||
print STDERR "$warnings warnings as Errors\n";
|
||||
exit($warnings);
|
||||
} else {
|
||||
exit($output_mode eq "none" ? 0 : $errors)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user