Skip to content

Commit 952f4c5

Browse files
committed
Remove parseHistory, improve class ending
- Support anonymous structs/classes in addition to unions
1 parent 2b4c628 commit 952f4c5

File tree

1 file changed

+51
-70
lines changed

1 file changed

+51
-70
lines changed

CppHeaderParser/CppHeaderParser.py

Lines changed: 51 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -142,10 +142,6 @@ def trace_print(*args):
142142
ignoreSymbols = ["Q_OBJECT"]
143143

144144

145-
# Track what was added in what order and at what depth
146-
parseHistory = []
147-
148-
149145
def is_namespace(nameStack):
150146
"""Determines if a namespace is being specified"""
151147
if len(nameStack) == 0:
@@ -2379,14 +2375,6 @@ def _evaluate_method_stack(self):
23792375
)
23802376
newMethod["parent"] = None
23812377
self.functions.append(newMethod)
2382-
global parseHistory
2383-
parseHistory.append(
2384-
{
2385-
"braceDepth": self.braceDepth,
2386-
"item_type": "method",
2387-
"item": newMethod,
2388-
}
2389-
)
23902378
else:
23912379
trace_print("free function?", self.nameStack)
23922380

@@ -2443,21 +2431,20 @@ def _evaluate_typedef(self):
24432431
if name not in self.typedefs_order:
24442432
self.typedefs_order.append(name)
24452433

2446-
def _finish_struct_typedef(self):
2434+
def _finish_struct_typedef(self, toks):
24472435
# Look for the name of a typedef struct: struct typedef {...] StructName; or unions to get renamed
24482436
debug_print("finish struct typedef")
24492437
self.typedef_encountered = False
24502438

2451-
toks = self._consume_up_to([], ";")
2452-
2453-
# grab the first name token, TODO: typedef struct{} X, *PX;
2439+
# grab the first name token
24542440
for tok in toks:
24552441
if tok.type == "NAME":
24562442
new_name = tok.value
24572443
break
24582444
else:
24592445
return
24602446

2447+
# TODO: typedef struct{} X, *PX;
24612448
type_name_to_rename = self.curClass["name"]
24622449
type_to_rename = self.classes[type_name_to_rename]
24632450
type_to_rename["name"] = new_name
@@ -2466,10 +2453,52 @@ def _finish_struct_typedef(self):
24662453
if new_name != type_name_to_rename:
24672454
del self.classes[type_name_to_rename]
24682455

