10 #include "legacy_generator.h"
11 #include "common_funcs.h"
13 static _eolian_class_vars class_env;
16 tmpl_eapi_funcdef[] = "\n\
23 EAPI @#type_return%s(@#params)@#flags;\n\
26 /*@#CLASS_CHECK(obj) @#check_ret;\n\*/
31 @#eapi_func(@#full_params)\n\
33 return eo_do(@#eo_obj, @#eo_func(@#eo_params));\n\
37 tmpl_eapi_body_void[] ="\
40 @#eapi_func(@#full_params)\n\
42 eo_do(@#eo_obj, @#eo_func(@#eo_params));\n\
47 _eapi_decl_func_generate(const Eolian_Class *class, const Eolian_Function *funcid, Eolian_Function_Type ftype, Eina_Strbuf *buf)
49 _eolian_class_func_vars func_env;
50 const char *funcname = eolian_function_name_get(funcid);
51 const Eolian_Type *rettypet = NULL;
52 const char *rettype = NULL;
53 Eina_Bool var_as_ret = EINA_FALSE;
54 Eina_Bool add_star = EINA_FALSE;
55 Eina_Bool ret_const = EINA_FALSE;
58 Eina_Strbuf *flags = NULL;
59 int leg_param_idx = 1; /* Index of the parameter inside the legacy function. It begins from 1 since obj is the first. */
61 Eina_Strbuf *fbody = eina_strbuf_new();
62 Eina_Strbuf *fparam = eina_strbuf_new();
63 Eina_Strbuf *descparam = eina_strbuf_new();
65 _class_func_env_create(class, funcname, ftype, &func_env);
66 rettypet = eolian_function_return_type_get(funcid, ftype);
67 if (ftype == EOLIAN_PROP_GET)
72 itr = eolian_function_parameters_get(funcid);
73 /* We want to check if there is only one parameter */
74 if (eina_iterator_next(itr, &data) && !eina_iterator_next(itr, &data2))
76 rettypet = eolian_parameter_type_get((Eolian_Function_Parameter*)data);
77 var_as_ret = EINA_TRUE;
78 ret_const = eolian_parameter_const_attribute_get(data, EINA_TRUE);
80 eina_iterator_free(itr);
84 if (func_env.legacy_func[0] == '\0') goto end;
85 eina_strbuf_append_printf(fbody, tmpl_eapi_funcdef, func_env.legacy_func);
87 if (!eolian_function_is_class(funcid))
89 if (ftype == EOLIAN_PROP_GET || eolian_function_object_is_const(funcid))
90 eina_strbuf_append(fparam, "const ");
91 eina_strbuf_append_printf(fparam, "%s *obj", class_env.full_classname);
93 Eina_Strbuf *linedesc = eina_strbuf_new();
94 const char *common_desc = eolian_function_description_get(funcid, EOLIAN_UNRESOLVED);
95 const char *specific_desc = (ftype == EOLIAN_PROP_SET || ftype == EOLIAN_PROP_GET) ?
96 eolian_function_description_get(funcid, ftype) : NULL;
97 if (!common_desc && !specific_desc) eina_strbuf_append(linedesc, "No description supplied.");
98 if (common_desc) eina_strbuf_append_printf(linedesc, "%s\n", common_desc);
99 if (specific_desc) eina_strbuf_append(linedesc, specific_desc);
100 if (eina_strbuf_length_get(linedesc))
102 eina_strbuf_replace_all(linedesc, "\n", "\n * ");
103 eina_strbuf_replace_all(linedesc, " * \n", " *\n");
104 eina_strbuf_prepend(linedesc," * ");
108 eina_strbuf_append(linedesc," *");
110 // TIZEN_ONLY(20160125): add parameter "obj" documentation
111 Eina_Bool has_param_obj = !!strstr(eina_strbuf_string_get(linedesc), "param[in] obj");
113 eina_strbuf_replace_all(fbody, "@#desc", eina_strbuf_string_get(linedesc));
114 eina_strbuf_free(linedesc);
118 Eolian_Class_Type type;
121 eina_strbuf_append(descparam, " * @param[in] obj The ");
123 type = eolian_class_type_get(class);
125 nm = strdup(eolian_class_name_get(class));
126 eina_str_tolower(&nm);
127 while ((ch = strchr(nm, '.'))) *ch = ' ';
128 while ((ch = strchr(nm, '_'))) *ch = ' ';
130 if (!strncmp(nm, "object", strlen("object")))
132 ch = nm + strlen("object");
135 while (*ch == ' ') ch++;
136 eina_strbuf_append(descparam, ch);
137 if ((type == EOLIAN_CLASS_REGULAR) ||
138 (type == EOLIAN_CLASS_ABSTRACT))
139 eina_strbuf_append(descparam, " object\n");
144 nm = strdup(eolian_class_full_name_get(class));
145 eina_str_tolower(&nm);
146 while ((ch = strchr(nm, '.'))) *ch = ' ';
147 while ((ch = strchr(nm, '_'))) *ch = ' ';
148 eina_strbuf_append(descparam, nm);
149 eina_strbuf_append_char(descparam, '\n');
154 eina_strbuf_append(descparam, nm);
155 if ((type == EOLIAN_CLASS_REGULAR) ||
156 (type == EOLIAN_CLASS_ABSTRACT))
157 eina_strbuf_append(descparam, " object\n");
162 itr = eolian_property_keys_get(funcid);
163 EINA_ITERATOR_FOREACH(itr, data)
165 Eolian_Function_Parameter *param = data;
166 const Eolian_Type *ptypet = eolian_parameter_type_get(param);
167 const char *pname = eolian_parameter_name_get(param);
168 const char *ptype = eolian_type_c_type_get(ptypet);
169 const char *pdesc = eolian_parameter_description_get(param);
171 if (eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, ", ");
172 eina_strbuf_append_printf(fparam, "%s%s %s",
173 eolian_parameter_const_attribute_get(data, ftype == EOLIAN_PROP_GET)?"const":"",
175 eina_stringshare_del(ptype);
176 eina_strbuf_append_printf(descparam, " * @param[in] %s %s\n", pname, pdesc?pdesc:"No description supplied.");
177 if (eolian_parameter_is_nonull((Eolian_Function_Parameter*)data))
181 flags = eina_strbuf_new();
182 eina_strbuf_append_printf(flags, " EINA_ARG_NONNULL(%d", leg_param_idx);
185 eina_strbuf_append_printf(flags, ", %d", leg_param_idx);
188 eina_iterator_free(itr);
191 itr = eolian_function_parameters_get(funcid);
192 EINA_ITERATOR_FOREACH(itr, data)
194 Eolian_Function_Parameter *param = data;
195 const Eolian_Type *ptypet = eolian_parameter_type_get(param);
196 const char *pname = eolian_parameter_name_get(param);
197 const char *ptype = eolian_type_c_type_get(ptypet);
198 const char *pdesc = eolian_parameter_description_get(param);
199 Eolian_Parameter_Dir pdir = eolian_parameter_direction_get(param);
200 // TIZEN_ONLY(20150725): for doxygen 1.7.6.1
201 //const char *str_dir[] = {"in", "out", "inout"};
202 const char *str_dir[] = {"in", "out", "in,out"};
203 Eina_Bool had_star = !!strchr(ptype, '*');
204 if (ftype == EOLIAN_UNRESOLVED || ftype == EOLIAN_METHOD) add_star = (pdir == EOLIAN_OUT_PARAM || pdir == EOLIAN_INOUT_PARAM);
205 if (ftype == EOLIAN_PROP_GET) pdir = EOLIAN_OUT_PARAM;
206 if (ftype == EOLIAN_PROP_SET) pdir = EOLIAN_IN_PARAM;
208 if (eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, ", ");
209 eina_strbuf_append_printf(fparam, "%s%s%s%s%s",
210 eolian_parameter_const_attribute_get(data, ftype == EOLIAN_PROP_GET)?"const ":"",
211 ptype, had_star?"":" ", add_star?"*":"", pname);
212 eina_stringshare_del(ptype);
213 const char *dir_str = str_dir[(int)pdir];
214 eina_strbuf_append_printf(descparam, " * @param[%s] %s %s\n", dir_str, pname, pdesc?pdesc:"No description supplied.");
215 if (eolian_parameter_is_nonull((Eolian_Function_Parameter*)data))
219 flags = eina_strbuf_new();
220 eina_strbuf_append_printf(flags, " EINA_ARG_NONNULL(%d", leg_param_idx);
223 eina_strbuf_append_printf(flags, ", %d", leg_param_idx);
226 eina_iterator_free(itr);
228 if (!eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, "void");
229 if (flags) eina_strbuf_append_printf(flags, ")");
231 if (rettypet) rettype = eolian_type_c_type_get(rettypet);
233 eina_strbuf_replace_all(fbody, "@#params", eina_strbuf_string_get(fparam));
234 eina_strbuf_replace_all(fbody, "@#list_desc_param", eina_strbuf_string_get(descparam));
235 eina_strbuf_reset(fparam);
236 eina_strbuf_append_printf(fparam, "%s%s%s",
237 ret_const ? "const " : "",
238 rettype ? rettype : "void",
239 rettype && strchr(rettype, '*')?"":" ");
240 eina_strbuf_replace_all(fbody, "@#type_return", eina_strbuf_string_get(fparam));
241 if (eolian_function_return_is_warn_unused(funcid, ftype))
243 Eina_Bool no_nonull = !flags;
244 if (no_nonull) flags = eina_strbuf_new();
245 eina_strbuf_prepend(flags, " EINA_WARN_UNUSED_RESULT");
248 eina_strbuf_replace_all(fbody, "@#flags", eina_strbuf_string_get(flags));
249 eina_strbuf_replace_all(fbody, "@#flags", (eolian_function_return_is_warn_unused(funcid, ftype)) ? " EINA_WARN_UNUSED_RESULT" : "");
250 eina_strbuf_append(buf, eina_strbuf_string_get(fbody));
252 if (rettype) eina_stringshare_del(rettype);
255 eina_strbuf_free(flags);
256 eina_strbuf_free(fbody);
257 eina_strbuf_free(fparam);
258 eina_strbuf_free(descparam);
262 _eapi_func_generate(const Eolian_Class *class, const Eolian_Function *funcid, Eolian_Function_Type ftype, Eina_Strbuf *buf)
264 _eolian_class_func_vars func_env;
266 Eina_Bool var_as_ret = EINA_FALSE;
267 const Eolian_Type *rettypet = NULL;
268 const char *rettype = NULL;
269 const char *retname = NULL;
270 Eina_Bool ret_const = EINA_FALSE;
271 Eina_Bool add_star = EINA_FALSE;
272 Eina_Bool ret_is_void = EINA_FALSE;
274 Eina_Strbuf *fbody = eina_strbuf_new();
275 Eina_Strbuf *fparam = eina_strbuf_new();
276 Eina_Strbuf *eoparam = eina_strbuf_new();
281 _class_func_env_create(class, eolian_function_name_get(funcid), ftype, &func_env);
282 rettypet = eolian_function_return_type_get(funcid, ftype);
283 if (rettypet) rettype = eolian_type_c_type_get(rettypet);
284 if (rettype && !strcmp(rettype, "void")) ret_is_void = EINA_TRUE;
286 if (ftype == EOLIAN_PROP_GET)
288 add_star = EINA_TRUE;
291 itr = eolian_function_parameters_get(funcid);
292 /* We want to check if there is only one parameter */
293 if (eina_iterator_next(itr, &data) && !eina_iterator_next(itr, &data2))
295 Eolian_Function_Parameter *param = data;
296 rettypet = eolian_parameter_type_get(param);
297 retname = eolian_parameter_name_get(param);
298 var_as_ret = EINA_TRUE;
299 ret_const = eolian_parameter_const_attribute_get(data, EINA_TRUE);
301 eina_iterator_free(itr);
305 if (func_env.legacy_func[0] == '\0') goto end;
307 if (!rettype && rettypet) rettype = eolian_type_c_type_get(rettypet);
309 if (rettype && (!ret_is_void))
310 eina_strbuf_append(fbody, tmpl_eapi_body);
312 eina_strbuf_append(fbody, tmpl_eapi_body_void);
314 if (!eolian_function_is_class(funcid))
316 if (ftype == EOLIAN_PROP_GET || eolian_function_object_is_const(funcid))
317 eina_strbuf_append(fparam, "const ");
318 eina_strbuf_append_printf(fparam, "%s *obj", class_env.full_classname);
320 snprintf(cbuf, sizeof(cbuf), "(%s *)obj", class_env.full_classname);
321 eina_strbuf_replace_all(fbody, "@#eo_obj", cbuf);
325 Eina_Strbuf *class_buf = eina_strbuf_new();
326 _template_fill(class_buf, "@#CLASS_@#CLASSTYPE", class, NULL, NULL, EINA_TRUE);
327 eina_strbuf_replace_all(fbody, "@#eo_obj", eina_strbuf_string_get(class_buf));
328 eina_strbuf_free(class_buf);
330 eina_strbuf_replace_all(fbody, "@#eapi_func", func_env.legacy_func);
331 eina_strbuf_replace_all(fbody, "@#eo_func", func_env.lower_eo_func);
335 itr = eolian_property_keys_get(funcid);
336 EINA_ITERATOR_FOREACH(itr, data)
338 Eolian_Function_Parameter *param = data;
339 const Eolian_Type *ptypet = eolian_parameter_type_get(param);
340 const char *pname = eolian_parameter_name_get(param);
341 const char *ptype = eolian_type_c_type_get(ptypet);
342 if (eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, ", ");
343 eina_strbuf_append_printf(fparam, "%s%s %s",
344 eolian_parameter_const_attribute_get(data, ftype == EOLIAN_PROP_GET)?"const ":"",
346 eina_stringshare_del(ptype);
347 if (eina_strbuf_length_get(eoparam)) eina_strbuf_append(eoparam, ", ");
348 eina_strbuf_append_printf(eoparam, "%s", pname);
350 eina_iterator_free(itr);
353 itr = eolian_function_parameters_get(funcid);
354 EINA_ITERATOR_FOREACH(itr, data)
356 Eolian_Function_Parameter *param = data;
357 const Eolian_Type *ptypet = eolian_parameter_type_get(param);
358 const char *pname = eolian_parameter_name_get(param);
359 const char *ptype = eolian_type_c_type_get(ptypet);
360 Eolian_Parameter_Dir pdir = eolian_parameter_direction_get(param);
361 Eina_Bool had_star = !!strchr(ptype, '*');
362 if (ftype == EOLIAN_UNRESOLVED || ftype == EOLIAN_METHOD) add_star = (pdir == EOLIAN_OUT_PARAM || pdir == EOLIAN_INOUT_PARAM);
363 if (eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, ", ");
364 eina_strbuf_append_printf(fparam, "%s%s%s%s%s",
365 eolian_parameter_const_attribute_get(data, ftype == EOLIAN_PROP_GET)?"const ":"",
366 ptype, had_star?"":" ", add_star?"*":"", pname);
367 eina_stringshare_del(ptype);
368 if (eina_strbuf_length_get(eoparam)) eina_strbuf_append(eoparam, ", ");
369 eina_strbuf_append_printf(eoparam, "%s", pname);
371 eina_iterator_free(itr);
373 if (!eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, "void");
375 if (rettype && (!ret_is_void))
377 char tmp_ret_str[0xFF];
378 sprintf (tmp_ret_str, "%s%s", ret_const?"const ":"", rettype);
379 const Eolian_Expression *default_ret_val =
380 eolian_function_return_default_value_get(funcid, ftype);
381 const char *val_str = NULL;
384 Eolian_Value val = eolian_expression_eval_type
385 (default_ret_val, rettypet);
387 val_str = eolian_expression_value_to_literal(&val);
389 Eina_Bool had_star = !!strchr(rettype, '*');
390 sprintf (tmpstr, " %s%s%s%s = %s;\n",
391 ret_const?"const ":"", rettype, had_star?"":" ", retname,
392 val_str?val_str:"0");
394 eina_strbuf_replace_all(fbody, "@#ret_type", tmp_ret_str);
395 eina_strbuf_replace_all(fbody, "@#ret_init_val", tmpstr);
398 eina_strbuf_replace_all(fbody, "@#full_params", eina_strbuf_string_get(fparam));
399 eina_strbuf_replace_all(fbody, "@#eo_params", eina_strbuf_string_get(eoparam));
401 eina_strbuf_replace_all(fbody, "@#ret_val", (rettype && !ret_is_void) ? retname : "");
403 eina_strbuf_append(buf, eina_strbuf_string_get(fbody));
405 if (rettype) eina_stringshare_del(rettype);
408 eina_strbuf_free(fbody);
409 eina_strbuf_free(fparam);
410 eina_strbuf_free(eoparam);
414 legacy_header_generate(const Eolian_Class *class, Eina_Strbuf *buf)
416 _class_env_create(class, NULL, &class_env);
418 const char *desc = eolian_class_description_get(class);
421 Eina_Strbuf *linedesc = eina_strbuf_new();
422 eina_strbuf_append(linedesc, "/**\n");
423 eina_strbuf_append(linedesc, desc);
424 eina_strbuf_replace_all(linedesc, "\n", "\n * ");
425 eina_strbuf_append(linedesc, "\n */\n");
426 eina_strbuf_replace_all(linedesc, " * \n", " *\n"); /* Remove trailing whitespaces */
427 eina_strbuf_append(buf, eina_strbuf_string_get(linedesc));
428 eina_strbuf_free(linedesc);
431 Eina_Iterator *itr = eolian_class_implements_get(class);
434 const Eolian_Implement *impl;
435 EINA_ITERATOR_FOREACH(itr, impl)
437 if (eolian_implement_class_get(impl) != class)
439 Eolian_Function_Type ftype = EOLIAN_UNRESOLVED;
440 const Eolian_Function *fid = eolian_implement_function_get(impl, &ftype);
443 case EOLIAN_PROP_GET: case EOLIAN_PROP_SET:
444 _eapi_decl_func_generate(class, fid, ftype, buf);
446 case EOLIAN_PROPERTY:
447 _eapi_decl_func_generate(class, fid, EOLIAN_PROP_SET, buf);
448 _eapi_decl_func_generate(class, fid, EOLIAN_PROP_GET, buf);
451 _eapi_decl_func_generate(class, fid, EOLIAN_METHOD, buf);
455 eina_iterator_free(itr);
461 legacy_source_generate(const Eolian_Class *class, Eina_Strbuf *buf)
463 Eina_Bool ret = EINA_FALSE;
466 _class_env_create(class, NULL, &class_env);
468 Eina_Strbuf *tmpbuf = eina_strbuf_new();
469 Eina_Strbuf *str_bodyf = eina_strbuf_new();
471 if ((itr = eolian_class_implements_get(class)))
473 const Eolian_Implement *impl;
474 EINA_ITERATOR_FOREACH(itr, impl)
476 if (eolian_implement_class_get(impl) != class)
478 Eolian_Function_Type ftype = EOLIAN_UNRESOLVED;
479 const Eolian_Function *fid = eolian_implement_function_get(impl, &ftype);
482 case EOLIAN_PROP_GET: case EOLIAN_PROP_SET:
483 _eapi_func_generate(class, fid, ftype, str_bodyf);
485 case EOLIAN_PROPERTY:
486 _eapi_func_generate(class, fid, EOLIAN_PROP_SET, str_bodyf);
487 _eapi_func_generate(class, fid, EOLIAN_PROP_GET, str_bodyf);
490 _eapi_func_generate(class, fid, EOLIAN_METHOD, str_bodyf);
494 eina_iterator_free(itr);
497 eina_strbuf_append(buf, eina_strbuf_string_get(str_bodyf));
500 eina_strbuf_free(tmpbuf);
501 eina_strbuf_free(str_bodyf);