Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions dissect/cstruct/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,11 +314,11 @@ def _names(self, tokens: TokenConsumer) -> list[str]:
tokens.eol()
break

if tokens.next not in (self.TOK.NAME, self.TOK.DEFS):
if tokens.next not in (self.TOK.NAME, self.TOK.DEFS, self.TOK.IDENTIFIER):
break

ntoken = tokens.consume()
if ntoken == self.TOK.NAME:
if ntoken in (self.TOK.NAME, self.TOK.IDENTIFIER):
names.append(ntoken.value.strip())
elif ntoken == self.TOK.DEFS:
names.extend([name.strip() for name in ntoken.value.strip().split(",")])
Expand Down
3 changes: 3 additions & 0 deletions dissect/cstruct/tools/stubgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ def generate_cstruct_stub(cs: cstruct, module_prefix: str = "", cls_name: str =
stub = f"{name}: TypeAlias = {typedef.__name__}"
elif issubclass(typedef, (types.Enum, types.Flag)):
stub = generate_enum_stub(typedef, cs_prefix=cs_prefix, module_prefix=module_prefix)
elif issubclass(typedef, types.Pointer):
typehint = generate_typehint(typedef, prefix=cs_prefix, module_prefix=module_prefix)
stub = f"{name}: TypeAlias = {typehint}"
elif issubclass(typedef, types.Structure):
stub = generate_structure_stub(typedef, cs_prefix=cs_prefix, module_prefix=module_prefix)
elif issubclass(typedef, types.BaseType):
Expand Down
17 changes: 16 additions & 1 deletion tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from dissect.cstruct.exceptions import ParserError
from dissect.cstruct.parser import TokenParser
from dissect.cstruct.types import BaseArray, Pointer
from dissect.cstruct.types import BaseArray, Pointer, Structure
from tests.utils import verify_compiled

if TYPE_CHECKING:
Expand Down Expand Up @@ -149,3 +149,18 @@ def test_includes(cs: cstruct) -> None:
assert cs.myStruct.__name__ == "myStruct"
assert len(cs.myStruct.fields) == 1
assert cs.myStruct.fields.get("charVal")


def test_typedef_pointer(cs: cstruct) -> None:
cdef = """
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
"""
cs.load(cdef)

assert issubclass(cs._IMAGE_DATA_DIRECTORY, Structure)
assert cs.IMAGE_DATA_DIRECTORY is cs._IMAGE_DATA_DIRECTORY
assert issubclass(cs.PIMAGE_DATA_DIRECTORY, Pointer)
assert cs.PIMAGE_DATA_DIRECTORY.type == cs._IMAGE_DATA_DIRECTORY
20 changes: 20 additions & 0 deletions tests/test_tools_stubgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,26 @@ class cstruct(cstruct):
""",
id="define literals",
),
pytest.param(
"""
typedef struct _Test {
uint8 a;
} Test, *pTest;
""",
"""
class cstruct(cstruct):
class _Test(Structure):
a: cstruct.uint8
@overload
def __init__(self, a: cstruct.uint8 | None = ...): ...
@overload
def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ...

Test: TypeAlias = _Test
pTest: TypeAlias = Pointer[cstruct._Test]
""",
id="pointer alias",
),
],
)
def test_generate_cstruct_stub(cs: cstruct, cdef: str, expected: str) -> None:
Expand Down