1b9721225SMauro Carvalho Chehab# coding=utf-8 2b9721225SMauro Carvalho Chehab# SPDX-License-Identifier: GPL-2.0 3b9721225SMauro Carvalho Chehab# 4b9721225SMauro Carvalho Chehabu""" 5b9721225SMauro Carvalho Chehab kernel-feat 6b9721225SMauro Carvalho Chehab ~~~~~~~~~~~ 7b9721225SMauro Carvalho Chehab 8b9721225SMauro Carvalho Chehab Implementation of the ``kernel-feat`` reST-directive. 9b9721225SMauro Carvalho Chehab 10b9721225SMauro Carvalho Chehab :copyright: Copyright (C) 2016 Markus Heiser 11b9721225SMauro Carvalho Chehab :copyright: Copyright (C) 2016-2019 Mauro Carvalho Chehab 12b9721225SMauro Carvalho Chehab :maintained-by: Mauro Carvalho Chehab <[email protected]> 13b9721225SMauro Carvalho Chehab :license: GPL Version 2, June 1991 see Linux/COPYING for details. 14b9721225SMauro Carvalho Chehab 15b9721225SMauro Carvalho Chehab The ``kernel-feat`` (:py:class:`KernelFeat`) directive calls the 16b9721225SMauro Carvalho Chehab scripts/get_feat.pl script to parse the Kernel ABI files. 17b9721225SMauro Carvalho Chehab 18b9721225SMauro Carvalho Chehab Overview of directive's argument and options. 19b9721225SMauro Carvalho Chehab 20b9721225SMauro Carvalho Chehab .. code-block:: rst 21b9721225SMauro Carvalho Chehab 22b9721225SMauro Carvalho Chehab .. kernel-feat:: <ABI directory location> 23b9721225SMauro Carvalho Chehab :debug: 24b9721225SMauro Carvalho Chehab 25b9721225SMauro Carvalho Chehab The argument ``<ABI directory location>`` is required. It contains the 26b9721225SMauro Carvalho Chehab location of the ABI files to be parsed. 27b9721225SMauro Carvalho Chehab 28b9721225SMauro Carvalho Chehab ``debug`` 29b9721225SMauro Carvalho Chehab Inserts a code-block with the *raw* reST. Sometimes it is helpful to see 30b9721225SMauro Carvalho Chehab what reST is generated. 31b9721225SMauro Carvalho Chehab 32b9721225SMauro Carvalho Chehab""" 33b9721225SMauro Carvalho Chehab 34b9721225SMauro Carvalho Chehabimport codecs 35b9721225SMauro Carvalho Chehabimport os 3685999f03SMauro Carvalho Chehabimport re 37b9721225SMauro Carvalho Chehabimport subprocess 38b9721225SMauro Carvalho Chehabimport sys 39b9721225SMauro Carvalho Chehab 40b9721225SMauro Carvalho Chehabfrom docutils import nodes, statemachine 41b9721225SMauro Carvalho Chehabfrom docutils.statemachine import ViewList 42b9721225SMauro Carvalho Chehabfrom docutils.parsers.rst import directives, Directive 43b9721225SMauro Carvalho Chehabfrom docutils.utils.error_reporting import ErrorString 44b9721225SMauro Carvalho Chehabfrom sphinx.util.docutils import switch_source_input 45b9721225SMauro Carvalho Chehab 46b9721225SMauro Carvalho Chehab__version__ = '1.0' 47b9721225SMauro Carvalho Chehab 48b9721225SMauro Carvalho Chehabdef setup(app): 49b9721225SMauro Carvalho Chehab 50b9721225SMauro Carvalho Chehab app.add_directive("kernel-feat", KernelFeat) 51b9721225SMauro Carvalho Chehab return dict( 52b9721225SMauro Carvalho Chehab version = __version__ 53b9721225SMauro Carvalho Chehab , parallel_read_safe = True 54b9721225SMauro Carvalho Chehab , parallel_write_safe = True 55b9721225SMauro Carvalho Chehab ) 56b9721225SMauro Carvalho Chehab 57b9721225SMauro Carvalho Chehabclass KernelFeat(Directive): 58b9721225SMauro Carvalho Chehab 59b9721225SMauro Carvalho Chehab u"""KernelFeat (``kernel-feat``) directive""" 60b9721225SMauro Carvalho Chehab 61b9721225SMauro Carvalho Chehab required_arguments = 1 62b9721225SMauro Carvalho Chehab optional_arguments = 2 63b9721225SMauro Carvalho Chehab has_content = False 64b9721225SMauro Carvalho Chehab final_argument_whitespace = True 65b9721225SMauro Carvalho Chehab 66b9721225SMauro Carvalho Chehab option_spec = { 67b9721225SMauro Carvalho Chehab "debug" : directives.flag 68b9721225SMauro Carvalho Chehab } 69b9721225SMauro Carvalho Chehab 70b9721225SMauro Carvalho Chehab def warn(self, message, **replace): 71b9721225SMauro Carvalho Chehab replace["fname"] = self.state.document.current_source 72b9721225SMauro Carvalho Chehab replace["line_no"] = replace.get("line_no", self.lineno) 73b9721225SMauro Carvalho Chehab message = ("%(fname)s:%(line_no)s: [kernel-feat WARN] : " + message) % replace 74b9721225SMauro Carvalho Chehab self.state.document.settings.env.app.warn(message, prefix="") 75b9721225SMauro Carvalho Chehab 76b9721225SMauro Carvalho Chehab def run(self): 77b9721225SMauro Carvalho Chehab doc = self.state.document 78b9721225SMauro Carvalho Chehab if not doc.settings.file_insertion_enabled: 79b9721225SMauro Carvalho Chehab raise self.warning("docutils: file insertion disabled") 80b9721225SMauro Carvalho Chehab 81b9721225SMauro Carvalho Chehab env = doc.settings.env 82*c48a7c44SVegard Nossum 83*c48a7c44SVegard Nossum srctree = os.path.abspath(os.environ["srctree"]) 84*c48a7c44SVegard Nossum 85*c48a7c44SVegard Nossum args = [ 86*c48a7c44SVegard Nossum os.path.join(srctree, 'scripts/get_feat.pl'), 87*c48a7c44SVegard Nossum 'rest', 88*c48a7c44SVegard Nossum '--enable-fname', 89*c48a7c44SVegard Nossum '--dir', 90*c48a7c44SVegard Nossum os.path.join(srctree, 'Documentation', self.arguments[0]), 91*c48a7c44SVegard Nossum ] 92b9721225SMauro Carvalho Chehab 93b9721225SMauro Carvalho Chehab if len(self.arguments) > 1: 94*c48a7c44SVegard Nossum args.extend(['--arch', self.arguments[1]]) 95b9721225SMauro Carvalho Chehab 96*c48a7c44SVegard Nossum lines = subprocess.check_output(args, cwd=os.path.dirname(doc.current_source)).decode('utf-8') 9785999f03SMauro Carvalho Chehab 9886a0adc0SBenjamin Gray line_regex = re.compile(r"^\.\. FILE (\S+)$") 9985999f03SMauro Carvalho Chehab 10085999f03SMauro Carvalho Chehab out_lines = "" 10185999f03SMauro Carvalho Chehab 10285999f03SMauro Carvalho Chehab for line in lines.split("\n"): 10385999f03SMauro Carvalho Chehab match = line_regex.search(line) 10485999f03SMauro Carvalho Chehab if match: 10585999f03SMauro Carvalho Chehab fname = match.group(1) 10685999f03SMauro Carvalho Chehab 10785999f03SMauro Carvalho Chehab # Add the file to Sphinx build dependencies 10885999f03SMauro Carvalho Chehab env.note_dependency(os.path.abspath(fname)) 10985999f03SMauro Carvalho Chehab else: 11085999f03SMauro Carvalho Chehab out_lines += line + "\n" 11185999f03SMauro Carvalho Chehab 11285999f03SMauro Carvalho Chehab nodeList = self.nestedParse(out_lines, fname) 113b9721225SMauro Carvalho Chehab return nodeList 114b9721225SMauro Carvalho Chehab 115b9721225SMauro Carvalho Chehab def nestedParse(self, lines, fname): 116b9721225SMauro Carvalho Chehab content = ViewList() 117b9721225SMauro Carvalho Chehab node = nodes.section() 118b9721225SMauro Carvalho Chehab 119b9721225SMauro Carvalho Chehab if "debug" in self.options: 120b9721225SMauro Carvalho Chehab code_block = "\n\n.. code-block:: rst\n :linenos:\n" 121b9721225SMauro Carvalho Chehab for l in lines.split("\n"): 122b9721225SMauro Carvalho Chehab code_block += "\n " + l 123b9721225SMauro Carvalho Chehab lines = code_block + "\n\n" 124b9721225SMauro Carvalho Chehab 125b9721225SMauro Carvalho Chehab for c, l in enumerate(lines.split("\n")): 126b9721225SMauro Carvalho Chehab content.append(l, fname, c) 127b9721225SMauro Carvalho Chehab 128b9721225SMauro Carvalho Chehab buf = self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter 129b9721225SMauro Carvalho Chehab 130b9721225SMauro Carvalho Chehab with switch_source_input(self.state, content): 131b9721225SMauro Carvalho Chehab self.state.nested_parse(content, 0, node, match_titles=1) 132b9721225SMauro Carvalho Chehab 133b9721225SMauro Carvalho Chehab return node.children 134