/tools/fbusgen/coder_client.c

http://ftk.googlecode.com/ · C · 381 lines · 305 code · 47 blank · 29 comment · 49 complexity · 88f40f4f0c3305e9cbf0c4404e35c6b2 MD5 · raw file

  1. /*
  2. * File: coder_client.c
  3. * Author: Li XianJing <xianjimli@hotmail.com>
  4. * Brief: coder generate client marshal/unmarshal code.
  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_marshal;
  38. gboolean has_interface;
  39. char interface[STR_LENGTH+1];
  40. char interface_lower[STR_LENGTH+1];
  41. char interface_upper[STR_LENGTH+1];
  42. }PrivInfo;
  43. static gboolean coder_client_end_interface(Coder* thiz)
  44. {
  45. FILE* fp = NULL;
  46. char h_filename[260] = {0};
  47. char c_filename[260] = {0};
  48. char create_func[STR_LENGTH+1] = {0};
  49. PrivInfo* priv = (PrivInfo*)thiz->priv;
  50. if(!priv->has_interface)
  51. {
  52. return TRUE;
  53. }
  54. mkdir(priv->interface, 0777);
  55. snprintf(create_func, STR_LENGTH, "%s_%s_create(void)", priv->interface_lower, priv->lower_name);
  56. snprintf(h_filename, sizeof(h_filename) - 1, "%s/%s_%s.h", priv->interface, priv->interface_lower, priv->lower_name);
  57. fp = fopen(h_filename, "w+");
  58. if(fp != NULL)
  59. {
  60. coder_write_header(fp);
  61. fprintf(fp, "#ifndef %s_CLIENT_H\n", priv->interface_upper);
  62. fprintf(fp, "#define %s_CLIENT_H\n\n", priv->interface_upper);
  63. fprintf(fp, "#include \"fbus_typedef.h\"\n\n");
  64. fprintf(fp, "#include \"%s.h\"\n\n", priv->interface_lower);
  65. fprintf(fp, "FTK_BEGIN_DECLS\n\n");
  66. fprintf(fp, "%s* %s;\n\n", priv->interface, create_func);
  67. fprintf(fp, "FTK_END_DECLS\n\n");
  68. fprintf(fp, "#endif/*%s_CLIENT_H*/\n", priv->interface_upper);
  69. fclose(fp);
  70. }
  71. snprintf(h_filename, sizeof(h_filename) - 1, "%s_%s.h", priv->interface_lower, priv->lower_name);
  72. snprintf(c_filename, sizeof(c_filename) - 1, "%s/%s_%s.c", priv->interface, priv->interface_lower, priv->name);
  73. fp = fopen(c_filename, "w+");
  74. if(fp != NULL)
  75. {
  76. coder_write_header(fp);
  77. fprintf(fp, "#include \"fbus_proxy.h\"\n");
  78. fprintf(fp, "#include \"%s_share.h\"\n\n", priv->interface_lower);
  79. fprintf(fp, "#include \"%s\"\n\n", h_filename);
  80. fprintf(fp, "typedef struct _PrivInfo\n");
  81. fprintf(fp, "{\n");
  82. fprintf(fp, " FBusProxy* proxy;\n");
  83. fprintf(fp, "}PrivInfo;\n\n");
  84. fprintf(fp, "%s\n", priv->func_marshal->str);
  85. fprintf(fp, "static void %s_%s_destroy(%s* thiz)\n", priv->interface_lower, priv->lower_name, priv->interface);
  86. fprintf(fp, "{\n");
  87. fprintf(fp, " if(thiz != NULL)\n");
  88. fprintf(fp, " {\n");
  89. fprintf(fp, " DECL_PRIV(thiz, priv);\n");
  90. fprintf(fp, " fbus_proxy_destroy(priv->proxy);\n");
  91. fprintf(fp, " FTK_FREE(thiz);\n");
  92. fprintf(fp, " }\n");
  93. fprintf(fp, " return;\n");
  94. fprintf(fp, "}\n\n");
  95. fprintf(fp, "%s* %s\n", priv->interface, create_func);
  96. fprintf(fp, "{\n");
  97. fprintf(fp, " %s* thiz = FTK_ZALLOC(sizeof(%s) + sizeof(PrivInfo));\n\n", priv->interface, priv->interface);
  98. fprintf(fp, " if(thiz != NULL)\n");
  99. fprintf(fp, " {\n");
  100. fprintf(fp, " DECL_PRIV(thiz, priv);\n");
  101. fprintf(fp, " priv->proxy = fbus_proxy_create(FBUS_SERVICE_%s);\n", priv->interface_upper);
  102. fprintf(fp, "%s", priv->func_create->str);
  103. fprintf(fp, " thiz->destroy = %s_%s_destroy;\n", priv->interface_lower, priv->lower_name);
  104. fprintf(fp, " }\n\n");
  105. fprintf(fp, " return thiz;\n");
  106. fprintf(fp, "}\n");
  107. fclose(fp);
  108. }
  109. g_string_free(priv->func_marshal, 1);
  110. g_string_free(priv->func_create, 1);
  111. priv->has_interface = FALSE;
  112. return TRUE;
  113. }
  114. static gboolean coder_client_on_interface(Coder* thiz, const char* name, const char* parent)
  115. {
  116. PrivInfo* priv = (PrivInfo*)thiz->priv;
  117. coder_client_end_interface(thiz);
  118. priv->has_interface = 1;
  119. strncpy(priv->interface, name, STR_LENGTH);
  120. coder_name_to_lower(name, priv->interface_lower);
  121. strcpy(priv->interface_upper, priv->interface_lower);
  122. coder_to_upper(priv->interface_upper);
  123. priv->func_marshal = g_string_sized_new(4096);
  124. priv->func_create = g_string_sized_new(4096);
  125. return TRUE;
  126. }
  127. typedef struct _TypeInfo
  128. {
  129. int attr;
  130. gboolean is_binary;
  131. char name[STR_LENGTH+1];
  132. char org_name[STR_LENGTH+1];
  133. }TypeInfo;
  134. static gboolean coder_get_type_info(IDL_tree tree, int attr, TypeInfo* type)
  135. {
  136. const char* name = "";
  137. type->attr = attr;
  138. if(attr == IDL_PARAM_INOUT)
  139. {
  140. assert(!"Not supported.");
  141. }
  142. memset(type, 0x00, sizeof(TypeInfo));
  143. if(IDL_NODE_IS_TYPE(tree))
  144. {
  145. switch(IDL_NODE_TYPE(tree))
  146. {
  147. case IDLN_TYPE_INTEGER:
  148. {
  149. name = "int";
  150. break;
  151. }
  152. case IDLN_TYPE_STRING:
  153. {
  154. name = "String";
  155. break;
  156. }
  157. default:
  158. {
  159. assert(!"Not supported");
  160. break;
  161. }
  162. }
  163. }
  164. else if(IDL_NODE_TYPE(tree) == IDLN_IDENT)
  165. {
  166. name = IDL_IDENT(tree).str;
  167. }
  168. strcat(type->org_name, name);
  169. if(strcmp(name, "int") == 0)
  170. {
  171. strcat(type->name, "int");
  172. strcat(type->name, attr == IDL_PARAM_OUT ? "*" : "");
  173. }
  174. else if(strcmp(name, "String") == 0)
  175. {
  176. strcat(type->name, attr == IDL_PARAM_OUT ? "" : "const ");
  177. strcat(type->name, "char*");
  178. strcat(type->name, attr == IDL_PARAM_OUT ? "*" : "");
  179. }
  180. else if(strcmp(name, "FBusBinary") == 0)
  181. {
  182. type->is_binary = TRUE;
  183. }
  184. else
  185. {
  186. strcat(type->name, attr == IDL_PARAM_OUT ? "" : "const ");
  187. strcat(type->name, name);
  188. strcat(type->name, "*");
  189. }
  190. return TRUE;
  191. }
  192. static gboolean coder_client_on_function(Coder* thiz, struct _IDL_OP_DCL f)
  193. {
  194. int i = 0;
  195. TypeInfo type = {0};
  196. const char* param_name = NULL;
  197. struct _IDL_LIST iter = {0};
  198. char lower_func_name[STR_LENGTH+1] = {0};
  199. PrivInfo* priv = (PrivInfo*)thiz->priv;
  200. char req_coder_name[STR_LENGTH+1];
  201. const char* func_name = IDL_IDENT(f.ident).str;
  202. GString* params_list = g_string_sized_new(1024);
  203. GString* params_in = g_string_sized_new(1024);
  204. GString* params_out = g_string_sized_new(1024);
  205. coder_name_to_lower(func_name, lower_func_name);
  206. coder_get_type_info(f.op_type_spec, 0, &type);
  207. if(f.parameter_dcls != NULL)
  208. {
  209. for (i = 0, iter = IDL_LIST(f.parameter_dcls); iter.data != NULL; iter = IDL_LIST(iter.next))
  210. {
  211. int attr = IDL_PARAM_DCL(iter.data).attr;
  212. param_name = IDL_IDENT(IDL_PARAM_DCL(iter.data).simple_declarator).str;
  213. coder_get_type_info(IDL_PARAM_DCL(iter.data).param_type_spec, attr, &type);
  214. g_string_append_printf(params_list, ", %s %s", type.name, param_name);
  215. if(attr == IDL_PARAM_IN)
  216. {
  217. if(strcmp(type.org_name, "int") == 0)
  218. {
  219. g_string_append_printf(params_in, "\tfbus_parcel_write_int(parcel, %s);\n", param_name);
  220. }
  221. else if(strcmp(type.org_name, "String") == 0)
  222. {
  223. g_string_append_printf(params_in, "\tfbus_parcel_write_string(parcel, %s);\n", param_name);
  224. }
  225. else
  226. {
  227. g_string_append_printf(params_in, "\tfbus_parcel_write_data(parcel, %s, sizeof(*%s));\n",
  228. param_name, param_name);
  229. }
  230. }
  231. if(attr == IDL_PARAM_OUT)
  232. {
  233. if(strcmp(type.org_name, "int") == 0)
  234. {
  235. g_string_append_printf(params_out, "\t\t\t*%s = fbus_parcel_get_int(parcel);\n", param_name);
  236. }
  237. else if(strcmp(type.org_name, "String") == 0)
  238. {
  239. g_string_append_printf(params_out, "\t\t\t*%s = (char*)fbus_parcel_get_string(parcel);\n", param_name);
  240. }
  241. else
  242. {
  243. g_string_append_printf(params_out, "\t\t\t*%s = *(%s)fbus_parcel_get_data(parcel, sizeof(*%s));\n",
  244. param_name, type.name, param_name);
  245. }
  246. }
  247. if(iter.next == NULL)
  248. {
  249. break;
  250. }
  251. }
  252. }
  253. coder_name_to_lower(func_name, lower_func_name);
  254. snprintf(req_coder_name, sizeof(req_coder_name)-1, "%s_%s", priv->interface_lower, lower_func_name);
  255. coder_to_upper(req_coder_name);
  256. g_string_append_printf(priv->func_marshal, "static Ret %s_%s_%s(%s* thiz%s)\n{\n",
  257. priv->interface_lower, priv->lower_name, lower_func_name, priv->interface, params_list->str);
  258. g_string_append_printf(priv->func_marshal, "\tRet ret = RET_FAIL;\n");
  259. g_string_append_printf(priv->func_marshal, "\tDECL_PRIV(thiz, priv);\n");
  260. g_string_append_printf(priv->func_marshal, "\tFBusParcel* parcel = fbus_proxy_get_parcel(priv->proxy);;\n");
  261. g_string_append_printf(priv->func_marshal,
  262. " return_val_if_fail(priv != NULL && priv->proxy != NULL && parcel != NULL, RET_FAIL);\n\n");
  263. g_string_append_printf(priv->func_marshal, "\tfbus_parcel_write_int(parcel, %s);\n", req_coder_name);
  264. g_string_append_printf(priv->func_marshal, "%s\n", params_in->str);
  265. g_string_append_printf(priv->func_marshal, "\tif((ret = fbus_proxy_request(priv->proxy, parcel)) == RET_OK)\n");
  266. g_string_append_printf(priv->func_marshal, "\t{\n");
  267. if(strlen(params_out->str) > 0)
  268. {
  269. g_string_append_printf(priv->func_marshal, "\t\tif((ret = fbus_parcel_get_int(parcel)) == RET_OK)\n");
  270. g_string_append_printf(priv->func_marshal, "\t\t{\n");
  271. g_string_append_printf(priv->func_marshal, "%s", params_out->str);
  272. g_string_append_printf(priv->func_marshal, "\t\t}\n");
  273. }
  274. else
  275. {
  276. g_string_append_printf(priv->func_marshal, "\t\tret = fbus_parcel_get_int(parcel);\n");
  277. }
  278. g_string_append_printf(priv->func_marshal, "\t}\n\n");
  279. g_string_append_printf(priv->func_marshal, "\treturn ret;\n");
  280. g_string_append_printf(priv->func_marshal, "}\n\n");
  281. g_string_append_printf(priv->func_create, " thiz->%s = %s_%s_%s;\n",
  282. lower_func_name, priv->interface_lower, priv->lower_name, lower_func_name);
  283. g_string_free(params_list, 1);
  284. g_string_free(params_in, 1);
  285. g_string_free(params_out, 1);
  286. return TRUE;
  287. }
  288. static gboolean coder_client_on_const(Coder* thiz, struct _IDL_CONST_DCL c)
  289. {
  290. return TRUE;
  291. }
  292. static gboolean coder_client_on_struct(Coder* thiz, struct _IDL_TYPE_STRUCT s)
  293. {
  294. return TRUE;
  295. }
  296. static gboolean coder_client_on_enum(Coder* thiz, struct _IDL_TYPE_ENUM e)
  297. {
  298. return TRUE;
  299. }
  300. static gboolean coder_client_on_union(Coder* thiz, struct _IDL_TYPE_UNION u)
  301. {
  302. return TRUE;
  303. }
  304. static void coder_client_destroy(Coder* thiz)
  305. {
  306. if(thiz != NULL)
  307. {
  308. PrivInfo* priv = (PrivInfo*)thiz->priv;
  309. coder_client_end_interface(thiz);
  310. g_free(priv->name);
  311. g_free(priv->lower_name);
  312. g_free(thiz);
  313. }
  314. return;
  315. }
  316. Coder* coder_client_create(const char* name)
  317. {
  318. Coder* thiz = g_malloc0(sizeof(Coder) + sizeof(PrivInfo));
  319. if(thiz != NULL)
  320. {
  321. PrivInfo* priv = (PrivInfo*)thiz->priv;
  322. priv->name = g_strdup(name);
  323. priv->lower_name = g_strdup(name);
  324. coder_to_lower(priv->lower_name);
  325. thiz->on_interface = coder_client_on_interface;
  326. thiz->on_function = coder_client_on_function;
  327. thiz->on_const = coder_client_on_const;
  328. thiz->on_enum = coder_client_on_enum;
  329. thiz->on_struct = coder_client_on_struct;
  330. thiz->on_union = coder_client_on_union;
  331. thiz->destroy = coder_client_destroy;
  332. }
  333. return thiz;
  334. }