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:
Mauro Carvalho Chehab
2026-01-06 17:38:19 +01:00
committed by Peter Maydell
parent 43f9287d3a
commit d9aa110bf1
5 changed files with 554 additions and 474 deletions

View File

@@ -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:

View File

@@ -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 = {}

View File

@@ -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

View File

@@ -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()