Merge branch 'kdoc-item2' into docs-mw

The kerneldoc parsing phase gathers all of the information about the
declarations of interest, then passes it through to the output phase as a
dict that is an unstructured blob of information; this organization has its
origins in the Perl version of the program.  It results in an interface
that is difficult to reason about, dozen-parameter function calls, and
other ills.

Introduce a new class (KdocItem) to carry this information between the
parser and the output modules, and, step by step, modify the system to use
this class in a more structured way.  This could be taken further by
creating a subclass of KdocItem for each declaration type (function,
struct, ...), but that is probably more structure than we need.

The result is (I hope) clearer code, the removal of a bunch of boilerplate,
and no changes to the generated output.
This commit is contained in:
Jonathan Corbet 2025-07-15 13:46:42 -06:00
commit f587722aa5
4 changed files with 145 additions and 244 deletions

View File

@ -275,8 +275,8 @@ class KernelFiles():
self.config.log.warning("No kernel-doc for file %s", fname)
continue
for name, arg in self.results[fname]:
m = self.out_msg(fname, name, arg)
for arg in self.results[fname]:
m = self.out_msg(fname, arg.name, arg)
if m is None:
ln = arg.get("ln", 0)

View File

@ -0,0 +1,42 @@
# SPDX-License-Identifier: GPL-2.0
#
# A class that will, eventually, encapsulate all of the parsed data that we
# then pass into the output modules.
#
class KdocItem:
def __init__(self, name, type, start_line, **other_stuff):
self.name = name
self.type = type
self.declaration_start_line = start_line
self.sections = {}
self.sections_start_lines = {}
self.parameterlist = []
self.parameterdesc_start_lines = []
self.parameterdescs = {}
self.parametertypes = {}
#
# Just save everything else into our own dict so that the output
# side can grab it directly as before. As we move things into more
# structured data, this will, hopefully, fade away.
#
self.other_stuff = other_stuff
def get(self, key, default = None):
return self.other_stuff.get(key, default)
def __getitem__(self, key):
return self.get(key)
#
# Tracking of section and parameter information.
#
def set_sections(self, sections, start_lines):
self.sections = sections
self.section_start_lines = start_lines
def set_params(self, names, descs, types, starts):
self.parameterlist = names
self.parameterdescs = descs
self.parametertypes = types
self.parameterdesc_start_lines = starts

View File

@ -124,9 +124,7 @@ class OutputFormat:
Output warnings for identifiers that will be displayed.
"""
warnings = args.get('warnings', [])
for log_msg in warnings:
for log_msg in args.warnings:
self.config.warning(log_msg)
def check_doc(self, name, args):
@ -184,7 +182,7 @@ class OutputFormat:
self.data = ""
dtype = args.get('type', "")
dtype = args.type
if dtype == "doc":
self.out_doc(fname, name, args)
@ -338,12 +336,7 @@ class RestFormat(OutputFormat):
starts by putting out the name of the doc section itself, but that
tends to duplicate a header already in the template file.
"""
sectionlist = args.get('sectionlist', [])
sections = args.get('sections', {})
section_start_lines = args.get('section_start_lines', {})
for section in sectionlist:
for section, text in args.sections.items():
# Skip sections that are in the nosymbol_table
if section in self.nosymbol:
continue
@ -355,8 +348,8 @@ class RestFormat(OutputFormat):
else:
self.data += f'{self.lineprefix}**{section}**\n\n'
self.print_lineno(section_start_lines.get(section, 0))
self.output_highlight(sections[section])
self.print_lineno(args.section_start_lines.get(section, 0))
self.output_highlight(text)
self.data += "\n"
self.data += "\n"
@ -372,24 +365,19 @@ class RestFormat(OutputFormat):
func_macro = args.get('func_macro', False)
if func_macro:
signature = args['function']
signature = name
else:
if args.get('functiontype'):
signature = args['functiontype'] + " "
signature += args['function'] + " ("
parameterlist = args.get('parameterlist', [])
parameterdescs = args.get('parameterdescs', {})
parameterdesc_start_lines = args.get('parameterdesc_start_lines', {})
ln = args.get('declaration_start_line', 0)
signature += name + " ("
ln = args.declaration_start_line
count = 0
for parameter in parameterlist:
for parameter in args.parameterlist:
if count != 0:
signature += ", "
count += 1
dtype = args['parametertypes'].get(parameter, "")
dtype = args.parametertypes.get(parameter, "")
if function_pointer.search(dtype):
signature += function_pointer.group(1) + parameter + function_pointer.group(3)
@ -401,7 +389,7 @@ class RestFormat(OutputFormat):
self.print_lineno(ln)
if args.get('typedef') or not args.get('functiontype'):
self.data += f".. c:macro:: {args['function']}\n\n"
self.data += f".. c:macro:: {name}\n\n"
if args.get('typedef'):
self.data += " **Typedef**: "
@ -424,26 +412,26 @@ class RestFormat(OutputFormat):
# function prototypes apart
self.lineprefix = " "
if parameterlist:
if args.parameterlist:
self.data += ".. container:: kernelindent\n\n"
self.data += f"{self.lineprefix}**Parameters**\n\n"
for parameter in parameterlist:
for parameter in args.parameterlist:
parameter_name = KernRe(r'\[.*').sub('', parameter)
dtype = args['parametertypes'].get(parameter, "")
dtype = args.parametertypes.get(parameter, "")
if dtype:
self.data += f"{self.lineprefix}``{dtype}``\n"
else:
self.data += f"{self.lineprefix}``{parameter}``\n"
self.print_lineno(parameterdesc_start_lines.get(parameter_name, 0))
self.print_lineno(args.parameterdesc_start_lines.get(parameter_name, 0))
self.lineprefix = " "
if parameter_name in parameterdescs and \
parameterdescs[parameter_name] != KernelDoc.undescribed:
if parameter_name in args.parameterdescs and \
args.parameterdescs[parameter_name] != KernelDoc.undescribed:
self.output_highlight(parameterdescs[parameter_name])
self.output_highlight(args.parameterdescs[parameter_name])
self.data += "\n"
else:
self.data += f"{self.lineprefix}*undescribed*\n\n"
@ -455,10 +443,7 @@ class RestFormat(OutputFormat):
def out_enum(self, fname, name, args):
oldprefix = self.lineprefix
name = args.get('enum', '')
parameterlist = args.get('parameterlist', [])
parameterdescs = args.get('parameterdescs', {})
ln = args.get('declaration_start_line', 0)
ln = args.declaration_start_line
self.data += f"\n\n.. c:enum:: {name}\n\n"
@ -472,11 +457,11 @@ class RestFormat(OutputFormat):
self.lineprefix = outer + " "
self.data += f"{outer}**Constants**\n\n"
for parameter in parameterlist:
for parameter in args.parameterlist:
self.data += f"{outer}``{parameter}``\n"
if parameterdescs.get(parameter, '') != KernelDoc.undescribed:
self.output_highlight(parameterdescs[parameter])
if args.parameterdescs.get(parameter, '') != KernelDoc.undescribed:
self.output_highlight(args.parameterdescs[parameter])
else:
self.data += f"{self.lineprefix}*undescribed*\n\n"
self.data += "\n"
@ -487,8 +472,7 @@ class RestFormat(OutputFormat):
def out_typedef(self, fname, name, args):
oldprefix = self.lineprefix
name = args.get('typedef', '')
ln = args.get('declaration_start_line', 0)
ln = args.declaration_start_line
self.data += f"\n\n.. c:type:: {name}\n\n"
@ -504,15 +488,10 @@ class RestFormat(OutputFormat):
def out_struct(self, fname, name, args):
name = args.get('struct', "")
purpose = args.get('purpose', "")
declaration = args.get('definition', "")
dtype = args.get('type', "struct")
ln = args.get('declaration_start_line', 0)
parameterlist = args.get('parameterlist', [])
parameterdescs = args.get('parameterdescs', {})
parameterdesc_start_lines = args.get('parameterdesc_start_lines', {})
dtype = args.type
ln = args.declaration_start_line
self.data += f"\n\n.. c:{dtype}:: {name}\n\n"
@ -536,21 +515,21 @@ class RestFormat(OutputFormat):
self.lineprefix = " "
self.data += f"{self.lineprefix}**Members**\n\n"
for parameter in parameterlist:
for parameter in args.parameterlist:
if not parameter or parameter.startswith("#"):
continue
parameter_name = parameter.split("[", maxsplit=1)[0]
if parameterdescs.get(parameter_name) == KernelDoc.undescribed:
if args.parameterdescs.get(parameter_name) == KernelDoc.undescribed:
continue
self.print_lineno(parameterdesc_start_lines.get(parameter_name, 0))
self.print_lineno(args.parameterdesc_start_lines.get(parameter_name, 0))
self.data += f"{self.lineprefix}``{parameter}``\n"
self.lineprefix = " "
self.output_highlight(parameterdescs[parameter_name])
self.output_highlight(args.parameterdescs[parameter_name])
self.lineprefix = " "
self.data += "\n"
@ -636,46 +615,38 @@ class ManFormat(OutputFormat):
self.data += line + "\n"
def out_doc(self, fname, name, args):
sectionlist = args.get('sectionlist', [])
sections = args.get('sections', {})
if not self.check_doc(name, args):
return
self.data += f'.TH "{self.modulename}" 9 "{self.modulename}" "{self.man_date}" "API Manual" LINUX' + "\n"
for section in sectionlist:
for section, text in args.sections.items():
self.data += f'.SH "{section}"' + "\n"
self.output_highlight(sections.get(section))
self.output_highlight(text)
def out_function(self, fname, name, args):
"""output function in man"""
parameterlist = args.get('parameterlist', [])
parameterdescs = args.get('parameterdescs', {})
sectionlist = args.get('sectionlist', [])
sections = args.get('sections', {})
self.data += f'.TH "{args["function"]}" 9 "{args["function"]}" "{self.man_date}" "Kernel Hacker\'s Manual" LINUX' + "\n"
self.data += f'.TH "{name}" 9 "{name}" "{self.man_date}" "Kernel Hacker\'s Manual" LINUX' + "\n"
self.data += ".SH NAME\n"
self.data += f"{args['function']} \\- {args['purpose']}\n"
self.data += f"{name} \\- {args['purpose']}\n"
self.data += ".SH SYNOPSIS\n"
if args.get('functiontype', ''):
self.data += f'.B "{args["functiontype"]}" {args["function"]}' + "\n"
self.data += f'.B "{args["functiontype"]}" {name}' + "\n"
else:
self.data += f'.B "{args["function"]}' + "\n"
self.data += f'.B "{name}' + "\n"
count = 0
parenth = "("
post = ","
for parameter in parameterlist:
if count == len(parameterlist) - 1:
for parameter in args.parameterlist:
if count == len(args.parameterlist) - 1:
post = ");"
dtype = args['parametertypes'].get(parameter, "")
dtype = args.parametertypes.get(parameter, "")
if function_pointer.match(dtype):
# Pointer-to-function
self.data += f'".BI "{parenth}{function_pointer.group(1)}" " ") ({function_pointer.group(2)}){post}"' + "\n"
@ -686,38 +657,32 @@ class ManFormat(OutputFormat):
count += 1
parenth = ""
if parameterlist:
if args.parameterlist:
self.data += ".SH ARGUMENTS\n"
for parameter in parameterlist:
for parameter in args.parameterlist:
parameter_name = re.sub(r'\[.*', '', parameter)
self.data += f'.IP "{parameter}" 12' + "\n"
self.output_highlight(parameterdescs.get(parameter_name, ""))
self.output_highlight(args.parameterdescs.get(parameter_name, ""))
for section in sectionlist:
for section, text in args.sections.items():
self.data += f'.SH "{section.upper()}"' + "\n"
self.output_highlight(sections[section])
self.output_highlight(text)
def out_enum(self, fname, name, args):
name = args.get('enum', '')
parameterlist = args.get('parameterlist', [])
sectionlist = args.get('sectionlist', [])
sections = args.get('sections', {})
self.data += f'.TH "{self.modulename}" 9 "enum {args["enum"]}" "{self.man_date}" "API Manual" LINUX' + "\n"
self.data += f'.TH "{self.modulename}" 9 "enum {name}" "{self.man_date}" "API Manual" LINUX' + "\n"
self.data += ".SH NAME\n"
self.data += f"enum {args['enum']} \\- {args['purpose']}\n"
self.data += f"enum {name} \\- {args['purpose']}\n"
self.data += ".SH SYNOPSIS\n"
self.data += f"enum {args['enum']}" + " {\n"
self.data += f"enum {name}" + " {\n"
count = 0
for parameter in parameterlist:
for parameter in args.parameterlist:
self.data += f'.br\n.BI " {parameter}"' + "\n"
if count == len(parameterlist) - 1:
if count == len(args.parameterlist) - 1:
self.data += "\n};\n"
else:
self.data += ", \n.br\n"
@ -726,68 +691,59 @@ class ManFormat(OutputFormat):
self.data += ".SH Constants\n"
for parameter in parameterlist:
for parameter in args.parameterlist:
parameter_name = KernRe(r'\[.*').sub('', parameter)
self.data += f'.IP "{parameter}" 12' + "\n"
self.output_highlight(args['parameterdescs'].get(parameter_name, ""))
self.output_highlight(args.parameterdescs.get(parameter_name, ""))
for section in sectionlist:
for section, text in args.sections.items():
self.data += f'.SH "{section}"' + "\n"
self.output_highlight(sections[section])
self.output_highlight(text)
def out_typedef(self, fname, name, args):
module = self.modulename
typedef = args.get('typedef')
purpose = args.get('purpose')
sectionlist = args.get('sectionlist', [])
sections = args.get('sections', {})
self.data += f'.TH "{module}" 9 "{typedef}" "{self.man_date}" "API Manual" LINUX' + "\n"
self.data += f'.TH "{module}" 9 "{name}" "{self.man_date}" "API Manual" LINUX' + "\n"
self.data += ".SH NAME\n"
self.data += f"typedef {typedef} \\- {purpose}\n"
self.data += f"typedef {name} \\- {purpose}\n"
for section in sectionlist:
for section, text in args.sections.items():
self.data += f'.SH "{section}"' + "\n"
self.output_highlight(sections.get(section))
self.output_highlight(text)
def out_struct(self, fname, name, args):
module = self.modulename
struct_type = args.get('type')
struct_name = args.get('struct')
purpose = args.get('purpose')
definition = args.get('definition')
sectionlist = args.get('sectionlist', [])
parameterlist = args.get('parameterlist', [])
sections = args.get('sections', {})
parameterdescs = args.get('parameterdescs', {})
self.data += f'.TH "{module}" 9 "{struct_type} {struct_name}" "{self.man_date}" "API Manual" LINUX' + "\n"
self.data += f'.TH "{module}" 9 "{args.type} {name}" "{self.man_date}" "API Manual" LINUX' + "\n"
self.data += ".SH NAME\n"
self.data += f"{struct_type} {struct_name} \\- {purpose}\n"
self.data += f"{args.type} {name} \\- {purpose}\n"
# Replace tabs with two spaces and handle newlines
declaration = definition.replace("\t", " ")
declaration = KernRe(r"\n").sub('"\n.br\n.BI "', declaration)
self.data += ".SH SYNOPSIS\n"
self.data += f"{struct_type} {struct_name} " + "{" + "\n.br\n"
self.data += f"{args.type} {name} " + "{" + "\n.br\n"
self.data += f'.BI "{declaration}\n' + "};\n.br\n\n"
self.data += ".SH Members\n"
for parameter in parameterlist:
for parameter in args.parameterlist:
if parameter.startswith("#"):
continue
parameter_name = re.sub(r"\[.*", "", parameter)
if parameterdescs.get(parameter_name) == KernelDoc.undescribed:
if args.parameterdescs.get(parameter_name) == KernelDoc.undescribed:
continue
self.data += f'.IP "{parameter}" 12' + "\n"
self.output_highlight(parameterdescs.get(parameter_name))
self.output_highlight(args.parameterdescs.get(parameter_name))
for section in sectionlist:
for section, text in args.sections.items():
self.data += f'.SH "{section}"' + "\n"
self.output_highlight(sections.get(section))
self.output_highlight(text)

