Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / Documentation / sphinx / kernel_abi.py
blob5911bd0d7965713a4905db331818c57d23dadb73
1 # -*- coding: utf-8; mode: python -*-
2 # coding=utf-8
3 # SPDX-License-Identifier: GPL-2.0
5 u"""
6 kernel-abi
7 ~~~~~~~~~~
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.
21 .. code-block:: rst
23 .. kernel-abi:: <ABI directory location>
24 :debug:
26 The argument ``<ABI directory location>`` is required. It contains the
27 location of the ABI files to be parsed.
29 ``debug``
30 Inserts a code-block with the *raw* reST. Sometimes it is helpful to see
31 what reST is generated.
33 """
35 import codecs
36 import os
37 import subprocess
38 import sys
39 import re
40 import kernellog
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
48 __version__ = '1.0'
50 def setup(app):
52 app.add_directive("kernel-abi", KernelCmd)
53 return dict(
54 version = __version__
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
65 has_content = False
66 final_argument_whitespace = True
68 option_spec = {
69 "debug" : directives.flag,
70 "rst" : directives.unchanged
73 def run(self):
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"])
80 args = [
81 os.path.join(srctree, 'scripts/get_abi.pl'),
82 'rest',
83 '--enable-lineno',
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])
92 return nodeList
94 def nestedParse(self, lines, fname):
95 env = self.state.document.settings.env
96 content = ViewList()
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]+)$")
106 ln = 0
107 n = 0
108 f = fname
110 for line in lines.split("\n"):
111 n = n + 1
112 match = line_regex.search(line)
113 if match:
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)
120 content = ViewList()
122 # Add the file to Sphinx build dependencies
123 env.note_dependency(os.path.abspath(f))
125 f = new_f
127 # sphinx counts lines from 0
128 ln = int(match.group(2)) - 1
129 else:
130 content.append(line, f, ln)
132 kernellog.info(self.state.document.settings.env.app, "%s: parsed %i lines" % (fname, n))
134 if content:
135 self.do_parse(content, node)
137 return node.children
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)