eolian: better struct support including an API for by-name lookup

This commit is contained in:
Daniel Kolesa 2014-07-08 16:42:33 +01:00
parent b2db8d3ffa
commit 6bd0e0ab7f
6 changed files with 72 additions and 7 deletions

View File

@ -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)
*

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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);