Merge branch 'devs/q66/eolian_gen_next'

This merges a rewritten Eolian C generator which replaces the previous
generator. The old generator did not properly reflect the design choices taken
in the Eolian library, which resulted in a sub-par codebase that was a lot more
complicated than it had to be which resulted in worse maintainability.

The new generator aims to remedy that; it has much simpler design that relies
on the Eolian library more and doesn't take certain design choices that were
made previously.
This commit is contained in:
Daniel Kolesa 2016-10-07 13:36:15 +02:00
commit 797e417d1e
34 changed files with 2186 additions and 2749 deletions

View File

@ -48,19 +48,16 @@ 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/main.c \
bin/eolian/main.h \
bin/eolian/types.c \
bin/eolian/types.h \
bin/eolian/headers.c \
bin/eolian/headers.h \
bin/eolian/sources.c \
bin/eolian/sources.h \
bin/eolian/docs.c \
bin/eolian/docs.h
bin_eolian_eolian_gen_CPPFLAGS = -I$(top_builddir)/src/lib/efl @EOLIAN_CFLAGS@
bin_eolian_eolian_gen_LDADD = @USE_EOLIAN_LIBS@

View File

@ -8,19 +8,19 @@ SUFFIXES = .eo .eo.c .eo.h .eo.legacy.h .eot .eot.h
%.eo.c: %.eo ${_EOLIAN_GEN_DEP}
$(AM_V_EOL) \
$(MKDIR_P) $(dir $@); \
$(EOLIAN_GEN) --legacy $(EOLIAN_FLAGS) --gc -o $@ $<
$(EOLIAN_GEN) $(EOLIAN_FLAGS) -gc -o c:$@ $<
%.eo.h: %.eo ${_EOLIAN_GEN_DEP}
$(AM_V_EOL) \
$(MKDIR_P) $(dir $@); \
$(EOLIAN_GEN) $(EOLIAN_FLAGS) --gh -o $@ $<
$(EOLIAN_GEN) $(EOLIAN_FLAGS) -gh -o h:$@ $<
%.eot.h: %.eot ${_EOLIAN_GEN_DEP}
$(AM_V_EOL) \
$(MKDIR_P) $(dir $@); \
$(EOLIAN_GEN) $(EOLIAN_FLAGS) --gh -o $@ $<
$(EOLIAN_GEN) $(EOLIAN_FLAGS) -gh -o h:$@ $<
%.eo.legacy.h: %.eo ${_EOLIAN_GEN_DEP}
$(AM_V_EOL) \
$(MKDIR_P) $(dir $@); \
$(EOLIAN_GEN) --legacy $(EOLIAN_FLAGS) --gh -o $@ $<
$(EOLIAN_GEN) $(EOLIAN_FLAGS) -gl -o l:$@ $<

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,10 +1,6 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <ctype.h>
#include "docs_generator.h"
#include "docs.h"
static int
_indent_line(Eina_Strbuf *buf, int ind)
@ -360,14 +356,14 @@ _gen_doc_buf(const Eolian_Documentation *doc, const char *group,
}
Eina_Strbuf *
docs_generate_full(const Eolian_Documentation *doc, const char *group,
int indent, Eina_Bool use_legacy)
eo_gen_docs_full_gen(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)
eo_gen_docs_event_gen(const Eolian_Event *ev, const char *group)
{
if (!ev) return NULL;
@ -402,8 +398,8 @@ docs_generate_event(const Eolian_Event *ev, const char *group)
}
Eina_Strbuf *
docs_generate_function(const Eolian_Function *fid, Eolian_Function_Type ftype,
int indent, Eina_Bool use_legacy)
eo_gen_docs_func_gen(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;

View File

@ -1,8 +1,7 @@
#ifndef DOCS_GENERATOR_H
#define DOCS_GENERATOR_H
#ifndef EOLIAN_GEN_DOCS_H
#define EOLIAN_GEN_DOCS_H
#include <Eina.h>
#include <Eolian.h>
#include "main.h"
/*
* @brief Generate standard documentation
@ -15,7 +14,7 @@
* @return A documentation comment
*
*/
Eina_Strbuf *docs_generate_full(const Eolian_Documentation *doc, const char *group, int indent, Eina_Bool use_legacy);
Eina_Strbuf *eo_gen_docs_full_gen(const Eolian_Documentation *doc, const char *group, int indent, Eina_Bool use_legacy);
/*
* @brief Generate function documentation
@ -28,7 +27,7 @@ Eina_Strbuf *docs_generate_full(const Eolian_Documentation *doc, const char *gro
* @return A documentation comment
*
*/
Eina_Strbuf *docs_generate_function(const Eolian_Function *fid, Eolian_Function_Type ftype, int indent, Eina_Bool use_legacy);
Eina_Strbuf *eo_gen_docs_func_gen(const Eolian_Function *fid, Eolian_Function_Type ftype, int indent, Eina_Bool use_legacy);
/*
* @brief Generate event documentation
@ -39,7 +38,7 @@ Eina_Strbuf *docs_generate_function(const Eolian_Function *fid, Eolian_Function_
* @return A documentation comment
*
*/
Eina_Strbuf *docs_generate_event(const Eolian_Event *ev, const char *group);
Eina_Strbuf *eo_gen_docs_event_gen(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

314
src/bin/eolian/headers.c Normal file
View File

@ -0,0 +1,314 @@
#include "main.h"
#include "docs.h"
static const char *
_cl_type_str_get(const Eolian_Class *cl, Eina_Bool uc)
{
switch (eolian_class_type_get(cl))
{
case EOLIAN_CLASS_REGULAR:
case EOLIAN_CLASS_ABSTRACT:
return uc ? "CLASS" : "class";
case EOLIAN_CLASS_MIXIN:
return uc ? "MIXIN" : "mixin";
case EOLIAN_CLASS_INTERFACE:
return uc ? "INTERFACE" : "interface";
default:
return NULL;
}
}
static 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 "";
}
static void
_gen_func(const Eolian_Function *fid, Eolian_Function_Type ftype,
Eina_Strbuf *buf, char *cname, char *cnameu, Eina_Bool legacy)
{
Eina_Stringshare *fcn = eolian_function_full_c_name_get(fid, ftype, legacy);
if (!fcn)
return;
Eina_Bool var_as_ret = EINA_FALSE;
const Eolian_Type *rtp = eolian_function_return_type_get(fid, ftype);
if (ftype == EOLIAN_PROP_GET && !rtp)
{
void *d1, *d2;
Eina_Iterator *itr = eolian_property_values_get(fid, ftype);
if (eina_iterator_next(itr, &d1) && !eina_iterator_next(itr, &d2))
{
rtp = eolian_parameter_type_get((Eolian_Function_Parameter *)d1);
var_as_ret = EINA_TRUE;
}
eina_iterator_free(itr);
}
Eolian_Object_Scope fsc = eolian_function_scope_get(fid, ftype);
/* this one will never be satisfied in legacy */
if (eolian_function_is_beta(fid))
eina_strbuf_append_printf(buf, "#ifdef %s_BETA\n", cnameu);
/* XXX: is this right? we expose potentially internal stuff into legacy */
if (!legacy && (fsc == EOLIAN_SCOPE_PROTECTED))
eina_strbuf_append_printf(buf, "#ifdef %s_PROTECTED\n", cnameu);
Eina_Bool hasdoc = eolian_function_documentation_get(fid, EOLIAN_UNRESOLVED) ||
eolian_function_documentation_get(fid, ftype);
if (hasdoc)
{
Eina_Strbuf *dbuf = eo_gen_docs_func_gen(fid, ftype, 0, legacy);
eina_strbuf_append(buf, eina_strbuf_string_get(dbuf));
eina_strbuf_append_char(buf, '\n');
eina_strbuf_free(dbuf);
}
eina_strbuf_append(buf, legacy ? "EAPI " : "EOAPI ");
if (rtp)
{
Eina_Stringshare *rtps = eolian_type_c_type_get(rtp);
eina_strbuf_append(buf, rtps);
if (rtps[strlen(rtps) - 1] != '*')
eina_strbuf_append_char(buf, ' ');
eina_stringshare_del(rtps);
}
else
eina_strbuf_append(buf, "void ");
eina_strbuf_append(buf, fcn);
eina_stringshare_del(fcn);
Eina_Bool first = EINA_TRUE;
Eina_Strbuf *flagbuf = NULL;
int nidx = !legacy || !eolian_function_is_class(fid);
eina_strbuf_append_char(buf, '(');
if (nidx)
{
if ((ftype == EOLIAN_PROP_GET) || eolian_function_object_is_const(fid)
|| eolian_function_is_class(fid))
{
eina_strbuf_append(buf, "const ");
}
if (legacy)
eina_strbuf_append_printf(buf, "%s *obj", cname);
else
eina_strbuf_append(buf, "Eo *obj");
first = EINA_FALSE;
}
{
Eolian_Function_Parameter *pr = NULL;
Eina_Iterator *itr = eolian_property_keys_get(fid, ftype);
EINA_ITERATOR_FOREACH(itr, pr)
{
const Eolian_Type *prt = eolian_parameter_type_get(pr);
const char *prn = eolian_parameter_name_get(pr);
Eina_Stringshare *prtn = eolian_type_c_type_get(prt);
++nidx;
if (!first)
eina_strbuf_append(buf, ", ");
eina_strbuf_append_printf(buf, "%s %s", prtn, prn);
eina_stringshare_del(prtn);
first = EINA_FALSE;
if (!eolian_parameter_is_nonull(pr))
continue;
if (!flagbuf)
{
flagbuf = eina_strbuf_new();
eina_strbuf_append_printf(flagbuf, " EINA_ARG_NONNULL(%d", nidx);
}
else
eina_strbuf_append_printf(flagbuf, ", %d", nidx);
}
eina_iterator_free(itr);
}
if (!var_as_ret)
{
Eina_Iterator *itr = NULL;
if (ftype == EOLIAN_PROP_GET || ftype == EOLIAN_PROP_SET)
itr = eolian_property_values_get(fid, ftype);
else
itr = eolian_function_parameters_get(fid);
Eolian_Function_Parameter *pr = NULL;
EINA_ITERATOR_FOREACH(itr, pr)
{
const Eolian_Type *prt = eolian_parameter_type_get(pr);
const char *prn = eolian_parameter_name_get(pr);
Eina_Stringshare *prtn = eolian_type_c_type_get(prt);
++nidx;
if (!first)
eina_strbuf_append(buf, ", ");
eina_strbuf_append(buf, prtn);
if (!strchr(prtn, '*'))
eina_strbuf_append_char(buf, ' ');
eina_strbuf_append(buf,
_get_add_star(ftype, eolian_parameter_direction_get(pr)));
eina_strbuf_append(buf, prn);
eina_stringshare_del(prtn);
first = EINA_FALSE;
if (!eolian_parameter_is_nonull(pr))
continue;
if (!flagbuf)
{
flagbuf = eina_strbuf_new();
eina_strbuf_append_printf(flagbuf, " EINA_ARG_NONNULL(%d", nidx);
}
else
eina_strbuf_append_printf(flagbuf, ", %d", nidx);
}
eina_iterator_free(itr);
}
if (flagbuf)
eina_strbuf_append_char(flagbuf, ')');
eina_strbuf_append(buf, ")");
if (eolian_function_return_is_warn_unused(fid, ftype))
{
if (!flagbuf)
flagbuf = eina_strbuf_new();
eina_strbuf_prepend(flagbuf, " EINA_WARN_UNUSED_RESULT");
}
if (flagbuf)
{
eina_strbuf_append(buf, eina_strbuf_string_get(flagbuf));
eina_strbuf_free(flagbuf);
}
eina_strbuf_append(buf, ";\n");
if (eolian_function_is_beta(fid))
eina_strbuf_append_printf(buf, "#endif\n");
if (!legacy && (fsc == EOLIAN_SCOPE_PROTECTED))
eina_strbuf_append_printf(buf, "#endif\n");
}
void
eo_gen_header_gen(const Eolian_Class *cl, Eina_Strbuf *buf, Eina_Bool legacy)
{
if (!cl)
return;
char *cname = NULL, *cnameu = NULL, *cnamel = NULL;
eo_gen_class_names_get(cl, &cname, &cnameu, &cnamel);
/* class definition */
if (!legacy)
{
const Eolian_Documentation *doc = eolian_class_documentation_get(cl);
if (doc)
{
Eina_Strbuf *cdoc = eo_gen_docs_full_gen(doc,
eolian_class_full_name_get(cl), 0, EINA_FALSE);
if (cdoc)
{
eina_strbuf_append(buf, eina_strbuf_string_get(cdoc));
eina_strbuf_append_char(buf, '\n');
eina_strbuf_free(cdoc);
}
}
eina_strbuf_append_printf(buf, "#define %s_%s %s_%s_get()\n\n",
cnameu, _cl_type_str_get(cl, EINA_TRUE),
cnamel, _cl_type_str_get(cl, EINA_FALSE));
eina_strbuf_append_printf(buf, "EWAPI const Efl_Class *%s_%s_get(void);\n",
cnamel, _cl_type_str_get(cl, EINA_FALSE));
}
/* method section */
{
Eina_Iterator *itr = eolian_class_implements_get(cl);
if (!itr)
goto events;
const Eolian_Implement *imp;
EINA_ITERATOR_FOREACH(itr, imp)
{
if (eolian_implement_class_get(imp) != cl)
continue;
Eolian_Function_Type ftype = EOLIAN_UNRESOLVED;
const Eolian_Function *fid = eolian_implement_function_get(imp, &ftype);
/* beta can only exist for eo api */
if (legacy && eolian_function_is_beta(fid))
continue;
eina_strbuf_append_char(buf, '\n');
switch (ftype)
{
case EOLIAN_PROP_GET:
case EOLIAN_PROP_SET:
_gen_func(fid, ftype, buf, cname, cnameu, legacy);
break;
case EOLIAN_PROPERTY:
_gen_func(fid, EOLIAN_PROP_SET, buf, cname, cnameu, legacy);
eina_strbuf_append_char(buf, '\n');
_gen_func(fid, EOLIAN_PROP_GET, buf, cname, cnameu, legacy);
break;
default:
_gen_func(fid, EOLIAN_UNRESOLVED, buf, cname, cnameu, legacy);
}
}
eina_iterator_free(itr);
}
events:
/* event section */
if (!legacy)
{
Eina_Iterator *itr = eolian_class_events_get(cl);
Eolian_Event *ev;
EINA_ITERATOR_FOREACH(itr, ev)
{
Eina_Stringshare *evn = eolian_event_c_name_get(ev);
Eolian_Object_Scope evs = eolian_event_scope_get(ev);
if (evs == EOLIAN_SCOPE_PRIVATE)
continue;
if (eolian_event_is_beta(ev))
{
eina_strbuf_append_printf(buf, "\n#ifdef %s_BETA\n", cnameu);
}
if (evs == EOLIAN_SCOPE_PROTECTED)
{
if (!eolian_event_is_beta(ev))
eina_strbuf_append_char(buf, '\n');
eina_strbuf_append_printf(buf, "#ifdef %s_PROTECTED\n", cnameu);
}
if (!eolian_event_is_beta(ev) && evs == EOLIAN_SCOPE_PUBLIC)
eina_strbuf_append_char(buf, '\n');
eina_strbuf_append_printf(buf, "EOAPI extern const "
"Efl_Event_Description _%s;\n\n", evn);
Eina_Strbuf *evdbuf = eo_gen_docs_event_gen(ev,
eolian_class_full_name_get(cl));
eina_strbuf_append(buf, eina_strbuf_string_get(evdbuf));
eina_strbuf_append_char(buf, '\n');
eina_strbuf_free(evdbuf);
eina_strbuf_append_printf(buf, "#define %s (&(_%s))\n", evn, evn);
if (evs == EOLIAN_SCOPE_PROTECTED)
eina_strbuf_append(buf, "#endif\n");
if (eolian_event_is_beta(ev))
eina_strbuf_append(buf, "#endif\n");
eina_stringshare_del(evn);
}
eina_iterator_free(itr);
}
free(cname);
free(cnameu);
free(cnamel);
}

8
src/bin/eolian/headers.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef EOLIAN_GEN_HEADERS_H
#define EOLIAN_GEN_HEADERS_H
#include "main.h"
void eo_gen_header_gen(const Eolian_Class *cl, Eina_Strbuf *buf, Eina_Bool legacy);
#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,169 +1,307 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <getopt.h>
#include <stdlib.h>
#include <unistd.h>
#include <libgen.h>
#include <Eina.h>
#include "main.h"
#include "types.h"
#include "headers.h"
#include "sources.h"
#include "Eolian.h"
#include "legacy_generator.h"
#include "eo_generator.h"
#include "impl_generator.h"
#include "types_generator.h"
#include "common_funcs.h"
int _eolian_gen_log_dom = -1;
static Eina_Strbuf *
_include_guard_enclose(const char *fname, const char *suffix, Eina_Strbuf *fbody)
enum
{
if (!fbody || !eina_strbuf_string_get(fbody))
return fbody;
GEN_H = 1 << 0,
GEN_H_LEGACY = 1 << 1,
GEN_H_STUB = 1 << 2,
GEN_C = 1 << 3,
GEN_C_IMPL = 1 << 4
};
if (!suffix)
suffix = "";
static const char *_dexts[5] =
{
".h", ".legacy.h", ".stub.h", ".c", ".c"
};
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 int
_get_bit_pos(int flag)
{
int pos = 0;
for (; !(flag & 1); flag >>= 1)
++pos;
return pos;
}
static const char *
_filename_get(const char *path)
static void
_print_usage(const char *progn, FILE *outf)
{
if (!path)
return NULL;
const char *ret = strrchr(path, '/');
if (!ret)
return path;
return ret + 1;
fprintf(outf, "Usage: %s [options] [input]\n", progn);
fprintf(outf, "Options:\n"
" -I inc include path \"inc\"\n"
" -g type generate file of type \"type\"\n"
" -o name specify the base name for output\n"
" -o type:name specify a particular output filename\n"
" -h print this message and exit\n"
" -v print version and exit\n"
"\n"
"Available types:\n"
" h: C header file (.h)\n"
" l: Legacy C header file (.legacy.h)\n"
" s: Stub C header file (.stub.h)\n"
" c: C source file (.c)\n"
" i: Implementation file (added into .c)\n"
"\n"
"By default, the 'hc' set is used ('h' for .eot files).\n"
"Output filenames are determined from input .eo filename.\n"
"Default filenames include input extension. (e.g. \".eo.c\")\n");
}
static void
_print_version(FILE *outf)
{
fprintf(outf, "Eolian C generator version: " PACKAGE_VERSION "\n");
}
static Eina_Bool
_read_file(const char *filename, Eina_Strbuf **buf)
_try_set_out(char t, char **outs, const char *val)
{
FILE *fd = fopen(filename, "rb");
if (!fd)
int pos = -1;
switch (t)
{
case 'h':
pos = _get_bit_pos(GEN_H);
break;
case 'l':
pos = _get_bit_pos(GEN_H_LEGACY);
break;
case 's':
pos = _get_bit_pos(GEN_H_STUB);
break;
case 'c':
pos = _get_bit_pos(GEN_C);
break;
case 'i':
pos = _get_bit_pos(GEN_C_IMPL);
break;
}
if (pos < 0)
return EINA_FALSE;
if (outs[pos])
free(outs[pos]);
outs[pos] = strdup(val);
return EINA_TRUE;
}
static void _fill_all_outs(char **outs, const char *val)
{
size_t vlen = strlen(val);
for (size_t i = 0; i < (sizeof(_dexts) / sizeof(char *)); ++i)
{
if (outs[i])
continue;
size_t dlen = strlen(_dexts[i]);
char *str = malloc(vlen + dlen + 1);
memcpy(str, val, vlen);
memcpy(str + vlen, _dexts[i], dlen);
str[vlen + dlen] = '\0';
outs[i] = str;
}
}
static Eina_Strbuf *
_include_guard(const char *fname, const char *gname, Eina_Strbuf *buf)
{
if (!buf)
return NULL;
if (!gname)
gname = "";
char iname[256] = {0};
strncpy(iname, fname, sizeof(iname) - 1);
char *inamep = iname;
eina_str_toupper(&inamep);
Eina_Strbuf *g = eina_strbuf_new();
eina_strbuf_append_printf(g, "#ifndef _%s_%s\n", iname, gname);
eina_strbuf_append_printf(g, "#define _%s_%s\n\n", iname, gname);
eina_strbuf_replace_all(g, ".", "_");
eina_strbuf_append(g, eina_strbuf_string_get(buf));
eina_strbuf_append(g, "\n#endif\n");
eina_strbuf_free(buf);
return g;
}
static const char *
_get_filename(const char *path)
{
if (!path)
return NULL;
const char *ret1 = strrchr(path, '/');
const char *ret2 = strrchr(path, '\\');
if (!ret1 && !ret2)
return path;
if (ret1 && ret2)
{
if (ret1 > ret2)
return ret1 + 1;
else
return ret2 + 1;
}
if (ret1)
return ret1 + 1;
return ret2 + 1;
}
static Eina_Bool
_write_file(const char *fname, const Eina_Strbuf *buf)
{
FILE *f = fopen(fname, "wb");
if (!f)
{
fprintf(stderr, "eolian: could not open '%s' (%s)\n",
fname, strerror(errno));
return EINA_FALSE;
}
Eina_Bool fret = EINA_TRUE;
size_t bl = eina_strbuf_length_get(buf);
if (!bl)
goto end;
if (fwrite(eina_strbuf_string_get(buf), 1, bl, f) != bl)
{
fprintf(stderr, "eolian: could not write '%s' (%s)\n",
fname, strerror(errno));
fret = EINA_FALSE;
}
end:
fclose(f);
return fret;
}
static Eina_Bool
_read_file(const char *fname, Eina_Strbuf **buf)
{
FILE *f = fopen(fname, "rb");
if (!f)
{
*buf = eina_strbuf_new();
return EINA_TRUE;
}
fseek(fd, 0, SEEK_END);
long file_size = ftell(fd);
if (file_size < 0)
fseek(f, 0, SEEK_END);
long fs = ftell(f);
if (fs < 0)
{
fprintf(stderr, "eolian: could not get length of '%s'\n", filename);
fclose(fd);
fprintf(stderr, "eolian: could not get length of '%s'\n", fname);
fclose(f);
return EINA_FALSE;
}
fseek(fd, 0, SEEK_SET);
fseek(f, 0, SEEK_SET);
char *content = malloc(file_size + 1);
if (!content)
char *cont = malloc(fs + 1);
if (!cont)
{
fprintf(stderr, "eolian: could not allocate memory for '%s'\n", filename);
fclose(fd);
fprintf(stderr, "eolian: could not allocate memory for '%s'\n", fname);
fclose(f);
return EINA_FALSE;
}
long actual_size = (long)fread(content, 1, file_size, fd);
if (actual_size != file_size)
long as = fread(cont, 1, fs, f);
if (as != fs)
{
fprintf(stderr, "eolian: could not read %ld bytes from '%s' (read %ld bytes)\n",
file_size, filename, actual_size);
free(content);
fclose(fd);
fprintf(stderr, "eolian: could not read %ld bytes from '%s' (got %ld)\n",
fs, fname, as);
free(cont);
fclose(f);
return EINA_FALSE;
}
content[file_size] = '\0';
fclose(fd);
*buf = eina_strbuf_manage_new_length(content, file_size);
cont[fs] = '\0';
fclose(f);
*buf = eina_strbuf_manage_new_length(cont, fs);
return EINA_TRUE;
}
static Eina_Bool
_write_file(const char *filename, const Eina_Strbuf *buffer, Eina_Bool append)
char *eo_gen_c_full_name_get(const char *nm)
{
FILE *fd = fopen(filename, append ? "ab" : "wb");
if (!fd)
if (!nm)
return NULL;
char *buf = strdup(nm);
if (!buf)
abort();
for (char *p = strchr(buf, '.'); p; p = strchr(p, '.'))
*p = '_';
return buf;
}
void eo_gen_class_names_get(const Eolian_Class *cl, char **cname,
char **cnameu, char **cnamel)
{
char *cn = NULL, *cnu = NULL, *cnl = NULL;
cn = eo_gen_c_full_name_get(eolian_class_full_name_get(cl));
if (!cn)
abort();
if (cname)
*cname = cn;
if (cnameu)
{
fprintf(stderr, "eolian: could not open '%s' for writing (%s)\n",
filename, strerror(errno));
return EINA_FALSE;
cnu = strdup(cn);
if (!cnu)
{
free(cn);
abort();
}
eina_str_toupper(&cnu);
*cnameu = cnu;
}
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)
if (cnamel)
{
fprintf(stderr, "eolian: could not write '%s' (%s)\n",
filename, strerror(errno));
ret = EINA_FALSE;
cnl = strdup(cn);
if (!cnl)
{
free(cn);
free(cnu);
abort();
}
eina_str_tolower(&cnl);
*cnamel = cnl;
}
end:
fclose(fd);
return ret;
if (!cname)
free(cn);
}
static Eina_Bool
_generate_header(const char *outf, const char *inf, Eina_Bool legacy)
_write_header(const char *ofname, const char *ifname, Eina_Bool legacy)
{
INF("generating header: %s (legacy: %d)", ofname, legacy);
Eina_Strbuf *buf = eina_strbuf_new();
if (!types_header_generate(inf, buf, EINA_TRUE, legacy))
eo_gen_types_header_gen(ifname, buf, EINA_TRUE, legacy);
buf = _include_guard(ifname, "TYPES", buf);
Eina_Strbuf *cltd = eo_gen_class_typedef_gen(ifname);
if (cltd)
{
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;
}
cltd = _include_guard(ifname, "CLASS_TYPE", cltd);
eina_strbuf_prepend_char(buf, '\n');
eina_strbuf_prepend(buf, eina_strbuf_string_get(cltd));
eina_strbuf_free(cltd);
}
const Eolian_Class *cl = eolian_class_get_by_file(ifname);
eo_gen_header_gen(cl, buf, legacy);
if (cl || !legacy)
{
buf = _include_guard_enclose(_filename_get(outf), NULL, buf);
if (_write_file(outf, buf, EINA_FALSE))
buf = _include_guard(_get_filename(ofname), NULL, buf);
if (_write_file(ofname, buf))
{
eina_strbuf_free(buf);
return EINA_TRUE;
@ -175,106 +313,72 @@ _generate_header(const char *outf, const char *inf, Eina_Bool legacy)
}
static Eina_Bool
_generate_stub_header(const char *outf, const char *inf)
_write_stub_header(const char *ofname, const char *ifname)
{
INF("generating stub header: %s", ofname);
Eina_Strbuf *buf = eina_strbuf_new();
if (!types_header_generate(inf, buf, EINA_FALSE, EINA_FALSE))
eo_gen_types_header_gen(ifname, buf, EINA_FALSE, EINA_FALSE);
Eina_Strbuf *cltd = eo_gen_class_typedef_gen(ifname);
if (cltd)
{
fprintf(stderr, "eolian: could not generate types of '%s'\n", inf);
eina_strbuf_free(buf);
return EINA_FALSE;
eina_strbuf_prepend_char(buf, '\n');
eina_strbuf_prepend(buf, eina_strbuf_string_get(cltd));
eina_strbuf_free(cltd);
}
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(_get_filename(ofname), "STUBS", buf);
buf = _include_guard_enclose(_filename_get(outf), "STUBS", buf);
Eina_Bool ret = _write_file(outf, buf, EINA_FALSE);
Eina_Bool ret = _write_file(ofname, buf);
eina_strbuf_free(buf);
return ret;
}
static Eina_Bool
_generate_c(const char *outf, const char *inf, Eina_Bool legacy)
_write_source(const char *ofname, const char *ifname)
{
Eina_Strbuf *eobuf = eina_strbuf_new(),
*lgbuf = eina_strbuf_new();
INF("generating source: %s", ofname);
Eina_Strbuf *buf = eina_strbuf_new();
const Eolian_Class *cl = eolian_class_get_by_file(inf);
const Eolian_Class *cl = eolian_class_get_by_file(ifname);
eo_gen_source_gen(cl, buf);
if (cl)
{
if (!eo_source_generate(cl, eobuf))
if (_write_file(ofname, buf))
{
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_strbuf_free(buf);
return EINA_TRUE;
}
}
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;
eina_strbuf_free(buf);
return EINA_FALSE;
}
static Eina_Bool
_generate_impl(const char *outf, const char *inf)
_write_impl(const char *ofname, const char *ifname)
{
const Eolian_Class *cl = eolian_class_get_by_file(inf);
INF("generating impl: %s", ofname);
const Eolian_Class *cl = eolian_class_get_by_file(ifname);
if (!cl)
return EINA_FALSE;
Eina_Strbuf *buf = NULL;
if (!_read_file(outf, &buf))
Eina_Strbuf *buf;
if (!_read_file(ofname, &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);
eo_gen_impl_gen(cl, buf);
Eina_Bool ret = _write_file(ofname, buf);
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;
int pret = 1;
eina_init();
eolian_init();
@ -289,28 +393,13 @@ main(int argc, char **argv)
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 }
};
char *outs[5] = { NULL, NULL, NULL, NULL, NULL };
for (int opt; (opt = getopt_long(argc, argv, "vho:I:", opts, NULL)) != -1; )
int gen_what = 0;
for (int opt; (opt = getopt(argc, argv, "I:g:o:hvV")) != -1;)
switch (opt)
{
case 0: break;
case 'o':
outf = optarg;
break;
case 'h':
help = EINA_TRUE;
case 0:
break;
case 'I':
if (!eolian_directory_scan(optarg))
@ -319,89 +408,107 @@ main(int argc, char **argv)
goto end;
}
break;
default:
help = EINA_TRUE;
case 'g':
for (const char *wstr = optarg; *wstr; ++wstr)
switch (*wstr)
{
case 'h':
gen_what |= GEN_H;
break;
case 'l':
gen_what |= GEN_H_LEGACY;
break;
case 's':
gen_what |= GEN_H_STUB;
break;
case 'c':
gen_what |= GEN_C;
break;
case 'i':
gen_what |= GEN_C_IMPL;
break;
default:
fprintf(stderr, "unknown type: '%c'\n", *wstr);
goto end;
}
break;
case 'o':
if (strchr(optarg, ':'))
{
const char *abeg = optarg;
const char *cpos = strchr(abeg, ':');
if (((cpos - abeg) != 1) || !_try_set_out(*abeg, outs, cpos + 1))
{
char *oa = strdup(abeg);
oa[cpos - abeg] = '\0';
fprintf(stderr, "unknown type: '%s'\n", oa);
free(oa);
goto end;
}
}
else _fill_all_outs(outs, optarg);
break;
case 'h':
_print_usage(argv[0], stdout);
goto end;
case 'v':
_print_version(stdout);
goto end;
default:
_print_usage(argv[0], stderr);
goto end;
}
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)
const char *input = argv[optind];
if (!input)
{
fprintf(stderr, "eolian: no input file\n");
goto end;
}
if (!eolian_file_parse(eof))
const char *ext = strrchr(input, '.');
if (!ext || (strcmp(ext, ".eo") && strcmp(ext, ".eot")))
{
fprintf(stderr, "eolian: could not parse file '%s'\n", eof);
fprintf(stderr, "eolian: invalid input file '%s'\n", input);
goto end;
}
if (!eolian_database_validate(silent_types))
if (!eolian_file_parse(input))
{
fprintf(stderr, "eolian: error validating database\n");
fprintf(stderr, "eolian: could not parse file '%s'\n", input);
goto end;
}
char *eofc = strdup(eof);
char *eobn = basename(eofc);
_fill_all_outs(outs, input);
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;
const char *eobn = _get_filename(input);
free(eofc);
if (!gen_what)
gen_what = !strcmp(ext, ".eot") ? GEN_H : (GEN_H | GEN_C);
Eina_Bool succ = EINA_TRUE;
if (gen_what & GEN_H)
succ = _write_header(outs[_get_bit_pos(GEN_H)], eobn, EINA_FALSE);
if (succ && (gen_what & GEN_H_LEGACY))
succ = _write_header(outs[_get_bit_pos(GEN_H_LEGACY)], eobn, EINA_TRUE);
if (succ && (gen_what & GEN_H_STUB))
succ = _write_stub_header(outs[_get_bit_pos(GEN_H_STUB)], eobn);
if (succ && (gen_what & GEN_C))
succ = _write_source(outs[_get_bit_pos(GEN_C)], eobn);
if (succ && (gen_what & GEN_C_IMPL))
succ = _write_impl(outs[_get_bit_pos(GEN_C_IMPL)], eobn);
if (!succ)
goto end;
pret = 0;
end:
eina_log_timing(_eolian_gen_log_dom, EINA_LOG_STATE_START, EINA_LOG_STATE_SHUTDOWN);
eina_log_domain_unregister(_eolian_gen_log_dom);
for (size_t i = 0; i < (sizeof(_dexts) / sizeof(char *)); ++i)
free(outs[i]);
eolian_shutdown();
eina_shutdown();
return ret;
return pret;
}

