134 lines · python
1# coding=utf-82# SPDX-License-Identifier: GPL-2.03#4u"""5 kernel-feat6 ~~~~~~~~~~~7 8 Implementation of the ``kernel-feat`` reST-directive.9 10 :copyright: Copyright (C) 2016 Markus Heiser11 :copyright: Copyright (C) 2016-2019 Mauro Carvalho Chehab12 :maintained-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>13 :license: GPL Version 2, June 1991 see Linux/COPYING for details.14 15 The ``kernel-feat`` (:py:class:`KernelFeat`) directive calls the16 scripts/get_feat.pl script to parse the Kernel ABI files.17 18 Overview of directive's argument and options.19 20 .. code-block:: rst21 22 .. kernel-feat:: <ABI directory location>23 :debug:24 25 The argument ``<ABI directory location>`` is required. It contains the26 location of the ABI files to be parsed.27 28 ``debug``29 Inserts a code-block with the *raw* reST. Sometimes it is helpful to see30 what reST is generated.31 32"""33 34import codecs35import os36import re37import subprocess38import sys39 40from docutils import nodes, statemachine41from docutils.statemachine import ViewList42from docutils.parsers.rst import directives, Directive43from docutils.utils.error_reporting import ErrorString44from sphinx.util.docutils import switch_source_input45 46__version__ = '1.0'47 48def setup(app):49 50 app.add_directive("kernel-feat", KernelFeat)51 return dict(52 version = __version__53 , parallel_read_safe = True54 , parallel_write_safe = True55 )56 57class KernelFeat(Directive):58 59 u"""KernelFeat (``kernel-feat``) directive"""60 61 required_arguments = 162 optional_arguments = 263 has_content = False64 final_argument_whitespace = True65 66 option_spec = {67 "debug" : directives.flag68 }69 70 def warn(self, message, **replace):71 replace["fname"] = self.state.document.current_source72 replace["line_no"] = replace.get("line_no", self.lineno)73 message = ("%(fname)s:%(line_no)s: [kernel-feat WARN] : " + message) % replace74 self.state.document.settings.env.app.warn(message, prefix="")75 76 def run(self):77 doc = self.state.document78 if not doc.settings.file_insertion_enabled:79 raise self.warning("docutils: file insertion disabled")80 81 env = doc.settings.env82 83 srctree = os.path.abspath(os.environ["srctree"])84 85 args = [86 os.path.join(srctree, 'scripts/get_feat.pl'),87 'rest',88 '--enable-fname',89 '--dir',90 os.path.join(srctree, 'Documentation', self.arguments[0]),91 ]92 93 if len(self.arguments) > 1:94 args.extend(['--arch', self.arguments[1]])95 96 lines = subprocess.check_output(args, cwd=os.path.dirname(doc.current_source)).decode('utf-8')97 98 line_regex = re.compile(r"^\.\. FILE (\S+)$")99 100 out_lines = ""101 102 for line in lines.split("\n"):103 match = line_regex.search(line)104 if match:105 fname = match.group(1)106 107 # Add the file to Sphinx build dependencies108 env.note_dependency(os.path.abspath(fname))109 else:110 out_lines += line + "\n"111 112 nodeList = self.nestedParse(out_lines, self.arguments[0])113 return nodeList114 115 def nestedParse(self, lines, fname):116 content = ViewList()117 node = nodes.section()118 119 if "debug" in self.options:120 code_block = "\n\n.. code-block:: rst\n :linenos:\n"121 for l in lines.split("\n"):122 code_block += "\n " + l123 lines = code_block + "\n\n"124 125 for c, l in enumerate(lines.split("\n")):126 content.append(l, fname, c)127 128 buf = self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter129 130 with switch_source_input(self.state, content):131 self.state.nested_parse(content, 0, node, match_titles=1)132 133 return node.children134