eolian: new API: eolian_type_enum_legacy_prefix_set + generator changes
authorDaniel Kolesa <d.kolesa@samsung.com>
Tue, 12 Aug 2014 16:24:24 +0000 (17:24 +0100)
committerDaniel Kolesa <d.kolesa@samsung.com>
Thu, 21 Aug 2014 08:26:04 +0000 (09:26 +0100)
This change adds a new API to retrieve the legacy prefix for enum members
and also adds support for generating enums into the C generator. Besides that,
it prevents generation of entire struct contents when the .eo file declares
a named struct inside of a typedef - as the struct itself gets generated later on.

src/bin/eolian/types_generator.c
src/lib/eolian/Eolian.h
src/lib/eolian/database_type_api.c
src/tests/eolian/data/struct_ref.c

index e770fe3..9da0558 100644 (file)
@@ -37,7 +37,7 @@ _desc_generate(const char *desc, Eina_Strbuf *buf)
 }
 
 static Eina_Strbuf *
-_type_generate(const Eolian_Type *tp)
+_type_generate(const Eolian_Type *tp, Eina_Bool in_typedef)
 {
    Eina_Strbuf *buf = eina_strbuf_new();
    _desc_generate(eolian_type_description_get(tp), buf);
@@ -48,10 +48,10 @@ _type_generate(const Eolian_Type *tp)
            {
               const Eolian_Type *base_tp = eolian_type_base_type_get(tp);
               Eolian_Type_Type base_tp_type = eolian_type_type_get(base_tp);
-              if (base_tp_type == EOLIAN_TYPE_STRUCT)
+              if (base_tp_type == EOLIAN_TYPE_STRUCT || base_tp_type == EOLIAN_TYPE_ENUM)
                 {
                    const char *name = eolian_type_name_get(tp);
-                   Eina_Strbuf *struct_buf = _type_generate(base_tp);
+                   Eina_Strbuf *struct_buf = _type_generate(base_tp, EINA_TRUE);
                    eina_strbuf_append_printf(buf, "typedef %s%s%s",
                          eina_strbuf_string_get(struct_buf),
                          name?" ":"", name?name:"");
@@ -72,6 +72,12 @@ _type_generate(const Eolian_Type *tp)
            {
               const char *member_name;
               char *name = _concat_name(tp);
+              if (in_typedef && name)
+                {
+                   eina_strbuf_append_printf(buf, "struct %s", name);
+                   free(name);
+                   break;
+                }
               eina_strbuf_append_printf(buf, "struct%s%s {\n", name?" ":"", name?name:"");
               free(name);
               Eina_Iterator *members = eolian_type_struct_field_names_get(tp);
@@ -90,6 +96,62 @@ _type_generate(const Eolian_Type *tp)
               eina_strbuf_append(buf, "}");
               break;
            }
+      case EOLIAN_TYPE_ENUM:
+           {
+              const char *member_name;
+              char *name = _concat_name(tp);
+              if (in_typedef)
+                {
+                   eina_strbuf_append_printf(buf, "enum %s", name);
+                   free(name);
+                   break;
+                }
+              char *pre = NULL;
+              eina_strbuf_append_printf(buf, "enum %s {\n", name);
+              if (eolian_type_enum_legacy_prefix_get(tp))
+                {
+                   pre = strdup(eolian_type_enum_legacy_prefix_get(tp));
+                   free(name);
+                }
+              else
+                pre = name;
+              eina_str_toupper(&pre);
+              Eina_Iterator *members = eolian_type_enum_field_names_get(tp);
+              Eina_Bool next = eina_iterator_next(members, (void**)&member_name);
+              Eina_Strbuf *membuf = eina_strbuf_new();
+              while (next)
+                {
+                   const char *desc = eolian_type_enum_field_description_get(tp, member_name);
+                   const Eolian_Expression *member = eolian_type_enum_field_get(tp, member_name);
+                   char *memb_u = strdup(member_name);
+                   eina_str_toupper(&memb_u);
+                   eina_strbuf_reset(membuf);
+                   eina_strbuf_append(membuf, pre);
+                   eina_strbuf_append_char(membuf, '_');
+                   eina_strbuf_append(membuf, memb_u);
+                   free(memb_u);
+                   if (!member)
+                     eina_strbuf_append_printf(buf, "  %s", eina_strbuf_string_get(membuf));
+                   else
+                     {
+                        Eina_Value *v = NULL;
+                        Eolian_Expression_Type et = eolian_expression_eval(member, EOLIAN_MASK_INT, &v);
+                        const char *lit = eolian_expression_value_to_literal(v, et);
+                        eina_strbuf_append_printf(buf, "  %s = %s", eina_strbuf_string_get(membuf), lit);
+                        eina_stringshare_del(lit);
+                     }
+                   next = eina_iterator_next(members, (void**)&member_name);
+                   if (next)
+                     eina_strbuf_append(buf, ",");
+                   if (desc) eina_strbuf_append_printf(buf, " /** %s */", desc);
+                   eina_strbuf_append(buf, "\n");
+                }
+              eina_strbuf_free(membuf);
+              free(pre);
+              eina_iterator_free(members);
+              eina_strbuf_append(buf, "}");
+              break;
+           }
       default:
            {
               eina_strbuf_reset(buf);
@@ -107,10 +169,7 @@ types_header_generate(const char *eo_filename, Eina_Strbuf *buf)
    Eina_Iterator *itr = eolian_type_aliases_get_by_file(eo_filename);
    EINA_ITERATOR_FOREACH(itr, tp)
      {
-        /* avoid for the time being */
-        if (eolian_type_type_get(eolian_type_base_type_get(tp)) == EOLIAN_TYPE_ENUM)
-          continue;
-        Eina_Strbuf *type_buf = _type_generate(tp);
+        Eina_Strbuf *type_buf = _type_generate(tp, EINA_TRUE);
         if (type_buf)
           {
              eina_strbuf_append(buf, eina_strbuf_string_get(type_buf));
@@ -124,7 +183,21 @@ types_header_generate(const char *eo_filename, Eina_Strbuf *buf)
    itr = eolian_type_structs_get_by_file(eo_filename);
    EINA_ITERATOR_FOREACH(itr, tp)
      {
-        Eina_Strbuf *type_buf = _type_generate(tp);
+        Eina_Strbuf *type_buf = _type_generate(tp, EINA_FALSE);
+        if (type_buf)
+          {
+             eina_strbuf_append(buf, eina_strbuf_string_get(type_buf));
+             eina_strbuf_append(buf, ";\n\n");
+             eina_strbuf_free(type_buf);
+          }
+     }
+   eina_iterator_free(itr);
+
+   /* Generation of enums */
+   itr = eolian_type_enums_get_by_file(eo_filename);
+   EINA_ITERATOR_FOREACH(itr, tp)
+     {
+        Eina_Strbuf *type_buf = _type_generate(tp, EINA_FALSE);
         if (type_buf)
           {
              eina_strbuf_append(buf, eina_strbuf_string_get(type_buf));
@@ -133,6 +206,7 @@ types_header_generate(const char *eo_filename, Eina_Strbuf *buf)
           }
      }
    eina_iterator_free(itr);
+
    return EINA_TRUE;
 }
 
index ff21665..5dd3925 100644 (file)
@@ -1086,6 +1086,17 @@ EAPI const Eolian_Expression *eolian_type_enum_field_get(const Eolian_Type *tp,
 EAPI Eina_Stringshare *eolian_type_enum_field_description_get(const Eolian_Type *tp, const char *field);
 
 /*
+ * @brief Get the legacy prefix of enum field names. When not specified,
+ * enum name is used.
+ *
+ * @param[in] tp the type.
+ * @return the legacy prefix or NULL.
+ *
+ * @ingroup Eolian
+ */
+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.
index 225d73a..9bc9da1 100644 (file)
@@ -173,6 +173,14 @@ eolian_type_enum_field_description_get(const Eolian_Type *tp, const char *field)
 }
 
 EAPI Eina_Stringshare *
+eolian_type_enum_legacy_prefix_get(const Eolian_Type *tp)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(tp, NULL);
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(tp->type == EOLIAN_TYPE_ENUM, NULL);
+   return tp->legacy;
+}
+
+EAPI Eina_Stringshare *
 eolian_type_description_get(const Eolian_Type *tp)
 {
    Eolian_Type_Type tpp;
index f5d633d..326de88 100644 (file)
@@ -11,10 +11,7 @@ typedef Eo Struct;
 #ifndef _STRUCT_EO_TYPES
 #define _STRUCT_EO_TYPES
 
-typedef struct _Foo {
-  int field;
-  float another;
-} Foo;
+typedef struct _Foo Foo;
 
 typedef struct {
   Foo a;