eolian gen2: remove old eolian gen

This commit is contained in:
Daniel Kolesa 2016-10-07 13:26:08 +02:00
parent 82291e9cf5
commit 4cc17ae28a
15 changed files with 0 additions and 3478 deletions

View File

@ -44,30 +44,6 @@ lib_eolian_libeolian_la_LDFLAGS = @EFL_LTLIBRARY_FLAGS@
### Binary
bin_PROGRAMS += \
bin/eolian/eolian_gen
bin_eolian_eolian_gen_SOURCES = \
bin/eolian/common_funcs.c \
bin/eolian/common_funcs.h \
bin/eolian/eo_generator.c \
bin/eolian/eo_generator.h \
bin/eolian/impl_generator.c \
bin/eolian/impl_generator.h \
bin/eolian/legacy_generator.c \
bin/eolian/legacy_generator.h \
bin/eolian/types_generator.c \
bin/eolian/types_generator.h \
bin/eolian/docs_generator.c \
bin/eolian/docs_generator.h \
bin/eolian/main.c
bin_eolian_eolian_gen_CPPFLAGS = -I$(top_builddir)/src/lib/efl @EOLIAN_CFLAGS@
bin_eolian_eolian_gen_LDADD = @USE_EOLIAN_LIBS@
bin_eolian_eolian_gen_DEPENDENCIES = @USE_EOLIAN_INTERNAL_LIBS@
### New generator
bin_PROGRAMS += \
bin/eolian2/eolian_gen2

View File

@ -1 +0,0 @@
/eolian_gen

View File

@ -1,141 +0,0 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "common_funcs.h"
#include "Eolian.h"
int _eolian_gen_log_dom = -1;
Eolian_Class *current_class;
static void
_class_name_concatenate(const Eolian_Class *class, char *buffer)
{
Eina_Iterator *itr = eolian_class_namespaces_get(class);
const char *name;
buffer[0] = '\0';
EINA_ITERATOR_FOREACH(itr, name)
{
sprintf(buffer, "%s_", name);
buffer += (strlen(name) + 1);
}
sprintf(buffer, "%s", eolian_class_name_get(class));
eina_iterator_free(itr);
}
static char *
_fill_envs(char *dest, const char *src, size_t bufs) {
strncpy(dest, src, bufs - 1);
dest[bufs - 1] = '\0';
return dest;
}
void
_class_env_create(const Eolian_Class *class, const char *over_classname, _eolian_class_vars *env)
{
if (!env) return;
const char *eo_prefix = NULL;
char *p;
if (!class)
_fill_envs(env->full_classname, over_classname, sizeof(env->full_classname));
else
_class_name_concatenate(class, env->full_classname);
/* class/CLASS*/
p = _fill_envs(env->upper_classname, env->full_classname, sizeof(env->upper_classname));
eina_str_toupper(&p);
p = _fill_envs(env->lower_classname, env->full_classname, sizeof(env->lower_classname));
eina_str_tolower(&p);
/* eo_prefix */
if (class) eo_prefix = eolian_class_eo_prefix_get(class);
if (!eo_prefix) eo_prefix = env->full_classname;
p = _fill_envs(env->upper_eo_prefix, eo_prefix, sizeof(env->upper_eo_prefix));
eina_str_toupper(&p);
p = _fill_envs(env->lower_eo_prefix, eo_prefix, sizeof(env->lower_eo_prefix));
eina_str_tolower(&p);
/* classtype */
if (class) switch (eolian_class_type_get(class))
{
case EOLIAN_CLASS_REGULAR:
case EOLIAN_CLASS_ABSTRACT:
strcpy(env->lower_classtype, "class");
strcpy(env->upper_classtype, "CLASS");
break;
case EOLIAN_CLASS_MIXIN:
strcpy(env->lower_classtype, "mixin");
strcpy(env->upper_classtype, "MIXIN");
break;
case EOLIAN_CLASS_INTERFACE:
strcpy(env->lower_classtype, "interface");
strcpy(env->upper_classtype, "INTERFACE");
break;
default:
break;
}
}
void
_class_func_env_create(const Eolian_Class *class, const char *funcname, Eolian_Function_Type ftype, _eolian_class_func_vars *env)
{
char *p;
const Eolian_Function *funcid = eolian_class_function_get_by_name(class, funcname, ftype);
p = _fill_envs(env->upper_func, funcname, sizeof(env->upper_func));
eina_str_toupper(&p);
Eolian_Function_Type aftype = ftype;
if (aftype == EOLIAN_PROPERTY) aftype = EOLIAN_METHOD;
Eina_Stringshare *fname = eolian_function_full_c_name_get(funcid, aftype, EINA_FALSE);
p = _fill_envs(env->upper_eo_func, fname, sizeof(env->upper_eo_func));
eina_str_toupper(&p);
p = _fill_envs(env->lower_eo_func, fname, sizeof(env->lower_eo_func));
eina_str_tolower(&p);
eina_stringshare_del(fname);
Eina_Stringshare *lname = eolian_function_full_c_name_get(funcid, aftype, EINA_TRUE);
env->legacy_func[0] = '\0';
if (!lname) return;
p = _fill_envs(env->legacy_func, lname, sizeof(env->legacy_func));
eina_stringshare_del(lname);
}
void
_template_fill(Eina_Strbuf *buf, const char *templ, const Eolian_Class *class, const char *classname, const char *funcname, Eina_Bool reset)
{
_eolian_class_vars tmp_env;
_eolian_class_func_vars tmp_func_env;
_class_env_create(class, classname, &tmp_env);
if (funcname)
_class_func_env_create(class, funcname, EOLIAN_UNRESOLVED, &tmp_func_env);
if (buf)
{
if (reset) eina_strbuf_reset(buf);
if (templ) eina_strbuf_append(buf, templ);
if (funcname)
{
eina_strbuf_replace_all(buf, "@#func", funcname);
eina_strbuf_replace_all(buf, "@#FUNC", tmp_func_env.upper_func);
}
eina_strbuf_replace_all(buf, "@#classtype", tmp_env.lower_classtype);
eina_strbuf_replace_all(buf, "@#CLASSTYPE", tmp_env.upper_classtype);
eina_strbuf_replace_all(buf, "@#Class", tmp_env.full_classname);
eina_strbuf_replace_all(buf, "@#class", tmp_env.lower_classname);
eina_strbuf_replace_all(buf, "@#CLASS", tmp_env.upper_classname);
}
}
const char *
_get_add_star(Eolian_Function_Type ftype, Eolian_Parameter_Dir pdir)
{
if (ftype == EOLIAN_PROP_GET)
return "*";
if ((pdir == EOLIAN_OUT_PARAM) || (pdir == EOLIAN_INOUT_PARAM))
return "*";
return "";
}

View File

@ -1,68 +0,0 @@
#ifndef __EOLIAN_COMMON_FUNCS_H
#define __EOLIAN_COMMON_FUNCS_H
#include <Eina.h>
#include <Eolian.h>
#define EO
extern int _eolian_gen_log_dom;
#ifdef ERR
# undef ERR
#endif
#define ERR(...) EINA_LOG_DOM_ERR(_eolian_gen_log_dom, __VA_ARGS__)
#ifdef DBG
# undef DBG
#endif
#define DBG(...) EINA_LOG_DOM_DBG(_eolian_gen_log_dom, __VA_ARGS__)
#ifdef INF
# undef INF
#endif
#define INF(...) EINA_LOG_DOM_INFO(_eolian_gen_log_dom, __VA_ARGS__)
#ifdef WRN
# undef WRN
#endif
#define WRN(...) EINA_LOG_DOM_WARN(_eolian_gen_log_dom, __VA_ARGS__)
#ifdef CRIT
# undef CRIT
#endif
#define CRIT(...) EINA_LOG_DOM_CRIT(_eolian_gen_log_dom, __VA_ARGS__)
typedef struct
{
char full_classname[PATH_MAX];
char upper_eo_prefix[PATH_MAX];
char lower_eo_prefix[PATH_MAX];
char upper_classname[PATH_MAX];
char lower_classname[PATH_MAX];
char upper_classtype[PATH_MAX];
char lower_classtype[PATH_MAX];
}_eolian_class_vars;
typedef struct
{
char upper_func[PATH_MAX];
char upper_eo_func[PATH_MAX];
char lower_eo_func[PATH_MAX];
char legacy_func[PATH_MAX];
}_eolian_class_func_vars;
void _template_fill(Eina_Strbuf *buf, const char *templ, const Eolian_Class *class, const char *classname, const char *funcname, Eina_Bool reset);
void _class_env_create(const Eolian_Class *class, const char *over_classname, _eolian_class_vars *env);
void _class_func_env_create(const Eolian_Class *class, const char *funcname, Eolian_Function_Type ftype EINA_UNUSED, _eolian_class_func_vars *env);
const char *_get_add_star(Eolian_Function_Type ftype, Eolian_Parameter_Dir pdir);
#endif

View File

