Eolian: Support of virtual pure functions.

Virtual pure can be defined in Eolian format by adding in the section
implements virtual::class_name::func_name[::func_type].
This commit is contained in:
Daniel Zaoui 2014-02-19 10:30:02 +02:00
parent f7dce9c8c9
commit 920c035c57
6 changed files with 116 additions and 51 deletions

View File

@ -306,6 +306,7 @@ eo1_bind_func_generate(const char *classname, Eolian_Function funcid, Eolian_Fun
const char *retname = NULL;
Eina_Bool ret_const = EINA_FALSE;
if (eolian_function_is_virtual_pure(funcid)) return EINA_TRUE;
Eina_Strbuf *fbody = eina_strbuf_new();
Eina_Strbuf *va_args = eina_strbuf_new();
Eina_Strbuf *params = eina_strbuf_new(); /* only variables names */
@ -606,7 +607,10 @@ eo1_source_end_generate(const char *classname, Eina_Strbuf *buf)
free(desc);
eina_strbuf_append(str_op, eina_strbuf_string_get(tmpbuf));
eo1_eo_func_desc_generate(classname, tmpstr, tmpbuf);
if (!eolian_function_is_virtual_pure(fn))
eo1_eo_func_desc_generate(classname, tmpstr, tmpbuf);
else
eina_strbuf_reset(tmpbuf);
eina_strbuf_append(str_func, eina_strbuf_string_get(tmpbuf));
}
if (prop_write)
@ -619,7 +623,10 @@ eo1_source_end_generate(const char *classname, Eina_Strbuf *buf)
eina_strbuf_append(str_op, eina_strbuf_string_get(tmpbuf));
free(desc);
eo1_eo_func_desc_generate(classname, tmpstr, tmpbuf);
if (!eolian_function_is_virtual_pure(fn))
eo1_eo_func_desc_generate(classname, tmpstr, tmpbuf);
else
eina_strbuf_reset(tmpbuf);
eina_strbuf_append(str_func, eina_strbuf_string_get(tmpbuf));
}
}
@ -635,7 +642,10 @@ eo1_source_end_generate(const char *classname, Eina_Strbuf *buf)
free(desc);
eina_strbuf_append(str_op, eina_strbuf_string_get(tmpbuf));
eo1_eo_func_desc_generate(classname, funcname, tmpbuf);
if (!eolian_function_is_virtual_pure(fn))
eo1_eo_func_desc_generate(classname, funcname, tmpbuf);
else
eina_strbuf_reset(tmpbuf);
eina_strbuf_append(str_func, eina_strbuf_string_get(tmpbuf));
}

View File

