1 # -*- coding: utf-8; mode: python -*-
3 # SPDX-License-Identifier: GPL-2.0
9 Implementation of the ``kernel-abi`` reST-directive.
11 :copyright: Copyright (C) 2016 Markus Heiser
12 :copyright: Copyright (C) 2016-2020 Mauro Carvalho Chehab
13 :maintained-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
14 :license: GPL Version 2, June 1991 see Linux/COPYING for details.
16 The ``kernel-abi`` (:py:class:`KernelCmd`) directive calls the
17 scripts/get_abi.pl script to parse the Kernel ABI files.
19 Overview of directive's argument and options.
23 .. kernel-abi:: <ABI directory location>
26 The argument ``<ABI directory location>`` is required. It contains the
27 location of the ABI files to be parsed.
30 Inserts a code-block with the *raw* reST. Sometimes it is helpful to see
31 what reST is generated.
42 from docutils import nodes, statemachine
43 from docutils.statemachine import ViewList
44 from docutils.parsers.rst import directives, Directive
45 from docutils.utils.error_reporting import ErrorString
46 from sphinx.util.docutils import switch_source_input
52 app.add_directive("kernel-abi", KernelCmd)
55 , parallel_read_safe = True
56 , parallel_write_safe = True
59 class KernelCmd(Directive):
61 u"""KernelABI (``kernel-abi``) directive"""
63 required_arguments = 1
64 optional_arguments = 2
66 final_argument_whitespace = True
69 "debug" : directives.flag,
70 "rst" : directives.unchanged
74 doc = self.state.document
75 if not doc.settings.file_insertion_enabled:
76 raise self.warning("docutils: file insertion disabled")
78 srctree = os.path.abspath(os.environ["srctree"])
81 os.path.join(srctree, 'scripts/get_abi.pl'),
84 '--dir', os.path.join(srctree, 'Documentation', self.arguments[0]),
87 if 'rst' in self.options:
88 args.append('--rst-source')
90 lines = subprocess.check_output(args, cwd=os.path.dirname(doc.current_source)).decode('utf-8')
91 nodeList = self.nestedParse(lines, self.arguments[0])
94 def nestedParse(self, lines, fname):
95 env = self.state.document.settings.env
97 node = nodes.section()
99 if "debug" in self.options:
100 code_block = "\n\n.. code-block:: rst\n :linenos:\n"
101 for l in lines.split("\n"):
102 code_block += "\n " + l
103 lines = code_block + "\n\n"
105 line_regex = re.compile(r"^\.\. LINENO (\S+)\#([0-9]+)$")
110 for line in lines.split("\n"):
112 match = line_regex.search(line)
114 new_f = match.group(1)
116 # Sphinx parser is lazy: it stops parsing contents in the
117 # middle, if it is too big. So, handle it per input file
118 if new_f != f and content:
119 self.do_parse(content, node)
122 # Add the file to Sphinx build dependencies
123 env.note_dependency(os.path.abspath(f))
127 # sphinx counts lines from 0
128 ln = int(match.group(2)) - 1
130 content.append(line, f, ln)
132 kernellog.info(self.state.document.settings.env.app, "%s: parsed %i lines" % (fname, n))
135 self.do_parse(content, node)
139 def do_parse(self, content, node):
140 with switch_source_input(self.state, content):
141 self.state.nested_parse(content, 0, node, match_titles=1)