@ -1,666 +0,0 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <ctype.h>
#include "docs_generator.h"
static int
_indent_line(Eina_Strbuf *buf, int ind)
{
int i;
for (i = 0; i < ind; ++i)
eina_strbuf_append_char(buf, ' ');
return ind;
}
#define DOC_LINE_LIMIT 79
#define DOC_LINE_TEST 59
#define DOC_LINE_OVER 39
#define DOC_LIMIT(ind) ((ind > DOC_LINE_TEST) ? (ind + DOC_LINE_OVER) \
: DOC_LINE_LIMIT)
static void
_generate_ref(const char *refn, Eina_Strbuf *wbuf, Eina_Bool use_legacy)
{
const Eolian_Declaration *decl = eolian_declaration_get_by_name(refn);
if (decl)
{
char *n = strdup(eolian_declaration_name_get(decl));
char *p = n;
while ((p = strchr(p, '.'))) *p = '_';
eina_strbuf_append(wbuf, n);
free(n);
return;
}
/* not a plain declaration, so it must be struct/enum field or func */
const char *sfx = strrchr(refn, '.');
if (!sfx) goto noref;
Eina_Stringshare *bname = eina_stringshare_add_length(refn, sfx - refn);
const Eolian_Typedecl *tp = eolian_typedecl_struct_get_by_name(bname);
if (tp)
{
if (!eolian_typedecl_struct_field_get(tp, sfx + 1))
{
eina_stringshare_del(bname);
goto noref;
}
_generate_ref(bname, wbuf, use_legacy);
eina_strbuf_append(wbuf, sfx);
eina_stringshare_del(bname);
return;
}
tp = eolian_typedecl_enum_get_by_name(bname);
if (tp)
{
const Eolian_Enum_Type_Field *efl = eolian_typedecl_enum_field_get(tp, sfx + 1);
if (!efl)
{
eina_stringshare_del(bname);
goto noref;
}
_generate_ref(bname, wbuf, use_legacy);
Eina_Stringshare *str = eolian_typedecl_enum_field_c_name_get(efl);
eina_strbuf_append_char(wbuf, '.');
eina_strbuf_append(wbuf, str);
eina_stringshare_del(str);
eina_stringshare_del(bname);
return;
}
const Eolian_Class *cl = eolian_class_get_by_name(bname);
const Eolian_Function *fn = NULL;
Eolian_Function_Type ftype = EOLIAN_UNRESOLVED;
if (!cl)
{
const char *mname;
if (!strcmp(sfx, ".get")) ftype = EOLIAN_PROP_GET;
else if (!strcmp(sfx, ".set")) ftype = EOLIAN_PROP_SET;
if (ftype != EOLIAN_UNRESOLVED)
{
eina_stringshare_del(bname);
mname = sfx - 1;
while ((mname != refn) && (*mname != '.')) --mname;
if (mname == refn) goto noref;
bname = eina_stringshare_add_length(refn, mname - refn);
cl = eolian_class_get_by_name(bname);
eina_stringshare_del(bname);
}
if (cl)
{
char *meth = strndup(mname + 1, sfx - mname - 1);
fn = eolian_class_function_get_by_name(cl, meth, ftype);
if (ftype == EOLIAN_UNRESOLVED)
ftype = eolian_function_type_get(fn);
free(meth);
}
}
else
{
fn = eolian_class_function_get_by_name(cl, sfx + 1, ftype);
ftype = eolian_function_type_get(fn);
}
if (!fn) goto noref;
Eina_Stringshare *fcn = eolian_function_full_c_name_get(fn, ftype, use_legacy);
if (!fcn) goto noref;
eina_strbuf_append(wbuf, fcn);
eina_stringshare_del(fcn);
return;
noref:
eina_strbuf_append(wbuf, refn);
}
static int
_append_section(const char *desc, int ind, int curl, Eina_Strbuf *buf,
Eina_Strbuf *wbuf, Eina_Bool use_legacy)
{
Eina_Bool try_note = EINA_TRUE;
while (*desc)
{
eina_strbuf_reset(wbuf);
while (*desc && isspace(*desc) && (*desc != '\n'))
eina_strbuf_append_char(wbuf, *desc++);
if (try_note)
{
#define CHECK_NOTE(str) !strncmp(desc, str ": ", sizeof(str ":"))
if (CHECK_NOTE("Note"))
{
eina_strbuf_append(wbuf, "@note ");
desc += sizeof("Note:");
}
else if (CHECK_NOTE("Warning"))
{
eina_strbuf_append(wbuf, "@warning ");
desc += sizeof("Warning:");
}
else if (CHECK_NOTE("Remark"))
{
eina_strbuf_append(wbuf, "@remark ");
desc += sizeof("Remark:");
}
else if (CHECK_NOTE("TODO"))
{
eina_strbuf_append(wbuf, "@todo ");
desc += sizeof("TODO:");
}
#undef CHECK_NOTE
try_note = EINA_FALSE;
}
if (*desc == '\\')
{
desc++;
if ((*desc != '@') && (*desc != '$'))
eina_strbuf_append_char(wbuf, '\\');
eina_strbuf_append_char(wbuf, *desc++);
}
else if (*desc == '@')
{
const char *ref = ++desc;
if (isalpha(*desc) || (*desc == '_'))
{
eina_strbuf_append(wbuf, "@ref ");
while (isalnum(*desc) || (*desc == '.') || (*desc == '_'))
++desc;
if (*(desc - 1) == '.') --desc;
Eina_Stringshare *refn = eina_stringshare_add_length(ref, desc - ref);
_generate_ref(refn, wbuf, use_legacy);
eina_stringshare_del(refn);
}
else
eina_strbuf_append_char(wbuf, '@');
}
else if (*desc == '$')
{
desc++;
if (isalpha(*desc))
eina_strbuf_append(wbuf, "@c ");
else
eina_strbuf_append_char(wbuf, '$');
}
while (*desc && !isspace(*desc))
eina_strbuf_append_char(wbuf, *desc++);
int limit = DOC_LIMIT(ind);
int wlen = eina_strbuf_length_get(wbuf);
if ((int)(curl + wlen) > limit)
{
curl = 3;
eina_strbuf_append_char(buf, '\n');
curl += _indent_line(buf, ind);
eina_strbuf_append(buf, " * ");
if (*eina_strbuf_string_get(wbuf) == ' ')
eina_strbuf_remove(wbuf, 0, 1);
}
curl += eina_strbuf_length_get(wbuf);
eina_strbuf_append(buf, eina_strbuf_string_get(wbuf));
if (*desc == '\n')
{
desc++;
eina_strbuf_append_char(buf, '\n');
while (*desc == '\n')
{
_indent_line(buf, ind);
eina_strbuf_append(buf, " *\n");
desc++;
try_note = EINA_TRUE;
}
curl = _indent_line(buf, ind) + 3;
eina_strbuf_append(buf, " * ");
}
}
return curl;
}
static int
_append_since(const char *since, int indent, int curl, Eina_Strbuf *buf)
{
if (since)
{
eina_strbuf_append_char(buf, '\n');
_indent_line(buf, indent);
eina_strbuf_append(buf, " *\n");
curl = _indent_line(buf, indent);
eina_strbuf_append(buf, " * @since ");
eina_strbuf_append(buf, since);
curl += strlen(since) + sizeof(" * @since ") - 1;
}
return curl;
}
static int
_append_extra(const char *el, int indent, int curl, Eina_Bool nl, Eina_Strbuf *buf)
{
if (el)
{
eina_strbuf_append_char(buf, '\n');
if (nl)
{
_indent_line(buf, indent);
eina_strbuf_append(buf, " *\n");
}
curl = _indent_line(buf, indent);
eina_strbuf_append(buf, " * ");
eina_strbuf_append(buf, el);
curl += strlen(el) + sizeof(" * ") - 1;
}
return curl;
}
static char *
_sanitize_group(const char *group)
{
if (!group) return NULL;
char *ret = strdup(group);
char *p;
while ((p = strchr(ret, '.'))) *p = '_';
return ret;
}
static void
_append_group(Eina_Strbuf *buf, char *sgrp, int indent)
{
if (!sgrp) return;
eina_strbuf_append(buf, " * @ingroup ");
eina_strbuf_append(buf, sgrp);
eina_strbuf_append_char(buf, '\n');
_indent_line(buf, indent);
free(sgrp);
}
static void
_gen_doc_brief(const char *summary, const char *since, const char *group,
const char *el, int indent, Eina_Strbuf *buf,
Eina_Bool use_legacy)
{
int curl = 4 + indent;
Eina_Strbuf *wbuf = eina_strbuf_new();
if (indent)
eina_strbuf_append(buf, "/**< ");
else
eina_strbuf_append(buf, "/** ");
curl = _append_section(summary, indent, curl, buf, wbuf, use_legacy);
eina_strbuf_free(wbuf);
curl = _append_extra(el, indent, curl, EINA_FALSE, buf);
curl = _append_since(since, indent, curl, buf);
char *sgrp = _sanitize_group(group);
if (((curl + 3) > DOC_LIMIT(indent)) || sgrp)
{
eina_strbuf_append_char(buf, '\n');
_indent_line(buf, indent);
if (sgrp) eina_strbuf_append(buf, " *");
}
if (sgrp)
{
eina_strbuf_append_char(buf, '\n');
_indent_line(buf, indent);
}
_append_group(buf, sgrp, indent);
eina_strbuf_append(buf, " */");
}
static void
_gen_doc_full(const char *summary, const char *description, const char *since,
const char *group, const char *el, int indent, Eina_Strbuf *buf,
Eina_Bool use_legacy)
{
int curl = 0;
Eina_Strbuf *wbuf = eina_strbuf_new();
if (indent)
eina_strbuf_append(buf, "/**<\n");
else
eina_strbuf_append(buf, "/**\n");
curl += _indent_line(buf, indent);
eina_strbuf_append(buf, " * @brief ");
curl += sizeof(" * @brief ") - 1;
_append_section(summary, indent, curl, buf, wbuf, use_legacy);
eina_strbuf_append_char(buf, '\n');
_indent_line(buf, indent);
eina_strbuf_append(buf, " *\n");
curl = _indent_line(buf, indent);
eina_strbuf_append(buf, " * ");
_append_section(description, indent, curl + 3, buf, wbuf, use_legacy);
curl = _append_extra(el, indent, curl, EINA_TRUE, buf);
curl = _append_since(since, indent, curl, buf);
eina_strbuf_append_char(buf, '\n');
_indent_line(buf, indent);
char *sgrp = _sanitize_group(group);
if (sgrp)
{
eina_strbuf_append(buf, " *\n");
_indent_line(buf, indent);
}
_append_group(buf, sgrp, indent);
eina_strbuf_append(buf, " */");
eina_strbuf_free(wbuf);
}
static Eina_Strbuf *
_gen_doc_buf(const Eolian_Documentation *doc, const char *group,
const char *el, int indent, Eina_Bool use_legacy)
{
if (!doc) return NULL;
const char *sum = eolian_documentation_summary_get(doc);
const char *desc = eolian_documentation_description_get(doc);
const char *since = eolian_documentation_since_get(doc);
Eina_Strbuf *buf = eina_strbuf_new();
if (!desc)
_gen_doc_brief(sum, since, group, el, indent, buf, use_legacy);
else
_gen_doc_full(sum, desc, since, group, el, indent, buf, use_legacy);
return buf;
}
Eina_Strbuf *
docs_generate_full(const Eolian_Documentation *doc, const char *group,
int indent, Eina_Bool use_legacy)
{
return _gen_doc_buf(doc, group, NULL, indent, use_legacy);
}
Eina_Strbuf *
docs_generate_event(const Eolian_Event *ev, const char *group)
{
if (!ev) return NULL;
const Eolian_Documentation *doc = eolian_event_documentation_get(ev);
char buf[1024];
const Eolian_Type *rt = eolian_event_type_get(ev);
const char *p = NULL;
if (rt)
{
p = buf;
Eina_Stringshare *rts = eolian_type_c_type_get(rt);
snprintf(buf, sizeof(buf), "@return %s", rts);
eina_stringshare_del(rts);
}
if (!doc)
{
Eina_Strbuf *bufs = eina_strbuf_new();
eina_strbuf_append(bufs, "/**\n * No description\n");
if (p)
{
eina_strbuf_append(bufs, " * ");
eina_strbuf_append(bufs, p);
eina_strbuf_append_char(bufs, '\n');
}
eina_strbuf_append(bufs, " */");
return bufs;
}
return _gen_doc_buf(doc, group, p, 0, EINA_FALSE);
}
Eina_Strbuf *
docs_generate_function(const Eolian_Function *fid, Eolian_Function_Type ftype,
int indent, Eina_Bool use_legacy)
{
const Eolian_Function_Parameter *par = NULL;
const Eolian_Function_Parameter *vpar = NULL;
const Eolian_Documentation *doc, *pdoc, *rdoc;
Eina_Iterator *itr = NULL;
Eina_Iterator *vitr = NULL;
Eina_Bool force_out = EINA_FALSE;
Eina_Strbuf *buf = eina_strbuf_new();
Eina_Strbuf *wbuf = NULL;
const char *sum = NULL, *desc = NULL, *since = NULL;
int curl = 0;
const char *group = eolian_class_full_name_get(eolian_function_class_get(fid));
if (ftype == EOLIAN_UNRESOLVED)
ftype = EOLIAN_METHOD;
if (ftype == EOLIAN_METHOD)
{
doc = eolian_function_documentation_get(fid, EOLIAN_METHOD);
pdoc = NULL;
}
else
{
doc = eolian_function_documentation_get(fid, EOLIAN_PROPERTY);
pdoc = eolian_function_documentation_get(fid, ftype);
if (!doc && pdoc) doc = pdoc;
if (pdoc == doc) pdoc = NULL;
}
rdoc = eolian_function_return_documentation_get(fid, ftype);
if (doc)
{
sum = eolian_documentation_summary_get(doc);
desc = eolian_documentation_description_get(doc);
since = eolian_documentation_since_get(doc);
if (pdoc && eolian_documentation_since_get(pdoc))
since = eolian_documentation_since_get(pdoc);
}
if (ftype == EOLIAN_METHOD)
{
itr = eolian_function_parameters_get(fid);
}
else
{
itr = eolian_property_keys_get(fid, ftype);
vitr = eolian_property_values_get(fid, ftype);
if (!vitr || !eina_iterator_next(vitr, (void**)&vpar))
{
eina_iterator_free(vitr);
vitr = NULL;
}
}
if (!itr || !eina_iterator_next(itr, (void**)&par))
{
eina_iterator_free(itr);
itr = NULL;
}
/* when return is not set on getter, value becomes return instead of param */
if (ftype == EOLIAN_PROP_GET && !eolian_function_return_type_get(fid, ftype))
{
const Eolian_Function_Parameter *rvpar = vpar;
if (!eina_iterator_next(vitr, (void**)&vpar))
{
/* one value - not out param */
eina_iterator_free(vitr);
rdoc = rvpar ? eolian_parameter_documentation_get(rvpar) : NULL;
vitr = NULL;
vpar = NULL;
}
else
{
/* multiple values - always out params */
eina_iterator_free(vitr);
vitr = eolian_property_values_get(fid, ftype);
if (!vitr)
vpar = NULL;
else if (!eina_iterator_next(vitr, (void**)&vpar))
{
eina_iterator_free(vitr);
vitr = NULL;
vpar = NULL;
}
}
}
if (!par)
{
/* no keys, try values */
itr = vitr;
par = vpar;
vitr = NULL;
vpar = NULL;
if (ftype == EOLIAN_PROP_GET)
force_out = EINA_TRUE;
}
/* only summary, nothing else; generate standard brief doc */
if (!desc && !par && !vpar && !rdoc && (ftype == EOLIAN_METHOD || !pdoc))
{
_gen_doc_brief(sum ? sum : "No description supplied.", since, group,
NULL, indent, buf, use_legacy);
return buf;
}
wbuf = eina_strbuf_new();
eina_strbuf_append(buf, "/**\n");
curl += _indent_line(buf, indent);
eina_strbuf_append(buf, " * @brief ");
curl += sizeof(" * @brief ") - 1;
_append_section(sum ? sum : "No description supplied.",
indent, curl, buf, wbuf, use_legacy);
eina_strbuf_append_char(buf, '\n');
if (desc || since || par || rdoc || pdoc)
{
_indent_line(buf, indent);
eina_strbuf_append(buf, " *\n");
}
if (desc)
{
curl = _indent_line(buf, indent);
eina_strbuf_append(buf, " * ");
_append_section(desc, indent, curl + 3, buf, wbuf, use_legacy);
eina_strbuf_append_char(buf, '\n');
if (par || rdoc || pdoc || since)
{
_indent_line(buf, indent);
eina_strbuf_append(buf, " *\n");
}
}
if (pdoc)
{
const char *pdesc = eolian_documentation_description_get(pdoc);
curl = _indent_line(buf, indent);
eina_strbuf_append(buf, " * ");
_append_section(eolian_documentation_summary_get(pdoc), indent,
curl + 3, buf, wbuf, use_legacy);
eina_strbuf_append_char(buf, '\n');
if (pdesc)
{
_indent_line(buf, indent);
eina_strbuf_append(buf, " *\n");
curl = _indent_line(buf, indent);
eina_strbuf_append(buf, " * ");
_append_section(pdesc, indent, curl + 3, buf, wbuf, use_legacy);
eina_strbuf_append_char(buf, '\n');
}
if (par || rdoc || since)
{
_indent_line(buf, indent);
eina_strbuf_append(buf, " *\n");
}
}
while (par)
{
const Eolian_Documentation *adoc = eolian_parameter_documentation_get(par);
curl = _indent_line(buf, indent);
Eolian_Parameter_Dir dir = EOLIAN_OUT_PARAM;
if (!force_out)
dir = eolian_parameter_direction_get(par);
switch (dir)
{
case EOLIAN_IN_PARAM:
eina_strbuf_append(buf, " * @param[in] ");
curl += sizeof(" * @param[in] ") - 1;
break;
case EOLIAN_OUT_PARAM:
eina_strbuf_append(buf, " * @param[out] ");
curl += sizeof(" * @param[out] ") - 1;
break;
case EOLIAN_INOUT_PARAM:
eina_strbuf_append(buf, " * @param[in,out] ");
curl += sizeof(" * @param[in,out] ") - 1;
break;
}
const char *nm = eolian_parameter_name_get(par);
eina_strbuf_append(buf, nm);
curl += strlen(nm);
if (adoc)
{
eina_strbuf_append_char(buf, ' ');
curl += 1;
_append_section(eolian_documentation_summary_get(adoc),
indent, curl, buf, wbuf, use_legacy);
}
eina_strbuf_append_char(buf, '\n');
if (!eina_iterator_next(itr, (void**)&par))
{
par = NULL;
if (vpar)
{
eina_iterator_free(itr);
itr = vitr;
par = vpar;
vitr = NULL;
vpar = NULL;
if (ftype == EOLIAN_PROP_GET)
force_out = EINA_TRUE;
}
}
if (!par && (rdoc || since))
{
_indent_line(buf, indent);
eina_strbuf_append(buf, " *\n");
}
}
eina_iterator_free(itr);
if (rdoc)
{
curl = _indent_line(buf, indent);
eina_strbuf_append(buf, " * @return ");
curl += sizeof(" * @return ") - 1;
_append_section(eolian_documentation_summary_get(rdoc), indent, curl,
buf, wbuf, use_legacy);
eina_strbuf_append_char(buf, '\n');
if (since)
{
_indent_line(buf, indent);
eina_strbuf_append(buf, " *\n");
}
}
if (since)
{
curl = _indent_line(buf, indent);
eina_strbuf_append(buf, " * @since ");
eina_strbuf_append(buf, since);
eina_strbuf_append_char(buf, '\n');
}
_indent_line(buf, indent);
eina_strbuf_append(buf, " *\n");
_indent_line(buf, indent);
_append_group(buf, _sanitize_group(group), indent);
eina_strbuf_append(buf, " */");
eina_strbuf_free(wbuf);
return buf;
}

