summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kolesa <d.kolesa@osg.samsung.com>2016-10-07 13:26:08 +0200
committerDaniel Kolesa <d.kolesa@osg.samsung.com>2016-10-07 13:26:08 +0200
commit4cc17ae28a960b8b009a0063fa34d74f9c8a006b (patch)
tree034c4f41ac2598b84a5a1184e62fabaa30e32660
parent82291e9cf557bac6c6b1e63edca2b37a7ade380b (diff)
eolian gen2: remove old eolian gen
-rw-r--r--src/Makefile_Eolian.am24
-rw-r--r--src/bin/eolian/.gitignore1
-rw-r--r--src/bin/eolian/common_funcs.c141
-rw-r--r--src/bin/eolian/common_funcs.h68
-rw-r--r--src/bin/eolian/docs_generator.c666
-rw-r--r--src/bin/eolian/docs_generator.h45
-rw-r--r--src/bin/eolian/eo_generator.c1047
-rw-r--r--src/bin/eolian/eo_generator.h34
-rw-r--r--src/bin/eolian/impl_generator.c324
-rw-r--r--src/bin/eolian/impl_generator.h22
-rw-r--r--src/bin/eolian/legacy_generator.c416
-rw-r--r--src/bin/eolian/legacy_generator.h36
-rw-r--r--src/bin/eolian/main.c407
-rw-r--r--src/bin/eolian/types_generator.c225
-rw-r--r--src/bin/eolian/types_generator.h22
15 files changed, 0 insertions, 3478 deletions
diff --git a/src/Makefile_Eolian.am b/src/Makefile_Eolian.am
index e5b3fa4f38..9fc82c63c2 100644
--- a/src/Makefile_Eolian.am
+++ b/src/Makefile_Eolian.am
@@ -45,30 +45,6 @@ lib_eolian_libeolian_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@
45### Binary 45### Binary
46 46
47bin_PROGRAMS += \ 47bin_PROGRAMS += \
48 bin/eolian/eolian_gen
49
50bin_eolian_eolian_gen_SOURCES = \
51 bin/eolian/common_funcs.c \
52 bin/eolian/common_funcs.h \
53 bin/eolian/eo_generator.c \
54 bin/eolian/eo_generator.h \
55 bin/eolian/impl_generator.c \
56 bin/eolian/impl_generator.h \
57 bin/eolian/legacy_generator.c \
58 bin/eolian/legacy_generator.h \
59 bin/eolian/types_generator.c \
60 bin/eolian/types_generator.h \
61 bin/eolian/docs_generator.c \
62 bin/eolian/docs_generator.h \
63 bin/eolian/main.c
64
65bin_eolian_eolian_gen_CPPFLAGS = -I$(top_builddir)/src/lib/efl @EOLIAN_CFLAGS@
66bin_eolian_eolian_gen_LDADD = @USE_EOLIAN_LIBS@
67bin_eolian_eolian_gen_DEPENDENCIES = @USE_EOLIAN_INTERNAL_LIBS@
68
69### New generator
70
71bin_PROGRAMS += \
72 bin/eolian2/eolian_gen2 48 bin/eolian2/eolian_gen2
73 49
74bin_eolian2_eolian_gen2_SOURCES = \ 50bin_eolian2_eolian_gen2_SOURCES = \
diff --git a/src/bin/eolian/.gitignore b/src/bin/eolian/.gitignore
deleted file mode 100644
index 4757034e1b..0000000000
--- a/src/bin/eolian/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
1/eolian_gen
diff --git a/src/bin/eolian/common_funcs.c b/src/bin/eolian/common_funcs.c
deleted file mode 100644
index 87aae20c80..0000000000
--- a/src/bin/eolian/common_funcs.c
+++ /dev/null
@@ -1,141 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include "common_funcs.h"
6#include "Eolian.h"
7
8int _eolian_gen_log_dom = -1;
9
10Eolian_Class *current_class;
11
12static void
13_class_name_concatenate(const Eolian_Class *class, char *buffer)
14{
15 Eina_Iterator *itr = eolian_class_namespaces_get(class);
16 const char *name;
17 buffer[0] = '\0';
18 EINA_ITERATOR_FOREACH(itr, name)
19 {
20 sprintf(buffer, "%s_", name);
21 buffer += (strlen(name) + 1);
22 }
23 sprintf(buffer, "%s", eolian_class_name_get(class));
24 eina_iterator_free(itr);
25}
26
27static char *
28_fill_envs(char *dest, const char *src, size_t bufs) {
29 strncpy(dest, src, bufs - 1);
30 dest[bufs - 1] = '\0';
31 return dest;
32}
33
34void
35_class_env_create(const Eolian_Class *class, const char *over_classname, _eolian_class_vars *env)
36{
37 if (!env) return;
38
39 const char *eo_prefix = NULL;
40 char *p;
41
42 if (!class)
43 _fill_envs(env->full_classname, over_classname, sizeof(env->full_classname));
44 else
45 _class_name_concatenate(class, env->full_classname);
46
47 /* class/CLASS*/
48 p = _fill_envs(env->upper_classname, env->full_classname, sizeof(env->upper_classname));
49 eina_str_toupper(&p);
50 p = _fill_envs(env->lower_classname, env->full_classname, sizeof(env->lower_classname));
51 eina_str_tolower(&p);
52
53 /* eo_prefix */
54 if (class) eo_prefix = eolian_class_eo_prefix_get(class);
55 if (!eo_prefix) eo_prefix = env->full_classname;
56 p = _fill_envs(env->upper_eo_prefix, eo_prefix, sizeof(env->upper_eo_prefix));
57 eina_str_toupper(&p);
58 p = _fill_envs(env->lower_eo_prefix, eo_prefix, sizeof(env->lower_eo_prefix));
59 eina_str_tolower(&p);
60
61 /* classtype */
62 if (class) switch (eolian_class_type_get(class))
63 {
64 case EOLIAN_CLASS_REGULAR:
65 case EOLIAN_CLASS_ABSTRACT:
66 strcpy(env->lower_classtype, "class");
67 strcpy(env->upper_classtype, "CLASS");
68 break;
69 case EOLIAN_CLASS_MIXIN:
70 strcpy(env->lower_classtype, "mixin");
71 strcpy(env->upper_classtype, "MIXIN");
72 break;
73 case EOLIAN_CLASS_INTERFACE:
74 strcpy(env->lower_classtype, "interface");
75 strcpy(env->upper_classtype, "INTERFACE");
76 break;
77 default:
78 break;
79 }
80}
81
82void
83_class_func_env_create(const Eolian_Class *class, const char *funcname, Eolian_Function_Type ftype, _eolian_class_func_vars *env)
84{
85 char *p;
86 const Eolian_Function *funcid = eolian_class_function_get_by_name(class, funcname, ftype);
87
88 p = _fill_envs(env->upper_func, funcname, sizeof(env->upper_func));
89 eina_str_toupper(&p);
90
91 Eolian_Function_Type aftype = ftype;
92 if (aftype == EOLIAN_PROPERTY) aftype = EOLIAN_METHOD;
93
94 Eina_Stringshare *fname = eolian_function_full_c_name_get(funcid, aftype, EINA_FALSE);
95 p = _fill_envs(env->upper_eo_func, fname, sizeof(env->upper_eo_func));
96 eina_str_toupper(&p);
97 p = _fill_envs(env->lower_eo_func, fname, sizeof(env->lower_eo_func));
98 eina_str_tolower(&p);
99 eina_stringshare_del(fname);
100
101 Eina_Stringshare *lname = eolian_function_full_c_name_get(funcid, aftype, EINA_TRUE);
102 env->legacy_func[0] = '\0';
103 if (!lname) return;
104 p = _fill_envs(env->legacy_func, lname, sizeof(env->legacy_func));
105 eina_stringshare_del(lname);
106}
107
108void
109_template_fill(Eina_Strbuf *buf, const char *templ, const Eolian_Class *class, const char *classname, const char *funcname, Eina_Bool reset)
110{
111 _eolian_class_vars tmp_env;
112 _eolian_class_func_vars tmp_func_env;
113 _class_env_create(class, classname, &tmp_env);
114 if (funcname)
115 _class_func_env_create(class, funcname, EOLIAN_UNRESOLVED, &tmp_func_env);
116 if (buf)
117 {
118 if (reset) eina_strbuf_reset(buf);
119 if (templ) eina_strbuf_append(buf, templ);
120 if (funcname)
121 {
122 eina_strbuf_replace_all(buf, "@#func", funcname);
123 eina_strbuf_replace_all(buf, "@#FUNC", tmp_func_env.upper_func);
124 }
125 eina_strbuf_replace_all(buf, "@#classtype", tmp_env.lower_classtype);
126 eina_strbuf_replace_all(buf, "@#CLASSTYPE", tmp_env.upper_classtype);
127 eina_strbuf_replace_all(buf, "@#Class", tmp_env.full_classname);
128 eina_strbuf_replace_all(buf, "@#class", tmp_env.lower_classname);
129 eina_strbuf_replace_all(buf, "@#CLASS", tmp_env.upper_classname);
130 }
131}
132
133const char *
134_get_add_star(Eolian_Function_Type ftype, Eolian_Parameter_Dir pdir)
135{
136 if (ftype == EOLIAN_PROP_GET)
137 return "*";
138 if ((pdir == EOLIAN_OUT_PARAM) || (pdir == EOLIAN_INOUT_PARAM))
139 return "*";
140 return "";
141}
diff --git a/src/bin/eolian/common_funcs.h b/src/bin/eolian/common_funcs.h
deleted file mode 100644
index b23515fd38..0000000000
--- a/src/bin/eolian/common_funcs.h
+++ /dev/null
@@ -1,68 +0,0 @@
1#ifndef __EOLIAN_COMMON_FUNCS_H
2#define __EOLIAN_COMMON_FUNCS_H
3
4#include <Eina.h>
5#include <Eolian.h>
6
7#define EO
8
9extern int _eolian_gen_log_dom;
10
11#ifdef ERR
12# undef ERR
13#endif
14#define ERR(...) EINA_LOG_DOM_ERR(_eolian_gen_log_dom, __VA_ARGS__)
15
16#ifdef DBG
17# undef DBG
18#endif
19#define DBG(...) EINA_LOG_DOM_DBG(_eolian_gen_log_dom, __VA_ARGS__)
20
21#ifdef INF
22# undef INF
23#endif
24#define INF(...) EINA_LOG_DOM_INFO(_eolian_gen_log_dom, __VA_ARGS__)
25
26#ifdef WRN
27# undef WRN
28#endif
29#define WRN(...) EINA_LOG_DOM_WARN(_eolian_gen_log_dom, __VA_ARGS__)
30
31#ifdef CRIT
32# undef CRIT
33#endif
34#define CRIT(...) EINA_LOG_DOM_CRIT(_eolian_gen_log_dom, __VA_ARGS__)
35
36typedef struct
37{
38 char full_classname[PATH_MAX];
39
40 char upper_eo_prefix[PATH_MAX];
41 char lower_eo_prefix[PATH_MAX];
42
43 char upper_classname[PATH_MAX];
44 char lower_classname[PATH_MAX];
45
46 char upper_classtype[PATH_MAX];
47 char lower_classtype[PATH_MAX];
48}_eolian_class_vars;
49
50typedef struct
51{
52 char upper_func[PATH_MAX];
53
54 char upper_eo_func[PATH_MAX];
55 char lower_eo_func[PATH_MAX];
56
57 char legacy_func[PATH_MAX];
58}_eolian_class_func_vars;
59
60void _template_fill(Eina_Strbuf *buf, const char *templ, const Eolian_Class *class, const char *classname, const char *funcname, Eina_Bool reset);
61
62void _class_env_create(const Eolian_Class *class, const char *over_classname, _eolian_class_vars *env);
63
64void _class_func_env_create(const Eolian_Class *class, const char *funcname, Eolian_Function_Type ftype EINA_UNUSED, _eolian_class_func_vars *env);
65
66const char *_get_add_star(Eolian_Function_Type ftype, Eolian_Parameter_Dir pdir);
67
68#endif
diff --git a/src/bin/eolian/docs_generator.c b/src/bin/eolian/docs_generator.c
deleted file mode 100644
index 0ee01a69ac..0000000000
--- a/src/bin/eolian/docs_generator.c
+++ /dev/null
@@ -1,666 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <ctype.h>
6
7#include "docs_generator.h"
8
9static int
10_indent_line(Eina_Strbuf *buf, int ind)
11{
12 int i;
13 for (i = 0; i < ind; ++i)
14 eina_strbuf_append_char(buf, ' ');
15 return ind;
16}
17
18#define DOC_LINE_LIMIT 79
19#define DOC_LINE_TEST 59
20#define DOC_LINE_OVER 39
21
22#define DOC_LIMIT(ind) ((ind > DOC_LINE_TEST) ? (ind + DOC_LINE_OVER) \
23 : DOC_LINE_LIMIT)
24
25static void
26_generate_ref(const char *refn, Eina_Strbuf *wbuf, Eina_Bool use_legacy)
27{
28 const Eolian_Declaration *decl = eolian_declaration_get_by_name(refn);
29 if (decl)
30 {
31 char *n = strdup(eolian_declaration_name_get(decl));
32 char *p = n;
33 while ((p = strchr(p, '.'))) *p = '_';
34 eina_strbuf_append(wbuf, n);
35 free(n);
36 return;
37 }
38
39 /* not a plain declaration, so it must be struct/enum field or func */
40 const char *sfx = strrchr(refn, '.');
41 if (!sfx) goto noref;
42
43 Eina_Stringshare *bname = eina_stringshare_add_length(refn, sfx - refn);
44
45 const Eolian_Typedecl *tp = eolian_typedecl_struct_get_by_name(bname);
46 if (tp)
47 {
48 if (!eolian_typedecl_struct_field_get(tp, sfx + 1))
49 {
50 eina_stringshare_del(bname);
51 goto noref;
52 }
53 _generate_ref(bname, wbuf, use_legacy);
54 eina_strbuf_append(wbuf, sfx);
55 eina_stringshare_del(bname);
56 return;
57 }
58
59 tp = eolian_typedecl_enum_get_by_name(bname);
60 if (tp)
61 {
62 const Eolian_Enum_Type_Field *efl = eolian_typedecl_enum_field_get(tp, sfx + 1);
63 if (!efl)
64 {
65 eina_stringshare_del(bname);
66 goto noref;
67 }
68 _generate_ref(bname, wbuf, use_legacy);
69 Eina_Stringshare *str = eolian_typedecl_enum_field_c_name_get(efl);
70 eina_strbuf_append_char(wbuf, '.');
71 eina_strbuf_append(wbuf, str);
72 eina_stringshare_del(str);
73 eina_stringshare_del(bname);
74 return;
75 }
76
77 const Eolian_Class *cl = eolian_class_get_by_name(bname);
78 const Eolian_Function *fn = NULL;
79 Eolian_Function_Type ftype = EOLIAN_UNRESOLVED;
80 if (!cl)
81 {
82 const char *mname;
83 if (!strcmp(sfx, ".get")) ftype = EOLIAN_PROP_GET;
84 else if (!strcmp(sfx, ".set")) ftype = EOLIAN_PROP_SET;
85 if (ftype != EOLIAN_UNRESOLVED)
86 {
87 eina_stringshare_del(bname);
88 mname = sfx - 1;
89 while ((mname != refn) && (*mname != '.')) --mname;
90 if (mname == refn) goto noref;
91 bname = eina_stringshare_add_length(refn, mname - refn);
92 cl = eolian_class_get_by_name(bname);
93 eina_stringshare_del(bname);
94 }
95 if (cl)
96 {
97 char *meth = strndup(mname + 1, sfx - mname - 1);
98 fn = eolian_class_function_get_by_name(cl, meth, ftype);
99 if (ftype == EOLIAN_UNRESOLVED)
100 ftype = eolian_function_type_get(fn);
101 free(meth);
102 }
103 }
104 else
105 {
106 fn = eolian_class_function_get_by_name(cl, sfx + 1, ftype);
107 ftype = eolian_function_type_get(fn);
108 }
109
110 if (!fn) goto noref;
111
112 Eina_Stringshare *fcn = eolian_function_full_c_name_get(fn, ftype, use_legacy);
113 if (!fcn) goto noref;
114 eina_strbuf_append(wbuf, fcn);
115 eina_stringshare_del(fcn);
116 return;
117noref:
118 eina_strbuf_append(wbuf, refn);
119}
120
121static int
122_append_section(const char *desc, int ind, int curl, Eina_Strbuf *buf,
123 Eina_Strbuf *wbuf, Eina_Bool use_legacy)
124{
125 Eina_Bool try_note = EINA_TRUE;
126 while (*desc)
127 {
128 eina_strbuf_reset(wbuf);
129 while (*desc && isspace(*desc) && (*desc != '\n'))
130 eina_strbuf_append_char(wbuf, *desc++);
131 if (try_note)
132 {
133#define CHECK_NOTE(str) !strncmp(desc, str ": ", sizeof(str ":"))
134 if (CHECK_NOTE("Note"))
135 {
136 eina_strbuf_append(wbuf, "@note ");
137 desc += sizeof("Note:");
138 }
139 else if (CHECK_NOTE("Warning"))
140 {
141 eina_strbuf_append(wbuf, "@warning ");
142 desc += sizeof("Warning:");
143 }
144 else if (CHECK_NOTE("Remark"))
145 {
146 eina_strbuf_append(wbuf, "@remark ");
147 desc += sizeof("Remark:");
148 }
149 else if (CHECK_NOTE("TODO"))
150 {
151 eina_strbuf_append(wbuf, "@todo ");
152 desc += sizeof("TODO:");
153 }
154#undef CHECK_NOTE
155 try_note = EINA_FALSE;
156 }
157 if (*desc == '\\')
158 {
159 desc++;
160 if ((*desc != '@') && (*desc != '$'))
161 eina_strbuf_append_char(wbuf, '\\');
162 eina_strbuf_append_char(wbuf, *desc++);
163 }
164 else if (*desc == '@')
165 {
166 const char *ref = ++desc;
167 if (isalpha(*desc) || (*desc == '_'))
168 {
169 eina_strbuf_append(wbuf, "@ref ");
170 while (isalnum(*desc) || (*desc == '.') || (*desc == '_'))
171 ++desc;
172 if (*(desc - 1) == '.') --desc;
173 Eina_Stringshare *refn = eina_stringshare_add_length(ref, desc - ref);
174 _generate_ref(refn, wbuf, use_legacy);
175 eina_stringshare_del(refn);
176 }
177 else
178 eina_strbuf_append_char(wbuf, '@');
179 }
180 else if (*desc == '$')
181 {
182 desc++;
183 if (isalpha(*desc))
184 eina_strbuf_append(wbuf, "@c ");
185 else
186 eina_strbuf_append_char(wbuf, '$');
187 }
188 while (*desc && !isspace(*desc))
189 eina_strbuf_append_char(wbuf, *desc++);
190 int limit = DOC_LIMIT(ind);
191 int wlen = eina_strbuf_length_get(wbuf);
192 if ((int)(curl + wlen) > limit)
193 {
194 curl = 3;
195 eina_strbuf_append_char(buf, '\n');
196 curl += _indent_line(buf, ind);
197 eina_strbuf_append(buf, " * ");
198 if (*eina_strbuf_string_get(wbuf) == ' ')
199 eina_strbuf_remove(wbuf, 0, 1);
200 }
201 curl += eina_strbuf_length_get(wbuf);
202 eina_strbuf_append(buf, eina_strbuf_string_get(wbuf));
203 if (*desc == '\n')
204 {
205 desc++;
206 eina_strbuf_append_char(buf, '\n');
207 while (*desc == '\n')
208 {
209 _indent_line(buf, ind);
210 eina_strbuf_append(buf, " *\n");
211 desc++;
212 try_note = EINA_TRUE;
213 }
214 curl = _indent_line(buf, ind) + 3;
215 eina_strbuf_append(buf, " * ");
216 }
217 }
218 return curl;
219}
220
221static int
222_append_since(const char *since, int indent, int curl, Eina_Strbuf *buf)
223{
224 if (since)
225 {
226 eina_strbuf_append_char(buf, '\n');
227 _indent_line(buf, indent);
228 eina_strbuf_append(buf, " *\n");
229 curl = _indent_line(buf, indent);
230 eina_strbuf_append(buf, " * @since ");
231 eina_strbuf_append(buf, since);
232 curl += strlen(since) + sizeof(" * @since ") - 1;
233 }
234 return curl;
235}
236
237static int
238_append_extra(const char *el, int indent, int curl, Eina_Bool nl, Eina_Strbuf *buf)
239{
240 if (el)
241 {
242 eina_strbuf_append_char(buf, '\n');
243 if (nl)
244 {
245 _indent_line(buf, indent);
246 eina_strbuf_append(buf, " *\n");
247 }
248 curl = _indent_line(buf, indent);
249 eina_strbuf_append(buf, " * ");
250 eina_strbuf_append(buf, el);
251 curl += strlen(el) + sizeof(" * ") - 1;
252 }
253 return curl;
254}
255
256static char *
257_sanitize_group(const char *group)
258{
259 if (!group) return NULL;
260 char *ret = strdup(group);
261 char *p;
262 while ((p = strchr(ret, '.'))) *p = '_';
263 return ret;
264}
265
266static void
267_append_group(Eina_Strbuf *buf, char *sgrp, int indent)
268{
269 if (!sgrp) return;
270 eina_strbuf_append(buf, " * @ingroup ");
271 eina_strbuf_append(buf, sgrp);
272 eina_strbuf_append_char(buf, '\n');
273 _indent_line(buf, indent);
274 free(sgrp);
275}
276
277static void
278_gen_doc_brief(const char *summary, const char *since, const char *group,
279 const char *el, int indent, Eina_Strbuf *buf,
280 Eina_Bool use_legacy)
281{
282 int curl = 4 + indent;
283 Eina_Strbuf *wbuf = eina_strbuf_new();
284 if (indent)
285 eina_strbuf_append(buf, "/**< ");
286 else
287 eina_strbuf_append(buf, "/** ");
288 curl = _append_section(summary, indent, curl, buf, wbuf, use_legacy);
289 eina_strbuf_free(wbuf);
290 curl = _append_extra(el, indent, curl, EINA_FALSE, buf);
291 curl = _append_since(since, indent, curl, buf);
292 char *sgrp = _sanitize_group(group);
293 if (((curl + 3) > DOC_LIMIT(indent)) || sgrp)
294 {
295 eina_strbuf_append_char(buf, '\n');
296 _indent_line(buf, indent);
297 if (sgrp) eina_strbuf_append(buf, " *");
298 }
299 if (sgrp)
300 {
301 eina_strbuf_append_char(buf, '\n');
302 _indent_line(buf, indent);
303 }
304 _append_group(buf, sgrp, indent);
305 eina_strbuf_append(buf, " */");
306}
307
308static void
309_gen_doc_full(const char *summary, const char *description, const char *since,
310 const char *group, const char *el, int indent, Eina_Strbuf *buf,
311 Eina_Bool use_legacy)
312{
313 int curl = 0;
314 Eina_Strbuf *wbuf = eina_strbuf_new();
315 if (indent)
316 eina_strbuf_append(buf, "/**<\n");
317 else
318 eina_strbuf_append(buf, "/**\n");
319 curl += _indent_line(buf, indent);
320 eina_strbuf_append(buf, " * @brief ");
321 curl += sizeof(" * @brief ") - 1;
322 _append_section(summary, indent, curl, buf, wbuf, use_legacy);
323 eina_strbuf_append_char(buf, '\n');
324 _indent_line(buf, indent);
325 eina_strbuf_append(buf, " *\n");
326 curl = _indent_line(buf, indent);
327 eina_strbuf_append(buf, " * ");
328 _append_section(description, indent, curl + 3, buf, wbuf, use_legacy);
329 curl = _append_extra(el, indent, curl, EINA_TRUE, buf);
330 curl = _append_since(since, indent, curl, buf);
331 eina_strbuf_append_char(buf, '\n');
332 _indent_line(buf, indent);
333 char *sgrp = _sanitize_group(group);
334 if (sgrp)
335 {
336 eina_strbuf_append(buf, " *\n");
337 _indent_line(buf, indent);
338 }
339 _append_group(buf, sgrp, indent);
340 eina_strbuf_append(buf, " */");
341 eina_strbuf_free(wbuf);
342}
343
344static Eina_Strbuf *
345_gen_doc_buf(const Eolian_Documentation *doc, const char *group,
346 const char *el, int indent, Eina_Bool use_legacy)
347{
348 if (!doc) return NULL;
349
350 const char *sum = eolian_documentation_summary_get(doc);
351 const char *desc = eolian_documentation_description_get(doc);
352 const char *since = eolian_documentation_since_get(doc);
353
354 Eina_Strbuf *buf = eina_strbuf_new();
355 if (!desc)
356 _gen_doc_brief(sum, since, group, el, indent, buf, use_legacy);
357 else
358 _gen_doc_full(sum, desc, since, group, el, indent, buf, use_legacy);
359 return buf;
360}
361
362Eina_Strbuf *
363docs_generate_full(const Eolian_Documentation *doc, const char *group,
364 int indent, Eina_Bool use_legacy)
365{
366 return _gen_doc_buf(doc, group, NULL, indent, use_legacy);
367}
368
369Eina_Strbuf *
370docs_generate_event(const Eolian_Event *ev, const char *group)
371{
372 if (!ev) return NULL;
373
374 const Eolian_Documentation *doc = eolian_event_documentation_get(ev);
375
376 char buf[1024];
377 const Eolian_Type *rt = eolian_event_type_get(ev);
378 const char *p = NULL;
379 if (rt)
380 {
381 p = buf;
382 Eina_Stringshare *rts = eolian_type_c_type_get(rt);
383 snprintf(buf, sizeof(buf), "@return %s", rts);
384 eina_stringshare_del(rts);
385 }
386
387 if (!doc)
388 {
389 Eina_Strbuf *bufs = eina_strbuf_new();
390 eina_strbuf_append(bufs, "/**\n * No description\n");
391 if (p)
392 {
393 eina_strbuf_append(bufs, " * ");
394 eina_strbuf_append(bufs, p);
395 eina_strbuf_append_char(bufs, '\n');
396 }
397 eina_strbuf_append(bufs, " */");
398 return bufs;
399 }
400
401 return _gen_doc_buf(doc, group, p, 0, EINA_FALSE);
402}
403
404Eina_Strbuf *
405docs_generate_function(const Eolian_Function *fid, Eolian_Function_Type ftype,
406 int indent, Eina_Bool use_legacy)
407{
408 const Eolian_Function_Parameter *par = NULL;
409 const Eolian_Function_Parameter *vpar = NULL;
410
411 const Eolian_Documentation *doc, *pdoc, *rdoc;
412
413 Eina_Iterator *itr = NULL;
414 Eina_Iterator *vitr = NULL;
415 Eina_Bool force_out = EINA_FALSE;
416
417 Eina_Strbuf *buf = eina_strbuf_new();
418 Eina_Strbuf *wbuf = NULL;
419
420 const char *sum = NULL, *desc = NULL, *since = NULL;
421
422 int curl = 0;
423
424 const char *group = eolian_class_full_name_get(eolian_function_class_get(fid));
425
426 if (ftype == EOLIAN_UNRESOLVED)
427 ftype = EOLIAN_METHOD;
428
429 if (ftype == EOLIAN_METHOD)
430 {
431 doc = eolian_function_documentation_get(fid, EOLIAN_METHOD);
432 pdoc = NULL;
433 }
434 else
435 {
436 doc = eolian_function_documentation_get(fid, EOLIAN_PROPERTY);
437 pdoc = eolian_function_documentation_get(fid, ftype);
438 if (!doc && pdoc) doc = pdoc;
439 if (pdoc == doc) pdoc = NULL;
440 }
441
442 rdoc = eolian_function_return_documentation_get(fid, ftype);
443
444 if (doc)
445 {
446 sum = eolian_documentation_summary_get(doc);
447 desc = eolian_documentation_description_get(doc);
448 since = eolian_documentation_since_get(doc);
449 if (pdoc && eolian_documentation_since_get(pdoc))
450 since = eolian_documentation_since_get(pdoc);
451 }
452
453 if (ftype == EOLIAN_METHOD)
454 {
455 itr = eolian_function_parameters_get(fid);
456 }
457 else
458 {
459 itr = eolian_property_keys_get(fid, ftype);
460 vitr = eolian_property_values_get(fid, ftype);
461 if (!vitr || !eina_iterator_next(vitr, (void**)&vpar))
462 {
463 eina_iterator_free(vitr);
464 vitr = NULL;
465 }
466 }
467
468 if (!itr || !eina_iterator_next(itr, (void**)&par))
469 {
470 eina_iterator_free(itr);
471 itr = NULL;
472 }
473
474 /* when return is not set on getter, value becomes return instead of param */
475 if (ftype == EOLIAN_PROP_GET && !eolian_function_return_type_get(fid, ftype))
476 {
477 const Eolian_Function_Parameter *rvpar = vpar;
478 if (!eina_iterator_next(vitr, (void**)&vpar))
479 {
480 /* one value - not out param */
481 eina_iterator_free(vitr);
482 rdoc = rvpar ? eolian_parameter_documentation_get(rvpar) : NULL;
483 vitr = NULL;
484 vpar = NULL;
485 }
486 else
487 {
488 /* multiple values - always out params */
489 eina_iterator_free(vitr);
490 vitr = eolian_property_values_get(fid, ftype);
491 if (!vitr)
492 vpar = NULL;
493 else if (!eina_iterator_next(vitr, (void**)&vpar))
494 {
495 eina_iterator_free(vitr);
496 vitr = NULL;
497 vpar = NULL;
498 }
499 }
500 }
501
502 if (!par)
503 {
504 /* no keys, try values */
505 itr = vitr;
506 par = vpar;
507 vitr = NULL;
508 vpar = NULL;
509 if (ftype == EOLIAN_PROP_GET)
510 force_out = EINA_TRUE;
511 }
512
513 /* only summary, nothing else; generate standard brief doc */
514 if (!desc && !par && !vpar && !rdoc && (ftype == EOLIAN_METHOD || !pdoc))
515 {
516 _gen_doc_brief(sum ? sum : "No description supplied.", since, group,
517 NULL, indent, buf, use_legacy);
518 return buf;
519 }
520
521 wbuf = eina_strbuf_new();
522
523 eina_strbuf_append(buf, "/**\n");
524 curl += _indent_line(buf, indent);
525 eina_strbuf_append(buf, " * @brief ");
526 curl += sizeof(" * @brief ") - 1;
527 _append_section(sum ? sum : "No description supplied.",
528 indent, curl, buf, wbuf, use_legacy);
529
530 eina_strbuf_append_char(buf, '\n');
531 if (desc || since || par || rdoc || pdoc)
532 {
533 _indent_line(buf, indent);
534 eina_strbuf_append(buf, " *\n");
535 }
536
537 if (desc)
538 {
539 curl = _indent_line(buf, indent);
540 eina_strbuf_append(buf, " * ");
541 _append_section(desc, indent, curl + 3, buf, wbuf, use_legacy);
542 eina_strbuf_append_char(buf, '\n');
543 if (par || rdoc || pdoc || since)
544 {
545 _indent_line(buf, indent);
546 eina_strbuf_append(buf, " *\n");
547 }
548 }
549
550 if (pdoc)
551 {
552 const char *pdesc = eolian_documentation_description_get(pdoc);
553 curl = _indent_line(buf, indent);
554 eina_strbuf_append(buf, " * ");
555 _append_section(eolian_documentation_summary_get(pdoc), indent,
556 curl + 3, buf, wbuf, use_legacy);
557 eina_strbuf_append_char(buf, '\n');
558 if (pdesc)
559 {
560 _indent_line(buf, indent);
561 eina_strbuf_append(buf, " *\n");
562 curl = _indent_line(buf, indent);
563 eina_strbuf_append(buf, " * ");
564 _append_section(pdesc, indent, curl + 3, buf, wbuf, use_legacy);
565 eina_strbuf_append_char(buf, '\n');
566 }
567 if (par || rdoc || since)
568 {
569 _indent_line(buf, indent);
570 eina_strbuf_append(buf, " *\n");
571 }
572 }
573
574 while (par)
575 {
576 const Eolian_Documentation *adoc = eolian_parameter_documentation_get(par);
577 curl = _indent_line(buf, indent);
578
579 Eolian_Parameter_Dir dir = EOLIAN_OUT_PARAM;
580 if (!force_out)
581 dir = eolian_parameter_direction_get(par);
582
583 switch (dir)
584 {
585 case EOLIAN_IN_PARAM:
586 eina_strbuf_append(buf, " * @param[in] ");
587 curl += sizeof(" * @param[in] ") - 1;
588 break;
589 case EOLIAN_OUT_PARAM:
590 eina_strbuf_append(buf, " * @param[out] ");
591 curl += sizeof(" * @param[out] ") - 1;
592 break;
593 case EOLIAN_INOUT_PARAM:
594 eina_strbuf_append(buf, " * @param[in,out] ");
595 curl += sizeof(" * @param[in,out] ") - 1;
596 break;
597 }
598
599 const char *nm = eolian_parameter_name_get(par);
600 eina_strbuf_append(buf, nm);
601 curl += strlen(nm);
602
603 if (adoc)
604 {
605 eina_strbuf_append_char(buf, ' ');
606 curl += 1;
607 _append_section(eolian_documentation_summary_get(adoc),
608 indent, curl, buf, wbuf, use_legacy);
609 }
610
611 eina_strbuf_append_char(buf, '\n');
612 if (!eina_iterator_next(itr, (void**)&par))
613 {
614 par = NULL;
615 if (vpar)
616 {
617 eina_iterator_free(itr);
618 itr = vitr;
619 par = vpar;
620 vitr = NULL;
621 vpar = NULL;
622 if (ftype == EOLIAN_PROP_GET)
623 force_out = EINA_TRUE;
624 }
625 }
626
627 if (!par && (rdoc || since))
628 {
629 _indent_line(buf, indent);
630 eina_strbuf_append(buf, " *\n");
631 }
632 }
633 eina_iterator_free(itr);
634
635 if (rdoc)
636 {
637 curl = _indent_line(buf, indent);
638 eina_strbuf_append(buf, " * @return ");
639 curl += sizeof(" * @return ") - 1;
640 _append_section(eolian_documentation_summary_get(rdoc), indent, curl,
641 buf, wbuf, use_legacy);
642 eina_strbuf_append_char(buf, '\n');
643 if (since)
644 {
645 _indent_line(buf, indent);
646 eina_strbuf_append(buf, " *\n");
647 }
648 }
649
650 if (since)
651 {
652 curl = _indent_line(buf, indent);
653 eina_strbuf_append(buf, " * @since ");
654 eina_strbuf_append(buf, since);
655 eina_strbuf_append_char(buf, '\n');
656 }
657
658 _indent_line(buf, indent);
659 eina_strbuf_append(buf, " *\n");
660
661 _indent_line(buf, indent);
662 _append_group(buf, _sanitize_group(group), indent);
663 eina_strbuf_append(buf, " */");
664 eina_strbuf_free(wbuf);
665 return buf;
666}
diff --git a/src/bin/eolian/docs_generator.h b/src/bin/eolian/docs_generator.h
deleted file mode 100644
index c7038ac71e..0000000000
--- a/src/bin/eolian/docs_generator.h
+++ /dev/null
@@ -1,45 +0,0 @@
1#ifndef DOCS_GENERATOR_H
2#define DOCS_GENERATOR_H
3
4#include <Eina.h>
5#include <Eolian.h>
6
7/*
8 * @brief Generate standard documentation
9 *
10 * @param[in] doc the documentation
11 * @param[in] group the group to use (can be NULL)
12 * @param[in] indent by how many spaces to indent the comment from second line
13 * @param[in] use_legacy whether to use legacy names
14 *
15 * @return A documentation comment
16 *
17 */
18Eina_Strbuf *docs_generate_full(const Eolian_Documentation *doc, const char *group, int indent, Eina_Bool use_legacy);
19
20/*
21 * @brief Generate function documentation
22 *
23 * @param[in] fid te function
24 * @param[in] type the function type (either METHOD, PROP_GET, PROP_SET)
25 * @param[in] indent by how many spaces to indent the comment from second line
26 * @param[in] use_legacy whether to use legacy names
27 *
28 * @return A documentation comment
29 *
30 */
31Eina_Strbuf *docs_generate_function(const Eolian_Function *fid, Eolian_Function_Type ftype, int indent, Eina_Bool use_legacy);
32
33/*
34 * @brief Generate event documentation
35 *
36 * @param[in] ev the event
37 * @param[in] group the group to use (can be NULL);
38 *
39 * @return A documentation comment
40 *
41 */
42Eina_Strbuf *docs_generate_event(const Eolian_Event *ev, const char *group);
43
44#endif
45
diff --git a/src/bin/eolian/eo_generator.c b/src/bin/eolian/eo_generator.c
deleted file mode 100644
index 7b793a0ef2..0000000000
--- a/src/bin/eolian/eo_generator.c
+++ /dev/null
@@ -1,1047 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <Eina.h>
6#include <string.h>
7#include <assert.h>
8
9#include "Eolian.h"
10#include "eo_generator.h"
11#include "docs_generator.h"
12#include "common_funcs.h"
13
14static _eolian_class_vars class_env;
15/* Used to store the function names that will have to be appended
16 * with __eolian during C generation. Needed when params have to
17 * be initialized and for future features. */
18static Eina_Hash *_funcs_params_init = NULL;
19
20static const char
21tmpl_eo_ops_def[] = "\
22 EFL_OPS_DEFINE(ops,@#list_op\n\
23 );\n";
24
25static const char
26tmpl_eo_cops_def[] = "\
27 EFL_OPS_DEFINE(cops,@#list_cop\n\
28 );\n";
29
30static const char
31tmpl_eo_ops_desc[] = "\
32static Eina_Bool\n\
33_@#class_class_initializer(Efl_Class *klass)\n\
34{\n\
35@#list_ops\
36@#list_cops\
37\n\
38 return efl_class_functions_set(klass, @#ref_ops, @#ref_cops);\n\
39}\n\n";
40
41static const char
42tmpl_eo_src[] = "\
43@#functions_body\
44\n\
45@#ctor_func\
46@#dtor_func\
47@#ops_desc\
48static const Efl_Class_Description _@#class_class_desc = {\n\
49 EO_VERSION,\n\
50 \"@#Class\",\n\
51 @#type_class,\n\
52 @#SizeOfData,\n\
53 @#init_name,\n\
54 @#ctor_name,\n\
55 @#dtor_name\n\
56};\n\
57\n\
58EFL_DEFINE_CLASS(@#klasstype_get, &_@#class_class_desc, @#list_inheritNULL);\
59";
60
61static const char
62tmpl_eo_obj_header[] = "\
63#define @#CLASS_@#CLASSTYPE @#klasstype_get()\n\
64\n\
65EWAPI const Efl_Class *@#klasstype_get(void);\n\
66\n\
67";
68
69static Eina_Bool
70eo_fundef_generate(const Eolian_Class *class, const Eolian_Function *func, Eolian_Function_Type ftype, Eina_Strbuf *functext)
71{
72 _eolian_class_func_vars func_env;
73 Eina_Iterator *itr;
74 void *data, *data2;
75 Eina_Bool var_as_ret = EINA_FALSE;
76 const Eolian_Type *rettypet = NULL;
77 const char *rettype = NULL;
78 Eolian_Object_Scope scope = eolian_function_scope_get(func, ftype);
79 Eina_Bool is_prop = (ftype == EOLIAN_PROP_GET || ftype == EOLIAN_PROP_SET);
80
81 _class_func_env_create(class, eolian_function_name_get(func), ftype, &func_env);
82 rettypet = eolian_function_return_type_get(func, ftype);
83 if (ftype == EOLIAN_PROP_GET && !rettypet)
84 {
85 itr = eolian_property_values_get(func, ftype);
86 /* We want to check if there is only one parameter */
87 if (eina_iterator_next(itr, &data) && !eina_iterator_next(itr, &data2))
88 {
89 rettypet = eolian_parameter_type_get((Eolian_Function_Parameter*)data);
90 var_as_ret = EINA_TRUE;
91 }
92 eina_iterator_free(itr);
93 }
94 Eina_Strbuf *str_func = eina_strbuf_new();
95 if (eolian_function_is_beta(func))
96 eina_strbuf_append_printf(str_func, "#ifdef %s_BETA\n", class_env.upper_classname);
97 if (scope == EOLIAN_SCOPE_PROTECTED)
98 eina_strbuf_append_printf(str_func, "#ifdef %s_PROTECTED\n", class_env.upper_classname);
99
100 Eina_Bool hasnewdocs = eolian_function_documentation_get(func, EOLIAN_UNRESOLVED) ||
101 eolian_function_documentation_get(func, ftype);
102 if (hasnewdocs)
103 {
104 Eina_Strbuf *dbuf = docs_generate_function(func, ftype, 0, EINA_FALSE);
105 eina_strbuf_append(str_func, eina_strbuf_string_get(dbuf));
106 eina_strbuf_append_char(str_func, '\n');
107 eina_strbuf_free(dbuf);
108 }
109 eina_strbuf_append_printf(str_func, "EOAPI @#rettype@#retspace%s(%sEo *obj@#full_params);\n",
110 func_env.lower_eo_func,
111 (ftype == EOLIAN_PROP_GET ||
112 eolian_function_object_is_const(func) ||
113 eolian_function_is_class(func))?"const ":"");
114
115 if (scope == EOLIAN_SCOPE_PROTECTED)
116 eina_strbuf_append_printf(str_func, "#endif\n");
117 if (eolian_function_is_beta(func))
118 eina_strbuf_append_printf(str_func, "#endif\n");
119 eina_strbuf_append_printf(str_func, "\n");
120
121 Eina_Strbuf *str_par = eina_strbuf_new();
122
123 itr = eolian_property_keys_get(func, ftype);
124 EINA_ITERATOR_FOREACH(itr, data)
125 {
126 Eolian_Function_Parameter *param = data;
127 const Eolian_Type *ptypet = eolian_parameter_type_get(param);
128 const char *pname = eolian_parameter_name_get(param);
129 const char *ptype = eolian_type_c_type_get(ptypet);
130 eina_strbuf_append_printf(str_par, ", %s %s", ptype, pname);
131 eina_stringshare_del(ptype);
132 }
133 eina_iterator_free(itr);
134
135 if (!var_as_ret)
136 {
137 itr = is_prop ? eolian_property_values_get(func, ftype) : eolian_function_parameters_get(func);
138 EINA_ITERATOR_FOREACH(itr, data)
139 {
140 Eolian_Function_Parameter *param = data;
141 const Eolian_Type *ptypet = eolian_parameter_type_get(param);
142 const char *pname = eolian_parameter_name_get(param);
143 const char *ptype = eolian_type_c_type_get(ptypet);
144 Eolian_Parameter_Dir pdir = eolian_parameter_direction_get(param);
145 Eina_Bool had_star = !!strchr(ptype, '*');
146
147 eina_strbuf_append_printf(str_par, ", %s%s%s%s",
148 ptype, had_star?"":" ", _get_add_star(ftype, pdir), pname);
149
150 eina_stringshare_del(ptype);
151 }
152 eina_iterator_free(itr);
153 }
154
155 if (rettypet) rettype = eolian_type_c_type_get(rettypet);
156
157 eina_strbuf_replace_all(str_func, "@#rettype", rettype ? rettype : "void");
158 if (!rettype || rettype[strlen(rettype) - 1] != '*')
159 eina_strbuf_replace_all(str_func, "@#retspace", " ");
160 else
161 eina_strbuf_replace_all(str_func, "@#retspace", "");
162
163 eina_strbuf_replace_all(str_func, "@#full_params", eina_strbuf_string_get(str_par));
164
165 if (rettype) eina_stringshare_del(rettype);
166
167 eina_strbuf_free(str_par);
168
169 eina_strbuf_append(functext, eina_strbuf_string_get(str_func));
170 eina_strbuf_free(str_func);
171
172 return EINA_TRUE;
173}
174
175Eina_Bool
176eo_header_generate(const Eolian_Class *class, Eina_Strbuf *buf)
177{
178 Eina_Iterator *itr;
179 Eolian_Event *event;
180 Eina_Strbuf * str_hdr = eina_strbuf_new();
181
182 const Eolian_Documentation *doc = eolian_class_documentation_get(class);
183 _class_env_create(class, NULL, &class_env);
184
185 if (doc)
186 {
187 Eina_Strbuf *cdoc = docs_generate_full(doc, eolian_class_full_name_get(class), 0, EINA_FALSE);
188 if (cdoc)
189 {
190 eina_strbuf_append(buf, eina_strbuf_string_get(cdoc));
191 eina_strbuf_append_char(buf, '\n');
192 eina_strbuf_free(cdoc);
193 }
194 }
195
196 _template_fill(str_hdr, tmpl_eo_obj_header, class, NULL, NULL, EINA_TRUE);
197
198 eina_strbuf_replace_all(str_hdr, "@#EOPREFIX", class_env.upper_eo_prefix);
199 eina_strbuf_replace_all(str_hdr, "@#eoprefix", class_env.lower_eo_prefix);
200 eina_strbuf_replace_all(str_hdr, "@#klasstype_get", eolian_class_c_get_function_name_get(class));
201
202 Eina_Strbuf *str_ev = eina_strbuf_new();
203 Eina_Strbuf *str_extrn_ev = eina_strbuf_new();
204 Eina_Strbuf *tmpbuf = eina_strbuf_new();
205
206 itr = eolian_class_events_get(class);
207 EINA_ITERATOR_FOREACH(itr, event)
208 {
209 Eina_Stringshare *evname = eolian_event_c_name_get(event);
210 Eolian_Object_Scope scope = eolian_event_scope_get(event);
211
212 if (scope == EOLIAN_SCOPE_PRIVATE)
213 continue;
214
215 if (eolian_event_is_beta(event))
216 {
217 eina_strbuf_append_printf(str_ev, "\n#ifdef %s_BETA\n", class_env.upper_classname);
218 eina_strbuf_append_printf(str_extrn_ev, "#ifdef %s_BETA\n", class_env.upper_classname);
219 }
220 if (scope == EOLIAN_SCOPE_PROTECTED)
221 {
222 if (!eolian_event_is_beta(event))
223 eina_strbuf_append_char(str_ev, '\n');
224 eina_strbuf_append_printf(str_ev, "#ifdef %s_PROTECTED\n", class_env.upper_classname);
225 eina_strbuf_append_printf(str_extrn_ev, "#ifdef %s_PROTECTED\n", class_env.upper_classname);
226 }
227
228 if (!eolian_event_is_beta(event) && scope == EOLIAN_SCOPE_PUBLIC)
229 eina_strbuf_append_char(str_ev, '\n');
230
231 Eina_Strbuf *evdbuf = docs_generate_event(event, eolian_class_full_name_get(class));
232 eina_strbuf_append(str_ev, eina_strbuf_string_get(evdbuf));
233 eina_strbuf_append_char(str_ev, '\n');
234 eina_strbuf_free(evdbuf);
235
236 eina_strbuf_append_printf(str_ev, "#define %s (&(_%s))\n", evname, evname);
237 eina_strbuf_append_printf(str_extrn_ev, "EOAPI extern const Efl_Event_Description _%s;\n", evname);
238 eina_stringshare_del(evname);
239
240 if (scope == EOLIAN_SCOPE_PROTECTED)
241 {
242 eina_strbuf_append(str_ev, "#endif\n");
243 eina_strbuf_append(str_extrn_ev, "#endif\n");
244 }
245 if (eolian_event_is_beta(event))
246 {
247 eina_strbuf_append(str_ev, "#endif\n");
248 eina_strbuf_append(str_extrn_ev, "#endif\n");
249 }
250 }
251 eina_iterator_free(itr);
252
253 if ((itr = eolian_class_implements_get(class)))
254 {
255 const Eolian_Implement *impl;
256 EINA_ITERATOR_FOREACH(itr, impl)
257 {
258 if (eolian_implement_class_get(impl) != class)
259 continue;
260 Eolian_Function_Type ftype = EOLIAN_UNRESOLVED;
261 const Eolian_Function *fid = eolian_implement_function_get(impl, &ftype);
262 switch (ftype)
263 {
264 case EOLIAN_PROP_GET: case EOLIAN_PROP_SET:
265 eo_fundef_generate(class, fid, ftype, str_hdr);
266 break;
267 case EOLIAN_PROPERTY:
268 eo_fundef_generate(class, fid, EOLIAN_PROP_SET, str_hdr);
269 eo_fundef_generate(class, fid, EOLIAN_PROP_GET, str_hdr);
270 break;
271 default:
272 eo_fundef_generate(class, fid, EOLIAN_UNRESOLVED, str_hdr);
273 break;
274 }
275 }
276 eina_iterator_free(itr);
277 }
278
279 eina_strbuf_append(str_hdr, eina_strbuf_string_get(str_extrn_ev));
280 eina_strbuf_append(str_hdr, eina_strbuf_string_get(str_ev));
281
282 eina_strbuf_append(buf, eina_strbuf_string_get(str_hdr));
283
284 eina_strbuf_free(str_ev);
285 eina_strbuf_free(str_extrn_ev);
286 eina_strbuf_free(tmpbuf);
287 eina_strbuf_free(str_hdr);
288
289 return EINA_TRUE;
290}
291
292static Eina_Bool
293eo_bind_func_generate(const Eolian_Class *class, const Eolian_Function *funcid, Eolian_Function_Type ftype, Eina_Strbuf *buf, Eolian_Implement *impl, _eolian_class_vars *impl_env)
294{
295 _eolian_class_func_vars func_env;
296 const char *suffix = "";
297 Eina_Bool var_as_ret = EINA_FALSE;
298 const Eolian_Type *rettypet = NULL;
299 const char *rettype = NULL;
300 Eina_Iterator *itr;
301 void *data, *data2;
302 const Eolian_Expression *default_ret_val = NULL;
303 Eina_Bool is_empty = impl ? eolian_implement_is_empty(impl) : eolian_function_is_empty(funcid, ftype);
304 Eina_Bool is_auto = impl ? eolian_implement_is_auto(impl) : eolian_function_is_auto(funcid, ftype);
305 if (ftype != EOLIAN_PROP_GET && ftype != EOLIAN_PROP_SET) ftype = eolian_function_type_get(funcid);
306 Eina_Bool is_prop = (ftype == EOLIAN_PROP_GET || ftype == EOLIAN_PROP_SET);
307
308 Eina_Bool has_promise = EINA_FALSE;
309 const char* promise_param_name = NULL;
310 const char* promise_value_type = NULL;
311 Eina_Bool need_implementation = EINA_TRUE;
312 if (!impl_env && eolian_function_is_virtual_pure(funcid, ftype)) need_implementation = EINA_FALSE;
313
314 Eina_Strbuf *fbody = eina_strbuf_new();
315 Eina_Strbuf *va_args = eina_strbuf_new();
316 Eina_Strbuf *params = eina_strbuf_new(); /* only variables names */
317 Eina_Strbuf *full_params = eina_strbuf_new(); /* variables types + names */
318 Eina_Strbuf *impl_full_params = eina_strbuf_new(); /* variables types + names */
319 Eina_Strbuf *params_init = eina_strbuf_new(); /* init of variables to default */
320
321 rettypet = eolian_function_return_type_get(funcid, ftype);
322 if (rettypet)
323 {
324 is_auto = EINA_FALSE; /* We block auto when the function has to return something */
325 default_ret_val = eolian_function_return_default_value_get(funcid, ftype);
326 }
327 if (ftype == EOLIAN_PROP_GET)
328 {
329 suffix = "_get";
330 if (!rettypet)
331 {
332 itr = eolian_property_values_get(funcid, ftype);
333 /* We want to check if there is only one parameter */
334 if (eina_iterator_next(itr, &data) && !eina_iterator_next(itr, &data2))
335 {
336 Eolian_Function_Parameter *param = data;
337 rettypet = eolian_parameter_type_get(param);
338 var_as_ret = EINA_TRUE;
339 default_ret_val = eolian_parameter_default_value_get(param);
340 }
341 eina_iterator_free(itr);
342 }
343 }
344 if (ftype == EOLIAN_PROP_SET)
345 {
346 suffix = "_set";
347 }
348
349 itr = eolian_property_keys_get(funcid, ftype);
350 EINA_ITERATOR_FOREACH(itr, data)
351 {
352 Eolian_Function_Parameter *param = data;
353 const Eolian_Type *ptypet = eolian_parameter_type_get(param);
354 const char *pname = eolian_parameter_name_get(param);
355 const char *ptype = eolian_type_c_type_get(ptypet);
356 if (eina_strbuf_length_get(params)) eina_strbuf_append(params, ", ");
357 eina_strbuf_append_printf(params, "%s", pname);
358 eina_strbuf_append_printf(full_params, ", %s %s%s",
359 ptype, pname, is_empty || is_auto?" EINA_UNUSED":"");
360 eina_strbuf_append_printf(impl_full_params, ", %s %s%s",
361 ptype, pname, is_empty || is_auto?" EINA_UNUSED":"");
362 eina_stringshare_del(ptype);
363 }
364 eina_iterator_free(itr);
365 if (!var_as_ret)
366 {
367 itr = is_prop ? eolian_property_values_get(funcid, ftype) : eolian_function_parameters_get(funcid);
368 EINA_ITERATOR_FOREACH(itr, data)
369 {
370 Eolian_Function_Parameter *param = data;
371 const Eolian_Expression *dflt_value = eolian_parameter_default_value_get(param);
372 const Eolian_Type *ptypet = eolian_parameter_type_get(param);
373 const char *pname = eolian_parameter_name_get(param);
374 const char *ptype = eolian_type_c_type_get(ptypet);
375 Eolian_Parameter_Dir pdir = eolian_parameter_direction_get(param);
376 Eina_Bool had_star = !!strchr(ptype, '*');
377 const char *add_star = _get_add_star(ftype, pdir);
378
379 if (eina_strbuf_length_get(params)) eina_strbuf_append(params, ", ");
380
381 /* FIXME: this looks really bad and should not be here */
382 if(!has_promise && !strcmp(ptype, "Eina_Promise *") &&
383 (ftype == EOLIAN_UNRESOLVED || ftype == EOLIAN_METHOD) && pdir == EOLIAN_INOUT_PARAM)
384 {
385 has_promise = EINA_TRUE;
386 promise_param_name = eina_stringshare_add(pname);
387 promise_value_type = eolian_type_c_type_get(eolian_type_base_type_get(ptypet));
388 eina_strbuf_append_printf(impl_full_params, ", Eina_Promise_Owner *%s%s",
389 pname, is_empty && !dflt_value ?" EINA_UNUSED":"");
390 eina_strbuf_append_printf(params, "__eo_promise");
391 }
392 else
393 {
394 eina_strbuf_append_printf(impl_full_params, ", %s%s%s%s%s",
395 ptype, had_star?"":" ", add_star, pname, is_empty && !dflt_value ?" EINA_UNUSED":"");
396 eina_strbuf_append_printf(params, "%s", pname);
397 }
398
399 eina_strbuf_append_printf(full_params, ", %s%s%s%s%s",
400 ptype, had_star?"":" ", add_star, pname, is_empty && !dflt_value ?" EINA_UNUSED":"");
401 if (is_auto)
402 {
403 if (ftype == EOLIAN_PROP_SET)
404 {
405 eina_strbuf_append_printf(params_init,
406 " %s = pd->%s;\n", pname, pname);
407 }
408 else
409 {
410 eina_strbuf_append_printf(params_init,
411 " if (%s) *%s = pd->%s;\n", pname, pname, pname);
412 }
413 }
414 else {
415 if (ftype != EOLIAN_PROP_SET)
416 {
417 if (dflt_value)
418 {
419 const char *val_str = NULL;
420 Eolian_Value val = eolian_expression_eval
421 (dflt_value, EOLIAN_MASK_ALL);
422 if (val.type)
423 {
424 val_str = eolian_expression_value_to_literal(&val);
425 eina_strbuf_append_printf(params_init,
426 " if (%s) *%s = %s;",
427 pname, pname, val_str);
428 if (eolian_expression_type_get(dflt_value) == EOLIAN_EXPR_NAME)
429 {
430 Eina_Stringshare *string = eolian_expression_serialize(dflt_value);
431 eina_strbuf_append_printf(params_init, " /* %s */", string);
432 eina_stringshare_del(string);
433 }
434 eina_strbuf_append_printf(params_init, "\n");
435 }
436 }
437 }
438 }
439 eina_stringshare_del(ptype);
440 }
441 eina_iterator_free(itr);
442 }
443
444 if (rettypet) rettype = eolian_type_c_type_get(rettypet);
445
446 if (need_implementation)
447 {
448 Eina_Strbuf *ret_param = eina_strbuf_new();
449 eina_strbuf_append_printf(fbody, "\n");
450 /* Generation of the user function prototype declaration - not needed when @auto and @empty are indicated */
451 if (!is_empty && !is_auto)
452 {
453 eina_strbuf_append_printf(fbody, "%s _%s%s%s_%s%s(%sEo *obj, @#Datatype_Data *pd%s);\n\n",
454 rettype?rettype:"void",
455 class_env.lower_classname,
456 impl_env?"_":"",
457 impl_env?impl_env->lower_classname:"",
458 eolian_function_name_get(funcid), suffix,
459 eolian_function_object_is_const(funcid)?"const ":"",
460 eina_strbuf_string_get(impl_full_params));
461 }
462
463 if (is_empty || is_auto || eina_strbuf_length_get(params_init))
464 {
465 /* We need to give the internal function name to Eo. We use this hash table as indication */
466 eina_hash_add(_funcs_params_init,
467 eina_stringshare_add(eolian_function_name_get(funcid)), (void *)ftype);
468 /* Generation of the intermediate function __eolian_... */
469 eina_strbuf_append_printf(fbody, "static %s __eolian_%s%s%s_%s%s(%sEo *obj%s, @#Datatype_Data *pd%s%s)\n{\n",
470 rettype?rettype:"void",
471 class_env.lower_classname,
472 impl_env?"_":"",
473 impl_env?impl_env->lower_classname:"",
474 eolian_function_name_get(funcid), suffix,
475 eolian_function_object_is_const(funcid)?"const ":"",
476 is_empty || is_auto?" EINA_UNUSED":"",
477 is_empty || (is_auto && !eina_strbuf_length_get(params_init))?" EINA_UNUSED":"",
478 eina_strbuf_string_get(impl_full_params));
479 }
480 if (eina_strbuf_length_get(params_init))
481 {
482 eina_strbuf_append_printf(fbody, "%s", eina_strbuf_string_get(params_init));
483 }
484 if (is_auto || is_empty)
485 {
486 if (rettype)
487 {
488 /* return for auto and empty */
489 const char *val_str = NULL;
490 if (default_ret_val)
491 {
492 Eolian_Value val = eolian_expression_eval
493 (default_ret_val, EOLIAN_MASK_ALL);
494 if (val.type)
495 val_str = eolian_expression_value_to_literal(&val);
496 }
497 eina_strbuf_append_printf(fbody, " return %s;\n", val_str?val_str:"0");
498 }
499 eina_strbuf_append_printf(fbody, "}\n\n");
500 }
501 else if (eina_strbuf_length_get(params_init))
502 {
503 /* Generation of the user function invocation, e.g return _user_foo(obj, pd, ...) */
504 eina_strbuf_append_printf(fbody, " %s_%s%s%s_%s%s(obj, pd, %s);\n}\n\n",
505 rettype?"return ":"",
506 class_env.lower_classname,
507 impl_env?"_":"",
508 impl_env?impl_env->lower_classname:"",
509 eolian_function_name_get(funcid), suffix,
510 eina_strbuf_string_get(params));
511 }
512 eina_strbuf_free(ret_param);
513 }
514 if (!impl_env)
515 {
516 Eina_Strbuf *eo_func_decl = eina_strbuf_new();
517 Eina_Bool has_params = EINA_FALSE;
518
519 itr = eolian_property_keys_get(funcid, ftype);
520 has_params |= (eina_iterator_next(itr, &data));
521 eina_iterator_free(itr);
522
523 if (!has_params && !var_as_ret)
524 {
525 itr = is_prop ? eolian_property_values_get(funcid, ftype) : eolian_function_parameters_get(funcid);
526 has_params |= (eina_iterator_next(itr, &data));
527 eina_iterator_free(itr);
528 }
529 Eina_Bool ret_is_void = (!rettype || !strcmp(rettype, "void"));
530 _class_func_env_create(class, eolian_function_name_get(funcid), ftype, &func_env);
531 eina_strbuf_append_printf(eo_func_decl,
532 "EOAPI EFL_%sFUNC_BODY%s%s(%s",
533 ret_is_void?"VOID_":"", has_params?"V":"",
534 (ftype == EOLIAN_PROP_GET ||
535 eolian_function_object_is_const(funcid) ||
536 eolian_function_is_class(funcid))?"_CONST":"", func_env.lower_eo_func);
537 if (!ret_is_void)
538 {
539 const char *val_str = NULL;
540 if (default_ret_val)
541 {
542 Eolian_Value val = eolian_expression_eval
543 (default_ret_val, EOLIAN_MASK_ALL);
544 if (val.type)
545 val_str = eolian_expression_value_to_literal(&val);
546 }
547 eina_strbuf_append_printf(eo_func_decl, ", %s, %s",
548 rettype, val_str?val_str:"0");
549 if (val_str && eolian_expression_type_get(default_ret_val) == EOLIAN_EXPR_NAME)
550 {
551 Eina_Stringshare *string = eolian_expression_serialize(default_ret_val);
552 eina_strbuf_append_printf(eo_func_decl, " /* %s */", string);
553 eina_stringshare_del(string);
554 }
555 }
556 if (has_params)
557 {
558 eina_strbuf_replace_all(full_params, " EINA_UNUSED", "");
559 eina_strbuf_append_printf(eo_func_decl, ", EFL_FUNC_CALL(%s)%s",
560 eina_strbuf_string_get(params),
561 eina_strbuf_string_get(full_params));
562 }
563 eina_strbuf_append_printf(eo_func_decl, ");");
564
565 if(has_promise)
566 {
567 eina_strbuf_append_printf(fbody,
568 "#undef _EFL_OBJECT_API_BEFORE_HOOK\n#undef _EFL_OBJECT_API_AFTER_HOOK\n#undef _EFL_OBJECT_API_CALL_HOOK\n"
569 "#define _EFL_OBJECT_API_BEFORE_HOOK _EINA_PROMISE_BEFORE_HOOK(%s, %s%s)\n"
570 "#define _EFL_OBJECT_API_AFTER_HOOK _EINA_PROMISE_AFTER_HOOK(%s)\n"
571 "#define _EFL_OBJECT_API_CALL_HOOK(x) _EINA_PROMISE_CALL_HOOK(EFL_FUNC_CALL(%s))\n\n",
572 promise_value_type, !rettype ? "void" : rettype,
573 eina_strbuf_string_get(impl_full_params),
574 promise_param_name,
575 eina_strbuf_string_get(params));
576 }
577
578 eina_strbuf_append_printf(fbody, "%s\n", eina_strbuf_string_get(eo_func_decl));
579
580 if(has_promise)
581 {
582 eina_strbuf_append_printf(fbody, "\n#undef _EFL_OBJECT_API_BEFORE_HOOK\n#undef _EFL_OBJECT_API_AFTER_HOOK\n#undef _EFL_OBJECT_API_CALL_HOOK\n"
583 "#define _EFL_OBJECT_API_BEFORE_HOOK\n#define _EFL_OBJECT_API_AFTER_HOOK\n"
584 "#define _EFL_OBJECT_API_CALL_HOOK(x) x\n");
585 }
586
587 eina_strbuf_free(eo_func_decl);
588 }
589
590 if (need_implementation)
591 {
592 Eina_Bool is_cf = eolian_function_is_class(funcid);
593 const char *data_type = eolian_class_data_type_get(class);
594 if (is_cf || (data_type && !strcmp(data_type, "null")))
595 eina_strbuf_replace_all(fbody, "@#Datatype_Data", "void");
596 else
597 {
598 if (data_type) eina_strbuf_replace_all(fbody, "@#Datatype_Data", data_type);
599 else eina_strbuf_replace_all(fbody, "@#Datatype", class_env.full_classname);
600 }
601
602 if (!data_type || !strcmp(data_type, "null"))
603 eina_strbuf_replace_all(fbody, "@#Datatype", class_env.full_classname);
604 else
605 eina_strbuf_replace_all(fbody, "@#Datatype_Data", data_type);
606 }
607 eina_strbuf_append(buf, eina_strbuf_string_get(fbody));
608
609 if (rettype) eina_stringshare_del(rettype);
610
611 eina_strbuf_free(va_args);
612 eina_strbuf_free(full_params);
613 eina_strbuf_free(impl_full_params);
614 eina_strbuf_free(params_init);
615 eina_strbuf_free(params);
616 eina_strbuf_free(fbody);
617 return EINA_TRUE;
618}
619
620static Eina_Bool
621eo_op_desc_generate(const Eolian_Class *class, const Eolian_Function *fid, Eolian_Function_Type ftype,
622 Eina_Strbuf *buf)
623{
624 _eolian_class_func_vars func_env;
625 const char *funcname = eolian_function_name_get(fid);
626 const char *suffix = "";
627
628 eina_strbuf_reset(buf);
629 _class_func_env_create(class, funcname, ftype, &func_env);
630 if (ftype == EOLIAN_PROP_GET) suffix = "_get";
631 if (ftype == EOLIAN_PROP_SET) suffix = "_set";
632 Eina_Bool is_virtual_pure = eolian_function_is_virtual_pure(fid, ftype);
633 eina_strbuf_append_printf(buf, "\n EFL_OBJECT_OP_FUNC(%s, ", func_env.lower_eo_func);
634 if (!is_virtual_pure)
635 {
636 Eolian_Function_Type ftype2 = (Eolian_Function_Type) eina_hash_find(_funcs_params_init, funcname);
637 eina_strbuf_append_printf(buf, "%s_%s_%s%s),",
638 ftype == ftype2?"__eolian":"",
639 class_env.lower_classname, funcname, suffix);
640 }
641 else
642 eina_strbuf_append_printf(buf, "NULL),");
643
644 return EINA_TRUE;
645}
646
647static Eina_Bool
648eo_source_beginning_generate(const Eolian_Class *class, Eina_Strbuf *buf)
649{
650 Eina_Iterator *itr;
651
652 Eina_Strbuf *tmpbuf = eina_strbuf_new();
653
654 Eolian_Event *event;
655 itr = eolian_class_events_get(class);
656 EINA_ITERATOR_FOREACH(itr, event)
657 {
658 Eina_Stringshare *evname = eolian_event_c_name_get(event);
659
660 eina_strbuf_append_printf(tmpbuf,
661 "EOAPI const Efl_Event_Description _%s =\n EFL_EVENT_DESCRIPTION%s%s(\"%s\");\n",
662 evname,
663 eolian_event_is_hot(event) ? "_HOT" : "",
664 eolian_event_is_restart(event) ? "_RESTART" : "",
665 eolian_event_name_get(event));
666 eina_stringshare_del(evname);
667 }
668 eina_iterator_free(itr);
669
670 eina_strbuf_append(buf, eina_strbuf_string_get(tmpbuf));
671
672 eina_strbuf_free(tmpbuf);
673 return EINA_TRUE;
674}
675
676static void
677_desc_generate(const Eolian_Class *class, const Eolian_Function *fid, Eolian_Function_Type ftype, Eina_Strbuf *tmpbuf, Eina_Strbuf *str_op)
678{
679 const char *funcname = eolian_function_name_get(fid);
680 char tmpstr[256];
681 snprintf(tmpstr, sizeof(tmpstr), "%s%s", funcname, (ftype == EOLIAN_PROP_SET)
682 ? "_set" : ((ftype == EOLIAN_PROP_GET) ? "_get" : ""));
683
684 eo_op_desc_generate(class, fid, ftype, tmpbuf);
685 eina_strbuf_append(str_op, eina_strbuf_string_get(tmpbuf));
686}
687
688static Eina_Bool
689eo_source_end_generate(const Eolian_Class *class, Eina_Strbuf *buf)
690{
691 Eina_Bool ret = EINA_FALSE;
692 Eina_Iterator *itr;
693 Eolian_Implement *impl_desc;
694 const char *inherit_name;
695
696 const char *str_classtype = NULL;
697 switch(eolian_class_type_get(class))
698 {
699 case EOLIAN_CLASS_REGULAR:
700 str_classtype = "EFL_CLASS_TYPE_REGULAR";
701 break;
702 case EOLIAN_CLASS_ABSTRACT:
703 str_classtype = "EFL_CLASS_TYPE_REGULAR_NO_INSTANT";
704 break;
705 case EOLIAN_CLASS_MIXIN:
706 str_classtype = "EFL_CLASS_TYPE_MIXIN";
707 break;
708 case EOLIAN_CLASS_INTERFACE:
709 str_classtype = "EFL_CLASS_TYPE_INTERFACE";
710 break;
711 default:
712 break;
713 }
714
715 if (!str_classtype)
716 {
717 fprintf(stderr, "eolian: unknown class type for class '%s'\n",
718 class_env.full_classname);
719 return EINA_FALSE;
720 }
721
722 Eina_Strbuf *str_end = eina_strbuf_new();
723 Eina_Strbuf *tmpbuf = eina_strbuf_new();
724 Eina_Strbuf *str_op = eina_strbuf_new();
725 Eina_Strbuf *str_cop = eina_strbuf_new();
726 Eina_Strbuf *str_bodyf = eina_strbuf_new();
727
728 _template_fill(str_end, tmpl_eo_src, class, NULL, NULL, EINA_TRUE);
729
730 eina_strbuf_replace_all(str_end, "@#type_class", str_classtype);
731 eina_strbuf_replace_all(str_end, "@#EOPREFIX", class_env.upper_eo_prefix);
732 eina_strbuf_replace_all(str_end, "@#eoprefix", class_env.lower_eo_prefix);
733 eina_strbuf_replace_all(str_end, "@#klasstype_get", eolian_class_c_get_function_name_get(class));
734
735 eina_strbuf_reset(tmpbuf);
736 eina_strbuf_replace_all(str_end, "@#ctor_func", eina_strbuf_string_get(tmpbuf));
737
738 eina_strbuf_reset(tmpbuf);
739 if (eolian_class_ctor_enable_get(class))
740 _template_fill(tmpbuf, "_@#class_class_constructor", class, NULL, NULL, EINA_TRUE);
741 else
742 eina_strbuf_append_printf(tmpbuf, "NULL");
743 eina_strbuf_replace_all(str_end, "@#ctor_name", eina_strbuf_string_get(tmpbuf));
744
745 eina_strbuf_reset(tmpbuf);
746 if (eolian_class_dtor_enable_get(class))
747 {
748 eina_strbuf_replace_all(str_end, "@#dtor_func", eina_strbuf_string_get(tmpbuf));
749 eina_strbuf_reset(tmpbuf);
750 _template_fill(tmpbuf, "_@#class_class_destructor", class, NULL, NULL, EINA_TRUE);
751 eina_strbuf_replace_all(str_end, "@#dtor_name", eina_strbuf_string_get(tmpbuf));
752 }
753 else
754 {
755 eina_strbuf_replace_all(str_end, "@#dtor_func", "");
756 eina_strbuf_replace_all(str_end, "@#dtor_name", "NULL");
757 }
758
759 eina_strbuf_reset(tmpbuf);
760
761 //Implements - TODO one generate func def for all
762 itr = eolian_class_implements_get(class);
763 EINA_ITERATOR_FOREACH(itr, impl_desc)
764 {
765 _eolian_class_vars impl_env;
766 char implname[0xFF];
767 const Eolian_Class *impl_class = NULL;
768 Eolian_Function_Type ftype;
769 const Eolian_Function *fnid = NULL;
770 const char *funcname = NULL;
771
772 const char *names[] = { "", "getter ", "setter " };
773
774 impl_class = eolian_implement_class_get(impl_desc);
775
776 if (impl_class)
777 {
778 char *tp = implname;
779 if (impl_class == class)
780 continue;
781 fnid = eolian_implement_function_get(impl_desc, &ftype);
782 _class_env_create(impl_class, NULL, &impl_env);
783 funcname = eolian_function_name_get(fnid);
784
785 Eina_Bool dflt_values = EINA_FALSE;
786 Eina_Iterator *pitr = NULL;
787 if (!eolian_implement_is_auto(impl_desc) && fnid && (ftype != EOLIAN_PROP_SET))
788 {
789 Eolian_Function_Parameter *param;
790 pitr = (ftype == EOLIAN_METHOD) ? eolian_function_parameters_get(fnid)
791 : eolian_property_values_get(fnid, ftype);
792 EINA_ITERATOR_FOREACH(pitr, param)
793 {
794 const Eolian_Expression *dflt_value = eolian_parameter_default_value_get(param);
795 if (dflt_value)
796 {
797 Eolian_Value val = eolian_expression_eval
798 (dflt_value, EOLIAN_MASK_ALL);
799 if (val.type)
800 {
801 dflt_values = EINA_TRUE;
802 break;
803 }
804 }
805 }
806 eina_iterator_free(pitr);
807 }
808
809 sprintf(implname, "%s_%s_%s",
810 (eolian_implement_is_auto(impl_desc) || eolian_implement_is_empty(impl_desc) || dflt_values)?
811 "__eolian":"",
812 class_env.full_classname, impl_env.full_classname);
813 eina_str_tolower(&tp);
814 }
815
816 if (!fnid)
817 {
818 const char *name = names[eolian_implement_is_prop_get(impl_desc)
819 | (eolian_implement_is_prop_set(impl_desc) << 1)];
820 fprintf(stderr, "eolian: failed to generate implementation of '%s%s' - missing from superclass\n",
821 name, eolian_implement_full_name_get(impl_desc));
822 goto end;
823 }
824
825 Eina_Strbuf *wbuf = str_op;
826 if (eolian_function_is_class(fnid)) wbuf = str_cop;
827
828 switch (ftype)
829 {
830 case EOLIAN_PROP_SET: case EOLIAN_PROP_GET: case EOLIAN_PROPERTY:
831 if (ftype != EOLIAN_PROP_GET)
832 {
833 Eina_Stringshare *rets = eolian_function_full_c_name_get(fnid, EOLIAN_PROP_SET, EINA_FALSE);
834 eina_strbuf_append_printf(wbuf, "\n EFL_OBJECT_OP_FUNC(%s, %s_%s_set),",
835 rets, implname, funcname);
836 eo_bind_func_generate(class, fnid, EOLIAN_PROP_SET, str_bodyf, impl_desc, &impl_env);
837 eina_stringshare_del(rets);
838 }
839
840 if (ftype != EOLIAN_PROP_SET)
841 {
842 Eina_Stringshare *rets = eolian_function_full_c_name_get(fnid, EOLIAN_PROP_GET, EINA_FALSE);
843 eina_strbuf_append_printf(wbuf, "\n EFL_OBJECT_OP_FUNC(%s, %s_%s_get),",
844 rets, implname, funcname);
845 eo_bind_func_generate(class, fnid, EOLIAN_PROP_GET, str_bodyf, impl_desc, &impl_env);
846 eina_stringshare_del(rets);
847 }
848 break;
849 default:
850 {
851 Eina_Stringshare *rets = eolian_function_full_c_name_get(fnid, ftype, EINA_FALSE);
852 eina_strbuf_append_printf(wbuf, "\n EFL_OBJECT_OP_FUNC(%s, %s_%s),",
853 rets, implname, funcname);
854 eo_bind_func_generate(class, fnid, ftype, str_bodyf, impl_desc, &impl_env);
855 eina_stringshare_del(rets);
856 break;
857 }
858 }
859 }
860 eina_iterator_free(itr);
861
862 if ((itr = eolian_class_implements_get(class)))
863 {
864 const Eolian_Implement *impl;
865 EINA_ITERATOR_FOREACH(itr, impl)
866 {
867 if (eolian_implement_class_get(impl) != class)
868 continue;
869 Eolian_Function_Type ftype = EOLIAN_UNRESOLVED;
870 const Eolian_Function *fid = eolian_implement_function_get(impl, &ftype);
871
872 Eina_Strbuf *wbuf = str_op;
873 if (eolian_function_is_class(fid)) wbuf = str_cop;
874
875 Eina_Bool prop_read = (ftype == EOLIAN_PROPERTY || ftype == EOLIAN_PROP_GET);
876 Eina_Bool prop_write = (ftype == EOLIAN_PROPERTY || ftype == EOLIAN_PROP_SET);
877
878 if (!prop_read && !prop_write && !eolian_function_is_legacy_only(fid, EOLIAN_METHOD))
879 _desc_generate(class, fid, EOLIAN_METHOD, tmpbuf, wbuf);
880 if (prop_write && !eolian_function_is_legacy_only(fid, EOLIAN_PROP_SET))
881 _desc_generate(class, fid, EOLIAN_PROP_SET, tmpbuf, wbuf);
882 if (prop_read && !eolian_function_is_legacy_only(fid, EOLIAN_PROP_GET))
883 _desc_generate(class, fid, EOLIAN_PROP_GET, tmpbuf, wbuf);
884 }
885 eina_iterator_free(itr);
886 }
887
888 eina_strbuf_reset(tmpbuf);
889 itr = eolian_class_inherits_get(class);
890 EINA_ITERATOR_FOREACH(itr, inherit_name)
891 {
892 const Eolian_Class *inherit_class = eolian_class_get_by_name(inherit_name);
893 _eolian_class_vars inherit_env;
894 assert(inherit_class);
895 _class_env_create(inherit_class, NULL, &inherit_env);
896 eina_strbuf_append_printf(tmpbuf, "%s_%s, ", inherit_env.upper_classname,
897 inherit_env.upper_classtype);
898 }
899 eina_iterator_free(itr);
900
901 if (eina_strbuf_length_get(tmpbuf) == 0) eina_strbuf_append(tmpbuf, "NULL, ");
902 eina_strbuf_replace_all(str_end, "@#list_inherit", eina_strbuf_string_get(tmpbuf));
903
904 Eina_Strbuf *ops_buf = eina_strbuf_new(), *cops_buf = eina_strbuf_new();
905
906 if (eina_strbuf_length_get(str_op))
907 {
908 size_t stroplen = eina_strbuf_length_get(str_op);
909 if (eina_strbuf_string_get(str_op)[stroplen - 1] == ',')
910 eina_strbuf_remove(str_op, stroplen - 1, stroplen);
911 _template_fill(ops_buf, tmpl_eo_ops_def, class, NULL, NULL, EINA_TRUE);
912 eina_strbuf_replace_all(ops_buf, "@#list_op", eina_strbuf_string_get(str_op));
913 }
914
915 if (eina_strbuf_length_get(str_cop))
916 {
917 size_t strcoplen = eina_strbuf_length_get(str_cop);
918 if (eina_strbuf_string_get(str_cop)[strcoplen - 1] == ',')
919 eina_strbuf_remove(str_cop, strcoplen - 1, strcoplen);
920 _template_fill(cops_buf, tmpl_eo_cops_def, class, NULL, NULL, EINA_TRUE);
921 eina_strbuf_replace_all(cops_buf, "@#list_cop", eina_strbuf_string_get(str_cop));
922 }
923
924 if (eina_strbuf_length_get(ops_buf) || eina_strbuf_length_get(cops_buf))
925 {
926 Eina_Strbuf *ops_desc = eina_strbuf_new();
927 _template_fill(ops_desc, tmpl_eo_ops_desc, class, NULL, NULL, EINA_TRUE);
928 if (eina_strbuf_length_get(ops_buf))
929 {
930 eina_strbuf_replace_all(ops_desc, "@#list_ops", eina_strbuf_string_get(ops_buf));
931 eina_strbuf_replace_all(ops_desc, "@#ref_ops", "&ops");
932 }
933 else
934 {
935 eina_strbuf_replace_all(ops_desc, "@#list_ops", "");
936 eina_strbuf_replace_all(ops_desc, "@#ref_ops", "NULL");
937 }
938 if (eina_strbuf_length_get(cops_buf))
939 {
940 eina_strbuf_replace_all(ops_desc, "@#list_cops", eina_strbuf_string_get(cops_buf));
941 eina_strbuf_replace_all(ops_desc, "@#ref_cops", "&cops");
942 }
943 else
944 {
945 eina_strbuf_replace_all(ops_desc, "@#list_cops", "");
946 eina_strbuf_replace_all(ops_desc, "@#ref_cops", "NULL");
947 }
948 eina_strbuf_replace_all(str_end, "@#ops_desc", eina_strbuf_string_get(ops_desc));
949 eina_strbuf_free(ops_desc);
950 eina_strbuf_reset(tmpbuf);
951 _template_fill(tmpbuf, "_@#class_class_initializer", class, NULL, NULL, EINA_TRUE);
952 eina_strbuf_replace_all(str_end, "@#init_name", eina_strbuf_string_get(tmpbuf));
953 }
954 else
955 {
956 eina_strbuf_replace_all(str_end, "@#ops_desc", "");
957 eina_strbuf_replace_all(str_end, "@#init_name", "NULL");
958 }
959
960 eina_strbuf_free(ops_buf);
961 eina_strbuf_free(cops_buf);
962
963 eina_strbuf_replace_all(str_end, "@#functions_body", eina_strbuf_string_get(str_bodyf));
964
965 const char *data_type = eolian_class_data_type_get(class);
966 if (data_type && !strcmp(data_type, "null"))
967 eina_strbuf_replace_all(str_end, "@#SizeOfData", "0");
968 else
969 {
970 Eina_Strbuf *sizeofbuf = eina_strbuf_new();
971 eina_strbuf_append_printf(sizeofbuf, "sizeof(%s%s)",
972 data_type?data_type:class_env.full_classname,
973 data_type?"":"_Data");
974 eina_strbuf_replace_all(str_end, "@#SizeOfData", eina_strbuf_string_get(sizeofbuf));
975 eina_strbuf_free(sizeofbuf);
976 }
977 eina_strbuf_append(buf, eina_strbuf_string_get(str_end));
978
979 ret = EINA_TRUE;
980end:
981 eina_strbuf_free(tmpbuf);
982 eina_strbuf_free(str_op);
983 eina_strbuf_free(str_cop);
984 eina_strbuf_free(str_bodyf);
985 eina_strbuf_free(str_end);
986
987 return ret;
988}
989
990Eina_Bool
991eo_source_generate(const Eolian_Class *class, Eina_Strbuf *buf)
992{
993 Eina_Bool ret = EINA_FALSE;
994 Eina_Iterator *itr = NULL;
995
996 Eina_Strbuf *str_bodyf = eina_strbuf_new();
997
998 _class_env_create(class, NULL, &class_env);
999 _funcs_params_init = eina_hash_stringshared_new(NULL);
1000
1001 if (!eo_source_beginning_generate(class, buf)) goto end;
1002
1003 if ((itr = eolian_class_implements_get(class)))
1004 {
1005 const Eolian_Implement *impl;
1006 EINA_ITERATOR_FOREACH(itr, impl)
1007 {
1008 if (eolian_implement_class_get(impl) != class)
1009 continue;
1010 Eolian_Function_Type ftype = EOLIAN_UNRESOLVED;
1011 const Eolian_Function *fid = eolian_implement_function_get(impl, &ftype);
1012 switch (ftype)
1013 {
1014 case EOLIAN_PROP_GET: case EOLIAN_PROP_SET:
1015 if (!eo_bind_func_generate(class, fid, ftype, str_bodyf, NULL, NULL))
1016 goto end;
1017 break;
1018 case EOLIAN_PROPERTY:
1019 if (!eo_bind_func_generate(class, fid, EOLIAN_PROP_SET, str_bodyf, NULL, NULL))
1020 goto end;
1021 if (!eo_bind_func_generate(class, fid, EOLIAN_PROP_GET, str_bodyf, NULL, NULL))
1022 goto end;
1023 break;
1024 default:
1025 if (!eo_bind_func_generate(class, fid, EOLIAN_UNRESOLVED, str_bodyf, NULL, NULL))
1026 goto end;
1027 break;
1028 }
1029 }
1030 eina_iterator_free(itr);
1031 itr = NULL;
1032 }
1033
1034 eina_strbuf_append(buf, eina_strbuf_string_get(str_bodyf));
1035 eina_strbuf_reset(str_bodyf);
1036
1037 if (!eo_source_end_generate(class, buf)) goto end;
1038
1039 ret = EINA_TRUE;
1040end:
1041 if (itr) eina_iterator_free(itr);
1042 eina_hash_free(_funcs_params_init);
1043 _funcs_params_init = NULL;
1044 eina_strbuf_free(str_bodyf);
1045 return ret;
1046}
1047
diff --git a/src/bin/eolian/eo_generator.h b/src/bin/eolian/eo_generator.h
deleted file mode 100644
index fc47a7b8ca..0000000000
--- a/src/bin/eolian/eo_generator.h
+++ /dev/null
@@ -1,34 +0,0 @@
1#ifndef EO1_GENERATOR_H
2#define EO1_GENERATOR_H
3
4#include<Eina.h>
5
6/*
7 * @brief Generate Eo source code for Eo class
8 *
9 * This function generates all the source code for Eo.
10 *
11 * @param[in] classname class name
12 * @param[inout] buf buffer to fill
13 *
14 * @return EINA_TRUE on success, EINA_FALSE on error.
15 *
16 */
17Eina_Bool
18eo_source_generate(const Eolian_Class *class, Eina_Strbuf *buf);
19
20/*
21 * @brief Generate the header code for a specific Eo class.
22 *
23 * This function generates header code from scratch.
24 *
25 * @param[in] classname class name
26 * @param[inout] buf buffer to fill
27 *
28 * @return EINA_TRUE on success, EINA_FALSE on error.
29 *
30 */
31Eina_Bool eo_header_generate(const Eolian_Class *class, Eina_Strbuf *buf);
32
33#endif
34
diff --git a/src/bin/eolian/impl_generator.c b/src/bin/eolian/impl_generator.c
deleted file mode 100644
index cd161855df..0000000000
--- a/src/bin/eolian/impl_generator.c
+++ /dev/null
@@ -1,324 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <Eina.h>
6#include <string.h>
7
8#include "Eolian.h"
9#include "impl_generator.h"
10#include "common_funcs.h"
11
12static _eolian_class_vars class_env;
13
14static Eina_Bool
15_params_generate(const Eolian_Function *foo, Eolian_Function_Type ftype, Eina_Bool var_as_ret, Eina_Strbuf *params, Eina_Strbuf *short_params)
16{
17 Eina_Iterator *itr;
18 Eolian_Function_Parameter *param;
19 Eina_Bool is_prop = (ftype == EOLIAN_PROP_GET || ftype == EOLIAN_PROP_SET);
20 eina_strbuf_reset(params);
21 eina_strbuf_reset(short_params);
22 itr = eolian_property_keys_get(foo, ftype);
23 EINA_ITERATOR_FOREACH(itr, param)
24 {
25 const Eolian_Type *ptypet = eolian_parameter_type_get(param);
26 const char *pname = eolian_parameter_name_get(param);
27 const char *ptype = eolian_type_c_type_get(ptypet);
28 Eina_Bool had_star = !!strchr(ptype, '*');
29 if (eina_strbuf_length_get(params))
30 {
31 eina_strbuf_append(params, ", ");
32 eina_strbuf_append(short_params, ", ");
33 }
34 eina_strbuf_append_printf(params, "%s%s%s",
35 ptype, had_star?"":" ", pname);
36 eina_strbuf_append_printf(short_params, "%s", pname);
37 eina_stringshare_del(ptype);
38 }
39 eina_iterator_free(itr);
40 if (!var_as_ret)
41 {
42 itr = is_prop ? eolian_property_values_get(foo, ftype) : eolian_function_parameters_get(foo);
43 EINA_ITERATOR_FOREACH(itr, param)
44 {
45 const Eolian_Type *ptypet = eolian_parameter_type_get(param);
46 const char *pname = eolian_parameter_name_get(param);
47 const char *ptype = eolian_type_c_type_get(ptypet);
48 Eolian_Parameter_Dir pdir = eolian_parameter_direction_get(param);
49 const char *add_star = _get_add_star(ftype, pdir);
50 Eina_Bool had_star = !!strchr(ptype, '*');
51 if (eina_strbuf_length_get(params))
52 {
53 eina_strbuf_append(params, ", ");
54 eina_strbuf_append(short_params, ", ");
55 }
56 eina_strbuf_append_printf(params, "%s%s%s%s",
57 ptype, had_star?"":" ", add_star, pname);
58 eina_strbuf_append_printf(short_params, "%s", pname);
59 eina_stringshare_del(ptype);
60 }
61 eina_iterator_free(itr);
62 }
63 return EINA_TRUE;
64}
65
66static Eina_Bool
67_function_exists(const char* func_name, Eina_Strbuf *buffer)
68{
69 const char *ptr = eina_strbuf_string_get(buffer);
70 int func_len = strlen(func_name);
71 while ((ptr = strstr(ptr, func_name)) != NULL)
72 {
73 switch (*(ptr - 1))
74 {
75 case '\n': case ' ':
76 {
77 switch (*(ptr + func_len))
78 {
79 case ' ': case '(':
80 return EINA_TRUE;
81 }
82 }
83 }
84 ptr++; /* so strstr doesn't fall again on func_name */
85 }
86 return EINA_FALSE;
87}
88
89/* Check if the type is used in the file, not if it is a typedef... */
90static Eina_Bool
91_type_exists(const char* type_name, Eina_Strbuf *buffer)
92{
93 const char *ptr = eina_strbuf_string_get(buffer);
94 int type_len = strlen(type_name);
95 while ((ptr = strstr(ptr, type_name)) != NULL)
96 {
97 switch (*(ptr - 1))
98 {
99 case '\n': case ' ': case ',':
100 {
101 switch (*(ptr + type_len))
102 {
103 case '\n': case ' ': case ',': case ';':
104 return EINA_TRUE;
105 }
106 }
107 }
108 ptr++; /* so strstr doesn't fall again on type_name */
109 }
110 return EINA_FALSE;
111}
112
113static Eina_Bool
114_prototype_generate(const Eolian_Function *foo, Eolian_Function_Type ftype, Eina_Strbuf *data_type_buf, Eolian_Implement *impl_desc, Eina_Strbuf *buffer)
115{
116 Eina_Bool var_as_ret = EINA_FALSE;
117 Eina_Strbuf *params = NULL, *short_params = NULL, *super_invok = NULL;
118 char func_name[PATH_MAX];
119 char impl_name[PATH_MAX];
120 const char *fname;
121 size_t flen;
122 _eolian_class_vars impl_env;
123
124 if (!impl_desc && eolian_function_is_virtual_pure(foo, ftype)) return EINA_TRUE;
125
126 super_invok = eina_strbuf_new();
127 if (impl_desc)
128 {
129 _class_env_create(eolian_implement_class_get(impl_desc), NULL, &impl_env);
130 char *tmp = impl_name;
131 sprintf(impl_name, "%s_%s", class_env.full_classname, impl_env.full_classname);
132 eina_str_tolower(&tmp);
133 }
134
135 sprintf(func_name, "_%s_%s%s",
136 impl_desc?impl_name:class_env.lower_classname, eolian_function_name_get(foo),
137 ftype == EOLIAN_PROP_GET?"_get": (ftype == EOLIAN_PROP_SET?"_set":""));
138
139 if (_function_exists(func_name, buffer)) goto end;
140
141 printf("Generation of function %s\n", func_name);
142 const Eolian_Type *rettypet = eolian_function_return_type_get(foo, ftype);
143 if (ftype == EOLIAN_PROP_GET && !rettypet)
144 {
145 Eina_Iterator *itr = eolian_property_values_get(foo, ftype);
146 void *data, *data2;
147 /* We want to check if there is only one parameter */
148 if (eina_iterator_next(itr, &data) && !eina_iterator_next(itr, &data2))
149 {
150 Eolian_Function_Parameter *param = data;
151 rettypet = eolian_parameter_type_get(param);
152 var_as_ret = EINA_TRUE;
153 }
154 eina_iterator_free(itr);
155 }
156
157 params = eina_strbuf_new();
158 short_params = eina_strbuf_new();
159 _params_generate(foo, ftype, var_as_ret, params, short_params);
160 if (eina_strbuf_length_get(params))
161 eina_strbuf_prepend_printf(params, ", ");
162 if (eina_strbuf_length_get(short_params))
163 eina_strbuf_prepend_printf(short_params, ", ");
164
165 fname = eolian_function_name_get(foo);
166 if (fname)
167 {
168 flen = strlen(fname);
169 if (flen >= strlen("destructor"))
170 {
171 if (impl_desc &&
172 (!strcmp(fname + flen - strlen("destructor"), "destructor")))
173 {
174 eina_strbuf_append_printf
175 (super_invok,
176 " %s_%s(efl_super(obj, %s_%s)%s);\n",
177 impl_env.lower_eo_prefix, eolian_function_name_get(foo),
178 class_env.upper_eo_prefix, class_env.upper_classtype,
179 eina_strbuf_string_get(short_params));
180 }
181 }
182 }
183
184 const char *rettype = NULL;
185 if (rettypet) rettype = eolian_type_c_type_get(rettypet);
186
187 eina_strbuf_append_printf(buffer,
188 "EOLIAN static %s\n%s(%sEo *obj, %s *pd%s%s)\n{\n%s\n}\n\n",
189 !rettype?"void":rettype,
190 func_name,
191 eolian_function_object_is_const(foo)?"const ":"",
192 !eina_strbuf_length_get(data_type_buf) ? "void" : eina_strbuf_string_get(data_type_buf),
193 !eina_strbuf_length_get(data_type_buf) ? " EINA_UNUSED" : "",
194 eina_strbuf_string_get(params),
195 eina_strbuf_string_get(super_invok)
196 );
197
198 if (rettype) eina_stringshare_del(rettype);
199
200end:
201 eina_strbuf_free(short_params);
202 eina_strbuf_free(params);
203 eina_strbuf_free(super_invok);
204 return EINA_TRUE;
205}
206
207Eina_Bool
208impl_source_generate(const Eolian_Class *class, Eina_Strbuf *buffer)
209{
210 Eina_Bool ret = EINA_FALSE;
211 Eina_Strbuf *data_type_buf = eina_strbuf_new();
212 Eina_Iterator *itr;
213 const Eolian_Function *foo;
214 Eina_Strbuf *begin = eina_strbuf_new();
215 char core_incl[PATH_MAX];
216
217 _class_env_create(class, NULL, &class_env);
218
219 if (!_type_exists("EFL_BETA_API_SUPPORT", buffer))
220 {
221 printf("Generation of EFL_BETA_API_SUPPORT\n");
222 eina_strbuf_append_printf(begin, "#define EFL_BETA_API_SUPPORT\n");
223 }
224
225 if (!_type_exists("<Eo.h>", buffer))
226 {
227 printf("Generation of #include <Eo.h> and \"%s.eo.h\"\n", class_env.lower_classname);
228 eina_strbuf_append_printf(begin, "#include <Eo.h>\n#include \"%s.eo.h\"\n\n", class_env.lower_classname);
229 }
230
231 /* Little calculation of the prefix of the data */
232 const char *data_type = eolian_class_data_type_get(class);
233 if (data_type)
234 {
235 if (strcmp(data_type, "null"))
236 eina_strbuf_append_printf(data_type_buf, "%s", data_type);
237 }
238 else
239 eina_strbuf_append_printf(data_type_buf, "%s_Data", class_env.full_classname);
240
241 /* Definition of the structure */
242 const char *data_type_str = eina_strbuf_string_get(data_type_buf);
243 if (!_type_exists(data_type_str, buffer) && 0 != eina_strbuf_length_get(data_type_buf))
244 {
245 printf("Generation of type %s\n", data_type_str);
246 eina_strbuf_append_printf(begin, "typedef struct\n{\n\n} %s;\n\n", data_type_str);
247 }
248
249 if (eina_strbuf_length_get(begin))
250 eina_strbuf_prepend_printf(buffer, "%s", eina_strbuf_string_get(begin));
251 eina_strbuf_free(begin);
252
253 itr = eolian_class_implements_get(class);
254 if (itr)
255 {
256 Eolian_Implement *impl_desc;
257 const char *names[] = { "", "getter ", "setter " };
258 EINA_ITERATOR_FOREACH(itr, impl_desc)
259 {
260 Eolian_Function_Type ftype;
261 Eolian_Implement *idesc = (eolian_implement_class_get(impl_desc) == class) ? NULL : impl_desc;
262 if (!(foo = eolian_implement_function_get(impl_desc, &ftype)))
263 {
264 const char *name = names[eolian_implement_is_prop_get(impl_desc)
265 | (eolian_implement_is_prop_set(impl_desc) << 1)];
266 fprintf(stderr, "eolian: failed to generate implementation of '%s%s' - missing from class\n",
267 name, eolian_implement_full_name_get(impl_desc));
268 goto end;
269 }
270 switch (ftype)
271 {
272 case EOLIAN_PROP_SET: case EOLIAN_PROP_GET:
273 _prototype_generate(foo, ftype, data_type_buf, idesc, buffer);
274 break;
275 case EOLIAN_PROPERTY:
276 _prototype_generate(foo, EOLIAN_PROP_SET, data_type_buf, idesc, buffer);
277 _prototype_generate(foo, EOLIAN_PROP_GET, data_type_buf, idesc, buffer);
278 break;
279 default:
280 _prototype_generate(foo, eolian_function_type_get(foo), data_type_buf, idesc, buffer);
281 break;
282 }
283 }
284 eina_iterator_free(itr);
285 }
286
287 if (eolian_class_ctor_enable_get(class))
288 {
289 char func_name[100];
290 sprintf(func_name, "_%s_class_constructor", class_env.lower_classname);
291 if (!_function_exists(func_name, buffer))
292 {
293 printf("Generation of function %s\n", func_name);
294 eina_strbuf_append_printf(buffer,
295 "EOLIAN static void\n_%s_class_constructor(Efl_Class *klass)\n{\n\n}\n\n",
296 class_env.lower_classname);
297 }
298 }
299
300 if (eolian_class_dtor_enable_get(class))
301 {
302 char func_name[100];
303 sprintf(func_name, "_%s_class_destructor", class_env.lower_classname);
304 if (!_function_exists(func_name, buffer))
305 {
306 printf("Generation of function %s\n", func_name);
307 eina_strbuf_append_printf(buffer, "EOLIAN static void\n_%s_class_destructor(Efl_Class *klass)\n{\n\n}\n\n",
308 class_env.lower_classname);
309 }
310 }
311 printf("Removal of all inline instances of #include \"%s.eo.c\"\n", class_env.lower_classname);
312 snprintf(core_incl, sizeof(core_incl), "\n#include \"%s.eo.c\"\n", class_env.lower_classname);
313 eina_strbuf_replace_all(buffer, core_incl, "\n");
314
315 snprintf(core_incl, sizeof(core_incl), "\"%s.eo.c\"", class_env.lower_classname);
316 printf("Generation of #include \"%s.eo.c\"\n", class_env.lower_classname);
317 eina_strbuf_append_printf(buffer, "#include \"%s.eo.c\"\n", class_env.lower_classname);
318
319 ret = EINA_TRUE;
320end:
321 eina_strbuf_free(data_type_buf);
322 return ret;
323}
324
diff --git a/src/bin/eolian/impl_generator.h b/src/bin/eolian/impl_generator.h
deleted file mode 100644
index a4686e2b9e..0000000000
--- a/src/bin/eolian/impl_generator.h
+++ /dev/null
@@ -1,22 +0,0 @@
1#ifndef IMPL_GENERATOR_H
2#define IMPL_GENERATOR_H
3
4#include<Eina.h>
5
6/*
7 * @brief Generate the implementation source code of a class
8 *
9 * This function generates all the source code of a class.
10 *
11 * @param[in] classname class name
12 * @param[inout] buf buffer to fill
13 *
14 * @return EINA_TRUE on success, EINA_FALSE on error.
15 *
16 */
17Eina_Bool
18impl_source_generate(const Eolian_Class *class, Eina_Strbuf *buf);
19
20#endif
21
22
diff --git a/src/bin/eolian/legacy_generator.c b/src/bin/eolian/legacy_generator.c
deleted file mode 100644
index cf913435b3..0000000000
--- a/src/bin/eolian/legacy_generator.c
+++ /dev/null
@@ -1,416 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <Eina.h>
6#include <string.h>
7
8#include "Eolian.h"
9
10#include "legacy_generator.h"
11#include "docs_generator.h"
12#include "common_funcs.h"
13
14static _eolian_class_vars class_env;
15
16static const char
17tmpl_eapi_funcdef[] = "EAPI @#type_return%s(@#params)@#flags;\n";
18
19/*@#CLASS_CHECK(obj) @#check_ret;\n\*/
20static const char
21tmpl_eapi_body[] ="\
22\n\
23EAPI @#ret_type\n\
24@#eapi_func(@#full_params)\n\
25{\n\
26 return @#eo_func(@#eo_obj@#eo_params);\n\
27}\n\
28";
29static const char
30tmpl_eapi_body_void[] ="\
31\n\
32EAPI void\n\
33@#eapi_func(@#full_params)\n\
34{\n\
35 @#eo_func(@#eo_obj@#eo_params);\n\
36}\n\
37";
38
39static void
40_eapi_decl_func_generate(const Eolian_Class *class, const Eolian_Function *funcid, Eolian_Function_Type ftype, Eina_Strbuf *buf)
41{
42 _eolian_class_func_vars func_env;
43 const char *funcname = eolian_function_name_get(funcid);
44 const Eolian_Type *rettypet = NULL;
45 const char *rettype = NULL;
46 Eina_Bool var_as_ret = EINA_FALSE;
47 Eina_Bool is_prop = (ftype == EOLIAN_PROP_GET || ftype == EOLIAN_PROP_SET);
48 Eina_Iterator *itr;
49 void *data, *data2;
50 Eina_Strbuf *flags = NULL;
51 int leg_param_idx = 1; /* Index of the parameter inside the legacy function. It begins from 1 since obj is the first. */
52
53 Eina_Strbuf *fbody = eina_strbuf_new();
54 Eina_Strbuf *fparam = eina_strbuf_new();
55
56 _class_func_env_create(class, funcname, ftype, &func_env);
57 rettypet = eolian_function_return_type_get(funcid, ftype);
58 if (ftype == EOLIAN_PROP_GET)
59 {
60 if (!rettypet)
61 {
62 itr = eolian_property_values_get(funcid, ftype);
63 /* We want to check if there is only one parameter */
64 if (eina_iterator_next(itr, &data) && !eina_iterator_next(itr, &data2))
65 {
66 rettypet = eolian_parameter_type_get((Eolian_Function_Parameter*)data);
67 var_as_ret = EINA_TRUE;
68 }
69 eina_iterator_free(itr);
70 }
71 }
72
73 if (func_env.legacy_func[0] == '\0') goto end;
74
75 Eina_Bool hasnewdocs = eolian_function_documentation_get(funcid, EOLIAN_UNRESOLVED) ||
76 eolian_function_documentation_get(funcid, ftype);
77 if (hasnewdocs)
78 {
79 Eina_Strbuf *dbuf = docs_generate_function(funcid, ftype, 0, EINA_TRUE);
80 eina_strbuf_append_char(fbody, '\n');
81 eina_strbuf_append(fbody, eina_strbuf_string_get(dbuf));
82 eina_strbuf_append_char(fbody, '\n');
83 eina_strbuf_free(dbuf);
84 }
85
86 eina_strbuf_append_printf(fbody, tmpl_eapi_funcdef, func_env.legacy_func);
87
88 if (!eolian_function_is_class(funcid))
89 {
90 if (ftype == EOLIAN_PROP_GET || eolian_function_object_is_const(funcid))
91 eina_strbuf_append(fparam, "const ");
92 eina_strbuf_append_printf(fparam, "%s *obj", class_env.full_classname);
93 }
94
95 itr = eolian_property_keys_get(funcid, ftype);
96 EINA_ITERATOR_FOREACH(itr, data)
97 {
98 Eolian_Function_Parameter *param = data;
99 const Eolian_Type *ptypet = eolian_parameter_type_get(param);
100 const char *pname = eolian_parameter_name_get(param);
101 const char *ptype = eolian_type_c_type_get(ptypet);
102 leg_param_idx++;
103 if (eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, ", ");
104 eina_strbuf_append_printf(fparam, "%s %s", ptype, pname);
105 eina_stringshare_del(ptype);
106
107 if (eolian_parameter_is_nonull((Eolian_Function_Parameter*)data))
108 {
109 if (!flags)
110 {
111 flags = eina_strbuf_new();
112 eina_strbuf_append_printf(flags, " EINA_ARG_NONNULL(%d", leg_param_idx);
113 }
114 else
115 eina_strbuf_append_printf(flags, ", %d", leg_param_idx);
116 }
117 }
118 eina_iterator_free(itr);
119 if (!var_as_ret)
120 {
121 itr = is_prop ? eolian_property_values_get(funcid, ftype) : eolian_function_parameters_get(funcid);
122 EINA_ITERATOR_FOREACH(itr, data)
123 {
124 Eolian_Function_Parameter *param = data;
125 const Eolian_Type *ptypet = eolian_parameter_type_get(param);
126 const char *pname = eolian_parameter_name_get(param);
127 const char *ptype = eolian_type_c_type_get(ptypet);
128 Eolian_Parameter_Dir pdir = eolian_parameter_direction_get(param);
129 Eina_Bool had_star = !!strchr(ptype, '*');
130
131 leg_param_idx++;
132 if (eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, ", ");
133 eina_strbuf_append_printf(fparam, "%s%s%s%s",
134 ptype, had_star?"":" ", _get_add_star(ftype, pdir), pname);
135 eina_stringshare_del(ptype);
136 if (eolian_parameter_is_nonull((Eolian_Function_Parameter*)data))
137 {
138 if (!flags)
139 {
140 flags = eina_strbuf_new();
141 eina_strbuf_append_printf(flags, " EINA_ARG_NONNULL(%d", leg_param_idx);
142 }
143 else
144 eina_strbuf_append_printf(flags, ", %d", leg_param_idx);
145 }
146 }
147 eina_iterator_free(itr);
148 }
149 if (!eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, "void");
150 if (flags) eina_strbuf_append_printf(flags, ")");
151
152 if (rettypet) rettype = eolian_type_c_type_get(rettypet);
153
154 eina_strbuf_replace_all(fbody, "@#params", eina_strbuf_string_get(fparam));
155 eina_strbuf_reset(fparam);
156 eina_strbuf_append_printf(fparam, "%s%s",
157 rettype ? rettype : "void",
158 rettype && strchr(rettype, '*')?"":" ");
159 eina_strbuf_replace_all(fbody, "@#type_return", eina_strbuf_string_get(fparam));
160 if (eolian_function_return_is_warn_unused(funcid, ftype))
161 {
162 Eina_Bool no_nonull = !flags;
163 if (no_nonull) flags = eina_strbuf_new();
164 eina_strbuf_prepend(flags, " EINA_WARN_UNUSED_RESULT");
165 }
166 if (flags)
167 eina_strbuf_replace_all(fbody, "@#flags", eina_strbuf_string_get(flags));
168 eina_strbuf_replace_all(fbody, "@#flags", (eolian_function_return_is_warn_unused(funcid, ftype)) ? " EINA_WARN_UNUSED_RESULT" : "");
169 eina_strbuf_append(buf, eina_strbuf_string_get(fbody));
170
171 if (rettype) eina_stringshare_del(rettype);
172
173end:
174 eina_strbuf_free(flags);
175 eina_strbuf_free(fbody);
176 eina_strbuf_free(fparam);
177}
178
179static void
180_eapi_func_generate(const Eolian_Class *class, const Eolian_Function *funcid, Eolian_Function_Type ftype, Eina_Strbuf *buf)
181{
182 _eolian_class_func_vars func_env;
183 char tmpstr[0xFF];
184 Eina_Bool var_as_ret = EINA_FALSE;
185 const Eolian_Type *rettypet = NULL;
186 const char *rettype = NULL;
187 const char *retname = NULL;
188 Eina_Bool ret_is_void = EINA_FALSE;
189 Eina_Bool is_prop = (ftype == EOLIAN_PROP_GET || ftype == EOLIAN_PROP_SET);
190
191 Eina_Strbuf *fbody = eina_strbuf_new();
192 Eina_Strbuf *fparam = eina_strbuf_new();
193 Eina_Strbuf *eoparam = eina_strbuf_new();
194
195 Eina_Iterator *itr;
196 void *data, *data2;
197
198 _class_func_env_create(class, eolian_function_name_get(funcid), ftype, &func_env);
199 rettypet = eolian_function_return_type_get(funcid, ftype);
200 if (rettypet) rettype = eolian_type_c_type_get(rettypet);
201 if (rettype && !strcmp(rettype, "void")) ret_is_void = EINA_TRUE;
202 retname = "ret";
203 if (ftype == EOLIAN_PROP_GET)
204 {
205 if (!rettypet)
206 {
207 itr = eolian_property_values_get(funcid, ftype);
208 /* We want to check if there is only one parameter */
209 if (eina_iterator_next(itr, &data) && !eina_iterator_next(itr, &data2))
210 {
211 Eolian_Function_Parameter *param = data;
212 rettypet = eolian_parameter_type_get(param);
213 retname = eolian_parameter_name_get(param);
214 var_as_ret = EINA_TRUE;
215 }
216 eina_iterator_free(itr);
217 }
218 }
219
220 if (func_env.legacy_func[0] == '\0') goto end;
221
222 if (!rettype && rettypet) rettype = eolian_type_c_type_get(rettypet);
223
224 if (rettype && (!ret_is_void))
225 eina_strbuf_append(fbody, tmpl_eapi_body);
226 else
227 eina_strbuf_append(fbody, tmpl_eapi_body_void);
228
229 if (!eolian_function_is_class(funcid))
230 {
231 if (ftype == EOLIAN_PROP_GET || eolian_function_object_is_const(funcid))
232 eina_strbuf_append(fparam, "const ");
233 eina_strbuf_append_printf(fparam, "%s *obj", class_env.full_classname);
234 char cbuf[256];
235 snprintf(cbuf, sizeof(cbuf), "(%s *)obj", class_env.full_classname);
236 eina_strbuf_replace_all(fbody, "@#eo_obj", cbuf);
237 }
238 else
239 {
240 Eina_Strbuf *class_buf = eina_strbuf_new();
241 _template_fill(class_buf, "@#CLASS_@#CLASSTYPE", class, NULL, NULL, EINA_TRUE);
242 eina_strbuf_replace_all(fbody, "@#eo_obj", eina_strbuf_string_get(class_buf));
243 eina_strbuf_free(class_buf);
244 }
245 eina_strbuf_replace_all(fbody, "@#eapi_func", func_env.legacy_func);
246 eina_strbuf_replace_all(fbody, "@#eo_func", func_env.lower_eo_func);
247
248 tmpstr[0] = '\0';
249
250 itr = eolian_property_keys_get(funcid, ftype);
251 EINA_ITERATOR_FOREACH(itr, data)
252 {
253 Eolian_Function_Parameter *param = data;
254 const Eolian_Type *ptypet = eolian_parameter_type_get(param);
255 const char *pname = eolian_parameter_name_get(param);
256 const char *ptype = eolian_type_c_type_get(ptypet);
257 if (eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, ", ");
258 eina_strbuf_append_printf(fparam, "%s %s", ptype, pname);
259 eina_stringshare_del(ptype);
260 eina_strbuf_append_printf(eoparam, ", %s", pname);
261 }
262 eina_iterator_free(itr);
263 if (!var_as_ret)
264 {
265 itr = is_prop ? eolian_property_values_get(funcid, ftype) : eolian_function_parameters_get(funcid);
266 EINA_ITERATOR_FOREACH(itr, data)
267 {
268 Eolian_Function_Parameter *param = data;
269 const Eolian_Type *ptypet = eolian_parameter_type_get(param);
270 const char *pname = eolian_parameter_name_get(param);
271 const char *ptype = eolian_type_c_type_get(ptypet);
272 Eolian_Parameter_Dir pdir = eolian_parameter_direction_get(param);
273 Eina_Bool had_star = !!strchr(ptype, '*');
274 if (eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, ", ");
275 eina_strbuf_append_printf(fparam, "%s%s%s%s",
276 ptype, had_star?"":" ", _get_add_star(ftype, pdir), pname);
277 eina_stringshare_del(ptype);
278 eina_strbuf_append_printf(eoparam, ", %s", pname);
279 }
280 eina_iterator_free(itr);
281 }
282 if (!eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, "void");
283
284 if (rettype && (!ret_is_void))
285 {
286 char tmp_ret_str[0xFF];
287 sprintf (tmp_ret_str, "%s", rettype);
288 const Eolian_Expression *default_ret_val =
289 eolian_function_return_default_value_get(funcid, ftype);
290 const char *val_str = NULL;
291 if (default_ret_val)
292 {
293 Eolian_Value val = eolian_expression_eval_type
294 (default_ret_val, rettypet);
295 if (val.type)
296 val_str = eolian_expression_value_to_literal(&val);
297 }
298 Eina_Bool had_star = !!strchr(rettype, '*');
299 sprintf (tmpstr, " %s%s%s = %s;\n",
300 rettype, had_star?"":" ", retname,
301 val_str?val_str:"0");
302
303 eina_strbuf_replace_all(fbody, "@#ret_type", tmp_ret_str);
304 eina_strbuf_replace_all(fbody, "@#ret_init_val", tmpstr);
305 }
306
307 eina_strbuf_replace_all(fbody, "@#full_params", eina_strbuf_string_get(fparam));
308 eina_strbuf_replace_all(fbody, "@#eo_params", eina_strbuf_string_get(eoparam));
309
310 eina_strbuf_replace_all(fbody, "@#ret_val", (rettype && !ret_is_void) ? retname : "");
311
312 eina_strbuf_append(buf, eina_strbuf_string_get(fbody));
313
314 if (rettype) eina_stringshare_del(rettype);
315
316end:
317 eina_strbuf_free(fbody);
318 eina_strbuf_free(fparam);
319 eina_strbuf_free(eoparam);
320}
321
322Eina_Bool
323legacy_header_generate(const Eolian_Class *class, Eina_Strbuf *buf)
324{
325 _class_env_create(class, NULL, &class_env);
326
327 const Eolian_Documentation *doc = eolian_class_documentation_get(class);
328 if (doc)
329 {
330 Eina_Strbuf *cdoc = docs_generate_full(doc, eolian_class_full_name_get(class), 0, EINA_TRUE);
331 if (cdoc)
332 {
333 eina_strbuf_append(buf, eina_strbuf_string_get(cdoc));
334 eina_strbuf_append_char(buf, '\n');
335 eina_strbuf_free(cdoc);
336 }
337 }
338
339 Eina_Iterator *itr = eolian_class_implements_get(class);
340 if (itr)
341 {
342 const Eolian_Implement *impl;
343 EINA_ITERATOR_FOREACH(itr, impl)
344 {
345 if (eolian_implement_class_get(impl) != class)
346 continue;
347 Eolian_Function_Type ftype = EOLIAN_UNRESOLVED;
348 const Eolian_Function *fid = eolian_implement_function_get(impl, &ftype);
349 if (eolian_function_is_beta(fid))
350 continue;
351 switch (ftype)
352 {
353 case EOLIAN_PROP_GET: case EOLIAN_PROP_SET:
354 _eapi_decl_func_generate(class, fid, ftype, buf);
355 break;
356 case EOLIAN_PROPERTY:
357 _eapi_decl_func_generate(class, fid, EOLIAN_PROP_SET, buf);
358 _eapi_decl_func_generate(class, fid, EOLIAN_PROP_GET, buf);
359 break;
360 default:
361 _eapi_decl_func_generate(class, fid, EOLIAN_METHOD, buf);
362 break;
363 }
364 }
365 eina_iterator_free(itr);
366 }
367 return EINA_TRUE;
368}
369
370Eina_Bool
371legacy_source_generate(const Eolian_Class *class, Eina_Strbuf *buf)
372{
373 Eina_Bool ret = EINA_FALSE;
374 Eina_Iterator *itr;
375
376 _class_env_create(class, NULL, &class_env);
377
378 Eina_Strbuf *tmpbuf = eina_strbuf_new();
379 Eina_Strbuf *str_bodyf = eina_strbuf_new();
380
381 if ((itr = eolian_class_implements_get(class)))
382 {
383 const Eolian_Implement *impl;
384 EINA_ITERATOR_FOREACH(itr, impl)
385 {
386 if (eolian_implement_class_get(impl) != class)
387 continue;
388 Eolian_Function_Type ftype = EOLIAN_UNRESOLVED;
389 const Eolian_Function *fid = eolian_implement_function_get(impl, &ftype);
390 if (eolian_function_is_beta(fid))
391 continue;
392 switch (ftype)
393 {
394 case EOLIAN_PROP_GET: case EOLIAN_PROP_SET:
395 _eapi_func_generate(class, fid, ftype, str_bodyf);
396 break;
397 case EOLIAN_PROPERTY:
398 _eapi_func_generate(class, fid, EOLIAN_PROP_SET, str_bodyf);
399 _eapi_func_generate(class, fid, EOLIAN_PROP_GET, str_bodyf);
400 break;
401 default:
402 _eapi_func_generate(class, fid, EOLIAN_METHOD, str_bodyf);
403 break;
404 }
405 }
406 eina_iterator_free(itr);
407 }
408
409 eina_strbuf_append(buf, eina_strbuf_string_get(str_bodyf));
410
411 ret = EINA_TRUE;
412 eina_strbuf_free(tmpbuf);
413 eina_strbuf_free(str_bodyf);
414
415 return ret;
416}
diff --git a/src/bin/eolian/legacy_generator.h b/src/bin/eolian/legacy_generator.h
deleted file mode 100644
index 0a69c96984..0000000000
--- a/src/bin/eolian/legacy_generator.h
+++ /dev/null
@@ -1,36 +0,0 @@
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[inout] buf buffer to fill
15 *
16 * @return EINA_TRUE on success, EINA_FALSE on error.
17 *
18 */
19Eina_Bool legacy_header_generate(const Eolian_Class *class, Eina_Strbuf *buf);
20
21/*
22 * @brief Generate C source code for Eo class
23 *
24 * This function needs to be used to generate C source code. It is generating
25 * code from scratch.
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 legacy_source_generate(const Eolian_Class *class, Eina_Strbuf *buf);
34
35#endif
36
diff --git a/src/bin/eolian/main.c b/src/bin/eolian/main.c
deleted file mode 100644
index 55c9399937..0000000000
--- a/src/bin/eolian/main.c
+++ /dev/null
@@ -1,407 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <getopt.h>
6#include <libgen.h>
7
8#include <Eina.h>
9
10#include "Eolian.h"
11#include "legacy_generator.h"
12#include "eo_generator.h"
13#include "impl_generator.h"
14#include "types_generator.h"
15#include "common_funcs.h"
16
17static Eina_Strbuf *
18_include_guard_enclose(const char *fname, const char *suffix, Eina_Strbuf *fbody)
19{
20 if (!fbody || !eina_strbuf_string_get(fbody))
21 return fbody;
22
23 if (!suffix)
24 suffix = "";
25
26 char incname[255];
27 memset(incname, 0, sizeof(incname));
28 strncpy (incname, fname, sizeof(incname) - 1);
29 char *p = incname;
30 eina_str_toupper(&p);
31
32 Eina_Strbuf *incguard = eina_strbuf_new();
33 eina_strbuf_append_printf(incguard, "#ifndef _%s_%s\n#define _%s_%s\n\n",
34 incname, suffix, incname, suffix);
35 eina_strbuf_replace_all(incguard, ".", "_");
36 eina_strbuf_append(incguard, eina_strbuf_string_get(fbody));
37 eina_strbuf_append(incguard, "\n#endif\n");
38 eina_strbuf_free(fbody);
39 return incguard;
40}
41
42static const char *
43_filename_get(const char *path)
44{
45 if (!path)
46 return NULL;
47 const char *ret = strrchr(path, '/');
48 if (!ret)
49 return path;
50 return ret + 1;
51}
52
53static Eina_Bool
54_read_file(const char *filename, Eina_Strbuf **buf)
55{
56 FILE *fd = fopen(filename, "rb");
57 if (!fd)
58 {
59 *buf = eina_strbuf_new();
60 return EINA_TRUE;
61 }
62
63 fseek(fd, 0, SEEK_END);
64 long file_size = ftell(fd);
65 if (file_size < 0)
66 {
67 fprintf(stderr, "eolian: could not get length of '%s'\n", filename);
68 fclose(fd);
69 return EINA_FALSE;
70 }
71 fseek(fd, 0, SEEK_SET);
72
73 char *content = malloc(file_size + 1);
74 if (!content)
75 {
76 fprintf(stderr, "eolian: could not allocate memory for '%s'\n", filename);
77 fclose(fd);
78 return EINA_FALSE;
79 }
80
81 long actual_size = (long)fread(content, 1, file_size, fd);
82 if (actual_size != file_size)
83 {
84 fprintf(stderr, "eolian: could not read %ld bytes from '%s' (read %ld bytes)\n",
85 file_size, filename, actual_size);
86 free(content);
87 fclose(fd);
88 return EINA_FALSE;
89 }
90
91 content[file_size] = '\0';
92 fclose(fd);
93 *buf = eina_strbuf_manage_new_length(content, file_size);
94 return EINA_TRUE;
95}
96
97static Eina_Bool
98_write_file(const char *filename, const Eina_Strbuf *buffer, Eina_Bool append)
99{
100 FILE *fd = fopen(filename, append ? "ab" : "wb");
101 if (!fd)
102 {
103 fprintf(stderr, "eolian: could not open '%s' for writing (%s)\n",
104 filename, strerror(errno));
105 return EINA_FALSE;
106 }
107
108 Eina_Bool ret = EINA_TRUE;
109 size_t blen = eina_strbuf_length_get(buffer);
110
111 if (!blen)
112 goto end;
113
114 if (fwrite(eina_strbuf_string_get(buffer), 1, blen, fd) != blen)
115 {
116 fprintf(stderr, "eolian: could not write '%s' (%s)\n",
117 filename, strerror(errno));
118 ret = EINA_FALSE;
119 }
120
121end:
122 fclose(fd);
123 return ret;
124}
125
126static Eina_Bool
127_generate_header(const char *outf, const char *inf, Eina_Bool legacy)
128{
129 Eina_Strbuf *buf = eina_strbuf_new();
130
131 if (!types_header_generate(inf, buf, EINA_TRUE, legacy))
132 {
133 fprintf(stderr, "eolian: could not generate types of '%s'\n", inf);
134 eina_strbuf_free(buf);
135 return EINA_FALSE;
136 }
137
138 buf = _include_guard_enclose(inf, "TYPES", buf);
139
140 Eina_Strbuf *ctbuf = eina_strbuf_new();
141 if (types_class_typedef_generate(inf, ctbuf))
142 {
143 ctbuf = _include_guard_enclose(inf, "CLASS_TYPE", ctbuf);
144 eina_strbuf_append_char(ctbuf, '\n');
145 eina_strbuf_prepend(buf, eina_strbuf_string_get(ctbuf));
146 }
147 eina_strbuf_free(ctbuf);
148
149 const Eolian_Class *cl = eolian_class_get_by_file(inf);
150 if (cl)
151 {
152 Eina_Bool gret = legacy ? legacy_header_generate(cl, buf)
153 : eo_header_generate(cl, buf);
154 if (!gret)
155 {
156 fprintf(stderr, "eolian: could not generate header for '%s'\n",
157 eolian_class_name_get(cl));
158 eina_strbuf_free(buf);
159 return EINA_FALSE;
160 }
161 }
162
163 if (cl || !legacy)
164 {
165 buf = _include_guard_enclose(_filename_get(outf), NULL, buf);
166 if (_write_file(outf, buf, EINA_FALSE))
167 {
168 eina_strbuf_free(buf);
169 return EINA_TRUE;
170 }
171 }
172
173 eina_strbuf_free(buf);
174 return EINA_FALSE;
175}
176
177static Eina_Bool
178_generate_stub_header(const char *outf, const char *inf)
179{
180 Eina_Strbuf *buf = eina_strbuf_new();
181
182 if (!types_header_generate(inf, buf, EINA_FALSE, EINA_FALSE))
183 {
184 fprintf(stderr, "eolian: could not generate types of '%s'\n", inf);
185 eina_strbuf_free(buf);
186 return EINA_FALSE;
187 }
188
189 Eina_Strbuf *ctbuf = eina_strbuf_new();
190 if (types_class_typedef_generate(inf, ctbuf))
191 {
192 eina_strbuf_append_char(ctbuf, '\n');
193 eina_strbuf_prepend(buf, eina_strbuf_string_get(ctbuf));
194 }
195 eina_strbuf_free(ctbuf);
196
197 buf = _include_guard_enclose(_filename_get(outf), "STUBS", buf);
198
199 Eina_Bool ret = _write_file(outf, buf, EINA_FALSE);
200 eina_strbuf_free(buf);
201 return ret;
202}
203
204static Eina_Bool
205_generate_c(const char *outf, const char *inf, Eina_Bool legacy)
206{
207 Eina_Strbuf *eobuf = eina_strbuf_new(),
208 *lgbuf = eina_strbuf_new();
209
210 const Eolian_Class *cl = eolian_class_get_by_file(inf);
211 if (cl)
212 {
213 if (!eo_source_generate(cl, eobuf))
214 {
215 fprintf(stderr, "eolian: could not generate source for '%s'\n",
216 eolian_class_name_get(cl));
217 eina_strbuf_free(eobuf);
218 eina_strbuf_free(lgbuf);
219 return EINA_FALSE;
220 }
221
222 if (legacy && !legacy_source_generate(cl, lgbuf))
223 {
224 fprintf(stderr, "eolian: could not generate source for '%s'\n",
225 eolian_class_name_get(cl));
226 eina_strbuf_free(eobuf);
227 eina_strbuf_free(lgbuf);
228 return EINA_FALSE;
229 }
230 }
231
232 Eina_Bool ret = _write_file(outf, eobuf, EINA_FALSE) &&
233 _write_file(outf, lgbuf, EINA_TRUE);
234 eina_strbuf_free(eobuf);
235 eina_strbuf_free(lgbuf);
236 return ret;
237}
238
239static Eina_Bool
240_generate_impl(const char *outf, const char *inf)
241{
242 const Eolian_Class *cl = eolian_class_get_by_file(inf);
243 if (!cl)
244 return EINA_FALSE;
245
246 Eina_Strbuf *buf = NULL;
247 if (!_read_file(outf, &buf))
248 return EINA_FALSE;
249
250 if (!impl_source_generate(cl, buf))
251 {
252 fprintf(stderr, "eolian: could not generate source for '%s'\n",
253 eolian_class_name_get(cl));
254 eina_strbuf_free(buf);
255 return EINA_FALSE;
256 }
257
258 Eina_Bool ret = _write_file(outf, buf, EINA_FALSE);
259 eina_strbuf_free(buf);
260 return ret;
261}
262
263enum
264{
265 GEN_NOTHING = 0,
266 GEN_H,
267 GEN_H_STUB,
268 GEN_C,
269 GEN_C_IMPL
270};
271
272int
273main(int argc, char **argv)
274{
275 int gen_what = GEN_NOTHING, do_legacy = 0, ret = 1, silent_types = 0;
276 Eina_Bool help = EINA_FALSE;
277 const char *outf = NULL;
278
279 eina_init();
280 eolian_init();
281
282 const char *dom = "eolian_gen";
283 _eolian_gen_log_dom = eina_log_domain_register(dom, EINA_COLOR_GREEN);
284 if (_eolian_gen_log_dom < 0)
285 {
286 EINA_LOG_ERR("Could not register log domain: %s", dom);
287 goto end;
288 }
289
290 eina_log_timing(_eolian_gen_log_dom, EINA_LOG_STATE_STOP, EINA_LOG_STATE_INIT);
291
292 struct option opts[] = {
293 { "help", no_argument, NULL, 'h' },
294 { "gh", no_argument, &gen_what, GEN_H },
295 { "gc", no_argument, &gen_what, GEN_C },
296 { "gi", no_argument, &gen_what, GEN_C_IMPL },
297 { "gs", no_argument, &gen_what, GEN_H_STUB },
298 { "output", required_argument, NULL, 'o' },
299 { "legacy", no_argument, &do_legacy, 1 },
300 { "include", required_argument, NULL, 'I' },
301 { "silent-types", no_argument, &silent_types, 1 },
302 { NULL, 0, NULL, 0 }
303 };
304
305 for (int opt; (opt = getopt_long(argc, argv, "vho:I:", opts, NULL)) != -1; )
306 switch (opt)
307 {
308 case 0: break;
309 case 'o':
310 outf = optarg;
311 break;
312 case 'h':
313 help = EINA_TRUE;
314 break;
315 case 'I':
316 if (!eolian_directory_scan(optarg))
317 {
318 fprintf(stderr, "eolian: could not scan '%s'\n", optarg);
319 goto end;
320 }
321 break;
322 default:
323 help = EINA_TRUE;
324 break;
325 }
326
327 if (help)
328 {
329 printf("Usage: %s [-h/--help] [-I/--include input_dir] [--legacy] [--gh|--gs|--gc|--gi] [--output/-o outfile] file.eo ... \n", argv[0]);
330 printf(" --help/-h Print that help\n");
331 printf(" --include/-I Include 'input_dir' as directory to search .eo files into\n");
332 printf(" --output/-o Force output filename to 'outfile'\n");
333 printf(" --gh Generate C header file [.h]\n");
334 printf(" --gs Generate C type stubs [.h]\n");
335 printf(" --gc Generate C source file [.c]\n");
336 printf(" --gi Generate C implementation source file [.c]. The output will be a series of functions that have to be filled.\n");
337 printf(" --legacy Generate legacy\n");
338 printf(" --silent-types Silence type validation\n");
339 ret = 0;
340 goto end;
341 }
342
343 const char *eof = argv[optind++];
344 if (!eof)
345 {
346 fprintf(stderr, "eolian: no input file\n");
347 goto end;
348 }
349
350 if (!eolian_file_parse(eof))
351 {
352 fprintf(stderr, "eolian: could not parse file '%s'\n", eof);
353 goto end;
354 }
355
356 if (!eolian_database_validate(silent_types))
357 {
358 fprintf(stderr, "eolian: error validating database\n");
359 goto end;
360 }
361
362 char *eofc = strdup(eof);
363 char *eobn = basename(eofc);
364
365 if (gen_what)
366 {
367 if (!outf)
368 {
369 fprintf(stderr, "eolian: no output file\n");
370 free(eofc);
371 goto end;
372 }
373 switch (gen_what)
374 {
375 case GEN_H:
376 INF("Generating header file %s\n", outf);
377 ret = !_generate_header(outf, eobn, do_legacy);
378 break;
379 case GEN_H_STUB:
380 INF("Generating stub header file %s\n", outf);
381 ret = !_generate_stub_header(outf, eobn);
382 break;
383 case GEN_C:
384 INF("Generating source file %s\n", outf);
385 ret = !_generate_c(outf, eobn, do_legacy);
386 break;
387 case GEN_C_IMPL:
388 INF("Generating user source file %s\n", outf);
389 ret = !_generate_impl(outf, eobn);
390 break;
391 default:
392 ERR("Wrong generation option\n");
393 break;
394 }
395 }
396 else
397 ret = 0;
398
399 free(eofc);
400
401end:
402 eina_log_timing(_eolian_gen_log_dom, EINA_LOG_STATE_START, EINA_LOG_STATE_SHUTDOWN);
403 eina_log_domain_unregister(_eolian_gen_log_dom);
404 eolian_shutdown();
405 eina_shutdown();
406 return ret;
407}
diff --git a/src/bin/eolian/types_generator.c b/src/bin/eolian/types_generator.c
deleted file mode 100644
index 54ed1d75b5..0000000000
--- a/src/bin/eolian/types_generator.c
+++ /dev/null
@@ -1,225 +0,0 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <Eina.h>
6#include <string.h>
7#include <ctype.h>
8
9#include "Eolian.h"
10#include "types_generator.h"
11#include "docs_generator.h"
12#include "common_funcs.h"
13
14static char *
15_concat_name(const Eolian_Typedecl *tp)
16{
17 const char *name;
18 char *str = NULL;
19 Eina_Strbuf *buf = eina_strbuf_new();
20 Eina_Iterator *itr = eolian_typedecl_namespaces_get(tp);
21 EINA_ITERATOR_FOREACH(itr, name)
22 if (name) eina_strbuf_append_printf(buf, "%s_", name);
23 eina_iterator_free(itr);
24 name = eolian_typedecl_name_get(tp);
25 if (name) eina_strbuf_append_printf(buf, "%s", name);
26 if (eina_strbuf_length_get(buf))
27 {
28 char *tmp = str = eina_strbuf_string_steal(buf);
29 *tmp = toupper(*tmp);
30 while (*tmp) if (*tmp++ == '_' && *tmp) *tmp = toupper(*tmp);
31 }
32 eina_strbuf_free(buf);
33 return str;
34}
35
36static Eina_Strbuf *
37_type_generate(const Eolian_Typedecl *tp, Eina_Bool full, Eina_Bool use_legacy)
38{
39 char *grp = strdup(eolian_typedecl_full_name_get(tp));
40 char *p = strrchr(grp, '.');
41 if (p) *p = '\0';
42 Eina_Strbuf *buf = docs_generate_full(eolian_typedecl_documentation_get(tp),
43 grp, 0, use_legacy);
44 free(grp);
45 if (!buf) buf = eina_strbuf_new();
46 else eina_strbuf_append_char(buf, '\n');
47 Eolian_Typedecl_Type tp_type = eolian_typedecl_type_get(tp);
48 switch(tp_type)
49 {
50 case EOLIAN_TYPEDECL_ALIAS:
51 {
52 Eina_Stringshare *tn = eolian_typedecl_c_type_get(tp);
53 eina_strbuf_append(buf, tn);
54 eina_stringshare_del(tn);
55 break;
56 }
57 case EOLIAN_TYPEDECL_STRUCT:
58 case EOLIAN_TYPEDECL_STRUCT_OPAQUE:
59 {
60 const Eolian_Struct_Type_Field *member;
61 char *name = _concat_name(tp);
62 if (tp_type == EOLIAN_TYPEDECL_STRUCT_OPAQUE || !full)
63 {
64 eina_strbuf_append_printf(buf, "typedef struct _%s %s", name, name);
65 free(name);
66 break;
67 }
68 eina_strbuf_append_printf(buf, "typedef struct _%s\n{\n", name);
69 Eina_Iterator *members = eolian_typedecl_struct_fields_get(tp);
70 EINA_ITERATOR_FOREACH(members, member)
71 {
72 const Eolian_Type *type = eolian_typedecl_struct_field_type_get(member);
73 Eina_Stringshare *c_type = NULL;
74 if (eolian_type_type_get(type) == EOLIAN_TYPE_STATIC_ARRAY)
75 {
76 c_type = eolian_type_c_type_get(eolian_type_base_type_get(type));
77 eina_strbuf_append_printf(buf, " %s%s%s[%zu];",
78 c_type, strchr(c_type, '*')?"":" ",
79 eolian_typedecl_struct_field_name_get(member),
80 eolian_type_array_size_get(type));
81 }
82 else
83 {
84 c_type = eolian_type_c_type_get(type);
85 eina_strbuf_append_printf(buf, " %s%s%s;",
86 c_type, strchr(c_type, '*')?"":" ",
87 eolian_typedecl_struct_field_name_get(member));
88 }
89 eina_stringshare_del(c_type);
90 const Eolian_Documentation *fdoc
91 = eolian_typedecl_struct_field_documentation_get(member);
92 if (fdoc)
93 {
94 const char *nl = strrchr(eina_strbuf_string_get(buf), '\n');
95 if (nl)
96 {
97 Eina_Strbuf *fbuf = docs_generate_full(fdoc, NULL, strlen(nl), use_legacy);
98 if (fbuf)
99 eina_strbuf_append_printf(buf, " %s",
100 eina_strbuf_string_get(fbuf));
101 eina_strbuf_free(fbuf);
102 }
103 }
104 eina_strbuf_append(buf, "\n");
105 }
106 eina_iterator_free(members);
107 eina_strbuf_append_printf(buf, "} %s", name);
108 free(name);
109 break;
110 }
111 case EOLIAN_TYPEDECL_ENUM:
112 {
113 const Eolian_Enum_Type_Field *member;
114 if (!full)
115 break;
116 char *name = _concat_name(tp);
117 eina_strbuf_append_printf(buf, "typedef enum\n{\n");
118 Eina_Iterator *members = eolian_typedecl_enum_fields_get(tp);
119 Eina_Bool next = eina_iterator_next(members, (void**)&member);
120 while (next)
121 {
122 const Eolian_Expression *value = eolian_typedecl_enum_field_value_get(member, EINA_FALSE);
123 Eina_Stringshare *membn = eolian_typedecl_enum_field_c_name_get(member);
124 if (!value)
125 eina_strbuf_append_printf(buf, " %s", membn);
126 else
127 {
128 Eolian_Value val = eolian_expression_eval(value, EOLIAN_MASK_INT);
129 const char *lit = eolian_expression_value_to_literal(&val);
130 eina_strbuf_append_printf(buf, " %s = %s", membn, lit);
131 const char *exp = eolian_expression_serialize(value);
132 if (exp && strcmp(lit, exp))
133 {
134 eina_strbuf_append_printf(buf, " /* %s */", exp);
135 eina_stringshare_del(exp);
136 }
137 eina_stringshare_del(lit);
138 }
139 eina_stringshare_del(membn);
140 const Eolian_Documentation *fdoc
141 = eolian_typedecl_enum_field_documentation_get(member);
142 next = eina_iterator_next(members, (void**)&member);
143 if (next)
144 eina_strbuf_append(buf, ",");
145 if (fdoc)
146 {
147 const char *nl = strrchr(eina_strbuf_string_get(buf), '\n');
148 if (nl)
149 {
150 Eina_Strbuf *fbuf = docs_generate_full(fdoc, NULL, strlen(nl), use_legacy);
151 if (fbuf)
152 eina_strbuf_append_printf(buf, " %s",
153 eina_strbuf_string_get(fbuf));
154 eina_strbuf_free(fbuf);
155 }
156 }
157 eina_strbuf_append(buf, "\n");
158 }
159 eina_strbuf_append_printf(buf, "} %s", name);
160 free(name);
161 eina_iterator_free(members);
162 break;
163 }
164 default:
165 {
166 eina_strbuf_reset(buf);
167 }
168 }
169 return buf;
170}
171
172Eina_Bool
173types_header_generate(const char *eo_filename, Eina_Strbuf *buf, Eina_Bool full, Eina_Bool use_legacy)
174{
175 const Eolian_Declaration *decl;
176
177 Eina_Iterator *itr = eolian_declarations_get_by_file(eo_filename);
178 EINA_ITERATOR_FOREACH(itr, decl)
179 {
180 Eolian_Declaration_Type dt = eolian_declaration_type_get(decl);
181 if (dt != EOLIAN_DECL_ALIAS &&
182 dt != EOLIAN_DECL_STRUCT &&
183 dt != EOLIAN_DECL_ENUM)
184 continue;
185
186 if (dt == EOLIAN_DECL_ENUM && !full)
187 continue;
188
189 const Eolian_Typedecl *tp = eolian_declaration_data_type_get(decl);
190 if (!tp || eolian_typedecl_is_extern(tp))
191 continue;
192
193 if (eolian_typedecl_type_get(tp) == EOLIAN_TYPEDECL_ALIAS)
194 {
195 const Eolian_Type *btp = eolian_typedecl_base_type_get(tp);
196 if (eolian_type_type_get(btp) == EOLIAN_TYPE_UNDEFINED)
197 continue;
198 }
199
200 Eina_Strbuf *tbuf = _type_generate(tp, full, use_legacy);
201 if (tbuf)
202 {
203 eina_strbuf_append(buf, eina_strbuf_string_get(tbuf));
204 eina_strbuf_append(buf, ";\n\n");
205 eina_strbuf_free(tbuf);
206 }
207 }
208 eina_iterator_free(itr);
209
210 return EINA_TRUE;
211}
212
213Eina_Bool
214types_class_typedef_generate(const char *eo_filename, Eina_Strbuf *buf)
215{
216 const Eolian_Class *class = eolian_class_get_by_file(eo_filename);
217 if (!class)
218 return EINA_FALSE;
219
220 static _eolian_class_vars class_env;
221 _class_env_create(class, NULL, &class_env);
222
223 eina_strbuf_append_printf(buf, "typedef Eo %s;\n", class_env.full_classname);
224 return EINA_TRUE;
225}
diff --git a/src/bin/eolian/types_generator.h b/src/bin/eolian/types_generator.h
deleted file mode 100644
index 5096614217..0000000000
--- a/src/bin/eolian/types_generator.h
+++ /dev/null
@@ -1,22 +0,0 @@
1#ifndef TYPES_GENERATOR_H
2#define TYPES_GENERATOR_H
3
4#include<Eina.h>
5
6/*
7 * @brief Generate the header code for the types of a specific file.
8 *
9 * @param[in] eo_filename Eo filename
10 * @param[inout] buf buffer to fill
11 * @param[in]full whether to generate full type definitions
12 * @param[in] use_legacy whether to use legacy names
13 *
14 * @return EINA_TRUE on success, EINA_FALSE on error.
15 *
16 */
17Eina_Bool types_header_generate(const char *eo_filename, Eina_Strbuf *buf, Eina_Bool full, Eina_Bool use_legacy);
18
19Eina_Bool types_class_typedef_generate(const char *eo_filename, Eina_Strbuf *buf);
20
21#endif
22