42
src/bin/eolian/main.h Normal file
View File

@ -0,0 +1,42 @@
#ifndef EOLIAN_GEN_MAIN_H
#define EOLIAN_GEN_MAIN_H
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Eina.h>
#include <Eolian.h>
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__)
char *eo_gen_c_full_name_get(const char *nm);
void eo_gen_class_names_get(const Eolian_Class *cl, char **cname,
char **cnameu, char **cnamel);
#endif

1094
src/bin/eolian/sources.c Normal file

File diff suppressed because it is too large Load Diff

9
src/bin/eolian/sources.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef EOLIAN_GEN_SOURCES_H
#define EOLIAN_GEN_SOURCES_H
#include "main.h"
void eo_gen_source_gen(const Eolian_Class *cl, Eina_Strbuf *buf);
void eo_gen_impl_gen(const Eolian_Class *cl, Eina_Strbuf *buf);
#endif

191
src/bin/eolian/types.c Normal file
View File

@ -0,0 +1,191 @@
#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;
}

8
src/bin/eolian/types.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef EOLIAN_GEN_TYPES_H
#define EOLIAN_GEN_TYPES_H
void eo_gen_types_header_gen(const char *eof, Eina_Strbuf *buf,
Eina_Bool full, Eina_Bool legacy);
Eina_Strbuf *eo_gen_class_typedef_gen(const char *eof);
#endif

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

