eolian: new API: eolian_type_enum_legacy_prefix_set + generator changes

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.
This commit is contained in:
Daniel Kolesa 2014-08-12 17:24:24 +01:00
parent c81356e2ec
commit 732e3f417e
4 changed files with 102 additions and 12 deletions

View 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,7 @@ 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));
@ -133,6 +192,21 @@ types_header_generate(const char *eo_filename, Eina_Strbuf *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));
eina_strbuf_append(buf, ";\n\n");
eina_strbuf_free(type_buf);
}
}
eina_iterator_free(itr);
return EINA_TRUE;
}

View File

@ -1085,6 +1085,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.
*

View File

@ -172,6 +172,14 @@ eolian_type_enum_field_description_get(const Eolian_Type *tp, const char *field)
return ef->comment;
}
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)
{

View 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;