133 lines · 3.8 KB · Python
RawDownload
# coding=utf-8# SPDX-License-Identifier: GPL-2.0#u"""    kernel-feat    ~~~~~~~~~~~     Implementation of the ``kernel-feat`` reST-directive.     :copyright:  Copyright (C) 2016  Markus Heiser    :copyright:  Copyright (C) 2016-2019  Mauro Carvalho Chehab    :maintained-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>    :license:    GPL Version 2, June 1991 see Linux/COPYING for details.     The ``kernel-feat`` (:py:class:`KernelFeat`) directive calls the    scripts/get_feat.pl script to parse the Kernel ABI files.     Overview of directive's argument and options.     .. code-block:: rst         .. kernel-feat:: <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. """ import codecsimport osimport reimport subprocessimport sys from docutils import nodes, statemachinefrom docutils.statemachine import ViewListfrom docutils.parsers.rst import directives, Directivefrom docutils.utils.error_reporting import ErrorStringfrom sphinx.util.docutils import switch_source_input __version__  = '1.0' def setup(app):     app.add_directive("kernel-feat", KernelFeat)    return dict(        version = __version__        , parallel_read_safe = True        , parallel_write_safe = True    ) class KernelFeat(Directive):     u"""KernelFeat (``kernel-feat``) directive"""     required_arguments = 1    optional_arguments = 2    has_content = False    final_argument_whitespace = True     option_spec = {        "debug"     : directives.flag    }     def warn(self, message, **replace):        replace["fname"]   = self.state.document.current_source        replace["line_no"] = replace.get("line_no", self.lineno)        message = ("%(fname)s:%(line_no)s: [kernel-feat WARN] : " + message) % replace        self.state.document.settings.env.app.warn(message, prefix="")     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         srctree = os.path.abspath(os.environ["srctree"])         args = [            os.path.join(srctree, 'scripts/get_feat.pl'),            'rest',            '--enable-fname',            '--dir',            os.path.join(srctree, 'Documentation', self.arguments[0]),        ]         if len(self.arguments) > 1:            args.extend(['--arch', self.arguments[1]])         lines = subprocess.check_output(args, cwd=os.path.dirname(doc.current_source)).decode('utf-8')         line_regex = re.compile(r"^\.\. FILE (\S+)$")         out_lines = ""         for line in lines.split("\n"):            match = line_regex.search(line)            if match:                fname = match.group(1)                 # Add the file to Sphinx build dependencies                env.note_dependency(os.path.abspath(fname))            else:                out_lines += line + "\n"         nodeList = self.nestedParse(out_lines, self.arguments[0])        return nodeList     def nestedParse(self, lines, fname):        content = ViewList()        node    = nodes.section()         if "debug" in self.options:            code_block = "\n\n.. code-block:: rst\n    :linenos:\n"            for l in lines.split("\n"):                code_block += "\n    " + l            lines = code_block + "\n\n"         for c, l in enumerate(lines.split("\n")):            content.append(l, fname, c)         buf  = self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter         with switch_source_input(self.state, content):            self.state.nested_parse(content, 0, node, match_titles=1)         return node.children