diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index a6392c1cb..31daa1f68 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -760,17 +760,33 @@ class DefinitionParser(object): self.skip_ws() if self.match(_string_re): return self.matched_text - idx1 = self.definition.find(',', self.pos) - idx2 = self.definition.find(')', self.pos) - if idx1 < 0: - idx = idx2 - elif idx2 < 0: - idx = idx1 - else: - idx = min(idx1, idx2) - if idx < 0: - self.fail('unexpected end in default expression') - rv = self.definition[self.pos:idx] + paren_stack_depth = 0 + max_pos = len(self.definition) + rv_start = self.pos + while 1: + idx0 = self.definition.find('(', self.pos) + idx1 = self.definition.find(',', self.pos) + idx2 = self.definition.find(')', self.pos) + if idx0 < 0: + idx0 = max_pos + if idx1 < 0: + idx1 = max_pos + if idx2 < 0: + idx2 = max_pos + idx = min(idx0, idx1, idx2) + if idx >= max_pos: + self.fail('unexpected end in default expression') + if idx == idx0: + paren_stack_depth += 1 + elif idx == idx2: + paren_stack_depth -= 1 + if paren_stack_depth < 0: + break + elif paren_stack_depth == 0: + break + self.pos = idx+1 + + rv = self.definition[rv_start:idx] self.pos = idx return rv diff --git a/tests/test_cpp_domain.py b/tests/test_cpp_domain.py index 3ab8ece4c..bd8aafa76 100644 --- a/tests/test_cpp_domain.py +++ b/tests/test_cpp_domain.py @@ -11,7 +11,7 @@ from util import * -from sphinx.domains.cpp import DefinitionParser +from sphinx.domains.cpp import DefinitionParser, DefinitionError def parse(name, string): @@ -73,6 +73,21 @@ def test_type_definitions(): x = 'module::myclass foo[n]' assert unicode(parse('member_object', x)) == x + x = 'int foo(Foo f=Foo(double(), std::make_pair(int(2), double(3.4))))' + assert unicode(parse('function', x)) == x + + x = 'int foo(A a=x(a))' + assert unicode(parse('function', x)) == x + + x = 'int foo(B b=x(a)' + raises(DefinitionError, parse, 'function', x) + + x = 'int foo)C c=x(a))' + raises(DefinitionError, parse, 'function', x) + + x = 'int foo(D d=x(a' + raises(DefinitionError, parse, 'function', x) + def test_bases(): x = 'A'