| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | kernel-feat
|
| 6 | ~~~~~~~~~~~
|
| 7 |
|
| 8 | Implementation of the ``kernel-feat`` reST-directive.
|
| 9 |
|
| 10 | :copyright: Copyright (C) 2016 Markus Heiser
|
| 11 | :copyright: Copyright (C) 2016-2019 Mauro Carvalho Chehab
|
| 12 | :maintained-by: Mauro Carvalho Chehab <[email protected]>
|
| 13 | :license: GPL Version 2, June 1991 see Linux/COPYING for details.
|
| 14 |
|
| 15 | The ``kernel-feat`` (:py:class:`KernelFeat`) directive calls the
|
| 16 | tools/docs/get_feat.pl script to parse the Kernel ABI files.
|
| 17 |
|
| 18 | Overview of directive's argument and options.
|
| 19 |
|
| 20 | .. code-block:: rst
|
| 21 |
|
| 22 | .. kernel-feat:: <ABI directory location>
|
| 23 | :debug:
|
| 24 |
|
| 25 | The argument ``<ABI directory location>`` is required. It contains the
|
| 26 | location of the ABI files to be parsed.
|
| 27 |
|
| 28 | ``debug``
|
| 29 | Inserts a code-block with the *raw* reST. Sometimes it is helpful to see
|
| 30 | what reST is generated.
|
| 31 |
|
| 32 |
|
| 33 |
|
| 34 | import codecs
|
| 35 | import os
|
| 36 | import re
|
| 37 | import sys
|
| 38 |
|
| 39 | from docutils import nodes, statemachine
|
| 40 | from docutils.statemachine import ViewList
|
| 41 | from docutils.parsers.rst import directives, Directive
|
| 42 | from sphinx.util.docutils import switch_source_input
|
| 43 |
|
| 44 | srctree = os.path.abspath(os.environ["srctree"])
|
| 45 | sys.path.insert(0, os.path.join(srctree, "tools/lib/python"))
|
| 46 |
|
| 47 | from feat.parse_features import ParseFeature |
| 48 |
|
| 49 | def ErrorString(exc): |
| 50 | return f'{exc.__class__.__name}: {exc}'
|
| 51 |
|
| 52 | __version__ = '1.0'
|
| 53 |
|
| 54 | def setup(app):
|
| 55 |
|
| 56 | app.add_directive("kernel-feat", KernelFeat)
|
| 57 | return dict(
|
| 58 | version = __version__
|
| 59 | , parallel_read_safe = True
|
| 60 | , parallel_write_safe = True
|
| 61 | )
|
| 62 |
|
| 63 | class KernelFeat(Directive):
|
| 64 |
|
| 65 |
|
| 66 |
|
| 67 | required_arguments = 1
|
| 68 | optional_arguments = 2
|
| 69 | has_content = False
|
| 70 | final_argument_whitespace = True
|
| 71 |
|
| 72 | option_spec = {
|
| 73 | "debug" : directives.flag
|
| 74 | }
|
| 75 |
|
| 76 | def warn(self, message, **replace):
|
| 77 | replace["fname"] = self.state.document.current_source
|
| 78 | replace["line_no"] = replace.get("line_no", self.lineno)
|
| 79 | message = ("%(fname)s:%(line_no)s: [kernel-feat WARN] : " + message) % replace
|
| 80 | self.state.document.settings.env.app.warn(message, prefix="")
|
| 81 |
|
| 82 | def run(self):
|
| 83 | doc = self.state.document
|
| 84 | if not doc.settings.file_insertion_enabled:
|
| 85 | raise self.warning("docutils: file insertion disabled")
|
| 86 |
|
| 87 | env = doc.settings.env
|
| 88 |
|
| 89 | srctree = os.path.abspath(os.environ["srctree"])
|
| 90 |
|
| 91 | feature_dir = os.path.join(srctree, 'Documentation', self.arguments[0])
|
| 92 |
|
| 93 | feat = ParseFeature(feature_dir, False, True)
|
| 94 | feat.parse()
|
| 95 |
|
| 96 | if len(self.arguments) > 1:
|
| 97 | arch = self.arguments[1]
|
| 98 | lines = feat.output_arch_table(arch)
|
| 99 | else:
|
| 100 | lines = feat.output_matrix()
|
| 101 |
|
| 102 | line_regex = re.compile(r"^\.\. FILE (\S+)$")
|
| 103 |
|
| 104 | out_lines = ""
|
| 105 |
|
| 106 | for line in lines.split("\n"):
|
| 107 | match = line_regex.search(line)
|
| 108 | if match:
|
| 109 | fname = match.group(1)
|
| 110 |
|
| 111 | |
| 112 | env.note_dependency(os.path.abspath(fname))
|
| 113 | else:
|
| 114 | out_lines += line + "\n"
|
| 115 |
|
| 116 | nodeList = self.nestedParse(out_lines, self.arguments[0])
|
| 117 | return nodeList
|
| 118 |
|
| 119 | def nestedParse(self, lines, fname):
|
| 120 | content = ViewList()
|
| 121 | node = nodes.section()
|
| 122 |
|
| 123 | if "debug" in self.options:
|
| 124 | code_block = "\n\n.. code-block:: rst\n :linenos:\n"
|
| 125 | for l in lines.split("\n"):
|
| 126 | code_block += "\n " + l
|
| 127 | lines = code_block + "\n\n"
|
| 128 |
|
| 129 | for c, l in enumerate(lines.split("\n")):
|
| 130 | content.append(l, fname, c)
|
| 131 |
|
| 132 | buf = self.state.memo.title_styles, self.state.memo.section_level, self.state.memo.reporter
|
| 133 |
|
| 134 | with switch_source_input(self.state, content):
|
| 135 | self.state.nested_parse(content, 0, node, match_titles=1)
|
| 136 |
|
| 137 | return node.children
|