diff --git a/scripts/gdb/lvglgdb/__init__.py b/scripts/gdb/lvglgdb/__init__.py index 64e5c071a1..ac6c485392 100644 --- a/scripts/gdb/lvglgdb/__init__.py +++ b/scripts/gdb/lvglgdb/__init__.py @@ -28,6 +28,7 @@ from .lvgl import ( LVImageHeaderCache, create_cache_iterator, LVRedBlackTree, + LVArray, ) from . import cmds as cmds @@ -59,4 +60,5 @@ __all__ = [ "LVImageCache", "LVImageHeaderCache", "create_cache_iterator", + "LVArray", ] diff --git a/scripts/gdb/lvglgdb/lvgl/__init__.py b/scripts/gdb/lvglgdb/lvgl/__init__.py index 4025e2af03..d7c6f2a58a 100644 --- a/scripts/gdb/lvglgdb/lvgl/__init__.py +++ b/scripts/gdb/lvglgdb/lvgl/__init__.py @@ -29,6 +29,7 @@ from .misc import ( LVImageCache, LVImageHeaderCache, create_cache_iterator, + LVArray, ) __all__ = [ @@ -64,4 +65,5 @@ __all__ = [ "LVImageCache", "LVImageHeaderCache", "create_cache_iterator", + "LVArray", ] diff --git a/scripts/gdb/lvglgdb/lvgl/misc/__init__.py b/scripts/gdb/lvglgdb/lvgl/misc/__init__.py index b1b4ddae15..b850e0dc79 100644 --- a/scripts/gdb/lvglgdb/lvgl/misc/__init__.py +++ b/scripts/gdb/lvglgdb/lvgl/misc/__init__.py @@ -15,6 +15,7 @@ from .lv_cache_iter_base import LVCacheIteratorBase from .lv_cache_iter_factory import create_cache_iterator from .lv_image_cache import LVImageCache from .lv_image_header_cache import LVImageHeaderCache +from .lv_array import LVArray __all__ = [ "LVList", @@ -37,4 +38,5 @@ __all__ = [ "LVImageCache", "LVImageHeaderCache", "create_cache_iterator", + "LVArray", ] diff --git a/scripts/gdb/lvglgdb/lvgl/misc/lv_array.py b/scripts/gdb/lvglgdb/lvgl/misc/lv_array.py new file mode 100644 index 0000000000..d019d5d6c6 --- /dev/null +++ b/scripts/gdb/lvglgdb/lvgl/misc/lv_array.py @@ -0,0 +1,52 @@ +from typing import Union + +import gdb + +from lvglgdb.value import Value, ValueInput + + +class LVArray(Value): + """LVGL dynamic array wrapper""" + + def __init__(self, arr: ValueInput, element_type: Union[gdb.Type, str] = None): + super().__init__(Value.normalize(arr, "lv_array_t")) + self.element_type = ( + gdb.lookup_type(element_type) + if isinstance(element_type, str) + else element_type + ) + + @property + def size(self) -> int: + return int(self.super_value("size")) + + @property + def capacity(self) -> int: + return int(self.super_value("capacity")) + + @property + def element_size(self) -> int: + return int(self.super_value("element_size")) + + def __len__(self) -> int: + return self.size + + def _element_at(self, data: Value, index: int) -> Value: + """Get element at index from data pointer.""" + addr = int(data) + index * self.element_size + val = Value(gdb.Value(addr)) + if self.element_type: + return val.cast(self.element_type, ptr=True).dereference() + return val + + def __iter__(self): + data = self.super_value("data") + for i in range(self.size): + yield self._element_at(data, i) + + def __getitem__(self, index): + if isinstance(index, str): + return super().__getitem__(index) + if index < 0 or index >= self.size: + raise IndexError(f"index {index} out of range [0, {self.size})") + return self._element_at(self.super_value("data"), index)