mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-07 18:40:10 +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
|
has_content = False
|
||||||
final_argument_whitespace = True
|
final_argument_whitespace = True
|
||||||
logger = logging.getLogger('kernel_abi')
|
logger = logging.getLogger('kernel_abi')
|
||||||
|
parser = None
|
||||||
|
|
||||||
option_spec = {
|
option_spec = {
|
||||||
"debug": directives.flag,
|
"debug": directives.flag,
|
||||||
@@ -79,59 +80,60 @@ class KernelCmd(Directive):
|
|||||||
raise self.warning("docutils: file insertion disabled")
|
raise self.warning("docutils: file insertion disabled")
|
||||||
|
|
||||||
path = os.path.join(srctree, "Documentation", self.arguments[0])
|
path = os.path.join(srctree, "Documentation", self.arguments[0])
|
||||||
parser = AbiParser(path, logger=self.logger)
|
self.parser = AbiParser(path, logger=self.logger)
|
||||||
parser.parse_abi()
|
self.parser.parse_abi()
|
||||||
parser.check_issues()
|
self.parser.check_issues()
|
||||||
|
|
||||||
msg = ""
|
node = self.nested_parse(None, self.arguments[0])
|
||||||
for m in parser.doc(enable_lineno=True, show_file=True):
|
|
||||||
msg += m
|
|
||||||
|
|
||||||
node = self.nested_parse(msg, self.arguments[0])
|
|
||||||
return node
|
return node
|
||||||
|
|
||||||
def nested_parse(self, lines, fname):
|
def nested_parse(self, data, fname):
|
||||||
env = self.state.document.settings.env
|
env = self.state.document.settings.env
|
||||||
content = ViewList()
|
content = ViewList()
|
||||||
node = nodes.section()
|
node = nodes.section()
|
||||||
|
|
||||||
if "debug" in self.options:
|
if data is not None:
|
||||||
code_block = "\n\n.. code-block:: rst\n :linenos:\n"
|
# Handles the .rst file
|
||||||
for line in lines.split("\n"):
|
for line in data.split("\n"):
|
||||||
code_block += "\n " + line
|
content.append(line, fname, 0)
|
||||||
lines = code_block + "\n\n"
|
|
||||||
|
|
||||||
line_regex = re.compile(r"^\.\. LINENO (\S+)\#([0-9]+)$")
|
self.do_parse(content, node)
|
||||||
ln = 0
|
|
||||||
n = 0
|
|
||||||
f = fname
|
|
||||||
|
|
||||||
for line in lines.split("\n"):
|
else:
|
||||||
n = n + 1
|
# Handles the ABI parser content, symbol by symbol
|
||||||
match = line_regex.search(line)
|
|
||||||
if match:
|
|
||||||
new_f = match.group(1)
|
|
||||||
|
|
||||||
# Sphinx parser is lazy: it stops parsing contents in the
|
old_f = fname
|
||||||
# middle, if it is too big. So, handle it per input file
|
n = 0
|
||||||
if new_f != f and content:
|
for msg, f, ln in self.parser.doc():
|
||||||
self.do_parse(content, node)
|
msg_list = msg.split("\n")
|
||||||
content = ViewList()
|
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
|
# Add the file to Sphinx build dependencies
|
||||||
env.note_dependency(os.path.abspath(f))
|
env.note_dependency(os.path.abspath(f))
|
||||||
|
|
||||||
f = new_f
|
old_f = f
|
||||||
|
|
||||||
# sphinx counts lines from 0
|
# Sphinx doesn't like to parse big messages. So, let's
|
||||||
ln = int(match.group(2)) - 1
|
# add content symbol by symbol
|
||||||
else:
|
if content:
|
||||||
content.append(line, f, ln)
|
self.do_parse(content, node)
|
||||||
|
content = ViewList()
|
||||||
|
|
||||||
self.logger.info("%s: parsed %i lines" % (fname, n))
|
self.logger.info("%s: parsed %i lines" % (fname, n))
|
||||||
|
|
||||||
if content:
|
|
||||||
self.do_parse(content, node)
|
|
||||||
|
|
||||||
return node.children
|
return node.children
|
||||||
|
|
||||||
|
|||||||
@@ -63,8 +63,11 @@ class AbiRest:
|
|||||||
parser.parse_abi()
|
parser.parse_abi()
|
||||||
parser.check_issues()
|
parser.check_issues()
|
||||||
|
|
||||||
for msg in parser.doc(args.enable_lineno, args.raw, not args.no_file):
|
for t in parser.doc(args.raw, not args.no_file):
|
||||||
print(msg)
|
if args.enable_lineno:
|
||||||
|
print (f".. LINENO {t[1]}#{t[2]}\n\n")
|
||||||
|
|
||||||
|
print(t[0])
|
||||||
|
|
||||||
class AbiValidate:
|
class AbiValidate:
|
||||||
"""Initialize an argparse subparser for ABI validation"""
|
"""Initialize an argparse subparser for ABI validation"""
|
||||||
|
|||||||
@@ -427,7 +427,7 @@ class AbiParser:
|
|||||||
|
|
||||||
return new_desc + "\n\n"
|
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"""
|
"""Print ABI at stdout"""
|
||||||
|
|
||||||
part = None
|
part = None
|
||||||
@@ -444,10 +444,6 @@ class AbiParser:
|
|||||||
|
|
||||||
msg = ""
|
msg = ""
|
||||||
|
|
||||||
if enable_lineno:
|
|
||||||
ln = v.get("line_no", 1)
|
|
||||||
msg += f".. LINENO {file_ref[0][0]}#{ln}\n\n"
|
|
||||||
|
|
||||||
if wtype != "File":
|
if wtype != "File":
|
||||||
cur_part = names[0]
|
cur_part = names[0]
|
||||||
if cur_part.find("/") >= 0:
|
if cur_part.find("/") >= 0:
|
||||||
@@ -508,7 +504,9 @@ class AbiParser:
|
|||||||
if users and users.strip(" \t\n"):
|
if users and users.strip(" \t\n"):
|
||||||
msg += f"Users:\n\t{users.strip("\n").replace('\n', '\n\t')}\n\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):
|
def check_issues(self):
|
||||||
"""Warn about duplicated ABI entries"""
|
"""Warn about duplicated ABI entries"""
|
||||||
|
|||||||
Reference in New Issue
Block a user