Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 56cd8692 authored by Markus Heiser's avatar Markus Heiser Committed by Jonathan Corbet
Browse files

doc-rst:c-domain: function-like macros arguments



Handle signatures of function-like macros well. Don't try to deduce
arguments types of function-like macros.

Signed-off-by: default avatarMarkus Heiser <markus.heiser@darmarIT.de>
Signed-off-by: default avatarJonathan Corbet <corbet@lwn.net>
parent b495360e
Loading
Loading
Loading
Loading
+54 −1
Original line number Diff line number Diff line
# -*- coding: utf-8; mode: python -*-
# pylint: disable=W0141,C0113,C0103,C0325
u"""
    cdomain
    ~~~~~~~
@@ -25,11 +26,18 @@ u"""

          * :c:func:`VIDIOC_LOG_STATUS` or
          * :any:`VIDIOC_LOG_STATUS` (``:any:`` needs sphinx 1.3)

     * Handle signatures of function-like macros well. Don't try to deduce
       arguments types of function-like macros.

"""

from docutils import nodes
from docutils.parsers.rst import directives

import sphinx
from sphinx import addnodes
from sphinx.domains.c import c_funcptr_sig_re, c_sig_re
from sphinx.domains.c import CObject as Base_CObject
from sphinx.domains.c import CDomain as Base_CDomain

@@ -57,9 +65,54 @@ class CObject(Base_CObject):
        "name" : directives.unchanged
    }

    def handle_func_like_macro(self, sig, signode):
        u"""Handles signatures of function-like macros.

        If the objtype is 'function' and the the signature ``sig`` is a
        function-like macro, the name of the macro is returned. Otherwise
        ``False`` is returned.  """

        if not self.objtype == 'function':
            return False

        m = c_funcptr_sig_re.match(sig)
        if m is None:
            m = c_sig_re.match(sig)
            if m is None:
                raise ValueError('no match')

        rettype, fullname, arglist, _const = m.groups()
        arglist = arglist.strip()
        if rettype or not arglist:
            return False

        arglist = arglist.replace('`', '').replace('\\ ', '') # remove markup
        arglist = [a.strip() for a in arglist.split(",")]

        # has the first argument a type?
        if len(arglist[0].split(" ")) > 1:
            return False

        # This is a function-like macro, it's arguments are typeless!
        signode  += addnodes.desc_name(fullname, fullname)
        paramlist = addnodes.desc_parameterlist()
        signode  += paramlist

        for argname in arglist:
            param = addnodes.desc_parameter('', '', noemph=True)
            # separate by non-breaking space in the output
            param += nodes.emphasis(argname, argname)
            paramlist += param

        return fullname

    def handle_signature(self, sig, signode):
        """Transform a C signature into RST nodes."""

        fullname = self.handle_func_like_macro(sig, signode)
        if not fullname:
            fullname = super(CObject, self).handle_signature(sig, signode)

        if "name" in self.options:
            if self.objtype == 'function':
                fullname = self.options["name"]