2 # SPDX-License-Identifier: GPL-2.0
8 Implementation of the ``kernel-feat`` reST-directive.
10 :copyright: Copyright (C) 2016 Markus Heiser
11 :copyright: Copyright (C) 2016-2019 Mauro Carvalho Chehab
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.
22 .. kernel-feat:: <ABI directory location>
25 The argument ``<ABI directory location>`` is required. It contains the
26 location of the ABI files to be parsed.
29 Inserts a code-block with the *raw* reST. Sometimes it is helpful to see
30 what reST is generated.
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
45 from sphinx.util.docutils import switch_source_input
51 app.add_directive("kernel-feat", KernelFeat)
54 , parallel_read_safe = True
55 , parallel_write_safe = True
58 class KernelFeat(Directive):
60 u"""KernelFeat (``kernel-feat``) directive"""
62 required_arguments = 1
63 optional_arguments = 2
65 final_argument_whitespace = True
68 "debug" : directives.flag
71 def warn(self, message, **replace):
72 replace["fname"] = self.state.document.current_source
73 replace["line_no"] = replace.get("line_no", self.lineno)
74 message = ("%(fname)s:%(line_no)s: [kernel-feat WARN] : " + message) % replace
75 self.state.document.settings.env.app.warn(message, prefix="")
79 doc = self.state.document
80 if not doc.settings.file_insertion_enabled:
81 raise self.warning("docutils: file insertion disabled")
83 env = doc.settings.env
84 cwd = path.dirname(doc.current_source)
85 cmd = "get_feat.pl rest --dir "
86 cmd += self.arguments[0]
88 if len(self.arguments) > 1:
89 cmd += " --arch " + self.arguments[1]
91 srctree = path.abspath(os.environ["srctree"])
95 # extend PATH with $(srctree)/scripts
96 path_env = os.pathsep.join([
97 srctree + os.sep + "scripts",
100 shell_env = os.environ.copy()
101 shell_env["PATH"] = path_env
102 shell_env["srctree"] = srctree
104 lines = self.runCmd(cmd, shell=True, cwd=cwd, env=shell_env)
105 nodeList = self.nestedParse(lines, fname)
108 def runCmd(self, cmd, **kwargs):
109 u"""Run command ``cmd`` and return it's stdout as unicode."""
112 proc = subprocess.Popen(
114 , stdout = subprocess.PIPE
115 , stderr = subprocess.PIPE
118 out, err = proc.communicate()
120 out, err = codecs.decode(out, 'utf-8'), codecs.decode(err, 'utf-8')
122 if proc.returncode != 0:
124 u"command '%s' failed with return code %d"
125 % (cmd, proc.returncode)
127 except OSError as exc:
128 raise self.severe(u"problems with '%s' directive: %s."
129 % (self.name, ErrorString(exc)))
132 def nestedParse(self, lines, fname):
134 node = nodes.section()
136 if "debug" in self.options:
137 code_block = "\n\n.. code-block:: rst\n :linenos:\n"
138 for l in lines.split("\n"):
139 code_block += "\n " + l
140 lines = code_block + "\n\n"
142 for c, l in enumerate(lines.split("\n")):
143 content.append(l, fname, c)
145 buf = self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter
147 with switch_source_input(self.state, content):
148 self.state.nested_parse(content, 0, node, match_titles=1)