/tools/fbusgen/coder_intf.c

http://ftk.googlecode.com/ · C · 289 lines · 219 code · 41 blank · 29 comment · 32 complexity · 4fd395992d15d0c332c19b95ad1671ed 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. GString* func_types;
  35. GString* func_decls;
  36. GString* func_inlines;
  37. gboolean has_interface;
  38. char interface[STR_LENGTH+1];
  39. char interface_lower[STR_LENGTH+1];
  40. char interface_upper[STR_LENGTH+1];
  41. }PrivInfo;
  42. static gboolean coder_intf_end_interface(Coder* thiz)
  43. {
  44. FILE* fp = NULL;
  45. char filename[260] = {0};
  46. PrivInfo* priv = (PrivInfo*)thiz->priv;
  47. if(!priv->has_interface)
  48. {
  49. return TRUE;
  50. }
  51. mkdir(priv->interface, 0777);
  52. g_string_append_printf(priv->func_types, "typedef void (*%sDestroy)(%s* thiz);\n", priv->interface, priv->interface);
  53. g_string_append_printf(priv->func_decls, "\t%sDestroy destroy;\n\n", priv->interface);
  54. g_string_append_printf(priv->func_decls, "\tchar priv[1];\n");
  55. g_string_append_printf(priv->func_decls, "};\n");
  56. g_string_append_printf(priv->func_inlines, "static inline void %s_destroy(%s* thiz)\n{\n",
  57. priv->interface_lower, priv->interface);
  58. g_string_append_printf(priv->func_inlines, "\tif(thiz != NULL && thiz->destroy != NULL)\n");
  59. g_string_append_printf(priv->func_inlines, "\t{\n");
  60. g_string_append_printf(priv->func_inlines, "\t\tthiz->destroy(thiz);\n");
  61. g_string_append_printf(priv->func_inlines, "\t}\n\n");
  62. g_string_append_printf(priv->func_inlines, "\treturn;\n");
  63. g_string_append_printf(priv->func_inlines, "}\n");
  64. snprintf(filename, sizeof(filename) - 1, "%s/%s.h", priv->interface, priv->interface_lower);
  65. fp = fopen(filename, "w+");
  66. if(fp != NULL)
  67. {
  68. coder_write_header(fp);
  69. fprintf(fp, "#ifndef %s_H\n", priv->interface_upper);
  70. fprintf(fp, "#define %s_H\n\n", priv->interface_upper);
  71. fprintf(fp, "#include \"fbus_typedef.h\"\n\n");
  72. fprintf(fp, "FTK_BEGIN_DECLS\n\n");
  73. fprintf(fp, "%s\n", priv->func_types->str);
  74. fprintf(fp, "%s\n", priv->func_decls->str);
  75. fprintf(fp, "%s\n", priv->func_inlines->str);
  76. fprintf(fp, "FTK_END_DECLS\n\n");
  77. fprintf(fp, "#endif/*%s_H*/\n", priv->interface_upper);
  78. fclose(fp);
  79. }
  80. g_string_free(priv->func_types, 1);
  81. g_string_free(priv->func_decls, 1);
  82. g_string_free(priv->func_inlines, 1);
  83. priv->has_interface = FALSE;
  84. return TRUE;
  85. }
  86. static gboolean coder_intf_on_interface(Coder* thiz, const char* name, const char* parent)
  87. {
  88. PrivInfo* priv = (PrivInfo*)thiz->priv;
  89. coder_intf_end_interface(thiz);
  90. priv->has_interface = TRUE;
  91. strncpy(priv->interface, name, STR_LENGTH);
  92. coder_name_to_lower(name, priv->interface_lower);
  93. strcpy(priv->interface_upper, priv->interface_lower);
  94. coder_to_upper(priv->interface_upper);
  95. priv->func_types = g_string_sized_new(4096);
  96. priv->func_decls = g_string_sized_new(4096);
  97. priv->func_inlines = g_string_sized_new(4096);
  98. g_string_append_printf(priv->func_types, "struct _%s;\n", name);
  99. g_string_append_printf(priv->func_types, "typedef struct _%s %s;\n\n", name, name);
  100. g_string_append_printf(priv->func_decls, "struct _%s\n{\n", name);
  101. return TRUE;
  102. }
  103. typedef struct _TypeInfo
  104. {
  105. int attr;
  106. gboolean is_binary;
  107. char name[STR_LENGTH+1];
  108. char org_name[STR_LENGTH+1];
  109. }TypeInfo;
  110. static gboolean coder_get_type_info(IDL_tree tree, int attr, TypeInfo* type)
  111. {
  112. const char* name = "";
  113. type->attr = attr;
  114. if(attr == IDL_PARAM_INOUT)
  115. {
  116. assert(!"Not supported.");
  117. }
  118. memset(type, 0x00, sizeof(TypeInfo));
  119. if(IDL_NODE_IS_TYPE(tree))
  120. {
  121. switch(IDL_NODE_TYPE(tree))
  122. {
  123. case IDLN_TYPE_INTEGER:
  124. {
  125. name = "int";
  126. break;
  127. }
  128. case IDLN_TYPE_STRING:
  129. {
  130. name = "String";
  131. break;
  132. }
  133. default:
  134. {
  135. assert(!"Not supported");
  136. break;
  137. }
  138. }
  139. }
  140. else if(IDL_NODE_TYPE(tree) == IDLN_IDENT)
  141. {
  142. name = IDL_IDENT(tree).str;
  143. }
  144. strcat(type->org_name, name);
  145. if(strcmp(name, "int") == 0)
  146. {
  147. strcat(type->name, "int");
  148. strcat(type->name, attr == IDL_PARAM_OUT ? "*" : "");
  149. }
  150. else if(strcmp(name, "String") == 0)
  151. {
  152. strcat(type->name, attr == IDL_PARAM_OUT ? "" : "const ");
  153. strcat(type->name, "char*");
  154. strcat(type->name, attr == IDL_PARAM_OUT ? "*" : "");
  155. }
  156. else if(strcmp(name, "FBusBinary") == 0)
  157. {
  158. type->is_binary = TRUE;
  159. }
  160. else
  161. {
  162. strcat(type->name, attr == IDL_PARAM_OUT ? "" : "const ");
  163. strcat(type->name, name);
  164. strcat(type->name, "*");
  165. }
  166. return TRUE;
  167. }
  168. static gboolean coder_intf_on_function(Coder* thiz, struct _IDL_OP_DCL f)
  169. {
  170. int i = 0;
  171. TypeInfo type = {0};
  172. const char* param_name = NULL;
  173. struct _IDL_LIST iter = {0};
  174. char lower_func_name[STR_LENGTH+1] = {0};
  175. PrivInfo* priv = (PrivInfo*)thiz->priv;
  176. const char* func_name = IDL_IDENT(f.ident).str;
  177. GString* params_list = g_string_sized_new(1024);
  178. GString* params_call = g_string_sized_new(1023);
  179. coder_name_to_lower(func_name, lower_func_name);
  180. coder_get_type_info(f.op_type_spec, 0, &type);
  181. g_string_append_printf(priv->func_types, "typedef Ret (*%s%s)(%s* thiz", priv->interface, func_name, priv->interface);
  182. g_string_append_printf(priv->func_decls, " %s%s %s;\n", priv->interface, func_name, lower_func_name);
  183. if(f.parameter_dcls != NULL)
  184. {
  185. for (i = 0, iter = IDL_LIST(f.parameter_dcls); iter.data != NULL; iter = IDL_LIST(iter.next))
  186. {
  187. int attr = IDL_PARAM_DCL(iter.data).attr;
  188. param_name = IDL_IDENT(IDL_PARAM_DCL(iter.data).simple_declarator).str;
  189. coder_get_type_info(IDL_PARAM_DCL(iter.data).param_type_spec, attr, &type);
  190. g_string_append_printf(params_call, ", %s", param_name);
  191. g_string_append_printf(params_list, ", %s %s", type.name, param_name);
  192. if(iter.next == NULL)
  193. {
  194. break;
  195. }
  196. }
  197. }
  198. g_string_append_printf(priv->func_inlines, "static inline Ret %s_%s(%s* thiz%s)\n{\n",
  199. priv->interface_lower, lower_func_name, priv->interface, params_list->str);
  200. g_string_append_printf(priv->func_inlines, " return_val_if_fail(thiz != NULL && thiz->%s != NULL, RET_FAIL);\n\n",
  201. lower_func_name);
  202. g_string_append_printf(priv->func_inlines, " return thiz->%s(thiz%s);\n", lower_func_name, params_call->str);
  203. g_string_append_printf(priv->func_inlines, "}\n\n");
  204. g_string_append_printf(priv->func_types, "%s);\n", params_list->str);
  205. g_string_free(params_list, 1);
  206. g_string_free(params_call, 1);
  207. return TRUE;
  208. }
  209. static gboolean coder_intf_on_const(Coder* thiz, struct _IDL_CONST_DCL c)
  210. {
  211. return TRUE;
  212. }
  213. static gboolean coder_intf_on_struct(Coder* thiz, struct _IDL_TYPE_STRUCT s)
  214. {
  215. return TRUE;
  216. }
  217. static gboolean coder_intf_on_enum(Coder* thiz, struct _IDL_TYPE_ENUM e)
  218. {
  219. return TRUE;
  220. }
  221. static gboolean coder_intf_on_union(Coder* thiz, struct _IDL_TYPE_UNION u)
  222. {
  223. return TRUE;
  224. }
  225. static void coder_intf_destroy(Coder* thiz)
  226. {
  227. if(thiz != NULL)
  228. {
  229. coder_intf_end_interface(thiz);
  230. g_free(thiz);
  231. }
  232. return;
  233. }
  234. Coder* coder_intf_create(const char* name)
  235. {
  236. Coder* thiz = g_malloc0(sizeof(Coder) + sizeof(PrivInfo));
  237. if(thiz != NULL)
  238. {
  239. thiz->on_interface = coder_intf_on_interface;
  240. thiz->on_function = coder_intf_on_function;
  241. thiz->on_const = coder_intf_on_const;
  242. thiz->on_enum = coder_intf_on_enum;
  243. thiz->on_struct = coder_intf_on_struct;
  244. thiz->on_union = coder_intf_on_union;
  245. thiz->destroy = coder_intf_destroy;
  246. }
  247. return thiz;
  248. }