forked from enlightenment/efl
eolian: add tests for struct types plus fix a double free and name storage on the way
This commit is contained in:
parent
4d68dfe603
commit
17a6bb122b
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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*);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue