Commits

Jon Waltman committed c47e3e7

Closes #681: Allow nested parentheses in C++ signatures (patch by Vadim and Jim Naslund)

Comments (0)

Files changed (2)

sphinx/domains/cpp.py

         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
 

tests/test_cpp_domain.py

 
 from util import *
 
-from sphinx.domains.cpp import DefinitionParser
+from sphinx.domains.cpp import DefinitionParser, DefinitionError
 
 
 def parse(name, string):
     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'
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.