Eolian/Generator: support params initialization.
This is needed when get properties or methods have to return a value in case of failure or to initialize parameters. The way used is to generate an intermediate function that will initialize the parameters and then invoke the "user" function.
This commit is contained in:
parent
3f468537fd
commit
ffa9ad7daf
|
@ -116,5 +116,6 @@ tests/eolian/data/class_funcs.eo \
|
|||
tests/eolian/data/enum.eo \
|
||||
tests/eolian/data/free_func.eo \
|
||||
tests/eolian/data/typedef_ref.c \
|
||||
tests/eolian/data/struct_ref.c
|
||||
tests/eolian/data/struct_ref.c \
|
||||
tests/eolian/data/class_simple_ref.c
|
||||
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
#include "common_funcs.h"
|
||||
|
||||
static _eolian_class_vars class_env;
|
||||
/* Used to store the function names that will have to be appended
|
||||
* with __eolian during C generation. Needed when params have to
|
||||
* be initialized and for future features. */
|
||||
static Eina_Hash *_funcs_params_init = NULL;
|
||||
|
||||
static const char
|
||||
tmpl_dtor[] = "\
|
||||
|
@ -348,6 +352,7 @@ eo_bind_func_generate(const Eolian_Class *class, const Eolian_Function *funcid,
|
|||
Eina_Bool add_star = EINA_FALSE;
|
||||
Eina_Iterator *itr;
|
||||
void *data, *data2;
|
||||
const Eolian_Expression *default_ret_val = NULL;
|
||||
|
||||
Eina_Bool need_implementation = EINA_TRUE;
|
||||
if (!impl_env && eolian_function_is_virtual_pure(funcid, ftype)) need_implementation = EINA_FALSE;
|
||||
|
@ -356,8 +361,11 @@ eo_bind_func_generate(const Eolian_Class *class, const Eolian_Function *funcid,
|
|||
Eina_Strbuf *va_args = eina_strbuf_new();
|
||||
Eina_Strbuf *params = eina_strbuf_new(); /* only variables names */
|
||||
Eina_Strbuf *full_params = eina_strbuf_new(); /* variables types + names */
|
||||
Eina_Strbuf *params_init = eina_strbuf_new(); /* init of variables to default */
|
||||
|
||||
rettypet = eolian_function_return_type_get(funcid, ftype);
|
||||
if (rettypet)
|
||||
default_ret_val = eolian_function_return_default_value_get(funcid, ftype);
|
||||
if (ftype == EOLIAN_PROP_GET)
|
||||
{
|
||||
suffix = "_get";
|
||||
|
@ -372,6 +380,7 @@ eo_bind_func_generate(const Eolian_Class *class, const Eolian_Function *funcid,
|
|||
rettypet = eolian_parameter_type_get(param);
|
||||
var_as_ret = EINA_TRUE;
|
||||
ret_const = eolian_parameter_const_attribute_get(data, EINA_TRUE);
|
||||
default_ret_val = eolian_parameter_default_value_get(param);
|
||||
}
|
||||
eina_iterator_free(itr);
|
||||
}
|
||||
|
@ -415,6 +424,30 @@ eo_bind_func_generate(const Eolian_Class *class, const Eolian_Function *funcid,
|
|||
eina_strbuf_append_printf(full_params, ", %s%s%s%s%s",
|
||||
is_const?"const ":"",
|
||||
ptype, had_star?"":" ", add_star?"*":"", pname);
|
||||
if (ftype != EOLIAN_PROP_SET)
|
||||
{
|
||||
const Eolian_Expression *dflt_value = eolian_parameter_default_value_get(param);
|
||||
if (dflt_value)
|
||||
{
|
||||
const char *val_str = NULL;
|
||||
Eolian_Value val = eolian_expression_eval
|
||||
(dflt_value, EOLIAN_MASK_ALL);
|
||||
if (val.type)
|
||||
{
|
||||
val_str = eolian_expression_value_to_literal(&val);
|
||||
eina_strbuf_append_printf(params_init,
|
||||
" if (%s) *%s = %s;",
|
||||
pname, pname, val_str);
|
||||
if (eolian_expression_type_get(dflt_value) == EOLIAN_EXPR_ENUM)
|
||||
{
|
||||
Eina_Stringshare *string = eolian_expression_serialize(dflt_value);
|
||||
eina_strbuf_append_printf(params_init, " /* %s */", string);
|
||||
eina_stringshare_del(string);
|
||||
}
|
||||
eina_strbuf_append_printf(params_init, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
eina_stringshare_del(ptype);
|
||||
}
|
||||
eina_iterator_free(itr);
|
||||
|
@ -433,6 +466,25 @@ eo_bind_func_generate(const Eolian_Class *class, const Eolian_Function *funcid,
|
|||
impl_env?impl_env->lower_classname:"",
|
||||
eolian_function_name_get(funcid), suffix);
|
||||
|
||||
if (eina_strbuf_length_get(params_init))
|
||||
{
|
||||
eina_hash_add(_funcs_params_init,
|
||||
eina_stringshare_add(eolian_function_name_get(funcid)), funcid);
|
||||
eina_strbuf_append_printf(fbody, "static %s%s __eolian_%s%s%s_%s%s(Eo *obj, @#Datatype_Data *pd@#full_params)\n{\n%s\n",
|
||||
ret_const?"const ":"", rettype?rettype:"void",
|
||||
class_env.lower_classname,
|
||||
impl_env?"_":"",
|
||||
impl_env?impl_env->lower_classname:"",
|
||||
eolian_function_name_get(funcid), suffix,
|
||||
eina_strbuf_string_get(params_init));
|
||||
eina_strbuf_append_printf(fbody, " %s_%s%s%s_%s%s(obj, pd, %s);\n}\n\n",
|
||||
rettype?"return ":"",
|
||||
class_env.lower_classname,
|
||||
impl_env?"_":"",
|
||||
impl_env?impl_env->lower_classname:"",
|
||||
eolian_function_name_get(funcid), suffix,
|
||||
eina_strbuf_string_get(params));
|
||||
}
|
||||
eina_strbuf_free(ret_param);
|
||||
}
|
||||
if (!impl_env)
|
||||
|
@ -458,20 +510,23 @@ eo_bind_func_generate(const Eolian_Class *class, const Eolian_Function *funcid,
|
|||
func_env.lower_eo_func);
|
||||
if (!ret_is_void)
|
||||
{
|
||||
const Eolian_Expression *default_ret_val =
|
||||
eolian_function_return_default_value_get(funcid, ftype);
|
||||
const char *val_str = NULL;
|
||||
if (default_ret_val)
|
||||
{
|
||||
Eolian_Value val = eolian_expression_eval_type
|
||||
(default_ret_val, rettypet);
|
||||
Eolian_Value val = eolian_expression_eval
|
||||
(default_ret_val, EOLIAN_MASK_ALL);
|
||||
if (val.type)
|
||||
val_str = eolian_expression_value_to_literal(&val);
|
||||
}
|
||||
eina_strbuf_append_printf(eo_func_decl, ", %s%s, %s",
|
||||
ret_const ? "const " : "", rettype,
|
||||
val_str?val_str:"0");
|
||||
|
||||
if (val_str && eolian_expression_type_get(default_ret_val) == EOLIAN_EXPR_ENUM)
|
||||
{
|
||||
Eina_Stringshare *string = eolian_expression_serialize(default_ret_val);
|
||||
eina_strbuf_append_printf(eo_func_decl, " /* %s */", string);
|
||||
eina_stringshare_del(string);
|
||||
}
|
||||
}
|
||||
if (has_params)
|
||||
{
|
||||
|
@ -508,6 +563,7 @@ eo_bind_func_generate(const Eolian_Class *class, const Eolian_Function *funcid,
|
|||
|
||||
eina_strbuf_free(va_args);
|
||||
eina_strbuf_free(full_params);
|
||||
eina_strbuf_free(params_init);
|
||||
eina_strbuf_free(params);
|
||||
eina_strbuf_free(fbody);
|
||||
return EINA_TRUE;
|
||||
|
@ -530,7 +586,12 @@ eo_op_desc_generate(const Eolian_Class *class, Eolian_Function *fid, Eolian_Func
|
|||
if (eolian_function_is_class(fid)) class_str = "CLASS_";
|
||||
eina_strbuf_append_printf(buf, "\n EO_OP_%sFUNC(%s, ", class_str, func_env.lower_eo_func);
|
||||
if (!is_virtual_pure)
|
||||
eina_strbuf_append_printf(buf, "_%s_%s%s, \"%s\"),", class_env.lower_classname, funcname, suffix, desc);
|
||||
{
|
||||
eina_strbuf_append_printf(buf, "%s_%s_%s%s, \"%s\"),",
|
||||
eina_hash_find(_funcs_params_init, funcname)
|
||||
&& ftype != EOLIAN_PROP_SET?"__eolian":"",
|
||||
class_env.lower_classname, funcname, suffix, desc);
|
||||
}
|
||||
else
|
||||
eina_strbuf_append_printf(buf, "NULL, \"%s\"),", desc);
|
||||
|
||||
|
@ -863,6 +924,7 @@ eo_source_generate(const Eolian_Class *class, Eina_Strbuf *buf)
|
|||
Eina_Strbuf *str_bodyf = eina_strbuf_new();
|
||||
|
||||
_class_env_create(class, NULL, &class_env);
|
||||
_funcs_params_init = eina_hash_stringshared_new(NULL);
|
||||
|
||||
if (!eo_source_beginning_generate(class, buf)) goto end;
|
||||
|
||||
|
@ -901,6 +963,8 @@ eo_source_generate(const Eolian_Class *class, Eina_Strbuf *buf)
|
|||
|
||||
ret = EINA_TRUE;
|
||||
end:
|
||||
eina_hash_free(_funcs_params_init);
|
||||
_funcs_params_init = NULL;
|
||||
eina_strbuf_free(str_bodyf);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -16,8 +16,8 @@ class Evas.Line (Evas.Object)
|
|||
second end point. */
|
||||
}
|
||||
values {
|
||||
Evas_Coord x1; /*@ The X coordinate of the first point. */
|
||||
Evas_Coord y1; /*@ The Y coordinate of the first point. */
|
||||
Evas_Coord x1(0); /*@ The X coordinate of the first point. */
|
||||
Evas_Coord y1(3); /*@ The Y coordinate of the first point. */
|
||||
Evas_Coord x2; /*@ The X coordinate of the second point. */
|
||||
Evas_Coord y2; /*@ The Y coordinate of the second point. */
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
|
||||
Eina_Bool _class_simple_a_set(Eo *obj, Evas_Simple_Data *pd, int value);
|
||||
|
||||
EOAPI EO_FUNC_BODYV(evas_obj_simple_a_set, Eina_Bool, EINA_TRUE, EO_FUNC_CALL(value), int value);
|
||||
|
||||
int _class_simple_a_get(Eo *obj, Evas_Simple_Data *pd);
|
||||
|
||||
EOAPI EO_FUNC_BODY(evas_obj_simple_a_get, int, 100);
|
||||
|
||||
void _class_simple_b_set(Eo *obj, Evas_Simple_Data *pd);
|
||||
|
||||
EOAPI EO_VOID_FUNC_BODY(evas_obj_simple_b_set);
|
||||
|
||||
char * _class_simple_foo(Eo *obj, Evas_Simple_Data *pd, int a, char *b, double *c);
|
||||
|
||||
static char * __eolian_class_simple_foo(Eo *obj, Evas_Simple_Data *pd, int a, char *b, double *c)
|
||||
{
|
||||
if (c) *c = 1337.600000;
|
||||
|
||||
return _class_simple_foo(obj, pd, a, b, c);
|
||||
}
|
||||
|
||||
EOAPI EO_FUNC_BODYV(evas_obj_simple_foo, char *, NULL, EO_FUNC_CALL(a, b, c), int a, char *b, double *c);
|
||||
|
||||
int _class_simple_bar(Eo *obj, Evas_Simple_Data *pd, int x);
|
||||
|
||||
EOAPI EO_FUNC_BODYV(evas_obj_simple_bar, int, 0, EO_FUNC_CALL(x), int x);
|
||||
|
||||
static Eo_Op_Description _class_simple_op_desc[] = {
|
||||
EO_OP_FUNC(evas_obj_simple_a_set, _class_simple_a_set, "comment a.set"),
|
||||
EO_OP_FUNC(evas_obj_simple_a_get, _class_simple_a_get, ""),
|
||||
EO_OP_FUNC(evas_obj_simple_foo, __eolian_class_simple_foo, "comment foo"),
|
||||
EO_OP_SENTINEL
|
||||
};
|
||||
|
||||
static const Eo_Class_Description _class_simple_class_desc = {
|
||||
EO_VERSION,
|
||||
"Class_Simple",
|
||||
EO_CLASS_TYPE_REGULAR,
|
||||
EO_CLASS_DESCRIPTION_OPS(_class_simple_op_desc),
|
||||
NULL,
|
||||
sizeof(Evas_Simple_Data),
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
EO_DEFINE_CLASS(class_simple_class_get, &_class_simple_class_desc, NULL, NULL);
|
|
@ -124,9 +124,26 @@ START_TEST(eolian_types_generation)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(eolian_default_values_generation)
|
||||
{
|
||||
char output_filepath[PATH_MAX] = "";
|
||||
snprintf(output_filepath, PATH_MAX, "%s/eolian_output.c",
|
||||
#ifdef HAVE_EVIL
|
||||
(char *)evil_tmpdir_get()
|
||||
#else
|
||||
"/tmp"
|
||||
#endif
|
||||
);
|
||||
remove(output_filepath);
|
||||
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/class_simple.eo", "--eo --gc", output_filepath));
|
||||
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/class_simple_ref.c", output_filepath));
|
||||
}
|
||||
END_TEST
|
||||
|
||||
void eolian_generation_test(TCase *tc)
|
||||
{
|
||||
tcase_add_test(tc, eolian_types_generation);
|
||||
tcase_add_test(tc, eolian_default_values_generation);
|
||||
tcase_add_test(tc, eolian_dev_impl_code);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue