Eolian: first import.

Imported by Tom, from the eolian repo which was written by:
Daniel Zaoui <daniel.zaoui@samsung.com>
Yakov Goldberg <yakov.g@samsung.com>
Yossi Kantor <yossi.kantor@samsung.com>
Savio Sena <savio@expertisesolutions.com.br>
Jérémy Zurcher <jeremy@asynk.ch>

Signed-off-by: Tom Hacohen <tom@stosb.com>
This commit is contained in:
Daniel Zaoui 2014-02-11 13:42:59 +00:00
parent 92a24dea79
commit 5dea8ee0a8
17 changed files with 7816 additions and 0 deletions

11
pc/eolian.pc.in Normal file
View File

@ -0,0 +1,11 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: Eolian
Description: EFL's .eo parser and code generator.
Version: @LIB_VERSION@
Libs: -L${libdir} -leolian
Libs.private:
Cflags: -I${includedir}/eolian-1

View File

@ -0,0 +1,73 @@
#include "common_funcs.h"
void
_template_fill(Eina_Strbuf *buf, const char* templ, const char* classname, const char *funcname, Eina_Bool reset)
{
static char capobjclass[0xFF];
static char lowobjclass[0xFF];
static char capclass[0xFF];
static char lowclass[0xFF];
static char normclass[0xFF];
static char capfunc[0xFF];
static char eoprefix[0xFF];
char *p;
if (reset) eina_strbuf_reset(buf);
if (templ) eina_strbuf_append(buf, templ);
if (strcmp(classname, normclass))
{
//Fill cache
strcpy(normclass, classname);
strcpy(capclass, classname);
p = capclass;
eina_str_toupper(&p);
strcpy(lowclass, classname);
p = lowclass;
eina_str_tolower(&p);
Eina_Strbuf *classobj = eina_strbuf_new();
eina_strbuf_append(classobj, classname);
// More to exclusion list
if (strcmp(classname, "Eo_Base") && strcmp(classname, "Elm_Widget"))
eina_strbuf_replace(classobj, "_", "_obj_", 1);
if (!strcmp(classname, "Evas_Object"))
{
eina_strbuf_reset(classobj);
eina_strbuf_append(classobj, "Evas_Obj");
}
strcpy(capobjclass, eina_strbuf_string_get(classobj));
p = capobjclass;
eina_str_toupper(&p);
strcpy(lowobjclass, eina_strbuf_string_get(classobj));
p = lowobjclass;
eina_str_tolower(&p);
strcpy(eoprefix, lowobjclass);
if (!strcmp(classname, "Elm_Widget"))
strcpy(eoprefix, "elm_wdg");
eina_strbuf_free(classobj);
}
strcpy(capfunc, funcname);
p = capfunc; eina_str_toupper(&p);
eina_strbuf_replace_all(buf, "@#func", funcname);
eina_strbuf_replace_all(buf, "@#FUNC", capfunc);
eina_strbuf_replace_all(buf, "@#Class", classname);
eina_strbuf_replace_all(buf, "@#class", lowclass);
eina_strbuf_replace_all(buf, "@#CLASS", capclass);
eina_strbuf_replace_all(buf, "@#OBJCLASS", capobjclass);
eina_strbuf_replace_all(buf, "@#objclass", lowobjclass);
eina_strbuf_replace_all(buf, "@#eoprefix", eoprefix);
}

View File

@ -0,0 +1,8 @@
#ifndef __EOLIAN_COMMON_FUNCS_H
#define __EOLIAN_COMMON_FUNCS_H
#include <Eina.h>
void _template_fill(Eina_Strbuf *buf, const char* templ, const char* classname, const char *funcname, Eina_Bool reset);
#endif

View File

