mirror of
https://github.com/qemu/qemu.git
synced 2026-07-08 17:46:10 +00:00
kernel-doc.py: sync with upstream Kernel v6.19-rc4
The changes here are aligned up to this Linux changeset:
f64c7e113dc9 ("scripts: docs: kdoc_files.py: don't consider symlinks as directories")
On other words, everything that it is there, except for the
patch moving the library to tools/lib/python.
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 54dec248994abf37c4b5b9e48d5ab8f0f8df6f2d.1767716928.git.mchehab+huawei@kernel.org
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
committed by
Peter Maydell
parent
43f9287d3a
commit
d9aa110bf1
@@ -49,7 +49,7 @@ class GlobSourceFiles:
|
||||
for entry in obj:
|
||||
name = os.path.join(dirname, entry.name)
|
||||
|
||||
if entry.is_dir():
|
||||
if entry.is_dir(follow_symlinks=False):
|
||||
yield from self._parse_dir(name)
|
||||
|
||||
if not entry.is_file():
|
||||
@@ -64,7 +64,7 @@ class GlobSourceFiles:
|
||||
|
||||
def parse_files(self, file_list, file_not_found_cb):
|
||||
"""
|
||||
Define an interator to parse all source files from file_list,
|
||||
Define an iterator to parse all source files from file_list,
|
||||
handling directories if any
|
||||
"""
|
||||
|
||||
@@ -229,7 +229,7 @@ class KernelFiles():
|
||||
Return output messages from a file name using the output style
|
||||
filtering.
|
||||
|
||||
If output type was not handled by the syler, return None.
|
||||
If output type was not handled by the styler, return None.
|
||||
"""
|
||||
|
||||
# NOTE: we can add rules here to filter out unwanted parts,
|
||||
@@ -275,7 +275,10 @@ class KernelFiles():
|
||||
self.config.log.warning("No kernel-doc for file %s", fname)
|
||||
continue
|
||||
|
||||
for arg in self.results[fname]:
|
||||
symbols = self.results[fname]
|
||||
self.out_style.set_symbols(symbols)
|
||||
|
||||
for arg in symbols:
|
||||
m = self.out_msg(fname, arg.name, arg)
|
||||
|
||||
if m is None:
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
#
|
||||
|
||||
class KdocItem:
|
||||
def __init__(self, name, type, start_line, **other_stuff):
|
||||
def __init__(self, name, fname, type, start_line, **other_stuff):
|
||||
self.name = name
|
||||
self.fname = fname
|
||||
self.type = type
|
||||
self.declaration_start_line = start_line
|
||||
self.sections = {}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
Implement output filters to print kernel-doc documentation.
|
||||
|
||||
The implementation uses a virtual base class (OutputFormat) which
|
||||
contains a dispatches to virtual methods, and some code to filter
|
||||
contains dispatches to virtual methods, and some code to filter
|
||||
out output messages.
|
||||
|
||||
The actual implementation is done on one separate class per each type
|
||||
@@ -59,7 +59,7 @@ class OutputFormat:
|
||||
OUTPUT_EXPORTED = 2 # output exported symbols
|
||||
OUTPUT_INTERNAL = 3 # output non-exported symbols
|
||||
|
||||
# Virtual member to be overriden at the inherited classes
|
||||
# Virtual member to be overridden at the inherited classes
|
||||
highlights = []
|
||||
|
||||
def __init__(self):
|
||||
@@ -85,7 +85,7 @@ class OutputFormat:
|
||||
def set_filter(self, export, internal, symbol, nosymbol, function_table,
|
||||
enable_lineno, no_doc_sections):
|
||||
"""
|
||||
Initialize filter variables according with the requested mode.
|
||||
Initialize filter variables according to the requested mode.
|
||||
|
||||
Only one choice is valid between export, internal and symbol.
|
||||
|
||||
@@ -208,13 +208,16 @@ class OutputFormat:
|
||||
return self.data
|
||||
|
||||
# Warn if some type requires an output logic
|
||||
self.config.log.warning("doesn't now how to output '%s' block",
|
||||
self.config.log.warning("doesn't know how to output '%s' block",
|
||||
dtype)
|
||||
|
||||
return None
|
||||
|
||||
# Virtual methods to be overridden by inherited classes
|
||||
# At the base class, those do nothing.
|
||||
def set_symbols(self, symbols):
|
||||
"""Get a list of all symbols from kernel_doc"""
|
||||
|
||||
def out_doc(self, fname, name, args):
|
||||
"""Outputs a DOC block"""
|
||||
|
||||
@@ -577,6 +580,7 @@ class ManFormat(OutputFormat):
|
||||
|
||||
super().__init__()
|
||||
self.modulename = modulename
|
||||
self.symbols = []
|
||||
|
||||
dt = None
|
||||
tstamp = os.environ.get("KBUILD_BUILD_TIMESTAMP")
|
||||
@@ -593,6 +597,69 @@ class ManFormat(OutputFormat):
|
||||
|
||||
self.man_date = dt.strftime("%B %Y")
|
||||
|
||||
def arg_name(self, args, name):
|
||||
"""
|
||||
Return the name that will be used for the man page.
|
||||
|
||||
As we may have the same name on different namespaces,
|
||||
prepend the data type for all types except functions and typedefs.
|
||||
|
||||
The doc section is special: it uses the modulename.
|
||||
"""
|
||||
|
||||
dtype = args.type
|
||||
|
||||
if dtype == "doc":
|
||||
return self.modulename
|
||||
|
||||
if dtype in ["function", "typedef"]:
|
||||
return name
|
||||
|
||||
return f"{dtype} {name}"
|
||||
|
||||
def set_symbols(self, symbols):
|
||||
"""
|
||||
Get a list of all symbols from kernel_doc.
|
||||
|
||||
Man pages will uses it to add a SEE ALSO section with other
|
||||
symbols at the same file.
|
||||
"""
|
||||
self.symbols = symbols
|
||||
|
||||
def out_tail(self, fname, name, args):
|
||||
"""Adds a tail for all man pages"""
|
||||
|
||||
# SEE ALSO section
|
||||
self.data += f'.SH "SEE ALSO"' + "\n.PP\n"
|
||||
self.data += (f"Kernel file \\fB{args.fname}\\fR\n")
|
||||
if len(self.symbols) >= 2:
|
||||
cur_name = self.arg_name(args, name)
|
||||
|
||||
related = []
|
||||
for arg in self.symbols:
|
||||
out_name = self.arg_name(arg, arg.name)
|
||||
|
||||
if cur_name == out_name:
|
||||
continue
|
||||
|
||||
related.append(f"\\fB{out_name}\\fR(9)")
|
||||
|
||||
self.data += ",\n".join(related) + "\n"
|
||||
|
||||
# TODO: does it make sense to add other sections? Maybe
|
||||
# REPORTING ISSUES? LICENSE?
|
||||
|
||||
def msg(self, fname, name, args):
|
||||
"""
|
||||
Handles a single entry from kernel-doc parser.
|
||||
|
||||
Add a tail at the end of man pages output.
|
||||
"""
|
||||
super().msg(fname, name, args)
|
||||
self.out_tail(fname, name, args)
|
||||
|
||||
return self.data
|
||||
|
||||
def output_highlight(self, block):
|
||||
"""
|
||||
Outputs a C symbol that may require being highlighted with
|
||||
@@ -618,7 +685,9 @@ class ManFormat(OutputFormat):
|
||||
if not self.check_doc(name, args):
|
||||
return
|
||||
|
||||
self.data += f'.TH "{self.modulename}" 9 "{self.modulename}" "{self.man_date}" "API Manual" LINUX' + "\n"
|
||||
out_name = self.arg_name(args, name)
|
||||
|
||||
self.data += f'.TH "{self.modulename}" 9 "{out_name}" "{self.man_date}" "API Manual" LINUX' + "\n"
|
||||
|
||||
for section, text in args.sections.items():
|
||||
self.data += f'.SH "{section}"' + "\n"
|
||||
@@ -627,7 +696,9 @@ class ManFormat(OutputFormat):
|
||||
def out_function(self, fname, name, args):
|
||||
"""output function in man"""
|
||||
|
||||
self.data += f'.TH "{name}" 9 "{name}" "{self.man_date}" "Kernel Hacker\'s Manual" LINUX' + "\n"
|
||||
out_name = self.arg_name(args, name)
|
||||
|
||||
self.data += f'.TH "{name}" 9 "{out_name}" "{self.man_date}" "Kernel Hacker\'s Manual" LINUX' + "\n"
|
||||
|
||||
self.data += ".SH NAME\n"
|
||||
self.data += f"{name} \\- {args['purpose']}\n"
|
||||
@@ -671,7 +742,9 @@ class ManFormat(OutputFormat):
|
||||
self.output_highlight(text)
|
||||
|
||||
def out_enum(self, fname, name, args):
|
||||
self.data += f'.TH "{self.modulename}" 9 "enum {name}" "{self.man_date}" "API Manual" LINUX' + "\n"
|
||||
out_name = self.arg_name(args, name)
|
||||
|
||||
self.data += f'.TH "{self.modulename}" 9 "{out_name}" "{self.man_date}" "API Manual" LINUX' + "\n"
|
||||
|
||||
self.data += ".SH NAME\n"
|
||||
self.data += f"enum {name} \\- {args['purpose']}\n"
|
||||
@@ -703,8 +776,9 @@ class ManFormat(OutputFormat):
|
||||
def out_typedef(self, fname, name, args):
|
||||
module = self.modulename
|
||||
purpose = args.get('purpose')
|
||||
out_name = self.arg_name(args, name)
|
||||
|
||||
self.data += f'.TH "{module}" 9 "{name}" "{self.man_date}" "API Manual" LINUX' + "\n"
|
||||
self.data += f'.TH "{module}" 9 "{out_name}" "{self.man_date}" "API Manual" LINUX' + "\n"
|
||||
|
||||
self.data += ".SH NAME\n"
|
||||
self.data += f"typedef {name} \\- {purpose}\n"
|
||||
@@ -717,8 +791,9 @@ class ManFormat(OutputFormat):
|
||||
module = self.modulename
|
||||
purpose = args.get('purpose')
|
||||
definition = args.get('definition')
|
||||
out_name = self.arg_name(args, name)
|
||||
|
||||
self.data += f'.TH "{module}" 9 "{args.type} {name}" "{self.man_date}" "API Manual" LINUX' + "\n"
|
||||
self.data += f'.TH "{module}" 9 "{out_name}" "{self.man_date}" "API Manual" LINUX' + "\n"
|
||||
|
||||
self.data += ".SH NAME\n"
|
||||
self.data += f"{args.type} {name} \\- {purpose}\n"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,7 +16,7 @@ re_cache = {}
|
||||
|
||||
class KernRe:
|
||||
"""
|
||||
Helper class to simplify regex declaration and usage,
|
||||
Helper class to simplify regex declaration and usage.
|
||||
|
||||
It calls re.compile for a given pattern. It also allows adding
|
||||
regular expressions and define sub at class init time.
|
||||
@@ -27,7 +27,7 @@ class KernRe:
|
||||
|
||||
def _add_regex(self, string, flags):
|
||||
"""
|
||||
Adds a new regex or re-use it from the cache.
|
||||
Adds a new regex or reuses it from the cache.
|
||||
"""
|
||||
self.regex = re_cache.get(string, None)
|
||||
if not self.regex:
|
||||
@@ -114,7 +114,7 @@ class NestedMatch:
|
||||
|
||||
'\\bSTRUCT_GROUP(\\(((?:(?>[^)(]+)|(?1))*)\\))[^;]*;'
|
||||
|
||||
which is used to properly match open/close parenthesis of the
|
||||
which is used to properly match open/close parentheses of the
|
||||
string search STRUCT_GROUP(),
|
||||
|
||||
Add a class that counts pairs of delimiters, using it to match and
|
||||
@@ -136,13 +136,13 @@ class NestedMatch:
|
||||
# \bSTRUCT_GROUP\(
|
||||
#
|
||||
# is similar to: STRUCT_GROUP\((.*)\)
|
||||
# except that the content inside the match group is delimiter's aligned.
|
||||
# except that the content inside the match group is delimiter-aligned.
|
||||
#
|
||||
# The content inside parenthesis are converted into a single replace
|
||||
# The content inside parentheses is converted into a single replace
|
||||
# group (e.g. r`\1').
|
||||
#
|
||||
# It would be nice to change such definition to support multiple
|
||||
# match groups, allowing a regex equivalent to.
|
||||
# match groups, allowing a regex equivalent to:
|
||||
#
|
||||
# FOO\((.*), (.*), (.*)\)
|
||||
#
|
||||
@@ -168,14 +168,14 @@ class NestedMatch:
|
||||
but I ended using a different implementation to align all three types
|
||||
of delimiters and seek for an initial regular expression.
|
||||
|
||||
The algorithm seeks for open/close paired delimiters and place them
|
||||
into a stack, yielding a start/stop position of each match when the
|
||||
The algorithm seeks for open/close paired delimiters and places them
|
||||
into a stack, yielding a start/stop position of each match when the
|
||||
stack is zeroed.
|
||||
|
||||
The algorithm shoud work fine for properly paired lines, but will
|
||||
silently ignore end delimiters that preceeds an start delimiter.
|
||||
The algorithm should work fine for properly paired lines, but will
|
||||
silently ignore end delimiters that precede a start delimiter.
|
||||
This should be OK for kernel-doc parser, as unaligned delimiters
|
||||
would cause compilation errors. So, we don't need to rise exceptions
|
||||
would cause compilation errors. So, we don't need to raise exceptions
|
||||
to cover such issues.
|
||||
"""
|
||||
|
||||
@@ -203,7 +203,7 @@ class NestedMatch:
|
||||
stack.append(end)
|
||||
continue
|
||||
|
||||
# Does the end delimiter match what it is expected?
|
||||
# Does the end delimiter match what is expected?
|
||||
if stack and d == stack[-1]:
|
||||
stack.pop()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user