View File

@ -1,45 +0,0 @@
#ifndef DOCS_GENERATOR_H
#define DOCS_GENERATOR_H
#include <Eina.h>
#include <Eolian.h>
/*
* @brief Generate standard documentation
*
* @param[in] doc the documentation
* @param[in] group the group to use (can be NULL)
* @param[in] indent by how many spaces to indent the comment from second line
* @param[in] use_legacy whether to use legacy names
*
* @return A documentation comment
*
*/
Eina_Strbuf *docs_generate_full(const Eolian_Documentation *doc, const char *group, int indent, Eina_Bool use_legacy);
/*
* @brief Generate function documentation
*
* @param[in] fid te function
* @param[in] type the function type (either METHOD, PROP_GET, PROP_SET)
* @param[in] indent by how many spaces to indent the comment from second line
* @param[in] use_legacy whether to use legacy names
*
* @return A documentation comment
*
*/
Eina_Strbuf *docs_generate_function(const Eolian_Function *fid, Eolian_Function_Type ftype, int indent, Eina_Bool use_legacy);
/*
* @brief Generate event documentation
*
* @param[in] ev the event
* @param[in] group the group to use (can be NULL);
*
* @return A documentation comment
*
*/
Eina_Strbuf *docs_generate_event(const Eolian_Event *ev, const char *group);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,34 +0,0 @@
#ifndef EO1_GENERATOR_H
#define EO1_GENERATOR_H
#include<Eina.h>
/*
* @brief Generate Eo source code for Eo class
*
* This function generates all the source code for Eo.
*
* @param[in] classname class name
* @param[inout] buf buffer to fill
*
* @return EINA_TRUE on success, EINA_FALSE on error.
*
*/
Eina_Bool
eo_source_generate(const Eolian_Class *class, Eina_Strbuf *buf);
/*
* @brief Generate the header code for a specific Eo class.
*
* This function generates header code from scratch.
*
* @param[in] classname class name
* @param[inout] buf buffer to fill
*
* @return EINA_TRUE on success, EINA_FALSE on error.
*
*/
Eina_Bool eo_header_generate(const Eolian_Class *class, Eina_Strbuf *buf);
#endif

