@@ -312,23 +312,23 @@ def values(self):
312312 def items (self ):
313313 return self .typedefs .items ()
314314
315- def getEnumTypes (self ):
316- retVal : list [EnumType ] = []
315+ def getTypes (self , classType ):
316+ retVal : list [classType ] = []
317317 allTypes = self .typedefs
318318 for currentType in allTypes .values ():
319- if isinstance (currentType , EnumType ):
319+ if isinstance (currentType , classType ):
320320 retVal .append (currentType )
321321
322322 return retVal
323323
324+ def getEnumTypes (self ):
325+ return self .getTypes (EnumType )
326+
324327 def getStructTypes (self ):
325- retVal : list [StructureType ] = []
326- allTypes = self .typedefs
327- for currentType in allTypes .values ():
328- if isinstance (currentType , StructureType ):
329- retVal .append (currentType )
328+ return self .getTypes (StructureType )
330329
331- return retVal
330+ def getMacroTypes (self ):
331+ return self .getTypes (MacroType )
332332
333333
334334class Parser (object ):
@@ -360,10 +360,14 @@ class CStyleParser(Parser):
360360
361361 def __init__ (self , cstruct , compiled = True ):
362362 self .compiled = compiled
363+ self .clearVersionDetails ()
363364 super (CStyleParser , self ).__init__ (cstruct )
364365
365- # TODO: Implement proper parsing
366+ def clearVersionDetails (self ):
367+ self .structVersionDetails = {"name" :"" , "valB" :2 ** 16 - 1 , "valL" :0 }
368+
366369 def parse (self , data ):
370+ self ._macros (data )
367371 self ._constants (data )
368372 self ._enums (data )
369373 self ._structs (data )
@@ -467,13 +471,68 @@ def _structs(self, data):
467471 self .cstruct .addtype (td , st )
468472
469473 def _parse_fields_struct (self , s ):
474+ def getNumber (sign :str , number :int ):
475+ retVal = number
476+ direction = "="
477+
478+ if "<" in sign :
479+ direction = "<"
480+ if "=" not in sign :
481+ retVal -= 1
482+ elif ">" in sign :
483+ direction = ">"
484+ if "=" not in sign :
485+ retVal += 1
486+ elif "=" in sign :
487+ pass
488+ else :
489+ retVal = None
490+ direction = None
491+
492+ return retVal ,direction
493+
494+ regex = r'(?P<if>#if\s*(?P<macroNameA>\w+)\s*(?P<signA>[<>=]*?)\s*(?P<valueA>[0-9]+)\s*(?:and\s*(?P<macroNameB>\w+)\s*(?P<signB>[<>=]*?)\s*(?P<valueB>[0-9]+))?)?\s*' + COMMENT_REGEX_START + r'(?P<type>[^\s]+)\s+(?P<name>[^\s\[:]+)(\s*:\s*(?P<bits>\d+))?(\[(?P<count>[^;\n]*)\])?;' + COMMENT_REGEX_END + r'(?P<endif>\s*#endif.*)?'
470495 fields = re .finditer (
471- COMMENT_REGEX_START + r'(?P<type>[^\s]+)\s+(?P<name>[^\s\[:]+)(\s*:\s*(?P<bits>\d+))?(\[(?P<count>[^;\n]*)\])?;' + COMMENT_REGEX_END ,
496+ regex ,
472497 s , re .MULTILINE
473498 )
474499 r :list [StructureFieldType ] = []
500+
475501 for f in fields :
476502 d = f .groupdict ()
503+ # print(regex)
504+ # print(d)
505+ if d .get ("if" ,None ) != None :
506+ macroNameA = d .get ('macroNameA' ,None )
507+ signA = d .get ('signA' ,None )
508+ valueA = d .get ('valueA' ,None )
509+ macroNameB = d .get ('macroNameB' , None )
510+ signB = d .get ('signB' ,None )
511+ valueB = d .get ('valueB' , None )
512+ if macroNameB != None and macroNameB != macroNameA :
513+ raise Exception (f"Expected macroNameA==macroNameB got { macroNameA } !={ macroNameB } " )
514+ self .structVersionDetails ["name" ] = macroNameA
515+ numA ,dirA = getNumber (signA , valueA )
516+ if dirA == "=" :
517+ self .structVersionDetails ["valL" ] = valueA
518+ self .structVersionDetails ["valB" ] = valueA
519+ else :
520+ if dirA == "<" :
521+ self .structVersionDetails ["valB" ] = numA
522+ elif dirA == ">" :
523+ self .structVersionDetails ["valL" ] = numA
524+ if signB != None :
525+ numB ,dirB = getNumber (signB , valueB )
526+ if dirA == dirB :
527+ raise Exception (f"Expected dirA different sign <> than dirB got { dirA } =={ dirB } " )
528+ if dirB == "<" :
529+ self .structVersionDetails ["valB" ] = numB
530+ elif dirB == ">" :
531+ self .structVersionDetails ["valL" ] = numB
532+ continue
533+ if d .get ("endif" ,None ) != None :
534+ self .clearVersionDetails ()
535+ continue
477536 if d ['type' ].startswith ('//' ):
478537 continue
479538
@@ -501,7 +560,7 @@ def _parse_fields_struct(self, s):
501560 d ['name' ] = d ['name' ][1 :]
502561 type_ = Pointer (self .cstruct , type_ )
503562
504- field = StructureFieldType (d ['name' ], type_ , int (d ['bits' ]) if d ['bits' ] else None , commentAttributes = commentAttributes )
563+ field = StructureFieldType (d ['name' ], type_ , int (d ['bits' ]) if d ['bits' ] else None , commentAttributes = commentAttributes , versionDetails = self . structVersionDetails . copy () )
505564 r .append (field )
506565
507566 return r
@@ -527,6 +586,19 @@ def parse_comment_block(self,s):
527586
528587 return commentAttributes
529588
589+ def _macros (self , s ):
590+ r = re .finditer (
591+ COMMENT_REGEX_START + r'#define\s*(?P<name>[A-Za-z0-9_]+)\s+(?P<value>[A-Za-z0-9_"()])' + COMMENT_REGEX_END ,
592+ s , re .MULTILINE
593+ )
594+
595+ for t in r :
596+ d = t .groupdict ()
597+
598+ mt = MacroType (self .cstruct , d ["name" ], d ["value" ])
599+
600+ self .cstruct .addtype (d ['name' ], mt , True )
601+
530602 def _lookups (self , data ):
531603 r = re .finditer (r'\$(?P<name>[^\s]+) = ({[^}]+})\w*\n' , data )
532604
@@ -1081,12 +1153,13 @@ def reset(self):
10811153class StructureFieldType (object ):
10821154 """Holds a structure field."""
10831155
1084- def __init__ (self , name :str , type_ :typeAll , bits = None , offset :typing .Union [int ,None ]= None , commentAttributes :typeCommentAttributes = {}):
1156+ def __init__ (self , name :str , type_ :typeAll , bits = None , offset :typing .Union [int ,None ]= None , commentAttributes :typeCommentAttributes = {}, versionDetails = {} ):
10851157 self .name :str = name
10861158 self .type :typeAll = type_
10871159 self .bits = bits
10881160 self .offset :typing .Union [int ,None ] = offset
10891161 self .commentAttributes :typeCommentAttributes = commentAttributes
1162+ self .versionDetails = versionDetails
10901163
10911164 def __repr__ (self ):
10921165 return '<Field {} {} {}>' .format (self .name , self .type , self .commentAttributes )
@@ -1466,6 +1539,13 @@ def __repr__(self):
14661539 return '<EnumType {}>' .format (self .name )
14671540
14681541
1542+ class MacroType (RawType ):
1543+ def __init__ (self , cstruct , name :str , value :typing .Any ):
1544+ self .name = name
1545+ self .value = value
1546+ super (MacroType , self ).__init__ (cstruct , name , 0 )
1547+
1548+
14691549class EnumInstance (object ):
14701550 """Implements a value instance of an EnumType"""
14711551
0 commit comments