brintos

brintos / linux-shallow public Read only

0
0
Text · 4.0 KiB · 5911bd0 Raw
142 lines · python
1# -*- coding: utf-8; mode: python -*-2# coding=utf-83# SPDX-License-Identifier: GPL-2.04#5u"""6    kernel-abi7    ~~~~~~~~~~8 9    Implementation of the ``kernel-abi`` reST-directive.10 11    :copyright:  Copyright (C) 2016  Markus Heiser12    :copyright:  Copyright (C) 2016-2020  Mauro Carvalho Chehab13    :maintained-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>14    :license:    GPL Version 2, June 1991 see Linux/COPYING for details.15 16    The ``kernel-abi`` (:py:class:`KernelCmd`) directive calls the17    scripts/get_abi.pl script to parse the Kernel ABI files.18 19    Overview of directive's argument and options.20 21    .. code-block:: rst22 23        .. kernel-abi:: <ABI directory location>24            :debug:25 26    The argument ``<ABI directory location>`` is required. It contains the27    location of the ABI files to be parsed.28 29    ``debug``30      Inserts a code-block with the *raw* reST. Sometimes it is helpful to see31      what reST is generated.32 33"""34 35import codecs36import os37import subprocess38import sys39import re40import kernellog41 42from docutils import nodes, statemachine43from docutils.statemachine import ViewList44from docutils.parsers.rst import directives, Directive45from docutils.utils.error_reporting import ErrorString46from sphinx.util.docutils import switch_source_input47 48__version__  = '1.0'49 50def setup(app):51 52    app.add_directive("kernel-abi", KernelCmd)53    return dict(54        version = __version__55        , parallel_read_safe = True56        , parallel_write_safe = True57    )58 59class KernelCmd(Directive):60 61    u"""KernelABI (``kernel-abi``) directive"""62 63    required_arguments = 164    optional_arguments = 265    has_content = False66    final_argument_whitespace = True67 68    option_spec = {69        "debug"     : directives.flag,70        "rst"       : directives.unchanged71    }72 73    def run(self):74        doc = self.state.document75        if not doc.settings.file_insertion_enabled:76            raise self.warning("docutils: file insertion disabled")77 78        srctree = os.path.abspath(os.environ["srctree"])79 80        args = [81            os.path.join(srctree, 'scripts/get_abi.pl'),82            'rest',83            '--enable-lineno',84            '--dir', os.path.join(srctree, 'Documentation', self.arguments[0]),85        ]86 87        if 'rst' in self.options:88            args.append('--rst-source')89 90        lines = subprocess.check_output(args, cwd=os.path.dirname(doc.current_source)).decode('utf-8')91        nodeList = self.nestedParse(lines, self.arguments[0])92        return nodeList93 94    def nestedParse(self, lines, fname):95        env = self.state.document.settings.env96        content = ViewList()97        node = nodes.section()98 99        if "debug" in self.options:100            code_block = "\n\n.. code-block:: rst\n    :linenos:\n"101            for l in lines.split("\n"):102                code_block += "\n    " + l103            lines = code_block + "\n\n"104 105        line_regex = re.compile(r"^\.\. LINENO (\S+)\#([0-9]+)$")106        ln = 0107        n = 0108        f = fname109 110        for line in lines.split("\n"):111            n = n + 1112            match = line_regex.search(line)113            if match:114                new_f = match.group(1)115 116                # Sphinx parser is lazy: it stops parsing contents in the117                # middle, if it is too big. So, handle it per input file118                if new_f != f and content:119                    self.do_parse(content, node)120                    content = ViewList()121 122                    # Add the file to Sphinx build dependencies123                    env.note_dependency(os.path.abspath(f))124 125                f = new_f126 127                # sphinx counts lines from 0128                ln = int(match.group(2)) - 1129            else:130                content.append(line, f, ln)131 132        kernellog.info(self.state.document.settings.env.app, "%s: parsed %i lines" % (fname, n))133 134        if content:135            self.do_parse(content, node)136 137        return node.children138 139    def do_parse(self, content, node):140        with switch_source_input(self.state, content):141            self.state.nested_parse(content, 0, node, match_titles=1)142