mirror of https://github.com/arendst/Tasmota.git
372 lines
11 KiB
Python
372 lines
11 KiB
Python
|
import re
|
||
|
|
||
|
in_file = "lv_widgets.txt"
|
||
|
out_file = "out.c"
|
||
|
|
||
|
m = re.compile("(.*?)\s(\w+)\((.*?)\);")
|
||
|
|
||
|
return_types = {
|
||
|
"void": "",
|
||
|
"bool": "b",
|
||
|
"uint8_t": "i",
|
||
|
"uint16_t": "i",
|
||
|
"int16_t": "i",
|
||
|
"uint32_t": "i",
|
||
|
"void *": "i",
|
||
|
"const void *": "i",
|
||
|
"char *": "s",
|
||
|
"const char *": "s",
|
||
|
"lv_obj_user_data_t": "i",
|
||
|
|
||
|
"lv_coord_t": "i",
|
||
|
"lv_res_t": "i",
|
||
|
"lv_style_int_t": "i",
|
||
|
"lv_opa_t": "i",
|
||
|
"lv_drag_dir_t": "i",
|
||
|
"lv_bidi_dir_t": "i",
|
||
|
"lv_state_t": "i",
|
||
|
"lv_label_long_mode_t": "i",
|
||
|
"lv_label_align_t": "i",
|
||
|
"lv_arc_type_t":"i",
|
||
|
"lv_chart_axis_t":"i",
|
||
|
"lv_bar_type_t":"i",
|
||
|
"lv_btn_state_t":"i",
|
||
|
"lv_point_t":"i",
|
||
|
|
||
|
"lv_obj_t *": "lv_obj",
|
||
|
"lv_color_t": "lv_color",
|
||
|
"lv_style_t *": "lv_style",
|
||
|
#"lv_disp_t*": "lv_disp",
|
||
|
#"lv_style_list_t*": "",
|
||
|
}
|
||
|
|
||
|
lv = {}
|
||
|
lvs = [] # special case for case for lv_style
|
||
|
lv0 = [] # function in lvlg module
|
||
|
|
||
|
lv_prefix = ['obj', 'label', 'group', 'arc', 'bar', 'btn', 'btnmatrix', 'calendar', 'canvas', 'chart', 'checkbox']
|
||
|
|
||
|
# convert a C return type to the string representation for the Berry parser
|
||
|
# using return_types
|
||
|
def c_convert_ret_type(c_ret):
|
||
|
return return_types.get(c_ret, "")
|
||
|
|
||
|
with open(in_file) as f, open(out_file,"w") as out:
|
||
|
for l_raw in f:
|
||
|
l_raw = re.sub('static ', '', l_raw)
|
||
|
l_raw = re.sub('inline ', '', l_raw)
|
||
|
l_raw = l_raw.strip(" \t\n\r") # remove leading or trailing spaces
|
||
|
l_raw = re.sub('//.*$', '', l_raw) # replace any multi-space with a single space
|
||
|
if (len(l_raw) == 0): continue
|
||
|
|
||
|
g = m.search(l_raw)
|
||
|
if g:
|
||
|
# if match, we parse the line
|
||
|
ret_type = g.group(1)
|
||
|
ret_type = re.sub('\s+', ' ', ret_type) # replace any multi-space with a single space
|
||
|
|
||
|
if ret_type not in return_types:
|
||
|
print(f" // Skipping unsupported return type: {ret_type}")
|
||
|
continue
|
||
|
|
||
|
# convert return type
|
||
|
c_ret = c_convert_ret_type(ret_type)
|
||
|
|
||
|
# convert arguments
|
||
|
# TODO
|
||
|
c_args = None
|
||
|
|
||
|
# analyze function name and determine if it needs to be assigned to a specific class
|
||
|
func_name = g.group(2)
|
||
|
if func_name.startswith("_"): continue # skip low-level
|
||
|
if func_name.startswith("lv_debug_"): continue # skip debug
|
||
|
|
||
|
c_func_name = ""
|
||
|
|
||
|
found = False
|
||
|
for subtype in lv_prefix:
|
||
|
if func_name.startswith("lv_" + subtype + "_"):
|
||
|
be_name = re.sub("^lv_" + subtype + "_", '', func_name)
|
||
|
c_func_name = "lvbe_" + subtype + "_" + be_name
|
||
|
if subtype not in lv: lv[subtype] = [] # add entry
|
||
|
# special case if the function is create, we change the return type to macth the class
|
||
|
if be_name == 'create':
|
||
|
c_ret = "lv_" + subtype
|
||
|
lv[subtype].append( [ c_func_name, c_ret, c_args, func_name, be_name ] )
|
||
|
found = True
|
||
|
break
|
||
|
|
||
|
if found: continue
|
||
|
# if func_name.startswith("lv_obj_"):
|
||
|
# c_func_name = "lvo_" + re.sub('^lv_obj_', '', func_name)
|
||
|
# lvo.append( [ c_func_name, c_ret, c_args, func_name ] )
|
||
|
# elif func_name.startswith("lv_label_"):
|
||
|
# c_func_name = "lvo_label_" + re.sub('^lv_label_', '', func_name)
|
||
|
# lvo.append( [ c_func_name, c_ret, c_args, func_name ] )
|
||
|
# elif func_name.startswith("lv_group_"):
|
||
|
# c_func_name = "lvg_" + re.sub('^lv_group_', '', func_name)
|
||
|
# lvg.append( [ c_func_name, c_ret, c_args, func_name ] )
|
||
|
|
||
|
|
||
|
# elif func_name.startswith("lv_arc_"):
|
||
|
# c_func_name = "lvg_" + re.sub('^lv_arc_', '', func_name)
|
||
|
# lvg.append( [ c_func_name, c_ret, c_args, func_name ] )
|
||
|
|
||
|
|
||
|
if func_name.startswith("lv_style_"):
|
||
|
be_name = re.sub('^lv_style_', '', func_name)
|
||
|
c_func_name = "lvs_" + be_name
|
||
|
lvs.append( [ c_func_name, c_ret, c_args, func_name, be_name ] )
|
||
|
|
||
|
else:
|
||
|
be_name = re.sub('^lv_', '', func_name)
|
||
|
c_func_name = "lvbe0_" + be_name
|
||
|
lv0.append( [ c_func_name, c_ret, c_args, func_name, be_name ] )
|
||
|
|
||
|
|
||
|
print(lv)
|
||
|
|
||
|
#print(f"orig {func_name} berry {c_func_name}")
|
||
|
|
||
|
#print(g.group(1))
|
||
|
#print(g.group(2))
|
||
|
#print(g.group(3))
|
||
|
|
||
|
print("/********************************************************************")
|
||
|
print(" * Generated code, don't edit")
|
||
|
print(" *******************************************************************/")
|
||
|
|
||
|
for subtype, flv in lv.items():
|
||
|
print(f" /* `lv_{subtype}` methods */")
|
||
|
for f in flv:
|
||
|
c_func_name = f[0]
|
||
|
c_ret_type = f[1]
|
||
|
c_argc = f[2]
|
||
|
if c_argc is not None: c_argc = "\"" + c_argc + "\""
|
||
|
orig_func_name = f[3]
|
||
|
#print(f" int {c_func_name}(bvm *vm) \{ return (vm, be_call_c_func(void*) &")
|
||
|
print(f" int {c_func_name}(bvm *vm) {{ return be_call_c_func(vm, (void*) &{orig_func_name}, \"{c_ret_type}\", { c_argc if c_argc else 'nullptr'}); }}")
|
||
|
print()
|
||
|
|
||
|
print("/********************************************************************/")
|
||
|
print()
|
||
|
|
||
|
|
||
|
print("/********************************************************************")
|
||
|
print(" * Generated code, don't edit")
|
||
|
print(" *******************************************************************/")
|
||
|
|
||
|
for subtype, flv in lv.items():
|
||
|
print(f"/* `lv_{subtype}` external functions definitions */")
|
||
|
for f in flv:
|
||
|
c_func_name = f[0]
|
||
|
print(f"extern int {c_func_name}(bvm *vm);")
|
||
|
|
||
|
print()
|
||
|
|
||
|
# class definitions
|
||
|
print(f"void be_load_lv_{subtype}_lib(bvm *vm) {{")
|
||
|
print(f" static const bnfuncinfo members[] = {{")
|
||
|
print(f" {{ \".p\", NULL }},")
|
||
|
print(f" {{ \"init\", lvx_init_2 }},")
|
||
|
print(f" {{ \"tostring\", lvx_tostring }},")
|
||
|
print()
|
||
|
for f in flv:
|
||
|
|
||
|
c_func_name = f[0]
|
||
|
be_name = f[4]
|
||
|
print(f" {{ \"{be_name}\", {c_func_name} }},")
|
||
|
|
||
|
print()
|
||
|
print(f" // {{ NULL, (bntvfunc) BE_CLOSURE }}, /* mark section for berry closures */")
|
||
|
print()
|
||
|
print(f" {{ NULL, NULL }}")
|
||
|
print(f" }};")
|
||
|
print(f" be_regclass(vm, \"lv_{subtype}\", members);")
|
||
|
print(f"}};")
|
||
|
print()
|
||
|
print(f"/* @const_object_info_begin")
|
||
|
print(f"class be_class_lv_{subtype} (scope: global, name: lv_{subtype}, super: lv_obj) {{")
|
||
|
print(f" .p, var")
|
||
|
print(f" init, func(lvx_init_2)")
|
||
|
print(f" tostring, func(lvx_tostring)")
|
||
|
|
||
|
for f in flv:
|
||
|
c_func_name = f[0]
|
||
|
be_name = f[4]
|
||
|
print(f" {be_name}, func({c_func_name})")
|
||
|
|
||
|
print(f"}}")
|
||
|
print(f"@const_object_info_end */")
|
||
|
print(f"//#include \"../generate/be_fixed_be_class_lv_{subtype}.h\"")
|
||
|
print()
|
||
|
|
||
|
print()
|
||
|
print(f"void be_load_lv_all_lib(bvm *vm) {{")
|
||
|
|
||
|
for subtype in lv:
|
||
|
print(f" be_load_lv_{subtype}_lib(vm);")
|
||
|
|
||
|
print(f"}};")
|
||
|
|
||
|
|
||
|
|
||
|
# for f in lvo:
|
||
|
# c_func_name = f[0]
|
||
|
# print(f"extern int {c_func_name}(bvm *vm);")
|
||
|
|
||
|
# print("/********************************************************************/")
|
||
|
# print()
|
||
|
|
||
|
# print("/********************************************************************")
|
||
|
# print(" * Generated code, don't edit")
|
||
|
# print(" *******************************************************************/")
|
||
|
|
||
|
# print("/* `lv_object` methods */")
|
||
|
# print()
|
||
|
|
||
|
# for f in lvo:
|
||
|
# c_func_name = f[0]
|
||
|
# berry_name = c_func_name
|
||
|
# berry_name = re.sub('^lvo_label_', '', berry_name)
|
||
|
# berry_name = re.sub('^lvo_', '', berry_name)
|
||
|
# print(f" {{ \"{berry_name}\", {c_func_name} }},")
|
||
|
|
||
|
# print("/********************************************************************/")
|
||
|
# print()
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
# print("/********************************************************************")
|
||
|
# print(" * Generated code, don't edit")
|
||
|
# print(" *******************************************************************/")
|
||
|
|
||
|
# print("/* `lv_group methods */")
|
||
|
# print()
|
||
|
|
||
|
# for f in lvg:
|
||
|
# c_func_name = f[0]
|
||
|
# c_ret_type = f[1]
|
||
|
# c_argc = f[2]
|
||
|
# if c_argc is not None: c_argc = "\"" + c_argc + "\""
|
||
|
# orig_func_name = f[3]
|
||
|
# #print(f" int {c_func_name}(bvm *vm) \{ return (vm, be_call_c_func(void*) &")
|
||
|
# print(f" int {c_func_name}(bvm *vm) {{ return be_call_c_func(vm, (void*) &{orig_func_name}, \"{c_ret_type}\", { c_argc if c_argc else 'nullptr'}); }}")
|
||
|
|
||
|
# print("/********************************************************************/")
|
||
|
# print()
|
||
|
|
||
|
|
||
|
# print("/********************************************************************")
|
||
|
# print(" * Generated code, don't edit")
|
||
|
# print(" *******************************************************************/")
|
||
|
|
||
|
# print("/* `lv_group external functions definitions */")
|
||
|
# print()
|
||
|
|
||
|
# for f in lvg:
|
||
|
# c_func_name = f[0]
|
||
|
# print(f"extern int {c_func_name}(bvm *vm);")
|
||
|
|
||
|
# print("/********************************************************************/")
|
||
|
# print()
|
||
|
|
||
|
# print("/********************************************************************")
|
||
|
# print(" * Generated code, don't edit")
|
||
|
# print(" *******************************************************************/")
|
||
|
|
||
|
# print("/* `lv_group` methods */")
|
||
|
# print()
|
||
|
|
||
|
# for f in lvg:
|
||
|
# c_func_name = f[0]
|
||
|
# berry_name = c_func_name
|
||
|
# berry_name = re.sub('^lvg_', '', berry_name)
|
||
|
# print(f" {{ \"{berry_name}\", {c_func_name} }},")
|
||
|
|
||
|
# print("/********************************************************************/")
|
||
|
# print()
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
# print("/********************************************************************")
|
||
|
# print(" * Generated code, don't edit")
|
||
|
# print(" *******************************************************************/")
|
||
|
|
||
|
# print("/* `lv_style methods */")
|
||
|
# print()
|
||
|
|
||
|
# for f in lvs:
|
||
|
# c_func_name = f[0]
|
||
|
# c_ret_type = f[1]
|
||
|
# c_argc = f[2]
|
||
|
# if c_argc is not None: c_argc = "\"" + c_argc + "\""
|
||
|
# orig_func_name = f[3]
|
||
|
# #print(f" int {c_func_name}(bvm *vm) \{ return (vm, be_call_c_func(void*) &")
|
||
|
# print(f" int {c_func_name}(bvm *vm) {{ return be_call_c_func(vm, (void*) &{orig_func_name}, \"{c_ret_type}\", { c_argc if c_argc else 'nullptr'}); }}")
|
||
|
|
||
|
# print("/********************************************************************/")
|
||
|
# print()
|
||
|
|
||
|
|
||
|
# print("/********************************************************************")
|
||
|
# print(" * Generated code, don't edit")
|
||
|
# print(" *******************************************************************/")
|
||
|
|
||
|
# print("/* `lv_style external functions definitions */")
|
||
|
# print()
|
||
|
|
||
|
# for f in lvs:
|
||
|
# c_func_name = f[0]
|
||
|
# print(f"extern int {c_func_name}(bvm *vm);")
|
||
|
|
||
|
# print("/********************************************************************/")
|
||
|
# print()
|
||
|
|
||
|
# print("/********************************************************************")
|
||
|
# print(" * Generated code, don't edit")
|
||
|
# print(" *******************************************************************/")
|
||
|
|
||
|
# print("/* `lv_style` methods */")
|
||
|
# print()
|
||
|
|
||
|
# for f in lvs:
|
||
|
# c_func_name = f[0]
|
||
|
# berry_name = c_func_name
|
||
|
# berry_name = re.sub('^lvs_', '', berry_name)
|
||
|
# print(f" {{ \"{berry_name}\", {c_func_name} }},")
|
||
|
|
||
|
# print("/********************************************************************/")
|
||
|
# print()
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
# print("/********************************************************************")
|
||
|
# print(" * Generated code, don't edit")
|
||
|
# print(" *******************************************************************/")
|
||
|
|
||
|
# print("/* `lvgl` functions */")
|
||
|
# print()
|
||
|
|
||
|
# for f in lv:
|
||
|
# c_func_name = f[0]
|
||
|
# c_ret_type = f[1]
|
||
|
# c_argc = f[2]
|
||
|
# if c_argc is not None: c_argc = "\"" + c_argc + "\""
|
||
|
# orig_func_name = f[3]
|
||
|
# #print(f" int {c_func_name}(bvm *vm) \{ return (vm, be_call_c_func(void*) &")
|
||
|
# print(f" int {c_func_name}(bvm *vm) {{ return be_call_c_func(vm, (void*) &{orig_func_name}, \"{c_ret_type}\", { c_argc if c_argc else 'nullptr'}); }}")
|
||
|
|
||
|
# print("/********************************************************************/")
|
||
|
# print()
|
||
|
|
||
|
|
||
|
|
||
|
#int lv0_label_create(bvm *vm) { return be_call_c_func(vm, (void*) &lv_label_create, LV_OBJ_CLASS); }
|
||
|
|
||
|
|
||
|
#print(lvo)
|