From 6bd0e0ab7f4f2835aff227d89352bf534c228ce9 Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Tue, 8 Jul 2014 16:42:33 +0100 Subject: [PATCH] eolian: better struct support including an API for by-name lookup --- src/lib/eolian/Eolian.h | 10 +++++++++ src/lib/eolian/eo_lexer.c | 2 ++ src/lib/eolian/eo_lexer.h | 4 +++- src/lib/eolian/eo_parser.c | 36 ++++++++++++++++++++++++++------ src/lib/eolian/eolian_database.c | 24 +++++++++++++++++++++ src/lib/eolian/eolian_database.h | 3 +++ 6 files changed, 72 insertions(+), 7 deletions(-) diff --git a/src/lib/eolian/Eolian.h b/src/lib/eolian/Eolian.h index dfec6c6363..5687cd8527 100644 --- a/src/lib/eolian/Eolian.h +++ b/src/lib/eolian/Eolian.h @@ -717,6 +717,16 @@ EAPI Eina_Bool eolian_class_dtor_enable_get(const Eolian_Class klass); */ EAPI Eolian_Type eolian_type_find_by_alias(const char *alias); +/* + * @brief Find a struct by name + * + * @param[in] name the name of the struct + * @return the struct or NULL + * + * @ingroup Eolian + */ +EAPI Eolian_Type eolian_type_struct_find_by_name(const char *name); + /* * @brief Get the type of a type (regular, function, pointer) * diff --git a/src/lib/eolian/eo_lexer.c b/src/lib/eolian/eo_lexer.c index 6fbf438e8a..32fd29e08c 100644 --- a/src/lib/eolian/eo_lexer.c +++ b/src/lib/eolian/eo_lexer.c @@ -358,6 +358,8 @@ eo_lexer_free(Eo_Lexer *ls) case NODE_TYPEDEF: eo_definitions_typedef_def_free(nd->def_typedef); break; + case NODE_STRUCT: + if (nd->def_struct) eo_definitions_type_free(nd->def_struct); default: break; } diff --git a/src/lib/eolian/eo_lexer.h b/src/lib/eolian/eo_lexer.h index 30f3d706b5..63faf0a17f 100644 --- a/src/lib/eolian/eo_lexer.h +++ b/src/lib/eolian/eo_lexer.h @@ -56,7 +56,8 @@ typedef struct _Eo_Token enum Nodes { NODE_CLASS = 0, - NODE_TYPEDEF + NODE_TYPEDEF, + NODE_STRUCT }; typedef struct _Eo_Node @@ -66,6 +67,7 @@ typedef struct _Eo_Node void *def; Eo_Class_Def *def_class; Eo_Typedef_Def *def_typedef; + Eo_Type_Def *def_struct; }; } Eo_Node; diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c index d31fd9f0ec..6c5042ec7f 100644 --- a/src/lib/eolian/eo_parser.c +++ b/src/lib/eolian/eo_parser.c @@ -214,16 +214,16 @@ parse_struct(Eo_Lexer *ls, const char *name) check_next(ls, '{'); while (ls->t.token != '}') { - const char *name; + const char *fname; 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); + fname = eina_stringshare_add(ls->t.value); eo_lexer_get(ls); check_next(ls, ':'); - eina_hash_add(def->fields, name, parse_type_struct_nonvoid(ls, + eina_hash_add(def->fields, fname, parse_type_struct_nonvoid(ls, EINA_TRUE, EINA_FALSE)); - eina_stringshare_del(name); + eina_stringshare_del(fname); check_next(ls, ';'); if (ls->t.token == TOK_COMMENT) { @@ -231,6 +231,7 @@ parse_struct(Eo_Lexer *ls, const char *name) } } check_match(ls, '}', '{', line, column); + if (name) append_node(ls, NODE_STRUCT, def); return def; } @@ -1003,6 +1004,7 @@ parse_unit(Eo_Lexer *ls, Eina_Bool eot) name = eina_stringshare_add(ls->t.value); eo_lexer_get(ls); parse_struct(ls, name); + ls->tmp.type_def = NULL; } def: default: @@ -1169,6 +1171,12 @@ _dump_type(Eo_Typedef_Def *type) printf("\n"); } +static void +_dump_struct(Eo_Type_Def *type) +{ + _print_type(stdout, type); +} + void eo_parser_dump(Eo_Lexer *ls) { @@ -1185,6 +1193,8 @@ eo_parser_dump(Eo_Lexer *ls) case NODE_TYPEDEF: _dump_type(nd->def_typedef); break; + case NODE_STRUCT: + _dump_struct(nd->def_struct); default: break; } @@ -1403,9 +1413,15 @@ _db_fill_class(Eo_Class_Def *kls, const char *filename) static Eina_Bool _db_fill_type(Eo_Typedef_Def *type_def) { - database_type_add(type_def->alias, (Eolian_Type)type_def->type); + Eina_Bool ret = database_type_add(type_def->alias, (Eolian_Type)type_def->type); type_def->type = NULL; - return EINA_TRUE; + return ret; +} + +static Eina_Bool +_db_fill_struct(Eo_Type_Def *struct_def) +{ + return database_struct_add((Eolian_Type)struct_def); } Eina_Bool @@ -1459,6 +1475,14 @@ nodeloop: if (!_db_fill_type(nd->def_typedef)) goto error; break; + case NODE_STRUCT: + { + Eo_Type_Def *def = nd->def_struct; + nd->def_struct = NULL; + if (!_db_fill_struct(def)) + goto error; + break; + } default: break; } diff --git a/src/lib/eolian/eolian_database.c b/src/lib/eolian/eolian_database.c index 87a435fbaf..6db24469e5 100644 --- a/src/lib/eolian/eolian_database.c +++ b/src/lib/eolian/eolian_database.c @@ -16,6 +16,7 @@ static Eina_List *_classes = NULL; static Eina_Hash *_types = NULL; +static Eina_Hash *_structs = NULL; static Eina_Hash *_filenames = NULL; /* Hash: filename without extension -> full path */ static Eina_Hash *_tfilenames = NULL; static int _database_init_count = 0; @@ -185,6 +186,7 @@ database_init() if (_database_init_count > 0) return ++_database_init_count; eina_init(); _types = eina_hash_stringshared_new(_type_hash_free_cb); + _structs = eina_hash_stringshared_new(EINA_FREE_CB(database_type_del)); _filenames = eina_hash_string_small_new(free); _tfilenames = eina_hash_string_small_new(free); return ++_database_init_count; @@ -206,6 +208,7 @@ database_shutdown() EINA_LIST_FREE(_classes, class) _class_del((_Class_Desc *)class); eina_hash_free(_types); + eina_hash_free(_structs); eina_hash_free(_filenames); eina_hash_free(_tfilenames); eina_shutdown(); @@ -227,6 +230,17 @@ database_type_add(const char *alias, Eolian_Type type) return EINA_FALSE; } +Eina_Bool database_struct_add(Eolian_Type type) +{ + _Parameter_Type *tp = (_Parameter_Type*)type; + if (_structs) + { + eina_hash_set(_structs, tp->name, tp); + return EINA_TRUE; + } + return EINA_FALSE; +} + EAPI Eolian_Type eolian_type_find_by_alias(const char *alias) { @@ -237,6 +251,16 @@ eolian_type_find_by_alias(const char *alias) return cl?cl->type:NULL; } +EAPI Eolian_Type +eolian_type_struct_find_by_name(const char *name) +{ + if (!_structs) return NULL; + Eina_Stringshare *shr = eina_stringshare_add(name); + Eolian_Type tp = eina_hash_find(_structs, shr); + eina_stringshare_del(shr); + return tp; +} + Eolian_Class database_class_add(const char *class_name, Eolian_Class_Type type) { diff --git a/src/lib/eolian/eolian_database.h b/src/lib/eolian/eolian_database.h index f89fb45831..9fd3f7a7b0 100644 --- a/src/lib/eolian/eolian_database.h +++ b/src/lib/eolian/eolian_database.h @@ -37,6 +37,9 @@ int database_shutdown(); /* Add a type in the database */ Eina_Bool database_type_add(const char *alias, Eolian_Type type); +/* Add a struct in the database */ +Eina_Bool database_struct_add(Eolian_Type type); + /* Add a class in the database */ Eolian_Class database_class_add(const char *class_name, Eolian_Class_Type type);