WIP FPC-III support
[linux/fpc-iii.git] / Documentation / sphinx / kernel_feat.py
blob2fee04f1dedd885aad9876cb47f50e801acef6c5
1 # coding=utf-8
2 # SPDX-License-Identifier: GPL-2.0
4 u"""
5 kernel-feat
6 ~~~~~~~~~~~
8 Implementation of the ``kernel-feat`` reST-directive.
10 :copyright: Copyright (C) 2016 Markus Heiser
11 :copyright: Copyright (C) 2016-2019 Mauro Carvalho Chehab
12 :maintained-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
13 :license: GPL Version 2, June 1991 see Linux/COPYING for details.
15 The ``kernel-feat`` (:py:class:`KernelFeat`) directive calls the
16 scripts/get_feat.pl script to parse the Kernel ABI files.
18 Overview of directive's argument and options.
20 .. code-block:: rst
22 .. kernel-feat:: <ABI directory location>
23 :debug:
25 The argument ``<ABI directory location>`` is required. It contains the
26 location of the ABI files to be parsed.
28 ``debug``
29 Inserts a code-block with the *raw* reST. Sometimes it is helpful to see
30 what reST is generated.
32 """
34 import codecs
35 import os
36 import subprocess
37 import sys
39 from os import path
41 from docutils import nodes, statemachine
42 from docutils.statemachine import ViewList
43 from docutils.parsers.rst import directives, Directive
44 from docutils.utils.error_reporting import ErrorString
47 # AutodocReporter is only good up to Sphinx 1.7
49 import sphinx
51 Use_SSI = sphinx.__version__[:3] >= '1.7'
52 if Use_SSI:
53 from sphinx.util.docutils import switch_source_input
54 else:
55 from sphinx.ext.autodoc import AutodocReporter
57 __version__ = '1.0'
59 def setup(app):
61 app.add_directive("kernel-feat", KernelFeat)
62 return dict(
63 version = __version__
64 , parallel_read_safe = True
65 , parallel_write_safe = True
68 class KernelFeat(Directive):
70 u"""KernelFeat (``kernel-feat``) directive"""
72 required_arguments = 1
73 optional_arguments = 2
74 has_content = False
75 final_argument_whitespace = True
77 option_spec = {
78 "debug" : directives.flag
81 def warn(self, message, **replace):
82 replace["fname"] = self.state.document.current_source
83 replace["line_no"] = replace.get("line_no", self.lineno)
84 message = ("%(fname)s:%(line_no)s: [kernel-feat WARN] : " + message) % replace
85 self.state.document.settings.env.app.warn(message, prefix="")
87 def run(self):
89 doc = self.state.document
90 if not doc.settings.file_insertion_enabled:
91 raise self.warning("docutils: file insertion disabled")
93 env = doc.settings.env
94 cwd = path.dirname(doc.current_source)
95 cmd = "get_feat.pl rest --dir "
96 cmd += self.arguments[0]
98 if len(self.arguments) > 1:
99 cmd += " --arch " + self.arguments[1]
101 srctree = path.abspath(os.environ["srctree"])
103 fname = cmd
105 # extend PATH with $(srctree)/scripts
106 path_env = os.pathsep.join([
107 srctree + os.sep + "scripts",
108 os.environ["PATH"]
110 shell_env = os.environ.copy()
111 shell_env["PATH"] = path_env
112 shell_env["srctree"] = srctree
114 lines = self.runCmd(cmd, shell=True, cwd=cwd, env=shell_env)
115 nodeList = self.nestedParse(lines, fname)
116 return nodeList
118 def runCmd(self, cmd, **kwargs):
119 u"""Run command ``cmd`` and return it's stdout as unicode."""
121 try:
122 proc = subprocess.Popen(
124 , stdout = subprocess.PIPE
125 , stderr = subprocess.PIPE
126 , **kwargs
128 out, err = proc.communicate()
130 out, err = codecs.decode(out, 'utf-8'), codecs.decode(err, 'utf-8')
132 if proc.returncode != 0:
133 raise self.severe(
134 u"command '%s' failed with return code %d"
135 % (cmd, proc.returncode)
137 except OSError as exc:
138 raise self.severe(u"problems with '%s' directive: %s."
139 % (self.name, ErrorString(exc)))
140 return out
142 def nestedParse(self, lines, fname):
143 content = ViewList()
144 node = nodes.section()
146 if "debug" in self.options:
147 code_block = "\n\n.. code-block:: rst\n :linenos:\n"
148 for l in lines.split("\n"):
149 code_block += "\n " + l
150 lines = code_block + "\n\n"
152 for c, l in enumerate(lines.split("\n")):
153 content.append(l, fname, c)
155 buf = self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter
157 if Use_SSI:
158 with switch_source_input(self.state, content):
159 self.state.nested_parse(content, 0, node, match_titles=1)
160 else:
161 self.state.memo.title_styles = []
162 self.state.memo.section_level = 0
163 self.state.memo.reporter = AutodocReporter(content, self.state.memo.reporter)
164 try:
165 self.state.nested_parse(content, 0, node, match_titles=1)
166 finally:
167 self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter = buf
169 return node.children