[2/3] doc-rst:c-domain: function-like macros arguments

Message ID 1472657372-21039-3-git-send-email-markus.heiser@darmarit.de (mailing list archive)
State Superseded, archived
Headers

Commit Message

Markus Heiser Aug. 31, 2016, 3:29 p.m. UTC
  From: Markus Heiser <markus.heiser@darmarIT.de>

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

Signed-off-by: Markus Heiser <markus.heiser@darmarIT.de>
---
 Documentation/sphinx/cdomain.py | 55 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 54 insertions(+), 1 deletion(-)
  

Comments

Jonathan Corbet Sept. 6, 2016, 12:27 p.m. UTC | #1
So I'm going into total nit-picking territory here, but since I'm looking
at it and I think the series needs a respin anyway...

On Wed, 31 Aug 2016 17:29:31 +0200
Markus Heiser <markus.heiser@darmarit.de> wrote:

> +        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')

How about we put that second test inside the first if block and avoid the
redundant None test if the first match works?  The energy saved may
prevent a hurricane someday :)

> +
> +        rettype, fullname, arglist, _const = m.groups()
> +        if rettype or not arglist.strip():
> +            return False
> +
> +        arglist = arglist.replace('`', '').replace('\\ ', '').strip()  # remove markup
> +        arglist = [a.strip() for a in arglist.split(",")]

Similarly, stripping the args three times seems a bit much.  The middle
one is totally redundant and could go at a minimum.

Thanks,

jon
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
  
Markus Heiser Sept. 7, 2016, 5:26 a.m. UTC | #2
Am 06.09.2016 um 14:27 schrieb Jonathan Corbet <corbet@lwn.net>:

> So I'm going into total nit-picking territory here, but since I'm looking
> at it and I think the series needs a respin anyway...
> 
> On Wed, 31 Aug 2016 17:29:31 +0200
> Markus Heiser <markus.heiser@darmarit.de> wrote:
> 
>> +        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')
> 
> How about we put that second test inside the first if block and avoid the
> redundant None test if the first match works?  The energy saved may
> prevent a hurricane someday :)

And prohibit the MS-Windows update installer will save the climate ;)
It is a habit of mine to avoid indentations, but you are right,
it is not appropriate here.

>> +
>> +        rettype, fullname, arglist, _const = m.groups()
>> +        if rettype or not arglist.strip():
>> +            return False
>> +
>> +        arglist = arglist.replace('`', '').replace('\\ ', '').strip()  # remove markup
>> +        arglist = [a.strip() for a in arglist.split(",")]
> 
> Similarly, stripping the args three times seems a bit much.  The middle
> one is totally redundant and could go at a minimum.

Thanks for pointing this. You are right, I will fix it.

-- Markus --

> 
> Thanks,
> 
> jon

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
  

Patch

diff --git a/Documentation/sphinx/cdomain.py b/Documentation/sphinx/cdomain.py
index 66816ae..0816090 100644
--- a/Documentation/sphinx/cdomain.py
+++ b/Documentation/sphinx/cdomain.py
@@ -1,4 +1,5 @@ 
 # -*- 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
 
@@ -38,6 +46,7 @@  __version__  = '1.0'
 # Get Sphinx version
 major, minor, patch = map(int, sphinx.__version__.split("."))
 
+
 def setup(app):
 
     app.override_domain(CDomain)
@@ -57,9 +66,53 @@  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()
+        if rettype or not arglist.strip():
+            return False
+
+        arglist = arglist.replace('`', '').replace('\\ ', '').strip()  # 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 = super(CObject, self).handle_signature(sig, signode)
+
+        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"]