mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-07 10:29:52 +00:00
docs: sphinx/kernel_abi: reduce buffer usage for ABI messages
Instead of producing a big message with all ABI contents and then parse as a whole, simplify the code by handling each ABI symbol in separate. As an additional benefit, there's no need to place file/line nubers inlined at the data and use a regex to convert them. Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> Signed-off-by: Jonathan Corbet <corbet@lwn.net> Link: https://lore.kernel.org/r/15be22955e3c6df49d7256c8fd24f62b397ad0ff.1739182025.git.mchehab+huawei@kernel.org
This commit is contained in:
committed by
Jonathan Corbet
parent
ee34f8300c
commit
aea5e52dce
@@ -68,6 +68,7 @@ class KernelCmd(Directive):
|
||||
has_content = False
|
||||
final_argument_whitespace = True
|
||||
logger = logging.getLogger('kernel_abi')
|
||||
parser = None
|
||||
|
||||
option_spec = {
|
||||
"debug": directives.flag,
|
||||
@@ -79,59 +80,60 @@ class KernelCmd(Directive):
|
||||
raise self.warning("docutils: file insertion disabled")
|
||||
|
||||
path = os.path.join(srctree, "Documentation", self.arguments[0])
|
||||
parser = AbiParser(path, logger=self.logger)
|
||||
parser.parse_abi()
|
||||
parser.check_issues()
|
||||
self.parser = AbiParser(path, logger=self.logger)
|
||||
self.parser.parse_abi()
|
||||
self.parser.check_issues()
|
||||
|
||||
msg = ""
|
||||
for m in parser.doc(enable_lineno=True, show_file=True):
|
||||
msg += m
|
||||
|
||||
node = self.nested_parse(msg, self.arguments[0])
|
||||
node = self.nested_parse(None, self.arguments[0])
|
||||
return node
|
||||
|
||||
def nested_parse(self, lines, fname):
|
||||
def nested_parse(self, data, fname):
|
||||
env = self.state.document.settings.env
|
||||
content = ViewList()
|
||||
node = nodes.section()
|
||||
|
||||
if "debug" in self.options:
|
||||
code_block = "\n\n.. code-block:: rst\n :linenos:\n"
|
||||
for line in lines.split("\n"):
|
||||
code_block += "\n " + line
|
||||
lines = code_block + "\n\n"
|
||||
if data is not None:
|
||||
# Handles the .rst file
|
||||
for line in data.split("\n"):
|
||||
content.append(line, fname, 0)
|
||||
|
||||
line_regex = re.compile(r"^\.\. LINENO (\S+)\#([0-9]+)$")
|
||||
ln = 0
|
||||
n = 0
|
||||
f = fname
|
||||
|
||||
for line in lines.split("\n"):
|
||||
n = n + 1
|
||||
match = line_regex.search(line)
|
||||
if match:
|
||||
new_f = match.group(1)
|
||||
|
||||
# Sphinx parser is lazy: it stops parsing contents in the
|
||||
# middle, if it is too big. So, handle it per input file
|
||||
if new_f != f and content:
|
||||
self.do_parse(content, node)
|
||||
content = ViewList()
|
||||
|
||||
else:
|
||||
# Handles the ABI parser content, symbol by symbol
|
||||
|
||||
old_f = fname
|
||||
n = 0
|
||||
for msg, f, ln in self.parser.doc():
|
||||
msg_list = msg.split("\n")
|
||||
if "debug" in self.options:
|
||||
lines = [
|
||||
"", "", ".. code-block:: rst",
|
||||
" :linenos:", ""
|
||||
]
|
||||
for m in msg_list:
|
||||
lines.append(" " + m)
|
||||
else:
|
||||
lines = msg_list
|
||||
|
||||
for line in lines:
|
||||
# sphinx counts lines from 0
|
||||
content.append(line, f, ln - 1)
|
||||
n += 1
|
||||
|
||||
if f != old_f:
|
||||
# Add the file to Sphinx build dependencies
|
||||
env.note_dependency(os.path.abspath(f))
|
||||
|
||||
f = new_f
|
||||
|
||||
# sphinx counts lines from 0
|
||||
ln = int(match.group(2)) - 1
|
||||
else:
|
||||
content.append(line, f, ln)
|
||||
|
||||
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()
|
||||
|
||||
self.logger.info("%s: parsed %i lines" % (fname, n))
|
||||
|
||||
return node.children
|
||||
|
||||
|
||||
@@ -63,8 +63,11 @@ class AbiRest:
|
||||
parser.parse_abi()
|
||||
parser.check_issues()
|
||||
|
||||
for msg in parser.doc(args.enable_lineno, args.raw, not args.no_file):
|
||||
print(msg)
|
||||
for t in parser.doc(args.raw, not args.no_file):
|
||||
if args.enable_lineno:
|
||||
print (f".. LINENO {t[1]}#{t[2]}\n\n")
|
||||
|
||||
print(t[0])
|
||||
|
||||
class AbiValidate:
|
||||
"""Initialize an argparse subparser for ABI validation"""
|
||||
|
||||
@@ -427,7 +427,7 @@ class AbiParser:
|
||||
|
||||
return new_desc + "\n\n"
|
||||
|
||||
def doc(self, enable_lineno, output_in_txt=False, show_file=False):
|
||||
def doc(self, output_in_txt=False, show_file=True):
|
||||
"""Print ABI at stdout"""
|
||||
|
||||
part = None
|
||||
@@ -444,10 +444,6 @@ class AbiParser:
|
||||
|
||||
msg = ""
|
||||
|
||||
if enable_lineno:
|
||||
ln = v.get("line_no", 1)
|
||||
msg += f".. LINENO {file_ref[0][0]}#{ln}\n\n"
|
||||
|
||||
if wtype != "File":
|
||||
cur_part = names[0]
|
||||
if cur_part.find("/") >= 0:
|
||||
@@ -508,7 +504,9 @@ class AbiParser:
|
||||
if users and users.strip(" \t\n"):
|
||||
msg += f"Users:\n\t{users.strip("\n").replace('\n', '\n\t')}\n\n"
|
||||
|
||||
yield msg
|
||||
ln = v.get("line_no", 1)
|
||||
|
||||
yield (msg, file_ref[0][0], ln)
|
||||
|
||||
def check_issues(self):
|
||||
"""Warn about duplicated ABI entries"""
|
||||
|
||||
Reference in New Issue
Block a user