View File

@ -12,11 +12,12 @@ Read a C language source or header FILE and extract embedded
documentation comments
"""
import sys
import re
from pprint import pformat
from kdoc_re import NestedMatch, KernRe
from kdoc_item import KdocItem
#
# Regular expressions used to parse kernel-doc markups at KernelDoc class.
@ -42,8 +43,10 @@ doc_decl = doc_com + KernRe(r'(\w+)', cache=False)
# @{section-name}:
# while trying to not match literal block starts like "example::"
#
known_section_names = 'description|context|returns?|notes?|examples?'
known_sections = KernRe(known_section_names, flags = re.I)
doc_sect = doc_com + \
KernRe(r'\s*(\@[.\w]+|\@\.\.\.|description|context|returns?|notes?|examples?)\s*:([^:].*)?$',
KernRe(r'\s*(\@[.\w]+|\@\.\.\.|' + known_section_names + r')\s*:([^:].*)?$',
flags=re.I, cache=False)
doc_content = doc_com_body + KernRe(r'(.*)', cache=False)
@ -115,8 +118,6 @@ class KernelEntry:
self.config = config
self._contents = []
self.sectcheck = ""
self.struct_actual = ""
self.prototype = ""
self.warnings = []
@ -127,7 +128,6 @@ class KernelEntry:
self.parameterdesc_start_lines = {}
self.section_start_lines = {}
self.sectionlist = []
self.sections = {}
self.anon_struct_union = False
@ -189,7 +189,6 @@ class KernelEntry:
self.parameterdescs[name] = contents
self.parameterdesc_start_lines[name] = self.new_start_line
self.sectcheck += name + " "
self.new_start_line = 0
else:
@ -202,7 +201,6 @@ class KernelEntry:
self.sections[name] += '\n' + contents
else:
self.sections[name] = contents
self.sectionlist.append(name)
self.section_start_lines[name] = self.new_start_line
self.new_start_line = 0
@ -241,6 +239,14 @@ class KernelDoc:
# Place all potential outputs into an array
self.entries = []
#
# We need Python 3.7 for its "dicts remember the insertion
# order" guarantee
#
if sys.version_info.major == 3 and sys.version_info.minor < 7:
self.emit_msg(0,
'Python 3.7 or later is required for correct results')
def emit_msg(self, ln, msg, warning=True):
"""Emit a message"""
@ -271,32 +277,20 @@ class KernelDoc:
The actual output and output filters will be handled elsewhere
"""
# The implementation here is different than the original kernel-doc:
# instead of checking for output filters or actually output anything,
# it just stores the declaration content at self.entries, as the
# output will happen on a separate class.
#
# For now, we're keeping the same name of the function just to make
# easier to compare the source code of both scripts
args["declaration_start_line"] = self.entry.declaration_start_line
args["type"] = dtype
args["warnings"] = self.entry.warnings
# TODO: use colletions.OrderedDict to remove sectionlist
sections = args.get('sections', {})
sectionlist = args.get('sectionlist', [])
item = KdocItem(name, dtype, self.entry.declaration_start_line, **args)
item.warnings = self.entry.warnings
# Drop empty sections
# TODO: improve empty sections logic to emit warnings
sections = self.entry.sections
for section in ["Description", "Return"]:
if section in sectionlist:
if not sections[section].rstrip():
if section in sections and not sections[section].rstrip():
del sections[section]
sectionlist.remove(section)
self.entries.append((name, args))
item.set_sections(sections, self.entry.section_start_lines)
item.set_params(self.entry.parameterlist, self.entry.parameterdescs,
self.entry.parametertypes,
self.entry.parameterdesc_start_lines)
self.entries.append(item)
self.config.log.debug("Output: %s:%s = %s", dtype, name, pformat(args))
@ -382,15 +376,6 @@ class KernelDoc:
org_arg = KernRe(r'\s\s+').sub(' ', org_arg)
self.entry.parametertypes[param] = org_arg
def save_struct_actual(self, actual):
"""
Strip all spaces from the actual param so that it looks like
one string item.
"""
actual = KernRe(r'\s*').sub("", actual, count=1)
self.entry.struct_actual += actual + " "
def create_parameter_list(self, ln, decl_type, args,
splitter, declaration_name):
@ -436,7 +421,6 @@ class KernelDoc:
param = arg
dtype = KernRe(r'([^\(]+\(\*?)\s*' + re.escape(param)).sub(r'\1', arg)
self.save_struct_actual(param)
self.push_parameter(ln, decl_type, param, dtype,
arg, declaration_name)
@ -453,7 +437,6 @@ class KernelDoc:
dtype = KernRe(r'([^\(]+\(\*?)\s*' + re.escape(param)).sub(r'\1', arg)
self.save_struct_actual(param)
self.push_parameter(ln, decl_type, param, dtype,
arg, declaration_name)
@ -486,7 +469,6 @@ class KernelDoc:
param = r.group(1)
self.save_struct_actual(r.group(2))
self.push_parameter(ln, decl_type, r.group(2),
f"{dtype} {r.group(1)}",
arg, declaration_name)
@ -498,52 +480,27 @@ class KernelDoc:
continue
if dtype != "": # Skip unnamed bit-fields
self.save_struct_actual(r.group(1))
self.push_parameter(ln, decl_type, r.group(1),
f"{dtype}:{r.group(2)}",
arg, declaration_name)
else:
self.save_struct_actual(param)
self.push_parameter(ln, decl_type, param, dtype,
arg, declaration_name)
def check_sections(self, ln, decl_name, decl_type, sectcheck, prmscheck):
def check_sections(self, ln, decl_name, decl_type):
"""
Check for errors inside sections, emitting warnings if not found
parameters are described.
"""
sects = sectcheck.split()
prms = prmscheck.split()
err = False
for sx in range(len(sects)): # pylint: disable=C0200
err = True
for px in range(len(prms)): # pylint: disable=C0200
prm_clean = prms[px]
prm_clean = KernRe(r'\[.*\]').sub('', prm_clean)
prm_clean = attribute.sub('', prm_clean)
# ignore array size in a parameter string;
# however, the original param string may contain
# spaces, e.g.: addr[6 + 2]
# and this appears in @prms as "addr[6" since the
# parameter list is split at spaces;
# hence just ignore "[..." for the sections check;
prm_clean = KernRe(r'\[.*').sub('', prm_clean)
if prm_clean == sects[sx]:
err = False
break
if err:
for section in self.entry.sections:
if section not in self.entry.parameterlist and \
not known_sections.search(section):
if decl_type == 'function':
dname = f"{decl_type} parameter"
else:
dname = f"{decl_type} member"
self.emit_msg(ln,
f"Excess {dname} '{sects[sx]}' description in '{decl_name}'")
f"Excess {dname} '{section}' description in '{decl_name}'")
def check_return_section(self, ln, declaration_name, return_type):
"""
@ -797,8 +754,7 @@ class KernelDoc:
self.create_parameter_list(ln, decl_type, members, ';',
declaration_name)
self.check_sections(ln, declaration_name, decl_type,
self.entry.sectcheck, self.entry.struct_actual)
self.check_sections(ln, declaration_name, decl_type)
# Adjust declaration for better display
declaration = KernRe(r'([\{;])').sub(r'\1\n', declaration)
@ -834,15 +790,7 @@ class KernelDoc:
level += 1
self.output_declaration(decl_type, declaration_name,
struct=declaration_name,
definition=declaration,
parameterlist=self.entry.parameterlist,
parameterdescs=self.entry.parameterdescs,
parametertypes=self.entry.parametertypes,
parameterdesc_start_lines=self.entry.parameterdesc_start_lines,
sectionlist=self.entry.sectionlist,
sections=self.entry.sections,
section_start_lines=self.entry.section_start_lines,
purpose=self.entry.declaration_purpose)
def dump_enum(self, ln, proto):
@ -921,13 +869,6 @@ class KernelDoc:
f"Excess enum value '%{k}' description in '{declaration_name}'")
self.output_declaration('enum', declaration_name,
enum=declaration_name,
parameterlist=self.entry.parameterlist,
parameterdescs=self.entry.parameterdescs,
parameterdesc_start_lines=self.entry.parameterdesc_start_lines,
sectionlist=self.entry.sectionlist,
sections=self.entry.sections,
section_start_lines=self.entry.section_start_lines,
purpose=self.entry.declaration_purpose)
def dump_declaration(self, ln, prototype):
@ -937,18 +878,13 @@ class KernelDoc:
if self.entry.decl_type == "enum":
self.dump_enum(ln, prototype)
return
if self.entry.decl_type == "typedef":
elif self.entry.decl_type == "typedef":
self.dump_typedef(ln, prototype)
return
if self.entry.decl_type in ["union", "struct"]:
elif self.entry.decl_type in ["union", "struct"]:
self.dump_struct(ln, prototype)
return
self.output_declaration(self.entry.decl_type, prototype,
entry=self.entry)
else:
# This would be a bug
self.emit_message(ln, f'Unknown declaration type: {self.entry.decl_type}')
def dump_function(self, ln, prototype):
"""
@ -1082,38 +1018,20 @@ class KernelDoc:
f"expecting prototype for {self.entry.identifier}(). Prototype was for {declaration_name}() instead")
return
prms = " ".join(self.entry.parameterlist)
self.check_sections(ln, declaration_name, "function",
self.entry.sectcheck, prms)
self.check_sections(ln, declaration_name, "function")
self.check_return_section(ln, declaration_name, return_type)
if 'typedef' in return_type:
self.output_declaration(decl_type, declaration_name,
function=declaration_name,
typedef=True,
functiontype=return_type,
parameterlist=self.entry.parameterlist,
parameterdescs=self.entry.parameterdescs,
parametertypes=self.entry.parametertypes,
parameterdesc_start_lines=self.entry.parameterdesc_start_lines,
sectionlist=self.entry.sectionlist,
sections=self.entry.sections,
section_start_lines=self.entry.section_start_lines,
purpose=self.entry.declaration_purpose,
func_macro=func_macro)
else:
self.output_declaration(decl_type, declaration_name,
function=declaration_name,
typedef=False,
functiontype=return_type,
parameterlist=self.entry.parameterlist,
parameterdescs=self.entry.parameterdescs,
parametertypes=self.entry.parametertypes,
parameterdesc_start_lines=self.entry.parameterdesc_start_lines,
sectionlist=self.entry.sectionlist,
sections=self.entry.sections,
section_start_lines=self.entry.section_start_lines,
purpose=self.entry.declaration_purpose,
func_macro=func_macro)
@ -1150,16 +1068,8 @@ class KernelDoc:
self.create_parameter_list(ln, decl_type, args, ',', declaration_name)
self.output_declaration(decl_type, declaration_name,
function=declaration_name,
typedef=True,
functiontype=return_type,
parameterlist=self.entry.parameterlist,
parameterdescs=self.entry.parameterdescs,
parametertypes=self.entry.parametertypes,
parameterdesc_start_lines=self.entry.parameterdesc_start_lines,
sectionlist=self.entry.sectionlist,
sections=self.entry.sections,
section_start_lines=self.entry.section_start_lines,
purpose=self.entry.declaration_purpose)
return
@ -1179,10 +1089,6 @@ class KernelDoc:
return
self.output_declaration('typedef', declaration_name,
typedef=declaration_name,
sectionlist=self.entry.sectionlist,
sections=self.entry.sections,
section_start_lines=self.entry.section_start_lines,
purpose=self.entry.declaration_purpose)
return
@ -1664,10 +1570,7 @@ class KernelDoc:
if doc_end.search(line):
self.dump_section()
self.output_declaration("doc", self.entry.identifier,
sectionlist=self.entry.sectionlist,
sections=self.entry.sections,
section_start_lines=self.entry.section_start_lines)
self.output_declaration("doc", self.entry.identifier)
self.reset_state(ln)
elif doc_content.search(line):