* Support for C class names (and const specifiers).

* Fix handling of describe environment.
This commit is contained in:
Georg Brandl 2008-05-04 17:55:35 +00:00
parent e1e999bdb0
commit 3761223d85
4 changed files with 55 additions and 9 deletions

View File

@ -30,6 +30,9 @@ New features added
* A new config value, `autoclass_content`, selects if the docstring of the * A new config value, `autoclass_content`, selects if the docstring of the
class' ``__init__`` method is added to the directive's body. class' ``__init__`` method is added to the directive's body.
* Support for C++ class names (in the style ``Class::Function``) in C function
descriptions.
Bugs fixed Bugs fixed
---------- ----------

View File

@ -16,6 +16,16 @@ directory`, the extension is stripped, and path separators are converted to
slashes. All values, parameters and suchlike referring to "documents" expect slashes. All values, parameters and suchlike referring to "documents" expect
such a document name. such a document name.
.. cfunction:: Class::method(int bla, int foo) const
pass
.. cmdoption:: --longopt <arg>
.. class:: Test
.. method:: X
The TOC tree The TOC tree
------------ ------------

View File

@ -154,12 +154,14 @@ def parse_py_signature(signode, sig, desctype, env):
c_sig_re = re.compile( c_sig_re = re.compile(
r'''^([^(]*?) # return type r'''^([^(]*?) # return type
([\w:]+) \s* # thing name (colon allowed for C++ class names) ([\w:]+) \s* # thing name (colon allowed for C++ class names)
(?: \((.*)\) )? $ # optionally arguments (?: \((.*)\) )? # optionally arguments
(\s+const)? $ # const specifier
''', re.VERBOSE) ''', re.VERBOSE)
c_funcptr_sig_re = re.compile( c_funcptr_sig_re = re.compile(
r'''^([^(]+?) # return type r'''^([^(]+?) # return type
(\( [^()]+ \)) \s* # name in parentheses (\( [^()]+ \)) \s* # name in parentheses
\( (.*) \) $ # arguments \( (.*) \) # arguments
(\s+const)? $ # const specifier
''', re.VERBOSE) ''', re.VERBOSE)
c_funcptr_name_re = re.compile(r'^\(\s*\*\s*(.*?)\s*\)$') c_funcptr_name_re = re.compile(r'^\(\s*\*\s*(.*?)\s*\)$')
@ -190,11 +192,18 @@ def parse_c_signature(signode, sig, desctype):
m = c_sig_re.match(sig) m = c_sig_re.match(sig)
if m is None: if m is None:
raise ValueError('no match') raise ValueError('no match')
rettype, name, arglist = m.groups() rettype, name, arglist, const = m.groups()
signode += addnodes.desc_type("", "") signode += addnodes.desc_type("", "")
parse_c_type(signode[-1], rettype) parse_c_type(signode[-1], rettype)
signode += addnodes.desc_name(name, name) try:
classname, funcname = name.split('::', 1)
classname += '::'
signode += addnodes.desc_classname(classname, classname)
signode += addnodes.desc_name(funcname, funcname)
# name (the full name) is still both parts
except ValueError:
signode += addnodes.desc_name(name, name)
# clean up parentheses from canonical name # clean up parentheses from canonical name
m = c_funcptr_name_re.match(name) m = c_funcptr_name_re.match(name)
if m: if m:
@ -222,6 +231,8 @@ def parse_c_signature(signode, sig, desctype):
param += nodes.emphasis(' '+argname, ' '+argname) param += nodes.emphasis(' '+argname, ' '+argname)
paramlist += param paramlist += param
signode += paramlist signode += paramlist
if const:
signode += addnodes.desc_classname(const, const)
return name return name

View File

@ -88,6 +88,7 @@ class Desc(object):
self.ni = node['noindex'] self.ni = node['noindex']
self.type = self.cls = self.name = self.params = '' self.type = self.cls = self.name = self.params = ''
self.count = 0 self.count = 0
self.name = ''
class LaTeXTranslator(nodes.NodeVisitor): class LaTeXTranslator(nodes.NodeVisitor):
@ -321,6 +322,9 @@ class LaTeXTranslator(nodes.NodeVisitor):
else: else:
t2 = "{%s}" % d.name t2 = "{%s}" % d.name
elif d.env == 'cfuncdesc': elif d.env == 'cfuncdesc':
if d.cls:
# C++ class names
d.name = '%s::%s' % (d.cls, d.name)
t2 = "{%s}{%s}{%s}" % (d.type, d.name, d.params) t2 = "{%s}{%s}{%s}" % (d.type, d.name, d.params)
elif d.env == 'cmemberdesc': elif d.env == 'cmemberdesc':
try: try:
@ -341,19 +345,35 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.body.append(t1 + t2) self.body.append(t1 + t2)
def visit_desc_type(self, node): def visit_desc_type(self, node):
self.descstack[-1].type = self.encode(node.astext().strip()) d = self.descstack[-1]
if d.env == 'describe':
d.name += self.encode(node.astext())
else:
self.descstack[-1].type = self.encode(node.astext().strip())
raise nodes.SkipNode raise nodes.SkipNode
def visit_desc_name(self, node): def visit_desc_name(self, node):
self.descstack[-1].name = self.encode(node.astext().strip()) d = self.descstack[-1]
if d.env == 'describe':
d.name += self.encode(node.astext())
else:
self.descstack[-1].name = self.encode(node.astext().strip())
raise nodes.SkipNode raise nodes.SkipNode
def visit_desc_classname(self, node): def visit_desc_classname(self, node):
self.descstack[-1].cls = self.encode(node.astext().strip()) d = self.descstack[-1]
if d.env == 'describe':
d.name += self.encode(node.astext())
else:
self.descstack[-1].cls = self.encode(node.astext().strip())
raise nodes.SkipNode raise nodes.SkipNode
def visit_desc_parameterlist(self, node): def visit_desc_parameterlist(self, node):
self.descstack[-1].params = self.encode(node.astext().strip()) d = self.descstack[-1]
if d.env == 'describe':
d.name += self.encode(node.astext())
else:
self.descstack[-1].params = self.encode(node.astext().strip())
raise nodes.SkipNode raise nodes.SkipNode
def visit_refcount(self, node): def visit_refcount(self, node):
@ -362,7 +382,9 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.body.append("}\\\\") self.body.append("}\\\\")
def visit_desc_content(self, node): def visit_desc_content(self, node):
pass if node.children and isinstance(node.children[0], addnodes.desc):
# avoid empty desc environment which causes a formatting bug
self.body.append('~')
def depart_desc_content(self, node): def depart_desc_content(self, node):
pass pass