Files
linux/Documentation/sphinx/kernel_abi.py
Mauro Carvalho Chehab 9d7ec88679 docs: use get_abi.py for ABI generation
Use the new script instead of the old one when generating ABI docs.

For now, execute it via exec. Future changes will better integrate it
by using the class defined there directly.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Link: https://lore.kernel.org/r/e7fcb121c0612c94f6f54f0d742cd3a26a46cd7d.1739182025.git.mchehab+huawei@kernel.org
2025-02-10 11:19:56 -07:00

138 lines
3.9 KiB
Python

# -*- coding: utf-8; mode: python -*-
# coding=utf-8
# SPDX-License-Identifier: GPL-2.0
#
u"""
kernel-abi
~~~~~~~~~~
Implementation of the ``kernel-abi`` reST-directive.
:copyright: Copyright (C) 2016 Markus Heiser
:copyright: Copyright (C) 2016-2020 Mauro Carvalho Chehab
:maintained-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
:license: GPL Version 2, June 1991 see Linux/COPYING for details.
The ``kernel-abi`` (:py:class:`KernelCmd`) directive calls the
scripts/get_abi.py script to parse the Kernel ABI files.
Overview of directive's argument and options.
.. code-block:: rst
.. kernel-abi:: <ABI directory location>
:debug:
The argument ``<ABI directory location>`` is required. It contains the
location of the ABI files to be parsed.
``debug``
Inserts a code-block with the *raw* reST. Sometimes it is helpful to see
what reST is generated.
"""
import os
import re
import subprocess
import sys
from docutils import nodes
from docutils.statemachine import ViewList
from docutils.parsers.rst import directives, Directive
from sphinx.util.docutils import switch_source_input
from sphinx.util import logging
__version__ = "1.0"
def setup(app):
app.add_directive("kernel-abi", KernelCmd)
return {
"version": __version__,
"parallel_read_safe": True,
"parallel_write_safe": True
}
class KernelCmd(Directive):
u"""KernelABI (``kernel-abi``) directive"""
required_arguments = 1
optional_arguments = 2
has_content = False
final_argument_whitespace = True
logger = logging.getLogger('kernel_abi')
option_spec = {
"debug" : directives.flag,
}
def run(self):
doc = self.state.document
if not doc.settings.file_insertion_enabled:
raise self.warning("docutils: file insertion disabled")
srctree = os.path.abspath(os.environ["srctree"])
args = [
os.path.join(srctree, 'scripts/get_abi.py'),
'-D', os.path.join(srctree, 'Documentation', self.arguments[0]),
'rest',
'--enable-lineno',
]
lines = subprocess.check_output(args, cwd=os.path.dirname(doc.current_source)).decode('utf-8')
nodeList = self.nestedParse(lines, self.arguments[0])
return nodeList
def nestedParse(self, lines, 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"
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()
# 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))
if content:
self.do_parse(content, node)
return node.children
def do_parse(self, content, node):
with switch_source_input(self.state, content):
self.state.nested_parse(content, 0, node, match_titles=1)