eolian: add support for opaque struct types (+ tests)
authorDaniel Kolesa <d.kolesa@samsung.com>
Wed, 13 Aug 2014 15:43:18 +0000 (16:43 +0100)
committerDaniel Kolesa <d.kolesa@samsung.com>
Thu, 21 Aug 2014 08:26:05 +0000 (09:26 +0100)
src/bin/eolian/types_generator.c
src/lib/eolian/Eolian.h
src/lib/eolian/database_type.c
src/lib/eolian/eo_parser.c
src/lib/eolian/eolian_database.h
src/tests/eolian/data/struct.eo
src/tests/eolian/data/struct_ref.c
src/tests/eolian/eolian_parsing.c

index 63d4128..300bbde 100644 (file)
@@ -69,10 +69,11 @@ _type_generate(const Eolian_Type *tp, Eina_Bool in_typedef)
               break;
            }
       case EOLIAN_TYPE_STRUCT:
+      case EOLIAN_TYPE_STRUCT_OPAQUE:
            {
               const char *member_name;
               char *name = _concat_name(tp);
-              if (in_typedef && name)
+              if ((in_typedef && name) || tp_type == EOLIAN_TYPE_STRUCT_OPAQUE)
                 {
                    eina_strbuf_append_printf(buf, "struct %s", name);
                    free(name);
index 7a6df64..0d6271a 100644 (file)
@@ -136,6 +136,7 @@ typedef enum
    EOLIAN_TYPE_POINTER,
    EOLIAN_TYPE_FUNCTION,
    EOLIAN_TYPE_STRUCT,
+   EOLIAN_TYPE_STRUCT_OPAQUE,
    EOLIAN_TYPE_ENUM,
    EOLIAN_TYPE_ALIAS,
    EOLIAN_TYPE_CLASS
@@ -1143,7 +1144,8 @@ EAPI Eina_Stringshare *eolian_type_enum_legacy_prefix_get(const Eolian_Type *tp)
  * @brief Get the description of a struct/alias type.
  *
  * @param[in] tp the type.
- * @return the description when @c tp is EOLIAN_TYPE_STRUCT, NULL otherwise.
+ * @return the description when @c tp is EOLIAN_TYPE_STRUCT or
+ * EOLIAN_TYPE_STRUCT_OPAQUE, NULL otherwise.
  *
  * @ingroup Eolian
  */
@@ -1153,7 +1155,7 @@ EAPI Eina_Stringshare *eolian_type_description_get(const Eolian_Type *tp);
  * @brief Get the filename of a struct/alias type.
  *
  * @param[in] tp the type.
- * @return the filename when @c tp is EOLIAN_TYPE_STRUCT, NULL otherwise.
+ * @return the filename.
  *
  * @ingroup Eolian
  */
@@ -1261,10 +1263,10 @@ EAPI Eina_Stringshare *eolian_type_c_type_get(const Eolian_Type *tp);
 /*
  * @brief Get the name of the given type. You have to manually delete
  * the stringshare. For EOLIAN_TYPE_REGULAR and EOLIAN_TYPE_REGULAR_STRUCT,
- * this is for example "int". For EOLIAN_TYPE_STRUCT and EOLIAN_TYPE_ALIAS,
- * this is the name of the alias or of the struct. For EOLIAN_TYPE_CLASS,
- * this can be "Button". Keep in mind that the name doesn't include
- * namespaces for structs and aliases.
+ * this is for example "int". For EOLIAN_TYPE_STRUCT, EOLIAN_TYPE_STRUCT_OPAQUE
+ * and EOLIAN_TYPE_ALIAS, this is the name of the alias or of the struct. For
+ * EOLIAN_TYPE_CLASS, this can be "Button". Keep in mind that the name doesn't
+ * include namespaces for structs and aliases.
  *
  * @param[in] tp the type.
  * @return the name.
index b6589b5..0cea70e 100644 (file)
@@ -34,7 +34,8 @@ database_typedef_del(Eolian_Type *tp)
      {
         if (btp->type == EOLIAN_TYPE_ENUM)
           tp->base_type = NULL;
-        else if (btp->type == EOLIAN_TYPE_STRUCT && btp->name)
+        else if ((btp->type == EOLIAN_TYPE_STRUCT
+               || btp->type == EOLIAN_TYPE_STRUCT_OPAQUE) && btp->name)
           tp->base_type = NULL;
      }
    database_type_del(tp);
@@ -107,6 +108,8 @@ _stype_to_str(const Eolian_Type *tp, Eina_Strbuf *buf, const char *name)
         eina_strbuf_append(buf, tp->name);
         eina_strbuf_append_char(buf, ' ');
      }
+   if (tp->type == EOLIAN_TYPE_STRUCT_OPAQUE)
+     goto append_name;
    eina_strbuf_append(buf, "{ ");
    EINA_LIST_FOREACH(tp->field_names, l, fname)
      {
@@ -115,6 +118,7 @@ _stype_to_str(const Eolian_Type *tp, Eina_Strbuf *buf, const char *name)
         eina_strbuf_append(buf, "; ");
      }
    eina_strbuf_append(buf, "}");
+append_name:
    if (name)
      {
         eina_strbuf_append_char(buf, ' ');
@@ -201,7 +205,8 @@ database_type_to_str(const Eolian_Type *tp, Eina_Strbuf *buf, const char *name)
         _ftype_to_str(tp, buf, name);
         return;
      }
-   else if (tp->type == EOLIAN_TYPE_STRUCT)
+   else if (tp->type == EOLIAN_TYPE_STRUCT
+         || tp->type == EOLIAN_TYPE_STRUCT_OPAQUE)
      {
         _stype_to_str(tp, buf, name);
         return;
@@ -299,7 +304,8 @@ database_type_print(Eolian_Type *tp)
      printf("%s", tp->full_name);
    else if (tp->type == EOLIAN_TYPE_VOID)
      printf("void");
-   else if (tp->type == EOLIAN_TYPE_REGULAR_STRUCT)
+   else if (tp->type == EOLIAN_TYPE_REGULAR_STRUCT
+         || tp->type == EOLIAN_TYPE_STRUCT_OPAQUE)
      printf("struct %s", tp->full_name);
    else if (tp->type == EOLIAN_TYPE_REGULAR_ENUM)
      printf("enum %s", tp->full_name);
index 5dc244d..0908f98 100644 (file)
@@ -1774,6 +1774,25 @@ parse_unit(Eo_Lexer *ls, Eina_Bool eot)
              }
            eo_lexer_context_pop(ls);
            pop_strbuf(ls);
+           if (ls->t.token == ';')
+             {
+                Eolian_Type *def = push_type(ls);
+                def->is_extern = is_extern;
+                def->type = EOLIAN_TYPE_STRUCT_OPAQUE;
+                _fill_type_name(def, name);
+                eo_lexer_get(ls);
+                if (ls->t.token == TOK_COMMENT)
+                  {
+                     def->comment = eina_stringshare_ref(ls->t.value.s);
+                     eo_lexer_get(ls);
+                  }
+                def->base.file = eina_stringshare_ref(ls->filename);
+                def->base.line = line;
+                def->base.column = col;
+                database_struct_add(def);
+                pop_type(ls);
+                break;
+             }
            if (is_enum)
              parse_enum(ls, name, is_extern, line, col);
            else
index 38f5365..3f9fe0a 100644 (file)
@@ -138,6 +138,7 @@ struct _Eolian_Type
    Eina_Bool is_const  :1;
    Eina_Bool is_own    :1;
    Eina_Bool is_extern :1;
+   Eina_Bool is_opaque :1;
 };
 
 struct _Eolian_Implement
index 5600393..7b952df 100644 (file)
@@ -19,6 +19,9 @@ type Bar: struct {
     b: struct _Foo;
 };
 
+/* opaque struct */
+struct Opaque;
+
 class Struct {
    methods {
       foo {
index 326de88..acc2d45 100644 (file)
@@ -32,6 +32,8 @@ struct _Foo {
   float another;
 };
 
+struct Opaque;
+
 
 #endif
 #define STRUCT_CLASS struct_class_get()
index 5d98a8f..9334dd1 100644 (file)
@@ -606,6 +606,10 @@ START_TEST(eolian_struct)
    fail_if(!!(type_name = eolian_type_name_get(type)));
    fail_if(eolian_type_type_get(type) != EOLIAN_TYPE_STRUCT);
 
+   /* opaque struct */
+   fail_if(!(type = eolian_type_struct_get_by_name("Opaque")));
+   fail_if(eolian_type_type_get(type) != EOLIAN_TYPE_STRUCT_OPAQUE);
+
    eolian_shutdown();
 }
 END_TEST