eolian: update C generator to respect by_ref as well as tests

This commit is contained in:
Daniel Kolesa 2019-09-05 15:14:39 +02:00
parent ee0023055f
commit 04b0321bea
9 changed files with 55 additions and 50 deletions

View File

@ -18,7 +18,7 @@ _gen_param(Eina_Strbuf *buf, Eolian_Function_Parameter *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, EOLIAN_C_TYPE_PARAM);
Eina_Stringshare *prtn = eolian_parameter_c_type_get(pr, EINA_FALSE);
if (ptd && (eolian_typedecl_type_get(ptd) == EOLIAN_TYPEDECL_FUNCTION_POINTER))
{
@ -83,6 +83,7 @@ _gen_func(const Eolian_State *state, const Eolian_Function *fid,
Eina_Bool var_as_ret = EINA_FALSE;
const Eolian_Type *rtp = eolian_function_return_type_get(fid, ftype);
Eina_Bool return_move = eolian_function_return_is_move(fid, ftype);
Eina_Stringshare *rtps = NULL;
if (ftype == EOLIAN_PROP_GET && !rtp)
{
void *d1, *d2;
@ -92,6 +93,7 @@ _gen_func(const Eolian_State *state, const Eolian_Function *fid,
Eolian_Function_Parameter *pr = (Eolian_Function_Parameter *)d1;
rtp = eolian_parameter_type_get(pr);
return_move = eolian_parameter_is_move(pr);
rtps = eolian_parameter_c_type_get(pr, EINA_TRUE);
var_as_ret = EINA_TRUE;
}
eina_iterator_free(itr);
@ -119,17 +121,18 @@ _gen_func(const Eolian_State *state, const Eolian_Function *fid,
eina_strbuf_append(buf, "EOAPI ");
if (rtp)
{
Eina_Stringshare *rtps = eolian_type_c_type_get(rtp, EOLIAN_C_TYPE_RETURN);
if (!rtps)
rtps = eolian_function_return_c_type_get(fid, ftype);
eina_strbuf_append(buf, rtps);
if (rtps[strlen(rtps) - 1] != '*')
eina_strbuf_append_char(buf, ' ');
eina_stringshare_del(rtps);
}
else
eina_strbuf_append(buf, "void ");
eina_strbuf_append(buf, fcn);
eina_stringshare_del(fcn);
eina_stringshare_del(rtps);
Eina_Strbuf *flagbuf = NULL;
int nidx = !eolian_function_is_static(fid);

View File

@ -103,7 +103,7 @@ _gen_func_pointer_param(const char *name, Eina_Stringshare *c_type,
}
static void
_append_defval(Eina_Strbuf *buf, const Eolian_Expression *exp, const Eolian_Type *tp)
_append_defval(Eina_Strbuf *buf, const Eolian_Expression *exp, const Eolian_Type *tp, const char *ctp)
{
if (exp)
{
@ -139,13 +139,11 @@ _append_defval(Eina_Strbuf *buf, const Eolian_Expression *exp, const Eolian_Type
free(sn);
return;
}
Eina_Stringshare *ctp = eolian_type_c_type_get(btp, EOLIAN_C_TYPE_DEFAULT);
if (strchr(ctp, '*'))
{
eina_strbuf_append(buf, "NULL");
return;
}
eina_stringshare_del(ctp);
/* enums and remaining regulars... 0 should do */
eina_strbuf_append(buf, "0");
}
@ -377,9 +375,11 @@ _get_reflect_initf(const Eolian_Type *abtp)
}
static void
_gen_reflect_get(Eina_Strbuf *buf, const char *cnamel, const Eolian_Type *valt,
_gen_reflect_get(Eina_Strbuf *buf, const char *cnamel,
const Eolian_Function_Parameter *pr,
const Eolian_Function *fid, Eina_Hash *refh)
{
const Eolian_Type *valt = eolian_parameter_type_get(pr);
if (eolian_type_is_ptr(valt))
return;
@ -399,7 +399,7 @@ _gen_reflect_get(Eina_Strbuf *buf, const char *cnamel, const Eolian_Type *valt,
cnamel, eolian_function_name_get(fid));
eina_strbuf_append(buf, "{\n");
Eina_Stringshare *ct = eolian_type_c_type_get(valt, EOLIAN_C_TYPE_RETURN);
Eina_Stringshare *ct = eolian_parameter_c_type_get(pr, EINA_TRUE);
const char *starsp = (ct[strlen(ct) - 1] != '*') ? " " : "";
Eina_Stringshare *fcn = eolian_function_full_c_name_get(fid, EOLIAN_PROP_GET);
@ -412,9 +412,11 @@ _gen_reflect_get(Eina_Strbuf *buf, const char *cnamel, const Eolian_Type *valt,
}
static void
_gen_reflect_set(Eina_Strbuf *buf, const char *cnamel, const Eolian_Type *valt,
_gen_reflect_set(Eina_Strbuf *buf, const char *cnamel,
const Eolian_Function_Parameter *pr,
const Eolian_Function *fid, Eina_Hash *refh)
{
const Eolian_Type *valt = eolian_parameter_type_get(pr);
if (eolian_type_is_ptr(valt))
return;
@ -435,7 +437,7 @@ _gen_reflect_set(Eina_Strbuf *buf, const char *cnamel, const Eolian_Type *valt,
eina_strbuf_append(buf, "{\n");
eina_strbuf_append(buf, " Eina_Error r = 0;");
Eina_Stringshare *ct = eolian_type_c_type_get(valt, EOLIAN_C_TYPE_PARAM);
Eina_Stringshare *ct = eolian_parameter_c_type_get(pr, EINA_FALSE);
const char *starsp = (ct[strlen(ct) - 1] != '*') ? " " : "";
eina_strbuf_append_printf(buf, " %s%scval;\n", ct, starsp);
eina_stringshare_del(ct);
@ -458,14 +460,11 @@ _gen_reflect_set(Eina_Strbuf *buf, const char *cnamel, const Eolian_Type *valt,
}
static void
_emit_class_function(Eina_Strbuf *buf, const Eolian_Function *fid, const Eolian_Type *rtp, Eina_Strbuf *params_full,
_emit_class_function(Eina_Strbuf *buf, const Eolian_Function *fid, const char *rtpn, Eina_Strbuf *params_full,
const char *ocnamel, const char *func_suffix, Eina_Strbuf *params, const char *function_name)
{
eina_strbuf_append(buf, "EOAPI ");
if (rtp)
eina_strbuf_append(buf, eolian_type_c_type_get(rtp, EOLIAN_C_TYPE_RETURN));
else
eina_strbuf_append(buf, "void");
eina_strbuf_append(buf, rtpn);
eina_strbuf_append(buf, " ");
eina_strbuf_append(buf, function_name);
eina_strbuf_append(buf, "(");
@ -476,7 +475,7 @@ _emit_class_function(Eina_Strbuf *buf, const Eolian_Function *fid, const Eolian_
eina_strbuf_append(buf, ")\n");
eina_strbuf_append(buf, "{\n");
eina_strbuf_append_printf(buf, " %s();\n", eolian_class_c_get_function_name_get(eolian_function_class_get(fid)));
if (rtp)
if (strcmp(rtpn, "void"))
eina_strbuf_append(buf, " return ");
else
eina_strbuf_append(buf, " ");
@ -504,14 +503,16 @@ _gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
Eina_Bool is_prop = (ftype == EOLIAN_PROP_GET || ftype == EOLIAN_PROP_SET);
Eina_Bool var_as_ret = EINA_FALSE;
/* assume we're not generating reflection api by default */
const Eolian_Type *reflect_type = NULL;
const Eolian_Function_Parameter *reflect_param = NULL;
const Eolian_Expression *def_ret = NULL;
const Eolian_Type *rtp = eolian_function_return_type_get(fid, ftype);
Eina_Stringshare *rtpn = NULL;
if (rtp)
{
is_auto = EINA_FALSE; /* can't do auto if func returns */
def_ret = eolian_function_return_default_value_get(fid, ftype);
rtpn = eolian_function_return_c_type_get(fid, ftype);
}
const char *func_suffix = "";
@ -528,9 +529,10 @@ _gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
rtp = eolian_parameter_type_get(pr);
/* reflect only when returning 1 val */
if (!eolian_parameter_is_by_ref(pr))
reflect_type = rtp;
reflect_param = pr;
var_as_ret = EINA_TRUE;
def_ret = eolian_parameter_default_value_get(pr);
rtpn = eolian_parameter_c_type_get(pr, EINA_TRUE);
}
eina_iterator_free(itr);
}
@ -545,7 +547,7 @@ _gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
{
Eolian_Function_Parameter *pr = d1;
if (!eolian_parameter_is_by_ref(pr))
reflect_type = eolian_parameter_type_get(pr);
reflect_param = pr;
}
eina_iterator_free(itr);
}
@ -560,13 +562,12 @@ _gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
{
Eina_Iterator *itr = eolian_property_keys_get(fid, ftype);
if (itr) /* has keys: no reflection */
reflect_type = NULL;
reflect_param = NULL;
Eolian_Function_Parameter *pr;
EINA_ITERATOR_FOREACH(itr, pr)
{
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, EOLIAN_C_TYPE_PARAM);
Eina_Stringshare *ptn = eolian_parameter_c_type_get(pr, EINA_FALSE);
if (eina_strbuf_length_get(params))
eina_strbuf_append(params, ", ");
@ -646,7 +647,7 @@ _gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
const Eolian_Expression *dfv = eolian_parameter_default_value_get(pr);
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, EOLIAN_C_TYPE_PARAM);
Eina_Stringshare *ptn = eolian_parameter_c_type_get(pr, EINA_FALSE);
const Eolian_Typedecl *ptd = eolian_type_typedecl_get(pt);
Eina_Bool had_star = ptn[strlen(ptn) - 1] == '*';
@ -720,8 +721,8 @@ _gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
if (impl_same_class && eolian_implement_is_pure_virtual(impl, ftype))
impl_need = EINA_FALSE;
Eina_Stringshare *rtpn = rtp ? eolian_type_c_type_get(rtp, EOLIAN_C_TYPE_RETURN)
: eina_stringshare_add("void");
if (!rtpn)
rtpn = eina_stringshare_add("void");
char *cname = NULL, *cnamel = NULL, *ocnamel = NULL;
eo_gen_class_names_get(cl, &cname, NULL, &cnamel);
@ -809,7 +810,7 @@ _gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
if (rtp)
{
eina_strbuf_append(buf, " return ");
_append_defval(buf, def_ret, rtp);
_append_defval(buf, def_ret, rtp, rtpn);
eina_strbuf_append(buf, ";\n");
}
eina_strbuf_append(buf, "}\n\n");
@ -837,12 +838,12 @@ _gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
if (impl_same_class && !eolian_function_is_static(fid))
{
/* generate reflection implementation */
if (reflect_type)
if (reflect_param)
{
if (ftype == EOLIAN_PROP_GET)
_gen_reflect_get(buf, cnamel, reflect_type, fid, refh);
_gen_reflect_get(buf, cnamel, reflect_param, fid, refh);
else
_gen_reflect_set(buf, cnamel, reflect_type, fid, refh);
_gen_reflect_set(buf, cnamel, reflect_param, fid, refh);
}
void *data;
@ -893,7 +894,7 @@ _gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
if (strcmp(rtpn, "void"))
{
eina_strbuf_append_printf(buf, ", %s, ", rtpn);
_append_defval(buf, def_ret, rtp);
_append_defval(buf, def_ret, rtp, rtpn);
}
if (fallback_free_ownership)
@ -912,7 +913,7 @@ _gen_func(const Eolian_Class *cl, const Eolian_Function *fid,
eina_stringshare_del(eofn);
}
if (impl_same_class && eolian_function_is_static(fid))
_emit_class_function(buf, fid, rtp, params_full, ocnamel, func_suffix, params, eolian_function_full_c_name_get(fid, ftype));
_emit_class_function(buf, fid, rtpn, params_full, ocnamel, func_suffix, params, eolian_function_full_c_name_get(fid, ftype));
free(cname);
free(cnamel);
@ -1245,8 +1246,7 @@ _gen_params(const Eolian_Function *fid, Eolian_Function_Type ftype,
EINA_ITERATOR_FOREACH(itr, pr)
{
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, EOLIAN_C_TYPE_PARAM);
Eina_Stringshare *ptn = eolian_parameter_c_type_get(pr, EINA_FALSE);
eina_strbuf_append(params, ", ");
eina_strbuf_append(params, prn);
@ -1276,7 +1276,7 @@ _gen_params(const Eolian_Function *fid, Eolian_Function_Type ftype,
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, EOLIAN_C_TYPE_PARAM);
Eina_Stringshare *ptn = eolian_parameter_c_type_get(pr, EINA_FALSE);
if (ptd && eolian_typedecl_type_get(ptd) == EOLIAN_TYPEDECL_FUNCTION_POINTER)
{
@ -1339,6 +1339,7 @@ _gen_proto(const Eolian_Class *cl, const Eolian_Function *fid,
Eina_Bool var_as_ret = EINA_FALSE;
const Eolian_Type *rtp = eolian_function_return_type_get(fid, ftype);
Eina_Stringshare *rtpn = NULL;
if ((ftype == EOLIAN_PROP_GET) && !rtp)
{
void *d1, *d2;
@ -1347,6 +1348,7 @@ _gen_proto(const Eolian_Class *cl, const Eolian_Function *fid,
{
Eolian_Function_Parameter *pr = d1;
rtp = eolian_parameter_type_get(pr);
rtpn = eolian_parameter_c_type_get(pr, EINA_FALSE);
var_as_ret = EINA_TRUE;
}
eina_iterator_free(itr);
@ -1355,7 +1357,8 @@ _gen_proto(const Eolian_Class *cl, const Eolian_Function *fid,
eina_strbuf_append(buf, "EOLIAN static ");
if (rtp)
{
Eina_Stringshare *rtpn = eolian_type_c_type_get(rtp, EOLIAN_C_TYPE_RETURN);
if (!rtpn)
rtpn = eolian_function_return_c_type_get(fid, ftype);
eina_strbuf_append(buf, rtpn);
eina_stringshare_del(rtpn);
}

View File

@ -41,9 +41,8 @@ _type_generate(const Eolian_State *state, const Eolian_Typedecl *tp,
Eina_Iterator *membs = eolian_typedecl_struct_fields_get(tp);
EINA_ITERATOR_FOREACH(membs, memb)
{
const Eolian_Type *mtp = eolian_typedecl_struct_field_type_get(memb);
Eina_Stringshare *ct = NULL;
ct = eolian_type_c_type_get(mtp, EOLIAN_C_TYPE_DEFAULT);
ct = eolian_typedecl_struct_field_c_type_get(memb);
eina_strbuf_append_printf(buf, " %s%s%s;",
ct, strchr(ct, '*') ? "" : " ",
eolian_typedecl_struct_field_name_get(memb));
@ -137,8 +136,9 @@ _type_generate(const Eolian_State *state, const Eolian_Typedecl *tp,
eina_strbuf_append(buf, "void ");
else
{
Eina_Stringshare *ct = eolian_type_c_type_get(rtp, EOLIAN_C_TYPE_RETURN);
Eina_Stringshare *ct = eolian_function_return_c_type_get(fid, EOLIAN_FUNCTION_POINTER);
eina_strbuf_append_printf(buf, "%s ", ct);
eina_stringshare_del(ct);
}
/* Function name */

View File

@ -31,9 +31,9 @@ class Class_Simple {
@in a: int; [[a]]
@inout b: char;
@out c: double (1337.6);
@in d: ptr(int);
@in d: int @by_ref;
}
return: ptr(char) (null); [[comment for method return]]
return: mstring (null); [[comment for method return]]
}
}
}

View File

@ -7,7 +7,7 @@ class Consts {
@inout b: char;
@out c: double;
}
return: ptr(char) (null); [[comment for method return]]
return: int;
}
}
}

View File

@ -41,7 +41,7 @@ abstract Object_Impl extends Base {
@inout b: char;
@out c: double;
}
return: ptr(char) (null); [[comment for method return]]
return: mstring (null); [[comment for method return]]
}
foo2 @const {
[[comment foo]]

View File

@ -38,7 +38,7 @@ abstract Override extends Base {
params {
@in idx: int;
@out a: int (250);
@out str: ptr(char) (null);
@out str: mstring (null);
}
}
}

View File

@ -1,5 +1,5 @@
struct Named {
field: ptr(int);
field: int @by_ref;
something: string;
}
@ -24,7 +24,7 @@ class Struct {
return: mstring @move;
}
bar {
return: ptr(Named);
return: Named @by_ref;
}
}
}

View File

@ -615,7 +615,6 @@ EFL_START_TEST(eolian_simple_parsing)
/* Method */
fail_if(!(fid = eolian_class_function_by_name_get(class, "foo", EOLIAN_METHOD)));
fail_if(!eolian_function_is_beta(fid));
fail_if(!eolian_type_is_ptr(eolian_function_return_type_get(fid, EOLIAN_METHOD)));
/* Function return */
tp = eolian_function_return_type_get(fid, EOLIAN_METHOD);
fail_if(!tp);
@ -652,7 +651,7 @@ EFL_START_TEST(eolian_simple_parsing)
fail_if(!(eina_iterator_next(iter, (void**)&param)));
fail_if(eolian_parameter_direction_get(param) != EOLIAN_IN_PARAM);
fail_if(strcmp(eolian_type_short_name_get(eolian_parameter_type_get(param)), "int"));
fail_if(!eolian_type_is_ptr(eolian_parameter_type_get(param)));
fail_if(!eolian_parameter_is_by_ref(param));
fail_if(strcmp(eolian_parameter_name_get(param), "d"));
fail_if(eina_iterator_next(iter, &dummy));
eina_iterator_free(iter);
@ -695,12 +694,12 @@ EFL_START_TEST(eolian_struct)
fail_if(strcmp(file, "struct.eo"));
fail_if(!(field = eolian_typedecl_struct_field_get(tdl, "field")));
fail_if(!(ftype = eolian_typedecl_struct_field_type_get(field)));
fail_if(!eolian_type_is_ptr(ftype));
fail_if(!eolian_typedecl_struct_field_is_by_ref(field));
fail_if(!(type_name = eolian_type_short_name_get(ftype)));
fail_if(strcmp(type_name, "int"));
fail_if(!(field = eolian_typedecl_struct_field_get(tdl, "something")));
fail_if(!(ftype = eolian_typedecl_struct_field_type_get(field)));
fail_if(eolian_type_is_ptr(ftype));
fail_if(eolian_typedecl_struct_field_is_by_ref(field));
fail_if(!(type_name = eolian_typedecl_struct_field_c_type_get(field)));
fail_if(strcmp(type_name, "const char *"));
eina_stringshare_del(type_name);
@ -728,7 +727,7 @@ EFL_START_TEST(eolian_struct)
fail_if(!(func = eolian_class_function_by_name_get(class, "bar", EOLIAN_METHOD)));
fail_if(!(type = eolian_function_return_type_get(func, EOLIAN_METHOD)));
fail_if(eolian_type_type_get(type) != EOLIAN_TYPE_REGULAR);
fail_if(!eolian_type_is_ptr(type));
fail_if(!eolian_function_return_is_by_ref(func, EOLIAN_METHOD));
fail_if(!(tdl = eolian_type_typedecl_get(type)));
fail_if(eolian_typedecl_type_get(tdl) != EOLIAN_TYPEDECL_STRUCT);