173 lines · 5.0 KB · Python
RawDownload
# -*- coding: utf-8; mode: python -*-# coding=utf-8# SPDX-License-Identifier: GPL-2.0#"""    kernel-abi    ~~~~~~~~~~     Implementation of the ``kernel-abi`` reST-directive.     :copyright:  Copyright (C) 2016  Markus Heiser    :copyright:  Copyright (C) 2016-2020  Mauro Carvalho Chehab    :maintained-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>    :license:    GPL Version 2, June 1991 see Linux/COPYING for details.     The ``kernel-abi`` (:py:class:`KernelCmd`) directive calls the    AbiParser class to parse the Kernel ABI files.     Overview of directive's argument and options.     .. code-block:: rst         .. kernel-abi:: <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 osimport reimport sys from docutils import nodes, statemachinefrom docutils.statemachine import ViewListfrom docutils.parsers.rst import directives, Directivefrom sphinx.util.docutils import switch_source_inputfrom sphinx.util import logging srctree = os.path.abspath(os.environ["srctree"])sys.path.insert(0, os.path.join(srctree, "tools/lib/python")) from abi.abi_parser import AbiParser __version__ = "1.0" logger = logging.getLogger('kernel_abi')path = os.path.join(srctree, "Documentation/ABI") _kernel_abi = None def get_kernel_abi():    """    Initialize kernel_abi global var, if not initialized yet.     This is needed to avoid warnings during Sphinx module initialization.    """    global _kernel_abi     if not _kernel_abi:        # Parse ABI symbols only once        _kernel_abi = AbiParser(path, logger=logger)        _kernel_abi.parse_abi()        _kernel_abi.check_issues()     return _kernel_abi def setup(app):     app.add_directive("kernel-abi", KernelCmd)    return {        "version": __version__,        "parallel_read_safe": True,        "parallel_write_safe": True    }  class KernelCmd(Directive):    """KernelABI (``kernel-abi``) directive"""     required_arguments = 1    optional_arguments = 3    has_content = False    final_argument_whitespace = True    parser = None     option_spec = {        "debug": directives.flag,        "no-symbols": directives.flag,        "no-files":  directives.flag,    }     def run(self):        kernel_abi = get_kernel_abi()         doc = self.state.document        if not doc.settings.file_insertion_enabled:            raise self.warning("docutils: file insertion disabled")         env = self.state.document.settings.env        content = ViewList()        node = nodes.section()         abi_type = self.arguments[0]         if "no-symbols" in self.options:            show_symbols = False        else:            show_symbols = True         if "no-files" in self.options:            show_file = False        else:            show_file = True         tab_width = self.options.get('tab-width',                                     self.state.document.settings.tab_width)         old_f = None        n = 0        n_sym = 0        for msg, f, ln in kernel_abi.doc(show_file=show_file,                                            show_symbols=show_symbols,                                            filter_path=abi_type):            n_sym += 1            msg_list = statemachine.string2lines(msg, tab_width,                                                 convert_whitespace=True)            if "debug" in self.options:                lines = [                    "", "",  ".. code-block:: rst",                    "    :linenos:", ""                ]                for m in msg_list:                    lines.append("    " + m)            else:                lines = msg_list             for line in lines:                # sphinx counts lines from 0                content.append(line, f, ln - 1)                n += 1             if f != old_f:                # Add the file to Sphinx build dependencies if the file exists                fname = os.path.join(srctree, f)                if os.path.isfile(fname):                    env.note_dependency(fname)                 old_f = f             # Sphinx doesn't like to parse big messages. So, let's            # add content symbol by symbol            if content:                self.do_parse(content, node)                content = ViewList()         if show_symbols and not show_file:            logger.verbose("%s ABI: %i symbols (%i ReST lines)" % (abi_type, n_sym, n))        elif not show_symbols and show_file:            logger.verbose("%s ABI: %i files (%i ReST lines)" % (abi_type, n_sym, n))        else:            logger.verbose("%s ABI: %i data (%i ReST lines)" % (abi_type, n_sym, n))         return node.children     def do_parse(self, content, node):        with switch_source_input(self.state, content):            self.state.nested_parse(content, 0, node, match_titles=1)