Linux Audio

Check our new training course

Loading...
v6.13.7
  1# -*- coding: utf-8; mode: python -*-
  2# coding=utf-8
  3# SPDX-License-Identifier: GPL-2.0
  4#
  5u"""
  6    kernel-abi
  7    ~~~~~~~~~~
  8
  9    Implementation of the ``kernel-abi`` reST-directive.
 10
 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.
 15
 16    The ``kernel-abi`` (:py:class:`KernelCmd`) directive calls the
 17    scripts/get_abi.pl script to parse the Kernel ABI files.
 18
 19    Overview of directive's argument and options.
 20
 21    .. code-block:: rst
 22
 23        .. kernel-abi:: <ABI directory location>
 24            :debug:
 25
 26    The argument ``<ABI directory location>`` is required. It contains the
 27    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 see
 31      what reST is generated.
 32
 33"""
 34
 35import codecs
 36import os
 37import subprocess
 38import sys
 39import re
 40import kernellog
 41
 
 
 42from docutils import nodes, statemachine
 43from docutils.statemachine import ViewList
 44from docutils.parsers.rst import directives, Directive
 45from docutils.utils.error_reporting import ErrorString
 46from sphinx.util.docutils import switch_source_input
 47
 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 = True
 56        , parallel_write_safe = True
 57    )
 58
 59class KernelCmd(Directive):
 60
 61    u"""KernelABI (``kernel-abi``) directive"""
 62
 63    required_arguments = 1
 64    optional_arguments = 2
 65    has_content = False
 66    final_argument_whitespace = True
 67
 68    option_spec = {
 69        "debug"     : directives.flag,
 70        "rst"       : directives.unchanged
 71    }
 72
 73    def run(self):
 
 74        doc = self.state.document
 75        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 nodeList
 93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 94    def nestedParse(self, lines, fname):
 95        env = self.state.document.settings.env
 96        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    " + l
103            lines = code_block + "\n\n"
104
105        line_regex = re.compile(r"^\.\. LINENO (\S+)\#([0-9]+)$")
106        ln = 0
107        n = 0
108        f = fname
109
110        for line in lines.split("\n"):
111            n = n + 1
112            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 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)
120                    content = ViewList()
121
122                    # Add the file to Sphinx build dependencies
123                    env.note_dependency(os.path.abspath(f))
124
125                f = new_f
126
127                # sphinx counts lines from 0
128                ln = int(match.group(2)) - 1
129            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.children
138
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)
v6.2
  1# -*- coding: utf-8; mode: python -*-
  2# coding=utf-8
  3# SPDX-License-Identifier: GPL-2.0
  4#
  5u"""
  6    kernel-abi
  7    ~~~~~~~~~~
  8
  9    Implementation of the ``kernel-abi`` reST-directive.
 10
 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.
 15
 16    The ``kernel-abi`` (:py:class:`KernelCmd`) directive calls the
 17    scripts/get_abi.pl script to parse the Kernel ABI files.
 18
 19    Overview of directive's argument and options.
 20
 21    .. code-block:: rst
 22
 23        .. kernel-abi:: <ABI directory location>
 24            :debug:
 25
 26    The argument ``<ABI directory location>`` is required. It contains the
 27    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 see
 31      what reST is generated.
 32
 33"""
 34
 35import codecs
 36import os
 37import subprocess
 38import sys
 39import re
 40import kernellog
 41
 42from os import path
 43
 44from docutils import nodes, statemachine
 45from docutils.statemachine import ViewList
 46from docutils.parsers.rst import directives, Directive
 47from docutils.utils.error_reporting import ErrorString
 48from sphinx.util.docutils import switch_source_input
 49
 50__version__  = '1.0'
 51
 52def setup(app):
 53
 54    app.add_directive("kernel-abi", KernelCmd)
 55    return dict(
 56        version = __version__
 57        , parallel_read_safe = True
 58        , parallel_write_safe = True
 59    )
 60
 61class KernelCmd(Directive):
 62
 63    u"""KernelABI (``kernel-abi``) directive"""
 64
 65    required_arguments = 1
 66    optional_arguments = 2
 67    has_content = False
 68    final_argument_whitespace = True
 69
 70    option_spec = {
 71        "debug"     : directives.flag,
 72        "rst"       : directives.unchanged
 73    }
 74
 75    def run(self):
 76
 77        doc = self.state.document
 78        if not doc.settings.file_insertion_enabled:
 79            raise self.warning("docutils: file insertion disabled")
 80
 81        env = doc.settings.env
 82        cwd = path.dirname(doc.current_source)
 83        cmd = "get_abi.pl rest --enable-lineno --dir "
 84        cmd += self.arguments[0]
 
 
 
 
 85
 86        if 'rst' in self.options:
 87            cmd += " --rst-source"
 88
 89        srctree = path.abspath(os.environ["srctree"])
 90
 91        fname = cmd
 92
 93        # extend PATH with $(srctree)/scripts
 94        path_env = os.pathsep.join([
 95            srctree + os.sep + "scripts",
 96            os.environ["PATH"]
 97        ])
 98        shell_env = os.environ.copy()
 99        shell_env["PATH"]    = path_env
100        shell_env["srctree"] = srctree
101
102        lines = self.runCmd(cmd, shell=True, cwd=cwd, env=shell_env)
103        nodeList = self.nestedParse(lines, self.arguments[0])
104        return nodeList
105
106    def runCmd(self, cmd, **kwargs):
107        u"""Run command ``cmd`` and return its stdout as unicode."""
108
109        try:
110            proc = subprocess.Popen(
111                cmd
112                , stdout = subprocess.PIPE
113                , stderr = subprocess.PIPE
114                , **kwargs
115            )
116            out, err = proc.communicate()
117
118            out, err = codecs.decode(out, 'utf-8'), codecs.decode(err, 'utf-8')
119
120            if proc.returncode != 0:
121                raise self.severe(
122                    u"command '%s' failed with return code %d"
123                    % (cmd, proc.returncode)
124                )
125        except OSError as exc:
126            raise self.severe(u"problems with '%s' directive: %s."
127                              % (self.name, ErrorString(exc)))
128        return out
129
130    def nestedParse(self, lines, fname):
131        env = self.state.document.settings.env
132        content = ViewList()
133        node = nodes.section()
134
135        if "debug" in self.options:
136            code_block = "\n\n.. code-block:: rst\n    :linenos:\n"
137            for l in lines.split("\n"):
138                code_block += "\n    " + l
139            lines = code_block + "\n\n"
140
141        line_regex = re.compile("^\.\. LINENO (\S+)\#([0-9]+)$")
142        ln = 0
143        n = 0
144        f = fname
145
146        for line in lines.split("\n"):
147            n = n + 1
148            match = line_regex.search(line)
149            if match:
150                new_f = match.group(1)
151
152                # Sphinx parser is lazy: it stops parsing contents in the
153                # middle, if it is too big. So, handle it per input file
154                if new_f != f and content:
155                    self.do_parse(content, node)
156                    content = ViewList()
157
158                    # Add the file to Sphinx build dependencies
159                    env.note_dependency(os.path.abspath(f))
160
161                f = new_f
162
163                # sphinx counts lines from 0
164                ln = int(match.group(2)) - 1
165            else:
166                content.append(line, f, ln)
167
168        kernellog.info(self.state.document.settings.env.app, "%s: parsed %i lines" % (fname, n))
169
170        if content:
171            self.do_parse(content, node)
172
173        return node.children
174
175    def do_parse(self, content, node):
176        with switch_source_input(self.state, content):
177            self.state.nested_parse(content, 0, node, match_titles=1)