genapi.py 27 KB

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