mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-27 03:25:28 +08:00
chore(gdb): cast fallback, NULL string handling, order-independent widget discovery
- Widget __init__ cast fallback to self when type missing in debug info - safe_string: NULL returns None (normal), CorruptedValue returns marker - parse_widgets: two-pass inheritance resolution, remove hardcoded list
This commit is contained in:
@@ -8,16 +8,16 @@ from lvglgdb.lvgl.data_utils import ptr_or_none # noqa: F401
|
|||||||
|
|
||||||
|
|
||||||
def safe_string(obj, field_name):
|
def safe_string(obj, field_name):
|
||||||
"""Read a char* field as string or corrupted marker. Never returns None."""
|
"""Read a char* field as string, corrupted marker, or None (NULL/missing)."""
|
||||||
from lvglgdb.value import CorruptedValue
|
from lvglgdb.value import CorruptedValue
|
||||||
val = obj.safe_field(field_name)
|
val = obj.safe_field(field_name)
|
||||||
if val is None:
|
if val is None:
|
||||||
return str(CorruptedValue(0, ValueError("field not found")))
|
return None
|
||||||
if not getattr(val, 'is_ok', True):
|
if not getattr(val, 'is_ok', True):
|
||||||
return str(val)
|
return str(val)
|
||||||
addr = int(val)
|
addr = int(val)
|
||||||
if not addr:
|
if not addr:
|
||||||
return str(CorruptedValue(0, ValueError("NULL pointer")))
|
return None
|
||||||
return val.string(fallback=str(CorruptedValue(addr, MemoryError("unreadable"))))
|
return val.string(fallback=str(CorruptedValue(addr, MemoryError("unreadable"))))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class LV3dtexture(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_3dtexture_t", ptr=True)
|
self._wv = self.cast("lv_3dtexture_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def id(self):
|
def id(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVAnimimg(LVImage):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_animimg_t", ptr=True)
|
self._wv = self.cast("lv_animimg_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def anim(self):
|
def anim(self):
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class LVArc(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_arc_t", ptr=True)
|
self._wv = self.cast("lv_arc_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def rotation(self):
|
def rotation(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVArclabel(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_arclabel_t", ptr=True)
|
self._wv = self.cast("lv_arclabel_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def text(self):
|
def text(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVBar(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_bar_t", ptr=True)
|
self._wv = self.cast("lv_bar_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def cur_value(self):
|
def cur_value(self):
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class LVButton(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_button_t", ptr=True)
|
self._wv = self.cast("lv_button_t", ptr=True) or self
|
||||||
|
|
||||||
def snapshot(self, include_children=False, include_styles=False):
|
def snapshot(self, include_children=False, include_styles=False):
|
||||||
"""Snapshot with widget-specific fields in widget_data."""
|
"""Snapshot with widget-specific fields in widget_data."""
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVButtonmatrix(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_buttonmatrix_t", ptr=True)
|
self._wv = self.cast("lv_buttonmatrix_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def map_p(self):
|
def map_p(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVCalendar(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_calendar_t", ptr=True)
|
self._wv = self.cast("lv_calendar_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def btnm(self):
|
def btnm(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVCanvas(LVImage):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_canvas_t", ptr=True)
|
self._wv = self.cast("lv_canvas_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def draw_buf(self):
|
def draw_buf(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVChart(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_chart_t", ptr=True)
|
self._wv = self.cast("lv_chart_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def series_ll(self):
|
def series_ll(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVCheckbox(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_checkbox_t", ptr=True)
|
self._wv = self.cast("lv_checkbox_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def txt(self):
|
def txt(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVDropdown(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_dropdown_t", ptr=True)
|
self._wv = self.cast("lv_dropdown_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def list(self):
|
def list(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVDropdownList(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_dropdown_list_t", ptr=True)
|
self._wv = self.cast("lv_dropdown_list_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dropdown(self):
|
def dropdown(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVImage(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_image_t", ptr=True)
|
self._wv = self.cast("lv_image_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def src(self):
|
def src(self):
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class LVImagebutton(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_imagebutton_t", ptr=True)
|
self._wv = self.cast("lv_imagebutton_t", ptr=True) or self
|
||||||
|
|
||||||
def snapshot(self, include_children=False, include_styles=False):
|
def snapshot(self, include_children=False, include_styles=False):
|
||||||
"""Snapshot with widget-specific fields in widget_data."""
|
"""Snapshot with widget-specific fields in widget_data."""
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVImePinyin(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_ime_pinyin_t", ptr=True)
|
self._wv = self.cast("lv_ime_pinyin_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def kb(self):
|
def kb(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVKeyboard(LVButtonmatrix):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_keyboard_t", ptr=True)
|
self._wv = self.cast("lv_keyboard_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ta(self):
|
def ta(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVLabel(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_label_t", ptr=True)
|
self._wv = self.cast("lv_label_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def text(self):
|
def text(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVLed(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_led_t", ptr=True)
|
self._wv = self.cast("lv_led_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def color(self):
|
def color(self):
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class LVLine(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_line_t", ptr=True)
|
self._wv = self.cast("lv_line_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def point_num(self):
|
def point_num(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVMenu(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_menu_t", ptr=True)
|
self._wv = self.cast("lv_menu_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def storage(self):
|
def storage(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVMenuPage(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_menu_page_t", ptr=True)
|
self._wv = self.cast("lv_menu_page_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def title(self):
|
def title(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVMsgbox(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_msgbox_t", ptr=True)
|
self._wv = self.cast("lv_msgbox_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def header(self):
|
def header(self):
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class LVRoller(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_roller_t", ptr=True)
|
self._wv = self.cast("lv_roller_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def option_cnt(self):
|
def option_cnt(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVScale(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_scale_t", ptr=True)
|
self._wv = self.cast("lv_scale_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def section_ll(self):
|
def section_ll(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVSlider(LVBar):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_slider_t", ptr=True)
|
self._wv = self.cast("lv_slider_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def left_knob_area(self):
|
def left_knob_area(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVSpangroup(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_spangroup_t", ptr=True)
|
self._wv = self.cast("lv_spangroup_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def lines(self):
|
def lines(self):
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class LVSpinbox(LVTextarea):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_spinbox_t", ptr=True)
|
self._wv = self.cast("lv_spinbox_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class LVSpinner(LVArc):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_spinner_t", ptr=True)
|
self._wv = self.cast("lv_spinner_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def duration(self):
|
def duration(self):
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class LVSwitch(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_switch_t", ptr=True)
|
self._wv = self.cast("lv_switch_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def anim_state(self):
|
def anim_state(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVTable(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_table_t", ptr=True)
|
self._wv = self.cast("lv_table_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def col_cnt(self):
|
def col_cnt(self):
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class LVTabview(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_tabview_t", ptr=True)
|
self._wv = self.cast("lv_tabview_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tab_cur(self):
|
def tab_cur(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVTextarea(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_textarea_t", ptr=True)
|
self._wv = self.cast("lv_textarea_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def label(self):
|
def label(self):
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LVTileview(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_tileview_t", ptr=True)
|
self._wv = self.cast("lv_tileview_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tile_act(self):
|
def tile_act(self):
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class LVTileviewTile(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_tileview_tile_t", ptr=True)
|
self._wv = self.cast("lv_tileview_tile_t", ptr=True) or self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dir(self):
|
def dir(self):
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class LVWin(LVObject):
|
|||||||
|
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
super().__init__(obj)
|
super().__init__(obj)
|
||||||
self._wv = self.cast("lv_win_t", ptr=True)
|
self._wv = self.cast("lv_win_t", ptr=True) or self
|
||||||
|
|
||||||
def snapshot(self, include_children=False, include_styles=False):
|
def snapshot(self, include_children=False, include_styles=False):
|
||||||
"""Snapshot with widget-specific fields in widget_data."""
|
"""Snapshot with widget-specific fields in widget_data."""
|
||||||
|
|||||||
@@ -190,36 +190,44 @@ def _find_structs(text: str):
|
|||||||
|
|
||||||
|
|
||||||
def parse_widgets() -> dict[str, WidgetDef]:
|
def parse_widgets() -> dict[str, WidgetDef]:
|
||||||
widgets = {}
|
# Pass 1: collect all structs with parent type
|
||||||
|
candidates = []
|
||||||
for private_h in sorted(WIDGETS_DIR.glob("*/lv_*_private.h")):
|
for private_h in sorted(WIDGETS_DIR.glob("*/lv_*_private.h")):
|
||||||
text = private_h.read_text()
|
text = private_h.read_text()
|
||||||
widget_dir = private_h.parent.name
|
widget_dir = private_h.parent.name
|
||||||
|
|
||||||
for raw_name, body in _find_structs(text):
|
for raw_name, body in _find_structs(text):
|
||||||
struct_name = f"lv_{raw_name}_t"
|
struct_name = f"lv_{raw_name}_t"
|
||||||
|
|
||||||
first_line = ""
|
first_line = ""
|
||||||
for line in body.splitlines():
|
for line in body.splitlines():
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if line and not line.startswith(("/*", "//", "*", "#")):
|
if line and not line.startswith(("/*", "//", "*", "#")):
|
||||||
first_line = line.rstrip(";").strip()
|
first_line = line.rstrip(";").strip()
|
||||||
break
|
break
|
||||||
|
|
||||||
parent_match = re.match(r"(lv_\w+_t)\s+\w+", first_line)
|
parent_match = re.match(r"(lv_\w+_t)\s+\w+", first_line)
|
||||||
if not parent_match:
|
if parent_match:
|
||||||
continue
|
candidates.append((struct_name, parent_match.group(1), body, widget_dir))
|
||||||
|
|
||||||
parent_type = parent_match.group(1)
|
# Pass 2: resolve inheritance from lv_obj_t (order-independent)
|
||||||
if parent_type == "lv_obj_t" or parent_type in widgets or parent_type in (
|
widget_types = {"lv_obj_t"}
|
||||||
"lv_bar_t", "lv_image_t", "lv_arc_t", "lv_textarea_t", "lv_buttonmatrix_t",
|
changed = True
|
||||||
):
|
while changed:
|
||||||
all_fields = parse_struct_fields(body)
|
changed = False
|
||||||
widgets[struct_name] = WidgetDef(
|
for name, parent, _, _ in candidates:
|
||||||
struct_name=struct_name, c_type=struct_name,
|
if name not in widget_types and parent in widget_types:
|
||||||
parent_type=parent_type,
|
widget_types.add(name)
|
||||||
fields=all_fields[1:] if all_fields else [],
|
changed = True
|
||||||
widget_dir=widget_dir,
|
|
||||||
)
|
# Pass 3: build WidgetDef for discovered widgets
|
||||||
|
widgets = {}
|
||||||
|
for struct_name, parent_type, body, widget_dir in candidates:
|
||||||
|
if struct_name in widget_types and struct_name != "lv_obj_t":
|
||||||
|
all_fields = parse_struct_fields(body)
|
||||||
|
widgets[struct_name] = WidgetDef(
|
||||||
|
struct_name=struct_name, c_type=struct_name,
|
||||||
|
parent_type=parent_type,
|
||||||
|
fields=all_fields[1:] if all_fields else [],
|
||||||
|
widget_dir=widget_dir,
|
||||||
|
)
|
||||||
return widgets
|
return widgets
|
||||||
|
|
||||||
|
|
||||||
@@ -284,16 +292,16 @@ from lvglgdb.lvgl.data_utils import ptr_or_none # noqa: F401
|
|||||||
|
|
||||||
|
|
||||||
def safe_string(obj, field_name):
|
def safe_string(obj, field_name):
|
||||||
"""Read a char* field as string or corrupted marker. Never returns None."""
|
"""Read a char* field as string, corrupted marker, or None (NULL/missing)."""
|
||||||
from lvglgdb.value import CorruptedValue
|
from lvglgdb.value import CorruptedValue
|
||||||
val = obj.safe_field(field_name)
|
val = obj.safe_field(field_name)
|
||||||
if val is None:
|
if val is None:
|
||||||
return str(CorruptedValue(0, ValueError("field not found")))
|
return None
|
||||||
if not getattr(val, 'is_ok', True):
|
if not getattr(val, 'is_ok', True):
|
||||||
return str(val)
|
return str(val)
|
||||||
addr = int(val)
|
addr = int(val)
|
||||||
if not addr:
|
if not addr:
|
||||||
return str(CorruptedValue(0, ValueError("NULL pointer")))
|
return None
|
||||||
return val.string(fallback=str(CorruptedValue(addr, MemoryError("unreadable"))))
|
return val.string(fallback=str(CorruptedValue(addr, MemoryError("unreadable"))))
|
||||||
|
|
||||||
|
|
||||||
@@ -396,7 +404,7 @@ def gen_widget_file(wdef: WidgetDef, widgets: dict[str, WidgetDef]) -> str:
|
|||||||
lines.append("")
|
lines.append("")
|
||||||
lines.append(f" def __init__(self, obj):")
|
lines.append(f" def __init__(self, obj):")
|
||||||
lines.append(f" super().__init__(obj)")
|
lines.append(f" super().__init__(obj)")
|
||||||
lines.append(f' self._wv = self.cast("{wdef.c_type}", ptr=True)')
|
lines.append(f' self._wv = self.cast("{wdef.c_type}", ptr=True) or self')
|
||||||
lines.append("")
|
lines.append("")
|
||||||
|
|
||||||
# Properties
|
# Properties
|
||||||
|
|||||||
Reference in New Issue
Block a user