View File

@ -11,9 +11,9 @@ void _class_simple_b_set(Eo *obj, Evas_Simple_Data *pd);
EOAPI EFL_VOID_FUNC_BODY(efl_canvas_object_simple_b_set);
char * _class_simple_foo(Eo *obj, Evas_Simple_Data *pd, int a, char *b, double *c, int *d);
char *_class_simple_foo(Eo *obj, Evas_Simple_Data *pd, int a, char *b, double *c, int *d);
static char * __eolian_class_simple_foo(Eo *obj, Evas_Simple_Data *pd, int a, char *b, double *c, int *d)
static char *__eolian_class_simple_foo(Eo *obj, Evas_Simple_Data *pd, int a, char *b, double *c, int *d)
{
if (c) *c = 1337.600000;
return _class_simple_foo(obj, pd, a, b, c, d);
@ -21,7 +21,7 @@ static char * __eolian_class_simple_foo(Eo *obj, Evas_Simple_Data *pd, int a, ch
EOAPI EFL_FUNC_BODYV(efl_canvas_object_simple_foo, char *, NULL, EFL_FUNC_CALL(a, b, c, d), int a, char *b, double *c, int *d);
int * _class_simple_bar(Eo *obj, Evas_Simple_Data *pd, int x);
int *_class_simple_bar(Eo *obj, Evas_Simple_Data *pd, int x);
EOAPI EFL_FUNC_BODYV(efl_canvas_object_simple_bar, int *, 0, EFL_FUNC_CALL(x), int x);
@ -31,20 +31,33 @@ _class_simple_class_initializer(Efl_Class *klass)
EFL_OPS_DEFINE(ops,
EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_a_set, _class_simple_a_set),
EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_a_get, _class_simple_a_get),
EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_foo, __eolian_class_simple_foo)
EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_b_set, _class_simple_b_set),
EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_foo, __eolian_class_simple_foo),
EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_bar, _class_simple_bar)
);
return efl_class_functions_set(klass, &ops, NULL);
}
static const Efl_Class_Description _class_simple_class_desc = {
EO_VERSION,
"Class_Simple",
EFL_CLASS_TYPE_REGULAR,
sizeof(Evas_Simple_Data),
_class_simple_class_initializer,
NULL,
NULL
EO_VERSION,
"Class_Simple",
EFL_CLASS_TYPE_REGULAR,
sizeof(Evas_Simple_Data),
_class_simple_class_initializer,
NULL,
NULL
};
EFL_DEFINE_CLASS(class_simple_class_get, &_class_simple_class_desc, NULL, NULL);
EAPI void
evas_object_simple_b_set(Class_Simple *obj)
{
efl_canvas_object_simple_b_set(obj);
}
EAPI int *
evas_object_simple_bar(Class_Simple *obj, int x)
{
return efl_canvas_object_simple_bar(obj, x);
}

