From 9dbdb4eb1f9936c0df070421b6b613bb29682ecd Mon Sep 17 00:00:00 2001 From: Benign X <1341398182@qq.com> Date: Wed, 22 Apr 2026 16:10:51 +0800 Subject: [PATCH] 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 --- scripts/gdb/lvglgdb/lvgl/widgets/_helpers.py | 6 +-- .../gdb/lvglgdb/lvgl/widgets/lv_3dtexture.py | 2 +- .../gdb/lvglgdb/lvgl/widgets/lv_animimg.py | 2 +- scripts/gdb/lvglgdb/lvgl/widgets/lv_arc.py | 2 +- .../gdb/lvglgdb/lvgl/widgets/lv_arclabel.py | 2 +- scripts/gdb/lvglgdb/lvgl/widgets/lv_bar.py | 2 +- scripts/gdb/lvglgdb/lvgl/widgets/lv_button.py | 2 +- .../lvglgdb/lvgl/widgets/lv_buttonmatrix.py | 2 +- .../gdb/lvglgdb/lvgl/widgets/lv_calendar.py | 2 +- scripts/gdb/lvglgdb/lvgl/widgets/lv_canvas.py | 2 +- scripts/gdb/lvglgdb/lvgl/widgets/lv_chart.py | 2 +- .../gdb/lvglgdb/lvgl/widgets/lv_checkbox.py | 2 +- .../gdb/lvglgdb/lvgl/widgets/lv_dropdown.py | 2 +- .../lvglgdb/lvgl/widgets/lv_dropdown_list.py | 2 +- scripts/gdb/lvglgdb/lvgl/widgets/lv_image.py | 2 +- .../lvglgdb/lvgl/widgets/lv_imagebutton.py | 2 +- .../gdb/lvglgdb/lvgl/widgets/lv_ime_pinyin.py | 2 +- .../gdb/lvglgdb/lvgl/widgets/lv_keyboard.py | 2 +- scripts/gdb/lvglgdb/lvgl/widgets/lv_label.py | 2 +- scripts/gdb/lvglgdb/lvgl/widgets/lv_led.py | 2 +- scripts/gdb/lvglgdb/lvgl/widgets/lv_line.py | 2 +- scripts/gdb/lvglgdb/lvgl/widgets/lv_menu.py | 2 +- .../gdb/lvglgdb/lvgl/widgets/lv_menu_page.py | 2 +- scripts/gdb/lvglgdb/lvgl/widgets/lv_msgbox.py | 2 +- scripts/gdb/lvglgdb/lvgl/widgets/lv_roller.py | 2 +- scripts/gdb/lvglgdb/lvgl/widgets/lv_scale.py | 2 +- scripts/gdb/lvglgdb/lvgl/widgets/lv_slider.py | 2 +- .../gdb/lvglgdb/lvgl/widgets/lv_spangroup.py | 2 +- .../gdb/lvglgdb/lvgl/widgets/lv_spinbox.py | 2 +- .../gdb/lvglgdb/lvgl/widgets/lv_spinner.py | 2 +- scripts/gdb/lvglgdb/lvgl/widgets/lv_switch.py | 2 +- scripts/gdb/lvglgdb/lvgl/widgets/lv_table.py | 2 +- .../gdb/lvglgdb/lvgl/widgets/lv_tabview.py | 2 +- .../gdb/lvglgdb/lvgl/widgets/lv_textarea.py | 2 +- .../gdb/lvglgdb/lvgl/widgets/lv_tileview.py | 2 +- .../lvglgdb/lvgl/widgets/lv_tileview_tile.py | 2 +- scripts/gdb/lvglgdb/lvgl/widgets/lv_win.py | 2 +- .../scripts/generators/gen_widget_wrappers.py | 50 +++++++++++-------- 38 files changed, 68 insertions(+), 60 deletions(-) diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/_helpers.py b/scripts/gdb/lvglgdb/lvgl/widgets/_helpers.py index c84d1a0700..b5206115dd 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/_helpers.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/_helpers.py @@ -8,16 +8,16 @@ from lvglgdb.lvgl.data_utils import ptr_or_none # noqa: F401 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 val = obj.safe_field(field_name) if val is None: - return str(CorruptedValue(0, ValueError("field not found"))) + return None if not getattr(val, 'is_ok', True): return str(val) addr = int(val) if not addr: - return str(CorruptedValue(0, ValueError("NULL pointer"))) + return None return val.string(fallback=str(CorruptedValue(addr, MemoryError("unreadable")))) diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_3dtexture.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_3dtexture.py index 683cc0b3e7..40f13a3c72 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_3dtexture.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_3dtexture.py @@ -13,7 +13,7 @@ class LV3dtexture(LVObject): def __init__(self, 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 def id(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_animimg.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_animimg.py index a30a635a8f..19b22749c3 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_animimg.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_animimg.py @@ -14,7 +14,7 @@ class LVAnimimg(LVImage): def __init__(self, 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 def anim(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_arc.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_arc.py index be8e263b41..3b7d59d7b2 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_arc.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_arc.py @@ -13,7 +13,7 @@ class LVArc(LVObject): def __init__(self, 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 def rotation(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_arclabel.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_arclabel.py index 7ca9257db7..efb130a4cb 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_arclabel.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_arclabel.py @@ -14,7 +14,7 @@ class LVArclabel(LVObject): def __init__(self, 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 def text(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_bar.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_bar.py index 89f32a8de3..f976b630e4 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_bar.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_bar.py @@ -14,7 +14,7 @@ class LVBar(LVObject): def __init__(self, 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 def cur_value(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_button.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_button.py index 7b26b56042..36f65ed213 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_button.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_button.py @@ -13,7 +13,7 @@ class LVButton(LVObject): def __init__(self, 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): """Snapshot with widget-specific fields in widget_data.""" diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_buttonmatrix.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_buttonmatrix.py index eb1d629b35..d0490a20b7 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_buttonmatrix.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_buttonmatrix.py @@ -14,7 +14,7 @@ class LVButtonmatrix(LVObject): def __init__(self, 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 def map_p(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_calendar.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_calendar.py index d0de269636..5242395090 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_calendar.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_calendar.py @@ -14,7 +14,7 @@ class LVCalendar(LVObject): def __init__(self, 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 def btnm(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_canvas.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_canvas.py index 8a719b518f..aece63023d 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_canvas.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_canvas.py @@ -14,7 +14,7 @@ class LVCanvas(LVImage): def __init__(self, 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 def draw_buf(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_chart.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_chart.py index 546e72ab97..bff3e3d684 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_chart.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_chart.py @@ -14,7 +14,7 @@ class LVChart(LVObject): def __init__(self, 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 def series_ll(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_checkbox.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_checkbox.py index ade7c08b75..8959ac6d1b 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_checkbox.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_checkbox.py @@ -14,7 +14,7 @@ class LVCheckbox(LVObject): def __init__(self, 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 def txt(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_dropdown.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_dropdown.py index a69752117e..39757dad47 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_dropdown.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_dropdown.py @@ -14,7 +14,7 @@ class LVDropdown(LVObject): def __init__(self, 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 def list(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_dropdown_list.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_dropdown_list.py index 673edfac7a..580a8e7801 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_dropdown_list.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_dropdown_list.py @@ -14,7 +14,7 @@ class LVDropdownList(LVObject): def __init__(self, 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 def dropdown(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_image.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_image.py index b8698503c8..5d7e8eddd2 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_image.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_image.py @@ -14,7 +14,7 @@ class LVImage(LVObject): def __init__(self, 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 def src(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_imagebutton.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_imagebutton.py index 7a48efa4cf..56487e08bc 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_imagebutton.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_imagebutton.py @@ -13,7 +13,7 @@ class LVImagebutton(LVObject): def __init__(self, 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): """Snapshot with widget-specific fields in widget_data.""" diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_ime_pinyin.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_ime_pinyin.py index 1619cd3a10..81bcfe6380 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_ime_pinyin.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_ime_pinyin.py @@ -14,7 +14,7 @@ class LVImePinyin(LVObject): def __init__(self, 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 def kb(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_keyboard.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_keyboard.py index 29c81bb15e..eaf66427a0 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_keyboard.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_keyboard.py @@ -14,7 +14,7 @@ class LVKeyboard(LVButtonmatrix): def __init__(self, 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 def ta(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_label.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_label.py index 29fde704f7..28a94be0fb 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_label.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_label.py @@ -14,7 +14,7 @@ class LVLabel(LVObject): def __init__(self, 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 def text(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_led.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_led.py index 0cbdf8cfc0..e4727f42f0 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_led.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_led.py @@ -14,7 +14,7 @@ class LVLed(LVObject): def __init__(self, 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 def color(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_line.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_line.py index e40ccce01b..bb35629214 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_line.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_line.py @@ -13,7 +13,7 @@ class LVLine(LVObject): def __init__(self, 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 def point_num(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_menu.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_menu.py index a5dfcf56a0..951ccc7b14 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_menu.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_menu.py @@ -14,7 +14,7 @@ class LVMenu(LVObject): def __init__(self, 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 def storage(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_menu_page.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_menu_page.py index 2108b55e94..0be30752b0 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_menu_page.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_menu_page.py @@ -14,7 +14,7 @@ class LVMenuPage(LVObject): def __init__(self, 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 def title(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_msgbox.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_msgbox.py index bd9b090350..a7f135ba59 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_msgbox.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_msgbox.py @@ -14,7 +14,7 @@ class LVMsgbox(LVObject): def __init__(self, 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 def header(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_roller.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_roller.py index c0b0dd8c5f..d5038bb27c 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_roller.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_roller.py @@ -13,7 +13,7 @@ class LVRoller(LVObject): def __init__(self, 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 def option_cnt(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_scale.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_scale.py index 15642203eb..3a7db77d3a 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_scale.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_scale.py @@ -14,7 +14,7 @@ class LVScale(LVObject): def __init__(self, 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 def section_ll(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_slider.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_slider.py index 721c494947..0a5bb92fa8 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_slider.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_slider.py @@ -14,7 +14,7 @@ class LVSlider(LVBar): def __init__(self, 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 def left_knob_area(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_spangroup.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_spangroup.py index 8be92b3af7..027922dd8c 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_spangroup.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_spangroup.py @@ -14,7 +14,7 @@ class LVSpangroup(LVObject): def __init__(self, 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 def lines(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_spinbox.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_spinbox.py index 7b7b8ae44b..f681707532 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_spinbox.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_spinbox.py @@ -13,7 +13,7 @@ class LVSpinbox(LVTextarea): def __init__(self, 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 def value(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_spinner.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_spinner.py index 56cb197e0b..0285a606b3 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_spinner.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_spinner.py @@ -13,7 +13,7 @@ class LVSpinner(LVArc): def __init__(self, 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 def duration(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_switch.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_switch.py index a6594f4720..d2a3f87034 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_switch.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_switch.py @@ -13,7 +13,7 @@ class LVSwitch(LVObject): def __init__(self, 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 def anim_state(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_table.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_table.py index da1f91683b..a712b33ecd 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_table.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_table.py @@ -14,7 +14,7 @@ class LVTable(LVObject): def __init__(self, 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 def col_cnt(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_tabview.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_tabview.py index 5447f24f57..09c123e5bb 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_tabview.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_tabview.py @@ -13,7 +13,7 @@ class LVTabview(LVObject): def __init__(self, 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 def tab_cur(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_textarea.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_textarea.py index a31e4fd5e8..df747ff2f9 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_textarea.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_textarea.py @@ -14,7 +14,7 @@ class LVTextarea(LVObject): def __init__(self, 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 def label(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_tileview.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_tileview.py index 8cbaa32d16..ea7ba48eb8 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_tileview.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_tileview.py @@ -14,7 +14,7 @@ class LVTileview(LVObject): def __init__(self, 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 def tile_act(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_tileview_tile.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_tileview_tile.py index 69ffc948ee..10a224b50e 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_tileview_tile.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_tileview_tile.py @@ -13,7 +13,7 @@ class LVTileviewTile(LVObject): def __init__(self, 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 def dir(self): diff --git a/scripts/gdb/lvglgdb/lvgl/widgets/lv_win.py b/scripts/gdb/lvglgdb/lvgl/widgets/lv_win.py index ff58c0c66f..2212d4f8ab 100644 --- a/scripts/gdb/lvglgdb/lvgl/widgets/lv_win.py +++ b/scripts/gdb/lvglgdb/lvgl/widgets/lv_win.py @@ -13,7 +13,7 @@ class LVWin(LVObject): def __init__(self, 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): """Snapshot with widget-specific fields in widget_data.""" diff --git a/scripts/gdb/scripts/generators/gen_widget_wrappers.py b/scripts/gdb/scripts/generators/gen_widget_wrappers.py index 94bb72a20e..662b2b7af3 100644 --- a/scripts/gdb/scripts/generators/gen_widget_wrappers.py +++ b/scripts/gdb/scripts/generators/gen_widget_wrappers.py @@ -190,36 +190,44 @@ def _find_structs(text: str): 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")): text = private_h.read_text() widget_dir = private_h.parent.name - for raw_name, body in _find_structs(text): struct_name = f"lv_{raw_name}_t" - first_line = "" for line in body.splitlines(): line = line.strip() if line and not line.startswith(("/*", "//", "*", "#")): first_line = line.rstrip(";").strip() break - parent_match = re.match(r"(lv_\w+_t)\s+\w+", first_line) - if not parent_match: - continue + if parent_match: + candidates.append((struct_name, parent_match.group(1), body, widget_dir)) - parent_type = parent_match.group(1) - if parent_type == "lv_obj_t" or parent_type in widgets or parent_type in ( - "lv_bar_t", "lv_image_t", "lv_arc_t", "lv_textarea_t", "lv_buttonmatrix_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, - ) + # Pass 2: resolve inheritance from lv_obj_t (order-independent) + widget_types = {"lv_obj_t"} + changed = True + while changed: + changed = False + for name, parent, _, _ in candidates: + if name not in widget_types and parent in widget_types: + widget_types.add(name) + changed = True + + # 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 @@ -284,16 +292,16 @@ from lvglgdb.lvgl.data_utils import ptr_or_none # noqa: F401 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 val = obj.safe_field(field_name) if val is None: - return str(CorruptedValue(0, ValueError("field not found"))) + return None if not getattr(val, 'is_ok', True): return str(val) addr = int(val) if not addr: - return str(CorruptedValue(0, ValueError("NULL pointer"))) + return None 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(f" def __init__(self, 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("") # Properties