genapi.py 27 KB

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