@ -251,16 +251,16 @@ EAPI Eolian_Function_Type eolian_function_type_get(Eolian_Function function_id);
EAPI const char *eolian_function_name_get(Eolian_Function function_id);
/*
* @brief Indicates if a function of a certain type exists in a class.
* @brief Find a function in a class by its name and type
*
* @param[in] class_name name of the class
* @param[in] func_name name of the function
* @param[in] f_type type of the function
* @return EINA_TRUE if exists, EINA_FALSE otherwise
* @return the function id if found, NULL otherwise.
*
* @ingroup Eolian
*/
EAPI Eina_Bool eolian_class_function_exists(const char *classname, const char *func_name, Eolian_Function_Type f_type);
EAPI Eolian_Function eolian_class_function_find_by_name(const char *classname, const char *func_name, Eolian_Function_Type f_type);
/*
* @brief Returns a specific data for a function.
@ -273,6 +273,16 @@ EAPI Eina_Bool eolian_class_function_exists(const char *classname, const char *f
*/
EAPI const char *eolian_function_data_get(Eolian_Function function_id, const char *key);
/*
* @brief Indicates if a function is virtual pure.
*
* @param[in] function_id Id of the function
* @return EINA_TRUE if virtual pure, EINA_FALSE othrewise..
*
* @ingroup Eolian
*/
EAPI Eina_Bool eolian_function_is_virtual_pure(Eolian_Function function_id);
/*
* @brief Returns a specific description for a function.
*

View File

@ -2797,6 +2797,7 @@ eo_tokenizer_database_fill(const char *filename)
EINA_LIST_FOREACH(kls->implements, l, impl)
{
const char *class = impl->meth_name;
Eina_Bool virtual_pure = EINA_FALSE;
if (!strcmp(class, "Eo_Base::constructor"))
{
Eolian_Function foo_id = database_function_new("constructor", DFLT_CONSTRUCTOR);
@ -2819,6 +2820,7 @@ eo_tokenizer_database_fill(const char *filename)
database_class_dtor_enable_set(kls->name, EINA_TRUE);
continue;
}
if (!strncmp(class, "virtual::", 9)) virtual_pure = EINA_TRUE;
char *func = strstr(class, "::");
if (func) *func = '\0';
func += 2;
@ -2830,6 +2832,19 @@ eo_tokenizer_database_fill(const char *filename)
if (!strcmp(type_as_str+2, "set")) ftype = SET;
else if (!strcmp(type_as_str+2, "get")) ftype = GET;
}
if (virtual_pure)
{
/* Search the function into the existing functions of the current class */
Eolian_Function foo_id = eolian_class_function_find_by_name(
kls->name, func, ftype);
if (!foo_id)
{
printf("Error - %s not known in class %s\n", class + 9, kls->name);
return EINA_FALSE;
}
database_function_set_as_virtual_pure(foo_id);
continue;
}
Eolian_Implement impl_desc = database_implement_new(class, func, ftype);
if (impl->legacy)
{

View File

@ -1203,6 +1203,7 @@ eo_tokenizer_database_fill(const char *filename)
EINA_LIST_FOREACH(kls->implements, l, impl)
{
const char *class = impl->meth_name;
Eina_Bool virtual_pure = EINA_FALSE;
if (!strcmp(class, "Eo_Base::constructor"))
{
Eolian_Function foo_id = database_function_new("constructor", DFLT_CONSTRUCTOR);
@ -1225,6 +1226,7 @@ eo_tokenizer_database_fill(const char *filename)
database_class_dtor_enable_set(kls->name, EINA_TRUE);
continue;
}
if (!strncmp(class, "virtual::", 9)) virtual_pure = EINA_TRUE;
char *func = strstr(class, "::");
if (func) *func = '\0';
func += 2;
@ -1236,6 +1238,19 @@ eo_tokenizer_database_fill(const char *filename)
if (!strcmp(type_as_str+2, "set")) ftype = SET;
else if (!strcmp(type_as_str+2, "get")) ftype = GET;
}
if (virtual_pure)
{
/* Search the function into the existing functions of the current class */
Eolian_Function foo_id = eolian_class_function_find_by_name(
kls->name, func, ftype);
if (!foo_id)
{
printf("Error - %s not known in class %s\n", class + 9, kls->name);
return EINA_FALSE;
}
database_function_set_as_virtual_pure(foo_id);
continue;
}
Eolian_Implement impl_desc = database_implement_new(class, func, ftype);
if (impl->legacy)
{

View File

@ -32,6 +32,7 @@ typedef struct
Eolian_Function_Type type;
Eina_Hash *data;
Eina_Bool obj_is_const :1; /* True if the object has to be const. Useful for a few methods. */
Eina_Bool virtual_pure :1;
} _Function_Id;
typedef struct
@ -460,58 +461,52 @@ eolian_implement_legacy_information_get(const Eolian_Implement_Legacy leg_desc,
return EINA_TRUE;
}
EAPI Eina_Bool eolian_class_function_exists(const char *class_name, const char *func_name, Eolian_Function_Type f_type)
EAPI Eolian_Function eolian_class_function_find_by_name(const char *class_name, const char *func_name, Eolian_Function_Type f_type)
{
Eina_Bool ret = EINA_FALSE;
Eina_List *itr;
Eolian_Function foo_id;
Class_desc *desc = _class_get(class_name);
switch (f_type)
if (f_type == UNRESOLVED || f_type == METHOD_FUNC)
EINA_LIST_FOREACH(desc->methods, itr, foo_id)
{
_Function_Id *fid = (_Function_Id *) foo_id;
if (!strcmp(fid->name, func_name))
return foo_id;
}
if (f_type == UNRESOLVED || f_type == PROPERTY_FUNC ||
f_type == SET || f_type == GET)
{
case METHOD_FUNC:
case SET:
case GET:
case PROPERTY_FUNC:
{
EINA_LIST_FOREACH(desc->methods, itr, foo_id)
{
_Function_Id *fid = (_Function_Id *) foo_id;
if (!strcmp(fid->name, func_name))
return EINA_TRUE;
}
EINA_LIST_FOREACH(desc->properties, itr, foo_id)
{
_Function_Id *fid = (_Function_Id *) foo_id;
if (!strcmp(fid->name, func_name))
return EINA_TRUE;
}
break;
}
case CONSTRUCTOR:
{
EINA_LIST_FOREACH(desc->constructors, itr, foo_id)
{
_Function_Id *fid = (_Function_Id *) foo_id;
if (!strcmp(fid->name, func_name))
return EINA_TRUE;
}
break;
}
case DESTRUCTOR:
{
EINA_LIST_FOREACH(desc->destructors, itr, foo_id)
{
_Function_Id *fid = (_Function_Id *) foo_id;
if (!strcmp(fid->name, func_name))
return EINA_TRUE;
}
break;
}
default:
return EINA_FALSE;
EINA_LIST_FOREACH(desc->properties, itr, foo_id)
{
_Function_Id *fid = (_Function_Id *) foo_id;
if (!strcmp(fid->name, func_name) && (f_type == UNRESOLVED || f_type == PROPERTY_FUNC || f_type == fid->type))
return foo_id;
}
}
return ret;
if (f_type == CONSTRUCTOR)
{
EINA_LIST_FOREACH(desc->constructors, itr, foo_id)
{
_Function_Id *fid = (_Function_Id *) foo_id;
if (!strcmp(fid->name, func_name))
return foo_id;
}
}
if (f_type == DESTRUCTOR)
{
EINA_LIST_FOREACH(desc->destructors, itr, foo_id)
{
_Function_Id *fid = (_Function_Id *) foo_id;
if (!strcmp(fid->name, func_name))
return foo_id;
}
}
return NULL;
}
EAPI const Eina_List *
@ -561,6 +556,23 @@ eolian_function_name_get(Eolian_Function function_id)
return fid->name;
}
Eina_Bool
database_function_set_as_virtual_pure(Eolian_Function function_id)
{
_Function_Id *fid = (_Function_Id *)function_id;
if (!fid) return EINA_FALSE;
fid->virtual_pure = EINA_TRUE;
return EINA_TRUE;
}
EAPI Eina_Bool
eolian_function_is_virtual_pure(Eolian_Function function_id)
{
_Function_Id *fid = (_Function_Id *)function_id;
if (!fid) return EINA_FALSE;
return fid->virtual_pure;
}
void
database_function_data_set(Eolian_Function function_id, const char *key, const char *data)
{

View File

@ -57,6 +57,9 @@ void database_function_return_type_set(Eolian_Function foo_id, Eolian_Function_T
void database_function_object_set_as_const(Eolian_Function foo_id, Eina_Bool is_const);
Eina_Bool
database_function_set_as_virtual_pure(Eolian_Function function_id);
/* Need to add API for callbacks and implements */
Eolian_Implement