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); 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) * @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: case NODE_TYPEDEF:
eo_definitions_typedef_def_free(nd->def_typedef); eo_definitions_typedef_def_free(nd->def_typedef);
break; break;
case NODE_STRUCT:
if (nd->def_struct) eo_definitions_type_free(nd->def_struct);
default: default:
break; break;
} }

View File

@ -56,7 +56,8 @@ typedef struct _Eo_Token
enum Nodes enum Nodes
{ {
NODE_CLASS = 0, NODE_CLASS = 0,
NODE_TYPEDEF NODE_TYPEDEF,
NODE_STRUCT
}; };
typedef struct _Eo_Node typedef struct _Eo_Node
@ -66,6 +67,7 @@ typedef struct _Eo_Node
void *def; void *def;
Eo_Class_Def *def_class; Eo_Class_Def *def_class;
Eo_Typedef_Def *def_typedef; Eo_Typedef_Def *def_typedef;
Eo_Type_Def *def_struct;
}; };
} Eo_Node; } Eo_Node;

View File

@ -214,16 +214,16 @@ parse_struct(Eo_Lexer *ls, const char *name)
check_next(ls, '{'); check_next(ls, '{');
while (ls->t.token != '}') while (ls->t.token != '}')
{ {
const char *name; const char *fname;
check(ls, TOK_VALUE); check(ls, TOK_VALUE);
if (eina_hash_find(def->fields, ls->t.value)) if (eina_hash_find(def->fields, ls->t.value))
eo_lexer_syntax_error(ls, "double field definition"); 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); eo_lexer_get(ls);
check_next(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_TRUE, EINA_FALSE));
eina_stringshare_del(name); eina_stringshare_del(fname);
check_next(ls, ';'); check_next(ls, ';');
if (ls->t.token == TOK_COMMENT) if (ls->t.token == TOK_COMMENT)
{ {
@ -231,6 +231,7 @@ parse_struct(Eo_Lexer *ls, const char *name)
} }
} }
check_match(ls, '}', '{', line, column); check_match(ls, '}', '{', line, column);
if (name) append_node(ls, NODE_STRUCT, def);
return def; return def;
} }
@ -1003,6 +1004,7 @@ parse_unit(Eo_Lexer *ls, Eina_Bool eot)
name = eina_stringshare_add(ls->t.value); name = eina_stringshare_add(ls->t.value);
eo_lexer_get(ls); eo_lexer_get(ls);
parse_struct(ls, name); parse_struct(ls, name);
ls->tmp.type_def = NULL;
} }
def: def:
default: default:
@ -1169,6 +1171,12 @@ _dump_type(Eo_Typedef_Def *type)
printf("\n"); printf("\n");
} }
static void
_dump_struct(Eo_Type_Def *type)
{
_print_type(stdout, type);
}
void void
eo_parser_dump(Eo_Lexer *ls) eo_parser_dump(Eo_Lexer *ls)
{ {
@ -1185,6 +1193,8 @@ eo_parser_dump(Eo_Lexer *ls)
case NODE_TYPEDEF: case NODE_TYPEDEF:
_dump_type(nd->def_typedef); _dump_type(nd->def_typedef);
break; break;
case NODE_STRUCT:
_dump_struct(nd->def_struct);
default: default:
break; break;
} }
@ -1403,9 +1413,15 @@ _db_fill_class(Eo_Class_Def *kls, const char *filename)
static Eina_Bool static Eina_Bool
_db_fill_type(Eo_Typedef_Def *type_def) _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; 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 Eina_Bool
@ -1459,6 +1475,14 @@ nodeloop:
if (!_db_fill_type(nd->def_typedef)) if (!_db_fill_type(nd->def_typedef))
goto error; goto error;
break; break;
case NODE_STRUCT:
{
Eo_Type_Def *def = nd->def_struct;
nd->def_struct = NULL;
if (!_db_fill_struct(def))
goto error;
break;
}
default: default:
break; break;
} }

View File

@ -16,6 +16,7 @@
static Eina_List *_classes = NULL; static Eina_List *_classes = NULL;
static Eina_Hash *_types = 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 *_filenames = NULL; /* Hash: filename without extension -> full path */
static Eina_Hash *_tfilenames = NULL; static Eina_Hash *_tfilenames = NULL;
static int _database_init_count = 0; static int _database_init_count = 0;
@ -185,6 +186,7 @@ database_init()
if (_database_init_count > 0) return ++_database_init_count; if (_database_init_count > 0) return ++_database_init_count;
eina_init(); eina_init();
_types = eina_hash_stringshared_new(_type_hash_free_cb); _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); _filenames = eina_hash_string_small_new(free);
_tfilenames = eina_hash_string_small_new(free); _tfilenames = eina_hash_string_small_new(free);
return ++_database_init_count; return ++_database_init_count;
@ -206,6 +208,7 @@ database_shutdown()
EINA_LIST_FREE(_classes, class) EINA_LIST_FREE(_classes, class)
_class_del((_Class_Desc *)class); _class_del((_Class_Desc *)class);
eina_hash_free(_types); eina_hash_free(_types);
eina_hash_free(_structs);
eina_hash_free(_filenames); eina_hash_free(_filenames);
eina_hash_free(_tfilenames); eina_hash_free(_tfilenames);
eina_shutdown(); eina_shutdown();
@ -227,6 +230,17 @@ database_type_add(const char *alias, Eolian_Type type)
return EINA_FALSE; 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 EAPI Eolian_Type
eolian_type_find_by_alias(const char *alias) 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; 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 Eolian_Class
database_class_add(const char *class_name, Eolian_Class_Type type) 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 */ /* Add a type in the database */
Eina_Bool database_type_add(const char *alias, Eolian_Type type); 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 */ /* Add a class in the database */
Eolian_Class database_class_add(const char *class_name, Eolian_Class_Type type); Eolian_Class database_class_add(const char *class_name, Eolian_Class_Type type);