Skip to content

Commit 5e65a22

Browse files
committed
Properly process parameters with initializer lists
1 parent 1702f27 commit 5e65a22

File tree

2 files changed

+80
-24
lines changed

2 files changed

+80
-24
lines changed

CppHeaderParser/CppHeaderParser.py

Lines changed: 50 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,20 +1043,31 @@ def __init__(self, nameStack, curClass, methinfo, curTemplate, doxygen, location
10431043
# Find commas that are not nexted in <>'s like template types
10441044
open_template_count = 0
10451045
open_paren_count = 0
1046+
open_brace_count = 0
10461047
param_separator = 0
10471048
i = 0
10481049
for elm in paramsStack:
1049-
if "<" in elm:
1050-
open_template_count += 1
1051-
elif ">" in elm:
1052-
open_template_count -= 1
1053-
elif "(" in elm:
1054-
open_paren_count += 1
1055-
elif ")" in elm:
1056-
open_paren_count -= 1
1057-
elif elm == "," and open_template_count == 0 and open_paren_count == 0:
1058-
param_separator = i
1059-
break
1050+
if elm in "<>(){},":
1051+
if elm == ",":
1052+
if (
1053+
open_template_count == 0
1054+
and open_paren_count == 0
1055+
and open_brace_count == 0
1056+
):
1057+
param_separator = i
1058+
break
1059+
elif "<" == elm:
1060+
open_template_count += 1
1061+
elif ">" == elm:
1062+
open_template_count -= 1
1063+
elif "(" == elm:
1064+
open_paren_count += 1
1065+
elif ")" == elm:
1066+
open_paren_count -= 1
1067+
elif "{" == elm:
1068+
open_brace_count += 1
1069+
elif "}" == elm:
1070+
open_brace_count -= 1
10601071
i += 1
10611072

10621073
if param_separator:
@@ -1215,9 +1226,11 @@ def __init__(self, nameStack, doxygen, location, **kwargs):
12151226
elif "=" in nameStack:
12161227
self["type"] = " ".join(nameStack[: nameStack.index("=") - 1])
12171228
self["name"] = nameStack[nameStack.index("=") - 1]
1218-
self["default"] = " ".join(nameStack[nameStack.index("=") + 1 :])
1229+
default = " ".join(nameStack[nameStack.index("=") + 1 :])
1230+
default = self._filter_name(default)
1231+
self["default"] = default
12191232
# backwards compat; deprecate camelCase in dicts
1220-
self["defaultValue"] = self["default"]
1233+
self["defaultValue"] = default
12211234

12221235
elif is_fundamental(nameStack[-1]) or nameStack[-1] in [">", "<", ":", "."]:
12231236
# Un named parameter
@@ -1228,12 +1241,7 @@ def __init__(self, nameStack, doxygen, location, **kwargs):
12281241
self["type"] = " ".join(nameStack[:-1])
12291242
self["name"] = nameStack[-1]
12301243

1231-
self["type"] = self["type"].replace(" :", ":")
1232-
self["type"] = self["type"].replace(": ", ":")
1233-
self["type"] = self["type"].replace(" < ", "<")
1234-
self["type"] = self["type"].replace(" > ", "> ").replace(">>", "> >")
1235-
self["type"] = self["type"].replace(") >", ")>")
1236-
self["type"] = self["type"].replace(" ,", ",")
1244+
self["type"] = self._filter_name(self["type"])
12371245

12381246
# Optional doxygen description
12391247
try:
@@ -1244,6 +1252,15 @@ def __init__(self, nameStack, doxygen, location, **kwargs):
12441252
self.init()
12451253
CppVariable.Vars.append(self) # save and resolve later
12461254

1255+
def _filter_name(self, name):
1256+
name = name.replace(" :", ":").replace(": ", ":")
1257+
name = name.replace(" < ", "<")
1258+
name = name.replace(" > ", "> ").replace(">>", "> >")
1259+
name = name.replace(") >", ")>")
1260+
name = name.replace(" {", "{").replace(" }", "}")
1261+
name = name.replace(" ,", ",")
1262+
return name
1263+
12471264
def __str__(self):
12481265
keys_white_list = [
12491266
"constant",
@@ -2508,8 +2525,8 @@ def evalute_forward_decl(self):
25082525

25092526
# fmt: off
25102527
_namestack_append_tokens = {
2511-
"(",
2512-
")",
2528+
"{",
2529+
"}",
25132530
"[",
25142531
"]",
25152532
"=",
@@ -2729,6 +2746,7 @@ def __init__(self, headerFileName, argType="file", encoding=None, **kwargs):
27292746
self.braceHandled = False
27302747
tok = None
27312748
self.stmtTokens = []
2749+
parenDepth = 0
27322750

27332751
try:
27342752
while True:
@@ -2779,7 +2797,7 @@ def __init__(self, headerFileName, argType="file", encoding=None, **kwargs):
27792797
self.nameStack = []
27802798
continue
27812799

2782-
if tok.type == "{":
2800+
if parenDepth == 0 and tok.type == "{":
27832801
if len(self.nameStack) >= 2 and is_namespace(
27842802
self.nameStack
27852803
): # namespace {} with no name used in boost, this sets default?
@@ -2830,7 +2848,7 @@ def __init__(self, headerFileName, argType="file", encoding=None, **kwargs):
28302848
if not self.braceHandled:
28312849
self.braceDepth += 1
28322850

2833-
elif tok.type == "}":
2851+
elif parenDepth == 0 and tok.type == "}":
28342852
if self.braceDepth == 0:
28352853
continue
28362854
if self.braceDepth == len(self.nameSpaces):
@@ -2862,7 +2880,6 @@ def __init__(self, headerFileName, argType="file", encoding=None, **kwargs):
28622880
self.curClass = ""
28632881
self.stack = []
28642882
self.stmtTokens = []
2865-
28662883
elif tok.type in _namestack_append_tokens:
28672884
self.nameStack.append(tok.value)
28682885
nameStackAppended = True
@@ -2922,6 +2939,15 @@ def __init__(self, headerFileName, argType="file", encoding=None, **kwargs):
29222939
self.stack = []
29232940
self.nameStack = []
29242941
self.stmtTokens = []
2942+
elif tok.type == "(":
2943+
parenDepth += 1
2944+
self.nameStack.append(tok.value)
2945+
nameStackAppended = True
2946+
elif tok.type == ")":
2947+
self.nameStack.append(tok.value)
2948+
nameStackAppended = True
2949+
if parenDepth != 0:
2950+
parenDepth -= 1
29252951

29262952
newNsLen = len(self.nameStack)
29272953
if nslen != newNsLen and newNsLen == 1:

test/test_CppHeaderParser.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3678,5 +3678,35 @@ def test_fn(self):
36783678
self.assertEqual(fn["rtnType"], "std::vector<Pointer *> *")
36793679

36803680

3681+
class ParamWithInitializer_TestCase(unittest.TestCase):
3682+
def setUp(self):
3683+
self.cppHeader = CppHeaderParser.CppHeader(
3684+
"""
3685+
template <typename T, typename U>
3686+
void fn(something<T, U> s = something<T, U>{1,2,3});
3687+
""",
3688+
"string",
3689+
)
3690+
3691+
def test_fn(self):
3692+
self.assertEqual(len(self.cppHeader.functions), 1)
3693+
fn = self.cppHeader.functions[0]
3694+
self.assertEqual(fn["name"], "fn")
3695+
self.assertEqual(
3696+
filter_pameters(fn["parameters"], ["namespace", "raw_type", "default"]),
3697+
[
3698+
{
3699+
"type": "something<T, U >",
3700+
"name": "s",
3701+
"desc": None,
3702+
"namespace": "",
3703+
"raw_type": "something<T, U >",
3704+
"default": "something<T, U>{ 1, 2, 3}",
3705+
},
3706+
],
3707+
)
3708+
self.assertEqual(fn["rtnType"], "void")
3709+
3710+
36813711
if __name__ == "__main__":
36823712
unittest.main()

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy