q66 pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=17a6bb122b120f9dfadfd3b0ea0555bd90ea2274

commit 17a6bb122b120f9dfadfd3b0ea0555bd90ea2274
Author: Daniel Kolesa <[email protected]>
Date:   Mon Jul 14 12:11:48 2014 +0100

    eolian: add tests for struct types plus fix a double free and name storage 
on the way
---
 src/lib/eolian/database_type.c    |  4 ++-
 src/lib/eolian/eo_parser.c        | 24 ++++++++++-----
 src/tests/eolian/data/struct.eo   | 31 ++++++++++++++++++++
 src/tests/eolian/eolian_parsing.c | 61 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 111 insertions(+), 9 deletions(-)

diff --git a/src/lib/eolian/database_type.c b/src/lib/eolian/database_type.c
index b7cfeb7..83c367c 100644
--- a/src/lib/eolian/database_type.c
+++ b/src/lib/eolian/database_type.c
@@ -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);
 }
 
diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c
index b63f259..d94688f 100644
--- a/src/lib/eolian/eo_parser.c
+++ b/src/lib/eolian/eo_parser.c
@@ -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:
diff --git a/src/tests/eolian/data/struct.eo b/src/tests/eolian/data/struct.eo
new file mode 100644
index 0000000..9b0209d
--- /dev/null
+++ b/src/tests/eolian/data/struct.eo
@@ -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*);
+      }
+   }
+}
diff --git a/src/tests/eolian/eolian_parsing.c 
b/src/tests/eolian/eolian_parsing.c
index 269817b..1c80281 100644
--- a/src/tests/eolian/eolian_parsing.c
+++ b/src/tests/eolian/eolian_parsing.c
@@ -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);
 }
 

-- 


Reply via email to