Blame view
Documentation/sphinx/kernel_abi.py
5.6 KB
9ca876f96
|
1 |
# -*- coding: utf-8; mode: python -*- |
823830d40
|
2 |
# coding=utf-8 |
9ca876f96
|
3 |
# SPDX-License-Identifier: GPL-2.0 |
823830d40
|
4 |
# |
9ca876f96
|
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
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.pl 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. """ |
823830d40
|
34 |
import codecs |
9ca876f96
|
35 |
import os |
9ca876f96
|
36 |
import subprocess |
c830fa9a4
|
37 |
import sys |
997b7c8b4
|
38 |
import re |
3c543d298
|
39 |
import kernellog |
9ca876f96
|
40 |
|
c830fa9a4
|
41 |
from os import path |
9ca876f96
|
42 |
|
c830fa9a4
|
43 |
from docutils import nodes, statemachine |
9ca876f96
|
44 |
from docutils.statemachine import ViewList |
c830fa9a4
|
45 |
from docutils.parsers.rst import directives, Directive |
9ca876f96
|
46 |
from docutils.utils.error_reporting import ErrorString |
c830fa9a4
|
47 48 49 50 51 52 53 54 55 56 |
# # AutodocReporter is only good up to Sphinx 1.7 # import sphinx Use_SSI = sphinx.__version__[:3] >= '1.7' if Use_SSI: from sphinx.util.docutils import switch_source_input else: from sphinx.ext.autodoc import AutodocReporter |
9ca876f96
|
57 58 |
__version__ = '1.0' |
9ca876f96
|
59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
def setup(app): app.add_directive("kernel-abi", KernelCmd) return dict( version = __version__ , parallel_read_safe = True , parallel_write_safe = True ) class KernelCmd(Directive): u"""KernelABI (``kernel-abi``) directive""" required_arguments = 1 |
642514df1
|
73 |
optional_arguments = 2 |
9ca876f96
|
74 75 76 77 |
has_content = False final_argument_whitespace = True option_spec = { |
642514df1
|
78 79 |
"debug" : directives.flag, "rst" : directives.unchanged |
9ca876f96
|
80 |
} |
9ca876f96
|
81 82 83 84 85 86 87 88 |
def run(self): doc = self.state.document if not doc.settings.file_insertion_enabled: raise self.warning("docutils: file insertion disabled") env = doc.settings.env cwd = path.dirname(doc.current_source) |
997b7c8b4
|
89 |
cmd = "get_abi.pl rest --enable-lineno --dir " |
9ca876f96
|
90 |
cmd += self.arguments[0] |
642514df1
|
91 92 |
if 'rst' in self.options: cmd += " --rst-source" |
9ca876f96
|
93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
srctree = path.abspath(os.environ["srctree"]) fname = cmd # extend PATH with $(srctree)/scripts path_env = os.pathsep.join([ srctree + os.sep + "scripts", os.environ["PATH"] ]) shell_env = os.environ.copy() shell_env["PATH"] = path_env shell_env["srctree"] = srctree lines = self.runCmd(cmd, shell=True, cwd=cwd, env=shell_env) |
3c543d298
|
107 |
nodeList = self.nestedParse(lines, self.arguments[0]) |
9ca876f96
|
108 109 110 111 112 113 114 115 116 117 |
return nodeList def runCmd(self, cmd, **kwargs): u"""Run command ``cmd`` and return it's stdout as unicode.""" try: proc = subprocess.Popen( cmd , stdout = subprocess.PIPE , stderr = subprocess.PIPE |
9ca876f96
|
118 119 120 |
, **kwargs ) out, err = proc.communicate() |
823830d40
|
121 122 |
out, err = codecs.decode(out, 'utf-8'), codecs.decode(err, 'utf-8') |
9ca876f96
|
123 124 125 126 127 128 129 130 |
if proc.returncode != 0: raise self.severe( u"command '%s' failed with return code %d" % (cmd, proc.returncode) ) except OSError as exc: raise self.severe(u"problems with '%s' directive: %s." % (self.name, ErrorString(exc))) |
823830d40
|
131 |
return out |
9ca876f96
|
132 |
|
3c543d298
|
133 |
def nestedParse(self, lines, fname): |
9ca876f96
|
134 |
content = ViewList() |
3c543d298
|
135 |
node = nodes.section() |
9ca876f96
|
136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
if "debug" in self.options: code_block = " .. code-block:: rst :linenos: " for l in lines.split(" "): code_block += " " + l lines = code_block + " " |
997b7c8b4
|
150 151 |
line_regex = re.compile("^#define LINENO (\S+)\#([0-9]+)$") ln = 0 |
3c543d298
|
152 153 |
n = 0 f = fname |
997b7c8b4
|
154 155 156 |
for line in lines.split(" "): |
3c543d298
|
157 |
n = n + 1 |
997b7c8b4
|
158 159 |
match = line_regex.search(line) if match: |
3c543d298
|
160 161 162 163 164 165 166 167 168 |
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() f = new_f |
997b7c8b4
|
169 170 171 172 |
# sphinx counts lines from 0 ln = int(match.group(2)) - 1 else: content.append(line, f, ln) |
9ca876f96
|
173 |
|
3c543d298
|
174 175 176 177 |
kernellog.info(self.state.document.settings.env.app, "%s: parsed %i lines" % (fname, n)) if content: self.do_parse(content, node) |
c830fa9a4
|
178 |
|
3c543d298
|
179 180 181 |
return node.children def do_parse(self, content, node): |
c830fa9a4
|
182 183 184 185 |
if Use_SSI: with switch_source_input(self.state, content): self.state.nested_parse(content, 0, node, match_titles=1) else: |
3c543d298
|
186 |
buf = self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter |
c830fa9a4
|
187 188 189 190 191 192 193 |
self.state.memo.title_styles = [] self.state.memo.section_level = 0 self.state.memo.reporter = AutodocReporter(content, self.state.memo.reporter) try: self.state.nested_parse(content, 0, node, match_titles=1) finally: self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter = buf |