From 920c035c57fd793bb2672185a1f19d4561077691 Mon Sep 17 00:00:00 2001 From: Daniel Zaoui Date: Wed, 19 Feb 2014 10:30:02 +0200 Subject: [PATCH] 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]. --- src/bin/eolian/eo1_generator.c | 16 ++++- src/lib/eolian/Eolian.h | 16 ++++- src/lib/eolian/eo_lexer.c | 15 +++++ src/lib/eolian/eo_lexer.rl | 15 +++++ src/lib/eolian/eolian_database.c | 102 +++++++++++++++++-------------- src/lib/eolian/eolian_database.h | 3 + 6 files changed, 116 insertions(+), 51 deletions(-) diff --git a/src/bin/eolian/eo1_generator.c b/src/bin/eolian/eo1_generator.c index b686fc6fc8..da6c27563d 100644 --- a/src/bin/eolian/eo1_generator.c +++ b/src/bin/eolian/eo1_generator.c @@ -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)); } diff --git a/src/lib/eolian/Eolian.h b/src/lib/eolian/Eolian.h index ac38c5d5f1..5402b145b5 100644 --- a/src/lib/eolian/Eolian.h +++ b/src/lib/eolian/Eolian.h @@ -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. * diff --git a/src/lib/eolian/eo_lexer.c b/src/lib/eolian/eo_lexer.c index 65b28ebc18..206180d267 100644 --- a/src/lib/eolian/eo_lexer.c +++ b/src/lib/eolian/eo_lexer.c @@ -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) { diff --git a/src/lib/eolian/eo_lexer.rl b/src/lib/eolian/eo_lexer.rl index ef6237a5d6..3b7adb76f8 100644 --- a/src/lib/eolian/eo_lexer.rl +++ b/src/lib/eolian/eo_lexer.rl @@ -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) { diff --git a/src/lib/eolian/eolian_database.c b/src/lib/eolian/eolian_database.c index 69a4ad4d88..e599b21048 100644 --- a/src/lib/eolian/eolian_database.c +++ b/src/lib/eolian/eolian_database.c @@ -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) { diff --git a/src/lib/eolian/eolian_database.h b/src/lib/eolian/eolian_database.h index 79a3412027..a307727fce 100644 --- a/src/lib/eolian/eolian_database.h +++ b/src/lib/eolian/eolian_database.h @@ -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