View File

@ -1,324 +0,0 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Eina.h>
#include <string.h>
#include "Eolian.h"
#include "impl_generator.h"
#include "common_funcs.h"
static _eolian_class_vars class_env;
static Eina_Bool
_params_generate(const Eolian_Function *foo, Eolian_Function_Type ftype, Eina_Bool var_as_ret, Eina_Strbuf *params, Eina_Strbuf *short_params)
{
Eina_Iterator *itr;
Eolian_Function_Parameter *param;
Eina_Bool is_prop = (ftype == EOLIAN_PROP_GET || ftype == EOLIAN_PROP_SET);
eina_strbuf_reset(params);
eina_strbuf_reset(short_params);
itr = eolian_property_keys_get(foo, ftype);
EINA_ITERATOR_FOREACH(itr, param)
{
const Eolian_Type *ptypet = eolian_parameter_type_get(param);
const char *pname = eolian_parameter_name_get(param);
const char *ptype = eolian_type_c_type_get(ptypet);
Eina_Bool had_star = !!strchr(ptype, '*');
if (eina_strbuf_length_get(params))
{
eina_strbuf_append(params, ", ");
eina_strbuf_append(short_params, ", ");
}
eina_strbuf_append_printf(params, "%s%s%s",
ptype, had_star?"":" ", pname);
eina_strbuf_append_printf(short_params, "%s", pname);
eina_stringshare_del(ptype);
}
eina_iterator_free(itr);
if (!var_as_ret)
{
itr = is_prop ? eolian_property_values_get(foo, ftype) : eolian_function_parameters_get(foo);
EINA_ITERATOR_FOREACH(itr, param)
{
const Eolian_Type *ptypet = eolian_parameter_type_get(param);
const char *pname = eolian_parameter_name_get(param);
const char *ptype = eolian_type_c_type_get(ptypet);
Eolian_Parameter_Dir pdir = eolian_parameter_direction_get(param);
const char *add_star = _get_add_star(ftype, pdir);
Eina_Bool had_star = !!strchr(ptype, '*');
if (eina_strbuf_length_get(params))
{
eina_strbuf_append(params, ", ");
eina_strbuf_append(short_params, ", ");
}
eina_strbuf_append_printf(params, "%s%s%s%s",
ptype, had_star?"":" ", add_star, pname);
eina_strbuf_append_printf(short_params, "%s", pname);
eina_stringshare_del(ptype);
}
eina_iterator_free(itr);
}
return EINA_TRUE;
}
static Eina_Bool
_function_exists(const char* func_name, Eina_Strbuf *buffer)
{
const char *ptr = eina_strbuf_string_get(buffer);
int func_len = strlen(func_name);
while ((ptr = strstr(ptr, func_name)) != NULL)
{
switch (*(ptr - 1))
{
case '\n': case ' ':
{
switch (*(ptr + func_len))
{
case ' ': case '(':
return EINA_TRUE;
}
}
}
ptr++; /* so strstr doesn't fall again on func_name */
}
return EINA_FALSE;
}
/* Check if the type is used in the file, not if it is a typedef... */
static Eina_Bool
_type_exists(const char* type_name, Eina_Strbuf *buffer)
{
const char *ptr = eina_strbuf_string_get(buffer);
int type_len = strlen(type_name);
while ((ptr = strstr(ptr, type_name)) != NULL)
{
switch (*(ptr - 1))
{
case '\n': case ' ': case ',':
{
switch (*(ptr + type_len))
{
case '\n': case ' ': case ',': case ';':
return EINA_TRUE;
}
}
}
ptr++; /* so strstr doesn't fall again on type_name */
}
return EINA_FALSE;
}
static Eina_Bool
_prototype_generate(const Eolian_Function *foo, Eolian_Function_Type ftype, Eina_Strbuf *data_type_buf, Eolian_Implement *impl_desc, Eina_Strbuf *buffer)
{
Eina_Bool var_as_ret = EINA_FALSE;
Eina_Strbuf *params = NULL, *short_params = NULL, *super_invok = NULL;
char func_name[PATH_MAX];
char impl_name[PATH_MAX];
const char *fname;
size_t flen;
_eolian_class_vars impl_env;
if (!impl_desc && eolian_function_is_virtual_pure(foo, ftype)) return EINA_TRUE;
super_invok = eina_strbuf_new();
if (impl_desc)
{
_class_env_create(eolian_implement_class_get(impl_desc), NULL, &impl_env);
char *tmp = impl_name;
sprintf(impl_name, "%s_%s", class_env.full_classname, impl_env.full_classname);
eina_str_tolower(&tmp);
}
sprintf(func_name, "_%s_%s%s",
impl_desc?impl_name:class_env.lower_classname, eolian_function_name_get(foo),
ftype == EOLIAN_PROP_GET?"_get": (ftype == EOLIAN_PROP_SET?"_set":""));
if (_function_exists(func_name, buffer)) goto end;
printf("Generation of function %s\n", func_name);
const Eolian_Type *rettypet = eolian_function_return_type_get(foo, ftype);
if (ftype == EOLIAN_PROP_GET && !rettypet)
{
Eina_Iterator *itr = eolian_property_values_get(foo, ftype);
void *data, *data2;
/* We want to check if there is only one parameter */
if (eina_iterator_next(itr, &data) && !eina_iterator_next(itr, &data2))
{
Eolian_Function_Parameter *param = data;
rettypet = eolian_parameter_type_get(param);
var_as_ret = EINA_TRUE;
}
eina_iterator_free(itr);
}
params = eina_strbuf_new();
short_params = eina_strbuf_new();
_params_generate(foo, ftype, var_as_ret, params, short_params);
if (eina_strbuf_length_get(params))
eina_strbuf_prepend_printf(params, ", ");
if (eina_strbuf_length_get(short_params))
eina_strbuf_prepend_printf(short_params, ", ");
fname = eolian_function_name_get(foo);
if (fname)
{
flen = strlen(fname);
if (flen >= strlen("destructor"))
{
if (impl_desc &&
(!strcmp(fname + flen - strlen("destructor"), "destructor")))
{
eina_strbuf_append_printf
(super_invok,
" %s_%s(efl_super(obj, %s_%s)%s);\n",
impl_env.lower_eo_prefix, eolian_function_name_get(foo),
class_env.upper_eo_prefix, class_env.upper_classtype,
eina_strbuf_string_get(short_params));
}
}
}
const char *rettype = NULL;
if (rettypet) rettype = eolian_type_c_type_get(rettypet);
eina_strbuf_append_printf(buffer,
"EOLIAN static %s\n%s(%sEo *obj, %s *pd%s%s)\n{\n%s\n}\n\n",
!rettype?"void":rettype,
func_name,
eolian_function_object_is_const(foo)?"const ":"",
!eina_strbuf_length_get(data_type_buf) ? "void" : eina_strbuf_string_get(data_type_buf),
!eina_strbuf_length_get(data_type_buf) ? " EINA_UNUSED" : "",
eina_strbuf_string_get(params),
eina_strbuf_string_get(super_invok)
);
if (rettype) eina_stringshare_del(rettype);
end:
eina_strbuf_free(short_params);
eina_strbuf_free(params);
eina_strbuf_free(super_invok);
return EINA_TRUE;
}
Eina_Bool
impl_source_generate(const Eolian_Class *class, Eina_Strbuf *buffer)
{
Eina_Bool ret = EINA_FALSE;
Eina_Strbuf *data_type_buf = eina_strbuf_new();
Eina_Iterator *itr;
const Eolian_Function *foo;
Eina_Strbuf *begin = eina_strbuf_new();
char core_incl[PATH_MAX];
_class_env_create(class, NULL, &class_env);
if (!_type_exists("EFL_BETA_API_SUPPORT", buffer))
{
printf("Generation of EFL_BETA_API_SUPPORT\n");
eina_strbuf_append_printf(begin, "#define EFL_BETA_API_SUPPORT\n");
}
if (!_type_exists("<Eo.h>", buffer))
{
printf("Generation of #include <Eo.h> and \"%s.eo.h\"\n", class_env.lower_classname);
eina_strbuf_append_printf(begin, "#include <Eo.h>\n#include \"%s.eo.h\"\n\n", class_env.lower_classname);
}
/* Little calculation of the prefix of the data */
const char *data_type = eolian_class_data_type_get(class);
if (data_type)
{
if (strcmp(data_type, "null"))
eina_strbuf_append_printf(data_type_buf, "%s", data_type);
}
else
eina_strbuf_append_printf(data_type_buf, "%s_Data", class_env.full_classname);
/* Definition of the structure */
const char *data_type_str = eina_strbuf_string_get(data_type_buf);
if (!_type_exists(data_type_str, buffer) && 0 != eina_strbuf_length_get(data_type_buf))
{
printf("Generation of type %s\n", data_type_str);
eina_strbuf_append_printf(begin, "typedef struct\n{\n\n} %s;\n\n", data_type_str);
}
if (eina_strbuf_length_get(begin))
eina_strbuf_prepend_printf(buffer, "%s", eina_strbuf_string_get(begin));
eina_strbuf_free(begin);
itr = eolian_class_implements_get(class);
if (itr)
{
Eolian_Implement *impl_desc;
const char *names[] = { "", "getter ", "setter " };
EINA_ITERATOR_FOREACH(itr, impl_desc)
{
Eolian_Function_Type ftype;
Eolian_Implement *idesc = (eolian_implement_class_get(impl_desc) == class) ? NULL : impl_desc;
if (!(foo = eolian_implement_function_get(impl_desc, &ftype)))
{
const char *name = names[eolian_implement_is_prop_get(impl_desc)
| (eolian_implement_is_prop_set(impl_desc) << 1)];
fprintf(stderr, "eolian: failed to generate implementation of '%s%s' - missing from class\n",
name, eolian_implement_full_name_get(impl_desc));
goto end;
}
switch (ftype)
{
case EOLIAN_PROP_SET: case EOLIAN_PROP_GET:
_prototype_generate(foo, ftype, data_type_buf, idesc, buffer);
break;
case EOLIAN_PROPERTY:
_prototype_generate(foo, EOLIAN_PROP_SET, data_type_buf, idesc, buffer);
_prototype_generate(foo, EOLIAN_PROP_GET, data_type_buf, idesc, buffer);
break;
default:
_prototype_generate(foo, eolian_function_type_get(foo), data_type_buf, idesc, buffer);
break;
}
}
eina_iterator_free(itr);
}
if (eolian_class_ctor_enable_get(class))
{
char func_name[100];
sprintf(func_name, "_%s_class_constructor", class_env.lower_classname);
if (!_function_exists(func_name, buffer))
{
printf("Generation of function %s\n", func_name);
eina_strbuf_append_printf(buffer,
"EOLIAN static void\n_%s_class_constructor(Efl_Class *klass)\n{\n\n}\n\n",
class_env.lower_classname);
}
}
if (eolian_class_dtor_enable_get(class))
{
char func_name[100];
sprintf(func_name, "_%s_class_destructor", class_env.lower_classname);
if (!_function_exists(func_name, buffer))
{
printf("Generation of function %s\n", func_name);
eina_strbuf_append_printf(buffer, "EOLIAN static void\n_%s_class_destructor(Efl_Class *klass)\n{\n\n}\n\n",
class_env.lower_classname);
}
}
printf("Removal of all inline instances of #include \"%s.eo.c\"\n", class_env.lower_classname);
snprintf(core_incl, sizeof(core_incl), "\n#include \"%s.eo.c\"\n", class_env.lower_classname);
eina_strbuf_replace_all(buffer, core_incl, "\n");
snprintf(core_incl, sizeof(core_incl), "\"%s.eo.c\"", class_env.lower_classname);
printf("Generation of #include \"%s.eo.c\"\n", class_env.lower_classname);
eina_strbuf_append_printf(buffer, "#include \"%s.eo.c\"\n", class_env.lower_classname);
ret = EINA_TRUE;
end:
eina_strbuf_free(data_type_buf);
return ret;
}

