@@ -70,7 +70,7 @@ class {name}(Structure):
7070 def __init__(self, cstruct, structure, source=None):
7171 self.structure = structure
7272 self.source = source
73- super({name}, self).__init__(cstruct, structure.name, structure.fields)
73+ super({name}, self).__init__(cstruct, structure.name, structure.fields, structure.commentAttributes )
7474
7575 def _read(self, stream):
7676 r = OrderedDict()
@@ -88,6 +88,14 @@ def __repr__(self):
8888 return '<Structure {name} +compiled>'
8989"""
9090
91+ COMMENT_MULTILINE = r'/\*[^*]*\*+(?:[^/*][^*]*\*+)*/'
92+ COMMENT_INLINE = r'//[^\n]*'
93+ COMMENT_MULTILINE_REPEATED = r'(^[ ]*(' + COMMENT_INLINE + r'|' + COMMENT_MULTILINE + r'([ ]*(' + COMMENT_INLINE + r'|' + COMMENT_MULTILINE + r'))*)[ \t\r]*\n?)*^[ ]*(' + COMMENT_INLINE + r'|(?P<commentBlock>' + COMMENT_MULTILINE + r'))+'
94+ COMMENT_REGEX_START = r'(' + COMMENT_MULTILINE_REPEATED + r')?[ \t\r\n]*'
95+ COMMENT_REGEX_END = r'(?P<commentBlockAfter>(([ ]*' + COMMENT_MULTILINE + r')+)?[ ]*(' + COMMENT_INLINE + r')?)?[ \t\r]*'
96+
97+ #print(f"COMMENT_REGEX_START:{COMMENT_REGEX_START}")
98+ #print(f"COMMENT_REGEX_END:{COMMENT_REGEX_END}")
9199
92100class Error (Exception ):
93101 pass
@@ -333,44 +341,58 @@ def _constants(self, data):
333341
334342 def _enums (self , data ):
335343 r = re .finditer (
336- r'enum\s+(?P<name>[^\s:{]+)\s*(:\s*(?P<type>[^\s]+)\s*)?\{(?P<values>[^}]+)\}\s*;' ,
337- data ,
344+ COMMENT_REGEX_START + r'enum\s+(?P<name>[^\s:{]+)\s*(:\s*(?P<type>[^\s]+)\s*)?\{(?P<values>[^}]+)\}\s*;' + COMMENT_REGEX_END ,
345+ data , re . MULTILINE
338346 )
339347 for t in r :
340348 d = t .groupdict ()
341349
342- nextval = 0
343- values = {}
344- for line in d ['values' ].split ('\n ' ):
345- line , sep , comment = line .partition ("//" )
346- for v in line .split ("," ):
347- key , sep , val = v .partition ("=" )
348- key = key .strip ()
349- val = val .strip ()
350- if not key :
351- continue
352- if not val :
353- val = nextval
354- else :
355- val = Expression (self .cstruct , val ).evaluate ({})
356-
357- nextval = val + 1
358-
359- values [key ] = val
360-
361350 if not d ['type' ]:
362351 d ['type' ] = 'uint32'
363352
353+ values , valuesDetails = self ._parse_fields_enums (d ['values' ])
354+
355+ commentAttributes = self .parse_comment_block (d ['commentBlock' ])
356+
364357 enum = Enum (
365- self .cstruct , d ['name' ], self .cstruct .resolve (d ['type' ]), values
358+ self .cstruct , d ['name' ], self .cstruct .resolve (d ['type' ]), values , valuesDetails , commentAttributes
366359 )
367360 self .cstruct .addtype (enum .name , enum )
368361
362+ def _parse_fields_enums (self , s ):
363+ nextval = 0
364+ values = {}
365+ valuesDetails = {}
366+ fields = re .finditer (
367+ COMMENT_REGEX_START + r'(?P<value>[a-zA-z][^\n,/]*),?' + COMMENT_REGEX_END ,
368+ s , re .MULTILINE
369+ )
370+
371+ for f in fields :
372+ d = f .groupdict ()
373+
374+ # Ignore fo now
375+ commentAttributes = self .parse_comment_block (d ['commentBlock' ])
376+
377+ field = re .finditer (
378+ r'(?P<key>[a-zA-z][^ =]*)[ ]*=?[ ]*(?P<value>[^ ]+)?' ,
379+ d ["value" ],
380+ )
381+
382+ f = list (field )[0 ].groupdict ()
383+
384+ values [f ["key" ]] = Expression (self .cstruct , f ["value" ]).evaluate ({}) if f ["value" ] != None else nextval
385+
386+ nextval = values [f ["key" ]] + 1
387+ valuesDetails [f ["key" ]] = {"value" :values [f ["key" ]], "commentAttributes" :commentAttributes }
388+
389+ return values , valuesDetails
390+
369391 def _structs (self , data ):
370392 compiler = Compiler (self .cstruct )
371393 r = re .finditer (
372- r'(#(?P<flags>(?:compile))\s+)?((?P<typedef>typedef)\s+)?(?P<type>[^\s]+)\s+(__attribute__\(\([^)]+\)\)\s*)?(?P<name>[^\s]+)?(?P<fields>\s*\{(\s*//[^\n]*|/\*[^*]*\*/|[^}])+\}(?P<defs>\s+[^;\n]+)?)?\s*;' ,
373- data ,
394+ COMMENT_REGEX_START + r'(#(?P<flags>(?:compile))\s+)?((?P<typedef>typedef)\s+)?(?P<type>[^\s]+)\s+(__attribute__\(\([^)]+\)\)\s*)?(?P<name>[^\s]+)?(?P<fields>\s*\{(\s*//[^\n]*|/\*[^*]*\*/|[^}])+\}(?P<defs>\s+[^;\n]+)?)?\s*;' + COMMENT_REGEX_END ,
395+ data , re . MULTILINE
374396 )
375397 for t in r :
376398 d = t .groupdict ()
@@ -383,8 +405,9 @@ def _structs(self, data):
383405 raise ParserError ("No name for struct" )
384406
385407 if d ['type' ] == 'struct' :
386- data = self ._parse_fields (d ['fields' ][1 :- 1 ].strip ())
387- st = Structure (self .cstruct , name , data )
408+ data = self ._parse_fields_struct (d ['fields' ][1 :- 1 ].strip ())
409+ commentAttributes = self .parse_comment_block (d ['commentBlock' ])
410+ st = Structure (self .cstruct , name , data , commentAttributes )
388411 if d ['flags' ] == 'compile' or self .compiled :
389412 st = compiler .compile (st )
390413 elif d ['typedef' ] == 'typedef' :
@@ -400,32 +423,18 @@ def _structs(self, data):
400423 td = td .strip ()
401424 self .cstruct .addtype (td , st )
402425
403- def _parse_fields (self , s ):
404- commentAttributes = {}
426+ def _parse_fields_struct (self , s ):
405427 fields = re .finditer (
406- r'(?P<commentBlock>\/\*(\*(?!\/)|[^*])*\*\/)?[ \t\r\n]*(?P< type>[^\s]+)\s+(?P<name>[^\s\[:]+)(\s*:\s*(?P<bits>\d+))?(\[(?P<count>[^;\n]*)\])?;' ,
407- s ,
428+ COMMENT_REGEX_START + r'(?P<type>[^\s]+)\s+(?P<name>[^\s\[:]+)(\s*:\s*(?P<bits>\d+))?(\[(?P<count>[^;\n]*)\])?;' + COMMENT_REGEX_END ,
429+ s , re . MULTILINE
408430 )
409431 r = []
410432 for f in fields :
411433 d = f .groupdict ()
412434 if d ['type' ].startswith ('//' ):
413435 continue
414436
415- commentAttributes = {}
416-
417- #parse the comment header
418- if d ['commentBlock' ] is not None and d ['commentBlock' ].startswith ('/*' ):
419- commentfields = re .finditer (
420- r'@(?P<commentType>[^@,;:\\]+):[ \t]*(?P<commentVal>[^@,;:\s\\]+)' ,
421- d ['commentBlock' ],
422- )
423- for cf in commentfields :
424- cd = cf .groupdict ()
425- try :
426- commentAttributes [cd ['commentType' ]]= cd ['commentVal' ]
427- except Exception :
428- pass
437+ commentAttributes = self .parse_comment_block (d ['commentBlock' ])
429438
430439 type_ = self .cstruct .resolve (d ['type' ])
431440
@@ -449,11 +458,32 @@ def _parse_fields(self, s):
449458 d ['name' ] = d ['name' ][1 :]
450459 type_ = Pointer (self .cstruct , type_ )
451460
452- field = Field (d ['name' ], type_ , int (d ['bits' ]) if d ['bits' ] else None , commentAttributes = commentAttributes )
461+ field = StructureField (d ['name' ], type_ , int (d ['bits' ]) if d ['bits' ] else None , commentAttributes = commentAttributes )
453462 r .append (field )
454463
455464 return r
456465
466+ def parse_comment_block (self ,s ):
467+ commentAttributes = {}
468+
469+ #parse the comment header
470+ if s is not None and s .startswith ('/*' ):
471+ commentfields = re .finditer (
472+ r'@(?P<commentType>[^@,;:\\]+):[ \t]*(?P<commentVal>[^@\n]+)' ,
473+ s ,
474+ )
475+ for cf in commentfields :
476+ cd = cf .groupdict ()
477+ try :
478+ oldData = commentAttributes .get (cd ['commentType' ],"" )
479+ if "" != oldData :
480+ oldData += " "
481+ commentAttributes [cd ['commentType' ]]= oldData + cd ['commentVal' ]
482+ except Exception :
483+ pass
484+
485+ return commentAttributes
486+
457487 def _lookups (self , data , consts ):
458488 r = re .finditer (r'\$(?P<name>[^\s]+) = ({[^}]+})\w*\n' , data )
459489
@@ -757,11 +787,12 @@ def __repr__(self):
757787class Structure (BaseType ):
758788 """Type class for structures."""
759789
760- def __init__ (self , cstruct , name , fields = None ):
790+ def __init__ (self , cstruct , name , fields = None , commentAttributes = {} ):
761791 self .name = name
762792 self .size = None
763793 self .lookup = OrderedDict ()
764794 self .fields = fields if fields else []
795+ self .commentAttributes = commentAttributes
765796
766797
767798 for f in self .fields :
@@ -885,7 +916,7 @@ def add_fields(self, name, type_, offset=None, commentAttributes={}):
885916 type_: The field type.
886917 offset: The field offset.
887918 """
888- field = Field (name , type_ , offset = offset , commentAttributes = commentAttributes )
919+ field = StructureField (name , type_ , offset = offset , commentAttributes = commentAttributes )
889920 self .fields .append (field )
890921 self .lookup [name ] = field
891922 self .size = None
@@ -915,7 +946,7 @@ def __repr__(self):
915946 def show (self , indent = 0 ):
916947 """Pretty print this structure."""
917948 if indent == 0 :
918- print ("struct {}" .format (self .name ))
949+ print ("{} struct {}" .format (self . commentAttributes , self .name ))
919950
920951 for field in self .fields :
921952 if field .offset is None :
@@ -983,7 +1014,7 @@ def reset(self):
9831014 self ._remaining = 0
9841015
9851016
986- class Field (object ):
1017+ class StructureField (object ):
9871018 """Holds a structure field."""
9881019
9891020 def __init__ (self , name , type_ , bits = None , offset = None , commentAttributes = {}):
@@ -1312,9 +1343,11 @@ class Enum(RawType):
13121343 };
13131344 """
13141345
1315- def __init__ (self , cstruct , name , type_ , values ):
1346+ def __init__ (self , cstruct , name , type_ , values , valuesDetails , commentAttributes = {} ):
13161347 self .type = type_
13171348 self .values = values
1349+ self .valuesDetails = valuesDetails
1350+ self .commentAttributes = commentAttributes
13181351 self .reverse = {}
13191352
13201353 for k , v in values .items ():
@@ -1365,6 +1398,9 @@ def __getattr__(self, attr):
13651398 def __contains__ (self , attr ):
13661399 return attr in self .values
13671400
1401+ def __repr__ (self ):
1402+ return '<Enum {}>' .format (self .name )
1403+
13681404
13691405class EnumInstance (object ):
13701406 """Implements a value instance of an Enum"""
0 commit comments