View File

@ -1,5 +1,5 @@
#ifndef _EOLIAN_OUTPUT_H_
#define _EOLIAN_OUTPUT_H_
#ifndef _EOLIAN_CLASS_SIMPLE_H_
#define _EOLIAN_CLASS_SIMPLE_H_
#ifndef _CLASS_SIMPLE_EO_CLASS_TYPE
#define _CLASS_SIMPLE_EO_CLASS_TYPE
@ -67,5 +67,4 @@ EOAPI char *efl_canvas_object_simple_foo(Eo *obj, int a, char *b, double *c, int
EOAPI int *efl_canvas_object_simple_bar(Eo *obj, int x);
#endif

View File

@ -1,5 +1,5 @@
#ifndef _EOLIAN_OUTPUT_H_
#define _EOLIAN_OUTPUT_H_
#ifndef _EOLIAN_CLASS_SIMPLE_LEGACY_H_
#define _EOLIAN_CLASS_SIMPLE_LEGACY_H_
#ifndef _CLASS_SIMPLE_EO_CLASS_TYPE
#define _CLASS_SIMPLE_EO_CLASS_TYPE
@ -13,11 +13,9 @@ typedef Eo Class_Simple;
#endif
/** Class Desc Simple
*
* @ingroup Class_Simple
*/
EAPI void evas_object_simple_b_set(Class_Simple *obj);
EAPI int *evas_object_simple_bar(Class_Simple *obj, int x);
#endif

View File

@ -1,5 +1,5 @@
#ifndef _EOLIAN_OUTPUT_H_
#define _EOLIAN_OUTPUT_H_
#ifndef _EOLIAN_DOCS_H_
#define _EOLIAN_DOCS_H_
#ifndef _DOCS_EO_CLASS_TYPE
#define _DOCS_EO_CLASS_TYPE

View File

@ -1,5 +1,5 @@
#ifndef _EOLIAN_OUTPUT_H_
#define _EOLIAN_OUTPUT_H_
#ifndef _EOLIAN_DOCS_LEGACY_H_
#define _EOLIAN_DOCS_LEGACY_H_
#ifndef _DOCS_EO_CLASS_TYPE
#define _DOCS_EO_CLASS_TYPE
@ -64,17 +64,6 @@ typedef struct _Opaque Opaque;
#endif
/**
* @brief Docs for class.
*
* More docs for class. Testing references now. @ref Foo @ref Bar @ref Alias
* @ref pants @ref docs_meth @ref docs_prop_get @ref docs_prop_get
* @ref docs_prop_set @ref Foo.field1 @ref Bar.BAR_FOO @ref Docs
*
* @since 1.18
*
* @ingroup Docs
*/
/**
* @brief Property common documentation.

View File

@ -1,4 +1,7 @@
void _override_base_constructor(Eo *obj, Override_Data *pd);
static void __eolian_override_b_set(Eo *obj EINA_UNUSED, Override_Data *pd, int idx EINA_UNUSED, float a, char b, int c)
{
a = pd->a;
@ -22,6 +25,19 @@ static int __eolian_override_c_get(Eo *obj EINA_UNUSED, Override_Data *pd EINA_U
}
EOAPI EFL_FUNC_BODYV_CONST(override_c_get, int, 50, EFL_FUNC_CALL(idx), int idx);
static void __eolian_override_base_z_get(Eo *obj EINA_UNUSED, Override_Data *pd, int *a, char *b, float *c)
{
if (a) *a = pd->a;
if (b) *b = pd->b;
if (c) *c = pd->c;
}
static void __eolian_override_base_z_set(Eo *obj EINA_UNUSED, Override_Data *pd EINA_UNUSED, int a EINA_UNUSED, char b EINA_UNUSED, float c EINA_UNUSED)
{
}
EOAPI EFL_VOID_FUNC_BODY(override_a_set);
void _override_a_get(Eo *obj, Override_Data *pd);
@ -37,50 +53,33 @@ void _override_c_set(Eo *obj, Override_Data *pd, int idx, int c);
EOAPI EFL_VOID_FUNC_BODYV(override_c_set, EFL_FUNC_CALL(idx, c), int idx, int c);
EOAPI EFL_VOID_FUNC_BODY(override_foo);
void _override_base_constructor(Eo *obj, Override_Data *pd);
static void __eolian_override_base_z_get(Eo *obj EINA_UNUSED, Override_Data *pd, int *a, char *b, float *c)
{
if (a) *a = pd->a;
if (b) *b = pd->b;
if (c) *c = pd->c;
}
static void __eolian_override_base_z_set(Eo *obj EINA_UNUSED, Override_Data *pd EINA_UNUSED, int a EINA_UNUSED, char b EINA_UNUSED, float c EINA_UNUSED)
{
}
static Eina_Bool
_override_class_initializer(Efl_Class *klass)
{
EFL_OPS_DEFINE(ops,
EFL_OBJECT_OP_FUNC(base_constructor, _override_base_constructor),
EFL_OBJECT_OP_FUNC(base_z_get, __eolian_override_base_z_get),
EFL_OBJECT_OP_FUNC(base_z_set, __eolian_override_base_z_set),
EFL_OBJECT_OP_FUNC(override_b_set, __eolian_override_b_set),
EFL_OBJECT_OP_FUNC(override_bar, __eolian_override_bar),
EFL_OBJECT_OP_FUNC(override_c_get, __eolian_override_c_get),
EFL_OBJECT_OP_FUNC(base_z_get, __eolian_override_base_z_get),
EFL_OBJECT_OP_FUNC(base_z_set, __eolian_override_base_z_set),
EFL_OBJECT_OP_FUNC(override_a_set, NULL),
EFL_OBJECT_OP_FUNC(override_a_get, _override_a_get),
EFL_OBJECT_OP_FUNC(override_b_get, _override_b_get),
EFL_OBJECT_OP_FUNC(override_c_set, _override_c_set),
EFL_OBJECT_OP_FUNC(override_foo, NULL)
);
return efl_class_functions_set(klass, &ops, NULL);
}
static const Efl_Class_Description _override_class_desc = {
EO_VERSION,
"Override",
EFL_CLASS_TYPE_REGULAR,
sizeof(Override_Data),
_override_class_initializer,
NULL,
NULL
EO_VERSION,
"Override",
EFL_CLASS_TYPE_REGULAR,
sizeof(Override_Data),
_override_class_initializer,
NULL,
NULL
};
EFL_DEFINE_CLASS(override_class_get, &_override_class_desc, BASE_CLASS, NULL);

View File

@ -1,5 +1,5 @@
#ifndef _TYPES_OUTPUT_C_
#define _TYPES_OUTPUT_C_
#ifndef _EOLIAN_TYPEDEF_H_
#define _EOLIAN_TYPEDEF_H_
#ifndef _STRUCT_EO_CLASS_TYPE
#define _STRUCT_EO_CLASS_TYPE
@ -43,5 +43,4 @@ EOAPI char *struct_foo(Eo *obj, int idx);
EOAPI Named *struct_bar(Eo *obj);
#endif

View File

@ -1,5 +1,5 @@
#ifndef _TYPES_OUTPUT_C_STUBS
#define _TYPES_OUTPUT_C_STUBS
#ifndef _EOLIAN_TYPEDEF_STUB_H_STUBS
#define _EOLIAN_TYPEDEF_STUB_H_STUBS
typedef Eo Struct;

View File

@ -20,7 +20,7 @@ enum Enum.Bar
last_item
}
enum Elm.Object.Select_mode
enum Elm.Object.Select_Mode
{
default = 0,
always,

View File

@ -1,5 +1,5 @@
#ifndef _TYPES_OUTPUT_C_
#define _TYPES_OUTPUT_C_
#ifndef _EOLIAN_TYPEDEF_H_
#define _EOLIAN_TYPEDEF_H_
#ifndef _TYPEDEF_EO_CLASS_TYPE
#define _TYPEDEF_EO_CLASS_TYPE
@ -47,5 +47,4 @@ EWAPI const Efl_Class *typedef_class_get(void);
EOAPI char *typedef_foo(Eo *obj, int idx);
#endif

View File

@ -1,5 +1,5 @@
#ifndef _TYPES_OUTPUT_C_STUBS
#define _TYPES_OUTPUT_C_STUBS
#ifndef _EOLIAN_TYPEDEF_STUB_H_STUBS
#define _EOLIAN_TYPEDEF_STUB_H_STUBS
typedef Eo Typedef;

View File

@ -15,17 +15,20 @@
#include "eolian_suite.h"
static Eina_Bool
_files_compare (const char *ref_filename, const char *tmp_filename)
_files_compare (const char *ref_filename, const char *tmp_filename, const char *ext)
{
Eina_Bool result = EINA_FALSE;
FILE *tmp_file = NULL, *ref_file = NULL;
char *tmp_content = NULL, *ref_content = NULL;
tmp_file = fopen(tmp_filename, "rb");
char ifnbuf[PATH_MAX];
snprintf(ifnbuf, sizeof(ifnbuf), "%s.%s", tmp_filename, ext);
tmp_file = fopen(ifnbuf, "rb");
if (!tmp_file)
{
printf("Unable to open %s\n", tmp_filename);
printf("Unable to open %s\n", ifnbuf);
goto end;
}
ref_file = fopen(ref_filename, "rb");
@ -69,6 +72,14 @@ end:
return result;
}
static void
_remove_ref(const char *base, const char *ext)
{
char ifnbuf[PATH_MAX];
snprintf(ifnbuf, sizeof(ifnbuf), "%s.%s", base, ext);
remove(ifnbuf);
}
static int
_eolian_gen_execute(const char *eo_filename, const char *options, const char *output_filename)
{
@ -85,7 +96,7 @@ _eolian_gen_execute(const char *eo_filename, const char *options, const char *ou
return -1;
snprintf(command, PATH_MAX,
"%s %s -I "PACKAGE_DATA_DIR"/data -o %s %s",
"%s %s -I \""PACKAGE_DATA_DIR"/data\" -o %s %s",
eolian_gen_path, options, output_filename, eo_filename);
return system(command);
}
@ -93,96 +104,96 @@ _eolian_gen_execute(const char *eo_filename, const char *options, const char *ou
START_TEST(eolian_dev_impl_code)
{
char output_filepath[PATH_MAX] = "";
snprintf(output_filepath, PATH_MAX, "%s/object_impl.c",
snprintf(output_filepath, PATH_MAX, "%s/eolian_object_impl",
eina_environment_tmp_get());
remove(output_filepath);
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/object_impl.eo", "--gi", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/object_impl_ref.c", output_filepath));
_remove_ref(output_filepath, "c");
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/object_impl.eo", "-gi", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/object_impl_ref.c", output_filepath, "c"));
/* Check that nothing is added */
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/object_impl.eo", "--gi", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/object_impl_ref.c", output_filepath));
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/object_impl_add.eo", "--gi", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/object_impl_add_ref.c", output_filepath));
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/object_impl.eo", "-gi", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/object_impl_ref.c", output_filepath, "c"));
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/object_impl_add.eo", "-gi", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/object_impl_add_ref.c", output_filepath, "c"));
}
END_TEST
START_TEST(eolian_types_generation)
{
char output_filepath[PATH_MAX] = "";
snprintf(output_filepath, PATH_MAX, "%s/types_output.c",
snprintf(output_filepath, PATH_MAX, "%s/eolian_typedef",
eina_environment_tmp_get());
remove(output_filepath);
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/typedef.eo", "--gh", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/typedef_ref.c", output_filepath));
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/struct.eo", "--gh", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/struct_ref.c", output_filepath));
_remove_ref(output_filepath, "h");
_remove_ref(output_filepath, "stub.h");
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/typedef.eo", "-gh", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/typedef_ref.c", output_filepath, "h"));
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/struct.eo", "-gh", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/struct_ref.c", output_filepath, "h"));
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/typedef.eo", "--gs", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/typedef_ref_stub.c", output_filepath));
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/struct.eo", "--gs", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/struct_ref_stub.c", output_filepath));
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/typedef.eo", "-gs", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/typedef_ref_stub.c", output_filepath, "stub.h"));
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/struct.eo", "-gs", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/struct_ref_stub.c", output_filepath, "stub.h"));
}
END_TEST
START_TEST(eolian_default_values_generation)
{
char output_filepath[PATH_MAX] = "";
snprintf(output_filepath, PATH_MAX, "%s/eolian_output.c",
snprintf(output_filepath, PATH_MAX, "%s/eolian_class_simple",
eina_environment_tmp_get());
remove(output_filepath);
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/class_simple.eo", "--gc", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/class_simple_ref.c", output_filepath));
_remove_ref(output_filepath, "c");
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/class_simple.eo", "-gc", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/class_simple_ref.c", output_filepath, "c"));
}
END_TEST
START_TEST(eolian_override_generation)
{
char output_filepath[PATH_MAX] = "";
snprintf(output_filepath, PATH_MAX, "%s/eolian_output.c",
snprintf(output_filepath, PATH_MAX, "%s/eolian_override",
eina_environment_tmp_get());
remove(output_filepath);
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/override.eo", "--gc", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/override_ref.c", output_filepath));
_remove_ref(output_filepath, "c");
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/override.eo", "-gc", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/override_ref.c", output_filepath, "c"));
}
END_TEST
START_TEST(eolian_functions_descriptions)
{
char output_filepath[PATH_MAX] = "";
snprintf(output_filepath, PATH_MAX, "%s/eolian_output.h",
snprintf(output_filepath, PATH_MAX, "%s/eolian_class_simple",
eina_environment_tmp_get());
remove(output_filepath);
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/class_simple.eo", "--gh", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/class_simple_ref_eo.h", output_filepath));
remove(output_filepath);
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/class_simple.eo", "--legacy --gh", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/class_simple_ref_legacy.h", output_filepath));
_remove_ref(output_filepath, "h");
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/class_simple.eo", "-gh", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/class_simple_ref_eo.h", output_filepath, "h"));
_remove_ref(output_filepath, "legacy.h");
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/class_simple.eo", "-gl", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/class_simple_ref_legacy.h", output_filepath, "legacy.h"));
}
END_TEST
START_TEST(eolian_import)
{
char output_filepath[PATH_MAX] = "";
snprintf(output_filepath, PATH_MAX, "%s/eolian_import_types.h",
snprintf(output_filepath, PATH_MAX, "%s/eolian_import_types",
eina_environment_tmp_get());
remove(output_filepath);
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/import_types.eot", "--gh", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/import_types_ref.h", output_filepath));
remove(output_filepath);
_remove_ref(output_filepath, "h");
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/import_types.eot", "-gh", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/import_types_ref.h", output_filepath, "h"));
}
END_TEST
START_TEST(eolian_docs)
{
char output_filepath[PATH_MAX] = "";
snprintf(output_filepath, PATH_MAX, "%s/eolian_output.h",
snprintf(output_filepath, PATH_MAX, "%s/eolian_docs",
eina_environment_tmp_get());
remove(output_filepath);
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/docs.eo", "--gh", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/docs_ref.h", output_filepath));
remove(output_filepath);
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/docs.eo", "--legacy --gh", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/docs_ref_legacy.h", output_filepath));
_remove_ref(output_filepath, "h");
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/docs.eo", "-gh", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/docs_ref.h", output_filepath, "h"));
_remove_ref(output_filepath, "legacy.h");
fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/docs.eo", "-gl", output_filepath));
fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/docs_ref_legacy.h", output_filepath, "legacy.h"));
}
END_TEST