q66 pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=b2db8d3ffa9a696c2a3a1333b3aa6eb26de70a69
commit b2db8d3ffa9a696c2a3a1333b3aa6eb26de70a69 Author: Daniel Kolesa <d.kol...@samsung.com> Date: Tue Jul 8 16:17:44 2014 +0100 eolian: new API for struct types This commit adds new Eolian API and proper parsing support for struct types. Structs can be named (allowed in global context, like typedefs, and in typedefs) and unnamed (allowed as fields of other structs). This extends the existing type API to support structs. This is incomplete for now - I still gotta add a way to query global structs besides other things. @feature --- src/lib/eolian/Eolian.h | 25 ++++++++++++++++++++++++- src/lib/eolian/eo_definitions.c | 8 +++++++- src/lib/eolian/eo_definitions.h | 2 ++ src/lib/eolian/eo_parser.c | 10 +++++++++- src/lib/eolian/eolian_database.c | 35 +++++++++++++++++++++++++---------- 5 files changed, 67 insertions(+), 13 deletions(-) diff --git a/src/lib/eolian/Eolian.h b/src/lib/eolian/Eolian.h index 5f61336..dfec6c6 100644 --- a/src/lib/eolian/Eolian.h +++ b/src/lib/eolian/Eolian.h @@ -119,7 +119,8 @@ typedef enum EOLIAN_TYPE_VOID, EOLIAN_TYPE_REGULAR, EOLIAN_TYPE_POINTER, - EOLIAN_TYPE_FUNCTION + EOLIAN_TYPE_FUNCTION, + EOLIAN_TYPE_STRUCT } Eolian_Type_Type; /* @@ -749,6 +750,28 @@ EAPI Eina_Iterator *eolian_type_arguments_list_get(Eolian_Type tp); EAPI Eina_Iterator *eolian_type_subtypes_list_get(Eolian_Type tp); /* + * @brief Get an iterator to all field names of a struct type. + * + * @param[in] tp the type. + * @return the iterator when @c tp is EOLIAN_TYPE_STRUCT, NULL otherwise. + * + * @ingroup Eolian + */ +EAPI Eina_Iterator *eolian_type_struct_field_names_list_get(Eolian_Type tp); + +/* + * @brief Get a field of a struct type. + * + * @param[in] tp the type. + * @param[in] field the field name. + * @return the field when @c tp is EOLIAN_TYPE_STRUCT, @c field is not NULL + * and the field exists, NULL otherwise. + * + * @ingroup Eolian + */ +EAPI Eolian_Type eolian_type_struct_field_get(Eolian_Type tp, const char *field); + +/* * @brief Get the return type of a function type. * * @param[in] tp the type. diff --git a/src/lib/eolian/eo_definitions.c b/src/lib/eolian/eo_definitions.c index 7ce36ea..bbb7fe8 100644 --- a/src/lib/eolian/eo_definitions.c +++ b/src/lib/eolian/eo_definitions.c @@ -3,11 +3,17 @@ #include "eo_definitions.h" -static void +void eo_definitions_type_free(Eo_Type_Def *tp) { Eo_Type_Def *stp; if (tp->name) eina_stringshare_del(tp->name); + if (tp->type == EOLIAN_TYPE_STRUCT) + { + eina_hash_free(tp->fields); + free(tp); + return; + } /* for function types, this will map to arguments and ret_type */ if (tp->subtypes) EINA_LIST_FREE(tp->subtypes, stp) eo_definitions_type_free(stp); diff --git a/src/lib/eolian/eo_definitions.h b/src/lib/eolian/eo_definitions.h index 5b97802..a8ba72e 100644 --- a/src/lib/eolian/eo_definitions.h +++ b/src/lib/eolian/eo_definitions.h @@ -20,6 +20,7 @@ struct _eo_type_def Eina_List *arguments; Eo_Type_Def *ret_type; }; + Eina_Hash *fields; }; Eina_Bool is_const :1; Eina_Bool is_own :1; @@ -170,6 +171,7 @@ typedef struct _Eo_Lexer_Temps Eo_Implement_Def *impl; } Eo_Lexer_Temps; +void eo_definitions_type_free(Eo_Type_Def *tp); void eo_definitions_class_def_free(Eo_Class_Def *kls); void eo_definitions_typedef_def_free(Eo_Typedef_Def *type); void eo_definitions_temps_free(Eo_Lexer_Temps *tmp); diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c index 9c915d6..d31fd9f 100644 --- a/src/lib/eolian/eo_parser.c +++ b/src/lib/eolian/eo_parser.c @@ -209,13 +209,21 @@ parse_struct(Eo_Lexer *ls, const char *name) Eo_Type_Def *def = calloc(1, sizeof(Eo_Type_Def)); ls->tmp.type_def = def; def->name = name; + def->type = EOLIAN_TYPE_STRUCT; + def->fields = eina_hash_string_small_new(EINA_FREE_CB(eo_definitions_type_free)); check_next(ls, '{'); while (ls->t.token != '}') { + const char *name; check(ls, TOK_VALUE); + if (eina_hash_find(def->fields, ls->t.value)) + eo_lexer_syntax_error(ls, "double field definition"); + name = eina_stringshare_add(ls->t.value); eo_lexer_get(ls); check_next(ls, ':'); - parse_type_struct_nonvoid(ls, EINA_TRUE, EINA_FALSE); + eina_hash_add(def->fields, name, parse_type_struct_nonvoid(ls, + EINA_TRUE, EINA_FALSE)); + eina_stringshare_del(name); check_next(ls, ';'); if (ls->t.token == TOK_COMMENT) { diff --git a/src/lib/eolian/eolian_database.c b/src/lib/eolian/eolian_database.c index af2f386..87a435f 100644 --- a/src/lib/eolian/eolian_database.c +++ b/src/lib/eolian/eolian_database.c @@ -89,6 +89,7 @@ typedef struct Eina_List *arguments; Eolian_Type ret_type; }; + Eina_Hash *fields; }; Eina_Bool is_const :1; Eina_Bool is_own :1; @@ -119,17 +120,8 @@ _param_del(_Parameter_Desc *pdesc) void database_type_del(Eolian_Type type) { - _Parameter_Type *typep = (_Parameter_Type*)type; - Eolian_Type stype; if (!type) return; - if (typep->name) eina_stringshare_del(typep->name); - /* for function types, this will map to arguments and ret_type */ - if (typep->subtypes) - EINA_LIST_FREE(typep->subtypes, stype) - database_type_del(stype); - if (typep->base_type) - database_type_del(typep->base_type); - free(typep); + eo_definitions_type_free((Eo_Type_Def*)type); } static void @@ -1157,6 +1149,29 @@ eolian_type_subtypes_list_get(Eolian_Type tp) return eina_list_iterator_new(tpp->subtypes); } +EAPI Eina_Iterator * +eolian_type_struct_field_names_list_get(Eolian_Type tp) +{ + _Parameter_Type *tpp = (_Parameter_Type*)tp; + Eolian_Type_Type tpt; + EINA_SAFETY_ON_NULL_RETURN_VAL(tp, NULL); + tpt = tpp->type; + EINA_SAFETY_ON_FALSE_RETURN_VAL(tpt == EOLIAN_TYPE_STRUCT, NULL); + return eina_hash_iterator_key_new(tpp->fields); +} + +EAPI Eolian_Type +eolian_type_struct_field_get(Eolian_Type tp, const char *field) +{ + _Parameter_Type *tpp = (_Parameter_Type*)tp; + Eolian_Type_Type tpt; + EINA_SAFETY_ON_NULL_RETURN_VAL(tp, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(field, NULL); + tpt = tpp->type; + EINA_SAFETY_ON_FALSE_RETURN_VAL(tpt == EOLIAN_TYPE_STRUCT, NULL); + return eina_hash_find(tpp->fields, field); +} + EAPI Eolian_Type eolian_type_return_type_get(Eolian_Type tp) { --