summaryrefslogtreecommitdiff
path: root/Documentation/sphinx/kernel_abi.py
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/sphinx/kernel_abi.py')
-rw-r--r--Documentation/sphinx/kernel_abi.py171
1 files changed, 171 insertions, 0 deletions
diff --git a/Documentation/sphinx/kernel_abi.py b/Documentation/sphinx/kernel_abi.py
new file mode 100644
index 000000000000..db6f0380de94
--- /dev/null
+++ b/Documentation/sphinx/kernel_abi.py
@@ -0,0 +1,171 @@
+# -*- 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
+ scripts/get_abi.py script 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 os
+import re
+import sys
+
+from docutils import nodes, statemachine
+from docutils.statemachine import ViewList
+from docutils.parsers.rst import directives, Directive
+from sphinx.util.docutils import switch_source_input
+from sphinx.util import logging
+
+srctree = os.path.abspath(os.environ["srctree"])
+sys.path.insert(0, os.path.join(srctree, "scripts/lib/abi"))
+
+from 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
+ env.note_dependency(os.path.abspath(f))
+
+ 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)