docs: sphinx/kernel_abi: parse ABI files only once
Right now, the logic parses ABI files on 4 steps, one for each directory. While this is fine in principle, by doing that, not all symbol cross-references will be created. Change the logic to do the parsing only once in order to get a global dictionary to be used when creating ABI cross-references. Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> Signed-off-by: Jonathan Corbet <corbet@lwn.net> Link: https://lore.kernel.org/r/5205c53838b6ea25f4cdd4cc1e3d17c0141e75a6.1739182025.git.mchehab+huawei@kernel.orgpull/1183/head
parent
98a4324a8b
commit
5d7871d77f
|
|
@ -9,4 +9,4 @@ marked to be removed at some later point in time.
|
|||
The description of the interface will document the reason why it is
|
||||
obsolete and when it can be expected to be removed.
|
||||
|
||||
.. kernel-abi:: ABI/obsolete
|
||||
.. kernel-abi:: obsolete
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@
|
|||
ABI removed symbols
|
||||
===================
|
||||
|
||||
.. kernel-abi:: ABI/removed
|
||||
.. kernel-abi:: removed
|
||||
|
|
|
|||
|
|
@ -12,4 +12,4 @@ for at least 2 years.
|
|||
Most interfaces (like syscalls) are expected to never change and always
|
||||
be available.
|
||||
|
||||
.. kernel-abi:: ABI/stable
|
||||
.. kernel-abi:: stable
|
||||
|
|
|
|||
|
|
@ -18,4 +18,4 @@ Programs that use these interfaces are strongly encouraged to add their
|
|||
name to the description of these interfaces, so that the kernel
|
||||
developers can easily notify them if any changes occur.
|
||||
|
||||
.. kernel-abi:: ABI/testing
|
||||
.. kernel-abi:: testing
|
||||
|
|
|
|||
|
|
@ -49,6 +49,13 @@ from abi_parser import AbiParser
|
|||
|
||||
__version__ = "1.0"
|
||||
|
||||
logger = logging.getLogger('kernel_abi')
|
||||
path = os.path.join(srctree, "Documentation/ABI")
|
||||
|
||||
# Parse ABI symbols only once
|
||||
kernel_abi = AbiParser(path, logger=logger)
|
||||
kernel_abi.parse_abi()
|
||||
kernel_abi.check_issues()
|
||||
|
||||
def setup(app):
|
||||
|
||||
|
|
@ -64,14 +71,15 @@ class KernelCmd(Directive):
|
|||
u"""KernelABI (``kernel-abi``) directive"""
|
||||
|
||||
required_arguments = 1
|
||||
optional_arguments = 2
|
||||
optional_arguments = 3
|
||||
has_content = False
|
||||
final_argument_whitespace = True
|
||||
logger = logging.getLogger('kernel_abi')
|
||||
parser = None
|
||||
|
||||
option_spec = {
|
||||
"debug": directives.flag,
|
||||
"no-symbols": directives.flag,
|
||||
"no-files": directives.flag,
|
||||
}
|
||||
|
||||
def run(self):
|
||||
|
|
@ -79,62 +87,67 @@ class KernelCmd(Directive):
|
|||
if not doc.settings.file_insertion_enabled:
|
||||
raise self.warning("docutils: file insertion disabled")
|
||||
|
||||
path = os.path.join(srctree, "Documentation", self.arguments[0])
|
||||
self.parser = AbiParser(path, logger=self.logger)
|
||||
self.parser.parse_abi()
|
||||
self.parser.check_issues()
|
||||
|
||||
node = self.nested_parse(None, self.arguments[0])
|
||||
return node
|
||||
|
||||
def nested_parse(self, data, fname):
|
||||
env = self.state.document.settings.env
|
||||
content = ViewList()
|
||||
node = nodes.section()
|
||||
|
||||
if data is not None:
|
||||
# Handles the .rst file
|
||||
for line in data.split("\n"):
|
||||
content.append(line, fname, 0)
|
||||
|
||||
self.do_parse(content, node)
|
||||
abi_type = self.arguments[0]
|
||||
|
||||
if "no-symbols" in self.options:
|
||||
show_symbols = False
|
||||
else:
|
||||
# Handles the ABI parser content, symbol by symbol
|
||||
show_symbols = True
|
||||
|
||||
old_f = fname
|
||||
n = 0
|
||||
for msg, f, ln in self.parser.doc():
|
||||
msg_list = statemachine.string2lines(msg, tab_width,
|
||||
convert_whitespace=True)
|
||||
if "debug" in self.options:
|
||||
lines = [
|
||||
"", "", ".. code-block:: rst",
|
||||
" :linenos:", ""
|
||||
]
|
||||
for m in msg_list:
|
||||
lines.append(" " + m)
|
||||
else:
|
||||
lines = msg_list
|
||||
if "no-files" in self.options:
|
||||
show_file = False
|
||||
else:
|
||||
show_file = True
|
||||
|
||||
for line in lines:
|
||||
# sphinx counts lines from 0
|
||||
content.append(line, f, ln - 1)
|
||||
n += 1
|
||||
tab_width = self.options.get('tab-width',
|
||||
self.state.document.settings.tab_width)
|
||||
|
||||
if f != old_f:
|
||||
# Add the file to Sphinx build dependencies
|
||||
env.note_dependency(os.path.abspath(f))
|
||||
old_f = None
|
||||
n = 0
|
||||
n_sym = 0
|
||||
for msg, f, ln in kernel_abi.doc(show_file=show_file,
|
||||
show_symbols=show_symbols,
|
||||
filter_path=abi_type):
|
||||
n_sym += 1
|
||||
msg_list = statemachine.string2lines(msg, tab_width,
|
||||
convert_whitespace=True)
|
||||
if "debug" in self.options:
|
||||
lines = [
|
||||
"", "", ".. code-block:: rst",
|
||||
" :linenos:", ""
|
||||
]
|
||||
for m in msg_list:
|
||||
lines.append(" " + m)
|
||||
else:
|
||||
lines = msg_list
|
||||
|
||||
old_f = f
|
||||
for line in lines:
|
||||
# sphinx counts lines from 0
|
||||
content.append(line, f, ln - 1)
|
||||
n += 1
|
||||
|
||||
# Sphinx doesn't like to parse big messages. So, let's
|
||||
# add content symbol by symbol
|
||||
if content:
|
||||
self.do_parse(content, node)
|
||||
content = ViewList()
|
||||
if f != old_f:
|
||||
# Add the file to Sphinx build dependencies
|
||||
env.note_dependency(os.path.abspath(f))
|
||||
|
||||
self.logger.info("%s: parsed %i lines" % (fname, n))
|
||||
old_f = f
|
||||
|
||||
# Sphinx doesn't like to parse big messages. So, let's
|
||||
# add content symbol by symbol
|
||||
if content:
|
||||
self.do_parse(content, node)
|
||||
content = ViewList()
|
||||
|
||||
if show_symbols and not show_file:
|
||||
logger.verbose("%s ABI: %i symbols (%i ReST lines)" % (abi_type, n_sym, n))
|
||||
elif not show_symbols and show_file:
|
||||
logger.verbose("%s ABI: %i files (%i ReST lines)" % (abi_type, n_sym, n))
|
||||
else:
|
||||
logger.verbose("%s ABI: %i data (%i ReST lines)" % (abi_type, n_sym, n))
|
||||
|
||||
return node.children
|
||||
|
||||
|
|
|
|||
|
|
@ -266,12 +266,20 @@ class AbiParser:
|
|||
def parse_readme(self, nametag, fname):
|
||||
"""Parse ABI README file"""
|
||||
|
||||
nametag["what"] = ["ABI file contents"]
|
||||
nametag["path"] = "README"
|
||||
with open(fname, "r", encoding="utf8", errors="backslashreplace") as fp:
|
||||
nametag["description"] = "```\n"
|
||||
for line in fp:
|
||||
nametag["description"] += " " + line
|
||||
match = self.re_tag.match(line)
|
||||
if match:
|
||||
new = match.group(1).lower()
|
||||
|
||||
nametag["description"] += "```\n"
|
||||
match = self.re_valid.search(new)
|
||||
if match:
|
||||
nametag["description"] += "\n:" + line
|
||||
continue
|
||||
|
||||
nametag["description"] += line
|
||||
|
||||
def parse_file(self, fname, path, basename):
|
||||
"""Parse a single file"""
|
||||
|
|
@ -459,12 +467,8 @@ class AbiParser:
|
|||
continue
|
||||
|
||||
if filter_path:
|
||||
if filter_path == "README":
|
||||
if not names[0].endswith("README"):
|
||||
continue
|
||||
else:
|
||||
if v.get("path") != filter_path:
|
||||
continue
|
||||
if v.get("path") != filter_path:
|
||||
continue
|
||||
|
||||
msg = ""
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue