Skip to content

Commit 8a2caee

Browse files
authored
Add support to variable with [] inside type (#85)
* Add support to variable with [] inside type std::unique_ptr<int[]> variable; * Type of "array_size" should always be the same * Add test for std::unique_ptr<int[]> * Add support for initialization with {} int double {0}; int double {(1.2+3.2)}; * Fix format
1 parent 7595d33 commit 8a2caee

File tree

2 files changed

+145
-28
lines changed

2 files changed

+145
-28
lines changed

CppHeaderParser/CppHeaderParser.py

+61-27
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ def trace_print(*args):
141141
_BRACE_REASON_OTHER = 0
142142
_BRACE_REASON_NS = 1
143143
_BRACE_REASON_EXTERN = 2
144+
_BRACE_REASON_VARIABLE = 3
144145

145146
# Track what was added in what order and at what depth
146147
parseHistory = []
@@ -239,10 +240,13 @@ def is_property_namestack(nameStack):
239240
r = False
240241
if "(" not in nameStack and ")" not in nameStack:
241242
r = True
242-
elif (
243-
"(" in nameStack
244-
and "=" in nameStack
245-
and nameStack.index("=") < nameStack.index("(")
243+
elif "(" in nameStack and (
244+
( # = initialization
245+
"=" in nameStack and nameStack.index("=") < nameStack.index("(")
246+
)
247+
or ( # {} initialization
248+
"{" in nameStack and nameStack.index("{") < nameStack.index("(")
249+
)
246250
):
247251
r = True
248252
# See if we are a function pointer
@@ -1217,29 +1221,48 @@ def __init__(self, nameStack, doxygen, location, is_var=True, **kwargs):
12171221
else:
12181222
self["extern"] = False
12191223

1224+
if "=" in nameStack:
1225+
self["type"] = " ".join(nameStack[: nameStack.index("=") - 1])
1226+
self["name"] = nameStack[nameStack.index("=") - 1]
1227+
default = " ".join(nameStack[nameStack.index("=") + 1 :])
1228+
nameStack = nameStack[: nameStack.index("=")]
1229+
default = self._filter_name(default)
1230+
self["default"] = default
1231+
# backwards compat; deprecate camelCase in dicts
1232+
self["defaultValue"] = default
1233+
elif "{" in nameStack and "}" in nameStack:
1234+
posBracket = nameStack.index("{")
1235+
self["type"] = " ".join(nameStack[: posBracket - 1])
1236+
self["name"] = nameStack[posBracket - 1]
1237+
default = " ".join(nameStack[posBracket + 1 : -1])
1238+
nameStack = nameStack[:posBracket]
1239+
default = self._filter_name(default)
1240+
self["default"] = default
1241+
# backwards compat; deprecate camelCase in dicts
1242+
self["defaultValue"] = default
1243+
12201244
_stack_ = nameStack
1221-
if "[" in nameStack: # strip off array informatin
1222-
arrayStack = nameStack[nameStack.index("[") :]
1223-
if nameStack.count("[") > 1:
1245+
self["array"] = 0
1246+
while "]" in nameStack[-1]: # strip off array information
1247+
arrayPos = len(nameStack) - 1 - nameStack[::-1].index("[")
1248+
arrayStack = nameStack[arrayPos:]
1249+
if self["array"] == 1:
12241250
debug_print("Multi dimensional array")
12251251
debug_print("arrayStack=%s", arrayStack)
1226-
nums = [x for x in arrayStack if x.isdigit()]
1227-
# Calculate size by multiplying all dimensions
1228-
p = 1
1229-
for n in nums:
1230-
p *= int(n)
1252+
if len(arrayStack) == 3:
1253+
n = arrayStack[1]
12311254
# Multi dimensional array
1232-
self["array_size"] = p
1255+
if not "multi_dimensional_array_size" in self:
1256+
self["multi_dimensional_array_size"] = self["array_size"]
1257+
self["multi_dimensional_array_size"] += "x" + n
1258+
self["array_size"] = str(int(self["array_size"]) * int(n))
12331259
self["multi_dimensional_array"] = 1
1234-
self["multi_dimensional_array_size"] = "x".join(nums)
12351260
else:
12361261
debug_print("Array")
12371262
if len(arrayStack) == 3:
12381263
self["array_size"] = arrayStack[1]
1239-
nameStack = nameStack[: nameStack.index("[")]
1264+
nameStack = nameStack[:arrayPos]
12401265
self["array"] = 1
1241-
else:
1242-
self["array"] = 0
12431266
nameStack = self._name_stack_helper(nameStack)
12441267

12451268
if doxygen:
@@ -1268,15 +1291,6 @@ def __init__(self, nameStack, doxygen, location, is_var=True, **kwargs):
12681291
)
12691292
self["function_pointer"] = 1
12701293

1271-
elif "=" in nameStack:
1272-
self["type"] = " ".join(nameStack[: nameStack.index("=") - 1])
1273-
self["name"] = nameStack[nameStack.index("=") - 1]
1274-
default = " ".join(nameStack[nameStack.index("=") + 1 :])
1275-
default = self._filter_name(default)
1276-
self["default"] = default
1277-
# backwards compat; deprecate camelCase in dicts
1278-
self["defaultValue"] = default
1279-
12801294
elif (
12811295
is_fundamental(nameStack[-1])
12821296
or nameStack[-1] in [">", "<", ":", "."]
@@ -2931,7 +2945,23 @@ def __init__(
29312945
continue
29322946

29332947
if parenDepth == 0 and tok.type == "{":
2934-
self.lastBraceReason = _BRACE_REASON_OTHER
2948+
if self.nameStack[0] in (
2949+
"class",
2950+
"struct",
2951+
"union",
2952+
"namespace",
2953+
"enum",
2954+
"extern",
2955+
"typedef",
2956+
) or (is_method_namestack(self.stack) or (not self.curClass)):
2957+
self.lastBraceReason = _BRACE_REASON_OTHER
2958+
else:
2959+
# Case : type variable {init};
2960+
self.lastBraceReason = _BRACE_REASON_VARIABLE
2961+
self.braceDepth += 1
2962+
self.braceReason.append(self.lastBraceReason)
2963+
self.nameStack.append(tok.value)
2964+
continue
29352965
if len(self.nameStack) >= 2 and is_namespace(
29362966
self.nameStack
29372967
): # namespace {} with no name used in boost, this sets default?
@@ -2991,6 +3021,10 @@ def __init__(
29913021
self.linkage_stack.pop()
29923022
self.stack = [] # clear stack when linkage ends?
29933023
self.stmtTokens = []
3024+
# Case : type variable {init};
3025+
elif reason == _BRACE_REASON_VARIABLE:
3026+
self.nameStack.append(tok.value)
3027+
continue
29943028
else:
29953029
self._evaluate_stack()
29963030
self.braceDepth -= 1

test/test_CppHeaderParser.py

+84-1
Original file line numberDiff line numberDiff line change
@@ -2359,7 +2359,7 @@ def setUp(self):
23592359
def test_array_size(self):
23602360
self.assertEqual(
23612361
self.cppHeader.classes["Picture"]["properties"]["public"][1]["array_size"],
2362-
16384,
2362+
"16384",
23632363
)
23642364

23652365
def test_multi_dimensional_array_size(self):
@@ -4222,5 +4222,88 @@ def test_fn(self):
42224222
self.assertEqual(fn["linkage"], "")
42234223

42244224

4225+
# Github PR 85
4226+
class ContainerOfArray_TestCase(unittest.TestCase):
4227+
def setUp(self):
4228+
self.cppHeader = CppHeaderParser.CppHeader(
4229+
"""
4230+
class ContainerOfArray {
4231+
public:
4232+
std::unique_ptr<int[]> variable;
4233+
std::unique_ptr<int[]> function(std::unique_ptr<int[]> param1);
4234+
};
4235+
""",
4236+
"string",
4237+
)
4238+
4239+
def test_rtntype(self):
4240+
self.assertEqual(
4241+
self.cppHeader.classes["ContainerOfArray"]["methods"]["public"][0][
4242+
"rtnType"
4243+
],
4244+
"std::unique_ptr<int [ ] >",
4245+
)
4246+
4247+
def test_parameters(self):
4248+
self.assertEqual(
4249+
filter_pameters(
4250+
self.cppHeader.classes["ContainerOfArray"]["methods"]["public"][0][
4251+
"parameters"
4252+
]
4253+
),
4254+
[{"name": "param1", "desc": None, "type": "std::unique_ptr<int [ ] >"}],
4255+
)
4256+
4257+
def test_member(self):
4258+
self.assertEqual(
4259+
self.cppHeader.classes["ContainerOfArray"]["properties"]["public"][0][
4260+
"name"
4261+
],
4262+
"variable",
4263+
)
4264+
self.assertEqual(
4265+
self.cppHeader.classes["ContainerOfArray"]["properties"]["public"][0][
4266+
"type"
4267+
],
4268+
"std::unique_ptr<int [ ] >",
4269+
)
4270+
4271+
4272+
class InitBracket_TestCase(unittest.TestCase):
4273+
def setUp(self):
4274+
self.cppHeader = CppHeaderParser.CppHeader(
4275+
"""
4276+
class InitBracket {
4277+
public:
4278+
int variable{10};
4279+
std::shared_ptr<int> variable2 {std::make_shared<int>(150)};
4280+
};
4281+
""",
4282+
"string",
4283+
)
4284+
4285+
def test_member(self):
4286+
self.assertEqual(
4287+
self.cppHeader.classes["InitBracket"]["properties"]["public"][0]["name"],
4288+
"variable",
4289+
)
4290+
self.assertEqual(
4291+
self.cppHeader.classes["InitBracket"]["properties"]["public"][0][
4292+
"defaultValue"
4293+
],
4294+
"10",
4295+
)
4296+
self.assertEqual(
4297+
self.cppHeader.classes["InitBracket"]["properties"]["public"][1]["name"],
4298+
"variable2",
4299+
)
4300+
self.assertEqual(
4301+
self.cppHeader.classes["InitBracket"]["properties"]["public"][1][
4302+
"defaultValue"
4303+
],
4304+
"std::make_shared<int> ( 150 )",
4305+
)
4306+
4307+
42254308
if __name__ == "__main__":
42264309
unittest.main()

0 commit comments

Comments
 (0)