dissect.cstruct 4.6.dev6__tar.gz → 4.6.dev8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/PKG-INFO +1 -1
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/parser.py +80 -3
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect.cstruct.egg-info/PKG-INFO +1 -1
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_parser.py +134 -4
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/.git-blame-ignore-revs +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/.gitattributes +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/CHANGELOG.md +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/COPYRIGHT +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/LICENSE +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/MANIFEST.in +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/README.md +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/__init__.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/bitbuffer.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/compiler.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/cstruct.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/exceptions.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/expression.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/tools/__init__.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/tools/stubgen.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/types/__init__.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/types/base.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/types/char.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/types/enum.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/types/flag.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/types/int.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/types/leb128.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/types/packed.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/types/pointer.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/types/structure.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/types/void.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/types/wchar.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect/cstruct/utils.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect.cstruct.egg-info/SOURCES.txt +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect.cstruct.egg-info/dependency_links.txt +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect.cstruct.egg-info/entry_points.txt +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect.cstruct.egg-info/requires.txt +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect.cstruct.egg-info/top_level.txt +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/examples/disk.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/examples/mirai.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/examples/pe.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/examples/protobuf.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/examples/secdesc.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/pyproject.toml +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/setup.cfg +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/__init__.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/_data/testdef.txt +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/_docs/Makefile +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/_docs/__init__.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/_docs/conf.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/_docs/index.rst +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/conftest.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_align.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_annotations.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_basic.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_bitbuffer.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_bitfield.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_compiler.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_ctypes.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_expression.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_tools_stubgen.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_types_base.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_types_char.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_types_custom.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_types_enum.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_types_flag.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_types_int.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_types_leb128.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_types_packed.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_types_pointer.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_types_structure.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_types_union.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_types_void.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_types_wchar.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/test_utils.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tests/utils.py +0 -0
- {dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/tox.ini +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dissect.cstruct
|
|
3
|
-
Version: 4.6.
|
|
3
|
+
Version: 4.6.dev8
|
|
4
4
|
Summary: A Dissect module implementing a parser for C-like structures: structure parsing in Python made easy
|
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
|
6
6
|
License: Apache License 2.0
|
|
@@ -49,12 +49,19 @@ class TokenParser(Parser):
|
|
|
49
49
|
self.compiled = compiled
|
|
50
50
|
self.align = align
|
|
51
51
|
self.TOK = self._tokencollection()
|
|
52
|
+
self._conditionals = []
|
|
53
|
+
self._conditionals_depth = 0
|
|
52
54
|
|
|
53
55
|
@staticmethod
|
|
54
56
|
def _tokencollection() -> TokenCollection:
|
|
55
57
|
TOK = TokenCollection()
|
|
56
58
|
TOK.add(r"#\[(?P<values>[^\]]+)\](?=\s*)", "CONFIG_FLAG")
|
|
57
|
-
TOK.add(r"#define\s+(?P<name>[^\s]+)
|
|
59
|
+
TOK.add(r"#define\s+(?P<name>[^\s]+)(?P<value>[^\r\n]*)", "DEFINE")
|
|
60
|
+
TOK.add(r"#undef\s+(?P<name>[^\s]+)\s*", "UNDEF")
|
|
61
|
+
TOK.add(r"#ifdef\s+(?P<name>[^\s]+)\s*", "IFDEF")
|
|
62
|
+
TOK.add(r"#ifndef\s+(?P<name>[^\s]+)\s*", "IFNDEF")
|
|
63
|
+
TOK.add(r"#else\s*", "ELSE")
|
|
64
|
+
TOK.add(r"#endif\s*", "ENDIF")
|
|
58
65
|
TOK.add(r"typedef(?=\s)", "TYPEDEF")
|
|
59
66
|
TOK.add(r"(?:struct|union)(?=\s|{)", "STRUCT")
|
|
60
67
|
TOK.add(
|
|
@@ -80,12 +87,61 @@ class TokenParser(Parser):
|
|
|
80
87
|
idents.append(tokens.consume())
|
|
81
88
|
return " ".join([i.value for i in idents])
|
|
82
89
|
|
|
90
|
+
def _conditional(self, tokens: TokenConsumer) -> None:
|
|
91
|
+
token = tokens.consume()
|
|
92
|
+
pattern = self.TOK.patterns[token.token]
|
|
93
|
+
match = pattern.match(token.value).groupdict()
|
|
94
|
+
|
|
95
|
+
value = match["name"]
|
|
96
|
+
|
|
97
|
+
if token.token == self.TOK.IFDEF:
|
|
98
|
+
self._conditionals.append(value in self.cstruct.consts)
|
|
99
|
+
elif token.token == self.TOK.IFNDEF:
|
|
100
|
+
self._conditionals.append(value not in self.cstruct.consts)
|
|
101
|
+
|
|
102
|
+
def _check_conditional(self, tokens: TokenConsumer) -> bool:
|
|
103
|
+
"""Check and handle conditionals. Return a boolean indicating if we need to continue to the next token."""
|
|
104
|
+
if self._conditionals and self._conditionals_depth == len(self._conditionals):
|
|
105
|
+
# If we have a conditional and the depth matches, handle it accordingly
|
|
106
|
+
if tokens.next == self.TOK.ELSE:
|
|
107
|
+
# Flip the last conditional
|
|
108
|
+
tokens.consume()
|
|
109
|
+
self._conditionals[-1] = not self._conditionals[-1]
|
|
110
|
+
return True
|
|
111
|
+
|
|
112
|
+
if tokens.next == self.TOK.ENDIF:
|
|
113
|
+
# Pop the last conditional
|
|
114
|
+
tokens.consume()
|
|
115
|
+
self._conditionals.pop()
|
|
116
|
+
self._conditionals_depth -= 1
|
|
117
|
+
return True
|
|
118
|
+
|
|
119
|
+
if tokens.next in (self.TOK.IFDEF, self.TOK.IFNDEF):
|
|
120
|
+
# If we encounter a new conditional, increase the depth
|
|
121
|
+
self._conditionals_depth += 1
|
|
122
|
+
|
|
123
|
+
if tokens.next == self.TOK.ENDIF:
|
|
124
|
+
# Similarly, decrease the depth if needed
|
|
125
|
+
self._conditionals_depth -= 1
|
|
126
|
+
|
|
127
|
+
if self._conditionals and not self._conditionals[-1]:
|
|
128
|
+
# If the last conditional evaluated to False, skip the next token
|
|
129
|
+
tokens.consume()
|
|
130
|
+
return True
|
|
131
|
+
|
|
132
|
+
if tokens.next in (self.TOK.IFDEF, self.TOK.IFNDEF):
|
|
133
|
+
# If the next token is a conditional, process it
|
|
134
|
+
self._conditional(tokens)
|
|
135
|
+
return True
|
|
136
|
+
|
|
137
|
+
return False
|
|
138
|
+
|
|
83
139
|
def _constant(self, tokens: TokenConsumer) -> None:
|
|
84
140
|
const = tokens.consume()
|
|
85
141
|
pattern = self.TOK.patterns[self.TOK.DEFINE]
|
|
86
142
|
match = pattern.match(const.value).groupdict()
|
|
87
143
|
|
|
88
|
-
value = match["value"]
|
|
144
|
+
value = match["value"].strip()
|
|
89
145
|
try:
|
|
90
146
|
value = ast.literal_eval(value)
|
|
91
147
|
except (ValueError, SyntaxError):
|
|
@@ -99,6 +155,16 @@ class TokenParser(Parser):
|
|
|
99
155
|
|
|
100
156
|
self.cstruct.consts[match["name"]] = value
|
|
101
157
|
|
|
158
|
+
def _undef(self, tokens: TokenConsumer) -> None:
|
|
159
|
+
const = tokens.consume()
|
|
160
|
+
pattern = self.TOK.patterns[self.TOK.UNDEF]
|
|
161
|
+
match = pattern.match(const.value).groupdict()
|
|
162
|
+
|
|
163
|
+
if match["name"] in self.cstruct.consts:
|
|
164
|
+
del self.cstruct.consts[match["name"]]
|
|
165
|
+
else:
|
|
166
|
+
raise ParserError(f"line {self._lineno(const)}: constant {match['name']!r} not defined")
|
|
167
|
+
|
|
102
168
|
def _enum(self, tokens: TokenConsumer) -> None:
|
|
103
169
|
# We cheat with enums because the entire enum is in the token
|
|
104
170
|
etok = tokens.consume()
|
|
@@ -208,6 +274,9 @@ class TokenParser(Parser):
|
|
|
208
274
|
tokens.consume()
|
|
209
275
|
break
|
|
210
276
|
|
|
277
|
+
if self._check_conditional(tokens):
|
|
278
|
+
continue
|
|
279
|
+
|
|
211
280
|
field = self._parse_field(tokens)
|
|
212
281
|
fields.append(field)
|
|
213
282
|
|
|
@@ -266,7 +335,7 @@ class TokenParser(Parser):
|
|
|
266
335
|
return Field(None, type_, None)
|
|
267
336
|
|
|
268
337
|
if tokens.next != self.TOK.NAME:
|
|
269
|
-
raise ParserError(f"line {self._lineno(tokens.next)}: expected name")
|
|
338
|
+
raise ParserError(f"line {self._lineno(tokens.next)}: expected name, got {tokens.next!r}")
|
|
270
339
|
nametok = tokens.consume()
|
|
271
340
|
|
|
272
341
|
type_, name, bits = self._parse_field_type(type_, nametok.value)
|
|
@@ -378,10 +447,15 @@ class TokenParser(Parser):
|
|
|
378
447
|
if token is None:
|
|
379
448
|
break
|
|
380
449
|
|
|
450
|
+
if self._check_conditional(tokens):
|
|
451
|
+
continue
|
|
452
|
+
|
|
381
453
|
if token == self.TOK.CONFIG_FLAG:
|
|
382
454
|
self._config_flag(tokens)
|
|
383
455
|
elif token == self.TOK.DEFINE:
|
|
384
456
|
self._constant(tokens)
|
|
457
|
+
elif token == self.TOK.UNDEF:
|
|
458
|
+
self._undef(tokens)
|
|
385
459
|
elif token == self.TOK.TYPEDEF:
|
|
386
460
|
self._typedef(tokens)
|
|
387
461
|
elif token == self.TOK.STRUCT:
|
|
@@ -395,6 +469,9 @@ class TokenParser(Parser):
|
|
|
395
469
|
else:
|
|
396
470
|
raise ParserError(f"line {self._lineno(token)}: unexpected token {token!r}")
|
|
397
471
|
|
|
472
|
+
if self._conditionals:
|
|
473
|
+
raise ParserError(f"line {self._lineno(tokens.previous)}: unclosed conditional statement")
|
|
474
|
+
|
|
398
475
|
|
|
399
476
|
class CStyleParser(Parser):
|
|
400
477
|
"""Definition parser for C-like structure syntax.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dissect.cstruct
|
|
3
|
-
Version: 4.6.
|
|
3
|
+
Version: 4.6.dev8
|
|
4
4
|
Summary: A Dissect module implementing a parser for C-like structures: structure parsing in Python made easy
|
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
|
6
6
|
License: Apache License 2.0
|
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from typing import TYPE_CHECKING
|
|
4
3
|
from unittest.mock import Mock
|
|
5
4
|
|
|
6
5
|
import pytest
|
|
7
6
|
|
|
7
|
+
from dissect.cstruct import cstruct
|
|
8
8
|
from dissect.cstruct.exceptions import ParserError
|
|
9
9
|
from dissect.cstruct.parser import TokenParser
|
|
10
10
|
from dissect.cstruct.types import BaseArray, Pointer, Structure
|
|
11
11
|
from tests.utils import verify_compiled
|
|
12
12
|
|
|
13
|
-
if TYPE_CHECKING:
|
|
14
|
-
from dissect.cstruct import cstruct
|
|
15
|
-
|
|
16
13
|
|
|
17
14
|
def test_nested_structs(cs: cstruct, compiled: bool) -> None:
|
|
18
15
|
cdef = """
|
|
@@ -164,3 +161,136 @@ def test_typedef_pointer(cs: cstruct) -> None:
|
|
|
164
161
|
assert cs.IMAGE_DATA_DIRECTORY is cs._IMAGE_DATA_DIRECTORY
|
|
165
162
|
assert issubclass(cs.PIMAGE_DATA_DIRECTORY, Pointer)
|
|
166
163
|
assert cs.PIMAGE_DATA_DIRECTORY.type == cs._IMAGE_DATA_DIRECTORY
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def test_undef(cs: cstruct) -> None:
|
|
167
|
+
cdef = """
|
|
168
|
+
#define MY_CONST 42
|
|
169
|
+
#undef MY_CONST
|
|
170
|
+
"""
|
|
171
|
+
cs.load(cdef)
|
|
172
|
+
|
|
173
|
+
assert "MY_CONST" not in cs.consts
|
|
174
|
+
|
|
175
|
+
with pytest.raises(ParserError, match="line 1: constant 'MY_CONST' not defined"):
|
|
176
|
+
cs.load("#undef MY_CONST") # This should raise an error since MY_CONST is not defined
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def test_conditional_ifdef(cs: cstruct) -> None:
|
|
180
|
+
cdef = """
|
|
181
|
+
#define MY_CONST 42
|
|
182
|
+
|
|
183
|
+
#ifdef MY_CONST
|
|
184
|
+
struct test {
|
|
185
|
+
uint32 a;
|
|
186
|
+
};
|
|
187
|
+
#endif
|
|
188
|
+
"""
|
|
189
|
+
cs.load(cdef)
|
|
190
|
+
|
|
191
|
+
assert "test" in cs.typedefs
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
def test_conditional_ifndef(cs: cstruct) -> None:
|
|
195
|
+
cdef = """
|
|
196
|
+
#ifndef MYVAR
|
|
197
|
+
#define MYVAR (1)
|
|
198
|
+
#endif
|
|
199
|
+
"""
|
|
200
|
+
cs.load(cdef)
|
|
201
|
+
|
|
202
|
+
assert "MYVAR" in cs.consts
|
|
203
|
+
assert cs.consts["MYVAR"] == 1
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def test_conditional_ifndef_guard(cs: cstruct) -> None:
|
|
207
|
+
cdef = """
|
|
208
|
+
/* Define Guard */
|
|
209
|
+
#ifndef __MYGUARD
|
|
210
|
+
#define __MYGUARD
|
|
211
|
+
|
|
212
|
+
typedef struct myStruct
|
|
213
|
+
{
|
|
214
|
+
char charVal[16];
|
|
215
|
+
}
|
|
216
|
+
#endif // __MYGUARD
|
|
217
|
+
"""
|
|
218
|
+
cs.load(cdef)
|
|
219
|
+
|
|
220
|
+
assert "__MYGUARD" in cs.consts
|
|
221
|
+
assert "myStruct" in cs.typedefs
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def test_conditional_nested() -> None:
|
|
225
|
+
cdef = """
|
|
226
|
+
#ifndef MYSWITCH1
|
|
227
|
+
#define MYVAR1 (1)
|
|
228
|
+
#else
|
|
229
|
+
#ifdef MYSWITCH2
|
|
230
|
+
#define MYVAR1 (2)
|
|
231
|
+
#else
|
|
232
|
+
#define MYVAR1 (3)
|
|
233
|
+
#endif
|
|
234
|
+
#endif
|
|
235
|
+
"""
|
|
236
|
+
cs = cstruct().load(cdef)
|
|
237
|
+
|
|
238
|
+
assert "MYVAR1" in cs.consts
|
|
239
|
+
assert cs.consts["MYVAR1"] == 1
|
|
240
|
+
|
|
241
|
+
cs = cstruct().load("#define MYSWITCH1")
|
|
242
|
+
|
|
243
|
+
assert "MYSWITCH1" in cs.consts
|
|
244
|
+
|
|
245
|
+
cs.load(cdef)
|
|
246
|
+
|
|
247
|
+
assert "MYVAR1" in cs.consts
|
|
248
|
+
assert cs.consts["MYVAR1"] == 3
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def test_conditional_in_struct(cs: cstruct) -> None:
|
|
252
|
+
cdef = """
|
|
253
|
+
struct t_bitfield {
|
|
254
|
+
union {
|
|
255
|
+
struct {
|
|
256
|
+
uint32_t bit0:1;
|
|
257
|
+
uint32_t bit1:1;
|
|
258
|
+
#ifdef MYSWT
|
|
259
|
+
uint32_t bit2:1;
|
|
260
|
+
#endif
|
|
261
|
+
} fval;
|
|
262
|
+
uint32_t bits;
|
|
263
|
+
};
|
|
264
|
+
};
|
|
265
|
+
"""
|
|
266
|
+
cs.load(cdef)
|
|
267
|
+
|
|
268
|
+
assert "t_bitfield" in cs.typedefs
|
|
269
|
+
assert "fval" in cs.t_bitfield.fields
|
|
270
|
+
assert "bit0" in cs.t_bitfield.fields["fval"].type.fields
|
|
271
|
+
assert "bit1" in cs.t_bitfield.fields["fval"].type.fields
|
|
272
|
+
assert "bit2" not in cs.t_bitfield.fields["fval"].type.fields
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
def test_conditional_parsing_error(cs: cstruct) -> None:
|
|
276
|
+
cdef = """
|
|
277
|
+
#ifndef __HELP
|
|
278
|
+
#define __HELP
|
|
279
|
+
#endif
|
|
280
|
+
struct test {
|
|
281
|
+
uint32 a;
|
|
282
|
+
};
|
|
283
|
+
#endif
|
|
284
|
+
"""
|
|
285
|
+
with pytest.raises(ParserError, match="line 8: unexpected token .+ENDIF"):
|
|
286
|
+
cs.load(cdef)
|
|
287
|
+
|
|
288
|
+
cdef = """
|
|
289
|
+
#ifndef __HELP
|
|
290
|
+
#define __HELP
|
|
291
|
+
struct test {
|
|
292
|
+
uint32 a;
|
|
293
|
+
};
|
|
294
|
+
"""
|
|
295
|
+
with pytest.raises(ParserError, match="line 6: unclosed conditional statement"):
|
|
296
|
+
cs.load(cdef)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect.cstruct.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect.cstruct.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
{dissect_cstruct-4.6.dev6 → dissect_cstruct-4.6.dev8}/dissect.cstruct.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|