docs: kernel-doc: add support to store output on a YAML file
Add a command line parameter and library support to optionally store: - KdocItem intermediate format after parsing; - man pages output; - rst output. inside a YAML file. Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> Signed-off-by: Jonathan Corbet <corbet@lwn.net> Message-ID: <ba54277b3c909867153b9547dfa33c1831ca35d9.1773823995.git.mchehab+huawei@kernel.org>master
parent
b37b3cbbb1
commit
01d6d7bf96
|
|
@ -240,11 +240,9 @@ def main():
|
||||||
help=EXPORT_FILE_DESC)
|
help=EXPORT_FILE_DESC)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Output format mutually-exclusive group
|
# Output format
|
||||||
#
|
#
|
||||||
out_group = parser.add_argument_group("Output format selection (mutually exclusive)")
|
out_fmt = parser.add_argument_group("Output format selection (mutually exclusive)")
|
||||||
|
|
||||||
out_fmt = out_group.add_mutually_exclusive_group()
|
|
||||||
|
|
||||||
out_fmt.add_argument("-m", "-man", "--man", action="store_true",
|
out_fmt.add_argument("-m", "-man", "--man", action="store_true",
|
||||||
help="Output troff manual page format.")
|
help="Output troff manual page format.")
|
||||||
|
|
@ -253,6 +251,12 @@ def main():
|
||||||
out_fmt.add_argument("-N", "-none", "--none", action="store_true",
|
out_fmt.add_argument("-N", "-none", "--none", action="store_true",
|
||||||
help="Do not output documentation, only warnings.")
|
help="Do not output documentation, only warnings.")
|
||||||
|
|
||||||
|
out_fmt.add_argument("-y", "--yaml-file", "--yaml",
|
||||||
|
help="Stores kernel-doc output on a yaml file.")
|
||||||
|
out_fmt.add_argument("-k", "--kdoc-item", "--kdoc", action="store_true",
|
||||||
|
help="Store KdocItem inside yaml file. Ued together with --yaml.")
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Output selection mutually-exclusive group
|
# Output selection mutually-exclusive group
|
||||||
#
|
#
|
||||||
|
|
@ -323,14 +327,42 @@ def main():
|
||||||
from kdoc.kdoc_files import KernelFiles # pylint: disable=C0415
|
from kdoc.kdoc_files import KernelFiles # pylint: disable=C0415
|
||||||
from kdoc.kdoc_output import RestFormat, ManFormat # pylint: disable=C0415
|
from kdoc.kdoc_output import RestFormat, ManFormat # pylint: disable=C0415
|
||||||
|
|
||||||
if args.man:
|
yaml_content = set()
|
||||||
out_style = ManFormat(modulename=args.modulename)
|
if args.yaml_file:
|
||||||
elif args.none:
|
|
||||||
out_style = None
|
out_style = None
|
||||||
|
|
||||||
|
if args.man:
|
||||||
|
yaml_content |= {"man"}
|
||||||
|
|
||||||
|
if args.rst:
|
||||||
|
yaml_content |= {"rst"}
|
||||||
|
|
||||||
|
if args.kdoc_item or not yaml_content:
|
||||||
|
yaml_content |= {"KdocItem"}
|
||||||
|
|
||||||
else:
|
else:
|
||||||
out_style = RestFormat()
|
n_outputs = 0
|
||||||
|
|
||||||
|
if args.man:
|
||||||
|
out_style = ManFormat(modulename=args.modulename)
|
||||||
|
n_outputs += 1
|
||||||
|
|
||||||
|
if args.none:
|
||||||
|
out_style = None
|
||||||
|
n_outputs += 1
|
||||||
|
|
||||||
|
if args.rst or n_outputs == 0:
|
||||||
|
n_outputs += 1
|
||||||
|
out_style = RestFormat()
|
||||||
|
|
||||||
|
if n_outputs > 1:
|
||||||
|
parser.error("Those arguments are muttually exclusive: --man, --rst, --none, except when generating a YAML file.")
|
||||||
|
|
||||||
|
elif not n_outputs:
|
||||||
|
out_style = RestFormat()
|
||||||
|
|
||||||
kfiles = KernelFiles(verbose=args.verbose,
|
kfiles = KernelFiles(verbose=args.verbose,
|
||||||
|
yaml_file=args.yaml_file, yaml_content=yaml_content,
|
||||||
out_style=out_style, werror=args.werror,
|
out_style=out_style, werror=args.werror,
|
||||||
wreturn=args.wreturn, wshort_desc=args.wshort_desc,
|
wreturn=args.wreturn, wshort_desc=args.wshort_desc,
|
||||||
wcontents_before_sections=args.wcontents_before_sections)
|
wcontents_before_sections=args.wcontents_before_sections)
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import re
|
||||||
from kdoc.kdoc_parser import KernelDoc
|
from kdoc.kdoc_parser import KernelDoc
|
||||||
from kdoc.xforms_lists import CTransforms
|
from kdoc.xforms_lists import CTransforms
|
||||||
from kdoc.kdoc_output import OutputFormat
|
from kdoc.kdoc_output import OutputFormat
|
||||||
|
from kdoc.kdoc_yaml_file import KDocTestFile
|
||||||
|
|
||||||
|
|
||||||
class GlobSourceFiles:
|
class GlobSourceFiles:
|
||||||
|
|
@ -152,6 +153,12 @@ class KernelFiles():
|
||||||
|
|
||||||
If not specified, defaults to use: ``logging.getLogger("kernel-doc")``
|
If not specified, defaults to use: ``logging.getLogger("kernel-doc")``
|
||||||
|
|
||||||
|
``yaml_file``
|
||||||
|
If defined, stores the output inside a YAML file.
|
||||||
|
|
||||||
|
``yaml_content``
|
||||||
|
Defines what will be inside the YAML file.
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
There are two type of parsers defined here:
|
There are two type of parsers defined here:
|
||||||
|
|
||||||
|
|
@ -181,7 +188,12 @@ class KernelFiles():
|
||||||
if fname in self.files:
|
if fname in self.files:
|
||||||
return
|
return
|
||||||
|
|
||||||
doc = KernelDoc(self.config, fname, self.xforms)
|
if self.test_file:
|
||||||
|
store_src = True
|
||||||
|
else:
|
||||||
|
store_src = False
|
||||||
|
|
||||||
|
doc = KernelDoc(self.config, fname, self.xforms, store_src=store_src)
|
||||||
export_table, entries = doc.parse_kdoc()
|
export_table, entries = doc.parse_kdoc()
|
||||||
|
|
||||||
self.export_table[fname] = export_table
|
self.export_table[fname] = export_table
|
||||||
|
|
@ -191,6 +203,10 @@ class KernelFiles():
|
||||||
|
|
||||||
self.results[fname] = entries
|
self.results[fname] = entries
|
||||||
|
|
||||||
|
source = doc.get_source()
|
||||||
|
if source:
|
||||||
|
self.source[fname] = source
|
||||||
|
|
||||||
def process_export_file(self, fname):
|
def process_export_file(self, fname):
|
||||||
"""
|
"""
|
||||||
Parses ``EXPORT_SYMBOL*`` macros from a single Kernel source file.
|
Parses ``EXPORT_SYMBOL*`` macros from a single Kernel source file.
|
||||||
|
|
@ -220,7 +236,7 @@ class KernelFiles():
|
||||||
def __init__(self, verbose=False, out_style=None, xforms=None,
|
def __init__(self, verbose=False, out_style=None, xforms=None,
|
||||||
werror=False, wreturn=False, wshort_desc=False,
|
werror=False, wreturn=False, wshort_desc=False,
|
||||||
wcontents_before_sections=False,
|
wcontents_before_sections=False,
|
||||||
logger=None):
|
yaml_file=None, yaml_content=None, logger=None):
|
||||||
"""
|
"""
|
||||||
Initialize startup variables and parse all files.
|
Initialize startup variables and parse all files.
|
||||||
"""
|
"""
|
||||||
|
|
@ -259,6 +275,11 @@ class KernelFiles():
|
||||||
# Override log warning, as we want to count errors
|
# Override log warning, as we want to count errors
|
||||||
self.config.warning = self.warning
|
self.config.warning = self.warning
|
||||||
|
|
||||||
|
if yaml_file:
|
||||||
|
self.test_file = KDocTestFile(self.config, yaml_file, yaml_content)
|
||||||
|
else:
|
||||||
|
self.test_file = None
|
||||||
|
|
||||||
if xforms:
|
if xforms:
|
||||||
self.xforms = xforms
|
self.xforms = xforms
|
||||||
else:
|
else:
|
||||||
|
|
@ -273,6 +294,7 @@ class KernelFiles():
|
||||||
|
|
||||||
self.errors = 0
|
self.errors = 0
|
||||||
self.results = {}
|
self.results = {}
|
||||||
|
self.source = {}
|
||||||
|
|
||||||
self.files = set()
|
self.files = set()
|
||||||
self.export_files = set()
|
self.export_files = set()
|
||||||
|
|
@ -331,16 +353,29 @@ class KernelFiles():
|
||||||
for s in symbol:
|
for s in symbol:
|
||||||
function_table.add(s)
|
function_table.add(s)
|
||||||
|
|
||||||
self.out_style.set_filter(export, internal, symbol, nosymbol,
|
|
||||||
function_table, enable_lineno,
|
|
||||||
no_doc_sections)
|
|
||||||
|
|
||||||
if fname not in self.results:
|
if fname not in self.results:
|
||||||
self.config.log.warning("No kernel-doc for file %s", fname)
|
self.config.log.warning("No kernel-doc for file %s", fname)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
symbols = self.results[fname]
|
symbols = self.results[fname]
|
||||||
|
|
||||||
|
if self.test_file:
|
||||||
|
self.test_file.set_filter(export, internal, symbol, nosymbol,
|
||||||
|
function_table, enable_lineno,
|
||||||
|
no_doc_sections)
|
||||||
|
|
||||||
|
self.test_file.output_symbols(fname, symbols,
|
||||||
|
self.source.get(fname))
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
|
self.out_style.set_filter(export, internal, symbol, nosymbol,
|
||||||
|
function_table, enable_lineno,
|
||||||
|
no_doc_sections)
|
||||||
|
|
||||||
msg = self.out_style.output_symbols(fname, symbols)
|
msg = self.out_style.output_symbols(fname, symbols)
|
||||||
if msg:
|
if msg:
|
||||||
yield fname, msg
|
yield fname, msg
|
||||||
|
|
||||||
|
if self.test_file:
|
||||||
|
self.test_file.write()
|
||||||
|
|
|
||||||
|
|
@ -246,12 +246,13 @@ class KernelDoc:
|
||||||
#: String to write when a parameter is not described.
|
#: String to write when a parameter is not described.
|
||||||
undescribed = "-- undescribed --"
|
undescribed = "-- undescribed --"
|
||||||
|
|
||||||
def __init__(self, config, fname, xforms):
|
def __init__(self, config, fname, xforms, store_src=False):
|
||||||
"""Initialize internal variables"""
|
"""Initialize internal variables"""
|
||||||
|
|
||||||
self.fname = fname
|
self.fname = fname
|
||||||
self.config = config
|
self.config = config
|
||||||
self.xforms = xforms
|
self.xforms = xforms
|
||||||
|
self.store_src = store_src
|
||||||
|
|
||||||
tokenizer_set_log(self.config.log, f"{self.fname}: CMatch: ")
|
tokenizer_set_log(self.config.log, f"{self.fname}: CMatch: ")
|
||||||
|
|
||||||
|
|
@ -264,6 +265,9 @@ class KernelDoc:
|
||||||
# Place all potential outputs into an array
|
# Place all potential outputs into an array
|
||||||
self.entries = []
|
self.entries = []
|
||||||
|
|
||||||
|
# When store_src is true, the kernel-doc source content is stored here
|
||||||
|
self.source = None
|
||||||
|
|
||||||
#
|
#
|
||||||
# We need Python 3.7 for its "dicts remember the insertion
|
# We need Python 3.7 for its "dicts remember the insertion
|
||||||
# order" guarantee
|
# order" guarantee
|
||||||
|
|
@ -1592,6 +1596,15 @@ class KernelDoc:
|
||||||
state.DOCBLOCK: process_docblock,
|
state.DOCBLOCK: process_docblock,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def get_source(self):
|
||||||
|
"""
|
||||||
|
Return the file content of the lines handled by kernel-doc at the
|
||||||
|
latest parse_kdoc() run.
|
||||||
|
|
||||||
|
Returns none if KernelDoc() was not initialized with store_src,
|
||||||
|
"""
|
||||||
|
return self.source
|
||||||
|
|
||||||
def parse_kdoc(self):
|
def parse_kdoc(self):
|
||||||
"""
|
"""
|
||||||
Open and process each line of a C source file.
|
Open and process each line of a C source file.
|
||||||
|
|
@ -1605,6 +1618,8 @@ class KernelDoc:
|
||||||
prev = ""
|
prev = ""
|
||||||
prev_ln = None
|
prev_ln = None
|
||||||
export_table = set()
|
export_table = set()
|
||||||
|
self.source = []
|
||||||
|
self.state = state.NORMAL
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(self.fname, "r", encoding="utf8",
|
with open(self.fname, "r", encoding="utf8",
|
||||||
|
|
@ -1631,6 +1646,8 @@ class KernelDoc:
|
||||||
ln, state.name[self.state],
|
ln, state.name[self.state],
|
||||||
line)
|
line)
|
||||||
|
|
||||||
|
prev_state = self.state
|
||||||
|
|
||||||
# This is an optimization over the original script.
|
# This is an optimization over the original script.
|
||||||
# There, when export_file was used for the same file,
|
# There, when export_file was used for the same file,
|
||||||
# it was read twice. Here, we use the already-existing
|
# it was read twice. Here, we use the already-existing
|
||||||
|
|
@ -1641,6 +1658,14 @@ class KernelDoc:
|
||||||
# Hand this line to the appropriate state handler
|
# Hand this line to the appropriate state handler
|
||||||
self.state_actions[self.state](self, ln, line)
|
self.state_actions[self.state](self, ln, line)
|
||||||
|
|
||||||
|
if self.store_src and prev_state != self.state or self.state != state.NORMAL:
|
||||||
|
if self.state == state.NAME:
|
||||||
|
# A "/**" was detected. Add a new source element
|
||||||
|
self.source.append({"ln": ln, "data": line + "\n"})
|
||||||
|
else:
|
||||||
|
# Append to the existing one
|
||||||
|
self.source[-1]["data"] += line + "\n"
|
||||||
|
|
||||||
self.emit_unused_warnings()
|
self.emit_unused_warnings()
|
||||||
|
|
||||||
except OSError:
|
except OSError:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue