1 # -*- coding: utf-8; mode: python -*-
3 # SPDX-License-Identifier: GPL-2.0
9 Implementation of the ``kernel-abi`` reST-directive.
11 :copyright: Copyright (C) 2016 Markus Heiser
12 :copyright: Copyright (C) 2016-2020 Mauro Carvalho Chehab
13 :maintained-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
14 :license: GPL Version 2, June 1991 see Linux/COPYING for details.
16 The ``kernel-abi`` (:py:class:`KernelCmd`) directive calls the
17 scripts/get_abi.pl script to parse the Kernel ABI files.
19 Overview of directive's argument and options.
23 .. kernel-abi:: <ABI directory location>
26 The argument ``<ABI directory location>`` is required. It contains the
27 location of the ABI files to be parsed.
30 Inserts a code-block with the *raw* reST. Sometimes it is helpful to see
31 what reST is generated.
42 from docutils
import nodes
, statemachine
43 from docutils
.statemachine
import ViewList
44 from docutils
.parsers
.rst
import directives
, Directive
45 from docutils
.utils
.error_reporting
import ErrorString
46 from sphinx
.util
.docutils
import switch_source_input
52 app
.add_directive("kernel-abi", KernelCmd
)
55 , parallel_read_safe
= True
56 , parallel_write_safe
= True
59 class KernelCmd(Directive
):
61 u
"""KernelABI (``kernel-abi``) directive"""
63 required_arguments
= 1
64 optional_arguments
= 2
66 final_argument_whitespace
= True
69 "debug" : directives
.flag
,
70 "rst" : directives
.unchanged
74 doc
= self
.state
.document
75 if not doc
.settings
.file_insertion_enabled
:
76 raise self
.warning("docutils: file insertion disabled")
78 srctree
= os
.path
.abspath(os
.environ
["srctree"])
81 os
.path
.join(srctree
, 'scripts/get_abi.pl'),
84 '--dir', os
.path
.join(srctree
, 'Documentation', self
.arguments
[0]),
87 if 'rst' in self
.options
:
88 args
.append('--rst-source')
90 lines
= subprocess
.check_output(args
, cwd
=os
.path
.dirname(doc
.current_source
)).decode('utf-8')
91 nodeList
= self
.nestedParse(lines
, self
.arguments
[0])
94 def nestedParse(self
, lines
, fname
):
95 env
= self
.state
.document
.settings
.env
97 node
= nodes
.section()
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 " + l
103 lines
= code_block
+ "\n\n"
105 line_regex
= re
.compile(r
"^\.\. LINENO (\S+)\#([0-9]+)$")
110 for line
in lines
.split("\n"):
112 match
= line_regex
.search(line
)
114 new_f
= match
.group(1)
116 # Sphinx parser is lazy: it stops parsing contents in the
117 # middle, if it is too big. So, handle it per input file
118 if new_f
!= f
and content
:
119 self
.do_parse(content
, node
)
122 # Add the file to Sphinx build dependencies
123 env
.note_dependency(os
.path
.abspath(f
))
127 # sphinx counts lines from 0
128 ln
= int(match
.group(2)) - 1
130 content
.append(line
, f
, ln
)
132 kernellog
.info(self
.state
.document
.settings
.env
.app
, "%s: parsed %i lines" % (fname
, n
))
135 self
.do_parse(content
, node
)
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)