mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-30 07:06:19 +08:00
chore(gdb): refactor generators into shared enum_parser and unified generate_all entry
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
*.egg-info/
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
__pycache__/
|
||||||
|
.idea/
|
||||||
|
.DS_Store
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
"""
|
"""
|
||||||
Auto-generated indev constants from LVGL headers.
|
Auto-generated indev constants from LVGL headers.
|
||||||
|
|
||||||
Do not edit manually. Regenerate with:
|
Do not edit manually. Regenerate from the GDB script root with:
|
||||||
python3 scripts/gen_indev_consts.py
|
python3 scripts/generate_all.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
INDEV_TYPE_NAMES = {
|
INDEV_TYPE_NAMES = {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
"""
|
"""
|
||||||
Auto-generated observer constants from LVGL headers.
|
Auto-generated observer constants from LVGL headers.
|
||||||
|
|
||||||
Do not edit manually. Regenerate with:
|
Do not edit manually. Regenerate from the GDB script root with:
|
||||||
python3 scripts/gen_subject_consts.py
|
python3 scripts/generate_all.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
SUBJECT_TYPE_NAMES = {
|
SUBJECT_TYPE_NAMES = {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
"""
|
"""
|
||||||
Auto-generated draw constants from LVGL headers.
|
Auto-generated draw constants from LVGL headers.
|
||||||
|
|
||||||
Do not edit manually. Regenerate with:
|
Do not edit manually. Regenerate from the GDB script root with:
|
||||||
python3 scripts/gen_draw_consts.py
|
python3 scripts/generate_all.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
DRAW_TASK_TYPE_NAMES = {
|
DRAW_TASK_TYPE_NAMES = {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
"""
|
"""
|
||||||
Auto-generated event constants from LVGL headers.
|
Auto-generated event constants from LVGL headers.
|
||||||
|
|
||||||
Do not edit manually. Regenerate with:
|
Do not edit manually. Regenerate from the GDB script root with:
|
||||||
python3 scripts/gen_event_consts.py
|
python3 scripts/generate_all.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
EVENT_CODE_NAMES = {
|
EVENT_CODE_NAMES = {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
"""
|
"""
|
||||||
Auto-generated style constants from LVGL headers.
|
Auto-generated style constants from LVGL headers.
|
||||||
|
|
||||||
Do not edit manually. Regenerate with:
|
Do not edit manually. Regenerate from the GDB script root with:
|
||||||
python3 scripts/gen_style_consts.py
|
python3 scripts/generate_all.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
STYLE_PROP_NAMES = {
|
STYLE_PROP_NAMES = {
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Shared utilities for LVGL constant generators.
|
||||||
|
|
||||||
|
Provides:
|
||||||
|
- parse_enum(): Parse a C typedef enum from a header file.
|
||||||
|
- generate_dict_module(): Generate a Python module with dict constants.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def parse_enum(path: Path, enum_type: str, prefix: str,
|
||||||
|
skip: set[str] | None = None) -> dict[int, str]:
|
||||||
|
"""Parse a C typedef enum from a header file.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path: Path to the C header file.
|
||||||
|
enum_type: The typedef name (e.g. "lv_indev_type_t").
|
||||||
|
prefix: Enum member prefix to strip (e.g. "LV_INDEV_TYPE_").
|
||||||
|
skip: Optional set of full enum member names to skip.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict mapping int value -> short name string.
|
||||||
|
"""
|
||||||
|
text = path.read_text()
|
||||||
|
skip = skip or set()
|
||||||
|
|
||||||
|
pattern = rf"\}}\s*{re.escape(enum_type)}\s*;"
|
||||||
|
m = re.search(rf"typedef\s+enum\s*\{{(.*?){pattern}", text, re.DOTALL)
|
||||||
|
if not m:
|
||||||
|
raise RuntimeError(f"Cannot find {enum_type} enum in {path}")
|
||||||
|
|
||||||
|
entries = {}
|
||||||
|
current_val = 0
|
||||||
|
for line in m.group(1).splitlines():
|
||||||
|
line = line.strip().rstrip(",")
|
||||||
|
if (
|
||||||
|
not line
|
||||||
|
or line.startswith("/*")
|
||||||
|
or line.startswith("//")
|
||||||
|
or line.startswith("*")
|
||||||
|
or line.startswith("#")
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
|
||||||
|
match = re.match(
|
||||||
|
rf"({re.escape(prefix)}\w+)\s*=\s*(0x[\da-fA-F]+|\d+)", line
|
||||||
|
)
|
||||||
|
if match:
|
||||||
|
name = match.group(1)
|
||||||
|
current_val = int(match.group(2), 0)
|
||||||
|
else:
|
||||||
|
match = re.match(rf"({re.escape(prefix)}\w+)", line)
|
||||||
|
if not match:
|
||||||
|
continue
|
||||||
|
name = match.group(1)
|
||||||
|
|
||||||
|
if name in skip:
|
||||||
|
current_val += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
short = name.removeprefix(prefix)
|
||||||
|
entries[current_val] = short
|
||||||
|
current_val += 1
|
||||||
|
|
||||||
|
return entries
|
||||||
|
|
||||||
|
|
||||||
|
def generate_dict_module(
|
||||||
|
description: str,
|
||||||
|
dicts: dict[str, dict],
|
||||||
|
) -> str:
|
||||||
|
"""Generate a Python module containing one or more dict constants.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
description: Short description for the module docstring.
|
||||||
|
dicts: Mapping of variable_name -> dict to emit.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Python source code string.
|
||||||
|
"""
|
||||||
|
lines = [
|
||||||
|
'"""',
|
||||||
|
f"Auto-generated {description}.",
|
||||||
|
"",
|
||||||
|
"Do not edit manually. Regenerate from the GDB script root with:",
|
||||||
|
" python3 scripts/generate_all.py",
|
||||||
|
'"""',
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
|
||||||
|
for var_name, data in dicts.items():
|
||||||
|
lines.append(f"{var_name} = {{")
|
||||||
|
for k in sorted(data):
|
||||||
|
v = data[k]
|
||||||
|
if isinstance(k, int):
|
||||||
|
lines.append(f' {k}: "{v}",')
|
||||||
|
else:
|
||||||
|
lines.append(f' "{k}": "{v}",')
|
||||||
|
lines.append("}")
|
||||||
|
lines.append("")
|
||||||
|
|
||||||
|
return "\n".join(lines)
|
||||||
@@ -1,141 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
Generate draw constant tables from LVGL header and source files.
|
|
||||||
|
|
||||||
Parses lv_draw.h for task type/state enums, and scans draw unit source
|
|
||||||
files for name-to-struct-type mappings.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
python3 scripts/gen_draw_consts.py
|
|
||||||
"""
|
|
||||||
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
SCRIPT_DIR = Path(__file__).parent
|
|
||||||
GDB_ROOT = SCRIPT_DIR.parent
|
|
||||||
LVGL_SRC = GDB_ROOT.parent.parent / "src"
|
|
||||||
OUTPUT = GDB_ROOT / "lvglgdb" / "lvgl" / "draw" / "lv_draw_consts.py"
|
|
||||||
|
|
||||||
DRAW_H = LVGL_SRC / "draw" / "lv_draw.h"
|
|
||||||
DRAW_DIR = LVGL_SRC / "draw"
|
|
||||||
|
|
||||||
sys.path.insert(0, str(SCRIPT_DIR))
|
|
||||||
|
|
||||||
|
|
||||||
def parse_enum(path: Path, enum_type: str, prefix: str) -> dict[int, str]:
|
|
||||||
"""Parse a C enum from a header file."""
|
|
||||||
text = path.read_text()
|
|
||||||
|
|
||||||
pattern = rf"\}}\s*{re.escape(enum_type)}\s*;"
|
|
||||||
m = re.search(rf"typedef\s+enum\s*\{{(.*?){pattern}", text, re.DOTALL)
|
|
||||||
if not m:
|
|
||||||
raise RuntimeError(f"Cannot find {enum_type} enum in {path}")
|
|
||||||
|
|
||||||
entries = {}
|
|
||||||
current_val = 0
|
|
||||||
for line in m.group(1).splitlines():
|
|
||||||
line = line.strip().rstrip(",")
|
|
||||||
if (
|
|
||||||
not line
|
|
||||||
or line.startswith("/*")
|
|
||||||
or line.startswith("//")
|
|
||||||
or line.startswith("*")
|
|
||||||
or line.startswith("#")
|
|
||||||
):
|
|
||||||
continue
|
|
||||||
|
|
||||||
match = re.match(rf"({re.escape(prefix)}\w+)\s*=\s*(0x[\da-fA-F]+|\d+)", line)
|
|
||||||
if match:
|
|
||||||
name = match.group(1)
|
|
||||||
current_val = int(match.group(2), 0)
|
|
||||||
else:
|
|
||||||
match = re.match(rf"({re.escape(prefix)}\w+)", line)
|
|
||||||
if not match:
|
|
||||||
continue
|
|
||||||
name = match.group(1)
|
|
||||||
|
|
||||||
short = name.removeprefix(prefix)
|
|
||||||
entries[current_val] = short
|
|
||||||
current_val += 1
|
|
||||||
|
|
||||||
return entries
|
|
||||||
|
|
||||||
|
|
||||||
def parse_draw_unit_types(draw_dir: Path) -> dict[str, str]:
|
|
||||||
"""Scan draw unit .c files for name-to-struct-type mappings.
|
|
||||||
|
|
||||||
Looks for patterns like: unit->base_unit.name = "SW";
|
|
||||||
Then finds the corresponding struct type from the variable declaration.
|
|
||||||
"""
|
|
||||||
mappings = {}
|
|
||||||
|
|
||||||
for c_file in draw_dir.rglob("*.c"):
|
|
||||||
text = c_file.read_text()
|
|
||||||
|
|
||||||
for m in re.finditer(r'(\w+)->base_unit\.name\s*=\s*"(\w+)"', text):
|
|
||||||
var_name = m.group(1)
|
|
||||||
unit_name = m.group(2)
|
|
||||||
|
|
||||||
decl = re.search(
|
|
||||||
rf"(lv_draw_\w+_unit_t)\s*\*\s*{re.escape(var_name)}\b", text
|
|
||||||
)
|
|
||||||
if decl:
|
|
||||||
mappings[unit_name] = decl.group(1)
|
|
||||||
|
|
||||||
return mappings
|
|
||||||
|
|
||||||
|
|
||||||
def generate(
|
|
||||||
task_types: dict[int, str],
|
|
||||||
task_states: dict[int, str],
|
|
||||||
unit_types: dict[str, str],
|
|
||||||
) -> str:
|
|
||||||
"""Generate Python source for the draw constants module."""
|
|
||||||
lines = [
|
|
||||||
'"""',
|
|
||||||
"Auto-generated draw constants from LVGL headers.",
|
|
||||||
"",
|
|
||||||
"Do not edit manually. Regenerate with:",
|
|
||||||
" python3 scripts/gen_draw_consts.py",
|
|
||||||
'"""',
|
|
||||||
"",
|
|
||||||
]
|
|
||||||
|
|
||||||
lines.append("DRAW_TASK_TYPE_NAMES = {")
|
|
||||||
for k in sorted(task_types):
|
|
||||||
lines.append(f' {k}: "{task_types[k]}",')
|
|
||||||
lines.append("}")
|
|
||||||
lines.append("")
|
|
||||||
|
|
||||||
lines.append("DRAW_TASK_STATE_NAMES = {")
|
|
||||||
for k in sorted(task_states):
|
|
||||||
lines.append(f' {k}: "{task_states[k]}",')
|
|
||||||
lines.append("}")
|
|
||||||
lines.append("")
|
|
||||||
|
|
||||||
lines.append("DRAW_UNIT_TYPE_NAMES = {")
|
|
||||||
for name in sorted(unit_types):
|
|
||||||
lines.append(f' "{name}": "{unit_types[name]}",')
|
|
||||||
lines.append("}")
|
|
||||||
lines.append("")
|
|
||||||
|
|
||||||
return "\n".join(lines)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
task_types = parse_enum(DRAW_H, "lv_draw_task_type_t", "LV_DRAW_TASK_TYPE_")
|
|
||||||
task_states = parse_enum(DRAW_H, "lv_draw_task_state_t", "LV_DRAW_TASK_STATE_")
|
|
||||||
unit_types = parse_draw_unit_types(DRAW_DIR)
|
|
||||||
|
|
||||||
src = generate(task_types, task_states, unit_types)
|
|
||||||
OUTPUT.write_text(src)
|
|
||||||
print(
|
|
||||||
f"Generated {OUTPUT} ({len(task_types)} task types, "
|
|
||||||
f"{len(task_states)} task states, {len(unit_types)} unit types)"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
Generate event constant tables from LVGL header files.
|
|
||||||
|
|
||||||
Parses lv_event.h for the lv_event_code_t enum.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
python3 scripts/gen_event_consts.py
|
|
||||||
"""
|
|
||||||
|
|
||||||
import re
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
SCRIPT_DIR = Path(__file__).parent
|
|
||||||
GDB_ROOT = SCRIPT_DIR.parent
|
|
||||||
LVGL_SRC = GDB_ROOT.parent.parent / "src"
|
|
||||||
OUTPUT = GDB_ROOT / "lvglgdb" / "lvgl" / "misc" / "lv_event_consts.py"
|
|
||||||
|
|
||||||
EVENT_H = LVGL_SRC / "misc" / "lv_event.h"
|
|
||||||
|
|
||||||
|
|
||||||
def parse_event_codes(path: Path) -> dict[int, str]:
|
|
||||||
"""Parse lv_event_code_t enum from lv_event.h."""
|
|
||||||
text = path.read_text()
|
|
||||||
|
|
||||||
m = re.search(r"typedef\s+enum\s*\{(.*?)\}\s*lv_event_code_t", text, re.DOTALL)
|
|
||||||
if not m:
|
|
||||||
raise RuntimeError("Cannot find lv_event_code_t enum")
|
|
||||||
|
|
||||||
codes = {}
|
|
||||||
current_val = 0
|
|
||||||
for line in m.group(1).splitlines():
|
|
||||||
line = line.strip().rstrip(",")
|
|
||||||
if (
|
|
||||||
not line
|
|
||||||
or line.startswith("/*")
|
|
||||||
or line.startswith("//")
|
|
||||||
or line.startswith("*")
|
|
||||||
or line.startswith("#")
|
|
||||||
):
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Match: LV_EVENT_XXX = value
|
|
||||||
match = re.match(r"(LV_EVENT_\w+)\s*=\s*(0x[\da-fA-F]+|\d+)", line)
|
|
||||||
if match:
|
|
||||||
name = match.group(1)
|
|
||||||
current_val = int(match.group(2), 0)
|
|
||||||
else:
|
|
||||||
match = re.match(r"(LV_EVENT_\w+)", line)
|
|
||||||
if not match:
|
|
||||||
continue
|
|
||||||
name = match.group(1)
|
|
||||||
|
|
||||||
# Skip meta entries
|
|
||||||
if name in ("LV_EVENT_LAST", "LV_EVENT_PREPROCESS", "LV_EVENT_MARKED_DELETING"):
|
|
||||||
current_val += 1
|
|
||||||
continue
|
|
||||||
|
|
||||||
short = name.removeprefix("LV_EVENT_")
|
|
||||||
codes[current_val] = short
|
|
||||||
current_val += 1
|
|
||||||
|
|
||||||
return codes
|
|
||||||
|
|
||||||
|
|
||||||
def generate(codes: dict[int, str]) -> str:
|
|
||||||
"""Generate Python source for the event constants module."""
|
|
||||||
lines = [
|
|
||||||
'"""',
|
|
||||||
"Auto-generated event constants from LVGL headers.",
|
|
||||||
"",
|
|
||||||
"Do not edit manually. Regenerate with:",
|
|
||||||
" python3 scripts/gen_event_consts.py",
|
|
||||||
'"""',
|
|
||||||
"",
|
|
||||||
]
|
|
||||||
|
|
||||||
lines.append("EVENT_CODE_NAMES = {")
|
|
||||||
for k in sorted(codes):
|
|
||||||
lines.append(f' {k}: "{codes[k]}",')
|
|
||||||
lines.append("}")
|
|
||||||
lines.append("")
|
|
||||||
|
|
||||||
return "\n".join(lines)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
codes = parse_event_codes(EVENT_H)
|
|
||||||
src = generate(codes)
|
|
||||||
OUTPUT.write_text(src)
|
|
||||||
print(f"Generated {OUTPUT} ({len(codes)} event codes)")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
Generate indev constant tables from LVGL header files.
|
|
||||||
|
|
||||||
Parses lv_indev.h for indev type enum.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
python3 scripts/gen_indev_consts.py
|
|
||||||
"""
|
|
||||||
|
|
||||||
import re
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
SCRIPT_DIR = Path(__file__).parent
|
|
||||||
GDB_ROOT = SCRIPT_DIR.parent
|
|
||||||
LVGL_SRC = GDB_ROOT.parent.parent / "src"
|
|
||||||
OUTPUT = GDB_ROOT / "lvglgdb" / "lvgl" / "core" / "lv_indev_consts.py"
|
|
||||||
|
|
||||||
INDEV_H = LVGL_SRC / "indev" / "lv_indev.h"
|
|
||||||
|
|
||||||
|
|
||||||
def parse_enum(path: Path, enum_type: str, prefix: str) -> dict[int, str]:
|
|
||||||
"""Parse a C enum from a header file."""
|
|
||||||
text = path.read_text()
|
|
||||||
|
|
||||||
pattern = rf"\}}\s*{re.escape(enum_type)}\s*;"
|
|
||||||
m = re.search(rf"typedef\s+enum\s*\{{(.*?){pattern}", text, re.DOTALL)
|
|
||||||
if not m:
|
|
||||||
raise RuntimeError(f"Cannot find {enum_type} enum in {path}")
|
|
||||||
|
|
||||||
entries = {}
|
|
||||||
current_val = 0
|
|
||||||
for line in m.group(1).splitlines():
|
|
||||||
line = line.strip().rstrip(",")
|
|
||||||
if (
|
|
||||||
not line
|
|
||||||
or line.startswith("/*")
|
|
||||||
or line.startswith("//")
|
|
||||||
or line.startswith("*")
|
|
||||||
or line.startswith("#")
|
|
||||||
):
|
|
||||||
continue
|
|
||||||
|
|
||||||
match = re.match(rf"({re.escape(prefix)}\w+)\s*=\s*(0x[\da-fA-F]+|\d+)", line)
|
|
||||||
if match:
|
|
||||||
name = match.group(1)
|
|
||||||
current_val = int(match.group(2), 0)
|
|
||||||
else:
|
|
||||||
match = re.match(rf"({re.escape(prefix)}\w+)", line)
|
|
||||||
if not match:
|
|
||||||
continue
|
|
||||||
name = match.group(1)
|
|
||||||
|
|
||||||
short = name.removeprefix(prefix)
|
|
||||||
entries[current_val] = short
|
|
||||||
current_val += 1
|
|
||||||
|
|
||||||
return entries
|
|
||||||
|
|
||||||
|
|
||||||
def generate(indev_types: dict[int, str]) -> str:
|
|
||||||
"""Generate Python source for the indev constants module."""
|
|
||||||
lines = [
|
|
||||||
'"""',
|
|
||||||
"Auto-generated indev constants from LVGL headers.",
|
|
||||||
"",
|
|
||||||
"Do not edit manually. Regenerate with:",
|
|
||||||
" python3 scripts/gen_indev_consts.py",
|
|
||||||
'"""',
|
|
||||||
"",
|
|
||||||
"INDEV_TYPE_NAMES = {",
|
|
||||||
]
|
|
||||||
for k in sorted(indev_types):
|
|
||||||
lines.append(f' {k}: "{indev_types[k]}",')
|
|
||||||
lines.append("}")
|
|
||||||
lines.append("")
|
|
||||||
|
|
||||||
return "\n".join(lines)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
indev_types = parse_enum(INDEV_H, "lv_indev_type_t", "LV_INDEV_TYPE_")
|
|
||||||
src = generate(indev_types)
|
|
||||||
OUTPUT.write_text(src)
|
|
||||||
print(f"Generated {OUTPUT} ({len(indev_types)} indev types)")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
Generate subject type constant table from LVGL header files.
|
|
||||||
|
|
||||||
Parses lv_observer.h for subject type enum.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
python3 scripts/gen_subject_consts.py
|
|
||||||
"""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
SCRIPT_DIR = Path(__file__).parent
|
|
||||||
GDB_ROOT = SCRIPT_DIR.parent
|
|
||||||
LVGL_SRC = GDB_ROOT.parent.parent / "src"
|
|
||||||
OUTPUT = GDB_ROOT / "lvglgdb" / "lvgl" / "core" / "lv_observer_consts.py"
|
|
||||||
|
|
||||||
OBSERVER_H = LVGL_SRC / "core" / "lv_observer.h"
|
|
||||||
|
|
||||||
sys.path.insert(0, str(SCRIPT_DIR))
|
|
||||||
from gen_indev_consts import parse_enum
|
|
||||||
|
|
||||||
|
|
||||||
def generate(subject_types: dict[int, str]) -> str:
|
|
||||||
"""Generate Python source for the observer constants module."""
|
|
||||||
lines = [
|
|
||||||
'"""',
|
|
||||||
"Auto-generated observer constants from LVGL headers.",
|
|
||||||
"",
|
|
||||||
"Do not edit manually. Regenerate with:",
|
|
||||||
" python3 scripts/gen_subject_consts.py",
|
|
||||||
'"""',
|
|
||||||
"",
|
|
||||||
"SUBJECT_TYPE_NAMES = {",
|
|
||||||
]
|
|
||||||
for k in sorted(subject_types):
|
|
||||||
lines.append(f' {k}: "{subject_types[k]}",')
|
|
||||||
lines.append("}")
|
|
||||||
lines.append("")
|
|
||||||
|
|
||||||
return "\n".join(lines)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
subject_types = parse_enum(OBSERVER_H, "lv_subject_type_t", "LV_SUBJECT_TYPE_")
|
|
||||||
src = generate(subject_types)
|
|
||||||
OUTPUT.write_text(src)
|
|
||||||
print(f"Generated {OUTPUT} ({len(subject_types)} subject types)")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Unified entry point for all LVGL GDB constant generators.
|
||||||
|
|
||||||
|
Scans the generators/ subdirectory for gen_*.py modules and calls
|
||||||
|
each module's main() function.
|
||||||
|
|
||||||
|
Usage (from the GDB script root):
|
||||||
|
python3 scripts/generate_all.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
import importlib
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
SCRIPT_DIR = Path(__file__).parent
|
||||||
|
GENERATORS_DIR = SCRIPT_DIR / "generators"
|
||||||
|
|
||||||
|
# Make enum_parser importable from generators
|
||||||
|
sys.path.insert(0, str(SCRIPT_DIR))
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
gen_files = sorted(GENERATORS_DIR.glob("gen_*.py"))
|
||||||
|
if not gen_files:
|
||||||
|
print("No generators found.")
|
||||||
|
return
|
||||||
|
|
||||||
|
print(f"Running {len(gen_files)} generator(s)...\n")
|
||||||
|
|
||||||
|
for gen_file in gen_files:
|
||||||
|
module_name = gen_file.stem
|
||||||
|
print(f" [{module_name}]")
|
||||||
|
spec = importlib.util.spec_from_file_location(module_name, gen_file)
|
||||||
|
mod = importlib.util.module_from_spec(spec)
|
||||||
|
spec.loader.exec_module(mod)
|
||||||
|
mod.main()
|
||||||
|
print()
|
||||||
|
|
||||||
|
print("All generators completed.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
# generators package
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Generate draw constant tables from LVGL headers and source files."""
|
||||||
|
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||||
|
from enum_parser import parse_enum, generate_dict_module
|
||||||
|
|
||||||
|
LVGL_SRC = Path(__file__).parent.parent.parent.parent.parent / "src"
|
||||||
|
OUTPUT = Path(__file__).parent.parent.parent / "lvglgdb" / "lvgl" / "draw" / "lv_draw_consts.py"
|
||||||
|
|
||||||
|
DRAW_H = LVGL_SRC / "draw" / "lv_draw.h"
|
||||||
|
DRAW_DIR = LVGL_SRC / "draw"
|
||||||
|
|
||||||
|
|
||||||
|
def parse_draw_unit_types(draw_dir: Path) -> dict[str, str]:
|
||||||
|
"""Scan draw unit .c files for name-to-struct-type mappings.
|
||||||
|
|
||||||
|
Looks for patterns like: unit->base_unit.name = "SW";
|
||||||
|
Then finds the corresponding struct type from the variable declaration.
|
||||||
|
"""
|
||||||
|
mappings = {}
|
||||||
|
for c_file in draw_dir.rglob("*.c"):
|
||||||
|
text = c_file.read_text()
|
||||||
|
for m in re.finditer(r'(\w+)->base_unit\.name\s*=\s*"(\w+)"', text):
|
||||||
|
var_name = m.group(1)
|
||||||
|
unit_name = m.group(2)
|
||||||
|
decl = re.search(
|
||||||
|
rf"(lv_draw_\w+_unit_t)\s*\*\s*{re.escape(var_name)}\b", text
|
||||||
|
)
|
||||||
|
if decl:
|
||||||
|
mappings[unit_name] = decl.group(1)
|
||||||
|
return mappings
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
task_types = parse_enum(DRAW_H, "lv_draw_task_type_t", "LV_DRAW_TASK_TYPE_")
|
||||||
|
task_states = parse_enum(DRAW_H, "lv_draw_task_state_t", "LV_DRAW_TASK_STATE_")
|
||||||
|
unit_types = parse_draw_unit_types(DRAW_DIR)
|
||||||
|
|
||||||
|
src = generate_dict_module(
|
||||||
|
"draw constants from LVGL headers",
|
||||||
|
{
|
||||||
|
"DRAW_TASK_TYPE_NAMES": task_types,
|
||||||
|
"DRAW_TASK_STATE_NAMES": task_states,
|
||||||
|
"DRAW_UNIT_TYPE_NAMES": unit_types,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
OUTPUT.write_text(src)
|
||||||
|
print(
|
||||||
|
f"Generated {OUTPUT.name} ({len(task_types)} task types, "
|
||||||
|
f"{len(task_states)} task states, {len(unit_types)} unit types)"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Generate event constant tables from LVGL headers."""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||||
|
from enum_parser import parse_enum, generate_dict_module
|
||||||
|
|
||||||
|
LVGL_SRC = Path(__file__).parent.parent.parent.parent.parent / "src"
|
||||||
|
OUTPUT = Path(__file__).parent.parent.parent / "lvglgdb" / "lvgl" / "misc" / "lv_event_consts.py"
|
||||||
|
|
||||||
|
SKIP_EVENTS = {"LV_EVENT_LAST", "LV_EVENT_PREPROCESS", "LV_EVENT_MARKED_DELETING"}
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
event_codes = parse_enum(
|
||||||
|
LVGL_SRC / "misc" / "lv_event.h",
|
||||||
|
"lv_event_code_t",
|
||||||
|
"LV_EVENT_",
|
||||||
|
skip=SKIP_EVENTS,
|
||||||
|
)
|
||||||
|
src = generate_dict_module(
|
||||||
|
"event constants from LVGL headers",
|
||||||
|
{"EVENT_CODE_NAMES": event_codes},
|
||||||
|
)
|
||||||
|
OUTPUT.write_text(src)
|
||||||
|
print(f"Generated {OUTPUT.name} ({len(event_codes)} event codes)")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Generate indev constant tables from LVGL headers."""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||||
|
from enum_parser import parse_enum, generate_dict_module
|
||||||
|
|
||||||
|
LVGL_SRC = Path(__file__).parent.parent.parent.parent.parent / "src"
|
||||||
|
OUTPUT = Path(__file__).parent.parent.parent / "lvglgdb" / "lvgl" / "core" / "lv_indev_consts.py"
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
indev_types = parse_enum(
|
||||||
|
LVGL_SRC / "indev" / "lv_indev.h",
|
||||||
|
"lv_indev_type_t",
|
||||||
|
"LV_INDEV_TYPE_",
|
||||||
|
)
|
||||||
|
src = generate_dict_module(
|
||||||
|
"indev constants from LVGL headers",
|
||||||
|
{"INDEV_TYPE_NAMES": indev_types},
|
||||||
|
)
|
||||||
|
OUTPUT.write_text(src)
|
||||||
|
print(f"Generated {OUTPUT.name} ({len(indev_types)} indev types)")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
+24
-76
@@ -1,32 +1,29 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""
|
"""Generate style constant tables from LVGL headers."""
|
||||||
Generate style constant tables from LVGL header files.
|
|
||||||
|
|
||||||
Parses lv_style.h, lv_obj_style.h, and lv_style_gen.h to produce
|
|
||||||
lv_style_consts.py used by the lvglgdb GDB plugin.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
python3 scripts/gen_style_consts.py
|
|
||||||
"""
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
SCRIPT_DIR = Path(__file__).parent
|
LVGL_SRC = Path(__file__).parent.parent.parent.parent.parent / "src"
|
||||||
GDB_ROOT = SCRIPT_DIR.parent
|
GDB_ROOT = Path(__file__).parent.parent.parent
|
||||||
LVGL_SRC = GDB_ROOT.parent.parent / "src"
|
|
||||||
OUTPUT = GDB_ROOT / "lvglgdb" / "lvgl" / "misc" / "lv_style_consts.py"
|
OUTPUT = GDB_ROOT / "lvglgdb" / "lvgl" / "misc" / "lv_style_consts.py"
|
||||||
|
|
||||||
STYLE_H = LVGL_SRC / "misc" / "lv_style.h"
|
STYLE_H = LVGL_SRC / "misc" / "lv_style.h"
|
||||||
OBJ_STYLE_H = LVGL_SRC / "core" / "lv_obj_style.h"
|
OBJ_STYLE_H = LVGL_SRC / "core" / "lv_obj_style.h"
|
||||||
STYLE_GEN_H = LVGL_SRC / "misc" / "lv_style_gen.h"
|
STYLE_GEN_H = LVGL_SRC / "misc" / "lv_style_gen.h"
|
||||||
|
|
||||||
|
SKIP_PROPS = {
|
||||||
|
"LV_STYLE_PROP_INV",
|
||||||
|
"LV_STYLE_PROP_ANY",
|
||||||
|
"LV_STYLE_PROP_CONST",
|
||||||
|
"LV_STYLE_LAST_BUILT_IN_PROP",
|
||||||
|
"LV_STYLE_NUM_BUILT_IN_PROPS",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def parse_style_props(path: Path) -> dict[int, str]:
|
def parse_style_props(path: Path) -> dict[int, str]:
|
||||||
"""Parse _lv_style_id_t enum from lv_style.h."""
|
"""Parse _lv_style_id_t enum from lv_style.h."""
|
||||||
text = path.read_text()
|
text = path.read_text()
|
||||||
|
|
||||||
# Extract enum block
|
|
||||||
m = re.search(r"enum\s+_lv_style_id_t\s*\{(.*?)\}", text, re.DOTALL)
|
m = re.search(r"enum\s+_lv_style_id_t\s*\{(.*?)\}", text, re.DOTALL)
|
||||||
if not m:
|
if not m:
|
||||||
raise RuntimeError("Cannot find _lv_style_id_t enum")
|
raise RuntimeError("Cannot find _lv_style_id_t enum")
|
||||||
@@ -35,41 +32,21 @@ def parse_style_props(path: Path) -> dict[int, str]:
|
|||||||
current_val = 0
|
current_val = 0
|
||||||
for line in m.group(1).splitlines():
|
for line in m.group(1).splitlines():
|
||||||
line = line.strip().rstrip(",")
|
line = line.strip().rstrip(",")
|
||||||
if (
|
if not line or line.startswith(("/*", "//", "*")):
|
||||||
not line
|
|
||||||
or line.startswith("/*")
|
|
||||||
or line.startswith("//")
|
|
||||||
or line.startswith("*")
|
|
||||||
):
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Match: LV_STYLE_XXX = value or LV_STYLE_XXX (auto-increment)
|
|
||||||
match = re.match(r"(LV_STYLE_\w+)\s*=\s*(0x[\da-fA-F]+|\d+)", line)
|
match = re.match(r"(LV_STYLE_\w+)\s*=\s*(0x[\da-fA-F]+|\d+)", line)
|
||||||
if match:
|
if match:
|
||||||
name = match.group(1)
|
name, current_val = match.group(1), int(match.group(2), 0)
|
||||||
val_str = match.group(2)
|
|
||||||
current_val = int(val_str, 0)
|
|
||||||
else:
|
else:
|
||||||
match = re.match(r"(LV_STYLE_\w+)", line)
|
match = re.match(r"(LV_STYLE_\w+)", line)
|
||||||
if not match:
|
if not match:
|
||||||
continue
|
continue
|
||||||
name = match.group(1)
|
name = match.group(1)
|
||||||
|
if name in SKIP_PROPS:
|
||||||
# Skip meta entries
|
|
||||||
if name in (
|
|
||||||
"LV_STYLE_PROP_INV",
|
|
||||||
"LV_STYLE_PROP_ANY",
|
|
||||||
"LV_STYLE_PROP_CONST",
|
|
||||||
"LV_STYLE_LAST_BUILT_IN_PROP",
|
|
||||||
"LV_STYLE_NUM_BUILT_IN_PROPS",
|
|
||||||
):
|
|
||||||
current_val += 1
|
current_val += 1
|
||||||
continue
|
continue
|
||||||
|
props[current_val] = name.removeprefix("LV_STYLE_")
|
||||||
short = name.removeprefix("LV_STYLE_")
|
|
||||||
props[current_val] = short
|
|
||||||
current_val += 1
|
current_val += 1
|
||||||
|
|
||||||
return props
|
return props
|
||||||
|
|
||||||
|
|
||||||
@@ -79,18 +56,13 @@ def parse_parts(path: Path) -> dict[int, str]:
|
|||||||
m = re.search(r"typedef\s+enum\s*\{(.*?)\}\s*lv_part_t", text, re.DOTALL)
|
m = re.search(r"typedef\s+enum\s*\{(.*?)\}\s*lv_part_t", text, re.DOTALL)
|
||||||
if not m:
|
if not m:
|
||||||
raise RuntimeError("Cannot find lv_part_t enum")
|
raise RuntimeError("Cannot find lv_part_t enum")
|
||||||
|
|
||||||
parts = {}
|
parts = {}
|
||||||
for line in m.group(1).splitlines():
|
for line in m.group(1).splitlines():
|
||||||
match = re.match(r"\s*(LV_PART_\w+)\s*=\s*(0x[\da-fA-F]+|\d+)", line)
|
match = re.match(r"\s*(LV_PART_\w+)\s*=\s*(0x[\da-fA-F]+|\d+)", line)
|
||||||
if not match:
|
if not match:
|
||||||
continue
|
continue
|
||||||
name = match.group(1)
|
|
||||||
val = int(match.group(2), 0)
|
val = int(match.group(2), 0)
|
||||||
short = name.removeprefix("LV_PART_")
|
parts[val >> 16] = match.group(1).removeprefix("LV_PART_")
|
||||||
# Selector uses bits [23:16], shift down to get the key
|
|
||||||
parts[val >> 16] = short
|
|
||||||
|
|
||||||
return parts
|
return parts
|
||||||
|
|
||||||
|
|
||||||
@@ -112,25 +84,17 @@ def parse_states(path: Path) -> dict[int, str]:
|
|||||||
m = re.search(r"typedef\s+enum\s*\{(.*?)\}\s*lv_state_t", text, re.DOTALL)
|
m = re.search(r"typedef\s+enum\s*\{(.*?)\}\s*lv_state_t", text, re.DOTALL)
|
||||||
if not m:
|
if not m:
|
||||||
raise RuntimeError("Cannot find lv_state_t enum")
|
raise RuntimeError("Cannot find lv_state_t enum")
|
||||||
|
|
||||||
states = {}
|
states = {}
|
||||||
for line in m.group(1).splitlines():
|
for line in m.group(1).splitlines():
|
||||||
match = re.match(r"\s*(LV_STATE_\w+)\s*=\s*(.+?)(?:,|/)", line)
|
match = re.match(r"\s*(LV_STATE_\w+)\s*=\s*(.+?)(?:,|/)", line)
|
||||||
if not match:
|
if not match:
|
||||||
continue
|
continue
|
||||||
name = match.group(1)
|
name = match.group(1)
|
||||||
expr = match.group(2).strip()
|
|
||||||
|
|
||||||
# Skip DEFAULT (0) and ANY (0xFFFF)
|
|
||||||
if name in ("LV_STATE_DEFAULT", "LV_STATE_ANY"):
|
if name in ("LV_STATE_DEFAULT", "LV_STATE_ANY"):
|
||||||
continue
|
continue
|
||||||
|
val = _parse_int_expr(match.group(2))
|
||||||
val = _parse_int_expr(expr)
|
if val is not None:
|
||||||
if val is None:
|
states[val] = name.removeprefix("LV_STATE_")
|
||||||
continue
|
|
||||||
short = name.removeprefix("LV_STATE_")
|
|
||||||
states[val] = short
|
|
||||||
|
|
||||||
return states
|
return states
|
||||||
|
|
||||||
|
|
||||||
@@ -138,7 +102,6 @@ def parse_color_props(style_gen_h: Path, prop_map: dict[int, str]) -> set[int]:
|
|||||||
"""Identify color properties from lv_style_gen.h setter signatures."""
|
"""Identify color properties from lv_style_gen.h setter signatures."""
|
||||||
text = style_gen_h.read_text()
|
text = style_gen_h.read_text()
|
||||||
name_to_id = {v: k for k, v in prop_map.items()}
|
name_to_id = {v: k for k, v in prop_map.items()}
|
||||||
|
|
||||||
color_ids = set()
|
color_ids = set()
|
||||||
for match in re.finditer(
|
for match in re.finditer(
|
||||||
r"void\s+lv_style_set_(\w+)\s*\([^,]+,\s*lv_color_t", text
|
r"void\s+lv_style_set_(\w+)\s*\([^,]+,\s*lv_color_t", text
|
||||||
@@ -146,7 +109,6 @@ def parse_color_props(style_gen_h: Path, prop_map: dict[int, str]) -> set[int]:
|
|||||||
prop_name = match.group(1).upper()
|
prop_name = match.group(1).upper()
|
||||||
if prop_name in name_to_id:
|
if prop_name in name_to_id:
|
||||||
color_ids.add(name_to_id[prop_name])
|
color_ids.add(name_to_id[prop_name])
|
||||||
|
|
||||||
return color_ids
|
return color_ids
|
||||||
|
|
||||||
|
|
||||||
@@ -154,7 +116,6 @@ def parse_pointer_props(style_gen_h: Path, prop_map: dict[int, str]) -> set[int]
|
|||||||
"""Identify pointer properties from lv_style_gen.h setter signatures."""
|
"""Identify pointer properties from lv_style_gen.h setter signatures."""
|
||||||
text = style_gen_h.read_text()
|
text = style_gen_h.read_text()
|
||||||
name_to_id = {v: k for k, v in prop_map.items()}
|
name_to_id = {v: k for k, v in prop_map.items()}
|
||||||
|
|
||||||
ptr_ids = set()
|
ptr_ids = set()
|
||||||
for match in re.finditer(
|
for match in re.finditer(
|
||||||
r"void\s+lv_style_set_(\w+)\s*\([^,]+,\s*(?:const\s+)?(?:void|lv_\w+)\s*\*",
|
r"void\s+lv_style_set_(\w+)\s*\([^,]+,\s*(?:const\s+)?(?:void|lv_\w+)\s*\*",
|
||||||
@@ -163,50 +124,38 @@ def parse_pointer_props(style_gen_h: Path, prop_map: dict[int, str]) -> set[int]
|
|||||||
prop_name = match.group(1).upper()
|
prop_name = match.group(1).upper()
|
||||||
if prop_name in name_to_id:
|
if prop_name in name_to_id:
|
||||||
ptr_ids.add(name_to_id[prop_name])
|
ptr_ids.add(name_to_id[prop_name])
|
||||||
|
|
||||||
return ptr_ids
|
return ptr_ids
|
||||||
|
|
||||||
|
|
||||||
def generate(
|
def generate(props, parts, states, color_ids, pointer_ids) -> str:
|
||||||
props: dict[int, str],
|
"""Generate Python source for the style constants module."""
|
||||||
parts: dict[int, str],
|
|
||||||
states: dict[int, str],
|
|
||||||
color_ids: set[int],
|
|
||||||
pointer_ids: set[int],
|
|
||||||
) -> str:
|
|
||||||
"""Generate Python source for the constants module."""
|
|
||||||
lines = [
|
lines = [
|
||||||
'"""',
|
'"""',
|
||||||
"Auto-generated style constants from LVGL headers.",
|
"Auto-generated style constants from LVGL headers.",
|
||||||
"",
|
"",
|
||||||
"Do not edit manually. Regenerate with:",
|
"Do not edit manually. Regenerate from the GDB script root with:",
|
||||||
" python3 scripts/gen_style_consts.py",
|
" python3 scripts/generate_all.py",
|
||||||
'"""',
|
'"""',
|
||||||
"",
|
"",
|
||||||
]
|
]
|
||||||
|
|
||||||
# STYLE_PROP_NAMES
|
|
||||||
lines.append("STYLE_PROP_NAMES = {")
|
lines.append("STYLE_PROP_NAMES = {")
|
||||||
for k in sorted(props):
|
for k in sorted(props):
|
||||||
lines.append(f' {k}: "{props[k]}",')
|
lines.append(f' {k}: "{props[k]}",')
|
||||||
lines.append("}")
|
lines.append("}")
|
||||||
lines.append("")
|
lines.append("")
|
||||||
|
|
||||||
# PART_NAMES
|
|
||||||
lines.append("PART_NAMES = {")
|
lines.append("PART_NAMES = {")
|
||||||
for k in sorted(parts):
|
for k in sorted(parts):
|
||||||
lines.append(f' 0x{k:02X}: "{parts[k]}",')
|
lines.append(f' 0x{k:02X}: "{parts[k]}",')
|
||||||
lines.append("}")
|
lines.append("}")
|
||||||
lines.append("")
|
lines.append("")
|
||||||
|
|
||||||
# STATE_FLAGS
|
|
||||||
lines.append("STATE_FLAGS = {")
|
lines.append("STATE_FLAGS = {")
|
||||||
for k in sorted(states):
|
for k in sorted(states):
|
||||||
lines.append(f' 0x{k:04X}: "{states[k]}",')
|
lines.append(f' 0x{k:04X}: "{states[k]}",')
|
||||||
lines.append("}")
|
lines.append("}")
|
||||||
lines.append("")
|
lines.append("")
|
||||||
|
|
||||||
# COLOR_PROPS
|
|
||||||
if color_ids:
|
if color_ids:
|
||||||
lines.append("COLOR_PROPS = {")
|
lines.append("COLOR_PROPS = {")
|
||||||
for v in sorted(color_ids):
|
for v in sorted(color_ids):
|
||||||
@@ -216,7 +165,6 @@ def generate(
|
|||||||
lines.append("COLOR_PROPS = set()")
|
lines.append("COLOR_PROPS = set()")
|
||||||
lines.append("")
|
lines.append("")
|
||||||
|
|
||||||
# POINTER_PROPS
|
|
||||||
if pointer_ids:
|
if pointer_ids:
|
||||||
lines.append("POINTER_PROPS = {")
|
lines.append("POINTER_PROPS = {")
|
||||||
for v in sorted(pointer_ids):
|
for v in sorted(pointer_ids):
|
||||||
@@ -239,7 +187,7 @@ def main():
|
|||||||
src = generate(props, parts, states, color_ids, pointer_ids)
|
src = generate(props, parts, states, color_ids, pointer_ids)
|
||||||
OUTPUT.write_text(src)
|
OUTPUT.write_text(src)
|
||||||
print(
|
print(
|
||||||
f"Generated {OUTPUT} ({len(props)} props, {len(parts)} parts, "
|
f"Generated {OUTPUT.name} ({len(props)} props, {len(parts)} parts, "
|
||||||
f"{len(states)} states, {len(color_ids)} color, {len(pointer_ids)} pointer)"
|
f"{len(states)} states, {len(color_ids)} color, {len(pointer_ids)} pointer)"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Generate subject type constant table from LVGL headers."""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||||
|
from enum_parser import parse_enum, generate_dict_module
|
||||||
|
|
||||||
|
LVGL_SRC = Path(__file__).parent.parent.parent.parent.parent / "src"
|
||||||
|
OUTPUT = Path(__file__).parent.parent.parent / "lvglgdb" / "lvgl" / "core" / "lv_observer_consts.py"
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
subject_types = parse_enum(
|
||||||
|
LVGL_SRC / "core" / "lv_observer.h",
|
||||||
|
"lv_subject_type_t",
|
||||||
|
"LV_SUBJECT_TYPE_",
|
||||||
|
)
|
||||||
|
src = generate_dict_module(
|
||||||
|
"observer constants from LVGL headers",
|
||||||
|
{"SUBJECT_TYPE_NAMES": subject_types},
|
||||||
|
)
|
||||||
|
OUTPUT.write_text(src)
|
||||||
|
print(f"Generated {OUTPUT.name} ({len(subject_types)} subject types)")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user