genapi.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592
  1. #!/usr/bin/python
  2. # -*- coding: UTF-8 -*-
  3. '''
  4. 使用 https://github.com/eliben/pycparser 生成 Lua 绑定 LVGL的 API
  5. '''
  6. import sys
  7. import subprocess
  8. import os
  9. import traceback
  10. from pycparser import c_parser, c_ast, parse_file
  11. methods = {}
  12. enums = []
  13. enum_names = set({})
  14. miss_arg_types = set({})
  15. miss_ret_types = set({})
  16. # 各种命名, 但全都上int变种
  17. map_lv_ints = ["lv_arc_type_t", "lv_style_int_t", "lv_coord_t", "lv_spinner_dir_t", "lv_drag_dir_t",
  18. "lv_keyboard_mode_t", "int16_t", "int8_t", "int32_t", "uint8_t", "uint16_t", "uint32_t",
  19. "lv_chart_type_t", "lv_border_side_t", "lv_anim_value_t", "lv_img_src_t", "lv_text_decor_t",
  20. "lv_align_t", "lv_spinner_type_t", "lv_dropdown_dir_t", "lv_scrollbar_mode_t",
  21. "lv_label_long_mode_t", "lv_chart_axis_t", "lv_blend_mode_t", "lv_bidi_dir_t",
  22. "lv_slider_type_t", "lv_tabview_btns_pos_t",
  23. "lv_indev_type_t", "lv_disp_size_t",
  24. "lv_opa_t", "lv_label_align_t", "lv_fit_t", "lv_bar_type_t", "lv_btn_state_t",
  25. "lv_gesture_dir_t", "lv_state_t", "lv_layout_t", "lv_cpicker_color_mode_t",
  26. "lv_disp_rot_t", "lv_grad_dir_t", "lv_chart_type_t", "lv_text_align_t", "lv_arc_mode_t", "lv_table_cell_ctrl_t",
  27. "lv_scroll_snap_t", "lv_style_prop_t", "lv_draw_mask_line_side_t", "lv_obj_flag_t",
  28. "lv_roller_mode_t", "lv_slider_mode_t", "lv_arc_mode_t", "lv_text_align_t", "lv_bar_mode_t", "lv_part_t",
  29. "lv_text_flag_t", "lv_style_selector_t", "lv_dir_t", "lv_scroll_snap_t", "lv_style_prop_t", "lv_base_dir_t",
  30. "lv_slider_mode_t", "lv_arc_mode_t", "lv_text_align_t", "lv_btnmatrix_ctrl_t", "lv_cover_res_t", "lv_event_code_t",
  31. "lv_flex_flow_t", "lv_grid_align_t"]
  32. custom_method_names = ["lv_img_set_src", "lv_imgbtn_set_src"]
  33. class FuncDefVisitor(c_ast.NodeVisitor):
  34. def __init__(self, group, prefix):
  35. self.group = group
  36. self.prefix = prefix
  37. #print("FuncDefVisitor >> " + prefix)
  38. def visit_Enum(self, node):
  39. if not node.values :
  40. return
  41. try :
  42. _index_val = None
  43. for e in node.values:
  44. k = e.name
  45. val = e.name
  46. '''
  47. if e.value :
  48. if e.value.__class__.__name__ == "Constant" :
  49. if e.value.value.startswith("0x") :
  50. val = int(e.value.value[2:], 16)
  51. else :
  52. val = int(e.value.value)
  53. #print("add enum", e.name, val)
  54. if _index_val == None :
  55. _index_val = val + 1
  56. else :
  57. print("skip enum ", e.name, e.value)
  58. pass
  59. else:
  60. if _index_val == None :
  61. _index_val = 0
  62. val = _index_val
  63. #print("add enum", e.name, _index_val)
  64. _index_val += 1
  65. '''
  66. if val != None and k not in enum_names :
  67. enum_names.add(k)
  68. enums.append([k, val])
  69. except Exception :
  70. import traceback
  71. traceback.print_exc()
  72. sys.exit()
  73. def visit_FuncDecl(self, node):
  74. try :
  75. is_ptr_return = False
  76. method_name = None
  77. if node.type.__class__.__name__ == "PtrDecl":
  78. is_ptr_return = True
  79. if type(node.type.type) == c_ast.TypeDecl :
  80. method_name = node.type.type.declname
  81. elif type(node.type.type) == c_ast.PtrDecl :
  82. # 返回值是 char**,暂不支持了
  83. # lv_btnmatrix_get_map_array
  84. # lv_calendar_get_day_names
  85. # lv_calendar_get_month_names
  86. # lv_keyboard_get_map_array,
  87. node.type.type.show()
  88. return
  89. else:
  90. node.type.type.show()
  91. sys.exit()
  92. else :
  93. method_name = node.type.declname
  94. if method_name.startswith("_"):
  95. return
  96. if not method_name.startswith(f"lv_{self.prefix}"):
  97. return
  98. # 一些回调方法, 这些没法自动生成
  99. if method_name.endswith("_cb") or method_name.endswith("cb_t") or method_name.endswith("_f_t"):
  100. print("skip callback func", method_name)
  101. return
  102. if method_name in ["lv_tlsf_walker", "lv_obj_remove_event_cb_with_user_data",
  103. "lv_win_add_btn"]:
  104. return
  105. if method_name in ["lv_btnmatrix_set_map", "lv_calendar_set_month_names",
  106. "lv_calendar_set_day_names", "lv_label_set_text_fmt",
  107. "lv_msgbox_add_btns", "lv_msgbox_set_text_fmt",
  108. "lv_table_set_cell_value_fmt", "lv_keyboard_set_map",
  109. "lv_dropdown_get_selected_str", "lv_roller_get_selected_str",
  110. "lv_canvas_set_buffer", "lv_dropdown_set_symbol"] :
  111. return
  112. # 因为 points[] 无法处理的方法
  113. if method_name in ["lv_indev_set_button_points", "lv_draw_triangle",
  114. "lv_canvas_draw_line", "lv_canvas_draw_polygon",
  115. "lv_line_set_points", "lv_tileview_set_valid_positions",
  116. "lv_draw_polygon"] :
  117. return
  118. # 因为各种数组无法处理的方法
  119. if method_name in ["lv_btnmatrix_set_ctrl_map", "lv_keyboard_set_ctrl_map", "lv_calendar_set_highlighted_dates",
  120. "lv_chart_set_points", "lv_chart_set_ext_array", "lv_gauge_set_needle_count", "lv_style_transition_dsc_init",
  121. "lv_animimg_set_src", "lv_msgbox_create", "lv_obj_set_grid_dsc_array", "lv_obj_set_grid_dsc_array", "lv_style_set_grid_row_dsc_array", "lv_style_set_grid_column_dsc_array", "lv_obj_set_style_grid_row_dsc_array", "lv_obj_set_style_grid_column_dsc_array", "lv_chart_set_ext_y_array", "lv_chart_set_ext_x_array"] :
  122. return
  123. # 这方法不太可能有人用吧,返回值是uint8_t*,很少见
  124. if method_name in ["lv_font_get_glyph_bitmap"] :
  125. return
  126. if method_name in custom_method_names :
  127. return
  128. #print(method_name + "(", end="")
  129. method_args = []
  130. method_return = "void"
  131. if type(node.type) == c_ast.TypeDecl :
  132. method_return = node.type.type.names[0]
  133. elif type(node.type.type.type) == c_ast.Struct :
  134. if node.type.type.type.name == "_lv_obj_t":
  135. method_return = "lv_obj_t*"
  136. else :
  137. method_return = "struct" + node.type.type.type.name + "*"
  138. else :
  139. method_return = node.type.type.type.names[0] + "*"
  140. if node.args :
  141. #print("has args")
  142. for arg in node.args:
  143. #print(arg.type.__class__.__name__)
  144. #print(arg.name)
  145. if arg.type.__class__.__name__ == "PtrDecl" :
  146. # 指针类型
  147. #print(arg.type.declname, "*", arg.type.type.names[0], )
  148. #arg.type.show()
  149. if arg.type.type.type.__class__.__name__ == "Struct" :
  150. if arg.type.type.type.name == "_lv_obj_t":
  151. method_args.append([arg.name, "lv_obj_t*"])
  152. else :
  153. method_args.append([arg.name, "struct "+arg.type.type.type.name+"*"])
  154. else :
  155. method_args.append([arg.name, arg.type.type.type.names[0] + "*"])
  156. elif arg.type.__class__.__name__ == "TypeDecl":
  157. if arg.type.type.names[0] != "void" :
  158. method_args.append([arg.name, arg.type.type.names[0]])
  159. elif arg.type.__class__.__name__ == "ArrayDecl":
  160. method_args.append([arg.name, arg.type.type.type.names[0] + "[]"])
  161. else :
  162. #print("FUCK", arg.type.__class__.__name__, arg.type.names[0], arg.name, ",", )
  163. print(arg.type.__class__.__name__)
  164. arg.show()
  165. sys.exit()
  166. #print(arg.type, arg.name, ",",)
  167. sb = method_return + " " + method_name + "("
  168. if len(method_args) > 0 :
  169. for arg in method_args :
  170. sb += str(arg[1]) + " " + str(arg[0]) + ", "
  171. sb = sb[:-2]
  172. sb += ");"
  173. #print(sb)
  174. if not self.group in methods :
  175. methods[self.group] = {}
  176. if not self.prefix in methods[self.group]:
  177. methods[self.group][self.prefix] = []
  178. methods[self.group][self.prefix].append({"group":self.group, "prefix":self.prefix, "name":method_name, "ret":method_return, "args":method_args})
  179. except Exception:
  180. print ("method_name", method_name, "error")
  181. import traceback
  182. traceback.print_exc()
  183. sys.exit()
  184. def handle_groups(group, path):
  185. for name in os.listdir(path) :
  186. if not name.endswith(".h"):
  187. continue
  188. if name in ["lv_obj_style_gen.h", "lv_async.h", "lv_fs.h", "lv_log.h", "lv_mem.h",
  189. "lv_printf.h", "lv_style_gen.h", "lv_timer.h", "lv_indev.h", "lv_img_decoder.h", "lv_img_cache.h", "lv_img_buf.h",
  190. "lv_task.h", "lv_debug.h", "lv_event.h", "lv_obj_class.h", "lv_obj_style.h", "lv_obj_tree.h", "lv_obj_draw.h", "lv_obj_scroll.h",
  191. "lv_indev_scroll.h", "lv_font_loader.h", "lv_tlsf.h"]:
  192. continue
  193. if name.startswith("lv_draw_") :
  194. continue
  195. #try :
  196. #print(">>>>>>>>>>>>" + name)
  197. ast = parse_file(os.path.join(path, name), use_cpp=True, cpp_path='D:\\RDA8910_V31\\prebuilts\\win32\\gcc-arm-none-eabi\\bin\\arm-none-eabi-cpp.exe', cpp_args=['-nostdinc', '-E', '-Imock', '-ID:\\RDA8910_V31\\tools\\fake_libc_include', '-I.', '-I../../lua/include', '-I../../luat/include', '-D__attribute__(x)='])
  198. v = FuncDefVisitor("lv_" + group, name[3:-2])
  199. v.visit(ast)
  200. #except Exception :
  201. # print("error>>>>>>>>>>>>" + name)
  202. #traceback.print_exc()
  203. #sys.exit()
  204. def make_style_dec():
  205. import json
  206. defines = []
  207. with open("src/lv_core/lv_obj_style_dec.h") as f :
  208. for line in f.readlines():
  209. if line.startswith("_LV_OBJ_STYLE_SET_GET_DECLARE") :
  210. desc = line[len("_LV_OBJ_STYLE_SET_GET_DECLARE")+1:-2].strip()
  211. vals = desc.split(", ")
  212. if vals[1] == "transition_path":
  213. continue
  214. defines.append(vals)
  215. with open("gen/luat_lv_style_dec.h", "w") as f :
  216. f.write('''#include "luat_base.h"
  217. #include "luat_msgbus.h"
  218. #include "luat_lvgl.h"
  219. #include "lvgl.h"
  220. ''')
  221. RTL = []
  222. for dec in defines :
  223. # 添加 set和get
  224. f.write("int luat_lv_style_set_%s(lua_State *L);\n" % (dec[1], ))
  225. f.write("int luat_lv_style_get_%s(lua_State *L);\n" % (dec[1], ))
  226. RTL.append("{\"style_set_%s\", luat_lv_style_set_%s, 0}," % (dec[1],dec[1],))
  227. #RTL.append("{\"style_get_%s\", luat_lv_style_get_%s, 0}," % (dec[1],dec[1],))
  228. f.write("\n")
  229. f.write("#define LUAT_LV_STYLE_DEC_RLT ")
  230. f.write("\\\n".join(RTL))
  231. f.write("\n")
  232. with open("gen/lv_core/luat_lv_style_dec.c", "w") as f :
  233. f.write('''#include "luat_base.h"
  234. #include "luat_msgbus.h"
  235. #include "luat_lvgl.h"
  236. #include "lvgl.h"
  237. ''')
  238. for dec in defines :
  239. # 先添加set方法
  240. f.write("int luat_lv_style_set_%s(lua_State *L){\n" % (dec[1], ))
  241. f.write(" lv_style_t* _style = (lv_style_t*)lua_touserdata(L, 1);\n")
  242. f.write(" lv_state_t state = (lv_state_t)luaL_checkinteger(L, 2);\n")
  243. if dec[2] in map_lv_ints:
  244. f.write(" %s %s = (%s)luaL_checkinteger(L, 3);\n" % (dec[2], dec[3], dec[2]))
  245. f.write(" lv_style_set_%s(_style, state, %s);\n" % (dec[1], dec[3]))
  246. elif dec[2] == "bool" :
  247. f.write(" %s %s = (%s)lua_toboolean(L, 3);\n" % (dec[2], dec[3], dec[2]))
  248. f.write(" lv_style_set_%s(_style, state, %s);\n" % (dec[1], dec[3]))
  249. elif dec[2] == "lv_color_t" :
  250. f.write(" %s %s;\n" % (dec[2], dec[3]))
  251. f.write(" %s.full = luaL_checkinteger(L, 3);\n" % (dec[3],))
  252. f.write(" lv_style_set_%s(_style, state, %s);\n" % (dec[1], dec[3]))
  253. elif dec[2] == "const char *":
  254. f.write(" %s %s = (%s)luaL_checkstring(L, 3);\n" % (dec[2], dec[3], dec[2]))
  255. f.write(" lv_style_set_%s(_style, state, %s);\n" % (dec[1], dec[3]))
  256. elif dec[2] == "const lv_font_t *" or dec[2] == "lv_font_t*":
  257. f.write(" %s %s = (%s)lua_touserdata(L, 3);\n" % (dec[2], dec[3], dec[2]))
  258. f.write(" lv_style_set_%s(_style, state, %s);\n" % (dec[1], dec[3]))
  259. else :
  260. f.write(" %s %s;\n" % (dec[2], dec[3]))
  261. f.write(" // TODO %s %s\n" % (dec[2], dec[3]))
  262. f.write(" lv_style_set_%s(_style, state, %s);\n" % (dec[1], dec[3]))
  263. print("what? " + dec[2] + " " + dec[1])
  264. f.write(" return 0;\n")
  265. f.write("}\n\n")
  266. # 然后添加get方法
  267. # f.write("int luat_lv_style_get_%s(lua_State *L){\n" % (dec[1], ))
  268. # f.write(" lv_style_t* _style = (lv_style_t*)lua_touserdata(L, 1);\n")
  269. # f.write(" lv_state_t state = (lv_state_t)luaL_checkinteger(L, 2);\n")
  270. # if dec[2] in map_lv_ints or dec[2] == "bool":
  271. # f.write(" %s %s;\n" % (dec[2], dec[3]))
  272. # f.write(" lv_style_get_%s(_style, state, &%s);\n" % (dec[1], dec[3]))
  273. # f.write(" lua_pushinteger(L, %s);\n" % (dec[3], ))
  274. # elif dec[2] == "lv_color_t" :
  275. # f.write(" %s %s;\n" % (dec[2], dec[3]))
  276. # f.write(" lv_style_get_%s(_style, state, &%s);\n" % (dec[1], dec[3]))
  277. # f.write(" lua_pushinteger(L, %s.full);\n" % (dec[3], ))
  278. # elif dec[2] == "const char *":
  279. # f.write(" %s %s = (%s)luaL_checkstring(L, 3);\n" % (dec[2], dec[3], dec[2]))
  280. # f.write(" lv_style_get_%s(_style, state, %s);\n" % (dec[1], dec[3]))
  281. # f.write(" lua_pushstring(L, %s);\n" % (dec[3], ))
  282. # else :
  283. # f.write(" %s %s;\n" % (dec[2], dec[3]))
  284. # f.write(" // TODO %s %s\n" % (dec[2], dec[3]))
  285. # f.write(" lv_style_get_%s(_style, state, %s);\n" % (dec[1], dec[3]))
  286. # f.write(" lua_pushlightuserdata(L, %s);\n" % (dec[3], ))
  287. # print("what? " + dec[2] + " " + dec[1])
  288. # f.write(" return 1;\n")
  289. # f.write("}\n\n")
  290. def main():
  291. handle_groups("core", "src/core/")
  292. handle_groups("draw", "src/draw/")
  293. handle_groups("font", "src/font/")
  294. handle_groups("misc", "src/misc/")
  295. handle_groups("widgets", "src/widgets/")
  296. extras = ["src/extra/layouts", "src/extra/widgets", "src/extra/themes"]
  297. for d in extras:
  298. group = list(filter(None, d.split('/')))[-1]
  299. dds = [f"{d}/{dd}" for dd in os.listdir(d) if os.path.isdir(f"{d}/{dd}")]
  300. for dd in dds:
  301. handle_groups(group, dd)
  302. print("============================================================")
  303. gen_methods()
  304. gen_enums()
  305. print_miss()
  306. print("============================================================")
  307. c = 0
  308. for group in methods :
  309. for prefix in methods[group] :
  310. c += len(methods[group][prefix])
  311. print("Method count", c)
  312. # make_style_dec()
  313. def print_miss():
  314. for m in miss_arg_types :
  315. print("MISS arg type : ", m)
  316. for m in miss_ret_types :
  317. print("MISS ret type : ", m)
  318. pass
  319. def gen_enums():
  320. if not os.path.exists("gen/") :
  321. os.makedirs("gen/")
  322. with open("gen/luat_lv_enum.h", "w") as fh :
  323. fh.write("\r\n")
  324. fh.write("#include \"luat_base.h\"\n")
  325. #fh.write("#include \"lvgl.h\"\n")
  326. fh.write("#ifndef LUAT_LV_ENUM\n")
  327. fh.write("#define LUAT_LV_ENUM\n")
  328. #for e in enums:
  329. # if e[0].startswith("_"):
  330. # continue
  331. # fh.write("#if (" + e[0] + " != " + str(e[1]) + ")\n")
  332. # fh.write("#error \"ERROR\"\n")
  333. # fh.write("#endif\n")
  334. fh.write("#include \"rotable.h\"\n")
  335. fh.write("#define LUAT_LV_ENMU_RLT {\"T\", NULL, 0xFF},\\\n")
  336. for e in enums:
  337. if e[0].startswith("_"):
  338. continue
  339. fh.write(" {\"%s\", NULL, %s},\\\n" % (e[0][3:], e[1]))
  340. fh.write("\n\n")
  341. fh.write("#endif\n")
  342. def gen_methods():
  343. if not os.path.exists("gen/") :
  344. os.makedirs("gen/")
  345. # 首先, 输出全部.h文件
  346. with open("gen/luat_lv_gen.h", "w") as fh :
  347. fh.write("\r\n")
  348. fh.write("#include \"luat_base.h\"\n")
  349. #fh.write("#include \"lvgl.h\"\n")
  350. fh.write("#ifndef LUAT_LV_GEN\n")
  351. fh.write("#define LUAT_LV_GEN\n")
  352. for group in methods :
  353. fh.write("\n")
  354. fh.write("// group " + group + "\n")
  355. for prefix in methods[group] :
  356. # 输出头文件
  357. fh.write("// prefix " + group + " " + prefix + "\n")
  358. for m in methods[group][prefix] :
  359. sb = "int luat_" + m["name"] + "(lua_State *L);\n"
  360. fh.write(sb)
  361. fh.write("\n#define LUAT_LV_" + prefix.upper() + "_RLT ")
  362. for m in methods[group][prefix] :
  363. sb = " {\"%s\", luat_%s, 0},\\\n" % (m["name"][3:], m["name"])
  364. fh.write(sb)
  365. fh.write("\n")
  366. # 然后, 输出src文件
  367. if not os.path.exists("gen/"+group+ "/") :
  368. os.makedirs("gen/"+group+"/")
  369. with open("gen/"+group+"/luat_" + prefix + ".c", "w") as f :
  370. f.write("\r\n")
  371. f.write("#include \"luat_base.h\"\n")
  372. #f.write("#include \"gen/%s/luat_%s.h\"\n" % (group, prefix))
  373. f.write("#include \"lvgl.h\"\n")
  374. f.write("#include \"luat_lvgl.h\"\n")
  375. f.write("\n\n")
  376. for m in methods[group][prefix] :
  377. f.write("// " + mtostr(m) + "\n")
  378. f.write("int luat_" + m["name"] + "(lua_State *L) {\n")
  379. f.write(" LV_DEBUG(\"CALL " + m["name"]+"\");\n");
  380. argnames = []
  381. if len(m["args"]) > 0:
  382. _index = 1
  383. _miss_arg_type = False
  384. for arg in m["args"] :
  385. #if (arg[1].endswith("*")) :
  386. # f.write(" %s %s = NULL;\n" % (str(arg[1]), str(arg[0])))
  387. #else :
  388. # f.write(" %s %s;\n" % (str(arg[1]), str(arg[0])))
  389. cnt, incr, miss_arg_type = gen_lua_arg(arg[1], arg[0], _index, prefix)
  390. _miss_arg_type = _miss_arg_type or miss_arg_type
  391. f.write(" " + cnt + "\n")
  392. if miss_arg_type :
  393. f.write(" // miss arg convert\n")
  394. miss_arg_types.add(arg[1])
  395. _index += incr
  396. #if arg[1] == "lv_area_t*" or arg[1] == "lv_point_t*":
  397. # argnames.append("&"+str(arg[0]))
  398. #else:
  399. # argnames.append(str(arg[0]))
  400. argnames.append(str(arg[0]))
  401. else :
  402. pass
  403. if "void" != m["ret"] :
  404. if m["ret"].endswith("*") :
  405. f.write(" %s ret = NULL;\n" % (m["ret"], ))
  406. else :
  407. f.write(" %s ret;\n" % (m["ret"], ))
  408. else :
  409. pass # end of non-void return
  410. #f.write(" //----\n")
  411. #f.write(" \n")
  412. #f.write(" //----\n")
  413. if "void" != m["ret"] :
  414. f.write(" ret = ")
  415. else:
  416. f.write(" ")
  417. f.write(m["name"] + "(")
  418. f.write(" ,".join(argnames))
  419. f.write(");\n")
  420. # 处理方法的返回值
  421. gen_lua_ret(m["ret"], f)
  422. f.write("}\n\n")
  423. fh.write("#endif\n")
  424. def mtostr(m) :
  425. sb = m["ret"] + " " + m["name"] + "("
  426. if len(m["args"]) > 0 :
  427. for arg in m["args"] :
  428. sb += str(arg[1]) + " " + str(arg[0]) + ", "
  429. sb = sb[:-2]
  430. sb += ")"
  431. return sb
  432. map_lua_arg = {
  433. "lv_coord_t" : {"fmt": "{} {} = (lv_coord_t)luaL_checknumber(L, {});", "incr" : 1},
  434. "int16_t" : {"fmt": "{} {} = (int16_t)luaL_checkinteger(L, {});", "incr" : 1},
  435. "int8_t" : {"fmt": "{} {} = (int8_t)luaL_checkinteger(L, {});", "incr" : 1},
  436. "int32_t" : {"fmt": "{} {} = (int32_t)luaL_checkinteger(L, {});", "incr" : 1},
  437. "uint8_t" : {"fmt": "{} {} = (uint8_t)luaL_checkinteger(L, {});", "incr" : 1},
  438. "uint16_t" : {"fmt": "{} {} = (uint16_t)luaL_checkinteger(L, {});", "incr" : 1},
  439. "uint32_t" : {"fmt": "{} {} = (uint32_t)luaL_checkinteger(L, {});", "incr" : 1},
  440. "bool" : {"fmt": "{} {} = (bool)lua_toboolean(L, {});", "incr" : 1},
  441. "size_t" : {"fmt": "{} {} = (size_t)luaL_checkinteger(L, {});", "incr" : 1},
  442. "char" : {"fmt": "{} {} = (char)luaL_checkinteger(L, {});", "incr" : 1},
  443. "lv_anim_enable_t" : {"fmt": "{} {} = (lv_anim_enable_t)lua_toboolean(L, {});", "incr" : 1},# 与uint8等价
  444. "lv_scrollbar_mode_t" : {"fmt": "{} {} = (lv_scrollbar_mode_t)luaL_checkinteger(L, {});", "incr" : 1},# 与uint8等价
  445. "lv_layout_t" : {"fmt": "{} {} = (lv_layout_t)luaL_checkinteger(L, {});", "incr" : 1},# 与uint8等价
  446. "lv_style_property_t" : {"fmt": "{} {} = (lv_style_property_t)luaL_checkinteger(L, {});", "incr" : 1}, # uint16_t
  447. "lv_style_state_t" : {"fmt": "{} {} = (lv_style_state_t)luaL_checkinteger(L, {});", "incr" : 1}, # uint16_t
  448. #"lv_color_t" : {"fmt": "{} {} = \\{.full = luaL_checkinteger(L, {})\\};", "incr" : 1},
  449. "lv_align_t" : {"fmt": "{} {} = (lv_align_t)luaL_checkinteger(L, {});", "incr" : 1},
  450. "lv_state_t" : {"fmt": "{} {} = (lv_state_t)luaL_checkinteger(L, {});", "incr" : 1},
  451. "lv_style_int_t" : {"fmt": "{} {} = (lv_style_int_t)luaL_checkinteger(L, {});", "incr" : 1},
  452. "lv_style_property_t" : {"fmt": "{} {} = (lv_style_property_t)luaL_checkinteger(L, {});", "incr" : 1},
  453. "lv_fit_t" : {"fmt": "{} {} = (lv_fit_t)luaL_checkinteger(L, {});", "incr" : 1},
  454. "char*" : {"fmt": "{} {} = (char*)luaL_checkstring(L, {});", "incr" : 1},
  455. "lv_opa_t" : {"fmt": "{} {} = (lv_opa_t)luaL_checknumber(L, {});", "incr" : 1}, # uint8_t
  456. "lv_img_cf_t" : {"fmt": "{} {} = (lv_img_cf_t)luaL_checkinteger(L, {});", "incr" : 1}, # uint8_t
  457. "lv_arc_type_t" : {"fmt": "{} {} = (lv_arc_type_t)luaL_checkinteger(L, {});", "incr" : 1}, # uint8_t
  458. "lv_chart_axis_t" : {"fmt": "{} {} = (lv_chart_axis_t)luaL_checkinteger(L, {});", "incr" : 1}, # uint8_t
  459. "lv_cpicker_type_t" : {"fmt": "{} {} = (lv_cpicker_type_t)luaL_checkinteger(L, {});", "incr" : 1}, # uint8_t
  460. "lv_img_cf_t" : {"fmt": "{} {} = (lv_img_cf_t)luaL_checkinteger(L, {});", "incr" : 1}, # uint8_t
  461. "lv_anim_value_t" : {"fmt": "{} {} = (lv_anim_value_t)luaL_checkinteger(L, {});", "incr" : 1}, # int16
  462. }
  463. def gen_lua_arg(tp, name, index, prefix=None):
  464. if prefix == "lv_arc" :
  465. if name == "start" or name == "end" or "uint16_t" == tp or "int16_t" == tp :
  466. return "{} {} = ({})luaL_checknumber(L, {});".format(tp, name, tp, index), 1, False
  467. if tp in map_lua_arg :
  468. fmt = map_lua_arg[tp]["fmt"]
  469. return fmt.format(str(tp), str(name), str(index)), map_lua_arg[tp]["incr"], False
  470. if tp in map_lv_ints :
  471. return "{} {} = ({})luaL_checkinteger(L, {});".format(tp, name, tp, index), 1, False
  472. #if tp == "lv_area_t*" :
  473. # cnt = "lua_pushvalue(L, %d);\n" % (index,)
  474. # cnt += " %s %s = {0};\n" % (tp[:-1], name)
  475. # cnt += " lua_geti(L, -1, 1); %s.x1 = luaL_checkinteger(L, -1); lua_pop(L, 1);\n" % (name,)
  476. # cnt += " lua_geti(L, -1, 2); %s.y1 = luaL_checkinteger(L, -1); lua_pop(L, 1);\n" % (name,)
  477. # cnt += " lua_geti(L, -1, 3); %s.x2 = luaL_checkinteger(L, -1); lua_pop(L, 1);\n" % (name,)
  478. # cnt += " lua_geti(L, -1, 4); %s.y2 = luaL_checkinteger(L, -1); lua_pop(L, 1);\n" % (name,)
  479. # cnt += " lua_pop(L, 1);\n"
  480. # return cnt, 1, False
  481. # if tp == "lv_point_t*" :
  482. # cnt = "lua_pushvalue(L, %d);\n" % (index,)
  483. # cnt += " %s %s = {0};\n" % (tp[:-1], name)
  484. # cnt += " lua_geti(L, -1, 1); %s.x = luaL_checkinteger(L, -1); lua_pop(L, 1);\n" % (name,)
  485. # cnt += " lua_geti(L, -1, 2); %s.y = luaL_checkinteger(L, -1); lua_pop(L, 1);\n" % (name,)
  486. # cnt += " lua_pop(L, 1);\n"
  487. # return cnt, 1, False
  488. if tp == "lv_font_t*":
  489. return "{} {} = ({})lua_touserdata(L, {});".format(str(tp), str(name), str(tp), str(index)), 1, False
  490. if tp == "lv_color_t" :
  491. return "%s %s = {0};\n" % (tp, name) + " %s.full = luaL_checkinteger(L, %d);" % (name, index), 1, False
  492. if tp.endswith("*"):
  493. return "{} {} = ({})lua_touserdata(L, {});".format(str(tp), str(name), str(tp), str(index)), 1, False
  494. #print("miss arg type", tp)
  495. return "{} {};".format(str(tp), str(name)), 1, True
  496. map_lua_ret = {
  497. "void" : ["return 0;"],
  498. "char*" : ["lua_pushstring(L, ret);", "return 1;"],
  499. "lv_res_t" : ["lua_pushboolean(L, ret == LV_RES_OK ? 1 : 0);", "lua_pushinteger(L, ret);", "return 2;"],
  500. "bool" : ["lua_pushboolean(L, ret);", "return 1;"],
  501. "lv_fs_res_t" : ["lua_pushboolean(L, ret == 0 ? 1 : 0);", "lua_pushinteger(L, ret);", "return 2;"],
  502. "lv_draw_mask_res_t" : ["lua_pushboolean(L, ret == 0 ? 1 : 0);", "lua_pushinteger(L, ret);", "return 2;"],
  503. "lv_color_hsv_t" : [ "lua_pushinteger(L, ret.h);", "lua_pushinteger(L, ret.s);", "lua_pushinteger(L, ret.v);", "return 3;"],
  504. "lv_point_t" : [ "lua_pushinteger(L, ret.x);", "lua_pushinteger(L, ret.y);", "return 2;"],
  505. }
  506. def gen_lua_ret(tp, f) :
  507. # 数值类
  508. if tp in map_lv_ints :
  509. f.write(" lua_pushinteger(L, ret);\n")
  510. f.write(" return 1;\n")
  511. # 配好的匹配
  512. elif tp in map_lua_ret :
  513. for line in map_lua_ret[tp] :
  514. f.write(" ")
  515. f.write(line)
  516. f.write("\n")
  517. # lv_color_t需要特别处理一下
  518. elif tp == "lv_color_t" :
  519. f.write(" lua_pushinteger(L, ret.full);\n")
  520. f.write(" return 1;\n")
  521. # 返回值是指针的
  522. elif tp.endswith("*") :
  523. if tp != "lv_obj_t*":
  524. miss_ret_types.add(tp)
  525. f.write(" if (ret) lua_pushlightuserdata(L, ret); else lua_pushnil(L);\n")
  526. f.write(" return 1;\n")
  527. # 其他的暂不支持
  528. else :
  529. miss_ret_types.add(tp)
  530. f.write(" return 0;\n")
  531. if __name__ == '__main__':
  532. main()