eolian: add tests for struct types plus fix a double free and name storage on the way

This commit is contained in:
Daniel Kolesa 2014-07-14 12:11:48 +01:00
parent 4d68dfe603
commit 17a6bb122b
4 changed files with 111 additions and 9 deletions

View File

@ -27,7 +27,9 @@ database_typedef_del(Eolian_Typedef *def)
{
if (!def) return;
eina_stringshare_del(def->alias);
database_type_del(def->type);
/* prevent deletion of named structs: stored in another hash */
if (def->type->type != EOLIAN_TYPE_STRUCT || !def->type->name)
database_type_del(def->type);
free(def);
}

View File

@ -274,9 +274,10 @@ parse_struct(Eo_Lexer *ls, const char *name)
static Eolian_Type *
parse_type_struct(Eo_Lexer *ls, Eina_Bool allow_struct, Eina_Bool allow_anon)
{
Eina_Bool has_struct = EINA_FALSE;
Eina_Bool has_struct = EINA_FALSE;
Eolian_Type *def;
const char *ctype;
const char *ctype;
const char *sname = NULL;
switch (ls->t.kw)
{
case KW_const:
@ -315,17 +316,21 @@ parse_type_struct(Eo_Lexer *ls, Eina_Bool allow_struct, Eina_Bool allow_anon)
{
if (allow_anon && ls->t.token == '{')
return parse_struct(ls, NULL);
check(ls, TOK_VALUE);
sname = eina_stringshare_add(ls->t.value);
if (eo_lexer_lookahead(ls) == '{')
{
const char *name;
check(ls, TOK_VALUE);
if (eo_lexer_get_c_type(ls->t.kw))
eo_lexer_syntax_error(ls, "invalid struct name");
name = eina_stringshare_add(ls->t.value);
eo_lexer_get(ls);
return parse_struct(ls, name);
return parse_struct(ls, sname);
}
}
else
{
check(ls, TOK_VALUE);
sname = eina_stringshare_add(ls->t.value);
}
has_struct = EINA_TRUE;
break;
case KW_func:
@ -343,8 +348,11 @@ parse_type_struct(Eo_Lexer *ls, Eina_Bool allow_struct, Eina_Bool allow_anon)
check(ls, TOK_VALUE);
ctype = eo_lexer_get_c_type(ls->t.kw);
if (ctype && has_struct)
eo_lexer_syntax_error(ls, "invalid struct name");
def->name = eina_stringshare_add(ctype ? ctype : ls->t.value);
{
eina_stringshare_del(sname);
eo_lexer_syntax_error(ls, "invalid struct name");
}
def->name = sname ? sname : eina_stringshare_add(ctype ? ctype : ls->t.value);
}
eo_lexer_get(ls);
parse_ptr:

View File

@ -0,0 +1,31 @@
struct Named {
field: int;
something: const(char)*;
}
struct Another {
field: struct Named;
}
/* named typedef'd */
type Foo: struct _Foo {
field: int;
another: float;
};
/* anonymous */
type Bar: struct {
a: Foo;
b: struct _Foo;
};
class Dummy {
methods {
foo {
params {
int idx;
}
return own(char*);
}
}
}

View File

@ -483,6 +483,66 @@ START_TEST(eolian_simple_parsing)
}
END_TEST
START_TEST(eolian_struct)
{
const Eolian_Type *type = NULL, *field = NULL;
const Eolian_Class *class;
const char *type_name;
eolian_init();
/* Parsing */
fail_if(!eolian_eo_file_parse(PACKAGE_DATA_DIR"/data/struct.eo"));
/* Check that the class Dummy is still readable */
fail_if(!(class = eolian_class_find_by_name("Dummy")));
fail_if(!eolian_class_function_find_by_name(class, "foo", EOLIAN_METHOD));
/* named struct */
fail_if(!(type = eolian_type_struct_find_by_name("Named")));
fail_if(!(type_name = eolian_type_name_get(type)));
fail_if(eolian_type_type_get(type) != EOLIAN_TYPE_STRUCT);
fail_if(eolian_type_is_own(type));
fail_if(eolian_type_is_const(type));
fail_if(strcmp(type_name, "Named"));
eina_stringshare_del(type_name);
fail_if(!(field = eolian_type_struct_field_get(type, "field")));
fail_if(!(type_name = eolian_type_name_get(field)));
fail_if(strcmp(type_name, "int"));
eina_stringshare_del(type_name);
fail_if(!(field = eolian_type_struct_field_get(type, "something")));
fail_if(!(type_name = eolian_type_c_type_get(field)));
fail_if(strcmp(type_name, "const char *"));
eina_stringshare_del(type_name);
/* referencing */
fail_if(!(type = eolian_type_struct_find_by_name("Another")));
fail_if(!(type_name = eolian_type_name_get(type)));
fail_if(eolian_type_type_get(type) != EOLIAN_TYPE_STRUCT);
fail_if(strcmp(type_name, "Another"));
eina_stringshare_del(type_name);
fail_if(!(field = eolian_type_struct_field_get(type, "field")));
fail_if(!(type_name = eolian_type_name_get(field)));
fail_if(strcmp(type_name, "Named"));
eina_stringshare_del(type_name);
fail_if(eolian_type_type_get(field) != EOLIAN_TYPE_REGULAR_STRUCT);
/* typedef */
fail_if(!(type = eolian_type_find_by_alias("Foo")));
fail_if(!(type_name = eolian_type_name_get(type)));
fail_if(eolian_type_type_get(type) != EOLIAN_TYPE_STRUCT);
fail_if(strcmp(type_name, "_Foo"));
eina_stringshare_del(type_name);
/* typedef - anon */
fail_if(!(type = eolian_type_find_by_alias("Bar")));
fail_if(!!(type_name = eolian_type_name_get(type)));
fail_if(eolian_type_type_get(type) != EOLIAN_TYPE_STRUCT);
eolian_shutdown();
}
END_TEST
void eolian_parsing_test(TCase *tc)
{
tcase_add_test(tc, eolian_simple_parsing);
@ -494,5 +554,6 @@ void eolian_parsing_test(TCase *tc)
tcase_add_test(tc, eolian_override);
tcase_add_test(tc, eolian_events);
tcase_add_test(tc, eolian_namespaces);
tcase_add_test(tc, eolian_struct);
}