View File

@ -1,22 +0,0 @@
#ifndef IMPL_GENERATOR_H
#define IMPL_GENERATOR_H
#include<Eina.h>
/*
* @brief Generate the implementation source code of a class
*
* This function generates all the source code of a class.
*
* @param[in] classname class name
* @param[inout] buf buffer to fill
*
* @return EINA_TRUE on success, EINA_FALSE on error.
*
*/
Eina_Bool
impl_source_generate(const Eolian_Class *class, Eina_Strbuf *buf);
#endif

View File

@ -1,416 +0,0 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Eina.h>
#include <string.h>
#include "Eolian.h"
#include "legacy_generator.h"
#include "docs_generator.h"
#include "common_funcs.h"
static _eolian_class_vars class_env;
static const char
tmpl_eapi_funcdef[] = "EAPI @#type_return%s(@#params)@#flags;\n";
/*@#CLASS_CHECK(obj) @#check_ret;\n\*/
static const char
tmpl_eapi_body[] ="\
\n\
EAPI @#ret_type\n\
@#eapi_func(@#full_params)\n\
{\n\
return @#eo_func(@#eo_obj@#eo_params);\n\
}\n\
";
static const char
tmpl_eapi_body_void[] ="\
\n\
EAPI void\n\
@#eapi_func(@#full_params)\n\
{\n\
@#eo_func(@#eo_obj@#eo_params);\n\
}\n\
";
static void
_eapi_decl_func_generate(const Eolian_Class *class, const Eolian_Function *funcid, Eolian_Function_Type ftype, Eina_Strbuf *buf)
{
_eolian_class_func_vars func_env;
const char *funcname = eolian_function_name_get(funcid);
const Eolian_Type *rettypet = NULL;
const char *rettype = NULL;
Eina_Bool var_as_ret = EINA_FALSE;
Eina_Bool is_prop = (ftype == EOLIAN_PROP_GET || ftype == EOLIAN_PROP_SET);
Eina_Iterator *itr;
void *data, *data2;
Eina_Strbuf *flags = NULL;
int leg_param_idx = 1; /* Index of the parameter inside the legacy function. It begins from 1 since obj is the first. */
Eina_Strbuf *fbody = eina_strbuf_new();
Eina_Strbuf *fparam = eina_strbuf_new();
_class_func_env_create(class, funcname, ftype, &func_env);
rettypet = eolian_function_return_type_get(funcid, ftype);
if (ftype == EOLIAN_PROP_GET)
{
if (!rettypet)
{
itr = eolian_property_values_get(funcid, ftype);
/* We want to check if there is only one parameter */
if (eina_iterator_next(itr, &data) && !eina_iterator_next(itr, &data2))
{
rettypet = eolian_parameter_type_get((Eolian_Function_Parameter*)data);
var_as_ret = EINA_TRUE;
}
eina_iterator_free(itr);
}
}
if (func_env.legacy_func[0] == '\0') goto end;
Eina_Bool hasnewdocs = eolian_function_documentation_get(funcid, EOLIAN_UNRESOLVED) ||
eolian_function_documentation_get(funcid, ftype);
if (hasnewdocs)
{
Eina_Strbuf *dbuf = docs_generate_function(funcid, ftype, 0, EINA_TRUE);
eina_strbuf_append_char(fbody, '\n');
eina_strbuf_append(fbody, eina_strbuf_string_get(dbuf));
eina_strbuf_append_char(fbody, '\n');
eina_strbuf_free(dbuf);
}
eina_strbuf_append_printf(fbody, tmpl_eapi_funcdef, func_env.legacy_func);
if (!eolian_function_is_class(funcid))
{
if (ftype == EOLIAN_PROP_GET || eolian_function_object_is_const(funcid))
eina_strbuf_append(fparam, "const ");
eina_strbuf_append_printf(fparam, "%s *obj", class_env.full_classname);
}
itr = eolian_property_keys_get(funcid, ftype);
EINA_ITERATOR_FOREACH(itr, data)
{
Eolian_Function_Parameter *param = data;
const Eolian_Type *ptypet = eolian_parameter_type_get(param);
const char *pname = eolian_parameter_name_get(param);
const char *ptype = eolian_type_c_type_get(ptypet);
leg_param_idx++;
if (eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, ", ");
eina_strbuf_append_printf(fparam, "%s %s", ptype, pname);
eina_stringshare_del(ptype);
if (eolian_parameter_is_nonull((Eolian_Function_Parameter*)data))
{
if (!flags)
{
flags = eina_strbuf_new();
eina_strbuf_append_printf(flags, " EINA_ARG_NONNULL(%d", leg_param_idx);
}
else
eina_strbuf_append_printf(flags, ", %d", leg_param_idx);
}
}
eina_iterator_free(itr);
if (!var_as_ret)
{
itr = is_prop ? eolian_property_values_get(funcid, ftype) : eolian_function_parameters_get(funcid);
EINA_ITERATOR_FOREACH(itr, data)
{
Eolian_Function_Parameter *param = data;
const Eolian_Type *ptypet = eolian_parameter_type_get(param);
const char *pname = eolian_parameter_name_get(param);
const char *ptype = eolian_type_c_type_get(ptypet);
Eolian_Parameter_Dir pdir = eolian_parameter_direction_get(param);
Eina_Bool had_star = !!strchr(ptype, '*');
leg_param_idx++;
if (eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, ", ");
eina_strbuf_append_printf(fparam, "%s%s%s%s",
ptype, had_star?"":" ", _get_add_star(ftype, pdir), pname);
eina_stringshare_del(ptype);
if (eolian_parameter_is_nonull((Eolian_Function_Parameter*)data))
{
if (!flags)
{
flags = eina_strbuf_new();
eina_strbuf_append_printf(flags, " EINA_ARG_NONNULL(%d", leg_param_idx);
}
else
eina_strbuf_append_printf(flags, ", %d", leg_param_idx);
}
}
eina_iterator_free(itr);
}
if (!eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, "void");
if (flags) eina_strbuf_append_printf(flags, ")");
if (rettypet) rettype = eolian_type_c_type_get(rettypet);
eina_strbuf_replace_all(fbody, "@#params", eina_strbuf_string_get(fparam));
eina_strbuf_reset(fparam);
eina_strbuf_append_printf(fparam, "%s%s",
rettype ? rettype : "void",
rettype && strchr(rettype, '*')?"":" ");
eina_strbuf_replace_all(fbody, "@#type_return", eina_strbuf_string_get(fparam));
if (eolian_function_return_is_warn_unused(funcid, ftype))
{
Eina_Bool no_nonull = !flags;
if (no_nonull) flags = eina_strbuf_new();
eina_strbuf_prepend(flags, " EINA_WARN_UNUSED_RESULT");
}
if (flags)
eina_strbuf_replace_all(fbody, "@#flags", eina_strbuf_string_get(flags));
eina_strbuf_replace_all(fbody, "@#flags", (eolian_function_return_is_warn_unused(funcid, ftype)) ? " EINA_WARN_UNUSED_RESULT" : "");
eina_strbuf_append(buf, eina_strbuf_string_get(fbody));
if (rettype) eina_stringshare_del(rettype);
end:
eina_strbuf_free(flags);
eina_strbuf_free(fbody);
eina_strbuf_free(fparam);
}
static void
_eapi_func_generate(const Eolian_Class *class, const Eolian_Function *funcid, Eolian_Function_Type ftype, Eina_Strbuf *buf)
{
_eolian_class_func_vars func_env;
char tmpstr[0xFF];
Eina_Bool var_as_ret = EINA_FALSE;
const Eolian_Type *rettypet = NULL;
const char *rettype = NULL;
const char *retname = NULL;
Eina_Bool ret_is_void = EINA_FALSE;
Eina_Bool is_prop = (ftype == EOLIAN_PROP_GET || ftype == EOLIAN_PROP_SET);
Eina_Strbuf *fbody = eina_strbuf_new();
Eina_Strbuf *fparam = eina_strbuf_new();
Eina_Strbuf *eoparam = eina_strbuf_new();
Eina_Iterator *itr;
void *data, *data2;
_class_func_env_create(class, eolian_function_name_get(funcid), ftype, &func_env);
rettypet = eolian_function_return_type_get(funcid, ftype);
if (rettypet) rettype = eolian_type_c_type_get(rettypet);
if (rettype && !strcmp(rettype, "void")) ret_is_void = EINA_TRUE;
retname = "ret";
if (ftype == EOLIAN_PROP_GET)
{
if (!rettypet)
{
itr = eolian_property_values_get(funcid, ftype);
/* We want to check if there is only one parameter */
if (eina_iterator_next(itr, &data) && !eina_iterator_next(itr, &data2))
{
Eolian_Function_Parameter *param = data;
rettypet = eolian_parameter_type_get(param);
retname = eolian_parameter_name_get(param);
var_as_ret = EINA_TRUE;
}
eina_iterator_free(itr);
}
}
if (func_env.legacy_func[0] == '\0') goto end;
if (!rettype && rettypet) rettype = eolian_type_c_type_get(rettypet);
if (rettype && (!ret_is_void))
eina_strbuf_append(fbody, tmpl_eapi_body);
else
eina_strbuf_append(fbody, tmpl_eapi_body_void);
if (!eolian_function_is_class(funcid))
{
if (ftype == EOLIAN_PROP_GET || eolian_function_object_is_const(funcid))
eina_strbuf_append(fparam, "const ");
eina_strbuf_append_printf(fparam, "%s *obj", class_env.full_classname);
char cbuf[256];
snprintf(cbuf, sizeof(cbuf), "(%s *)obj", class_env.full_classname);
eina_strbuf_replace_all(fbody, "@#eo_obj", cbuf);
}
else
{
Eina_Strbuf *class_buf = eina_strbuf_new();
_template_fill(class_buf, "@#CLASS_@#CLASSTYPE", class, NULL, NULL, EINA_TRUE);
eina_strbuf_replace_all(fbody, "@#eo_obj", eina_strbuf_string_get(class_buf));
eina_strbuf_free(class_buf);
}
eina_strbuf_replace_all(fbody, "@#eapi_func", func_env.legacy_func);
eina_strbuf_replace_all(fbody, "@#eo_func", func_env.lower_eo_func);
tmpstr[0] = '\0';
itr = eolian_property_keys_get(funcid, ftype);
EINA_ITERATOR_FOREACH(itr, data)
{
Eolian_Function_Parameter *param = data;
const Eolian_Type *ptypet = eolian_parameter_type_get(param);
const char *pname = eolian_parameter_name_get(param);
const char *ptype = eolian_type_c_type_get(ptypet);
if (eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, ", ");
eina_strbuf_append_printf(fparam, "%s %s", ptype, pname);
eina_stringshare_del(ptype);
eina_strbuf_append_printf(eoparam, ", %s", pname);
}
eina_iterator_free(itr);
if (!var_as_ret)
{
itr = is_prop ? eolian_property_values_get(funcid, ftype) : eolian_function_parameters_get(funcid);
EINA_ITERATOR_FOREACH(itr, data)
{
Eolian_Function_Parameter *param = data;
const Eolian_Type *ptypet = eolian_parameter_type_get(param);
const char *pname = eolian_parameter_name_get(param);
const char *ptype = eolian_type_c_type_get(ptypet);
Eolian_Parameter_Dir pdir = eolian_parameter_direction_get(param);
Eina_Bool had_star = !!strchr(ptype, '*');
if (eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, ", ");
eina_strbuf_append_printf(fparam, "%s%s%s%s",
ptype, had_star?"":" ", _get_add_star(ftype, pdir), pname);
eina_stringshare_del(ptype);
eina_strbuf_append_printf(eoparam, ", %s", pname);
}
eina_iterator_free(itr);
}
if (!eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, "void");
if (rettype && (!ret_is_void))
{
char tmp_ret_str[0xFF];
sprintf (tmp_ret_str, "%s", rettype);
const Eolian_Expression *default_ret_val =
eolian_function_return_default_value_get(funcid, ftype);
const char *val_str = NULL;
if (default_ret_val)
{
Eolian_Value val = eolian_expression_eval_type
(default_ret_val, rettypet);
if (val.type)
val_str = eolian_expression_value_to_literal(&val);
}
Eina_Bool had_star = !!strchr(rettype, '*');
sprintf (tmpstr, " %s%s%s = %s;\n",
rettype, had_star?"":" ", retname,
val_str?val_str:"0");
eina_strbuf_replace_all(fbody, "@#ret_type", tmp_ret_str);
eina_strbuf_replace_all(fbody, "@#ret_init_val", tmpstr);
}
eina_strbuf_replace_all(fbody, "@#full_params", eina_strbuf_string_get(fparam));
eina_strbuf_replace_all(fbody, "@#eo_params", eina_strbuf_string_get(eoparam));
eina_strbuf_replace_all(fbody, "@#ret_val", (rettype && !ret_is_void) ? retname : "");
eina_strbuf_append(buf, eina_strbuf_string_get(fbody));
if (rettype) eina_stringshare_del(rettype);
end:
eina_strbuf_free(fbody);
eina_strbuf_free(fparam);
eina_strbuf_free(eoparam);
}
Eina_Bool
legacy_header_generate(const Eolian_Class *class, Eina_Strbuf *buf)
{
_class_env_create(class, NULL, &class_env);
const Eolian_Documentation *doc = eolian_class_documentation_get(class);
if (doc)
{
Eina_Strbuf *cdoc = docs_generate_full(doc, eolian_class_full_name_get(class), 0, EINA_TRUE);
if (cdoc)
{
eina_strbuf_append(buf, eina_strbuf_string_get(cdoc));
eina_strbuf_append_char(buf, '\n');
eina_strbuf_free(cdoc);
}
}
Eina_Iterator *itr = eolian_class_implements_get(class);
if (itr)
{
const Eolian_Implement *impl;
EINA_ITERATOR_FOREACH(itr, impl)
{
if (eolian_implement_class_get(impl) != class)
continue;
Eolian_Function_Type ftype = EOLIAN_UNRESOLVED;
const Eolian_Function *fid = eolian_implement_function_get(impl, &ftype);
if (eolian_function_is_beta(fid))
continue;
switch (ftype)
{
case EOLIAN_PROP_GET: case EOLIAN_PROP_SET:
_eapi_decl_func_generate(class, fid, ftype, buf);
break;
case EOLIAN_PROPERTY:
_eapi_decl_func_generate(class, fid, EOLIAN_PROP_SET, buf);
_eapi_decl_func_generate(class, fid, EOLIAN_PROP_GET, buf);
break;
default:
_eapi_decl_func_generate(class, fid, EOLIAN_METHOD, buf);
break;
}
}
eina_iterator_free(itr);
}
return EINA_TRUE;
}
Eina_Bool
legacy_source_generate(const Eolian_Class *class, Eina_Strbuf *buf)
{
Eina_Bool ret = EINA_FALSE;
Eina_Iterator *itr;
_class_env_create(class, NULL, &class_env);
Eina_Strbuf *tmpbuf = eina_strbuf_new();
Eina_Strbuf *str_bodyf = eina_strbuf_new();
if ((itr = eolian_class_implements_get(class)))
{
const Eolian_Implement *impl;
EINA_ITERATOR_FOREACH(itr, impl)
{
if (eolian_implement_class_get(impl) != class)
continue;
Eolian_Function_Type ftype = EOLIAN_UNRESOLVED;
const Eolian_Function *fid = eolian_implement_function_get(impl, &ftype);
if (eolian_function_is_beta(fid))
continue;
switch (ftype)
{
case EOLIAN_PROP_GET: case EOLIAN_PROP_SET:
_eapi_func_generate(class, fid, ftype, str_bodyf);
break;
case EOLIAN_PROPERTY:
_eapi_func_generate(class, fid, EOLIAN_PROP_SET, str_bodyf);
_eapi_func_generate(class, fid, EOLIAN_PROP_GET, str_bodyf);
break;
default:
_eapi_func_generate(class, fid, EOLIAN_METHOD, str_bodyf);
break;
}
}
eina_iterator_free(itr);
}
eina_strbuf_append(buf, eina_strbuf_string_get(str_bodyf));
ret = EINA_TRUE;
eina_strbuf_free(tmpbuf);
eina_strbuf_free(str_bodyf);
return ret;
}