@ -0,0 +1,667 @@
#include <Eina.h>
#include <string.h>
#include "Eolian.h"
#include "eo1_generator.h"
#include "common_funcs.h"
static const char
tmpl_eo_src_begin[] = "\
EAPI Eo_Op @#OBJCLASS_BASE_ID = EO_NOOP;\n\
\n\
@#list_events\n\
\n\
";
static const char
tmpl_eo_src_end[] = "\
@#list_ctors_body\
\n\
static void\n\
_@#class_class_constructor(Eo_Class *klass)\n\
{\n\
const Eo_Op_Func_Description func_desc[] = {@#list_func\n\
EO_OP_FUNC_SENTINEL\n\
};\n\
eo_class_funcs_set(klass, func_desc);\n\
_user_@#class_class_constructor(klass);\n\
}\n\
\n\
static const Eo_Op_Description @#class_op_desc[] = {@#list_op\n\
EO_OP_DESCRIPTION_SENTINEL\n\
};\n\
\n\
static const Eo_Event_Description *@#class_event_desc[] = {@#list_evdesc\n\
NULL\n\
};\n\
\n\
static const Eo_Class_Description @#class_class_desc = {\n\
EO_VERSION,\n\
\"@#Class\",\n\
EO_CLASS_TYPE_REGULAR,\n\
EO_CLASS_DESCRIPTION_OPS(&@#OBJCLASS_BASE_ID, @#class_op_desc, @#OBJCLASS_SUB_ID_LAST),\n\
@#class_event_desc,\n\
sizeof(@#Class_Data),\n\
_@#class_class_constructor,\n\
NULL\n\
};\n\
\n\
EO_DEFINE_CLASS(@#objclass_class_get, &@#class_class_desc, @#list_inheritNULL);\
";
static const char
tmpl_eo_op_desc[] = "\n EO_OP_DESCRIPTION(@#OBJCLASS_SUB_ID_@#FUNC, \"@#desc\"),";
static const char
tmpl_eo_func_desc[] = "\n EO_OP_FUNC(@#OBJCLASS_ID(@#OBJCLASS_SUB_ID_@#FUNC), _eo_obj_@#class_@#func),";
static const char
tmpl_eobase_func_desc[] = "\n EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_@#FUNC), _eo_obj_@#class_@#func),";
static const char
tmpl_eo_header[] = "\
#define @#OBJCLASS_CLASS @#objclass_class_get()\n\
\n\
const Eo_Class *@#objclass_class_get(void) EINA_CONST;\n\
\n\
extern EAPI Eo_Op @#OBJCLASS_BASE_ID;\n\
\n\
enum\n\
{@#list_subid\n\
@#OBJCLASS_SUB_ID_LAST\n\
};\n\
\n\
#define @#OBJCLASS_ID(sub_id) (@#OBJCLASS_BASE_ID + sub_id)\n\
";
static const char
tmpl_eo_subid[] = "\n @#OBJCLASS_SUB_ID_@#FUNC,";
static const char
tmpl_eo_subid_apnd[] = " @#OBJCLASS_SUB_ID_@#FUNC,\n";
static const char
tmpl_eo_funcdef[] = "\n\
/**\n\
* @def @#objclass_@#func\n\
*\n\
@#desc\n\
*\n\
@#list_desc_param\
*\n\
*/\n\
#define @#eoprefix_@#func(@#list_param) @#OBJCLASS_ID(@#OBJCLASS_SUB_ID_@#FUNC) @#list_typecheck\n\
";
static const char
tmpl_eo_pardesc[] =" * @param[%s] %s\n";
static const char
tmpl_eobind_body[] ="\
\n\
@#ret_type _@#class_@#func(Eo *obj@#full_params);\n\n\
static void\n\
_eo_obj_@#class_@#func(Eo *obj, void *_pd EINA_UNUSED, va_list *list@#list_unused)\n\
{\n\
@#list_vars\
@#ret_param_@#class_@#func(obj@#list_params);\n\
}\n\
";
char *
_first_line_get(const char *str)
{
Eina_Strbuf *ret = eina_strbuf_new();
if (str)
{
const char *p = strchr(str, '\n');
size_t offs = (p) ? (size_t)(p - str) : strlen(str);
eina_strbuf_append_n(ret, str, offs);
}
return eina_strbuf_string_steal(ret);
}
Eina_Bool
eo1_enum_append(const char *classname, const char *funcname, Eina_Strbuf *str)
{
_template_fill(str, tmpl_eo_subid_apnd, classname, funcname, EINA_FALSE);
return EINA_TRUE;
}
Eina_Bool
eo1_fundef_generate(const char *classname, Eolian_Function func, Eolian_Function_Type ftype, Eina_Strbuf *functext)
{
const char *str_dir[] = {"in", "out", "inout"};
const Eina_List *l;
void *data;
char funcname[0xFF];
char descname[0xFF];
char *fsuffix = "";
if (ftype == GET) fsuffix = "_get";
if (ftype == SET) fsuffix = "_set";
sprintf (funcname, "%s%s", eolian_function_name_get(func), fsuffix);
sprintf (descname, "comment%s", fsuffix);
const char *funcdesc = eolian_function_description_get(func, descname);
Eina_Strbuf *str_func = eina_strbuf_new();
_template_fill(str_func, tmpl_eo_funcdef, classname, funcname, EINA_TRUE);
Eina_Strbuf *linedesc = eina_strbuf_new();
eina_strbuf_append(linedesc, funcdesc ? funcdesc : "");
if (eina_strbuf_length_get(linedesc))
{
eina_strbuf_replace_all(linedesc, "\n", "\n * ");
eina_strbuf_prepend(linedesc," * ");
}
eina_strbuf_replace_all(str_func, "@#desc", eina_strbuf_string_get(linedesc));
eina_strbuf_free(linedesc);
Eina_Strbuf *str_par = eina_strbuf_new();
Eina_Strbuf *str_pardesc = eina_strbuf_new();
Eina_Strbuf *str_typecheck = eina_strbuf_new();
const char* rettype = eolian_function_return_type_get(func, ftype);
if (rettype && strcmp(rettype, "void"))
{
eina_strbuf_append_printf(str_pardesc, tmpl_eo_pardesc, "out", "ret");
eina_strbuf_append(str_par, "ret");
eina_strbuf_append_printf(str_typecheck, ", EO_TYPECHECK(%s*, ret)", rettype);
}
EINA_LIST_FOREACH(eolian_parameters_list_get(func), l, data)
{
const char *pname;
const char *ptype;
Eolian_Parameter_Dir pdir;
eolian_parameter_information_get((Eolian_Function_Parameter)data, &pdir, &ptype, &pname, NULL);
if (ftype == GET) pdir = EOLIAN_OUT_PARAM;
if (ftype == SET) pdir = EOLIAN_IN_PARAM;
char *umpr = (pdir == EOLIAN_IN_PARAM) ? "" : "*";
const char *dir_str = str_dir[(int)pdir];
eina_strbuf_append_printf(str_pardesc, tmpl_eo_pardesc, dir_str, pname);
if (eina_strbuf_length_get(str_par)) eina_strbuf_append(str_par, ", ");
eina_strbuf_append(str_par, pname);
eina_strbuf_append_printf(str_typecheck, ", EO_TYPECHECK(%s%s, %s)", ptype, umpr, pname);
}
eina_strbuf_replace_all(str_func, "@#list_param", eina_strbuf_string_get(str_par));
eina_strbuf_replace_all(str_func, "@#list_desc_param", eina_strbuf_string_get(str_pardesc));
eina_strbuf_replace_all(str_func, "@#list_typecheck", eina_strbuf_string_get(str_typecheck));
eina_strbuf_free(str_par);
eina_strbuf_free(str_pardesc);
eina_strbuf_free(str_typecheck);
eina_strbuf_append(functext, eina_strbuf_string_get(str_func));
eina_strbuf_free(str_func);
return EINA_TRUE;
}
Eina_Bool
eo1_header_generate(const char *classname, Eina_Strbuf *buf)
{
const Eolian_Function_Type ftype_order[] = {CONSTRUCTOR, PROPERTY_FUNC, METHOD_FUNC};
const Eina_List *l;
void *data;
char tmpstr[0x1FF];
if (!eolian_class_exists(classname))
{
printf ("Class \"%s\" not found in database\n", classname);
return EINA_FALSE;
}
Eina_Strbuf * str_hdr = eina_strbuf_new();
_template_fill(str_hdr, tmpl_eo_header, classname, "", EINA_TRUE);
Eina_Strbuf *str_subid = eina_strbuf_new();
Eina_Strbuf *str_ev = eina_strbuf_new();
Eina_Strbuf *tmpbuf = eina_strbuf_new();
Eolian_Event event;
EINA_LIST_FOREACH(eolian_class_events_list_get(classname), l, event)
{
const char *evname;
const char *evdesc;
eolian_class_event_information_get(event, &evname, &evdesc);
eina_strbuf_reset(tmpbuf);
eina_strbuf_append(tmpbuf, evdesc);
eina_strbuf_replace_all(tmpbuf, "\n", "\n * ");
eina_strbuf_prepend(tmpbuf," * ");
eina_strbuf_append_printf(str_ev, "\n/**\n%s\n */\n", eina_strbuf_string_get(tmpbuf));
_template_fill(tmpbuf, "@#CLASS_@#FUNC", classname, evname, EINA_TRUE);
eina_strbuf_replace_all(tmpbuf, ",", "_");
const char* s = eina_strbuf_string_get(tmpbuf);
eina_strbuf_append_printf(str_ev, "#define %s (&(_%s))\n", s, s);
}
int i;
for (i = 0; i < 3; i++)
EINA_LIST_FOREACH(eolian_class_functions_list_get(classname, ftype_order[i]), l, data)
{
const Eolian_Function_Type ftype = eolian_function_type_get((Eolian_Function)data);
const char *funcname = eolian_function_name_get((Eolian_Function)data);
Eina_Bool prop_read = (ftype == PROPERTY_FUNC || ftype == GET ) ? EINA_TRUE : EINA_FALSE ;
Eina_Bool prop_write = (ftype == PROPERTY_FUNC || ftype == SET ) ? EINA_TRUE : EINA_FALSE ;
if (!prop_read && !prop_write)
{
_template_fill(str_subid, tmpl_eo_subid, classname, funcname, EINA_FALSE);
eo1_fundef_generate(classname, (Eolian_Function)data, UNRESOLVED, str_hdr);
}
if (prop_read)
{
sprintf(tmpstr, "%s_get", funcname);
_template_fill(str_subid, tmpl_eo_subid, classname, tmpstr, EINA_FALSE);
eo1_fundef_generate(classname, (Eolian_Function)data, GET, str_hdr);
}
if (prop_write)
{
sprintf(tmpstr, "%s_set", funcname);
_template_fill(str_subid, tmpl_eo_subid, classname, tmpstr, EINA_FALSE);
eo1_fundef_generate(classname, (Eolian_Function)data, SET, str_hdr);
}
}
eina_strbuf_replace_all(str_hdr, "@#list_subid", eina_strbuf_string_get(str_subid));
eina_strbuf_append(str_hdr, eina_strbuf_string_get(str_ev));
eina_strbuf_free(str_subid);
eina_strbuf_free(str_ev);
eina_strbuf_free(tmpbuf);
eina_strbuf_append(buf, eina_strbuf_string_get(str_hdr));
return EINA_TRUE;
}
static const char*
_varg_upgr(const char *stype)
{
if (!strcmp(stype, "Eina_Bool") ||
!strcmp(stype, "char") ||
!strcmp(stype, "short"))
return "int";
return stype;
}
Eina_Bool
eo1_bind_func_generate(const char *classname, Eolian_Function funcid, Eolian_Function_Type ftype, Eina_Strbuf *buf)
{
const char *suffix = "";
const char *umpr = NULL;
Eina_Bool var_as_ret = EINA_FALSE;
const char *rettype = NULL;
const char *retname = NULL;
Eina_Bool ret_const = EINA_FALSE;
Eina_Strbuf *fbody = eina_strbuf_new();
Eina_Strbuf *va_args = eina_strbuf_new();
Eina_Strbuf *params = eina_strbuf_new(); /* only variables names */
Eina_Strbuf *full_params = eina_strbuf_new(); /* variables types + names */
rettype = eolian_function_return_type_get(funcid, ftype);
if (rettype && !strcmp(rettype, "void")) rettype = NULL;
retname = "ret";
if (ftype == GET)
{
suffix = "_get";
umpr = "*";
if (!rettype)
{
const Eina_List *l = eolian_parameters_list_get(funcid);
if (eina_list_count(l) == 1)
{
void* data = eina_list_data_get(l);
eolian_parameter_information_get((Eolian_Function_Parameter)data, NULL, &rettype, &retname, NULL);
var_as_ret = EINA_TRUE;
ret_const = eolian_parameter_get_const_attribute_get(data);
}
}
}
if (ftype == SET)
{
suffix = "_set";
umpr = "";
}
char tmpstr[0xFF];
sprintf (tmpstr, "%s%s", eolian_function_name_get(funcid), suffix);
_template_fill(fbody, tmpl_eobind_body, classname, tmpstr, EINA_FALSE);
const Eina_List *l;
void *data;
if (!var_as_ret)
{
EINA_LIST_FOREACH(eolian_parameters_list_get(funcid), l, data)
{
const char *pname;
const char *ptype;
Eolian_Parameter_Dir pdir;
eolian_parameter_information_get((Eolian_Function_Parameter)data, &pdir, &ptype, &pname, NULL);
const char *ptrstr = (umpr) ? umpr : ( (pdir == EOLIAN_IN_PARAM) ? "" : " *" );
Eina_Bool is_const = eolian_parameter_get_const_attribute_get(data);
eina_strbuf_append_printf(va_args, " %s%s %s%s = va_arg(*list, %s%s%s);\n",
ftype == GET && is_const?"const ":"", ptype, ptrstr, pname,
ftype == GET && is_const?"const ":"", (*ptrstr) ? ptype : _varg_upgr(ptype), ptrstr);
eina_strbuf_append_printf(params, ", %s", pname);
eina_strbuf_append_printf(full_params, ", %s%s%s %s",
ftype == GET && eolian_parameter_get_const_attribute_get(data)?"const ":"",
ptype, ptrstr, pname);
}
}
if (rettype && strcmp(rettype, "void"))
{
eina_strbuf_append_printf(va_args, " %s%s *%s = va_arg(*list, %s%s *);\n",
ret_const?"const ":"",
rettype, retname,
ret_const?"const ":"",
rettype);
Eina_Strbuf *ret_param = eina_strbuf_new();
eina_strbuf_append_printf(ret_param, "*%s = ", retname);
eina_strbuf_replace_all(fbody, "@#ret_param", eina_strbuf_string_get(ret_param));
sprintf(tmpstr, "%s%s", ret_const?"const ":"", rettype);
eina_strbuf_replace_all(fbody, "@#ret_type", tmpstr);
eina_strbuf_free(ret_param);
}
else
{
eina_strbuf_replace_all(fbody, "@#ret_param", "");
eina_strbuf_replace_all(fbody, "@#ret_type", "void");
}
if (eina_list_count(eolian_parameters_list_get(funcid)) == 0)
{
eina_strbuf_replace_all(fbody, "@#list_unused", " EINA_UNUSED");
}
else
{
eina_strbuf_replace_all(fbody, "@#list_unused", "");
}
eina_strbuf_replace_all(fbody, "@#list_vars", eina_strbuf_string_get(va_args));
eina_strbuf_replace_all(fbody, "@#full_params", eina_strbuf_string_get(full_params));
eina_strbuf_replace_all(fbody, "@#list_params", eina_strbuf_string_get(params));
eina_strbuf_append(buf, eina_strbuf_string_get(fbody));
eina_strbuf_free(va_args);
eina_strbuf_free(full_params);
eina_strbuf_free(params);
eina_strbuf_free(fbody);
return EINA_TRUE;
}
Eina_Bool
eo1_eo_func_desc_generate(const char *classname, const char *funcname, Eina_Strbuf *buf)
{
_template_fill(buf, tmpl_eo_func_desc, classname, funcname, EINA_TRUE);
return EINA_TRUE;
}
Eina_Bool
eo1_eo_op_desc_generate(const char *classname, const char *funcname, Eina_Strbuf *buf)
{
_template_fill(buf, tmpl_eo_op_desc, classname, funcname, EINA_TRUE);
return EINA_TRUE;
}
Eina_Bool
eo1_source_beginning_generate(const char *classname, Eina_Strbuf *buf)
{
const Eina_List *itr;
Eina_Strbuf *tmpbuf = eina_strbuf_new();
Eina_Strbuf *str_begin = eina_strbuf_new();
Eina_Strbuf *str_ev = eina_strbuf_new();
_template_fill(str_begin, tmpl_eo_src_begin, classname, "", EINA_TRUE);
Eolian_Event event;
EINA_LIST_FOREACH(eolian_class_events_list_get(classname), itr, event)
{
const char *evname;
const char *evdesc;
char *evdesc_line1;
eolian_class_event_information_get(event, &evname, &evdesc);
evdesc_line1 = _first_line_get(evdesc);
_template_fill(str_ev, "@#CLASS_@#FUNC", classname, evname, EINA_TRUE);
eina_strbuf_replace_all(str_ev, ",", "_");
eina_strbuf_append_printf(tmpbuf,
"EAPI const Eo_Event_Description _%s = EO_EVENT_DESCRIPTION(\"%s\", \"%s\");\n",
eina_strbuf_string_get(str_ev), evname, evdesc_line1);
free(evdesc_line1);
}
eina_strbuf_replace_all(str_begin, "@#list_events", eina_strbuf_string_get(tmpbuf));
eina_strbuf_append(buf, eina_strbuf_string_get(str_begin));
eina_strbuf_free(str_ev);
eina_strbuf_free(tmpbuf);
eina_strbuf_free(str_begin);
return EINA_TRUE;
}
Eina_Bool
eo1_source_end_generate(const char *classname, Eina_Strbuf *buf)
{
const Eina_List *itr;
Eolian_Function fn;
Eina_Strbuf *str_end = eina_strbuf_new();
Eina_Strbuf *tmpbuf = eina_strbuf_new();
Eina_Strbuf *str_op = eina_strbuf_new();
Eina_Strbuf *str_func = eina_strbuf_new();
Eina_Strbuf *str_bodyf = eina_strbuf_new();
Eina_Strbuf *str_ev = eina_strbuf_new();
_template_fill(str_end, tmpl_eo_src_end, classname, "", EINA_TRUE);
// default constructor
Eolian_Function ctor_fn = eolian_class_default_constructor_get(classname);
if (ctor_fn)
{
_template_fill(str_func, tmpl_eobase_func_desc, classname, "constructor", EINA_FALSE);
eo1_bind_func_generate(classname, ctor_fn, UNRESOLVED, str_bodyf);
}
// default destructor
Eolian_Function dtor_fn = eolian_class_default_destructor_get(classname);
if (dtor_fn)
{
_template_fill(str_func, tmpl_eobase_func_desc, classname, "destructor", EINA_FALSE);
eo1_bind_func_generate(classname, dtor_fn, UNRESOLVED, str_bodyf);
}
//Implements - TODO one generate func def for all
Eolian_Implement impl_desc;
EINA_LIST_FOREACH(eolian_class_implements_list_get(classname), itr, impl_desc)
{
const char *funcname;
const char *impl_class;
Eolian_Function_Type ftype;
eolian_implement_information_get(impl_desc, &impl_class, &funcname, &ftype);
Eina_Strbuf *tmpl_impl = eina_strbuf_new();
eina_strbuf_append(tmpl_impl, tmpl_eo_func_desc);
char tbuff[0xFF];
char *tp = tbuff;
strcpy(tbuff, classname);
eina_str_tolower(&tp);
eina_strbuf_replace_all(tmpl_impl, "@#class", tbuff);
const char *tmpl_impl_str = eina_strbuf_string_get(tmpl_impl);
Eolian_Function in_meth = NULL;
Eolian_Function in_prop = NULL;
const Eina_List *itr2;
Eolian_Function fnid;
EINA_LIST_FOREACH(eolian_class_functions_list_get((char *)impl_class, CONSTRUCTOR), itr2, fnid)
if (fnid && !strcmp(eolian_function_name_get(fnid), funcname)) in_meth = fnid;
EINA_LIST_FOREACH(eolian_class_functions_list_get((char *)impl_class, METHOD_FUNC), itr2, fnid)
if (fnid && !strcmp(eolian_function_name_get(fnid), funcname)) in_meth = fnid;
EINA_LIST_FOREACH(eolian_class_functions_list_get((char *)impl_class, PROPERTY_FUNC), itr2, fnid)
if (fnid && !strcmp(eolian_function_name_get(fnid), funcname)) in_prop = fnid;
if (!in_meth && !in_prop)
{
printf ("Failed to generate implementation of %s:%s - missing form super class\n", impl_class, funcname);
return EINA_FALSE;
}
if (in_meth)
{
_template_fill(str_func, tmpl_impl_str, impl_class, funcname, EINA_FALSE);
eo1_bind_func_generate(classname, in_meth, UNRESOLVED, str_bodyf);
}
if (in_prop)
{
char tmpstr[0xFF];
if ((ftype != GET) && (ftype != SET)) ftype = eolian_function_type_get(in_prop);
Eina_Bool prop_read = ( ftype == SET ) ? EINA_FALSE : EINA_TRUE;
Eina_Bool prop_write = ( ftype == GET ) ? EINA_FALSE : EINA_TRUE;
if (prop_read)
{
sprintf(tmpstr, "%s_get", funcname);
_template_fill(str_func, tmpl_impl_str, impl_class, tmpstr, EINA_FALSE);
eo1_bind_func_generate(classname, in_prop, GET, str_bodyf);
}
if (prop_write)
{
sprintf(tmpstr, "%s_set", funcname);
_template_fill(str_func, tmpl_impl_str, impl_class, tmpstr, EINA_FALSE);
eo1_bind_func_generate(classname, in_prop, SET, str_bodyf);
}
}
eina_strbuf_free(tmpl_impl);
}
//Constructors
EINA_LIST_FOREACH(eolian_class_functions_list_get(classname, CONSTRUCTOR), itr, fn)
{
const char *funcname = eolian_function_name_get(fn);
char *desc = _first_line_get(eolian_function_description_get(fn, "comment"));
_template_fill(tmpbuf, tmpl_eo_op_desc, classname, funcname, EINA_TRUE);
eina_strbuf_replace_all(tmpbuf, "@#desc", desc);
free(desc);
eina_strbuf_append(str_op, eina_strbuf_string_get(tmpbuf));
_template_fill(str_func, tmpl_eo_func_desc, classname, funcname, EINA_FALSE);
eo1_bind_func_generate(classname, fn, UNRESOLVED, str_bodyf);
}
//Properties
EINA_LIST_FOREACH(eolian_class_functions_list_get(classname, PROPERTY_FUNC), itr, fn)
{
const char *funcname = eolian_function_name_get(fn);
const Eolian_Function_Type ftype = eolian_function_type_get(fn);
char tmpstr[0xFF];
Eina_Bool prop_read = ( ftype == SET ) ? EINA_FALSE : EINA_TRUE;
Eina_Bool prop_write = ( ftype == GET ) ? EINA_FALSE : EINA_TRUE;
if (prop_read)
{
char *desc = _first_line_get(eolian_function_description_get(fn, "comment_get"));
sprintf(tmpstr, "%s_get", funcname);
eo1_eo_op_desc_generate(classname, tmpstr, tmpbuf);
eina_strbuf_replace_all(tmpbuf, "@#desc", desc);
free(desc);
eina_strbuf_append(str_op, eina_strbuf_string_get(tmpbuf));
eo1_eo_func_desc_generate(classname, tmpstr, tmpbuf);
eina_strbuf_append(str_func, eina_strbuf_string_get(tmpbuf));
}
if (prop_write)
{
char *desc = _first_line_get(eolian_function_description_get(fn, "comment_set"));
sprintf(tmpstr, "%s_set", funcname);
eo1_eo_op_desc_generate(classname, tmpstr, tmpbuf);
eina_strbuf_replace_all(tmpbuf, "@#desc", desc);
eina_strbuf_append(str_op, eina_strbuf_string_get(tmpbuf));
free(desc);
eo1_eo_func_desc_generate(classname, tmpstr, tmpbuf);
eina_strbuf_append(str_func, eina_strbuf_string_get(tmpbuf));
}
}
//Methods
EINA_LIST_FOREACH(eolian_class_functions_list_get(classname, METHOD_FUNC), itr, fn)
{
const char *funcname = eolian_function_name_get(fn);
char *desc = _first_line_get(eolian_function_description_get(fn, "comment"));
eo1_eo_op_desc_generate(classname, funcname, tmpbuf);
eina_strbuf_replace_all(tmpbuf, "@#desc", desc);
free(desc);
eina_strbuf_append(str_op, eina_strbuf_string_get(tmpbuf));
eo1_eo_func_desc_generate(classname, funcname, tmpbuf);
eina_strbuf_append(str_func, eina_strbuf_string_get(tmpbuf));
}
Eolian_Event event;
EINA_LIST_FOREACH(eolian_class_events_list_get(classname), itr, event)
{
const char *evname;
eolian_class_event_information_get(event, &evname, NULL);
_template_fill(tmpbuf, "@#CLASS_@#FUNC", classname, evname, EINA_TRUE);
eina_strbuf_replace_all(tmpbuf, ",", "_");
eina_strbuf_append_printf(str_ev, "\n %s,", eina_strbuf_string_get(tmpbuf));
}
eina_strbuf_replace_all(str_end, "@#list_evdesc", eina_strbuf_string_get(str_ev));
const char *inherit_name;
eina_strbuf_reset(tmpbuf);
EINA_LIST_FOREACH(eolian_class_inherits_list_get(classname), itr, inherit_name)
{
if (!strcmp(inherit_name, "Elm_Widget"))
eina_strbuf_append(tmpbuf, "ELM_OBJ_WIDGET_CLASS, ");
else if (!strcmp(inherit_name, "Elm_Interface_Scrollable"))
eina_strbuf_append(tmpbuf, "ELM_SCROLLABLE_INTERFACE, ");
else
_template_fill(tmpbuf, "@#OBJCLASS_CLASS, ", inherit_name, "", EINA_FALSE);
}
if (eina_strbuf_length_get(tmpbuf) == 0) eina_strbuf_append(tmpbuf,"EO_BASE_CLASS, ");
eina_strbuf_replace_all(str_end, "@#list_inherit", eina_strbuf_string_get(tmpbuf));
eina_strbuf_replace_all(str_end, "@#list_func", eina_strbuf_string_get(str_func));
eina_strbuf_replace_all(str_end, "@#list_op", eina_strbuf_string_get(str_op));
eina_strbuf_replace_all(str_end, "@#list_ctors_body", eina_strbuf_string_get(str_bodyf));
eina_strbuf_append(buf, eina_strbuf_string_get(str_end));
eina_strbuf_free(tmpbuf);
eina_strbuf_free(str_op);
eina_strbuf_free(str_func);
eina_strbuf_free(str_bodyf);
eina_strbuf_free(str_end);
eina_strbuf_free(str_ev);
return EINA_TRUE;
}

