aboutsummaryrefslogtreecommitdiffstats
path: root/src/bin/eolian
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2017-04-07 13:54:55 -0300
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2017-06-18 12:09:22 -0300
commit1634c141698499ea0fe735c5447c38488e8891ad (patch)
tree3edbc5ccec818f29242401e53259fdad579dd3d8 /src/bin/eolian
parenteolian-cxx: Fix C++ generation errors with handle opaque types (diff)
downloadefl-1634c141698499ea0fe735c5447c38488e8891ad.tar.gz
eolian: function pointers
First steps toward explicit function pointer support in eolian. To declare a function pointer type, use the following syntax, similar to a regular eolian method declaration. function FunctionName { params { ... } return: Return type }
Diffstat (limited to 'src/bin/eolian')
-rw-r--r--src/bin/eolian/headers.c21
-rw-r--r--src/bin/eolian/sources.c52
-rw-r--r--src/bin/eolian/types.c45
3 files changed, 118 insertions, 0 deletions
diff --git a/src/bin/eolian/headers.c b/src/bin/eolian/headers.c
index 8538731a44..1d11da860a 100644
--- a/src/bin/eolian/headers.c
+++ b/src/bin/eolian/headers.c
@@ -128,9 +128,30 @@ _gen_func(const Eolian_Unit *src, const Eolian_Function *fid,
EINA_ITERATOR_FOREACH(itr, pr)
{
const Eolian_Type *prt = eolian_parameter_type_get(pr);
+ const Eolian_Typedecl *ptd = eolian_type_typedecl_get(prt);
const char *prn = eolian_parameter_name_get(pr);
Eina_Stringshare *prtn = eolian_type_c_type_get(prt);
+ if (ptd && eolian_typedecl_type_get(ptd) == EOLIAN_TYPEDECL_FUNCTION_POINTER)
+ {
+ nidx += 3;
+ if (!first)
+ eina_strbuf_append(buf, ", ");
+ eina_strbuf_append_printf(buf, "void *%s_data, %s %s, Eina_Free_Cb %s_free_cb",
+ prn, prtn, prn, prn);
+ eina_stringshare_del(prtn);
+ if (!eolian_parameter_is_nonull(pr))
+ continue;
+ if (!flagbuf)
+ {
+ flagbuf = eina_strbuf_new();
+ eina_strbuf_append_printf(flagbuf, " EINA_ARG_NONNULL(%d", nidx - 1);
+ }
+ else
+ eina_strbuf_append_printf(flagbuf, ", %d", nidx - 1);
+ continue;
+ }
+
++nidx;
if (!first)
eina_strbuf_append(buf, ", ");
diff --git a/src/bin/eolian/sources.c b/src/bin/eolian/sources.c
index 6eb6ad7927..b2d4b2065a 100644
--- a/src/bin/eolian/sources.c
+++ b/src/bin/eolian/sources.c
@@ -69,6 +69,40 @@ _type_exists(const char *tname, Eina_Strbuf *buf)
}
static void
+_gen_func_pointer_param(const char *name, Eina_Stringshare *c_type,
+ const Eolian_Typedecl *typedecl EINA_UNUSED,
+ Eina_Strbuf *params, Eina_Strbuf *params_full,
+ Eina_Strbuf *params_full_imp,
+ Eina_Bool is_empty EINA_UNUSED)
+{
+ Eina_Strbuf *dataname = eina_strbuf_new();
+ Eina_Strbuf *freename = eina_strbuf_new();
+
+ eina_strbuf_append_printf(dataname, "%s_data", name);
+ eina_strbuf_append_printf(freename, "%s_free_cb", name);
+
+ if (eina_strbuf_length_get(params))
+ eina_strbuf_append(params, ", ");
+
+ eina_strbuf_append_printf(params, "%s, %s, %s",
+ eina_strbuf_string_get(dataname),
+ name,
+ eina_strbuf_string_get(freename));
+
+ eina_strbuf_append_printf(params_full_imp, ", void *%s, %s %s, Eina_Free_Cb %s",
+ eina_strbuf_string_get(dataname),
+ c_type, name,
+ eina_strbuf_string_get(freename));
+ eina_strbuf_append_printf(params_full, ", void *%s, %s %s, Eina_Free_Cb %s",
+ eina_strbuf_string_get(dataname),
+ c_type, name,
+ eina_strbuf_string_get(freename));
+
+ eina_strbuf_free(dataname);
+ eina_strbuf_free(freename);
+}
+
+static void
_append_defval(const Eolian_Unit *src, Eina_Strbuf *buf,
const Eolian_Expression *exp, const Eolian_Type *tp)
{
@@ -212,10 +246,18 @@ _gen_func(const Eolian_Unit *src, const Eolian_Class *cl,
const char *prn = eolian_parameter_name_get(pr);
const Eolian_Type *pt = eolian_parameter_type_get(pr);
Eina_Stringshare *ptn = eolian_type_c_type_get(pt);
+ const Eolian_Typedecl *ptd = eolian_type_typedecl_get(pt);
Eina_Bool had_star = ptn[strlen(ptn) - 1] == '*';
const char *add_star = _get_add_star(ftype, pd);
+ if (ptd && eolian_typedecl_type_get(ptd) == EOLIAN_TYPEDECL_FUNCTION_POINTER)
+ {
+ _gen_func_pointer_param(prn, ptn, ptd, params, params_full, params_full_imp, is_empty);
+ eina_stringshare_del(ptn);
+ continue;
+ }
+
if (eina_strbuf_length_get(params))
eina_strbuf_append(params, ", ");
@@ -828,8 +870,18 @@ _gen_params(const Eolian_Function *fid, Eolian_Function_Type ftype,
Eolian_Parameter_Dir pd = eolian_parameter_direction_get(pr);
const char *prn = eolian_parameter_name_get(pr);
const Eolian_Type *pt = eolian_parameter_type_get(pr);
+ const Eolian_Typedecl *ptd = eolian_type_typedecl_get(pt);
Eina_Stringshare *ptn = eolian_type_c_type_get(pt);
+ if (ptd && eolian_typedecl_type_get(ptd) == EOLIAN_TYPEDECL_FUNCTION_POINTER)
+ {
+ eina_strbuf_append_printf(params, ", %s_data, %s, %s_free_cb", prn, prn, prn);
+ eina_strbuf_append_printf(params_full, ", void *%s_data, %s %s, Eina_Free_Cb %s_free_cb", prn, ptn, prn, prn);
+
+ eina_stringshare_del(ptn);
+ continue;
+ }
+
Eina_Bool had_star = ptn[strlen(ptn) - 1] == '*';
const char *add_star = _get_add_star(ftype, pd);
diff --git a/src/bin/eolian/types.c b/src/bin/eolian/types.c
index c1d4e1fa94..9baebed02a 100644
--- a/src/bin/eolian/types.c
+++ b/src/bin/eolian/types.c
@@ -133,6 +133,51 @@ _type_generate(const Eolian_Unit *src, const Eolian_Typedecl *tp,
free(fn);
break;
}
+ case EOLIAN_TYPEDECL_FUNCTION_POINTER:
+ {
+ const Eolian_Function *fid = eolian_typedecl_function_pointer_get(tp);
+
+ eina_strbuf_append(buf, "typedef ");
+
+ /* Return type */
+ const Eolian_Type *rtp = eolian_function_return_type_get(fid, EOLIAN_FUNCTION_POINTER);
+ if (!rtp)
+ eina_strbuf_append(buf, "void ");
+ else
+ {
+ Eina_Stringshare *ct = eolian_type_c_type_get(rtp);
+ eina_strbuf_append_printf(buf, "%s ", ct);
+ }
+
+ /* Function name */
+ char *fn = eo_gen_c_full_name_get(eolian_typedecl_full_name_get(tp));
+ eina_strbuf_append_printf(buf, "(*%s)", fn);
+ free(fn);
+
+ /* Parameters */
+ eina_strbuf_append(buf, "(void *data");
+ Eina_Iterator *params = eolian_function_parameters_get(fid);
+ const Eolian_Function_Parameter *param = NULL;
+ EINA_ITERATOR_FOREACH(params, param)
+ {
+ const Eolian_Typedecl *ptd = eolian_type_typedecl_get(eolian_parameter_type_get(param));
+ Eina_Stringshare *pn = eolian_parameter_name_get(param);
+ Eina_Stringshare *pt = eolian_type_c_type_get(eolian_parameter_type_get(param));
+
+ if (!pn)
+ pn = ""; // FIXME add some kind of param1/param2 control for null?
+
+ if (ptd && eolian_typedecl_type_get(ptd) == EOLIAN_TYPEDECL_FUNCTION_POINTER)
+ eina_strbuf_append_printf(buf, ", void *%s_data, %s %s, Eina_Free_Cb %s_free_cb",
+ pn, pt, pn, pn);
+ else
+ eina_strbuf_append_printf(buf, ", %s %s", pt, pn);
+
+ }
+ eina_strbuf_append(buf, ")");
+
+ break;
+ }
default:
eina_strbuf_reset(buf);
break;