View File

@ -1,36 +0,0 @@
#ifndef __EOLIAN_LEGACY_GENERATOR_H
#define __EOLIAN_LEGACY_GENERATOR_H
#include <Eina.h>
/*
* @brief Generate legacy EAPI header for Eo class
*
* This function needs to be used in case we want to generate a function
* from scratch.
* There will not be respect of the order of the Eo Op Ids.
*
* @param[in] classname class name
* @param[inout] buf buffer to fill
*
* @return EINA_TRUE on success, EINA_FALSE on error.
*
*/
Eina_Bool legacy_header_generate(const Eolian_Class *class, Eina_Strbuf *buf);
/*
* @brief Generate C source code for Eo class
*
* This function needs to be used to generate C source code. It is generating
* code from scratch.
*
* @param[in] classname class name
* @param[inout] buf buffer to fill
*
* @return EINA_TRUE on success, EINA_FALSE on error.
*
*/
Eina_Bool legacy_source_generate(const Eolian_Class *class, Eina_Strbuf *buf);
#endif

View File

@ -1,407 +0,0 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <getopt.h>
#include <libgen.h>
#include <Eina.h>
#include "Eolian.h"
#include "legacy_generator.h"
#include "eo_generator.h"
#include "impl_generator.h"
#include "types_generator.h"
#include "common_funcs.h"
static Eina_Strbuf *
_include_guard_enclose(const char *fname, const char *suffix, Eina_Strbuf *fbody)
{
if (!fbody || !eina_strbuf_string_get(fbody))
return fbody;
if (!suffix)
suffix = "";
char incname[255];
memset(incname, 0, sizeof(incname));
strncpy (incname, fname, sizeof(incname) - 1);
char *p = incname;
eina_str_toupper(&p);
Eina_Strbuf *incguard = eina_strbuf_new();
eina_strbuf_append_printf(incguard, "#ifndef _%s_%s\n#define _%s_%s\n\n",
incname, suffix, incname, suffix);
eina_strbuf_replace_all(incguard, ".", "_");
eina_strbuf_append(incguard, eina_strbuf_string_get(fbody));
eina_strbuf_append(incguard, "\n#endif\n");
eina_strbuf_free(fbody);
return incguard;
}
static const char *
_filename_get(const char *path)
{
if (!path)
return NULL;
const char *ret = strrchr(path, '/');
if (!ret)
return path;
return ret + 1;
}
static Eina_Bool
_read_file(const char *filename, Eina_Strbuf **buf)
{
FILE *fd = fopen(filename, "rb");
if (!fd)
{
*buf = eina_strbuf_new();
return EINA_TRUE;
}
fseek(fd, 0, SEEK_END);
long file_size = ftell(fd);
if (file_size < 0)
{
fprintf(stderr, "eolian: could not get length of '%s'\n", filename);
fclose(fd);
return EINA_FALSE;
}
fseek(fd, 0, SEEK_SET);
char *content = malloc(file_size + 1);
if (!content)
{
fprintf(stderr, "eolian: could not allocate memory for '%s'\n", filename);
fclose(fd);
return EINA_FALSE;
}
long actual_size = (long)fread(content, 1, file_size, fd);
if (actual_size != file_size)
{
fprintf(stderr, "eolian: could not read %ld bytes from '%s' (read %ld bytes)\n",
file_size, filename, actual_size);
free(content);
fclose(fd);
return EINA_FALSE;
}
content[file_size] = '\0';
fclose(fd);
*buf = eina_strbuf_manage_new_length(content, file_size);
return EINA_TRUE;
}
static Eina_Bool
_write_file(const char *filename, const Eina_Strbuf *buffer, Eina_Bool append)
{
FILE *fd = fopen(filename, append ? "ab" : "wb");
if (!fd)
{
fprintf(stderr, "eolian: could not open '%s' for writing (%s)\n",
filename, strerror(errno));
return EINA_FALSE;
}
Eina_Bool ret = EINA_TRUE;
size_t blen = eina_strbuf_length_get(buffer);
if (!blen)
goto end;
if (fwrite(eina_strbuf_string_get(buffer), 1, blen, fd) != blen)
{
fprintf(stderr, "eolian: could not write '%s' (%s)\n",
filename, strerror(errno));
ret = EINA_FALSE;
}
end:
fclose(fd);
return ret;
}
static Eina_Bool
_generate_header(const char *outf, const char *inf, Eina_Bool legacy)
{
Eina_Strbuf *buf = eina_strbuf_new();
if (!types_header_generate(inf, buf, EINA_TRUE, legacy))
{
fprintf(stderr, "eolian: could not generate types of '%s'\n", inf);
eina_strbuf_free(buf);
return EINA_FALSE;
}
buf = _include_guard_enclose(inf, "TYPES", buf);
Eina_Strbuf *ctbuf = eina_strbuf_new();
if (types_class_typedef_generate(inf, ctbuf))
{
ctbuf = _include_guard_enclose(inf, "CLASS_TYPE", ctbuf);
eina_strbuf_append_char(ctbuf, '\n');
eina_strbuf_prepend(buf, eina_strbuf_string_get(ctbuf));
}
eina_strbuf_free(ctbuf);
const Eolian_Class *cl = eolian_class_get_by_file(inf);
if (cl)
{
Eina_Bool gret = legacy ? legacy_header_generate(cl, buf)
: eo_header_generate(cl, buf);
if (!gret)
{
fprintf(stderr, "eolian: could not generate header for '%s'\n",
eolian_class_name_get(cl));
eina_strbuf_free(buf);
return EINA_FALSE;
}
}
if (cl || !legacy)
{
buf = _include_guard_enclose(_filename_get(outf), NULL, buf);
if (_write_file(outf, buf, EINA_FALSE))
{
eina_strbuf_free(buf);
return EINA_TRUE;
}
}
eina_strbuf_free(buf);
return EINA_FALSE;
}
static Eina_Bool
_generate_stub_header(const char *outf, const char *inf)
{
Eina_Strbuf *buf = eina_strbuf_new();
if (!types_header_generate(inf, buf, EINA_FALSE, EINA_FALSE))
{
fprintf(stderr, "eolian: could not generate types of '%s'\n", inf);
eina_strbuf_free(buf);
return EINA_FALSE;
}
Eina_Strbuf *ctbuf = eina_strbuf_new();
if (types_class_typedef_generate(inf, ctbuf))
{
eina_strbuf_append_char(ctbuf, '\n');
eina_strbuf_prepend(buf, eina_strbuf_string_get(ctbuf));
}
eina_strbuf_free(ctbuf);
buf = _include_guard_enclose(_filename_get(outf), "STUBS", buf);
Eina_Bool ret = _write_file(outf, buf, EINA_FALSE);
eina_strbuf_free(buf);
return ret;
}
static Eina_Bool
_generate_c(const char *outf, const char *inf, Eina_Bool legacy)
{
Eina_Strbuf *eobuf = eina_strbuf_new(),
*lgbuf = eina_strbuf_new();
const Eolian_Class *cl = eolian_class_get_by_file(inf);
if (cl)
{
if (!eo_source_generate(cl, eobuf))
{
fprintf(stderr, "eolian: could not generate source for '%s'\n",
eolian_class_name_get(cl));
eina_strbuf_free(eobuf);
eina_strbuf_free(lgbuf);
return EINA_FALSE;
}
if (legacy && !legacy_source_generate(cl, lgbuf))
{
fprintf(stderr, "eolian: could not generate source for '%s'\n",
eolian_class_name_get(cl));
eina_strbuf_free(eobuf);
eina_strbuf_free(lgbuf);
return EINA_FALSE;
}
}
Eina_Bool ret = _write_file(outf, eobuf, EINA_FALSE) &&
_write_file(outf, lgbuf, EINA_TRUE);
eina_strbuf_free(eobuf);
eina_strbuf_free(lgbuf);
return ret;
}
static Eina_Bool
_generate_impl(const char *outf, const char *inf)
{
const Eolian_Class *cl = eolian_class_get_by_file(inf);
if (!cl)
return EINA_FALSE;
Eina_Strbuf *buf = NULL;
if (!_read_file(outf, &buf))
return EINA_FALSE;
if (!impl_source_generate(cl, buf))
{
fprintf(stderr, "eolian: could not generate source for '%s'\n",
eolian_class_name_get(cl));
eina_strbuf_free(buf);
return EINA_FALSE;
}
Eina_Bool ret = _write_file(outf, buf, EINA_FALSE);
eina_strbuf_free(buf);
return ret;
}
enum
{
GEN_NOTHING = 0,
GEN_H,
GEN_H_STUB,
GEN_C,
GEN_C_IMPL
};
int
main(int argc, char **argv)
{
int gen_what = GEN_NOTHING, do_legacy = 0, ret = 1, silent_types = 0;
Eina_Bool help = EINA_FALSE;
const char *outf = NULL;
eina_init();
eolian_init();
const char *dom = "eolian_gen";
_eolian_gen_log_dom = eina_log_domain_register(dom, EINA_COLOR_GREEN);
if (_eolian_gen_log_dom < 0)
{
EINA_LOG_ERR("Could not register log domain: %s", dom);
goto end;
}
eina_log_timing(_eolian_gen_log_dom, EINA_LOG_STATE_STOP, EINA_LOG_STATE_INIT);
struct option opts[] = {
{ "help", no_argument, NULL, 'h' },
{ "gh", no_argument, &gen_what, GEN_H },
{ "gc", no_argument, &gen_what, GEN_C },
{ "gi", no_argument, &gen_what, GEN_C_IMPL },
{ "gs", no_argument, &gen_what, GEN_H_STUB },
{ "output", required_argument, NULL, 'o' },
{ "legacy", no_argument, &do_legacy, 1 },
{ "include", required_argument, NULL, 'I' },
{ "silent-types", no_argument, &silent_types, 1 },
{ NULL, 0, NULL, 0 }
};
for (int opt; (opt = getopt_long(argc, argv, "vho:I:", opts, NULL)) != -1; )
switch (opt)
{
case 0: break;
case 'o':
outf = optarg;
break;
case 'h':
help = EINA_TRUE;
break;
case 'I':
if (!eolian_directory_scan(optarg))
{
fprintf(stderr, "eolian: could not scan '%s'\n", optarg);
goto end;
}
break;
default:
help = EINA_TRUE;
break;
}
if (help)
{
printf("Usage: %s [-h/--help] [-I/--include input_dir] [--legacy] [--gh|--gs|--gc|--gi] [--output/-o outfile] file.eo ... \n", argv[0]);
printf(" --help/-h Print that help\n");
printf(" --include/-I Include 'input_dir' as directory to search .eo files into\n");
printf(" --output/-o Force output filename to 'outfile'\n");
printf(" --gh Generate C header file [.h]\n");
printf(" --gs Generate C type stubs [.h]\n");
printf(" --gc Generate C source file [.c]\n");
printf(" --gi Generate C implementation source file [.c]. The output will be a series of functions that have to be filled.\n");
printf(" --legacy Generate legacy\n");
printf(" --silent-types Silence type validation\n");
ret = 0;
goto end;
}
const char *eof = argv[optind++];
if (!eof)
{
fprintf(stderr, "eolian: no input file\n");
goto end;
}
if (!eolian_file_parse(eof))
{
fprintf(stderr, "eolian: could not parse file '%s'\n", eof);
goto end;
}
if (!eolian_database_validate(silent_types))
{
fprintf(stderr, "eolian: error validating database\n");
goto end;
}
char *eofc = strdup(eof);
char *eobn = basename(eofc);
if (gen_what)
{
if (!outf)
{
fprintf(stderr, "eolian: no output file\n");
free(eofc);
goto end;
}
switch (gen_what)
{
case GEN_H:
INF("Generating header file %s\n", outf);
ret = !_generate_header(outf, eobn, do_legacy);
break;
case GEN_H_STUB:
INF("Generating stub header file %s\n", outf);
ret = !_generate_stub_header(outf, eobn);
break;
case GEN_C:
INF("Generating source file %s\n", outf);
ret = !_generate_c(outf, eobn, do_legacy);
break;
case GEN_C_IMPL:
INF("Generating user source file %s\n", outf);
ret = !_generate_impl(outf, eobn);
break;
default:
ERR("Wrong generation option\n");
break;
}
}
else
ret = 0;
free(eofc);
end:
eina_log_timing(_eolian_gen_log_dom, EINA_LOG_STATE_START, EINA_LOG_STATE_SHUTDOWN);
eina_log_domain_unregister(_eolian_gen_log_dom);
eolian_shutdown();
eina_shutdown();
return ret;
}

