efl/src/bin/eolian/types.c

192 lines
7.3 KiB
C

#include "main.h"
#include "docs.h"
static Eina_Strbuf *
_type_generate(const Eolian_Typedecl *tp, Eina_Bool full, Eina_Bool legacy)
{
char *grp = strdup(eolian_typedecl_full_name_get(tp));
char *p = strrchr(grp, '.');
if (p) *p = '\0';
Eina_Strbuf *buf = eo_gen_docs_full_gen(eolian_typedecl_documentation_get(tp),
grp, 0, legacy);
free(grp);
if (!buf) buf = eina_strbuf_new();
else eina_strbuf_append_char(buf, '\n');
Eolian_Typedecl_Type tpt = eolian_typedecl_type_get(tp);
switch (tpt)
{
case EOLIAN_TYPEDECL_ALIAS:
{
Eina_Stringshare *tn = eolian_typedecl_c_type_get(tp);
eina_strbuf_append(buf, tn);
eina_stringshare_del(tn);
break;
}
case EOLIAN_TYPEDECL_STRUCT:
case EOLIAN_TYPEDECL_STRUCT_OPAQUE:
{
const Eolian_Struct_Type_Field *memb;
char *fn = eo_gen_c_full_name_get(eolian_typedecl_full_name_get(tp));
if (tpt == EOLIAN_TYPEDECL_STRUCT_OPAQUE || !full)
{
eina_strbuf_append_printf(buf, "typedef struct _%s %s", fn, fn);
free(fn);
break;
}
eina_strbuf_append_printf(buf, "typedef struct _%s\n{\n", fn);
Eina_Iterator *membs = eolian_typedecl_struct_fields_get(tp);
EINA_ITERATOR_FOREACH(membs, memb)
{
const Eolian_Type *mtp = eolian_typedecl_struct_field_type_get(memb);
Eina_Stringshare *ct = NULL;
if (eolian_type_type_get(mtp) == EOLIAN_TYPE_STATIC_ARRAY)
{
ct = eolian_type_c_type_get(eolian_type_base_type_get(mtp));
eina_strbuf_append_printf(buf, " %s%s%s[%zu];",
ct, strchr(ct, '*') ? "" : " ",
eolian_typedecl_struct_field_name_get(memb),
eolian_type_array_size_get(mtp));
}
else
{
ct = eolian_type_c_type_get(mtp);
eina_strbuf_append_printf(buf, " %s%s%s;",
ct, strchr(ct, '*') ? "" : " ",
eolian_typedecl_struct_field_name_get(memb));
}
eina_stringshare_del(ct);
const Eolian_Documentation *fdoc
= eolian_typedecl_struct_field_documentation_get(memb);
if (fdoc)
{
const char *nl = strrchr(eina_strbuf_string_get(buf), '\n');
if (nl)
{
Eina_Strbuf *fbuf = eo_gen_docs_full_gen(fdoc, NULL,
strlen(nl), legacy);
if (fbuf)
eina_strbuf_append_printf(buf, " %s",
eina_strbuf_string_get(fbuf));
eina_strbuf_free(fbuf);
}
}
eina_strbuf_append(buf, "\n");
}
eina_iterator_free(membs);
eina_strbuf_append_printf(buf, "} %s", fn);
free(fn);
break;
}
case EOLIAN_TYPEDECL_ENUM:
{
const Eolian_Enum_Type_Field *memb;
if (!full)
break;
eina_strbuf_append_printf(buf, "typedef enum\n{\n");
Eina_Iterator *membs = eolian_typedecl_enum_fields_get(tp);
Eina_Bool next = eina_iterator_next(membs, (void **)&memb);
while (next)
{
const Eolian_Expression *vale =
eolian_typedecl_enum_field_value_get(memb, EINA_FALSE);
Eina_Stringshare *membn =
eolian_typedecl_enum_field_c_name_get(memb);
if (!vale)
eina_strbuf_append_printf(buf, " %s", membn);
else
{
Eolian_Value val =
eolian_expression_eval(vale, EOLIAN_MASK_INT);
const char *lit = eolian_expression_value_to_literal(&val);
eina_strbuf_append_printf(buf, " %s = %s", membn, lit);
const char *exp = eolian_expression_serialize(vale);
if (exp && strcmp(lit, exp))
eina_strbuf_append_printf(buf, " /* %s */", exp);
eina_stringshare_del(exp);
eina_stringshare_del(lit);
}
eina_stringshare_del(membn);
const Eolian_Documentation *fdoc
= eolian_typedecl_enum_field_documentation_get(memb);
next = eina_iterator_next(membs, (void **)&memb);
if (next)
eina_strbuf_append(buf, ",");
if (fdoc)
{
const char *nl = strrchr(eina_strbuf_string_get(buf), '\n');
if (nl)
{
Eina_Strbuf *fbuf = eo_gen_docs_full_gen(fdoc, NULL,
strlen(nl), legacy);
if (fbuf)
eina_strbuf_append_printf(buf, " %s",
eina_strbuf_string_get(fbuf));
eina_strbuf_free(fbuf);
}
}
eina_strbuf_append(buf, "\n");
}
eina_iterator_free(membs);
char *fn = eo_gen_c_full_name_get(eolian_typedecl_full_name_get(tp));
eina_strbuf_append_printf(buf, "} %s", fn);
free(fn);
break;
}
default:
eina_strbuf_reset(buf);
break;
}
return buf;
}
void eo_gen_types_header_gen(const char *eof, Eina_Strbuf *buf,
Eina_Bool full, Eina_Bool legacy)
{
const Eolian_Declaration *decl;
Eina_Iterator *itr = eolian_declarations_get_by_file(eof);
EINA_ITERATOR_FOREACH(itr, decl)
{
Eolian_Declaration_Type dt = eolian_declaration_type_get(decl);
if ((dt != EOLIAN_DECL_ALIAS) &&
(dt != EOLIAN_DECL_STRUCT) &&
(dt != EOLIAN_DECL_ENUM))
continue;
if (dt == EOLIAN_DECL_ENUM && !full)
continue;
const Eolian_Typedecl *tp = eolian_declaration_data_type_get(decl);
if (!tp || eolian_typedecl_is_extern(tp))
continue;
if (eolian_typedecl_type_get(tp) == EOLIAN_TYPEDECL_ALIAS)
{
const Eolian_Type *btp = eolian_typedecl_base_type_get(tp);
if (eolian_type_type_get(btp) == EOLIAN_TYPE_UNDEFINED)
continue;
}
Eina_Strbuf *tbuf = _type_generate(tp, full, legacy);
if (tbuf)
{
eina_strbuf_append(buf, eina_strbuf_string_get(tbuf));
eina_strbuf_append(buf, ";\n\n");
eina_strbuf_free(tbuf);
}
}
}
Eina_Strbuf *eo_gen_class_typedef_gen(const char *eof)
{
const Eolian_Class *cl = eolian_class_get_by_file(eof);
if (!cl)
return NULL;
char *clfn = eo_gen_c_full_name_get(eolian_class_full_name_get(cl));
if (!clfn)
return NULL;
Eina_Strbuf *ret = eina_strbuf_new();
eina_strbuf_append_printf(ret, "typedef Eo %s;\n", clfn);
free(clfn);
return ret;
}