/tools/fbusgen/coder_service.c

http://ftk.googlecode.com/ · C · 428 lines · 352 code · 47 blank · 29 comment · 51 complexity · 1c8b528c8137d9a6b13e17948e73b53d MD5 · raw file

  1. /*
  2. * File:
  3. * Author: Li XianJing <xianjimli@hotmail.com>
  4. * Brief:
  5. *
  6. * Copyright (c) 2009 - 2010 Li XianJing <xianjimli@hotmail.com>
  7. *
  8. * Licensed under the Academic Free License version 2.1
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  23. */
  24. /*
  25. * History:
  26. * ================================================================
  27. * 2010-07-31 Li XianJing <xianjimli@hotmail.com> created
  28. *
  29. */
  30. #include "coder_intf.h"
  31. #define STR_LENGTH 127
  32. typedef struct _PrivInfo
  33. {
  34. char* name;
  35. char* lower_name;
  36. GString* func_create;
  37. GString* func_empty;
  38. GString* func_dispatch;
  39. gboolean has_interface;
  40. char interface[STR_LENGTH+1];
  41. char interface_lower[STR_LENGTH+1];
  42. char interface_upper[STR_LENGTH+1];
  43. }PrivInfo;
  44. static gboolean coder_service_gen_service(PrivInfo* priv, FILE* fp)
  45. {
  46. fprintf(fp, "static const char* %s_service_get_name(FBusService* thiz)\n", priv->interface_lower);
  47. fprintf(fp, "{\n");
  48. fprintf(fp, " return FBUS_SERVICE_%s;\n", priv->interface_upper);
  49. fprintf(fp, "}\n\n");
  50. fprintf(fp, "static Ret %s_service_on_client_connect(FBusService* thiz, int client_id)\n",
  51. priv->interface_lower);
  52. fprintf(fp, "{\n");
  53. fprintf(fp, "\treturn RET_OK;\n");
  54. fprintf(fp, "}\n\n");
  55. fprintf(fp, "static Ret %s_service_on_client_disconnect(FBusService* thiz, int client_id)\n",
  56. priv->interface_lower);
  57. fprintf(fp, "{\n");
  58. fprintf(fp, "\treturn RET_OK;\n");
  59. fprintf(fp, "}\n\n");
  60. fprintf(fp, "static Ret %s_service_handle_request(FBusService* thiz, int client_id, FBusParcel* req_resp)\n",
  61. priv->interface_lower);
  62. fprintf(fp, "{\n");
  63. fprintf(fp, "\tint req_code = fbus_parcel_get_int(req_resp);\n\n");
  64. fprintf(fp, "\tswitch(req_code)\n");
  65. fprintf(fp, "\t{\n");
  66. fprintf(fp, "%s", priv->func_dispatch->str);
  67. fprintf(fp, "\t\tdefault:break;\n");
  68. fprintf(fp, "\t}\n");
  69. fprintf(fp, "\treturn RET_OK;\n");
  70. fprintf(fp, "}\n\n");
  71. fprintf(fp, "static void %s_service_destroy(FBusService* thiz)\n", priv->interface_lower);
  72. fprintf(fp, "{\n");
  73. fprintf(fp, "\tif(thiz != NULL)\n");
  74. fprintf(fp, "\t{\n");
  75. fprintf(fp, "\t\tDECL_PRIV(thiz, priv);\n");
  76. fprintf(fp, "\t\t%s_destroy(priv->impl);\n", priv->interface_lower);
  77. fprintf(fp, "\t\tFTK_FREE(thiz);\n");
  78. fprintf(fp, "\t}\n");
  79. fprintf(fp, "\treturn;\n");
  80. fprintf(fp, "}\n\n");
  81. fprintf(fp, "FBusService* %s_service_create(void)\n", priv->interface_lower);
  82. fprintf(fp, "{\n");
  83. fprintf(fp, "\tFBusService* thiz = FTK_ZALLOC(sizeof(FBusService)+sizeof(PrivInfo));\n");
  84. fprintf(fp, "\tif(thiz != NULL)\n");
  85. fprintf(fp, "\t{\n");
  86. fprintf(fp, "\t\tDECL_PRIV(thiz, priv);\n");
  87. fprintf(fp, "\t\tpriv->impl = %s_impl_create();\n", priv->interface_lower);
  88. fprintf(fp, "\t\tthiz->get_name = %s_service_get_name;\n", priv->interface_lower);
  89. fprintf(fp, "\t\tthiz->on_client_connect = %s_service_on_client_connect;\n", priv->interface_lower);
  90. fprintf(fp, "\t\tthiz->on_client_disconnect = %s_service_on_client_disconnect;\n", priv->interface_lower);
  91. fprintf(fp, "\t\tthiz->handle_request = %s_service_handle_request;\n", priv->interface_lower);
  92. fprintf(fp, "\t\tthiz->destroy = %s_service_destroy;\n", priv->interface_lower);
  93. fprintf(fp, "\t\tfbus_service_register(thiz);\n");
  94. fprintf(fp, "\t}\n\n");
  95. fprintf(fp, "\treturn thiz;\n");
  96. fprintf(fp, "}\n\n");
  97. fprintf(fp, "\n");
  98. return TRUE;
  99. }
  100. static gboolean coder_service_end_interface(Coder* thiz)
  101. {
  102. FILE* fp = NULL;
  103. char h_filename[260] = {0};
  104. char c_filename[260] = {0};
  105. PrivInfo* priv = (PrivInfo*)thiz->priv;
  106. if(!priv->has_interface)
  107. {
  108. return TRUE;
  109. }
  110. mkdir(priv->interface, 0777);
  111. snprintf(h_filename, sizeof(h_filename) - 1, "%s/%s_service.h", priv->interface, priv->interface_lower);
  112. fp = fopen(h_filename, "w+");
  113. if(fp != NULL)
  114. {
  115. coder_write_header(fp);
  116. fprintf(fp, "#ifndef %s_SERVICE_H\n", priv->interface_upper);
  117. fprintf(fp, "#define %s_SERVICE_H\n\n", priv->interface_upper);
  118. fprintf(fp, "#include \"fbus_service.h\"\n\n");
  119. fprintf(fp, "FTK_BEGIN_DECLS\n\n");
  120. fprintf(fp, "FBusService* %s_service_create(void);\n\n", priv->interface_lower);
  121. fprintf(fp, "FTK_END_DECLS\n\n");
  122. fprintf(fp, "#endif/*%s_SERVICE_H*/\n", priv->interface_upper);
  123. fclose(fp);
  124. }
  125. snprintf(c_filename, sizeof(c_filename) - 1, "%s/%s_service.c", priv->interface, priv->interface_lower);
  126. fp = fopen(c_filename, "w+");
  127. if(fp != NULL)
  128. {
  129. coder_write_header(fp);
  130. fprintf(fp, "#include \"%s.h\"\n", priv->interface_lower);
  131. fprintf(fp, "#include \"%s_impl.h\"\n", priv->interface_lower);
  132. fprintf(fp, "#include \"%s_share.h\"\n", priv->interface_lower);
  133. fprintf(fp, "#include \"%s_service.h\"\n\n", priv->interface_lower);
  134. fprintf(fp, "typedef struct _PrivInfo\n");
  135. fprintf(fp, "{\n");
  136. fprintf(fp, " %s* impl;\n", priv->interface);
  137. fprintf(fp, "}PrivInfo;\n\n");
  138. fprintf(fp, "%s\n", priv->func_empty->str);
  139. coder_service_gen_service(priv, fp);
  140. fclose(fp);
  141. }
  142. g_string_free(priv->func_empty, 1);
  143. g_string_free(priv->func_create, 1);
  144. g_string_free(priv->func_dispatch, 1);
  145. priv->has_interface = FALSE;
  146. return TRUE;
  147. }
  148. static gboolean coder_service_on_interface(Coder* thiz, const char* name, const char* parent)
  149. {
  150. PrivInfo* priv = (PrivInfo*)thiz->priv;
  151. coder_service_end_interface(thiz);
  152. priv->has_interface = 1;
  153. strncpy(priv->interface, name, STR_LENGTH);
  154. coder_name_to_lower(name, priv->interface_lower);
  155. strcpy(priv->interface_upper, priv->interface_lower);
  156. coder_to_upper(priv->interface_upper);
  157. priv->func_empty = g_string_sized_new(4096);
  158. priv->func_create = g_string_sized_new(4096);
  159. priv->func_dispatch = g_string_sized_new(4096);
  160. return TRUE;
  161. }
  162. typedef struct _TypeInfo
  163. {
  164. int attr;
  165. gboolean is_binary;
  166. char name[STR_LENGTH+1];
  167. char org_name[STR_LENGTH+1];
  168. }TypeInfo;
  169. static gboolean coder_get_type_info(IDL_tree tree, int attr, TypeInfo* type)
  170. {
  171. const char* name = "";
  172. type->attr = attr;
  173. if(attr == IDL_PARAM_INOUT)
  174. {
  175. assert(!"Not supported.");
  176. }
  177. memset(type, 0x00, sizeof(TypeInfo));
  178. if(IDL_NODE_IS_TYPE(tree))
  179. {
  180. switch(IDL_NODE_TYPE(tree))
  181. {
  182. case IDLN_TYPE_INTEGER:
  183. {
  184. name = "int";
  185. break;
  186. }
  187. case IDLN_TYPE_STRING:
  188. {
  189. name = "String";
  190. break;
  191. }
  192. default:
  193. {
  194. assert(!"Not supported");
  195. break;
  196. }
  197. }
  198. }
  199. else if(IDL_NODE_TYPE(tree) == IDLN_IDENT)
  200. {
  201. name = IDL_IDENT(tree).str;
  202. }
  203. strcat(type->org_name, name);
  204. if(strcmp(name, "int") == 0)
  205. {
  206. strcat(type->name, "int");
  207. }
  208. else if(strcmp(name, "String") == 0)
  209. {
  210. strcat(type->name, attr == IDL_PARAM_OUT ? "" : "const ");
  211. strcat(type->name, "char*");
  212. }
  213. else if(strcmp(name, "FBusBinary") == 0)
  214. {
  215. type->is_binary = TRUE;
  216. }
  217. else
  218. {
  219. strcat(type->name, attr == IDL_PARAM_OUT ? "" : "const ");
  220. strcat(type->name, name);
  221. strcat(type->name, attr == IDL_PARAM_IN ? "*" : "");
  222. }
  223. return TRUE;
  224. }
  225. static gboolean coder_service_on_function(Coder* thiz, struct _IDL_OP_DCL f)
  226. {
  227. int i = 0;
  228. TypeInfo type = {0};
  229. const char* param_name = NULL;
  230. struct _IDL_LIST iter = {0};
  231. char lower_func_name[STR_LENGTH+1] = {0};
  232. PrivInfo* priv = (PrivInfo*)thiz->priv;
  233. char req_coder_name[STR_LENGTH+1];
  234. const char* func_name = IDL_IDENT(f.ident).str;
  235. GString* params_list = g_string_sized_new(1024);
  236. GString* params_in = g_string_sized_new(1024);
  237. GString* params_out = g_string_sized_new(1024);
  238. GString* params_call = g_string_sized_new(1024);
  239. GString* params_decls = g_string_sized_new(1024);
  240. GString* params_free = g_string_sized_new(1024);
  241. coder_name_to_lower(func_name, lower_func_name);
  242. coder_get_type_info(f.op_type_spec, 0, &type);
  243. if(f.parameter_dcls != NULL)
  244. {
  245. for (i = 0, iter = IDL_LIST(f.parameter_dcls); iter.data != NULL; iter = IDL_LIST(iter.next))
  246. {
  247. int attr = IDL_PARAM_DCL(iter.data).attr;
  248. param_name = IDL_IDENT(IDL_PARAM_DCL(iter.data).simple_declarator).str;
  249. coder_get_type_info(IDL_PARAM_DCL(iter.data).param_type_spec, attr, &type);
  250. g_string_append_printf(params_list, ", %s %s", type.name, param_name);
  251. g_string_append_printf(params_decls, "\t%s %s = {0};\n", type.name, param_name);
  252. g_string_append_printf(params_call, ", %s%s", attr == IDL_PARAM_OUT ? "&" : "", param_name);
  253. if(attr == IDL_PARAM_OUT)
  254. {
  255. if(strcmp(type.org_name, "int") == 0)
  256. {
  257. g_string_append_printf(params_out, "\t\t\tfbus_parcel_write_int(req_resp, %s);\n", param_name);
  258. }
  259. else if(strcmp(type.org_name, "String") == 0)
  260. {
  261. g_string_append_printf(params_out, "\t\t\tfbus_parcel_write_string(req_resp, %s);\n", param_name);
  262. g_string_append_printf(params_free, "\t\t\tFTK_FREE(%s);\n", param_name);
  263. }
  264. else
  265. {
  266. g_string_append_printf(params_out, "\t\t\tfbus_parcel_write_data(req_resp, &%s, sizeof(%s));\n",
  267. param_name, param_name);
  268. }
  269. }
  270. if(attr == IDL_PARAM_IN)
  271. {
  272. if(strcmp(type.org_name, "int") == 0)
  273. {
  274. g_string_append_printf(params_in, "\t%s = fbus_parcel_get_int(req_resp);\n", param_name);
  275. }
  276. else if(strcmp(type.org_name, "String") == 0)
  277. {
  278. g_string_append_printf(params_in, "\t%s = fbus_parcel_get_string(req_resp);\n", param_name);
  279. }
  280. else
  281. {
  282. g_string_append_printf(params_in, "\t%s = (%s)fbus_parcel_get_data(req_resp, sizeof(%s));\n",
  283. param_name, type.name, param_name);
  284. }
  285. }
  286. if(iter.next == NULL)
  287. {
  288. break;
  289. }
  290. }
  291. }
  292. coder_name_to_lower(func_name, lower_func_name);
  293. snprintf(req_coder_name, sizeof(req_coder_name)-1, "%s_%s", priv->interface_lower, lower_func_name);
  294. coder_to_upper(req_coder_name);
  295. g_string_append_printf(priv->func_dispatch, "\t\tcase %s:\n", req_coder_name);
  296. g_string_append_printf(priv->func_dispatch, "\t\t{\n");
  297. g_string_append_printf(priv->func_dispatch, "\t\t\t%s_marshal_%s(thiz, req_resp);\n",
  298. priv->interface_lower, lower_func_name);
  299. g_string_append_printf(priv->func_dispatch, "\t\t\tbreak;\n");
  300. g_string_append_printf(priv->func_dispatch, "\t\t}\n");
  301. g_string_append_printf(priv->func_empty, "static Ret %s_marshal_%s(FBusService* thiz, FBusParcel* req_resp)\n{\n",
  302. priv->interface_lower, lower_func_name);
  303. g_string_append_printf(priv->func_empty, "%s\n", params_decls->str);
  304. g_string_append_printf(priv->func_empty, "\tRet ret = RET_FAIL;\n");
  305. g_string_append_printf(priv->func_empty, "\tDECL_PRIV(thiz, priv);\n");
  306. g_string_append_printf(priv->func_empty,
  307. " return_val_if_fail(priv != NULL && priv->impl != NULL && req_resp != NULL, RET_FAIL);\n\n");
  308. g_string_append_printf(priv->func_empty, "%s\n", params_in->str);
  309. g_string_append_printf(priv->func_empty, "\tif((ret = %s_%s(priv->impl%s)) == RET_OK)\n",
  310. priv->interface_lower, lower_func_name, params_call->str);
  311. g_string_append_printf(priv->func_empty, "\t{\n");
  312. g_string_append_printf(priv->func_empty, "\t\tfbus_parcel_reset(req_resp);\n");
  313. g_string_append_printf(priv->func_empty, "\t\tfbus_parcel_write_int(req_resp, ret);\n");
  314. if(params_out->str != NULL && strlen(params_out->str) > 0)
  315. {
  316. g_string_append_printf(priv->func_empty, "\t\tif(ret == RET_OK)\n");
  317. g_string_append_printf(priv->func_empty, "\t\t{\n");
  318. g_string_append_printf(priv->func_empty, "%s", params_out->str);
  319. g_string_append_printf(priv->func_empty, "%s", params_free->str);
  320. g_string_append_printf(priv->func_empty, "\t\t}\n");
  321. }
  322. g_string_append_printf(priv->func_empty, "\t}\n\n");
  323. g_string_append_printf(priv->func_empty, "\treturn ret;\n");
  324. g_string_append_printf(priv->func_empty, "}\n\n");
  325. g_string_append_printf(priv->func_create, " thiz->%s = %s_marshal_%s;\n",
  326. lower_func_name, priv->interface_lower, lower_func_name);
  327. g_string_free(params_list, 1);
  328. g_string_free(params_in, 1);
  329. g_string_free(params_out, 1);
  330. g_string_free(params_call, 1);
  331. g_string_free(params_decls, 1);
  332. g_string_free(params_free, 1);
  333. return TRUE;
  334. }
  335. static gboolean coder_service_on_const(Coder* thiz, struct _IDL_CONST_DCL c)
  336. {
  337. return TRUE;
  338. }
  339. static gboolean coder_service_on_struct(Coder* thiz, struct _IDL_TYPE_STRUCT s)
  340. {
  341. return TRUE;
  342. }
  343. static gboolean coder_service_on_enum(Coder* thiz, struct _IDL_TYPE_ENUM e)
  344. {
  345. return TRUE;
  346. }
  347. static gboolean coder_service_on_union(Coder* thiz, struct _IDL_TYPE_UNION u)
  348. {
  349. return TRUE;
  350. }
  351. static void coder_service_destroy(Coder* thiz)
  352. {
  353. if(thiz != NULL)
  354. {
  355. PrivInfo* priv = (PrivInfo*)thiz->priv;
  356. coder_service_end_interface(thiz);
  357. g_free(priv->name);
  358. g_free(priv->lower_name);
  359. g_free(thiz);
  360. }
  361. return;
  362. }
  363. Coder* coder_service_create(const char* name)
  364. {
  365. Coder* thiz = g_malloc0(sizeof(Coder) + sizeof(PrivInfo));
  366. if(thiz != NULL)
  367. {
  368. PrivInfo* priv = (PrivInfo*)thiz->priv;
  369. priv->name = g_strdup(name);
  370. priv->lower_name = g_strdup(name);
  371. coder_to_lower(priv->lower_name);
  372. thiz->on_interface = coder_service_on_interface;
  373. thiz->on_function = coder_service_on_function;
  374. thiz->on_const = coder_service_on_const;
  375. thiz->on_enum = coder_service_on_enum;
  376. thiz->on_struct = coder_service_on_struct;
  377. thiz->on_union = coder_service_on_union;
  378. thiz->destroy = coder_service_destroy;
  379. }
  380. return thiz;
  381. }