View File

@ -1,225 +0,0 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Eina.h>
#include <string.h>
#include <ctype.h>
#include "Eolian.h"
#include "types_generator.h"
#include "docs_generator.h"
#include "common_funcs.h"
static char *
_concat_name(const Eolian_Typedecl *tp)
{
const char *name;
char *str = NULL;
Eina_Strbuf *buf = eina_strbuf_new();
Eina_Iterator *itr = eolian_typedecl_namespaces_get(tp);
EINA_ITERATOR_FOREACH(itr, name)
if (name) eina_strbuf_append_printf(buf, "%s_", name);
eina_iterator_free(itr);
name = eolian_typedecl_name_get(tp);
if (name) eina_strbuf_append_printf(buf, "%s", name);
if (eina_strbuf_length_get(buf))
{
char *tmp = str = eina_strbuf_string_steal(buf);
*tmp = toupper(*tmp);
while (*tmp) if (*tmp++ == '_' && *tmp) *tmp = toupper(*tmp);
}
eina_strbuf_free(buf);
return str;
}
static Eina_Strbuf *
_type_generate(const Eolian_Typedecl *tp, Eina_Bool full, Eina_Bool use_legacy)
{
char *grp = strdup(eolian_typedecl_full_name_get(tp));
char *p = strrchr(grp, '.');
if (p) *p = '\0';
Eina_Strbuf *buf = docs_generate_full(eolian_typedecl_documentation_get(tp),
grp, 0, use_legacy);
free(grp);
if (!buf) buf = eina_strbuf_new();
else eina_strbuf_append_char(buf, '\n');
Eolian_Typedecl_Type tp_type = eolian_typedecl_type_get(tp);
switch(tp_type)
{
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 *member;
char *name = _concat_name(tp);
if (tp_type == EOLIAN_TYPEDECL_STRUCT_OPAQUE || !full)
{
eina_strbuf_append_printf(buf, "typedef struct _%s %s", name, name);
free(name);
break;
}
eina_strbuf_append_printf(buf, "typedef struct _%s\n{\n", name);
Eina_Iterator *members = eolian_typedecl_struct_fields_get(tp);
EINA_ITERATOR_FOREACH(members, member)
{
const Eolian_Type *type = eolian_typedecl_struct_field_type_get(member);
Eina_Stringshare *c_type = NULL;
if (eolian_type_type_get(type) == EOLIAN_TYPE_STATIC_ARRAY)
{
c_type = eolian_type_c_type_get(eolian_type_base_type_get(type));
eina_strbuf_append_printf(buf, " %s%s%s[%zu];",
c_type, strchr(c_type, '*')?"":" ",
eolian_typedecl_struct_field_name_get(member),
eolian_type_array_size_get(type));
}
else
{
c_type = eolian_type_c_type_get(type);
eina_strbuf_append_printf(buf, " %s%s%s;",
c_type, strchr(c_type, '*')?"":" ",
eolian_typedecl_struct_field_name_get(member));
}
eina_stringshare_del(c_type);
const Eolian_Documentation *fdoc
= eolian_typedecl_struct_field_documentation_get(member);
if (fdoc)
{
const char *nl = strrchr(eina_strbuf_string_get(buf), '\n');
if (nl)
{
Eina_Strbuf *fbuf = docs_generate_full(fdoc, NULL, strlen(nl), use_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(members);
eina_strbuf_append_printf(buf, "} %s", name);
free(name);
break;
}
case EOLIAN_TYPEDECL_ENUM:
{
const Eolian_Enum_Type_Field *member;
if (!full)
break;
char *name = _concat_name(tp);
eina_strbuf_append_printf(buf, "typedef enum\n{\n");
Eina_Iterator *members = eolian_typedecl_enum_fields_get(tp);
Eina_Bool next = eina_iterator_next(members, (void**)&member);
while (next)
{
const Eolian_Expression *value = eolian_typedecl_enum_field_value_get(member, EINA_FALSE);
Eina_Stringshare *membn = eolian_typedecl_enum_field_c_name_get(member);
if (!value)
eina_strbuf_append_printf(buf, " %s", membn);
else
{
Eolian_Value val = eolian_expression_eval(value, 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(value);
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(member);
next = eina_iterator_next(members, (void**)&member);
if (next)
eina_strbuf_append(buf, ",");
if (fdoc)
{
const char *nl = strrchr(eina_strbuf_string_get(buf), '\n');
if (nl)
{
Eina_Strbuf *fbuf = docs_generate_full(fdoc, NULL, strlen(nl), use_legacy);
if (fbuf)
eina_strbuf_append_printf(buf, " %s",
eina_strbuf_string_get(fbuf));
eina_strbuf_free(fbuf);
}
}
eina_strbuf_append(buf, "\n");
}
eina_strbuf_append_printf(buf, "} %s", name);
free(name);
eina_iterator_free(members);
break;
}
default:
{
eina_strbuf_reset(buf);
}
}
return buf;
}
Eina_Bool
types_header_generate(const char *eo_filename, Eina_Strbuf *buf, Eina_Bool full, Eina_Bool use_legacy)
{
const Eolian_Declaration *decl;
Eina_Iterator *itr = eolian_declarations_get_by_file(eo_filename);
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, use_legacy);
if (tbuf)
{
eina_strbuf_append(buf, eina_strbuf_string_get(tbuf));
eina_strbuf_append(buf, ";\n\n");
eina_strbuf_free(tbuf);
}
}
eina_iterator_free(itr);
return EINA_TRUE;
}
Eina_Bool
types_class_typedef_generate(const char *eo_filename, Eina_Strbuf *buf)
{
const Eolian_Class *class = eolian_class_get_by_file(eo_filename);
if (!class)
return EINA_FALSE;
static _eolian_class_vars class_env;
_class_env_create(class, NULL, &class_env);
eina_strbuf_append_printf(buf, "typedef Eo %s;\n", class_env.full_classname);
return EINA_TRUE;
}

View File

@ -1,22 +0,0 @@
#ifndef TYPES_GENERATOR_H
#define TYPES_GENERATOR_H
#include<Eina.h>
/*
* @brief Generate the header code for the types of a specific file.
*
* @param[in] eo_filename Eo filename
* @param[inout] buf buffer to fill
* @param[in]full whether to generate full type definitions
* @param[in] use_legacy whether to use legacy names
*
* @return EINA_TRUE on success, EINA_FALSE on error.
*
*/
Eina_Bool types_header_generate(const char *eo_filename, Eina_Strbuf *buf, Eina_Bool full, Eina_Bool use_legacy);
Eina_Bool types_class_typedef_generate(const char *eo_filename, Eina_Strbuf *buf);
#endif