2456+
def _finish_class_def(self):
2457+
2458+
# starting at the last } of a class/struct/union
2459+
debug_print("finish_class_def")
2460+
2461+
# consume any names for parsing
2462+
toks = self._consume_up_to([], ";")
2463+
2464+
is_typedef = self.typedef_encountered
2465+
if is_typedef:
2466+
self._finish_struct_typedef(toks)
2467+
2468+
thisClass = self.curClass
2469+
self.curClass = thisClass["parent"]
2470+
2471+
if not is_typedef:
2472+
if len(toks) > 1:
2473+
# Deal with "struct { } x;" style of things
2474+
expected_types = {",", "NAME", "*", ";"}
2475+
stack = [thisClass["name"]]
2476+
for tok in toks:
2477+
stack.append(tok.value)
2478+
if tok.type not in expected_types:
2479+
self._parse_error((tok,), ",".join(expected_types))
2480+
2481+
self.nameStack = stack[:-1]
2482+
self.stack = stack
2483+
self.stmtTokens = toks
2484+
2485+
self._evaluate_property_stack(clearStack=False)
2486+
2487+
elif self.curClass and thisClass["name"].startswith("<"):
2488+
# anonymous class struct/union
2489+
stack = [thisClass["name"], "", ";"]
2490+
self.nameStack = stack[:-1]
2491+
self.stack = stack
2492+
2493+
self._evaluate_property_stack(clearStack=False)
2494+
2495+
self.stack = []
2496+
self.nameStack = []
2497+
self.stmtTokens = []
2498+
24692499
def _evaluate_property_stack(self, clearStack=True, addToVar=None):
24702500
"""Create a Property out of the name stack"""
2471-
global parseHistory
2472-
debug_print("trace")
2501+
debug_print("evaluate_property_stack")
24732502
if self.nameStack[0] == "typedef":
24742503
assert self.stack and self.stack[-1] == ";"
24752504
if self.curClass:
@@ -2482,21 +2511,6 @@ def _evaluate_property_stack(self, clearStack=True, addToVar=None):
24822511
else:
24832512
assert 0
24842513
elif self.curClass:
2485-
if len(self.nameStack) == 1:
2486-
# See if we can de anonymize the type
2487-
filteredParseHistory = [
2488-
h for h in parseHistory if h["braceDepth"] == self.braceDepth
2489-
]
2490-
if (
2491-
len(filteredParseHistory)
2492-
and filteredParseHistory[-1]["item_type"] == "class"
2493-
):
2494-
self.nameStack.insert(0, filteredParseHistory[-1]["item"]["name"])
2495-
debug_print(
2496-
"DEANONYMOIZING %s to type '%s'",
2497-
self.nameStack[1],
2498-
self.nameStack[0],
2499-
)
25002514
if "," in self.nameStack: # Maybe we have a variable list
25012515
# Figure out what part is the variable separator but remember templates of function pointer
25022516
# First find left most comma outside of a > and )
@@ -2535,9 +2549,6 @@ def _evaluate_property_stack(self, clearStack=True, addToVar=None):
25352549
klass["properties"][self.curAccessSpecifier].append(newVar)
25362550
newVar["property_of_class"] = klass["name"]
25372551
newVar["parent"] = klass
2538-
parseHistory.append(
2539-
{"braceDepth": self.braceDepth, "item_type": "variable", "item": newVar}
2540-
)
25412552
if addToVar:
25422553
newVar.update(addToVar)
25432554
else:
@@ -2638,10 +2649,6 @@ def _evaluate_class_stack(self):
26382649
newClass.show()
26392650
assert key not in self.classes # namespace collision
26402651
self.classes[key] = newClass
2641-
global parseHistory
2642-
parseHistory.append(
2643-
{"braceDepth": self.braceDepth, "item_type": "class", "item": newClass}
2644-
)
26452652

26462653
def evalute_forward_decl(self):
26472654
trace_print("FORWARD DECL", self.nameStack)
@@ -3003,34 +3010,9 @@ def __init__(self, headerFileName, argType="file", encoding=None, **kwargs):
30033010
self.curAccessSpecifier = self.accessSpecifierStack[-1]
30043011
self.accessSpecifierStack = self.accessSpecifierStack[:-1]
30053012

3006-
if self.curClass and self.typedef_encountered:
3007-
self._finish_struct_typedef()
3013+
if self.curClass:
3014+
self._finish_class_def()
30083015

3009-
if self.curClass and self.curClass["parent"]:
3010-
thisClass = self.curClass
3011-
self.curClass = self.curClass["parent"]
3012-
3013-
# Detect anonymous union members
3014-
if (
3015-
self.curClass
3016-
and thisClass["declaration_method"] == "union"
3017-
and thisClass["name"].startswith("<")
3018-
and self.lex.token_if(";")
3019-
):
3020-
debug_print("Creating anonymous union")
3021-
# Force the processing of an anonymous union
3022-
self.nameStack = [""]
3023-
self.stack = self.nameStack + [";"]
3024-
debug_print("pre eval anon stack")
3025-
self._evaluate_stack(";")
3026-
debug_print("post eval anon stack")
3027-
self.stack = []
3028-
self.nameStack = []
3029-
self.stmtTokens = []
3030-
else:
3031-
self.curClass = None
3032-
self.stack = []
3033-
self.stmtTokens = []
30343016
elif tok.type in _namestack_append_tokens:
30353017
self.nameStack.append(tok.value)
30363018
elif tok.type in _namestack_pass_tokens:
@@ -3110,8 +3092,7 @@ def __init__(self, headerFileName, argType="file", encoding=None, **kwargs):
31103092
)
31113093

31123094
self.finalize()
3113-
global parseHistory
3114-
parseHistory = []
3095+
31153096
# Delete some temporary variables
31163097
for key in [
31173098
"_precomp_macro_buf",
@@ -3181,7 +3162,7 @@ def _consume_up_to(self, rtoks, *token_types):
31813162
rtoks.append(tok)
31823163
if tok.type in token_types:
31833164
break
3184-
3165+
31853166
return rtoks
31863167

31873168
_end_balanced_tokens = {">", "}", "]", ")", "DBL_RBRACKET"}

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