View File

@ -0,0 +1,141 @@
#ifndef EO1_GENERATOR_H
#define EO1_GENERATOR_H
#include<Eina.h>
#include "eolian_database.h"
/*
* @brief Generate beginning of Eo1 source code for Eo class
*
* This function generates the base id definition and the list of events.
*
* @param[in] classname class name
* @param[inout] buf buffer to fill
*
* @return EINA_TRUE on success, EINA_FALSE on error.
*
*/
Eina_Bool
eo1_source_beginning_generate(const char *classname, Eina_Strbuf *buf);
/*
* @brief Generate end of Eo1 source code for Eo class
*
* This function generates the constructors, the class constructor, the function
* descriptions and the class description.
*
* @param[in] classname class name
* @param[inout] buf buffer to fill
*
* @return EINA_TRUE on success, EINA_FALSE on error.
*
*/
Eina_Bool
eo1_source_end_generate(const char *classname, Eina_Strbuf *buf);
/*
* @brief Generate the source code for a specific Eo function.
*
* This function generates for a given function id the corresponding
* Eo function.
*
* @param[in] classname class name
* @param[in] funcid Function Id
* @param[in] ftype type of the function (SET/GET/METHOD...)
* @param[inout] buf buffer to fill
*
* @return EINA_TRUE on success, EINA_FALSE on error.
*
*/
Eina_Bool
eo1_bind_func_generate(const char *classname, Eolian_Function funcid, Eolian_Function_Type ftype, 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 eo1_header_generate(const char *classname, Eina_Strbuf *buf);
/*
* @brief Append the header code for a specific Eo class.
*
* This function generates header code by appending it into an existing class.
*
* @param[in] classname class name
* @param[inout] buf buffer to fill
*
* @return EINA_TRUE on success, EINA_FALSE on error.
*
*/
Eina_Bool eo1_header_append(const char *classname, Eina_Strbuf *buf);
/*
* @brief Fill the given buffer with the Eo enum of a given function.
*
* @param[in] classname class name
* @param[in] funcname function name
* @param[inout] buf buffer to fill
*
* @return EINA_TRUE on success, EINA_FALSE on error.
*
*/
Eina_Bool eo1_enum_append(const char *classname, const char *funcname, Eina_Strbuf *buf);
/*
* @brief Generate the function definition (header) for a specific Eo function.
*
* This function generates for a given function the corresponding
* Eo function definition.
*
* @param[in] classname class name
* @param[in] funcid Function Id
* @param[in] ftype type of the function (SET/GET/METHOD...)
* @param[inout] buf buffer to fill
*
* @return EINA_TRUE on success, EINA_FALSE on error.
*
*/
Eina_Bool
eo1_fundef_generate(const char *classname, Eolian_Function func, Eolian_Function_Type ftype, Eina_Strbuf *buf);
/*
* @brief Generate the function description for a specific Eo function.
*
* This function generates for a given function the corresponding
* Eo function description.
*
* @param[in] classname class name
* @param[in] funcname function name
* @param[inout] buf buffer to fill
*
* @return EINA_TRUE on success, EINA_FALSE on error.
*
*/
Eina_Bool
eo1_eo_func_desc_generate(const char *classname, const char *funcname, Eina_Strbuf *buf);
/*
* @brief Generate the Eo op description for a specific Eo function.
*
* This function generates for a given function the corresponding
* Eo function definition.
*
* @param[in] classname class name
* @param[in] funcname function name
* @param[inout] buf buffer to fill
*
* @return EINA_TRUE on success, EINA_FALSE on error.
*
*/
Eina_Bool
eo1_eo_op_desc_generate(const char *classname, const char *funcname, Eina_Strbuf *buf);
#endif

View File

@ -0,0 +1,452 @@
#include <Eina.h>
#include <string.h>
#include "Eolian.h"
#include "legacy_generator.h"
#include "eo1_generator.h"
#include "common_funcs.h"
static const char
tmpl_eapi_funcdef[] = "\n\
/**\n\
*\n\
@#desc\n\
*\n\
@#list_desc_param\
*/\n\
EAPI @#type_return @#class_@#func(@#is_constEvas_Object *obj@#params);\n\
";
/*@#CLASS_CHECK(obj) @#check_ret;\n\*/
static const char
tmpl_eapi_body[] ="\
\n\
EAPI @#ret_type\n\
@#eapi_prefix_@#func(@#is_constEvas_Object *obj@#full_params)\n\
{\n\
@#ret_init_val\
eo_do((Eo *) obj, @#eoprefix_@#func(@#eo_params));\n\
return @#ret_val;\n\
}\n\
";
static void
_eapi_decl_func_generate(const char *classname, Eolian_Function funcid, Eolian_Function_Type ftype, Eina_Strbuf *buf)
{
//TODO return value
const char *suffix = "";
const char *umpr = NULL;
const char *rettype = NULL;
const char *func_lpref = NULL;
Eina_Bool var_as_ret = EINA_FALSE;
rettype = eolian_function_return_type_get(funcid, ftype);
if (rettype && !strcmp(rettype, "void")) rettype = NULL;
if (ftype == GET)
{
suffix = "_get";
umpr = "*";
func_lpref = eolian_function_data_get(funcid, EOLIAN_LEGACY_GET);
if (!rettype)
{
const Eina_List *l = eolian_parameters_list_get(funcid);
if (eina_list_count(l) == 1)
{
void* data = eina_list_data_get(l);
eolian_parameter_information_get((Eolian_Function_Parameter)data, NULL, &rettype, NULL, NULL);
var_as_ret = EINA_TRUE;
}
}
}
if (ftype == SET)
{
suffix = "_set";
umpr = "";
func_lpref = eolian_function_data_get(funcid, EOLIAN_LEGACY_SET);
}
func_lpref = (func_lpref) ? func_lpref : eolian_function_data_get(funcid, EOLIAN_LEGACY);
func_lpref = (func_lpref) ? func_lpref : eolian_class_legacy_prefix_get(classname);
if (!func_lpref) func_lpref = classname;
Eina_Strbuf *fbody = eina_strbuf_new();
Eina_Strbuf *fparam = eina_strbuf_new();
Eina_Strbuf *descparam = eina_strbuf_new();
char tmpstr[0xFF];
sprintf (tmpstr, "%s%s", eolian_function_name_get(funcid), suffix);
_template_fill(fbody, tmpl_eapi_funcdef, func_lpref, tmpstr, EINA_FALSE);
sprintf (tmpstr, "comment%s", suffix);
const char *desc = eolian_function_description_get(funcid, tmpstr);
Eina_Strbuf *linedesc = eina_strbuf_new();
eina_strbuf_append(linedesc, desc ? desc : "");
if (eina_strbuf_length_get(linedesc))
{
eina_strbuf_replace_all(linedesc, "\n", "\n * ");
eina_strbuf_prepend(linedesc," * ");
}
eina_strbuf_replace_all(fbody, "@#desc", eina_strbuf_string_get(linedesc));
eina_strbuf_free(linedesc);
const Eina_List *l;
void *data;
if (!var_as_ret)
{
EINA_LIST_FOREACH(eolian_parameters_list_get(funcid), l, data)
{
const char *pname;
const char *pdesc;
const char *ptype;
Eolian_Parameter_Dir pdir;
eolian_parameter_information_get((Eolian_Function_Parameter)data, &pdir, &ptype, &pname, &pdesc);
const char *ptrstr = (umpr) ? umpr : ( (pdir == EOLIAN_IN_PARAM) ? "" : "*" );
eina_strbuf_append_printf(fparam, ", %s%s%s %s",
eolian_parameter_get_const_attribute_get(data)?"const":"",
ptype, ptrstr, pname);
eina_strbuf_append_printf(descparam, " * @param %s\n", pname);
}
}
eina_strbuf_replace_all(fbody, "@#params", eina_strbuf_string_get(fparam));
eina_strbuf_replace_all(fbody, "@#list_desc_param", eina_strbuf_string_get(descparam));
eina_strbuf_replace_all(fbody, "@#type_return", (rettype) ? rettype : "void");
eina_strbuf_replace_all(fbody, "@#is_const", (ftype == GET || eolian_function_object_is_const(funcid)) ? "const " : "");
eina_strbuf_append(buf, eina_strbuf_string_get(fbody));
eina_strbuf_free(fbody);
eina_strbuf_free(fparam);
eina_strbuf_free(descparam);
}
static void
_eapi_func_generate(const char *classname, Eolian_Function funcid, Eolian_Function_Type ftype, Eina_Strbuf *buf)
{
//TODO return value
const char *suffix = "";
const char *umpr = NULL;
const char *func_lpref = NULL;
Eina_Bool var_as_ret = EINA_FALSE;
const char *rettype = NULL;
const char *retname = NULL;
Eina_Bool ret_const = EINA_FALSE;
rettype = eolian_function_return_type_get(funcid, ftype);
if (rettype && !strcmp(rettype, "void")) rettype = NULL;
retname = "ret";
if (ftype == GET)
{
suffix = "_get";
umpr = "*";
func_lpref = eolian_function_data_get(funcid, EOLIAN_LEGACY_GET);
if (!rettype)
{
const Eina_List *l = eolian_parameters_list_get(funcid);
if (eina_list_count(l) == 1)
{
void* data = eina_list_data_get(l);
eolian_parameter_information_get((Eolian_Function_Parameter)data, NULL, &rettype, &retname, NULL);
var_as_ret = EINA_TRUE;
ret_const = eolian_parameter_get_const_attribute_get(data);
}
}
}
if (ftype == SET)
{
suffix = "_set";
umpr = "";
func_lpref = eolian_function_data_get(funcid, EOLIAN_LEGACY_SET);
}
func_lpref = (func_lpref) ? func_lpref : eolian_function_data_get(funcid, EOLIAN_LEGACY);
func_lpref = (func_lpref) ? func_lpref : eolian_class_legacy_prefix_get(classname);
Eina_Strbuf *fbody = eina_strbuf_new();
Eina_Strbuf *fparam = eina_strbuf_new();
Eina_Strbuf *eoparam = eina_strbuf_new();
char tmpstr[0xFF];
sprintf (tmpstr, "%s%s", eolian_function_name_get(funcid), suffix);
_template_fill(fbody, tmpl_eapi_body, classname, tmpstr, EINA_FALSE);
if (!func_lpref)
{
strcpy(tmpstr, classname);
char *p = tmpstr;
eina_str_tolower(&p);
func_lpref = tmpstr;
}
eina_strbuf_replace_all(fbody, "@#eapi_prefix", func_lpref);
const Eina_List *l;
void *data;
tmpstr[0] = '\0';
if (!var_as_ret)
{
EINA_LIST_FOREACH(eolian_parameters_list_get(funcid), l, data)
{
const char *pname;
const char *ptype;
Eolian_Parameter_Dir pdir;
eolian_parameter_information_get((Eolian_Function_Parameter)data, &pdir, &ptype, &pname, NULL);
const char *ptrstr = (umpr) ? umpr : ( (pdir == EOLIAN_IN_PARAM) ? "" : "*" );
eina_strbuf_append_printf(fparam, ", %s%s%s %s",
ftype == GET && eolian_parameter_get_const_attribute_get(data)?"const ":"",
ptype, ptrstr, pname);
if (eina_strbuf_length_get(eoparam)) eina_strbuf_append(eoparam, ", ");
eina_strbuf_append_printf(eoparam, "%s", pname);
}
}
char tmp_ret_str[0xFF];
sprintf (tmp_ret_str, "%s%s", ret_const?"const ":"", rettype?rettype:"void");
if (rettype && strcmp(rettype, "void"))
{
if (eina_strbuf_length_get(eoparam)) eina_strbuf_append(eoparam, ", ");
sprintf (tmpstr, " %s%s %s;\n", ret_const?"const ":"", rettype, retname);
eina_strbuf_append_printf(eoparam, "&%s", retname);
}
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_type", tmp_ret_str);
eina_strbuf_replace_all(fbody, "@#ret_init_val", tmpstr);
eina_strbuf_replace_all(fbody, "@#ret_val", (rettype) ? retname : "");
eina_strbuf_replace_all(fbody, "@#is_const", (ftype == GET || eolian_function_object_is_const(funcid)) ? "const " : "");
tmpstr[0] = '\0';
if (rettype) sprintf (tmpstr, "(%s)(0)", rettype);
eina_strbuf_replace_all(fbody, "@#check_ret", tmpstr);
eina_strbuf_append(buf, eina_strbuf_string_get(fbody));
eina_strbuf_free(fbody);
eina_strbuf_free(fparam);
eina_strbuf_free(eoparam);
}
//TODO change replacement
static char*
_class_h_find(const char *classname, Eina_Strbuf *buf)
{
Eina_Strbuf *classreal = eina_strbuf_new();
_template_fill(classreal, "@#OBJCLASS_CLASS", classname, "", EINA_FALSE);
char *ret = strstr(eina_strbuf_string_get(buf), eina_strbuf_string_get(classreal));
eina_strbuf_free(classreal);
return ret;
}
Eina_Bool
legacy_header_generate(const char *classname, int eo_version, Eina_Strbuf *buf)
{
const Eolian_Function_Type ftype_order[] = {PROPERTY_FUNC, METHOD_FUNC};
const Eina_List *l;
void *data;
if (!eolian_class_exists(classname))
{
printf ("Class \"%s\" not found in database\n", classname);
return EINA_FALSE;
}
int i;
for (i = 0; i < 2; i++)
EINA_LIST_FOREACH(eolian_class_functions_list_get(classname, ftype_order[i]), l, data)
{
const Eolian_Function_Type ftype = eolian_function_type_get((Eolian_Function)data);
Eina_Bool prop_read = (ftype == PROPERTY_FUNC || ftype == GET ) ? EINA_TRUE : EINA_FALSE ;
Eina_Bool prop_write = (ftype == PROPERTY_FUNC || ftype == SET ) ? EINA_TRUE : EINA_FALSE ;
if (!prop_read && !prop_write)
{
_eapi_decl_func_generate(classname, (Eolian_Function)data, UNRESOLVED, buf);
}
if (prop_read)
{
_eapi_decl_func_generate(classname, (Eolian_Function)data, GET, buf);
}
if (prop_write)
{
_eapi_decl_func_generate(classname, (Eolian_Function)data, SET, buf);
}
}
return EINA_TRUE;
}
static char*
_nextline(char *str, unsigned int lines)
{
if (!str) return NULL;
char *ret = str;
while ((lines--) && *ret)
{
ret= strchr(ret, '\n');
if (ret) ret++;
}
return ret;
}
static char*
_startline(char *str, char *pos)
{
if (!str || !pos) return NULL;
char *ret = pos;
while ((ret > str) && (*(ret-1)!='\n')) ret--;
return ret;
}
Eina_Bool
legacy_header_append(const char *classname, int eo_version, Eina_Strbuf *header)
{
const Eolian_Function_Type ftype_order[] = {CONSTRUCTOR, PROPERTY_FUNC, METHOD_FUNC};
char tmpstr[0xFF];
if (!eolian_class_exists(classname))
{
printf ("Class \"%s\" not found in database\n", classname);
return EINA_FALSE;
}
char *clsptr = _class_h_find(classname, header);
if (!clsptr)
{
printf ("Class %s not found - append all\n", classname);
eina_strbuf_append_char(header, '\n');
eo1_header_generate(classname, header);
return EINA_TRUE;
}
printf ("Class %s found - searching for functions...\n", classname);
char *funcdef_pos = _nextline(strstr(clsptr, "+ sub_id)"), 1);
char *subid_pos = _startline(clsptr, strstr(clsptr, "SUB_ID_LAST"));
if (!(funcdef_pos && subid_pos) || (subid_pos > funcdef_pos))
{
printf ("Bad insertion queues - update aborted\n");
return EINA_FALSE;
}
Eina_Strbuf *str_subid = eina_strbuf_new();
Eina_Strbuf *str_funcdef = eina_strbuf_new();
const Eina_List *l;
void *data;
int i;
for (i = 0; i < 3; i++)
EINA_LIST_FOREACH(eolian_class_functions_list_get(classname, ftype_order[i]), l, data)
{
const Eolian_Function_Type ftype = eolian_function_type_get((Eolian_Function)data);
const char *funcname = eolian_function_name_get((Eolian_Function)data);
Eina_Bool prop_read = (ftype == PROPERTY_FUNC || ftype == GET ) ? EINA_TRUE : EINA_FALSE ;
Eina_Bool prop_write = (ftype == PROPERTY_FUNC || ftype == SET ) ? EINA_TRUE : EINA_FALSE ;
if (!prop_read && !prop_write)
{
if (!strstr(eina_strbuf_string_get(header), funcname))
{
printf ("Appending eo function %s\n", funcname);
eo1_enum_append(classname, funcname, str_subid);
eo1_fundef_generate(classname, (Eolian_Function)data, UNRESOLVED, str_funcdef);
}
}
if (prop_read)
{
sprintf(tmpstr, "%s_get", funcname);
if (!strstr(eina_strbuf_string_get(header), tmpstr))
{
printf ("Appending eo function %s\n", tmpstr);
eo1_enum_append(classname, tmpstr, str_subid);
eo1_fundef_generate(classname, (Eolian_Function)data, GET, str_funcdef);
}
}
if (prop_write)
{
sprintf(tmpstr, "%s_set", funcname);
if (!strstr(eina_strbuf_string_get(header), tmpstr))
{
printf ("Appending eo function %s\n", tmpstr);
eo1_enum_append(classname, tmpstr, str_subid);
eo1_fundef_generate(classname, (Eolian_Function)data, SET, str_funcdef);
}
}
}
const char *hdstr = eina_strbuf_string_get(header);
unsigned enum_offs = subid_pos - hdstr;
unsigned defs_offs = funcdef_pos - hdstr + eina_strbuf_length_get(str_subid);
eina_strbuf_insert(header, eina_strbuf_string_get(str_subid), enum_offs);
eina_strbuf_insert(header, eina_strbuf_string_get(str_funcdef), defs_offs);
eina_strbuf_free(str_subid);
eina_strbuf_free(str_funcdef);
return EINA_TRUE;
}
Eina_Bool
legacy_source_generate(const char *classname, int eo_version, Eina_Strbuf *buf)
{
const Eina_List *itr;
if (!eolian_class_exists(classname))
{
printf ("Class \"%s\" not found in database\n", classname);
return EINA_FALSE;
}
Eina_Strbuf *tmpbuf = eina_strbuf_new();
Eina_Strbuf *str_bodyf = eina_strbuf_new();
eo1_source_beginning_generate(classname, buf);
//Properties
Eolian_Function fn;
EINA_LIST_FOREACH(eolian_class_functions_list_get(classname, PROPERTY_FUNC), itr, fn)
{
const Eolian_Function_Type ftype = eolian_function_type_get(fn);
Eina_Bool prop_read = ( ftype == SET ) ? EINA_FALSE : EINA_TRUE;
Eina_Bool prop_write = ( ftype == GET ) ? EINA_FALSE : EINA_TRUE;
if (prop_read)
{
eo1_bind_func_generate(classname, fn, GET, str_bodyf);
_eapi_func_generate(classname, fn, GET, str_bodyf);
}
if (prop_write)
{
eo1_bind_func_generate(classname, fn, SET, str_bodyf);
_eapi_func_generate(classname, fn, SET, str_bodyf);
}
}
//Methods
EINA_LIST_FOREACH(eolian_class_functions_list_get(classname, METHOD_FUNC), itr, fn)
{
eo1_bind_func_generate(classname, fn, UNRESOLVED, str_bodyf);
_eapi_func_generate(classname, fn, UNRESOLVED, str_bodyf);
}
eina_strbuf_append(buf, eina_strbuf_string_get(str_bodyf));
eo1_source_end_generate(classname, buf);
eina_strbuf_free(tmpbuf);
eina_strbuf_free(str_bodyf);
return EINA_TRUE;
}

View File

@ -0,0 +1,53 @@
#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[in] eo_version Eo version to generate
* @param[inout] buf buffer to fill
*
* @return EINA_TRUE on success, EINA_FALSE on error.
*
*/
Eina_Bool legacy_header_generate(const char *classname, int eo_version, Eina_Strbuf *buf);
/*
* @brief Append legacy EAPI header for Eo class
*
* This function needs to be used in case we want to add new functions
* to an existing class.
*
* @param[in] classname class name
* @param[in] eo_version Eo version to generate
* @param[inout] buf buffer to fill
*
* @return EINA_TRUE on success, EINA_FALSE on error.
*
*/
Eina_Bool legacy_header_append(const char *classname, int eo_version, 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[in] eo_version Eo version to generate
* @param[inout] buf buffer to fill
*
* @return EINA_TRUE on success, EINA_FALSE on error.
*
*/
Eina_Bool legacy_source_generate(const char *classname, int eo_version, Eina_Strbuf *buf);
#endif

334
src/bin/eolian/main.c Normal file
View File

@ -0,0 +1,334 @@
#include <Eina.h>
#include <Ecore_File.h>
#include "Eolian.h"
#include "legacy_generator.h"
#include "eo1_generator.h"
#define EO_SUFFIX ".eo"
static int eo_version = 0;
static Eina_Bool
_generate_h_file(char *filename, char *classname, Eina_Bool append)
{
Eina_Bool ret = EINA_FALSE;
Eina_Strbuf *hfile = eina_strbuf_new();
if (append)
{
Eina_File *fn = eina_file_open(filename, EINA_FALSE);
if (!fn)
{
printf ("Cant open file \"%s\" for updating.\n", filename);
goto end;
}
eina_strbuf_append(hfile, (char*)eina_file_map_all(fn, EINA_FILE_SEQUENTIAL));
eina_file_close(fn);
legacy_header_append(classname, eo_version, hfile);
}
else
{
eo1_header_generate(classname, hfile);
}
const char *htext = eina_strbuf_string_get(hfile);
FILE* fd = fopen(filename, "w");
if (!fd)
{
printf ("Couldn't open file %s for writing\n", filename);
goto end;
}
if (htext) fputs(htext, fd);
fclose(fd);
ret = EINA_TRUE;
end:
eina_strbuf_free(hfile);
return ret;
}
static Eina_Bool
_generate_c_file(char *filename, char *classname, Eina_Bool append)
{
Eina_Bool ret = EINA_FALSE;
Eina_Strbuf *cfile = eina_strbuf_new();
legacy_source_generate(classname, eo_version, cfile);
FILE* fd = fopen(filename, (append) ? "a" : "w");
if (!fd)
{
printf ("Couldnt open file %s for writing\n", filename);
goto end;
}
const char *ctext = eina_strbuf_string_get(cfile);
if (ctext) fputs(ctext, fd);
fclose(fd);
ret = EINA_TRUE;
end:
eina_strbuf_free(cfile);
return ret;
}
// TODO join with header gen.
static Eina_Bool
_generate_legacy_header_file(char *filename, char *classname, Eina_Bool append)
{
Eina_Bool ret = EINA_FALSE;
Eina_Strbuf *lfile = eina_strbuf_new();
if (append)
{
Eina_File *fn = eina_file_open(filename, EINA_FALSE);
if (!fn)
{
printf ("Cant open file \"%s\" for updating.\n", filename);
goto end;
}
eina_strbuf_append(lfile, (char*)eina_file_map_all(fn, EINA_FILE_SEQUENTIAL));
eina_file_close(fn);
legacy_header_append(classname, eo_version, lfile);
}
else
{
legacy_header_generate(classname, eo_version, lfile);
}
FILE* fd = fopen(filename, "w");
if (!fd)
{
printf ("Couldnt open file %s for writing\n", filename);
goto end;
}
const char *ltext = eina_strbuf_string_get(lfile);
if (ltext) fputs(ltext, fd);
fclose(fd);
ret = EINA_TRUE;
end:
eina_strbuf_free(lfile);
return ret;
}
static Eina_Bool
_generate_eo_and_legacy_h_file(char *filename, char *classname)
{
Eina_Bool ret = EINA_FALSE;
Eina_Strbuf *hfile = eina_strbuf_new();
FILE* fd = fopen(filename, "w");
if (!fd)
{
printf ("Couldnt open file %s for writing\n", filename);
goto end;
}
eo1_header_generate(classname, hfile);
legacy_header_generate(classname, eo_version, hfile);
const char *htext = eina_strbuf_string_get(hfile);
if (htext) fputs(htext, fd);
fclose(fd);
ret = EINA_TRUE;
end:
eina_strbuf_free(hfile);
return ret;
}
int main(int argc, char **argv)
{
eina_init();
int i, ret = 0;
Eina_Bool help = EINA_FALSE, show = EINA_FALSE;
Eina_List *files = NULL, *itr;
Eina_List *classes = NULL;
char *h_filename = NULL, *c_filename = NULL,
*classname = NULL, *leg_filename = NULL,
*eoleg_filename = NULL;
Eina_Bool happend = EINA_FALSE;
Eina_Bool lappend = EINA_FALSE;
for(i = 1; i < argc; i++)
{
if (!strcmp(argv[i], "-eo1"))
{
eo_version = 1;
continue;
}
if (!strcmp(argv[i], "-eo2"))
{
eo_version = 2;
continue;
}
if (!strcmp(argv[i], "-gh") && (i < (argc-1)))
{
h_filename = argv[i + 1];
continue;
}
if (!strcmp(argv[i], "-gc") && (i < (argc-1)))
{
c_filename = argv[i + 1];
continue;
}
if (!strcmp(argv[i], "-gl") && (i < (argc-1)))
{
leg_filename = argv[i + 1];
continue;
}
if (!strcmp(argv[i], "-gle") && (i < (argc-1)))
{
eoleg_filename = argv[i + 1];
continue;
}
if (!strcmp(argv[i], "-ah") && (i < (argc-1)))
{
h_filename = argv[i + 1];
happend = EINA_TRUE;
continue;
}
if (!strcmp(argv[i], "-al") && (i < (argc-1)))
{
leg_filename = argv[i + 1];
lappend = EINA_TRUE;
continue;
}
if (!strcmp(argv[i], "--class") && (i < (argc-1)))
{
classes = eina_list_append(classes, argv[i + 1]);
continue;
}
if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help"))
{
help = EINA_TRUE;
continue;
}
if (!strcmp(argv[i], "--show"))
{
show = EINA_TRUE;
continue;
}
/* Directory parameter found. */
if ((!strcmp(argv[i], "-d") || !strcmp(argv[i], "--dir")) && (i < (argc-1)))
{
i++;
char *dir = ecore_file_realpath(argv[i]);
if (strlen(dir) != 0)
{
if (ecore_file_is_dir(dir))
{
Eina_List *dir_files;
char *file;
/* Get all files from directory. Not recursively!!!*/
dir_files = ecore_file_ls(dir);
EINA_LIST_FREE(dir_files, file)
{
char *filepath = malloc(strlen(dir) + 1 + strlen(file) + 1);
sprintf(filepath, "%s/%s", dir, file);
if ((!ecore_file_is_dir(filepath)) && eina_str_has_suffix(filepath, EO_SUFFIX))
{
/* Allocated string will be freed during deletion of "files" list. */
files = eina_list_append(files, strdup(filepath));
}
free(filepath);
free(file);
}
}
}
free(dir);
continue;
}
if ((!strcmp(argv[i], "-f") || !strcmp(argv[i], "--file")) && (i < (argc-1)))
{
i++;
char *realpath = ecore_file_realpath(argv[i]);
if (strlen(realpath) != 0)
{
if (!ecore_file_is_dir(realpath))
{
if (eina_str_has_suffix(realpath, EO_SUFFIX))
files = eina_list_append(files, strdup(realpath));
}
}
free(realpath);
continue;
}
}
if (eina_list_count(classes)) classname = eina_list_data_get(classes);
if (!files || help || !classname)
{
printf("Usage: %s [-h/--help] [--show] [-d/--dir input_dir] [-f/--file input_file] [-gh|-gc|-ah] filename [--class] classname \n", argv[0]);
printf(" -eo1/-eo2 Set generator to eo1/eo2 mode. Must be specified\n");
printf(" -gh Generate c header file [.h] for eo class specified by classname\n");
printf(" -gc Generate c source file [.c] for eo class specified by classname\n");
printf(" -ah Append eo class definitions to an existing c header file [.h]\n");
printf(" -al Append legacy function definitions to an existing c header file [.h]\n");
printf(" -gle Generate eo and legacy file [.h]\n");
return 0;
}
eolian_init();
const char *filename;
EINA_LIST_FOREACH(files, itr, filename)
{
if (!eolian_eo_file_parse(filename))
{
printf("Error during parsing file %s\n", filename);
goto end;
}
}
if (show) eolian_show(classname);
if (!eo_version)
{
printf("No eo version specified (use -eo1 or -eo2). Aborting eo generation.\n");
ret = 1;
goto end;
}
if (h_filename)
{
printf("%s header file %s\n", (happend) ? "Appending" : "Generating", h_filename);
_generate_h_file(h_filename, classname, happend);
}
if (c_filename)
{
printf("Generating source file %s\n", c_filename);
Eina_List *l = NULL;
char *cname = NULL;
EINA_LIST_FOREACH(classes,l,cname)
_generate_c_file(c_filename, cname, (classes != l));
}
if (leg_filename)
{
printf("%s legacy file %s\n", (lappend) ? "Appending" : "Generating", leg_filename);
_generate_legacy_header_file(leg_filename, classname, lappend);
}
if (eoleg_filename)
{
printf("Generating eo and legacy header file %s\n", eoleg_filename);
_generate_eo_and_legacy_h_file(eoleg_filename, classname);
}
end:
EINA_LIST_FREE(files, filename)
free((char *)filename);
eina_list_free(classes);
eolian_shutdown();
eina_shutdown();
return ret;
}

417
src/lib/eolian/Eolian.h Normal file
View File

@ -0,0 +1,417 @@
#ifndef EOLIAN_H
#define EOLIAN_H
#ifdef __cplusplus
extern "C" {
#endif
#include <Eina.h>
/* Function Id used to extract information on class functions
*
* @ingroup Eolian
*/
typedef struct _Function_Id* Eolian_Function;
/* Class function parameter information
*
* @ingroup Eolian
*/
typedef struct _Parameter_Desc* Eolian_Function_Parameter;
/* Class implement information
*
* @ingroup Eolian
*/
typedef struct _Implement_Desc* Eolian_Implement;
/* Class implement legacy information
*
* @ingroup Eolian
*/
typedef struct _Implement_Legacy_Desc* Eolian_Implement_Legacy;
/* Class implement legacy parameter information
*
* @ingroup Eolian
*/
typedef struct _Implement_Legacy_Param* Eolian_Implement_Legacy_Parameter;
/* Event information
*
* @ingroup Eolian
*/
typedef struct _Event_Desc* Eolian_Event;
#define EOLIAN_METHOD_RETURN_TYPE "method_return_type"
#define EOLIAN_PROP_GET_RETURN_TYPE "property_get_return_type"
#define EOLIAN_PROP_SET_RETURN_TYPE "property_set_return_type"
#define EOLIAN_RETURN_COMMENT "return_comment"
#define EOLIAN_LEGACY "legacy"
#define EOLIAN_LEGACY_GET "legacy_get"
#define EOLIAN_LEGACY_SET "legacy_set"
#define EOLIAN_COMMENT "comment"
#define EOLIAN_COMMENT_SET "comment_set"
#define EOLIAN_COMMENT_GET "comment_get"
typedef enum
{
UNRESOLVED,
PROPERTY_FUNC,
// FIXME: bs
SET,
GET,
METHOD_FUNC,
CONSTRUCTOR,
DFLT_CONSTRUCTOR,
DESTRUCTOR,
DFLT_DESTRUCTOR
} Eolian_Function_Type;
typedef enum
{
EOLIAN_IN_PARAM,
EOLIAN_OUT_PARAM,
EOLIAN_INOUT_PARAM
} Eolian_Parameter_Dir;
typedef enum
{
EOLIAN_CLASS_UNKNOWN_TYPE,
EOLIAN_CLASS_REGULAR,
EOLIAN_CLASS_REGULAR_NON_INSTANT,
EOLIAN_CLASS_MIXIN,
EOLIAN_CLASS_INTERFACE
} Eolian_Class_Type;
/*
* @brief Parse a given .eo file and fill the database.
*
* During parsing, the class described into the .eo file is created with
* all the information related to this class.
*
* @param[in] filename Name of the file to parse.
*
* @ingroup Eolian
*/
Eina_Bool eolian_eo_file_parse(const char *filename);
/*
* @brief Init Eolian.
*
* @ingroup Eolian
*/
Eina_Bool eolian_init();
/*
* @brief Shutdown Eolian.
*
* @ingroup Eolian
*/
Eina_Bool eolian_shutdown();
/*
* @brief Show information about a given class.
*
* If class_name is NULL, this function will print information of
* all the classes stored into the database.
*
* @param[in] class_name the class to show
*
* @ingroup Eolian
*/
Eina_Bool eolian_show(const char *class_name);
/*
* @brief Returns the class type of the given class
*
* @param[in] class_name name of the class
* @return the class type
*
* @ingroup Eolian
*/
Eolian_Class_Type eolian_class_type_get(const char *class_name);
/*
* @brief Returns the names list of all the classes stored into the database.
*
* @return the list
*
* @ingroup Eolian
*/
/* Returns the list of class names of the database */
const Eina_List *eolian_class_names_list_get();
/*
* @brief Indicates if class exists in the database.
*
* @param[in] class_name name of the class
* @return EINA_TRUE if exists, EINA_FALSE otherwise
*
* @ingroup Eolian
*/
Eina_Bool eolian_class_exists(const char *class_name);
/*
* @brief Returns the description of a class.
*
* @param[in] class_name name of the class
* @return the description of a class
*
* @ingroup Eolian
*/
const char*
eolian_class_description_get(const char *class_name);
/*
* @brief Returns the legacy prefix of a class
*
* @param[in] class_name name of the class
* @return the legacy prefix
*
* @ingroup Eolian
*/
const char*
eolian_class_legacy_prefix_get(const char *class_name);
/*
* @brief Returns the names list of the inherit classes of a class
*
* @param[in] class_name name of the class
* @return the list
*
* @ingroup Eolian
*/
const Eina_List *eolian_class_inherits_list_get(const char *class_name);
/*
* @brief Returns a list of functions of a class.
*
* @param[in] class_name name of the class
* @param[in] func_type type of the functions to insert into the list.
* @return the list of Eolian_Function
*
* @ingroup Eolian
*/
const Eina_List *eolian_class_functions_list_get(const char *class_name, Eolian_Function_Type func_type);
/*
* @brief Returns the Function Id for the default constructor.
*
* @param[in] class_name name of the class
* @return a Function Id
*
* @ingroup Eolian
*/
Eolian_Function eolian_class_default_constructor_get(const char *class_name);
/*
* @brief Returns the Function Id for the default destructor.
*
* @param[in] class_name name of the class
* @return a Function Id
*
* @ingroup Eolian
*/
Eolian_Function eolian_class_default_destructor_get(const char *class_name);
/*
* @brief Returns the type of a function
*
* @param[in] function_id Id of the function
* @return the function type
*
* @ingroup Eolian
*/
Eolian_Function_Type eolian_function_type_get(Eolian_Function function_id);
/*
* @brief Returns the name of a function
*
* @param[in] function_id Id of the function
* @return the function name
*
* @ingroup Eolian
*/
const char *eolian_function_name_get(Eolian_Function function_id);
/*
* @brief Indicates if a function of a certain type exists in a class.
*
* @param[in] class_name name of the class
* @param[in] func_name name of the function
* @param[in] f_type type of the function
* @return EINA_TRUE if exists, EINA_FALSE otherwise
*
* @ingroup Eolian
*/
Eina_Bool eolian_class_function_exists(const char *classname, const char *func_name, Eolian_Function_Type f_type);
/*
* @brief Returns a specific data for a function.
*
* @param[in] function_id Id of the function
* @param[in] key key to access the data
* @return the data.
*
* @ingroup Eolian
*/
const char *eolian_function_data_get(Eolian_Function function_id, const char *key);
/*
* @brief Returns a specific description for a function.
*
* @param[in] function_id Id of the function
* @param[in] key key to access the description
* @return the description.
*
* @ingroup Eolian
*/
#define eolian_function_description_get(function_id, key) eolian_function_data_get((function_id), (key))
/*
* @brief Returns a parameter of a function pointed by its id.
*
* @param[in] function_id Id of the function
* @param[in] param_name Name of the parameter
* @return a handle to this parameter.
*
* @ingroup Eolian
*/
Eolian_Function_Parameter eolian_function_parameter_get(const Eolian_Function function_id, const char *param_name);
/*
* @brief Returns a list of parameter handles for a function pointed by its id.
*
* @param[in] function_id Id of the function
* @return a handle to this parameter.
*
* @ingroup Eolian
*/
const Eina_List *eolian_parameters_list_get(Eolian_Function function_id);
/*
* @brief Get information about a function parameter
*
* @param[in] param_desc parameter handle
* @param[out] param_dir in/out/inout
* @param[out] type type of the parameter
* @param[out] name name of the parameter
* @param[out] description description of the parameter
*
* @ingroup Eolian
*/
void eolian_parameter_information_get(Eolian_Function_Parameter param_desc, Eolian_Parameter_Dir *param_dir, const char **type, const char **name, const char **description);
/*
* @brief Get type of a parameter
*
* @param[in] param_desc parameter handle
* @return the type of the parameter
*
* @ingroup Eolian
*/
Eina_Stringshare* eolian_parameter_type_get(const Eolian_Function_Parameter param);
/*
* @brief Get name of a parameter
*
* @param[in] param_desc parameter handle
* @return the name of the parameter
*
* @ingroup Eolian
*/
Eina_Stringshare* eolian_parameter_name_get(const Eolian_Function_Parameter param);
/*
* @brief Indicates if a parameter has a const attribute.
*
* This function is relevant for properties, to know if a parameter is a const
* parameter in the get operation.
*
* @param[in] param_desc parameter handle
* @return EINA_TRUE if const in get, EINA_FALSE otherwise
*
* @ingroup Eolian
*/
Eina_Bool eolian_parameter_get_const_attribute_get(Eolian_Function_Parameter param_desc);
/*
* @brief Get the return type of a function.
*
* @param[in] function_id id of the function
* @param[in] ftype type of the function
* @return the return type of the function
*
* The type of the function is needed because a given function can represent a
* property, that can be set and get functions.
*
* @ingroup Eolian
*/
const char *eolian_function_return_type_get(Eolian_Function function_id, Eolian_Function_Type ftype);
/*
* @brief Indicates if a function object is const.
*
* @param[in] function_id id of the function
* @return EINA_TRUE if the object is const, EINA_FALSE otherwise
*
* @ingroup Eolian
*/
Eina_Bool eolian_function_object_is_const(Eolian_Function function_id);
/*
* @brief Get information about an overriding function (implement).
*
* @param[in] impl handle of the implement
* @param[out] class_name name of the class to override
* @param[out] func_name name of the function to override
* @param[out] type type of the function to override
* @return EINA_TRUE on success, EINA_FALSE otherwise.
*
* @ingroup Eolian
*/
Eina_Bool
eolian_implement_information_get(Eolian_Implement impl,
const char **class_name, const char **func_name, Eolian_Function_Type *type);
/*
* @brief Get the list of overriding functions defined in a class.
*
* @param[in] class_name name of the class.
* @return a list of Eolian_Implement handles
*
* @ingroup Eolian
*/
const Eina_List*
eolian_class_implements_list_get(const char *class_name);
/*
* @brief Get the list of events defined in a class.
*
* @param[in] class_name name of the class.
* @return a list of Eolian_Event handles
*
* @ingroup Eolian
*/
const Eina_List*
eolian_class_events_list_get(const char *class_name);
/*
* @brief Get information about an event.
*
* @param[in] event handle of the event
* @param[out] event_name name of the event
* @param[out] event_desc description of the event
* @return EINA_TRUE on success, EINA_FALSE otherwise.
*
* @ingroup Eolian
*/
Eina_Bool
eolian_class_event_information_get(Eolian_Event event, const char **event_name, const char **event_desc);
#ifdef __cplusplus
} // extern "C" {
#endif
#endif

View File

@ -0,0 +1,162 @@
#include <stdio.h>
#include <stdlib.h>
#include "eo_definitions.h"
void
eo_definitions_ret_free(Eo_Ret_Def *ret)
{
if (ret->type) eina_stringshare_del(ret->type);
if (ret->comment) eina_stringshare_del(ret->comment);
/* do not free */
}
void
eo_definitions_param_free(Eo_Param_Def *param)
{
if (param->type) eina_stringshare_del(param->type);
if (param->name) eina_stringshare_del(param->name);
if (param->comment) eina_stringshare_del(param->comment);
free(param);
}
void
eo_definitions_accessor_free(Eo_Accessor_Def *accessor)
{
if (accessor->comment)
eina_stringshare_del(accessor->comment);
if (accessor->legacy)
eina_stringshare_del(accessor->legacy);
eo_definitions_ret_free(&accessor->ret);
free(accessor);
}
void
eo_definitions_property_def_free(Eo_Property_Def *prop)
{
Eo_Param_Def *param;
Eo_Accessor_Def *accessor;
if (prop->name)
eina_stringshare_del(prop->name);
EINA_LIST_FREE(prop->params, param)
eo_definitions_param_free(param);
EINA_LIST_FREE(prop->accessors, accessor)
eo_definitions_accessor_free(accessor);
free(prop);
}
void
eo_definitions_method_def_free(Eo_Method_Def *meth)
{
Eo_Param_Def *param;
eo_definitions_ret_free(&meth->ret);
if (meth->name)
eina_stringshare_del(meth->name);
if (meth->comment)
eina_stringshare_del(meth->comment);
if (meth->legacy)
eina_stringshare_del(meth->legacy);
EINA_LIST_FREE(meth->params, param)
eo_definitions_param_free(param);
free(meth);
}
void
eo_definitions_signal_def_free(Eo_Signal_Def *sgn)
{
if (sgn->name)
eina_stringshare_del(sgn->name);
if (sgn->comment)
eina_stringshare_del(sgn->comment);
free(sgn);
}
void
eo_definitions_dfltctor_def_free(Eo_DfltCtor_Def *ctor)
{
if (ctor->name)
eina_stringshare_del(ctor->name);
if (ctor->comment)
eina_stringshare_del(ctor->comment);
free(ctor);
}
void
eo_definitions_dfltdtor_def_free(Eo_DfltDtor_Def *dtor)
{
if (dtor->name)
eina_stringshare_del(dtor->name);
if (dtor->comment)
eina_stringshare_del(dtor->comment);
free(dtor);
}
void
eo_definitions_impl_def_free(Eo_Implement_Def *impl)
{
if (impl->meth_name)
eina_stringshare_del(impl->meth_name);
if (impl->legacy)
free(impl->legacy);
free(impl);
}
void
eo_definitions_class_def_free(Eo_Class_Def *kls)
{
const char *s;
Eina_List *l;
Eo_Property_Def *prop;
Eo_Method_Def *meth;
Eo_Signal_Def *sgn;
Eo_Implement_Def *impl;
if (kls->name)
eina_stringshare_del(kls->name);
if (kls->comment)
eina_stringshare_del(kls->comment);
if (kls->legacy_prefix)
eina_stringshare_del(kls->legacy_prefix);
EINA_LIST_FOREACH(kls->inherits, l, s)
if (s) eina_stringshare_del(s);
EINA_LIST_FREE(kls->implements, impl)
eo_definitions_impl_def_free(impl);
EINA_LIST_FREE(kls->constructors, meth)
eo_definitions_method_def_free(meth);
EINA_LIST_FREE(kls->destructors, meth)
eo_definitions_method_def_free(meth);
EINA_LIST_FREE(kls->properties, prop)
eo_definitions_property_def_free(prop);
EINA_LIST_FREE(kls->methods, meth)
eo_definitions_method_def_free(meth);
EINA_LIST_FREE(kls->signals, sgn)
eo_definitions_signal_def_free(sgn);
if (kls->dflt_ctor) eo_definitions_dfltctor_def_free(kls->dflt_ctor);
if (kls->dflt_dtor) eo_definitions_dfltdtor_def_free(kls->dflt_dtor);
free(kls);
}

View File

@ -0,0 +1,169 @@
#ifndef __EO_DEFINITIONS_H__
#define __EO_DEFINITIONS_H__
#include <Eina.h>
/* RET */
typedef struct _eo_ret_def
{
const char *type;
const char *comment;
} Eo_Ret_Def;
/* PARAM */
typedef enum _param_way
{
PARAM_IN,
PARAM_OUT,
PARAM_INOUT,
PARAM_WAY_LAST
} Param_Way;
typedef struct _eo_param_def
{
Param_Way way;
const char *type;
const char *name;
const char *comment;
} Eo_Param_Def;
/* ACCESSOR */
typedef enum _eo_accessor_type
{
SETTER,
GETTER,
ACCESSOR_TYPE_LAST
} Eo_Accessor_Type;
typedef struct _eo_accessor_param
{
const char *name;
const char *attrs;
} Eo_Accessor_Param;
typedef struct _eo_accessor_def
{
Eo_Accessor_Type type;
Eo_Ret_Def ret;
const char *comment;
const char* legacy;
Eina_List *params; /* List of Eo_Accessor_Param */
} Eo_Accessor_Def;
/* PROPERTY */
typedef struct _eo_property_def
{
const char *name;
Eina_List *params;
Eina_List *accessors;
} Eo_Property_Def;
/* METHOD */
typedef enum _eo_method_type {
METH_REGULAR,
METH_CONSTRUCTOR,
METH_DESTRUCTOR,
METH_TYPE_LAST
} Eo_Method_Type;
typedef struct _eo_method_def
{
Eo_Ret_Def ret;
Eo_Method_Type type;
const char *name;
const char *comment;
Eina_List *params;
const char* legacy;
Eina_Bool obj_const;
} Eo_Method_Def;
/* SIGNAL */
typedef struct _eo_signal_def
{
const char *name;
const char *comment;
} Eo_Signal_Def;
/* DEFAULT CONSTRUCTOR */
typedef struct _eo_dflt_ctor_def
{
const char *name;
const char *comment;
} Eo_DfltCtor_Def;
/* DEFAULT DESTRUCTOR */
typedef struct _eo_dflt_dtor_def
{
const char *name;
const char *comment;
} Eo_DfltDtor_Def;
/* IMPLEMENT */
typedef struct _eo_implement_legacy_param_def
{
const char *eo_name;
const char *legacy_name;
const char *comment;
} Eo_Implement_Legacy_Param_Def;
typedef struct _eo_implement_legacy_def
{
const char *function_name;
Eina_List *params; /* List of Eo_Implement_Legacy_Param_Def * */
const char *ret_type;
const char *ret_value;
} Eo_Implement_Legacy_Def;
typedef struct _eo_implement_def
{
const char *meth_name;
Eo_Implement_Legacy_Def *legacy;
} Eo_Implement_Def;
/* CLASS */
typedef struct _eo_class_def
{
const char *name;
const char *type; /* Regular, RegularNonInstantiable, Mixin and Interface */
const char *comment;
const char *legacy_prefix;
Eina_List *inherits;
Eina_List *implements;
Eina_List *signals;
Eina_List *constructors;
Eina_List *destructors;
Eina_List *properties;
Eina_List *methods;
Eo_DfltCtor_Def *dflt_ctor;
Eo_DfltDtor_Def *dflt_dtor;
} Eo_Class_Def;
void eo_definitions_ret_free(Eo_Ret_Def *ret);
void eo_definitions_param_free(Eo_Param_Def *param);
void eo_definitions_accessor_free(Eo_Accessor_Def *accessor);
void eo_definitions_property_def_free(Eo_Property_Def *prop);
void eo_definitions_method_def_free(Eo_Method_Def *prop);
void eo_definitions_class_def_free(Eo_Class_Def *kls);
void eo_definitions_signal_def_free(Eo_Signal_Def *sgn);
void eo_definitions_dfltctor_def_free(Eo_DfltCtor_Def *ctor);
void eo_definitions_dfltdtor_def_free(Eo_DfltDtor_Def *dtor);
void eo_definitions_impl_def_free(Eo_Implement_Def *impl);
#endif /* __EO_DEFINITIONS_H__ */

2891
src/lib/eolian/eo_lexer.c Normal file

File diff suppressed because it is too large Load Diff

65
src/lib/eolian/eo_lexer.h Normal file
View File

@ -0,0 +1,65 @@
#ifndef __EO_TOKENIZER_H__
#define __EO_TOKENIZER_H__
#include <Eina.h>
#include "eo_definitions.h"
/* TOKENIZER */
#define BUFSIZE 65536
typedef struct _eo_tokenizer
{
/* ragel vars */
int cs; /* current machine state */
int act; /* last pattern matched */
char *ts; /* current token match start */
char *te; /* current token match end */
char *p; /* data start */
char *pe; /* data end */
char *eof; /* eof = (EOF ? pe : NULL) */
/* int stack[10]; /1* state stack used by fret fcall ... *1/ */
/* int top; /1* stack pointer *1/ */
const char *source;
int current_line;
int current_nesting;
int max_nesting;
Eo_Method_Type current_methods_type;
char buf[BUFSIZE];
struct {
char *tok;
int line;
} saved;
Eina_List *classes;
struct {
Eo_Class_Def *kls;
Eo_Property_Def *prop;
Eo_Method_Def *meth;
Eo_Param_Def *param;
Eo_Accessor_Def *accessor;
Eo_Accessor_Param *accessor_param;
Eina_List *str_items;
Eo_Signal_Def *signal;
Eo_Implement_Def *impl;
Eo_Implement_Legacy_Param_Def *impl_leg_param;
} tmp;
} Eo_Tokenizer;
int eo_tokenizer_init();
int eo_tokenizer_shutdown();
Eo_Tokenizer* eo_tokenizer_get(void);
Eina_Bool eo_tokenizer_walk(Eo_Tokenizer *toknz, const char *source);
void eo_tokenizer_dump(Eo_Tokenizer *toknz);
void eo_tokenizer_free(Eo_Tokenizer *toknz);
Eina_Bool eo_tokenizer_database_fill(const char *filename);
#endif /* __EO_TOKENIZER_H__ */

1317
src/lib/eolian/eo_lexer.rl Normal file

File diff suppressed because it is too large Load Diff

23
src/lib/eolian/eolian.c Normal file
View File

@ -0,0 +1,23 @@
#include "Eolian.h"
#include "eolian_database.h"
#include "eo_lexer.h"
Eina_Bool eolian_init()
{
database_init();
eo_tokenizer_init();
return EINA_TRUE;
}
Eina_Bool eolian_shutdown()
{
eo_tokenizer_shutdown();
database_shutdown();
return EINA_TRUE;
}
Eina_Bool eolian_eo_file_parse(const char *filename)
{
return eo_tokenizer_database_fill(filename);
}

View File

@ -0,0 +1,955 @@
#include <Eina.h>
#include "eolian_database.h"
static Eina_Hash *_classes = NULL;
typedef struct
{
Eina_Stringshare *name;
Eolian_Class_Type type;
Eina_Stringshare *description;
Eina_Stringshare *legacy_prefix;
Eolian_Function dflt_ctor;
Eolian_Function dflt_dtor;
Eina_List *inherits; /* List Eina_Stringshare * */
Eina_List *properties; /* List prop_name -> _Function_Id */
Eina_List *methods; /* List meth_name -> _Function_Id */
Eina_List *constructors; /* List constructor_name -> _Function_Id */
Eina_List *destructors; /* List destructor_name -> _Function_Id */
Eina_List *implements; /* List implements name -> _Implement_Desc */
Eina_List *events; /* List event_name -> _Event_Desc */
} Class_desc;
typedef struct
{
Eina_Stringshare *name;
Eina_List *params; /* list of _Parameter_Desc */
Eolian_Function_Type type;
Eina_Hash *data;
Eina_Bool obj_is_const :1; /* True if the object has to be const. Useful for a few methods. */
} _Function_Id;
typedef struct
{
Eina_Stringshare *name;
Eina_Stringshare *type;
Eina_Stringshare *description;
Eolian_Parameter_Dir param_dir;
Eina_Bool is_const :1; /* True if const in this function (e.g get) but not const in the opposite one (e.g set) */
} _Parameter_Desc;
typedef struct
{
Eina_Stringshare *eo_param;
Eina_Stringshare *leg_param;
Eina_Stringshare *comment;
} _Implement_Legacy_Param;
typedef struct
{
Eina_Stringshare *legacy_function_name;
Eina_List *params; /* List of Eolian_Implement_Legacy_Parameter */
Eina_Stringshare *ret_type;
Eina_Stringshare *ret_value;
} _Implement_Legacy_Desc;
typedef struct
{
Eina_Stringshare *class_name;
Eina_Stringshare *func_name;
Eolian_Function_Type type;
Eolian_Implement_Legacy leg_desc;
} _Implement_Desc;
typedef struct
{
Eina_Stringshare *name;
Eina_Stringshare *comment;
} _Event_Desc;
static void
_param_del(_Parameter_Desc *pdesc)
{
eina_stringshare_del(pdesc->name);
eina_stringshare_del(pdesc->type);
eina_stringshare_del(pdesc->description);
free(pdesc);
}
static void
_fid_del(_Function_Id *fid)
{
_Parameter_Desc *param;
eina_stringshare_del(fid->name);
eina_hash_free(fid->data);
EINA_LIST_FREE(fid->params, param) _param_del(param);
free(fid);
}
static void
_class_del(Class_desc *class)
{
Eina_Stringshare *inherit_name;
Eina_List *inherits = class->inherits;
EINA_LIST_FREE(inherits, inherit_name)
eina_stringshare_del(inherit_name);
_Function_Id *fid;
Eolian_Event ev;
EINA_LIST_FREE(class->constructors, fid) _fid_del(fid);
EINA_LIST_FREE(class->methods, fid) _fid_del(fid);
EINA_LIST_FREE(class->properties, fid) _fid_del(fid);
EINA_LIST_FREE(class->events, ev) database_event_free(ev);
eina_stringshare_del(class->name);
eina_stringshare_del(class->description);
eina_stringshare_del(class->legacy_prefix);
free(class);
}
void _hash_free_cb(void *data)
{
Class_desc *cl = data;
_class_del(cl);
}
static Class_desc *
_class_get(const char *class_name)
{
Eina_Stringshare *shr = eina_stringshare_add(class_name);
Class_desc *cl = eina_hash_find(_classes, shr);
eina_stringshare_del(shr);
return cl;
}
Eina_Bool
database_init()
{
eina_init();
if (!_classes)
_classes = eina_hash_stringshared_new(_hash_free_cb);
return EINA_TRUE;
}
Eina_Bool
database_shutdown()
{
eina_hash_free(_classes);
eina_shutdown();
return EINA_TRUE;
}
Eina_Bool
database_class_add(const char *class_name, Eolian_Class_Type type)
{
if (_classes)
{
Class_desc *desc = calloc(1, sizeof(*desc));
desc->name = eina_stringshare_add(class_name);
desc->type = type;
eina_hash_set(_classes, desc->name, desc);
}
return EINA_TRUE;
}
Eolian_Class_Type
eolian_class_type_get(const char *class_name)
{
Class_desc *cl = _class_get(class_name);
return (cl?cl->type:EOLIAN_CLASS_UNKNOWN_TYPE);
}
Eina_Bool
database_class_del(const char *class_name)
{
Class_desc *cl = _class_get(class_name);
if (cl)
{
eina_hash_del(_classes, class_name, NULL);
_class_del(cl);
return EINA_TRUE;
}
return EINA_FALSE;
}
static Eina_Bool _class_name_get(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata)
{
Class_desc *desc = data;
Eina_List **list = fdata;
if (desc && list)
{
*list = eina_list_append(*list, desc->name);
return EINA_TRUE;
}
return EINA_FALSE;
}
const Eina_List *
eolian_class_names_list_get()
{
Eina_List *list = NULL;
eina_hash_foreach(_classes, _class_name_get, &list);
return list;
}
Eina_Bool eolian_class_exists(const char *class_name)
{
return !!_class_get(class_name);
}
Eina_Bool
database_class_inherit_add(const char *class_name, const char *inherit_class_name)
{
Class_desc *desc = _class_get(class_name);
if (!desc) return EINA_FALSE;
desc->inherits = eina_list_append(desc->inherits, eina_stringshare_add(inherit_class_name));
return EINA_TRUE;
}
const char*
eolian_class_description_get(const char *class_name)
{
Class_desc *desc = _class_get(class_name);
return (desc ? desc->description : NULL);
}
void
database_class_description_set(const char *class_name, const char *description)
{
Class_desc *desc = _class_get(class_name);
if (desc) desc->description = eina_stringshare_add(description);
}
const char*
eolian_class_legacy_prefix_get(const char *class_name)
{
Class_desc *desc = _class_get(class_name);
return (desc ? desc->legacy_prefix : NULL);
}
void
database_class_legacy_prefix_set(const char *class_name, const char *legacy_prefix)
{
Class_desc *desc = _class_get(class_name);
if (desc) desc->legacy_prefix = eina_stringshare_add(legacy_prefix);
}
const Eina_List *
eolian_class_inherits_list_get(const char *class_name)
{
Class_desc *desc = _class_get(class_name);
return (desc?desc->inherits:NULL);
}
const Eina_List*
eolian_class_implements_list_get(const char *class_name)
{
Class_desc *desc = _class_get(class_name);
return (desc ? desc->implements : NULL);
}
Eolian_Function
database_function_new(const char *function_name, Eolian_Function_Type foo_type)
{
_Function_Id *fid = calloc(1, sizeof(*fid));
fid->name = eina_stringshare_add(function_name);
fid->type = foo_type;
fid->data = eina_hash_string_superfast_new(free);
return (Eolian_Function) fid;
}
void
database_function_type_set(Eolian_Function function_id, Eolian_Function_Type foo_type)
{
_Function_Id *fid = (_Function_Id *)function_id;
switch (foo_type)
{
case SET:
if (fid->type == GET) foo_type = PROPERTY_FUNC;
break;
case GET:
if (fid->type == SET) foo_type = PROPERTY_FUNC;
break;
default:
break;
}
fid->type = foo_type;
}
Eina_Bool database_class_function_add(const char *class_name, Eolian_Function foo_id)
{
Class_desc *desc = _class_get(class_name);
if (!foo_id || !desc) return EINA_FALSE;
_Function_Id *fid = (_Function_Id *) foo_id;
switch (fid->type)
{
case PROPERTY_FUNC:
case SET:
case GET:
desc->properties = eina_list_append(desc->properties, foo_id);
break;
case METHOD_FUNC:
desc->methods = eina_list_append(desc->methods, foo_id);
break;
case CONSTRUCTOR:
desc->constructors = eina_list_append(desc->constructors, foo_id);
break;
case DFLT_CONSTRUCTOR:
desc->dflt_ctor = foo_id;
break;
case DESTRUCTOR:
desc->destructors = eina_list_append(desc->destructors, foo_id);
break;
case DFLT_DESTRUCTOR:
desc->dflt_dtor = foo_id;
break;
default:
return EINA_FALSE;
}
return EINA_TRUE;
}
Eolian_Implement
database_implement_new(const char *class_name, const char *func_name, Eolian_Function_Type type)
{
if (!class_name || !func_name) return NULL;
_Implement_Desc *impl_desc = calloc(1, sizeof(_Implement_Desc));
if (!impl_desc) return NULL;
impl_desc->class_name = eina_stringshare_add(class_name);
impl_desc->func_name = eina_stringshare_add(func_name);
impl_desc->type = type;
return (Eolian_Implement) impl_desc;
}
Eina_Bool
database_class_implement_add(const char *class_name, Eolian_Implement impl_desc)
{
Class_desc *desc = _class_get(class_name);
if (!impl_desc || !desc) return EINA_FALSE;
desc->implements = eina_list_append(desc->implements, impl_desc);
return EINA_TRUE;
}
Eina_Bool
eolian_implement_information_get(Eolian_Implement impl, const char **class_name, const char **func_name, Eolian_Function_Type *type)
{
_Implement_Desc *_impl = (_Implement_Desc *)impl;
if (!_impl) return EINA_FALSE;
if (class_name) *class_name = _impl->class_name;
if (func_name) *func_name = _impl->func_name;
if (type) *type = _impl->type;
return EINA_TRUE;
}
Eolian_Implement_Legacy
database_implement_legacy_add(Eolian_Implement impl, const char *legacy_function_name)
{
_Implement_Desc *_impl = (_Implement_Desc *)impl;
_impl->leg_desc = calloc(1, sizeof(_Implement_Legacy_Desc));
_Implement_Legacy_Desc *leg_desc = (_Implement_Legacy_Desc *)_impl->leg_desc;
if (leg_desc && legacy_function_name) leg_desc->legacy_function_name = legacy_function_name;
return _impl->leg_desc;
}
Eolian_Implement_Legacy_Parameter
database_implement_legacy_param_add(Eolian_Implement_Legacy leg,
Eina_Stringshare *eo_param, Eina_Stringshare *leg_param,
Eina_Stringshare *comment)
{
_Implement_Legacy_Desc *_leg = (_Implement_Legacy_Desc *)leg;
if (!_leg) return NULL;
_Implement_Legacy_Param *param = calloc(1, sizeof(_Implement_Legacy_Param));
param->eo_param = eo_param;
param->leg_param = leg_param;
param->comment = comment;
_leg->params = eina_list_append(_leg->params, param);
return (Eolian_Implement_Legacy_Parameter) param;
}
Eina_Bool
eolian_implement_legacy_param_info_get(Eolian_Implement_Legacy_Parameter param,
Eina_Stringshare **eo_param, Eina_Stringshare **leg_param,
Eina_Stringshare **comment)
{
_Implement_Legacy_Param *_param = (_Implement_Legacy_Param *)param;
if (!_param) return EINA_FALSE;
if (eo_param) *eo_param = _param->eo_param;
if (leg_param) *leg_param = _param->leg_param;
if (comment) *comment = _param->comment;
return EINA_TRUE;
}
Eina_Bool
database_implement_legacy_return_add(Eolian_Implement_Legacy leg, Eina_Stringshare *ret_type, Eina_Stringshare *ret_value)
{
_Implement_Legacy_Desc *_leg = (_Implement_Legacy_Desc *)leg;
if (!_leg) return EINA_FALSE;
_leg->ret_type = ret_type;
_leg->ret_value = ret_value;
return EINA_TRUE;
}
Eolian_Implement_Legacy
eolian_implement_legacy_desc_get(Eolian_Implement impl)
{
_Implement_Desc *_impl = (_Implement_Desc *)impl;
return (Eolian_Implement_Legacy) (_impl->leg_desc);
}
Eina_Bool
eolian_implement_legacy_information_get(const Eolian_Implement_Legacy leg_desc,
Eina_Stringshare **leg_func_name, Eina_List **params,
Eina_Stringshare **ret_type, Eina_Stringshare **ret_value)
{
_Implement_Legacy_Desc *_leg = (_Implement_Legacy_Desc *)leg_desc;
if (!_leg) return EINA_FALSE;
if (leg_func_name) *leg_func_name = _leg->legacy_function_name;
if (params) *params = _leg->params;
if (ret_type) *ret_type = _leg->ret_type;
if (ret_value) *ret_value = _leg->ret_value;
return EINA_TRUE;
}
Eina_Bool eolian_class_function_exists(const char *class_name, const char *func_name, Eolian_Function_Type f_type)
{
Eina_Bool ret = EINA_FALSE;
Eina_List *itr;
Eolian_Function foo_id;
Class_desc *desc = _class_get(class_name);
switch (f_type)
{
case METHOD_FUNC:
case SET:
case GET:
case PROPERTY_FUNC:
{
EINA_LIST_FOREACH(desc->methods, itr, foo_id)
{
_Function_Id *fid = (_Function_Id *) foo_id;
if (!strcmp(fid->name, func_name))
return EINA_TRUE;
}
EINA_LIST_FOREACH(desc->properties, itr, foo_id)
{
_Function_Id *fid = (_Function_Id *) foo_id;
if (!strcmp(fid->name, func_name))
return EINA_TRUE;
}
break;
}
case CONSTRUCTOR:
{
EINA_LIST_FOREACH(desc->constructors, itr, foo_id)
{
_Function_Id *fid = (_Function_Id *) foo_id;
if (!strcmp(fid->name, func_name))
return EINA_TRUE;
}
break;
}
case DESTRUCTOR:
{
EINA_LIST_FOREACH(desc->destructors, itr, foo_id)
{
_Function_Id *fid = (_Function_Id *) foo_id;
if (!strcmp(fid->name, func_name))
return EINA_TRUE;
}
break;
}
default:
return EINA_FALSE;
}
return ret;
}
const Eina_List *
eolian_class_functions_list_get(const char *class_name, Eolian_Function_Type foo_type)
{
Class_desc *desc = _class_get(class_name);
if (!desc) return NULL;
switch (foo_type)
{
case PROPERTY_FUNC:
return desc->properties;
case METHOD_FUNC:
return desc->methods;
case CONSTRUCTOR:
return desc->constructors;
case DESTRUCTOR:
return desc->destructors;
default: return NULL;
}
}
Eolian_Function
eolian_class_default_constructor_get(const char *class_name)
{
Class_desc *desc = _class_get(class_name);
return desc->dflt_ctor;
}
Eolian_Function
eolian_class_default_destructor_get(const char *class_name)
{
Class_desc *desc = _class_get(class_name);
return desc->dflt_dtor;
}
Eolian_Function_Type
eolian_function_type_get(Eolian_Function function_id)
{
_Function_Id *fid = (_Function_Id *)function_id;
return fid->type;
}
const char *
eolian_function_name_get(Eolian_Function function_id)
{
_Function_Id *fid = (_Function_Id *)function_id;
return fid->name;
}
void
database_function_data_set(Eolian_Function function_id, const char *key, const char *data)
{
_Function_Id *fid = (_Function_Id *)function_id;
EINA_SAFETY_ON_NULL_RETURN(key);
if (data)
{
if (!eina_hash_find(fid->data, key))
eina_hash_set(fid->data, key, strdup(data));
}
else
{
eina_hash_del(fid->data, key, NULL);
}
}
const char *
eolian_function_data_get(Eolian_Function function_id, const char *key)
{
_Function_Id *fid = (_Function_Id *)function_id;
return (fid ? eina_hash_find(fid->data, key) : NULL);
}
Eolian_Function_Parameter
database_function_parameter_add(Eolian_Function foo_id, Eolian_Parameter_Dir param_dir, const char *type, const char *name, const char *description)
{
_Parameter_Desc *param = NULL;
_Function_Id *fid = (_Function_Id *)foo_id;
if (fid)
{
param = calloc(1, sizeof(*param));
param->param_dir = param_dir;
param->name = eina_stringshare_add(name);
param->type = eina_stringshare_add(type);
param->description = eina_stringshare_add(description);
fid->params = eina_list_append(fid->params, param);
}
return (Eolian_Function_Parameter) param;
}
Eolian_Function_Parameter
eolian_function_parameter_get(const Eolian_Function foo_id, const char *param_name)
{
_Function_Id *fid = (_Function_Id *)foo_id;
if (fid)
{
Eina_List *itr;
_Parameter_Desc *param;
EINA_LIST_FOREACH(fid->params, itr, param)
if (!strcmp(param->name, param_name)) return (Eolian_Function_Parameter)param;
}
return NULL;
}
Eina_Stringshare*
eolian_parameter_type_get(const Eolian_Function_Parameter param)
{
eina_stringshare_ref(((_Parameter_Desc*)param)->type);
return ((_Parameter_Desc*)param)->type;
}
Eina_Stringshare*
eolian_parameter_name_get(const Eolian_Function_Parameter param)
{
eina_stringshare_ref(((_Parameter_Desc*)param)->name);
return ((_Parameter_Desc*)param)->name;
}
const Eina_List *
eolian_parameters_list_get(Eolian_Function foo_id)
{
_Function_Id *fid = (_Function_Id *)foo_id;
return (fid?fid->params:NULL);
}
/* Get parameter information */
void
eolian_parameter_information_get(Eolian_Function_Parameter param_desc, Eolian_Parameter_Dir *param_dir, const char **type, const char **name, const char **description)
{
_Parameter_Desc *param = (_Parameter_Desc *)param_desc;
if (!param) return;
if (param_dir) *param_dir = param->param_dir;
if (type) *type = param->type;
if (name) *name = param->name;
if (description) *description = param->description;
}
void
database_parameter_get_const_attribute_set(Eolian_Function_Parameter param_desc, Eina_Bool is_const)
{
_Parameter_Desc *param = (_Parameter_Desc *)param_desc;
if (!param) return;
param->is_const = is_const;
}
Eina_Bool
eolian_parameter_get_const_attribute_get(Eolian_Function_Parameter param_desc)
{
_Parameter_Desc *param = (_Parameter_Desc *)param_desc;
return param?param->is_const:EINA_FALSE;
}
void database_function_return_type_set(Eolian_Function foo_id, Eolian_Function_Type ftype, const char *ret_type)
{
const char *key = NULL;
switch (ftype)
{
case SET: key= EOLIAN_PROP_SET_RETURN_TYPE; break;
case GET: key = EOLIAN_PROP_GET_RETURN_TYPE; break;
case METHOD_FUNC: key = EOLIAN_METHOD_RETURN_TYPE; break;
default: return;
}
database_function_data_set(foo_id, key, ret_type);
}
const char *eolian_function_return_type_get(Eolian_Function foo_id, Eolian_Function_Type ftype)
{
const char *key = NULL;
switch (ftype)
{
case SET: key= EOLIAN_PROP_SET_RETURN_TYPE; break;
case GET: key = EOLIAN_PROP_GET_RETURN_TYPE; break;
case UNRESOLVED: case METHOD_FUNC: key = EOLIAN_METHOD_RETURN_TYPE; break;
default: return NULL;
}
const char *ret = eolian_function_data_get(foo_id, key);
if (!ret) ret = "void";
return ret;
}
void
database_function_object_set_as_const(Eolian_Function foo_id, Eina_Bool is_const)
{
_Function_Id *fid = (_Function_Id *)foo_id;
if (fid)
{
fid->obj_is_const = is_const;
}
}
Eina_Bool
eolian_function_object_is_const(Eolian_Function foo_id)
{
_Function_Id *fid = (_Function_Id *)foo_id;
return (fid?fid->obj_is_const:EINA_FALSE);
}
Eolian_Event
database_event_new(const char *event_name, const char *event_comment)
{
if (!event_name) return NULL;
_Event_Desc *event_desc = calloc(1, sizeof(_Event_Desc));
if (!event_desc) return NULL;
event_desc->name = eina_stringshare_add(event_name);
event_desc->comment = eina_stringshare_add(event_comment);
return (Eolian_Event) event_desc;
}
void
database_event_free(Eolian_Event event)
{
_Event_Desc *event_desc = (_Event_Desc *)event;
eina_stringshare_del(event_desc->name);
eina_stringshare_del(event_desc->comment);
free(event_desc);
}
Eina_Bool
database_class_event_add(const char *class_name, Eolian_Event event_desc)
{
Class_desc *desc = _class_get(class_name);
if (!event_desc || !desc) return EINA_FALSE;
desc->events = eina_list_append(desc->events, event_desc);
return EINA_TRUE;
}
const Eina_List*
eolian_class_events_list_get(const char *class_name)
{
Class_desc *desc = _class_get(class_name);
return (desc ? desc->events : NULL);
}
Eina_Bool
eolian_class_event_information_get(Eolian_Event event, const char **event_name, const char **event_comment)
{
_Event_Desc *_event_desc = (_Event_Desc *) event;
if (!_event_desc) return EINA_FALSE;
if (event_name) *event_name = _event_desc->name;
if (event_comment) *event_comment = _event_desc->comment;
return EINA_TRUE;
}
static void
_implements_print(Eolian_Implement impl, int nb_spaces)
{
const char *t, *cl, *fn;
Eolian_Function_Type ft;
eolian_implement_information_get(impl, &cl, &fn, &ft);
switch (ft)
{
case SET: t = "SET"; break;
case GET: t = "GET"; break;
case METHOD_FUNC: t = "METHOD"; break;
case UNRESOLVED:
{
t = "Type is the same as function being overriden";
break;
}
default:
return;
}
printf("%*s <%s :: %s> <%s>\n", nb_spaces + 5, "", cl, fn, t);
Eolian_Implement_Legacy leg_desc = eolian_implement_legacy_desc_get(impl);
if (leg_desc)
{
Eina_Stringshare *func_name, *ret_type, *ret_value;
Eina_List *params = NULL;
eolian_implement_legacy_information_get(leg_desc, &func_name, &params, &ret_type, &ret_value);
printf("%*s Legacy\n", nb_spaces + 8, "");
if (func_name) printf("%*s Function name: %s\n", nb_spaces + 11, "", func_name);
if (ret_type && ret_value)
printf("%*s Return %s::%s\n", nb_spaces + 11, "", ret_type, ret_value);
if (params)
{
printf("%*s Params:\n", nb_spaces + 11, "");
Eina_List *itr;
Eolian_Implement_Legacy_Parameter p;
EINA_LIST_FOREACH(params, itr, p)
{
Eina_Stringshare *eo_param, *leg_param, *comment;
eolian_implement_legacy_param_info_get(p, &eo_param, &leg_param, &comment);
printf("%*s %s -> %s <%s>\n", nb_spaces + 14, "", eo_param, leg_param, comment);
}
}
}
}
static void
_event_print(Eolian_Event ev, int nb_spaces)
{
const char *name, *comment;
eolian_class_event_information_get(ev, &name, &comment);
printf("%*s <%s> <%s>\n", nb_spaces + 5, "", name, comment);
}
static Eina_Bool _function_print(const _Function_Id *fid, int nb_spaces)
{
Eolian_Function foo_id = (Eolian_Function) fid;
const char *ret_desc = eolian_function_description_get(foo_id, EOLIAN_RETURN_COMMENT);
switch (fid->type)
{
case PROPERTY_FUNC:
{
printf("%*s<%s> %s\n", nb_spaces, "", ret_desc ? ret_desc : "", fid->name);
const char *str = eolian_function_description_get(foo_id, EOLIAN_COMMENT_GET);
if (str) printf("%*s<%s>\n", nb_spaces + 5, "", (str ? str : ""));
str = eolian_function_description_get(foo_id, EOLIAN_COMMENT_SET);
if (str) printf("%*s<%s>\n", nb_spaces + 5, "", (str ? str : ""));
str = eolian_function_data_get(foo_id, EOLIAN_LEGACY_GET);
if (str) printf("%*slegacy_get: <%s>\n", nb_spaces + 5, "", (str ? str : ""));
str = eolian_function_data_get(foo_id, EOLIAN_LEGACY_SET);
if (str) printf("%*slegacy_set: <%s>\n", nb_spaces + 5, "", (str ? str : ""));
str = eolian_function_data_get(foo_id, EOLIAN_PROP_GET_RETURN_TYPE);
if (str) printf("%*sreturn type for get: <%s>\n", nb_spaces + 5, "", (str ? str : ""));
str = eolian_function_data_get(foo_id, EOLIAN_PROP_SET_RETURN_TYPE);
if (str) printf("%*sreturn type for set: <%s>\n", nb_spaces + 5, "", (str ? str : ""));
break;
}
case GET:
{
printf("%*sGET:<%s> %s\n", nb_spaces, "", ret_desc ? ret_desc : "", fid->name);
const char *str = eolian_function_description_get(foo_id, EOLIAN_COMMENT_GET);
if (str) printf("%*s<%s>\n", nb_spaces + 5, "", (str ? str : ""));
str = eolian_function_data_get(foo_id, EOLIAN_LEGACY_GET);
if (str) printf("%*slegacy: <%s>\n", nb_spaces + 5, "", (str ? str : ""));
str = eolian_function_data_get(foo_id, EOLIAN_PROP_GET_RETURN_TYPE);
if (str) printf("%*sreturn type: <%s>\n", nb_spaces + 5, "", (str ? str : ""));
break;
}
case SET:
{
printf("%*sSET:<%s> %s\n", nb_spaces, "", ret_desc ? ret_desc : "", fid->name);
const char *str = eolian_function_description_get(foo_id, EOLIAN_COMMENT_SET);
if (str) printf("%*s<%s>\n", nb_spaces + 5, "", (str ? str : ""));
str = eolian_function_data_get(foo_id, EOLIAN_LEGACY_SET);
if (str) printf("%*slegacy: <%s>\n", nb_spaces + 5, "", (str ? str : ""));
str = eolian_function_data_get(foo_id, EOLIAN_PROP_SET_RETURN_TYPE);
if (str) printf("%*sreturn type: <%s>\n", nb_spaces + 5, "", (str ? str : ""));
break;
}
case METHOD_FUNC:
{
printf("%*s<%s> %s\n", nb_spaces, "", ret_desc ? ret_desc : "", fid->name);
const char *str = eolian_function_description_get(foo_id, EOLIAN_COMMENT);
if (str) printf("%*s<%s>\n", nb_spaces + 5, "", (str ? str : ""));
str = eolian_function_data_get(foo_id, EOLIAN_LEGACY);
if (str) printf("%*slegacy: <%s>\n", nb_spaces + 5, "", (str ? str : ""));
str = eolian_function_data_get(foo_id, EOLIAN_METHOD_RETURN_TYPE);
if (str) printf("%*sreturn type: <%s>\n", nb_spaces + 5, "", (str ? str : ""));
if (fid->obj_is_const) printf("%*sobj const: <true>\n", nb_spaces + 5, "");
break;
}
case CONSTRUCTOR:
case DESTRUCTOR:
{
//char *str = eina_hash_find(fid->data, "comment");
const char *str = eolian_function_description_get(foo_id, EOLIAN_COMMENT);
if (str) printf("%*s<%s>\n", nb_spaces + 5, "", (str ? str : ""));
str = eolian_function_data_get(foo_id, EOLIAN_LEGACY);
if (str) printf("%*slegacy: <%s>\n", nb_spaces + 5, "", (str ? str : ""));
str = eolian_function_data_get(foo_id, EOLIAN_METHOD_RETURN_TYPE);
if (str) printf("%*sreturn type: <%s>\n", nb_spaces + 5, "", (str ? str : ""));
break;
}
default:
return EINA_FALSE;
}
Eina_List *itr;
_Parameter_Desc *param;
EINA_LIST_FOREACH(fid->params, itr, param)
{
char *param_dir = NULL;
switch (param->param_dir)
{
case EOLIAN_IN_PARAM:
param_dir = "IN";
break;
case EOLIAN_OUT_PARAM:
param_dir = "OUT";
break;
case EOLIAN_INOUT_PARAM:
param_dir = "INOUT";
break;
}
printf("%*s%s <%s> <%s> <%s>\n", nb_spaces + 5, "", param_dir, param->name, param->type, (param->description?param->description:""));
}
return EINA_TRUE;
}
static Eina_Bool _class_print(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
{
Eina_List *itr;
_Function_Id *function;
const char *types[5] = {"", "Regular", "Regular Non Instantiable", "Mixin", "Interface"};
Class_desc *desc = data;
if (!desc) return EINA_FALSE;
printf("Class %s:\n", desc->name);
if (desc->description)
printf(" description: <%s>\n", desc->description);
printf(" type: %s\n", types[desc->type]);
// Inherits
if (desc->inherits)
{
printf(" inherits: ");
char *word;
EINA_LIST_FOREACH(desc->inherits, itr, word)
{
printf("%s ", word);
}
printf("\n");
}
// Legacy prefix
if (desc->legacy_prefix)
{
printf(" legacy prefix: <%s>\n", desc->legacy_prefix);
}
// Default constructor
if (desc->dflt_ctor)
{
printf(" default constructor: present - description <%s>\n", eolian_function_description_get(desc->dflt_ctor, "comment"));
}
// Default destructor
if (desc->dflt_dtor)
{
printf(" default destructor: present - description <%s>\n", eolian_function_description_get(desc->dflt_dtor, "comment"));
}
// Constructors
printf(" constructors:\n");
EINA_LIST_FOREACH(desc->constructors, itr, function)
{
_function_print(function, 4);
}
printf("\n");
// Properties
printf(" properties:\n");
EINA_LIST_FOREACH(desc->properties, itr, function)
{
_function_print(function, 4);
}
printf("\n");
// Methods
printf(" methods:\n");
EINA_LIST_FOREACH(desc->methods, itr, function)
{
_function_print(function, 4);
}
// Implement
printf(" implements:\n");
Eolian_Implement impl;
EINA_LIST_FOREACH((Eina_List *) eolian_class_implements_list_get(desc->name), itr, impl)
{
_implements_print(impl, 4);
}
printf("\n");
// Implement
printf(" events:\n");
Eolian_Event ev;
EINA_LIST_FOREACH((Eina_List *) eolian_class_events_list_get(desc->name), itr, ev)
{
_event_print(ev, 4);
}
printf("\n");
return EINA_TRUE;
}
Eina_Bool eolian_show(const char *class_name)
{
if (!class_name)
eina_hash_foreach(_classes, _class_print, NULL);
else
{
Class_desc *klass = _class_get(class_name);
_class_print(NULL, NULL, klass, NULL);
}
return EINA_TRUE;
}

View File

@ -0,0 +1,78 @@
#ifndef __EOLIAN_DATABASE_H
#define __EOLIAN_DATABASE_H
#include <Eolian.h>
Eina_Bool database_init();
Eina_Bool database_shutdown();
/* Add a class in the database */
Eina_Bool database_class_add(const char *class_name, Eolian_Class_Type type);
/* Add a class from the database */
Eina_Bool
database_class_del(const char *class_name);
/* Add an inherit class name to a class */
Eina_Bool database_class_inherit_add(const char *class_name, const char *inherit_class_name);
/* Set description of class. */
void
database_class_description_set(const char *class_name, const char *description);
/* Set legacy of class. */
void
database_class_legacy_prefix_set(const char *class_name, const char *legacy_prefix);
/* Create a function */
Eolian_Function database_function_new(const char *function_name, Eolian_Function_Type foo_type);
/* Set a type to a function */
void database_function_type_set(Eolian_Function function_id, Eolian_Function_Type foo_type);
/* Add a function to a class */
Eina_Bool database_class_function_add(const char *classname, Eolian_Function foo_id);
void database_function_data_set(Eolian_Function function_id, const char *key, const char *description);
/* Add a description to a function */
#define database_function_description_set(foo_id, key, desc) database_function_data_set((foo_id), (key), (desc))
/* Add a parameter to a function */
Eolian_Function_Parameter database_function_parameter_add(Eolian_Function foo_id, Eolian_Parameter_Dir param_dir, const char *type, const char *name, const char *description);
void database_parameter_get_const_attribute_set(Eolian_Function_Parameter param_desc, Eina_Bool is_const);
void database_function_return_type_set(Eolian_Function foo_id, Eolian_Function_Type ftype, const char *ret_type);
void database_function_object_set_as_const(Eolian_Function foo_id, Eina_Bool is_const);
/* Need to add API for callbacks and implements */
Eolian_Implement
database_implement_new(const char *class_name, const char *func_name, Eolian_Function_Type type);
Eolian_Implement_Legacy
database_implement_legacy_add(Eolian_Implement impl, const char *legacy_func_name);
Eolian_Implement_Legacy_Parameter
database_implement_legacy_param_add(Eolian_Implement_Legacy leg,
Eina_Stringshare *eo_param, Eina_Stringshare *leg_param,
Eina_Stringshare *comment);
Eina_Bool
database_implement_legacy_return_add(Eolian_Implement_Legacy leg, Eina_Stringshare *ret_type, Eina_Stringshare *ret_value);
Eina_Bool
database_class_implement_add(const char *class_name, Eolian_Implement impl_id);
Eolian_Event
database_event_new(const char *event_name, const char *event_desc);
void
database_event_free(Eolian_Event event);
Eina_Bool
database_class_event_add(const char *class_name, Eolian_Event event_desc);
#endif