summaryrefslogtreecommitdiff
path: root/src/bin
diff options
context:
space:
mode:
authorDaniel Zaoui <daniel.zaoui@samsung.com>2014-02-11 13:42:59 +0000
committerDaniel Zaoui <daniel.zaoui@samsung.com>2014-03-03 14:09:53 +0200
commit5dea8ee0a89f5cee23a3812752cf1d7ceb9e3fca (patch)
tree575cc96ffb7b1a97ea3d463503899a274884eb77 /src/bin
parent92a24dea79bc2ffe215bbc8f3d2ad467bb7e6f62 (diff)
Eolian: first import.
Imported by Tom, from the eolian repo which was written by: Daniel Zaoui <daniel.zaoui@samsung.com> Yakov Goldberg <yakov.g@samsung.com> Yossi Kantor <yossi.kantor@samsung.com> Savio Sena <savio@expertisesolutions.com.br> Jérémy Zurcher <jeremy@asynk.ch> Signed-off-by: Tom Hacohen <tom@stosb.com>
Diffstat (limited to 'src/bin')
-rw-r--r--src/bin/eolian/common_funcs.c73
-rw-r--r--src/bin/eolian/common_funcs.h8
-rw-r--r--src/bin/eolian/eo1_generator.c667
-rw-r--r--src/bin/eolian/eo1_generator.h141
-rw-r--r--src/bin/eolian/legacy_generator.c452
-rw-r--r--src/bin/eolian/legacy_generator.h53
-rw-r--r--src/bin/eolian/main.c334
7 files changed, 1728 insertions, 0 deletions
diff --git a/src/bin/eolian/common_funcs.c b/src/bin/eolian/common_funcs.c
new file mode 100644
index 0000000000..dbd2c329a3
--- /dev/null
+++ b/src/bin/eolian/common_funcs.c
@@ -0,0 +1,73 @@
1#include "common_funcs.h"
2
3void
4_template_fill(Eina_Strbuf *buf, const char* templ, const char* classname, const char *funcname, Eina_Bool reset)
5{
6 static char capobjclass[0xFF];
7 static char lowobjclass[0xFF];
8 static char capclass[0xFF];
9 static char lowclass[0xFF];
10 static char normclass[0xFF];
11 static char capfunc[0xFF];
12 static char eoprefix[0xFF];
13
14 char *p;
15
16 if (reset) eina_strbuf_reset(buf);
17 if (templ) eina_strbuf_append(buf, templ);
18
19 if (strcmp(classname, normclass))
20 {
21 //Fill cache
22 strcpy(normclass, classname);
23
24 strcpy(capclass, classname);
25 p = capclass;
26 eina_str_toupper(&p);
27
28 strcpy(lowclass, classname);
29 p = lowclass;
30 eina_str_tolower(&p);
31
32 Eina_Strbuf *classobj = eina_strbuf_new();
33 eina_strbuf_append(classobj, classname);
34
35 // More to exclusion list
36 if (strcmp(classname, "Eo_Base") && strcmp(classname, "Elm_Widget"))
37 eina_strbuf_replace(classobj, "_", "_obj_", 1);
38
39 if (!strcmp(classname, "Evas_Object"))
40 {
41 eina_strbuf_reset(classobj);
42 eina_strbuf_append(classobj, "Evas_Obj");
43 }
44
45 strcpy(capobjclass, eina_strbuf_string_get(classobj));
46 p = capobjclass;
47 eina_str_toupper(&p);
48
49 strcpy(lowobjclass, eina_strbuf_string_get(classobj));
50 p = lowobjclass;
51 eina_str_tolower(&p);
52
53 strcpy(eoprefix, lowobjclass);
54
55 if (!strcmp(classname, "Elm_Widget"))
56 strcpy(eoprefix, "elm_wdg");
57
58 eina_strbuf_free(classobj);
59 }
60
61 strcpy(capfunc, funcname);
62 p = capfunc; eina_str_toupper(&p);
63
64 eina_strbuf_replace_all(buf, "@#func", funcname);
65 eina_strbuf_replace_all(buf, "@#FUNC", capfunc);
66 eina_strbuf_replace_all(buf, "@#Class", classname);
67 eina_strbuf_replace_all(buf, "@#class", lowclass);
68 eina_strbuf_replace_all(buf, "@#CLASS", capclass);
69 eina_strbuf_replace_all(buf, "@#OBJCLASS", capobjclass);
70 eina_strbuf_replace_all(buf, "@#objclass", lowobjclass);
71 eina_strbuf_replace_all(buf, "@#eoprefix", eoprefix);
72}
73
diff --git a/src/bin/eolian/common_funcs.h b/src/bin/eolian/common_funcs.h
new file mode 100644
index 0000000000..d0c67e0bd7
--- /dev/null
+++ b/src/bin/eolian/common_funcs.h
@@ -0,0 +1,8 @@
1#ifndef __EOLIAN_COMMON_FUNCS_H
2#define __EOLIAN_COMMON_FUNCS_H
3
4#include <Eina.h>
5
6void _template_fill(Eina_Strbuf *buf, const char* templ, const char* classname, const char *funcname, Eina_Bool reset);
7
8#endif
diff --git a/src/bin/eolian/eo1_generator.c b/src/bin/eolian/eo1_generator.c
new file mode 100644
index 0000000000..c67576c754
--- /dev/null
+++ b/src/bin/eolian/eo1_generator.c
@@ -0,0 +1,667 @@
1#include <Eina.h>
2#include <string.h>
3
4#include "Eolian.h"
5#include "eo1_generator.h"
6#include "common_funcs.h"
7
8static const char
9tmpl_eo_src_begin[] = "\
10EAPI Eo_Op @#OBJCLASS_BASE_ID = EO_NOOP;\n\
11\n\
12@#list_events\n\
13\n\
14";
15
16static const char
17tmpl_eo_src_end[] = "\
18@#list_ctors_body\
19\n\
20static void\n\
21_@#class_class_constructor(Eo_Class *klass)\n\
22{\n\
23 const Eo_Op_Func_Description func_desc[] = {@#list_func\n\
24 EO_OP_FUNC_SENTINEL\n\
25 };\n\
26 eo_class_funcs_set(klass, func_desc);\n\
27 _user_@#class_class_constructor(klass);\n\
28}\n\
29\n\
30static const Eo_Op_Description @#class_op_desc[] = {@#list_op\n\
31 EO_OP_DESCRIPTION_SENTINEL\n\
32};\n\
33\n\
34static const Eo_Event_Description *@#class_event_desc[] = {@#list_evdesc\n\
35 NULL\n\
36};\n\
37\n\
38static const Eo_Class_Description @#class_class_desc = {\n\
39 EO_VERSION,\n\
40 \"@#Class\",\n\
41 EO_CLASS_TYPE_REGULAR,\n\
42 EO_CLASS_DESCRIPTION_OPS(&@#OBJCLASS_BASE_ID, @#class_op_desc, @#OBJCLASS_SUB_ID_LAST),\n\
43 @#class_event_desc,\n\
44 sizeof(@#Class_Data),\n\
45 _@#class_class_constructor,\n\
46 NULL\n\
47};\n\
48\n\
49EO_DEFINE_CLASS(@#objclass_class_get, &@#class_class_desc, @#list_inheritNULL);\
50";
51
52static const char
53tmpl_eo_op_desc[] = "\n EO_OP_DESCRIPTION(@#OBJCLASS_SUB_ID_@#FUNC, \"@#desc\"),";
54
55static const char
56tmpl_eo_func_desc[] = "\n EO_OP_FUNC(@#OBJCLASS_ID(@#OBJCLASS_SUB_ID_@#FUNC), _eo_obj_@#class_@#func),";
57
58static const char
59tmpl_eobase_func_desc[] = "\n EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_@#FUNC), _eo_obj_@#class_@#func),";
60
61static const char
62tmpl_eo_header[] = "\
63#define @#OBJCLASS_CLASS @#objclass_class_get()\n\
64\n\
65const Eo_Class *@#objclass_class_get(void) EINA_CONST;\n\
66\n\
67extern EAPI Eo_Op @#OBJCLASS_BASE_ID;\n\
68\n\
69enum\n\
70{@#list_subid\n\
71 @#OBJCLASS_SUB_ID_LAST\n\
72};\n\
73\n\
74#define @#OBJCLASS_ID(sub_id) (@#OBJCLASS_BASE_ID + sub_id)\n\
75";
76
77static const char
78tmpl_eo_subid[] = "\n @#OBJCLASS_SUB_ID_@#FUNC,";
79
80static const char
81tmpl_eo_subid_apnd[] = " @#OBJCLASS_SUB_ID_@#FUNC,\n";
82
83static const char
84tmpl_eo_funcdef[] = "\n\
85/**\n\
86 * @def @#objclass_@#func\n\
87 *\n\
88@#desc\n\
89 *\n\
90@#list_desc_param\
91 *\n\
92 */\n\
93#define @#eoprefix_@#func(@#list_param) @#OBJCLASS_ID(@#OBJCLASS_SUB_ID_@#FUNC) @#list_typecheck\n\
94";
95
96static const char
97tmpl_eo_pardesc[] =" * @param[%s] %s\n";
98
99static const char
100tmpl_eobind_body[] ="\
101\n\
102@#ret_type _@#class_@#func(Eo *obj@#full_params);\n\n\
103static void\n\
104_eo_obj_@#class_@#func(Eo *obj, void *_pd EINA_UNUSED, va_list *list@#list_unused)\n\
105{\n\
106@#list_vars\
107 @#ret_param_@#class_@#func(obj@#list_params);\n\
108}\n\
109";
110
111char *
112_first_line_get(const char *str)
113{
114 Eina_Strbuf *ret = eina_strbuf_new();
115 if (str)
116 {
117 const char *p = strchr(str, '\n');
118 size_t offs = (p) ? (size_t)(p - str) : strlen(str);
119 eina_strbuf_append_n(ret, str, offs);
120 }
121 return eina_strbuf_string_steal(ret);
122}
123
124Eina_Bool
125eo1_enum_append(const char *classname, const char *funcname, Eina_Strbuf *str)
126{
127 _template_fill(str, tmpl_eo_subid_apnd, classname, funcname, EINA_FALSE);
128 return EINA_TRUE;
129}
130
131Eina_Bool
132eo1_fundef_generate(const char *classname, Eolian_Function func, Eolian_Function_Type ftype, Eina_Strbuf *functext)
133{
134 const char *str_dir[] = {"in", "out", "inout"};
135 const Eina_List *l;
136 void *data;
137 char funcname[0xFF];
138 char descname[0xFF];
139
140 char *fsuffix = "";
141 if (ftype == GET) fsuffix = "_get";
142 if (ftype == SET) fsuffix = "_set";
143
144 sprintf (funcname, "%s%s", eolian_function_name_get(func), fsuffix);
145 sprintf (descname, "comment%s", fsuffix);
146 const char *funcdesc = eolian_function_description_get(func, descname);
147
148 Eina_Strbuf *str_func = eina_strbuf_new();
149 _template_fill(str_func, tmpl_eo_funcdef, classname, funcname, EINA_TRUE);
150
151 Eina_Strbuf *linedesc = eina_strbuf_new();
152 eina_strbuf_append(linedesc, funcdesc ? funcdesc : "");
153 if (eina_strbuf_length_get(linedesc))
154 {
155 eina_strbuf_replace_all(linedesc, "\n", "\n * ");
156 eina_strbuf_prepend(linedesc," * ");
157 }
158
159 eina_strbuf_replace_all(str_func, "@#desc", eina_strbuf_string_get(linedesc));
160 eina_strbuf_free(linedesc);
161
162 Eina_Strbuf *str_par = eina_strbuf_new();
163 Eina_Strbuf *str_pardesc = eina_strbuf_new();
164 Eina_Strbuf *str_typecheck = eina_strbuf_new();
165
166 const char* rettype = eolian_function_return_type_get(func, ftype);
167 if (rettype && strcmp(rettype, "void"))
168 {
169 eina_strbuf_append_printf(str_pardesc, tmpl_eo_pardesc, "out", "ret");
170 eina_strbuf_append(str_par, "ret");
171 eina_strbuf_append_printf(str_typecheck, ", EO_TYPECHECK(%s*, ret)", rettype);
172 }
173
174 EINA_LIST_FOREACH(eolian_parameters_list_get(func), l, data)
175 {
176 const char *pname;
177 const char *ptype;
178 Eolian_Parameter_Dir pdir;
179 eolian_parameter_information_get((Eolian_Function_Parameter)data, &pdir, &ptype, &pname, NULL);
180 if (ftype == GET) pdir = EOLIAN_OUT_PARAM;
181 if (ftype == SET) pdir = EOLIAN_IN_PARAM;
182 char *umpr = (pdir == EOLIAN_IN_PARAM) ? "" : "*";
183
184 const char *dir_str = str_dir[(int)pdir];
185
186 eina_strbuf_append_printf(str_pardesc, tmpl_eo_pardesc, dir_str, pname);
187
188 if (eina_strbuf_length_get(str_par)) eina_strbuf_append(str_par, ", ");
189 eina_strbuf_append(str_par, pname);
190
191 eina_strbuf_append_printf(str_typecheck, ", EO_TYPECHECK(%s%s, %s)", ptype, umpr, pname);
192 }
193
194 eina_strbuf_replace_all(str_func, "@#list_param", eina_strbuf_string_get(str_par));
195 eina_strbuf_replace_all(str_func, "@#list_desc_param", eina_strbuf_string_get(str_pardesc));
196 eina_strbuf_replace_all(str_func, "@#list_typecheck", eina_strbuf_string_get(str_typecheck));
197
198 eina_strbuf_free(str_par);
199 eina_strbuf_free(str_pardesc);
200 eina_strbuf_free(str_typecheck);
201
202 eina_strbuf_append(functext, eina_strbuf_string_get(str_func));
203 eina_strbuf_free(str_func);
204
205 return EINA_TRUE;
206}
207
208Eina_Bool
209eo1_header_generate(const char *classname, Eina_Strbuf *buf)
210{
211 const Eolian_Function_Type ftype_order[] = {CONSTRUCTOR, PROPERTY_FUNC, METHOD_FUNC};
212 const Eina_List *l;
213 void *data;
214 char tmpstr[0x1FF];
215
216 if (!eolian_class_exists(classname))
217 {
218 printf ("Class \"%s\" not found in database\n", classname);
219 return EINA_FALSE;
220 }
221
222 Eina_Strbuf * str_hdr = eina_strbuf_new();
223 _template_fill(str_hdr, tmpl_eo_header, classname, "", EINA_TRUE);
224
225 Eina_Strbuf *str_subid = eina_strbuf_new();
226 Eina_Strbuf *str_ev = eina_strbuf_new();
227 Eina_Strbuf *tmpbuf = eina_strbuf_new();
228
229 Eolian_Event event;
230 EINA_LIST_FOREACH(eolian_class_events_list_get(classname), l, event)
231 {
232 const char *evname;
233 const char *evdesc;
234 eolian_class_event_information_get(event, &evname, &evdesc);
235
236 eina_strbuf_reset(tmpbuf);
237 eina_strbuf_append(tmpbuf, evdesc);
238 eina_strbuf_replace_all(tmpbuf, "\n", "\n * ");
239 eina_strbuf_prepend(tmpbuf," * ");
240 eina_strbuf_append_printf(str_ev, "\n/**\n%s\n */\n", eina_strbuf_string_get(tmpbuf));
241
242 _template_fill(tmpbuf, "@#CLASS_@#FUNC", classname, evname, EINA_TRUE);
243 eina_strbuf_replace_all(tmpbuf, ",", "_");
244 const char* s = eina_strbuf_string_get(tmpbuf);
245 eina_strbuf_append_printf(str_ev, "#define %s (&(_%s))\n", s, s);
246 }
247
248 int i;
249 for (i = 0; i < 3; i++)
250 EINA_LIST_FOREACH(eolian_class_functions_list_get(classname, ftype_order[i]), l, data)
251 {
252 const Eolian_Function_Type ftype = eolian_function_type_get((Eolian_Function)data);
253 const char *funcname = eolian_function_name_get((Eolian_Function)data);
254 Eina_Bool prop_read = (ftype == PROPERTY_FUNC || ftype == GET ) ? EINA_TRUE : EINA_FALSE ;
255 Eina_Bool prop_write = (ftype == PROPERTY_FUNC || ftype == SET ) ? EINA_TRUE : EINA_FALSE ;
256
257 if (!prop_read && !prop_write)
258 {
259 _template_fill(str_subid, tmpl_eo_subid, classname, funcname, EINA_FALSE);
260 eo1_fundef_generate(classname, (Eolian_Function)data, UNRESOLVED, str_hdr);
261 }
262 if (prop_read)
263 {
264 sprintf(tmpstr, "%s_get", funcname);
265 _template_fill(str_subid, tmpl_eo_subid, classname, tmpstr, EINA_FALSE);
266 eo1_fundef_generate(classname, (Eolian_Function)data, GET, str_hdr);
267 }
268 if (prop_write)
269 {
270 sprintf(tmpstr, "%s_set", funcname);
271 _template_fill(str_subid, tmpl_eo_subid, classname, tmpstr, EINA_FALSE);
272 eo1_fundef_generate(classname, (Eolian_Function)data, SET, str_hdr);
273 }
274 }
275
276 eina_strbuf_replace_all(str_hdr, "@#list_subid", eina_strbuf_string_get(str_subid));
277 eina_strbuf_append(str_hdr, eina_strbuf_string_get(str_ev));
278
279 eina_strbuf_free(str_subid);
280 eina_strbuf_free(str_ev);
281 eina_strbuf_free(tmpbuf);
282
283 eina_strbuf_append(buf, eina_strbuf_string_get(str_hdr));
284 return EINA_TRUE;
285}
286
287static const char*
288_varg_upgr(const char *stype)
289{
290 if (!strcmp(stype, "Eina_Bool") ||
291 !strcmp(stype, "char") ||
292 !strcmp(stype, "short"))
293 return "int";
294 return stype;
295}
296
297Eina_Bool
298eo1_bind_func_generate(const char *classname, Eolian_Function funcid, Eolian_Function_Type ftype, Eina_Strbuf *buf)
299{
300 const char *suffix = "";
301 const char *umpr = NULL;
302 Eina_Bool var_as_ret = EINA_FALSE;
303 const char *rettype = NULL;
304 const char *retname = NULL;
305 Eina_Bool ret_const = EINA_FALSE;
306
307 Eina_Strbuf *fbody = eina_strbuf_new();
308 Eina_Strbuf *va_args = eina_strbuf_new();
309 Eina_Strbuf *params = eina_strbuf_new(); /* only variables names */
310 Eina_Strbuf *full_params = eina_strbuf_new(); /* variables types + names */
311
312 rettype = eolian_function_return_type_get(funcid, ftype);
313 if (rettype && !strcmp(rettype, "void")) rettype = NULL;
314 retname = "ret";
315 if (ftype == GET)
316 {
317 suffix = "_get";
318 umpr = "*";
319 if (!rettype)
320 {
321 const Eina_List *l = eolian_parameters_list_get(funcid);
322 if (eina_list_count(l) == 1)
323 {
324 void* data = eina_list_data_get(l);
325 eolian_parameter_information_get((Eolian_Function_Parameter)data, NULL, &rettype, &retname, NULL);
326 var_as_ret = EINA_TRUE;
327 ret_const = eolian_parameter_get_const_attribute_get(data);
328 }
329 }
330 }
331 if (ftype == SET)
332 {
333 suffix = "_set";
334 umpr = "";
335 }
336
337 char tmpstr[0xFF];
338 sprintf (tmpstr, "%s%s", eolian_function_name_get(funcid), suffix);
339 _template_fill(fbody, tmpl_eobind_body, classname, tmpstr, EINA_FALSE);
340
341 const Eina_List *l;
342 void *data;
343
344 if (!var_as_ret)
345 {
346 EINA_LIST_FOREACH(eolian_parameters_list_get(funcid), l, data)
347 {
348 const char *pname;
349 const char *ptype;
350 Eolian_Parameter_Dir pdir;
351 eolian_parameter_information_get((Eolian_Function_Parameter)data, &pdir, &ptype, &pname, NULL);
352 const char *ptrstr = (umpr) ? umpr : ( (pdir == EOLIAN_IN_PARAM) ? "" : " *" );
353 Eina_Bool is_const = eolian_parameter_get_const_attribute_get(data);
354 eina_strbuf_append_printf(va_args, " %s%s %s%s = va_arg(*list, %s%s%s);\n",
355 ftype == GET && is_const?"const ":"", ptype, ptrstr, pname,
356 ftype == GET && is_const?"const ":"", (*ptrstr) ? ptype : _varg_upgr(ptype), ptrstr);
357 eina_strbuf_append_printf(params, ", %s", pname);
358 eina_strbuf_append_printf(full_params, ", %s%s%s %s",
359 ftype == GET && eolian_parameter_get_const_attribute_get(data)?"const ":"",
360 ptype, ptrstr, pname);
361 }
362 }
363
364 if (rettype && strcmp(rettype, "void"))
365 {
366 eina_strbuf_append_printf(va_args, " %s%s *%s = va_arg(*list, %s%s *);\n",
367 ret_const?"const ":"",
368 rettype, retname,
369 ret_const?"const ":"",
370 rettype);
371 Eina_Strbuf *ret_param = eina_strbuf_new();
372 eina_strbuf_append_printf(ret_param, "*%s = ", retname);
373 eina_strbuf_replace_all(fbody, "@#ret_param", eina_strbuf_string_get(ret_param));
374 sprintf(tmpstr, "%s%s", ret_const?"const ":"", rettype);
375 eina_strbuf_replace_all(fbody, "@#ret_type", tmpstr);
376 eina_strbuf_free(ret_param);
377 }
378 else
379 {
380 eina_strbuf_replace_all(fbody, "@#ret_param", "");
381 eina_strbuf_replace_all(fbody, "@#ret_type", "void");
382 }
383
384 if (eina_list_count(eolian_parameters_list_get(funcid)) == 0)
385 {
386 eina_strbuf_replace_all(fbody, "@#list_unused", " EINA_UNUSED");
387 }
388 else
389 {
390 eina_strbuf_replace_all(fbody, "@#list_unused", "");
391 }
392 eina_strbuf_replace_all(fbody, "@#list_vars", eina_strbuf_string_get(va_args));
393 eina_strbuf_replace_all(fbody, "@#full_params", eina_strbuf_string_get(full_params));
394 eina_strbuf_replace_all(fbody, "@#list_params", eina_strbuf_string_get(params));
395 eina_strbuf_append(buf, eina_strbuf_string_get(fbody));
396
397 eina_strbuf_free(va_args);
398 eina_strbuf_free(full_params);
399 eina_strbuf_free(params);
400 eina_strbuf_free(fbody);
401 return EINA_TRUE;
402}
403
404Eina_Bool
405eo1_eo_func_desc_generate(const char *classname, const char *funcname, Eina_Strbuf *buf)
406{
407 _template_fill(buf, tmpl_eo_func_desc, classname, funcname, EINA_TRUE);
408 return EINA_TRUE;
409}
410
411Eina_Bool
412eo1_eo_op_desc_generate(const char *classname, const char *funcname, Eina_Strbuf *buf)
413{
414 _template_fill(buf, tmpl_eo_op_desc, classname, funcname, EINA_TRUE);
415 return EINA_TRUE;
416}
417
418Eina_Bool
419eo1_source_beginning_generate(const char *classname, Eina_Strbuf *buf)
420{
421 const Eina_List *itr;
422
423 Eina_Strbuf *tmpbuf = eina_strbuf_new();
424 Eina_Strbuf *str_begin = eina_strbuf_new();
425 Eina_Strbuf *str_ev = eina_strbuf_new();
426
427 _template_fill(str_begin, tmpl_eo_src_begin, classname, "", EINA_TRUE);
428
429 Eolian_Event event;
430 EINA_LIST_FOREACH(eolian_class_events_list_get(classname), itr, event)
431 {
432 const char *evname;
433 const char *evdesc;
434 char *evdesc_line1;
435
436 eolian_class_event_information_get(event, &evname, &evdesc);
437 evdesc_line1 = _first_line_get(evdesc);
438 _template_fill(str_ev, "@#CLASS_@#FUNC", classname, evname, EINA_TRUE);
439 eina_strbuf_replace_all(str_ev, ",", "_");
440
441 eina_strbuf_append_printf(tmpbuf,
442 "EAPI const Eo_Event_Description _%s = EO_EVENT_DESCRIPTION(\"%s\", \"%s\");\n",
443 eina_strbuf_string_get(str_ev), evname, evdesc_line1);
444 free(evdesc_line1);
445 }
446
447 eina_strbuf_replace_all(str_begin, "@#list_events", eina_strbuf_string_get(tmpbuf));
448 eina_strbuf_append(buf, eina_strbuf_string_get(str_begin));
449
450 eina_strbuf_free(str_ev);
451 eina_strbuf_free(tmpbuf);
452 eina_strbuf_free(str_begin);
453 return EINA_TRUE;
454}
455
456Eina_Bool
457eo1_source_end_generate(const char *classname, Eina_Strbuf *buf)
458{
459 const Eina_List *itr;
460 Eolian_Function fn;
461
462 Eina_Strbuf *str_end = eina_strbuf_new();
463 Eina_Strbuf *tmpbuf = eina_strbuf_new();
464 Eina_Strbuf *str_op = eina_strbuf_new();
465 Eina_Strbuf *str_func = eina_strbuf_new();
466 Eina_Strbuf *str_bodyf = eina_strbuf_new();
467 Eina_Strbuf *str_ev = eina_strbuf_new();
468
469 _template_fill(str_end, tmpl_eo_src_end, classname, "", EINA_TRUE);
470
471 // default constructor
472 Eolian_Function ctor_fn = eolian_class_default_constructor_get(classname);
473 if (ctor_fn)
474 {
475 _template_fill(str_func, tmpl_eobase_func_desc, classname, "constructor", EINA_FALSE);
476 eo1_bind_func_generate(classname, ctor_fn, UNRESOLVED, str_bodyf);
477 }
478 // default destructor
479 Eolian_Function dtor_fn = eolian_class_default_destructor_get(classname);
480 if (dtor_fn)
481 {
482 _template_fill(str_func, tmpl_eobase_func_desc, classname, "destructor", EINA_FALSE);
483 eo1_bind_func_generate(classname, dtor_fn, UNRESOLVED, str_bodyf);
484 }
485
486 //Implements - TODO one generate func def for all
487 Eolian_Implement impl_desc;
488 EINA_LIST_FOREACH(eolian_class_implements_list_get(classname), itr, impl_desc)
489 {
490 const char *funcname;
491 const char *impl_class;
492 Eolian_Function_Type ftype;
493
494 eolian_implement_information_get(impl_desc, &impl_class, &funcname, &ftype);
495
496 Eina_Strbuf *tmpl_impl = eina_strbuf_new();
497 eina_strbuf_append(tmpl_impl, tmpl_eo_func_desc);
498
499 char tbuff[0xFF];
500 char *tp = tbuff;
501 strcpy(tbuff, classname);
502 eina_str_tolower(&tp);
503
504 eina_strbuf_replace_all(tmpl_impl, "@#class", tbuff);
505 const char *tmpl_impl_str = eina_strbuf_string_get(tmpl_impl);
506
507 Eolian_Function in_meth = NULL;
508 Eolian_Function in_prop = NULL;
509 const Eina_List *itr2;
510 Eolian_Function fnid;
511 EINA_LIST_FOREACH(eolian_class_functions_list_get((char *)impl_class, CONSTRUCTOR), itr2, fnid)
512 if (fnid && !strcmp(eolian_function_name_get(fnid), funcname)) in_meth = fnid;
513 EINA_LIST_FOREACH(eolian_class_functions_list_get((char *)impl_class, METHOD_FUNC), itr2, fnid)
514 if (fnid && !strcmp(eolian_function_name_get(fnid), funcname)) in_meth = fnid;
515 EINA_LIST_FOREACH(eolian_class_functions_list_get((char *)impl_class, PROPERTY_FUNC), itr2, fnid)
516 if (fnid && !strcmp(eolian_function_name_get(fnid), funcname)) in_prop = fnid;
517
518 if (!in_meth && !in_prop)
519 {
520 printf ("Failed to generate implementation of %s:%s - missing form super class\n", impl_class, funcname);
521 return EINA_FALSE;
522 }
523
524 if (in_meth)
525 {
526 _template_fill(str_func, tmpl_impl_str, impl_class, funcname, EINA_FALSE);
527 eo1_bind_func_generate(classname, in_meth, UNRESOLVED, str_bodyf);
528 }
529
530 if (in_prop)
531 {
532 char tmpstr[0xFF];
533
534 if ((ftype != GET) && (ftype != SET)) ftype = eolian_function_type_get(in_prop);
535
536 Eina_Bool prop_read = ( ftype == SET ) ? EINA_FALSE : EINA_TRUE;
537 Eina_Bool prop_write = ( ftype == GET ) ? EINA_FALSE : EINA_TRUE;
538
539 if (prop_read)
540 {
541 sprintf(tmpstr, "%s_get", funcname);
542 _template_fill(str_func, tmpl_impl_str, impl_class, tmpstr, EINA_FALSE);
543 eo1_bind_func_generate(classname, in_prop, GET, str_bodyf);
544 }
545
546 if (prop_write)
547 {
548 sprintf(tmpstr, "%s_set", funcname);
549 _template_fill(str_func, tmpl_impl_str, impl_class, tmpstr, EINA_FALSE);
550 eo1_bind_func_generate(classname, in_prop, SET, str_bodyf);
551 }
552 }
553 eina_strbuf_free(tmpl_impl);
554 }
555
556 //Constructors
557 EINA_LIST_FOREACH(eolian_class_functions_list_get(classname, CONSTRUCTOR), itr, fn)
558 {
559 const char *funcname = eolian_function_name_get(fn);
560 char *desc = _first_line_get(eolian_function_description_get(fn, "comment"));
561
562 _template_fill(tmpbuf, tmpl_eo_op_desc, classname, funcname, EINA_TRUE);
563 eina_strbuf_replace_all(tmpbuf, "@#desc", desc);
564 free(desc);
565
566 eina_strbuf_append(str_op, eina_strbuf_string_get(tmpbuf));
567
568 _template_fill(str_func, tmpl_eo_func_desc, classname, funcname, EINA_FALSE);
569 eo1_bind_func_generate(classname, fn, UNRESOLVED, str_bodyf);
570 }
571
572 //Properties
573 EINA_LIST_FOREACH(eolian_class_functions_list_get(classname, PROPERTY_FUNC), itr, fn)
574 {
575 const char *funcname = eolian_function_name_get(fn);
576 const Eolian_Function_Type ftype = eolian_function_type_get(fn);
577 char tmpstr[0xFF];
578
579 Eina_Bool prop_read = ( ftype == SET ) ? EINA_FALSE : EINA_TRUE;
580 Eina_Bool prop_write = ( ftype == GET ) ? EINA_FALSE : EINA_TRUE;
581
582 if (prop_read)
583 {
584 char *desc = _first_line_get(eolian_function_description_get(fn, "comment_get"));
585
586 sprintf(tmpstr, "%s_get", funcname);
587 eo1_eo_op_desc_generate(classname, tmpstr, tmpbuf);
588 eina_strbuf_replace_all(tmpbuf, "@#desc", desc);
589 free(desc);
590 eina_strbuf_append(str_op, eina_strbuf_string_get(tmpbuf));
591
592 eo1_eo_func_desc_generate(classname, tmpstr, tmpbuf);
593 eina_strbuf_append(str_func, eina_strbuf_string_get(tmpbuf));
594 }
595 if (prop_write)
596 {
597 char *desc = _first_line_get(eolian_function_description_get(fn, "comment_set"));
598
599 sprintf(tmpstr, "%s_set", funcname);
600 eo1_eo_op_desc_generate(classname, tmpstr, tmpbuf);
601 eina_strbuf_replace_all(tmpbuf, "@#desc", desc);
602 eina_strbuf_append(str_op, eina_strbuf_string_get(tmpbuf));
603 free(desc);
604
605 eo1_eo_func_desc_generate(classname, tmpstr, tmpbuf);
606 eina_strbuf_append(str_func, eina_strbuf_string_get(tmpbuf));
607 }
608 }
609
610 //Methods
611 EINA_LIST_FOREACH(eolian_class_functions_list_get(classname, METHOD_FUNC), itr, fn)
612 {
613 const char *funcname = eolian_function_name_get(fn);
614 char *desc = _first_line_get(eolian_function_description_get(fn, "comment"));
615
616 eo1_eo_op_desc_generate(classname, funcname, tmpbuf);
617 eina_strbuf_replace_all(tmpbuf, "@#desc", desc);
618 free(desc);
619 eina_strbuf_append(str_op, eina_strbuf_string_get(tmpbuf));
620
621 eo1_eo_func_desc_generate(classname, funcname, tmpbuf);
622 eina_strbuf_append(str_func, eina_strbuf_string_get(tmpbuf));
623 }
624
625 Eolian_Event event;
626 EINA_LIST_FOREACH(eolian_class_events_list_get(classname), itr, event)
627 {
628 const char *evname;
629
630 eolian_class_event_information_get(event, &evname, NULL);
631 _template_fill(tmpbuf, "@#CLASS_@#FUNC", classname, evname, EINA_TRUE);
632 eina_strbuf_replace_all(tmpbuf, ",", "_");
633 eina_strbuf_append_printf(str_ev, "\n %s,", eina_strbuf_string_get(tmpbuf));
634 }
635 eina_strbuf_replace_all(str_end, "@#list_evdesc", eina_strbuf_string_get(str_ev));
636
637 const char *inherit_name;
638 eina_strbuf_reset(tmpbuf);
639 EINA_LIST_FOREACH(eolian_class_inherits_list_get(classname), itr, inherit_name)
640 {
641 if (!strcmp(inherit_name, "Elm_Widget"))
642 eina_strbuf_append(tmpbuf, "ELM_OBJ_WIDGET_CLASS, ");
643 else if (!strcmp(inherit_name, "Elm_Interface_Scrollable"))
644 eina_strbuf_append(tmpbuf, "ELM_SCROLLABLE_INTERFACE, ");
645 else
646 _template_fill(tmpbuf, "@#OBJCLASS_CLASS, ", inherit_name, "", EINA_FALSE);
647 }
648
649 if (eina_strbuf_length_get(tmpbuf) == 0) eina_strbuf_append(tmpbuf,"EO_BASE_CLASS, ");
650 eina_strbuf_replace_all(str_end, "@#list_inherit", eina_strbuf_string_get(tmpbuf));
651
652 eina_strbuf_replace_all(str_end, "@#list_func", eina_strbuf_string_get(str_func));
653 eina_strbuf_replace_all(str_end, "@#list_op", eina_strbuf_string_get(str_op));
654 eina_strbuf_replace_all(str_end, "@#list_ctors_body", eina_strbuf_string_get(str_bodyf));
655
656 eina_strbuf_append(buf, eina_strbuf_string_get(str_end));
657
658 eina_strbuf_free(tmpbuf);
659 eina_strbuf_free(str_op);
660 eina_strbuf_free(str_func);
661 eina_strbuf_free(str_bodyf);
662 eina_strbuf_free(str_end);
663 eina_strbuf_free(str_ev);
664
665 return EINA_TRUE;
666}
667
diff --git a/src/bin/eolian/eo1_generator.h b/src/bin/eolian/eo1_generator.h
new file mode 100644
index 0000000000..7a0309505b
--- /dev/null
+++ b/src/bin/eolian/eo1_generator.h
@@ -0,0 +1,141 @@
1#ifndef EO1_GENERATOR_H
2#define EO1_GENERATOR_H
3
4#include<Eina.h>
5#include "eolian_database.h"
6
7/*
8 * @brief Generate beginning of Eo1 source code for Eo class
9 *
10 * This function generates the base id definition and the list of events.
11 *
12 * @param[in] classname class name
13 * @param[inout] buf buffer to fill
14 *
15 * @return EINA_TRUE on success, EINA_FALSE on error.
16 *
17 */
18Eina_Bool
19eo1_source_beginning_generate(const char *classname, Eina_Strbuf *buf);
20
21/*
22 * @brief Generate end of Eo1 source code for Eo class
23 *
24 * This function generates the constructors, the class constructor, the function
25 * descriptions and the class description.
26 *
27 * @param[in] classname class name
28 * @param[inout] buf buffer to fill
29 *
30 * @return EINA_TRUE on success, EINA_FALSE on error.
31 *
32 */
33Eina_Bool
34eo1_source_end_generate(const char *classname, Eina_Strbuf *buf);
35
36/*
37 * @brief Generate the source code for a specific Eo function.
38 *
39 * This function generates for a given function id the corresponding
40 * Eo function.
41 *
42 * @param[in] classname class name
43 * @param[in] funcid Function Id
44 * @param[in] ftype type of the function (SET/GET/METHOD...)
45 * @param[inout] buf buffer to fill
46 *
47 * @return EINA_TRUE on success, EINA_FALSE on error.
48 *
49 */
50Eina_Bool
51eo1_bind_func_generate(const char *classname, Eolian_Function funcid, Eolian_Function_Type ftype, Eina_Strbuf *buf);
52
53/*
54 * @brief Generate the header code for a specific Eo class.
55 *
56 * This function generates header code from scratch.
57 *
58 * @param[in] classname class name
59 * @param[inout] buf buffer to fill
60 *
61 * @return EINA_TRUE on success, EINA_FALSE on error.
62 *
63 */
64Eina_Bool eo1_header_generate(const char *classname, Eina_Strbuf *buf);
65
66/*
67 * @brief Append the header code for a specific Eo class.
68 *
69 * This function generates header code by appending it into an existing class.
70 *
71 * @param[in] classname class name
72 * @param[inout] buf buffer to fill
73 *
74 * @return EINA_TRUE on success, EINA_FALSE on error.
75 *
76 */
77Eina_Bool eo1_header_append(const char *classname, Eina_Strbuf *buf);
78
79/*
80 * @brief Fill the given buffer with the Eo enum of a given function.
81 *
82 * @param[in] classname class name
83 * @param[in] funcname function name
84 * @param[inout] buf buffer to fill
85 *
86 * @return EINA_TRUE on success, EINA_FALSE on error.
87 *
88 */
89Eina_Bool eo1_enum_append(const char *classname, const char *funcname, Eina_Strbuf *buf);
90
91/*
92 * @brief Generate the function definition (header) for a specific Eo function.
93 *
94 * This function generates for a given function the corresponding
95 * Eo function definition.
96 *
97 * @param[in] classname class name
98 * @param[in] funcid Function Id
99 * @param[in] ftype type of the function (SET/GET/METHOD...)
100 * @param[inout] buf buffer to fill
101 *
102 * @return EINA_TRUE on success, EINA_FALSE on error.
103 *
104 */
105Eina_Bool
106eo1_fundef_generate(const char *classname, Eolian_Function func, Eolian_Function_Type ftype, Eina_Strbuf *buf);
107
108/*
109 * @brief Generate the function description for a specific Eo function.
110 *
111 * This function generates for a given function the corresponding
112 * Eo function description.
113 *
114 * @param[in] classname class name
115 * @param[in] funcname function name
116 * @param[inout] buf buffer to fill
117 *
118 * @return EINA_TRUE on success, EINA_FALSE on error.
119 *
120 */
121Eina_Bool
122eo1_eo_func_desc_generate(const char *classname, const char *funcname, Eina_Strbuf *buf);
123
124/*
125 * @brief Generate the Eo op description for a specific Eo function.
126 *
127 * This function generates for a given function the corresponding
128 * Eo function definition.
129 *
130 * @param[in] classname class name
131 * @param[in] funcname function name
132 * @param[inout] buf buffer to fill
133 *
134 * @return EINA_TRUE on success, EINA_FALSE on error.
135 *
136 */
137Eina_Bool
138eo1_eo_op_desc_generate(const char *classname, const char *funcname, Eina_Strbuf *buf);
139
140#endif
141
diff --git a/src/bin/eolian/legacy_generator.c b/src/bin/eolian/legacy_generator.c
new file mode 100644
index 0000000000..207772859b
--- /dev/null
+++ b/src/bin/eolian/legacy_generator.c
@@ -0,0 +1,452 @@
1#include <Eina.h>
2#include <string.h>
3
4#include "Eolian.h"
5
6#include "legacy_generator.h"
7#include "eo1_generator.h"
8#include "common_funcs.h"
9
10static const char
11tmpl_eapi_funcdef[] = "\n\
12/**\n\
13 *\n\
14@#desc\n\
15 *\n\
16@#list_desc_param\
17 */\n\
18EAPI @#type_return @#class_@#func(@#is_constEvas_Object *obj@#params);\n\
19";
20
21/*@#CLASS_CHECK(obj) @#check_ret;\n\*/
22static const char
23tmpl_eapi_body[] ="\
24\n\
25EAPI @#ret_type\n\
26@#eapi_prefix_@#func(@#is_constEvas_Object *obj@#full_params)\n\
27{\n\
28@#ret_init_val\
29 eo_do((Eo *) obj, @#eoprefix_@#func(@#eo_params));\n\
30 return @#ret_val;\n\
31}\n\
32";
33
34static void
35_eapi_decl_func_generate(const char *classname, Eolian_Function funcid, Eolian_Function_Type ftype, Eina_Strbuf *buf)
36{
37 //TODO return value
38 const char *suffix = "";
39 const char *umpr = NULL;
40 const char *rettype = NULL;
41 const char *func_lpref = NULL;
42 Eina_Bool var_as_ret = EINA_FALSE;
43
44 rettype = eolian_function_return_type_get(funcid, ftype);
45 if (rettype && !strcmp(rettype, "void")) rettype = NULL;
46 if (ftype == GET)
47 {
48 suffix = "_get";
49 umpr = "*";
50 func_lpref = eolian_function_data_get(funcid, EOLIAN_LEGACY_GET);
51 if (!rettype)
52 {
53 const Eina_List *l = eolian_parameters_list_get(funcid);
54 if (eina_list_count(l) == 1)
55 {
56 void* data = eina_list_data_get(l);
57 eolian_parameter_information_get((Eolian_Function_Parameter)data, NULL, &rettype, NULL, NULL);
58 var_as_ret = EINA_TRUE;
59 }
60 }
61 }
62
63 if (ftype == SET)
64 {
65 suffix = "_set";
66 umpr = "";
67 func_lpref = eolian_function_data_get(funcid, EOLIAN_LEGACY_SET);
68 }
69
70 func_lpref = (func_lpref) ? func_lpref : eolian_function_data_get(funcid, EOLIAN_LEGACY);
71 func_lpref = (func_lpref) ? func_lpref : eolian_class_legacy_prefix_get(classname);
72
73 if (!func_lpref) func_lpref = classname;
74
75 Eina_Strbuf *fbody = eina_strbuf_new();
76 Eina_Strbuf *fparam = eina_strbuf_new();
77 Eina_Strbuf *descparam = eina_strbuf_new();
78
79 char tmpstr[0xFF];
80 sprintf (tmpstr, "%s%s", eolian_function_name_get(funcid), suffix);
81 _template_fill(fbody, tmpl_eapi_funcdef, func_lpref, tmpstr, EINA_FALSE);
82 sprintf (tmpstr, "comment%s", suffix);
83
84 const char *desc = eolian_function_description_get(funcid, tmpstr);
85 Eina_Strbuf *linedesc = eina_strbuf_new();
86 eina_strbuf_append(linedesc, desc ? desc : "");
87 if (eina_strbuf_length_get(linedesc))
88 {
89 eina_strbuf_replace_all(linedesc, "\n", "\n * ");
90 eina_strbuf_prepend(linedesc," * ");
91 }
92
93 eina_strbuf_replace_all(fbody, "@#desc", eina_strbuf_string_get(linedesc));
94 eina_strbuf_free(linedesc);
95
96 const Eina_List *l;
97 void *data;
98
99 if (!var_as_ret)
100 {
101 EINA_LIST_FOREACH(eolian_parameters_list_get(funcid), l, data)
102 {
103 const char *pname;
104 const char *pdesc;
105 const char *ptype;
106 Eolian_Parameter_Dir pdir;
107 eolian_parameter_information_get((Eolian_Function_Parameter)data, &pdir, &ptype, &pname, &pdesc);
108 const char *ptrstr = (umpr) ? umpr : ( (pdir == EOLIAN_IN_PARAM) ? "" : "*" );
109 eina_strbuf_append_printf(fparam, ", %s%s%s %s",
110 eolian_parameter_get_const_attribute_get(data)?"const":"",
111 ptype, ptrstr, pname);
112 eina_strbuf_append_printf(descparam, " * @param %s\n", pname);
113 }
114 }
115 eina_strbuf_replace_all(fbody, "@#params", eina_strbuf_string_get(fparam));
116 eina_strbuf_replace_all(fbody, "@#list_desc_param", eina_strbuf_string_get(descparam));
117 eina_strbuf_replace_all(fbody, "@#type_return", (rettype) ? rettype : "void");
118 eina_strbuf_replace_all(fbody, "@#is_const", (ftype == GET || eolian_function_object_is_const(funcid)) ? "const " : "");
119 eina_strbuf_append(buf, eina_strbuf_string_get(fbody));
120
121 eina_strbuf_free(fbody);
122 eina_strbuf_free(fparam);
123 eina_strbuf_free(descparam);
124}
125
126static void
127_eapi_func_generate(const char *classname, Eolian_Function funcid, Eolian_Function_Type ftype, Eina_Strbuf *buf)
128{
129 //TODO return value
130 const char *suffix = "";
131 const char *umpr = NULL;
132 const char *func_lpref = NULL;
133 Eina_Bool var_as_ret = EINA_FALSE;
134 const char *rettype = NULL;
135 const char *retname = NULL;
136 Eina_Bool ret_const = EINA_FALSE;
137
138 rettype = eolian_function_return_type_get(funcid, ftype);
139 if (rettype && !strcmp(rettype, "void")) rettype = NULL;
140 retname = "ret";
141 if (ftype == GET)
142 {
143 suffix = "_get";
144 umpr = "*";
145 func_lpref = eolian_function_data_get(funcid, EOLIAN_LEGACY_GET);
146 if (!rettype)
147 {
148 const Eina_List *l = eolian_parameters_list_get(funcid);
149 if (eina_list_count(l) == 1)
150 {
151 void* data = eina_list_data_get(l);
152 eolian_parameter_information_get((Eolian_Function_Parameter)data, NULL, &rettype, &retname, NULL);
153 var_as_ret = EINA_TRUE;
154 ret_const = eolian_parameter_get_const_attribute_get(data);
155 }
156 }
157 }
158 if (ftype == SET)
159 {
160 suffix = "_set";
161 umpr = "";
162 func_lpref = eolian_function_data_get(funcid, EOLIAN_LEGACY_SET);
163 }
164
165 func_lpref = (func_lpref) ? func_lpref : eolian_function_data_get(funcid, EOLIAN_LEGACY);
166 func_lpref = (func_lpref) ? func_lpref : eolian_class_legacy_prefix_get(classname);
167
168 Eina_Strbuf *fbody = eina_strbuf_new();
169 Eina_Strbuf *fparam = eina_strbuf_new();
170 Eina_Strbuf *eoparam = eina_strbuf_new();
171
172 char tmpstr[0xFF];
173 sprintf (tmpstr, "%s%s", eolian_function_name_get(funcid), suffix);
174 _template_fill(fbody, tmpl_eapi_body, classname, tmpstr, EINA_FALSE);
175
176 if (!func_lpref)
177 {
178 strcpy(tmpstr, classname);
179 char *p = tmpstr;
180 eina_str_tolower(&p);
181 func_lpref = tmpstr;
182 }
183 eina_strbuf_replace_all(fbody, "@#eapi_prefix", func_lpref);
184
185 const Eina_List *l;
186 void *data;
187
188 tmpstr[0] = '\0';
189
190 if (!var_as_ret)
191 {
192 EINA_LIST_FOREACH(eolian_parameters_list_get(funcid), l, data)
193 {
194 const char *pname;
195 const char *ptype;
196 Eolian_Parameter_Dir pdir;
197 eolian_parameter_information_get((Eolian_Function_Parameter)data, &pdir, &ptype, &pname, NULL);
198 const char *ptrstr = (umpr) ? umpr : ( (pdir == EOLIAN_IN_PARAM) ? "" : "*" );
199 eina_strbuf_append_printf(fparam, ", %s%s%s %s",
200 ftype == GET && eolian_parameter_get_const_attribute_get(data)?"const ":"",
201 ptype, ptrstr, pname);
202 if (eina_strbuf_length_get(eoparam)) eina_strbuf_append(eoparam, ", ");
203 eina_strbuf_append_printf(eoparam, "%s", pname);
204 }
205 }
206
207 char tmp_ret_str[0xFF];
208 sprintf (tmp_ret_str, "%s%s", ret_const?"const ":"", rettype?rettype:"void");
209 if (rettype && strcmp(rettype, "void"))
210 {
211 if (eina_strbuf_length_get(eoparam)) eina_strbuf_append(eoparam, ", ");
212 sprintf (tmpstr, " %s%s %s;\n", ret_const?"const ":"", rettype, retname);
213 eina_strbuf_append_printf(eoparam, "&%s", retname);
214 }
215
216 eina_strbuf_replace_all(fbody, "@#full_params", eina_strbuf_string_get(fparam));
217 eina_strbuf_replace_all(fbody, "@#eo_params", eina_strbuf_string_get(eoparam));
218 eina_strbuf_replace_all(fbody, "@#ret_type", tmp_ret_str);
219 eina_strbuf_replace_all(fbody, "@#ret_init_val", tmpstr);
220 eina_strbuf_replace_all(fbody, "@#ret_val", (rettype) ? retname : "");
221 eina_strbuf_replace_all(fbody, "@#is_const", (ftype == GET || eolian_function_object_is_const(funcid)) ? "const " : "");
222
223 tmpstr[0] = '\0';
224 if (rettype) sprintf (tmpstr, "(%s)(0)", rettype);
225 eina_strbuf_replace_all(fbody, "@#check_ret", tmpstr);
226
227 eina_strbuf_append(buf, eina_strbuf_string_get(fbody));
228
229 eina_strbuf_free(fbody);
230 eina_strbuf_free(fparam);
231 eina_strbuf_free(eoparam);
232}
233
234//TODO change replacement
235static char*
236_class_h_find(const char *classname, Eina_Strbuf *buf)
237{
238 Eina_Strbuf *classreal = eina_strbuf_new();
239 _template_fill(classreal, "@#OBJCLASS_CLASS", classname, "", EINA_FALSE);
240 char *ret = strstr(eina_strbuf_string_get(buf), eina_strbuf_string_get(classreal));
241 eina_strbuf_free(classreal);
242
243 return ret;
244}
245
246Eina_Bool
247legacy_header_generate(const char *classname, int eo_version, Eina_Strbuf *buf)
248{
249 const Eolian_Function_Type ftype_order[] = {PROPERTY_FUNC, METHOD_FUNC};
250 const Eina_List *l;
251 void *data;
252
253 if (!eolian_class_exists(classname))
254 {
255 printf ("Class \"%s\" not found in database\n", classname);
256 return EINA_FALSE;
257 }
258
259 int i;
260 for (i = 0; i < 2; i++)
261 EINA_LIST_FOREACH(eolian_class_functions_list_get(classname, ftype_order[i]), l, data)
262 {
263 const Eolian_Function_Type ftype = eolian_function_type_get((Eolian_Function)data);
264 Eina_Bool prop_read = (ftype == PROPERTY_FUNC || ftype == GET ) ? EINA_TRUE : EINA_FALSE ;
265 Eina_Bool prop_write = (ftype == PROPERTY_FUNC || ftype == SET ) ? EINA_TRUE : EINA_FALSE ;
266
267 if (!prop_read && !prop_write)
268 {
269 _eapi_decl_func_generate(classname, (Eolian_Function)data, UNRESOLVED, buf);
270 }
271 if (prop_read)
272 {
273 _eapi_decl_func_generate(classname, (Eolian_Function)data, GET, buf);
274 }
275 if (prop_write)
276 {
277 _eapi_decl_func_generate(classname, (Eolian_Function)data, SET, buf);
278 }
279 }
280 return EINA_TRUE;
281}
282
283static char*
284_nextline(char *str, unsigned int lines)
285{
286 if (!str) return NULL;
287
288 char *ret = str;
289 while ((lines--) && *ret)
290 {
291 ret= strchr(ret, '\n');
292 if (ret) ret++;
293 }
294 return ret;
295}
296
297static char*
298_startline(char *str, char *pos)
299{
300 if (!str || !pos) return NULL;
301
302 char *ret = pos;
303 while ((ret > str) && (*(ret-1)!='\n')) ret--;
304
305 return ret;
306}
307
308Eina_Bool
309legacy_header_append(const char *classname, int eo_version, Eina_Strbuf *header)
310{
311 const Eolian_Function_Type ftype_order[] = {CONSTRUCTOR, PROPERTY_FUNC, METHOD_FUNC};
312 char tmpstr[0xFF];
313
314 if (!eolian_class_exists(classname))
315 {
316 printf ("Class \"%s\" not found in database\n", classname);
317 return EINA_FALSE;
318 }
319
320 char *clsptr = _class_h_find(classname, header);
321
322 if (!clsptr)
323 {
324 printf ("Class %s not found - append all\n", classname);
325 eina_strbuf_append_char(header, '\n');
326 eo1_header_generate(classname, header);
327 return EINA_TRUE;
328 }
329
330 printf ("Class %s found - searching for functions...\n", classname);
331
332 char *funcdef_pos = _nextline(strstr(clsptr, "+ sub_id)"), 1);
333 char *subid_pos = _startline(clsptr, strstr(clsptr, "SUB_ID_LAST"));
334
335 if (!(funcdef_pos && subid_pos) || (subid_pos > funcdef_pos))
336 {
337 printf ("Bad insertion queues - update aborted\n");
338 return EINA_FALSE;
339 }
340
341 Eina_Strbuf *str_subid = eina_strbuf_new();
342 Eina_Strbuf *str_funcdef = eina_strbuf_new();
343
344 const Eina_List *l;
345 void *data;
346
347 int i;
348 for (i = 0; i < 3; i++)
349 EINA_LIST_FOREACH(eolian_class_functions_list_get(classname, ftype_order[i]), l, data)
350 {
351 const Eolian_Function_Type ftype = eolian_function_type_get((Eolian_Function)data);
352 const char *funcname = eolian_function_name_get((Eolian_Function)data);
353 Eina_Bool prop_read = (ftype == PROPERTY_FUNC || ftype == GET ) ? EINA_TRUE : EINA_FALSE ;
354 Eina_Bool prop_write = (ftype == PROPERTY_FUNC || ftype == SET ) ? EINA_TRUE : EINA_FALSE ;
355
356 if (!prop_read && !prop_write)
357 {
358 if (!strstr(eina_strbuf_string_get(header), funcname))
359 {
360 printf ("Appending eo function %s\n", funcname);
361 eo1_enum_append(classname, funcname, str_subid);
362 eo1_fundef_generate(classname, (Eolian_Function)data, UNRESOLVED, str_funcdef);
363 }
364 }
365 if (prop_read)
366 {
367 sprintf(tmpstr, "%s_get", funcname);
368 if (!strstr(eina_strbuf_string_get(header), tmpstr))
369 {
370 printf ("Appending eo function %s\n", tmpstr);
371 eo1_enum_append(classname, tmpstr, str_subid);
372 eo1_fundef_generate(classname, (Eolian_Function)data, GET, str_funcdef);
373 }
374 }
375 if (prop_write)
376 {
377 sprintf(tmpstr, "%s_set", funcname);
378 if (!strstr(eina_strbuf_string_get(header), tmpstr))
379 {
380 printf ("Appending eo function %s\n", tmpstr);
381 eo1_enum_append(classname, tmpstr, str_subid);
382 eo1_fundef_generate(classname, (Eolian_Function)data, SET, str_funcdef);
383 }
384 }
385 }
386
387 const char *hdstr = eina_strbuf_string_get(header);
388 unsigned enum_offs = subid_pos - hdstr;
389 unsigned defs_offs = funcdef_pos - hdstr + eina_strbuf_length_get(str_subid);
390 eina_strbuf_insert(header, eina_strbuf_string_get(str_subid), enum_offs);
391 eina_strbuf_insert(header, eina_strbuf_string_get(str_funcdef), defs_offs);
392
393 eina_strbuf_free(str_subid);
394 eina_strbuf_free(str_funcdef);
395
396 return EINA_TRUE;
397}
398
399Eina_Bool
400legacy_source_generate(const char *classname, int eo_version, Eina_Strbuf *buf)
401{
402 const Eina_List *itr;
403
404 if (!eolian_class_exists(classname))
405 {
406 printf ("Class \"%s\" not found in database\n", classname);
407 return EINA_FALSE;
408 }
409
410 Eina_Strbuf *tmpbuf = eina_strbuf_new();
411 Eina_Strbuf *str_bodyf = eina_strbuf_new();
412
413 eo1_source_beginning_generate(classname, buf);
414
415 //Properties
416 Eolian_Function fn;
417 EINA_LIST_FOREACH(eolian_class_functions_list_get(classname, PROPERTY_FUNC), itr, fn)
418 {
419 const Eolian_Function_Type ftype = eolian_function_type_get(fn);
420
421 Eina_Bool prop_read = ( ftype == SET ) ? EINA_FALSE : EINA_TRUE;
422 Eina_Bool prop_write = ( ftype == GET ) ? EINA_FALSE : EINA_TRUE;
423
424 if (prop_read)
425 {
426 eo1_bind_func_generate(classname, fn, GET, str_bodyf);
427 _eapi_func_generate(classname, fn, GET, str_bodyf);
428 }
429 if (prop_write)
430 {
431 eo1_bind_func_generate(classname, fn, SET, str_bodyf);
432 _eapi_func_generate(classname, fn, SET, str_bodyf);
433 }
434 }
435
436 //Methods
437 EINA_LIST_FOREACH(eolian_class_functions_list_get(classname, METHOD_FUNC), itr, fn)
438 {
439 eo1_bind_func_generate(classname, fn, UNRESOLVED, str_bodyf);
440 _eapi_func_generate(classname, fn, UNRESOLVED, str_bodyf);
441 }
442
443 eina_strbuf_append(buf, eina_strbuf_string_get(str_bodyf));
444
445 eo1_source_end_generate(classname, buf);
446
447 eina_strbuf_free(tmpbuf);
448 eina_strbuf_free(str_bodyf);
449
450 return EINA_TRUE;
451}
452
diff --git a/src/bin/eolian/legacy_generator.h b/src/bin/eolian/legacy_generator.h
new file mode 100644
index 0000000000..5f22afa811
--- /dev/null
+++ b/src/bin/eolian/legacy_generator.h
@@ -0,0 +1,53 @@
1#ifndef __EOLIAN_LEGACY_GENERATOR_H
2#define __EOLIAN_LEGACY_GENERATOR_H
3
4#include <Eina.h>
5
6/*
7 * @brief Generate legacy EAPI header for Eo class
8 *
9 * This function needs to be used in case we want to generate a function
10 * from scratch.
11 * There will not be respect of the order of the Eo Op Ids.
12 *
13 * @param[in] classname class name
14 * @param[in] eo_version Eo version to generate
15 * @param[inout] buf buffer to fill
16 *
17 * @return EINA_TRUE on success, EINA_FALSE on error.
18 *
19 */
20Eina_Bool legacy_header_generate(const char *classname, int eo_version, Eina_Strbuf *buf);
21
22/*
23 * @brief Append legacy EAPI header for Eo class
24 *
25 * This function needs to be used in case we want to add new functions
26 * to an existing class.
27 *
28 * @param[in] classname class name
29 * @param[in] eo_version Eo version to generate
30 * @param[inout] buf buffer to fill
31 *
32 * @return EINA_TRUE on success, EINA_FALSE on error.
33 *
34 */
35Eina_Bool legacy_header_append(const char *classname, int eo_version, Eina_Strbuf *buf);
36
37/*
38 * @brief Generate C source code for Eo class
39 *
40 * This function needs to be used to generate C source code. It is generating
41 * code from scratch.
42 *
43 * @param[in] classname class name
44 * @param[in] eo_version Eo version to generate
45 * @param[inout] buf buffer to fill
46 *
47 * @return EINA_TRUE on success, EINA_FALSE on error.
48 *
49 */
50Eina_Bool legacy_source_generate(const char *classname, int eo_version, Eina_Strbuf *buf);
51
52#endif
53
diff --git a/src/bin/eolian/main.c b/src/bin/eolian/main.c
new file mode 100644
index 0000000000..c47376de6e
--- /dev/null
+++ b/src/bin/eolian/main.c
@@ -0,0 +1,334 @@
1#include <Eina.h>
2#include <Ecore_File.h>
3
4#include "Eolian.h"
5#include "legacy_generator.h"
6#include "eo1_generator.h"
7
8#define EO_SUFFIX ".eo"
9
10static int eo_version = 0;
11
12static Eina_Bool
13_generate_h_file(char *filename, char *classname, Eina_Bool append)
14{
15 Eina_Bool ret = EINA_FALSE;
16 Eina_Strbuf *hfile = eina_strbuf_new();
17 if (append)
18 {
19 Eina_File *fn = eina_file_open(filename, EINA_FALSE);
20 if (!fn)
21 {
22 printf ("Cant open file \"%s\" for updating.\n", filename);
23 goto end;
24 }
25
26 eina_strbuf_append(hfile, (char*)eina_file_map_all(fn, EINA_FILE_SEQUENTIAL));
27 eina_file_close(fn);
28
29 legacy_header_append(classname, eo_version, hfile);
30 }
31 else
32 {
33 eo1_header_generate(classname, hfile);
34 }
35 const char *htext = eina_strbuf_string_get(hfile);
36
37 FILE* fd = fopen(filename, "w");
38 if (!fd)
39 {
40 printf ("Couldn't open file %s for writing\n", filename);
41 goto end;
42 }
43 if (htext) fputs(htext, fd);
44 fclose(fd);
45
46 ret = EINA_TRUE;
47end:
48 eina_strbuf_free(hfile);
49
50 return ret;
51}
52
53static Eina_Bool
54_generate_c_file(char *filename, char *classname, Eina_Bool append)
55{
56 Eina_Bool ret = EINA_FALSE;
57
58 Eina_Strbuf *cfile = eina_strbuf_new();
59 legacy_source_generate(classname, eo_version, cfile);
60
61 FILE* fd = fopen(filename, (append) ? "a" : "w");
62 if (!fd)
63 {
64 printf ("Couldnt open file %s for writing\n", filename);
65 goto end;
66 }
67 const char *ctext = eina_strbuf_string_get(cfile);
68 if (ctext) fputs(ctext, fd);
69 fclose(fd);
70
71 ret = EINA_TRUE;
72end:
73 eina_strbuf_free(cfile);
74 return ret;
75}
76
77// TODO join with header gen.
78static Eina_Bool
79_generate_legacy_header_file(char *filename, char *classname, Eina_Bool append)
80{
81 Eina_Bool ret = EINA_FALSE;
82
83 Eina_Strbuf *lfile = eina_strbuf_new();
84
85 if (append)
86 {
87 Eina_File *fn = eina_file_open(filename, EINA_FALSE);
88 if (!fn)
89 {
90 printf ("Cant open file \"%s\" for updating.\n", filename);
91 goto end;
92 }
93 eina_strbuf_append(lfile, (char*)eina_file_map_all(fn, EINA_FILE_SEQUENTIAL));
94 eina_file_close(fn);
95
96 legacy_header_append(classname, eo_version, lfile);
97 }
98 else
99 {
100 legacy_header_generate(classname, eo_version, lfile);
101 }
102
103 FILE* fd = fopen(filename, "w");
104 if (!fd)
105 {
106 printf ("Couldnt open file %s for writing\n", filename);
107 goto end;
108 }
109 const char *ltext = eina_strbuf_string_get(lfile);
110 if (ltext) fputs(ltext, fd);
111 fclose(fd);
112
113 ret = EINA_TRUE;
114end:
115 eina_strbuf_free(lfile);
116 return ret;
117}
118
119static Eina_Bool
120_generate_eo_and_legacy_h_file(char *filename, char *classname)
121{
122 Eina_Bool ret = EINA_FALSE;
123
124 Eina_Strbuf *hfile = eina_strbuf_new();
125
126 FILE* fd = fopen(filename, "w");
127 if (!fd)
128 {
129 printf ("Couldnt open file %s for writing\n", filename);
130 goto end;
131 }
132
133 eo1_header_generate(classname, hfile);
134 legacy_header_generate(classname, eo_version, hfile);
135 const char *htext = eina_strbuf_string_get(hfile);
136 if (htext) fputs(htext, fd);
137
138 fclose(fd);
139
140 ret = EINA_TRUE;
141end:
142 eina_strbuf_free(hfile);
143 return ret;
144}
145
146int main(int argc, char **argv)
147{
148 eina_init();
149 int i, ret = 0;
150 Eina_Bool help = EINA_FALSE, show = EINA_FALSE;
151 Eina_List *files = NULL, *itr;
152 Eina_List *classes = NULL;
153 char *h_filename = NULL, *c_filename = NULL,
154 *classname = NULL, *leg_filename = NULL,
155 *eoleg_filename = NULL;
156
157 Eina_Bool happend = EINA_FALSE;
158 Eina_Bool lappend = EINA_FALSE;
159
160 for(i = 1; i < argc; i++)
161 {
162 if (!strcmp(argv[i], "-eo1"))
163 {
164 eo_version = 1;
165 continue;
166 }
167 if (!strcmp(argv[i], "-eo2"))
168 {
169 eo_version = 2;
170 continue;
171 }
172 if (!strcmp(argv[i], "-gh") && (i < (argc-1)))
173 {
174 h_filename = argv[i + 1];
175 continue;
176 }
177 if (!strcmp(argv[i], "-gc") && (i < (argc-1)))
178 {
179 c_filename = argv[i + 1];
180 continue;
181 }
182 if (!strcmp(argv[i], "-gl") && (i < (argc-1)))
183 {
184 leg_filename = argv[i + 1];
185 continue;
186 }
187 if (!strcmp(argv[i], "-gle") && (i < (argc-1)))
188 {
189 eoleg_filename = argv[i + 1];
190 continue;
191 }
192 if (!strcmp(argv[i], "-ah") && (i < (argc-1)))
193 {
194 h_filename = argv[i + 1];
195 happend = EINA_TRUE;
196 continue;
197 }
198 if (!strcmp(argv[i], "-al") && (i < (argc-1)))
199 {
200 leg_filename = argv[i + 1];
201 lappend = EINA_TRUE;
202 continue;
203 }
204 if (!strcmp(argv[i], "--class") && (i < (argc-1)))
205 {
206 classes = eina_list_append(classes, argv[i + 1]);
207 continue;
208 }
209 if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help"))
210 {
211 help = EINA_TRUE;
212 continue;
213 }
214 if (!strcmp(argv[i], "--show"))
215 {
216 show = EINA_TRUE;
217 continue;
218 }
219 /* Directory parameter found. */
220 if ((!strcmp(argv[i], "-d") || !strcmp(argv[i], "--dir")) && (i < (argc-1)))
221 {
222 i++;
223 char *dir = ecore_file_realpath(argv[i]);
224 if (strlen(dir) != 0)
225 {
226 if (ecore_file_is_dir(dir))
227 {
228 Eina_List *dir_files;
229 char *file;
230 /* Get all files from directory. Not recursively!!!*/
231 dir_files = ecore_file_ls(dir);
232 EINA_LIST_FREE(dir_files, file)
233 {
234 char *filepath = malloc(strlen(dir) + 1 + strlen(file) + 1);
235 sprintf(filepath, "%s/%s", dir, file);
236 if ((!ecore_file_is_dir(filepath)) && eina_str_has_suffix(filepath, EO_SUFFIX))
237 {
238 /* Allocated string will be freed during deletion of "files" list. */
239 files = eina_list_append(files, strdup(filepath));
240 }
241 free(filepath);
242 free(file);
243 }
244 }
245 }
246 free(dir);
247 continue;
248 }
249 if ((!strcmp(argv[i], "-f") || !strcmp(argv[i], "--file")) && (i < (argc-1)))
250 {
251 i++;
252 char *realpath = ecore_file_realpath(argv[i]);
253 if (strlen(realpath) != 0)
254 {
255 if (!ecore_file_is_dir(realpath))
256 {
257 if (eina_str_has_suffix(realpath, EO_SUFFIX))
258 files = eina_list_append(files, strdup(realpath));
259 }
260 }
261 free(realpath);
262 continue;
263 }
264 }
265
266 if (eina_list_count(classes)) classname = eina_list_data_get(classes);
267
268 if (!files || help || !classname)
269 {
270 printf("Usage: %s [-h/--help] [--show] [-d/--dir input_dir] [-f/--file input_file] [-gh|-gc|-ah] filename [--class] classname \n", argv[0]);
271 printf(" -eo1/-eo2 Set generator to eo1/eo2 mode. Must be specified\n");
272 printf(" -gh Generate c header file [.h] for eo class specified by classname\n");
273 printf(" -gc Generate c source file [.c] for eo class specified by classname\n");
274 printf(" -ah Append eo class definitions to an existing c header file [.h]\n");
275 printf(" -al Append legacy function definitions to an existing c header file [.h]\n");
276 printf(" -gle Generate eo and legacy file [.h]\n");
277 return 0;
278 }
279
280 eolian_init();
281 const char *filename;
282 EINA_LIST_FOREACH(files, itr, filename)
283 {
284 if (!eolian_eo_file_parse(filename))
285 {
286 printf("Error during parsing file %s\n", filename);
287 goto end;
288 }
289 }
290
291 if (show) eolian_show(classname);
292
293 if (!eo_version)
294 {
295 printf("No eo version specified (use -eo1 or -eo2). Aborting eo generation.\n");
296 ret = 1;
297 goto end;
298 }
299
300 if (h_filename)
301 {
302 printf("%s header file %s\n", (happend) ? "Appending" : "Generating", h_filename);
303 _generate_h_file(h_filename, classname, happend);
304 }
305
306 if (c_filename)
307 {
308 printf("Generating source file %s\n", c_filename);
309 Eina_List *l = NULL;
310 char *cname = NULL;
311 EINA_LIST_FOREACH(classes,l,cname)
312 _generate_c_file(c_filename, cname, (classes != l));
313 }
314
315 if (leg_filename)
316 {
317 printf("%s legacy file %s\n", (lappend) ? "Appending" : "Generating", leg_filename);
318 _generate_legacy_header_file(leg_filename, classname, lappend);
319 }
320
321 if (eoleg_filename)
322 {
323 printf("Generating eo and legacy header file %s\n", eoleg_filename);
324 _generate_eo_and_legacy_h_file(eoleg_filename, classname);
325 }
326
327end:
328 EINA_LIST_FREE(files, filename)
329 free((char *)filename);
330 eina_list_free(classes);
331 eolian_shutdown();
332 eina_shutdown();
333 return ret;
334}