2
2
3
3
import ast
4
4
import re
5
- from typing import TYPE_CHECKING , Dict , List
5
+ from typing import TYPE_CHECKING , Dict , List , Optional
6
6
7
7
from dissect .cstruct .compiler import Compiler
8
8
from dissect .cstruct .exceptions import ParserError
9
9
from dissect .cstruct .expression import Expression
10
- from dissect .cstruct .types import Array , Enum , Field , Flag , Pointer , Structure , Union
10
+ from dissect .cstruct .types import (
11
+ Array ,
12
+ BaseType ,
13
+ Enum ,
14
+ Field ,
15
+ Flag ,
16
+ Pointer ,
17
+ Structure ,
18
+ Union ,
19
+ )
11
20
12
21
if TYPE_CHECKING :
13
22
from dissect .cstruct import cstruct
@@ -158,6 +167,9 @@ def _typedef(self, tokens: TokenConsumer) -> None:
158
167
159
168
names = self ._names (tokens )
160
169
for name in names :
170
+ type_ , name , bits = self ._parse_field_type (type_ , name )
171
+ if bits is not None :
172
+ raise ParserError (f"line { self ._lineno (tokens .previous )} : typedefs cannot have bitfields" )
161
173
self .cstruct .addtype (name , type_ )
162
174
163
175
def _struct (self , tokens : TokenConsumer , register : bool = False ) -> None :
@@ -236,9 +248,15 @@ def _parse_field(self, tokens: TokenConsumer) -> Field:
236
248
raise ParserError (f"line { self ._lineno (tokens .next )} : expected name" )
237
249
nametok = tokens .consume ()
238
250
251
+ type_ , name , bits = self ._parse_field_type (type_ , nametok .value )
252
+
253
+ tokens .eol ()
254
+ return Field (name .strip (), type_ , bits )
255
+
256
+ def _parse_field_type (self , type_ : BaseType , name : str ) -> tuple [BaseType , str , Optional [int ]]:
239
257
pattern = self .TOK .patterns [self .TOK .NAME ]
240
258
# Dirty trick because the regex expects a ; but we don't want it to be part of the value
241
- d = pattern .match (nametok . value + ";" ).groupdict ()
259
+ d = pattern .match (name + ";" ).groupdict ()
242
260
243
261
name = d ["name" ]
244
262
count_expression = d ["count" ]
@@ -269,8 +287,7 @@ def _parse_field(self, tokens: TokenConsumer) -> Field:
269
287
270
288
type_ = Array (self .cstruct , type_ , count )
271
289
272
- tokens .eol ()
273
- return Field (name , type_ , int (d ["bits" ]) if d ["bits" ] else None )
290
+ return type_ , name , int (d ["bits" ]) if d ["bits" ] else None
274
291
275
292
def _names (self , tokens : TokenConsumer ) -> List [str ]:
276
293
names = []
@@ -564,6 +581,7 @@ class TokenConsumer:
564
581
def __init__ (self , tokens : List [Token ]):
565
582
self .tokens = tokens
566
583
self .flags = []
584
+ self .previous = None
567
585
568
586
def __contains__ (self , token ) -> bool :
569
587
return token in self .tokens
@@ -582,7 +600,8 @@ def next(self) -> Token:
582
600
return None
583
601
584
602
def consume (self ) -> Token :
585
- return self .tokens .pop (0 )
603
+ self .previous = self .tokens .pop (0 )
604
+ return self .previous
586
605
587
606
def reset_flags (self ) -> None :
588
607
self .flags = []
0 commit comments