Eolian: first import.
authorDaniel Zaoui <daniel.zaoui@samsung.com>
Tue, 11 Feb 2014 13:42:59 +0000 (13:42 +0000)
committerDaniel Zaoui <daniel.zaoui@samsung.com>
Mon, 3 Mar 2014 12:09:53 +0000 (14:09 +0200)
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>
17 files changed:
pc/eolian.pc.in [new file with mode: 0644]
src/bin/eolian/common_funcs.c [new file with mode: 0644]
src/bin/eolian/common_funcs.h [new file with mode: 0644]
src/bin/eolian/eo1_generator.c [new file with mode: 0644]
src/bin/eolian/eo1_generator.h [new file with mode: 0644]
src/bin/eolian/legacy_generator.c [new file with mode: 0644]
src/bin/eolian/legacy_generator.h [new file with mode: 0644]
src/bin/eolian/main.c [new file with mode: 0644]
src/lib/eolian/Eolian.h [new file with mode: 0644]
src/lib/eolian/eo_definitions.c [new file with mode: 0644]
src/lib/eolian/eo_definitions.h [new file with mode: 0644]
src/lib/eolian/eo_lexer.c [new file with mode: 0644]
src/lib/eolian/eo_lexer.h [new file with mode: 0644]
src/lib/eolian/eo_lexer.rl [new file with mode: 0644]
src/lib/eolian/eolian.c [new file with mode: 0644]
src/lib/eolian/eolian_database.c [new file with mode: 0644]
src/lib/eolian/eolian_database.h [new file with mode: 0644]

diff --git a/pc/eolian.pc.in b/pc/eolian.pc.in
new file mode 100644 (file)
index 0000000..093bab5
--- /dev/null
@@ -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
diff --git a/src/bin/eolian/common_funcs.c b/src/bin/eolian/common_funcs.c
new file mode 100644 (file)
index 0000000..dbd2c32
--- /dev/null
@@ -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);
+}
+
diff --git a/src/bin/eolian/common_funcs.h b/src/bin/eolian/common_funcs.h
new file mode 100644 (file)
index 0000000..d0c67e0
--- /dev/null
@@ -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
diff --git a/src/bin/eolian/eo1_generator.c b/src/bin/eolian/eo1_generator.c
new file mode 100644 (file)
index 0000000..c67576c
--- /dev/null
@@ -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;
+}
+
diff --git a/src/bin/eolian/eo1_generator.h b/src/bin/eolian/eo1_generator.h
new file mode 100644 (file)
index 0000000..7a03095
--- /dev/null
@@ -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
+
diff --git a/src/bin/eolian/legacy_generator.c b/src/bin/eolian/legacy_generator.c
new file mode 100644 (file)
index 0000000..2077728
--- /dev/null
@@ -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;
+}
+
diff --git a/src/bin/eolian/legacy_generator.h b/src/bin/eolian/legacy_generator.h
new file mode 100644 (file)
index 0000000..5f22afa
--- /dev/null
@@ -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
+
diff --git a/src/bin/eolian/main.c b/src/bin/eolian/main.c
new file mode 100644 (file)
index 0000000..c47376d
--- /dev/null
@@ -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;
+}
diff --git a/src/lib/eolian/Eolian.h b/src/lib/eolian/Eolian.h
new file mode 100644 (file)
index 0000000..60a9a2e
--- /dev/null
@@ -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
diff --git a/src/lib/eolian/eo_definitions.c b/src/lib/eolian/eo_definitions.c
new file mode 100644 (file)
index 0000000..12d8df4
--- /dev/null
@@ -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);
+}
+
diff --git a/src/lib/eolian/eo_definitions.h b/src/lib/eolian/eo_definitions.h
new file mode 100644 (file)
index 0000000..23e9ed4
--- /dev/null
@@ -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__ */
diff --git a/src/lib/eolian/eo_lexer.c b/src/lib/eolian/eo_lexer.c
new file mode 100644 (file)
index 0000000..97c4eb6
--- /dev/null
@@ -0,0 +1,2891 @@
+
+#line 1 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <Eina.h>
+
+#include "eo_lexer.h"
+#include "eolian_database.h"
+
+static int _eo_tokenizer_log_dom = -1;
+#ifdef CRITICAL
+#undef CRITICAL
+#endif
+#define CRITICAL(...) EINA_LOG_DOM_CRIT(_eo_tokenizer_log_dom, __VA_ARGS__)
+
+#ifdef ERR
+#undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_eo_tokenizer_log_dom, __VA_ARGS__)
+
+#ifdef WRN
+#undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(_eo_tokenizer_log_dom, __VA_ARGS__)
+
+#ifdef INF
+#undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_eo_tokenizer_log_dom, __VA_ARGS__)
+
+#ifdef DBG
+#undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_eo_tokenizer_log_dom, __VA_ARGS__)
+
+static int _init_counter = 0;
+
+int
+eo_tokenizer_init()
+{
+   if (!_init_counter)
+     {
+        eina_init();
+        eina_log_color_disable_set(EINA_FALSE);
+        _eo_tokenizer_log_dom = eina_log_domain_register("eo_toknz", EINA_COLOR_CYAN);
+     }
+   return _init_counter++;
+}
+
+int
+eo_tokenizer_shutdown()
+{
+   if (_init_counter <= 0) return 0;
+   _init_counter--;
+   if (!_init_counter)
+     {
+        eina_log_domain_unregister(_eo_tokenizer_log_dom);
+        _eo_tokenizer_log_dom = -1;
+        eina_shutdown();
+     }
+   return _init_counter;
+}
+
+static void
+_eo_tokenizer_abort(Eo_Tokenizer *toknz,
+                    const char *file, const char* fct, int line,
+                    const char *fmt, ...)
+{
+   va_list ap;
+   va_start (ap, fmt);
+   eina_log_vprint(_eo_tokenizer_log_dom, EINA_LOG_LEVEL_ERR,
+                   file, fct, line, fmt, ap);
+   va_end(ap);
+   fprintf(stderr, "File:%s\n toknz[%d] n:%d l:%d p:%d pe:%d ts:%s te:%s act:%d\n",
+          toknz->source,
+          toknz->cs, toknz->current_nesting, toknz->current_line,
+          (int)(toknz->p - toknz->buf), (int)(toknz->pe - toknz->buf),
+          toknz->ts, toknz->te, toknz->act);
+   exit(EXIT_FAILURE);
+}
+#define ABORT(toknz, ...) \
+   _eo_tokenizer_abort(toknz, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__);
+
+static void _eo_tokenizer_normalize_buf(char *buf)
+{
+   int c;
+   char *s, *d;
+   Eina_Bool in_space = EINA_TRUE;
+   Eina_Bool in_newline = EINA_FALSE;
+
+   /* ' '+ -> ' '
+    * '\n' ' '* '*' ' '* -> '\n'
+    */
+   for (s = buf, d = buf; *s != '\0'; s++)
+     {
+        c = *s;
+        *d = c;
+
+        if (!in_space || (c != ' '))
+          d++;
+
+        if (c == ' ')
+          in_space = EINA_TRUE;
+        else
+          in_space = EINA_FALSE;
+
+        if (c == '\n')
+          {
+             in_newline = EINA_TRUE;
+             in_space = EINA_TRUE;
+          }
+        else if (in_newline && c == '*' )
+          {
+             in_space = EINA_TRUE;
+             in_newline = EINA_FALSE;
+             d--;
+          }
+     }
+   /* ' '+$ -> $ */
+   d--;
+   while (*d == ' ') d--;
+   d++;
+   if (d < buf) return;
+   *d = '\0';
+}
+
+static const char*
+_eo_tokenizer_token_get(Eo_Tokenizer *toknz, char *p)
+{
+   if (toknz->saved.tok == NULL) ABORT(toknz, "toknz->saved.tok is NULL");
+   char d[BUFSIZE];
+   int l = (p - toknz->saved.tok);
+   memcpy(d, toknz->saved.tok, l);
+   d[l] = '\0';
+   _eo_tokenizer_normalize_buf(d);
+   toknz->saved.tok = NULL;
+   DBG("token : >%s<", d);
+   return eina_stringshare_add(d);
+}
+
+static Eo_Class_Def*
+_eo_tokenizer_class_get(Eo_Tokenizer *toknz, char *p)
+{
+   Eo_Class_Def *kls = calloc(1, sizeof(Eo_Class_Def));
+   if (kls == NULL) ABORT(toknz, "calloc Eo_Class_Def failure");
+
+   kls->name = _eo_tokenizer_token_get(toknz, p);
+
+   return kls;
+}
+
+static Eo_Property_Def*
+_eo_tokenizer_property_get(Eo_Tokenizer *toknz, char *p)
+{
+   Eo_Property_Def *prop = calloc(1, sizeof(Eo_Property_Def));
+   if (prop == NULL) ABORT(toknz, "calloc Eo_Property_Def failure");
+
+   prop->name = _eo_tokenizer_token_get(toknz, p);
+
+   return prop;
+}
+
+static Eo_Method_Def*
+_eo_tokenizer_method_get(Eo_Tokenizer *toknz, char *p)
+{
+   Eo_Method_Def *meth = calloc(1, sizeof(Eo_Method_Def));
+   if (meth == NULL) ABORT(toknz, "calloc Eo_Method_Def failure");
+
+   meth->name = _eo_tokenizer_token_get(toknz, p);
+
+   return meth;
+}
+
+static Eo_Param_Def*
+_eo_tokenizer_param_get(Eo_Tokenizer *toknz, char *p)
+{
+   char *s;
+
+   Eo_Param_Def *param = calloc(1, sizeof(Eo_Param_Def));
+   if (param == NULL) ABORT(toknz, "calloc Eo_Param_Def failure");
+
+   s = p - 1; /* Don't look at ';' */
+   /* Remove any space between the param name and ';'
+    * This loop fixes the case where "char *name ;" becomes the type of the param.
+    */
+   while (*s == ' ') s--;
+   for (; s >= toknz->saved.tok; s--)
+     {
+        if ((*s == ' ') || (*s == '*'))
+          break;
+     }
+
+   if (s == toknz->saved.tok)
+     ABORT(toknz, "wrong parameter: %s", _eo_tokenizer_token_get(toknz, p));
+   s++;
+
+   param->way = PARAM_IN;
+   if (strncmp(toknz->saved.tok, "in ", 3) == 0)
+     {
+        toknz->saved.tok += 3;
+        param->way = PARAM_IN;
+     }
+   else if (strncmp(toknz->saved.tok, "out ", 4) == 0)
+     {
+        toknz->saved.tok += 4;
+        param->way = PARAM_OUT;
+     }
+   else if (strncmp(toknz->saved.tok, "inout ", 6) == 0)
+     {
+        toknz->saved.tok += 6;
+        param->way = PARAM_INOUT;
+     }
+
+   param->type = _eo_tokenizer_token_get(toknz, s);
+
+   toknz->saved.tok = s;
+   param->name = _eo_tokenizer_token_get(toknz, p);
+
+   return param;
+}
+
+static Eo_Accessor_Param*
+_eo_tokenizer_accessor_param_get(Eo_Tokenizer *toknz, char *p)
+{
+   Eo_Accessor_Param *param = calloc(1, sizeof(Eo_Accessor_Param));
+   if (param == NULL) ABORT(toknz, "calloc Eo_Accessor_Param failure");
+
+   /* Remove the colon and spaces - we just need the param name */
+   while (*p == ':') p--;
+   while (*p == ' ') p--;
+   param->name = _eo_tokenizer_token_get(toknz, p);
+
+   return param;
+}
+
+static Eo_Accessor_Def *
+_eo_tokenizer_accessor_get(Eo_Tokenizer *toknz, Eo_Accessor_Type type)
+{
+   Eo_Accessor_Def *accessor = calloc(1, sizeof(Eo_Accessor_Def));
+   if (accessor == NULL) ABORT(toknz, "calloc Eo_Accessor_Def failure");
+
+   accessor->type = type;
+
+   return accessor;
+}
+
+static Eo_Signal_Def*
+_eo_tokenizer_signal_get(Eo_Tokenizer *toknz, char *p)
+{
+   Eo_Signal_Def *sgn = calloc(1, sizeof(Eo_Signal_Def));
+   if (sgn == NULL) ABORT(toknz, "calloc Eo_Signal_Def failure");
+
+   sgn->name = _eo_tokenizer_token_get(toknz, p);
+
+   return sgn;
+}
+
+static Eo_DfltCtor_Def*
+_eo_tokenizer_dflt_ctor_get(Eo_Tokenizer *toknz, char *p)
+{
+   Eo_DfltCtor_Def *ctor = calloc(1, sizeof(Eo_DfltCtor_Def));
+   if (ctor == NULL) ABORT(toknz, "calloc Eo_DfltCtor_Def failure");
+
+   ctor->name = _eo_tokenizer_token_get(toknz, p);
+
+   return ctor;
+}
+
+static Eo_DfltDtor_Def*
+_eo_tokenizer_dflt_dtor_get(Eo_Tokenizer *toknz, char *p)
+{
+   Eo_DfltDtor_Def *dtor = calloc(1, sizeof(Eo_DfltDtor_Def));
+   if (dtor == NULL) ABORT(toknz, "calloc Eo_DfltDtor_Def failure");
+
+   dtor->name = _eo_tokenizer_token_get(toknz, p);
+
+   return dtor;
+}
+
+static Eo_Implement_Def*
+_eo_tokenizer_implement_get(Eo_Tokenizer *toknz, char *p)
+{
+   Eo_Implement_Def *impl = calloc(1, sizeof(Eo_Implement_Def));
+   if (impl == NULL) ABORT(toknz, "calloc Eo_DfltDtor_Def failure");
+
+   impl->meth_name = _eo_tokenizer_token_get(toknz, p);
+
+   return impl;
+}
+
+
+#line 364 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+
+
+
+#line 298 "eo_lexer.c"
+static const char _eo_tokenizer_actions[] = {
+       0, 1, 0, 1, 2, 1, 6, 1, 
+       10, 1, 15, 1, 16, 1, 17, 1, 
+       18, 1, 19, 1, 20, 1, 21, 1, 
+       22, 1, 23, 1, 24, 1, 25, 1, 
+       26, 1, 27, 1, 28, 1, 29, 1, 
+       30, 1, 31, 1, 32, 1, 33, 1, 
+       34, 1, 35, 1, 36, 1, 37, 1, 
+       38, 1, 41, 1, 42, 1, 43, 1, 
+       44, 1, 45, 1, 46, 1, 47, 1, 
+       48, 1, 49, 1, 50, 1, 51, 1, 
+       52, 1, 53, 1, 54, 1, 55, 1, 
+       56, 1, 57, 1, 58, 1, 59, 1, 
+       60, 1, 61, 1, 62, 1, 63, 1, 
+       64, 1, 65, 1, 66, 1, 67, 1, 
+       68, 1, 69, 1, 70, 1, 71, 1, 
+       72, 1, 73, 1, 74, 1, 77, 1, 
+       78, 1, 79, 1, 80, 1, 81, 1, 
+       82, 1, 83, 1, 84, 1, 85, 1, 
+       86, 1, 87, 1, 88, 1, 89, 1, 
+       90, 1, 91, 1, 92, 1, 93, 1, 
+       94, 1, 95, 1, 96, 1, 97, 1, 
+       98, 1, 99, 1, 100, 1, 101, 1, 
+       102, 1, 103, 1, 104, 1, 105, 1, 
+       106, 1, 107, 1, 108, 1, 109, 1, 
+       110, 1, 111, 1, 112, 1, 113, 1, 
+       114, 1, 115, 2, 0, 38, 2, 0, 
+       48, 2, 0, 56, 2, 0, 65, 2, 
+       0, 73, 2, 0, 84, 2, 0, 92, 
+       2, 0, 110, 2, 4, 44, 2, 5, 
+       39, 2, 6, 2, 2, 7, 40, 2, 
+       8, 52, 2, 10, 0, 2, 10, 66, 
+       2, 12, 80, 2, 13, 75, 2, 14, 
+       76, 2, 15, 0, 2, 15, 85, 2, 
+       16, 0, 2, 17, 0, 2, 18, 0, 
+       2, 18, 2, 2, 19, 0, 2, 21, 
+       0, 2, 22, 0, 2, 22, 104, 2, 
+       23, 0, 2, 23, 105, 2, 24, 0, 
+       2, 25, 0, 2, 25, 2, 2, 26, 
+       0, 2, 28, 0, 2, 29, 0, 2, 
+       29, 2, 2, 32, 0, 2, 32, 111, 
+       2, 33, 0, 2, 33, 111, 2, 36, 
+       1, 2, 36, 2, 2, 36, 3, 2, 
+       36, 9, 2, 36, 11, 2, 36, 19, 
+       2, 36, 21
+};
+
+static const short _eo_tokenizer_key_offsets[] = {
+       0, 2, 5, 6, 20, 24, 32, 33, 
+       36, 42, 43, 44, 45, 46, 47, 48, 
+       49, 50, 54, 55, 56, 57, 58, 59, 
+       60, 61, 62, 63, 64, 69, 70, 71, 
+       72, 73, 74, 75, 76, 77, 78, 79, 
+       80, 81, 82, 85, 87, 90, 101, 103, 
+       106, 107, 118, 122, 129, 136, 148, 160, 
+       172, 184, 196, 207, 215, 222, 230, 242, 
+       254, 266, 278, 289, 297, 308, 320, 324, 
+       325, 326, 336, 338, 341, 343, 346, 347, 
+       359, 363, 364, 365, 375, 377, 380, 382, 
+       385, 386, 387, 391, 392, 393, 394, 395, 
+       399, 400, 404, 406, 409, 410, 421, 425, 
+       428, 430, 433, 444, 446, 449, 450, 451, 
+       452, 453, 454, 457, 464, 471, 479, 480, 
+       481, 482, 483, 487, 491, 492, 493, 494, 
+       495, 496, 497, 498, 499, 500, 504, 505, 
+       506, 507, 508, 511, 518, 529, 541, 545, 
+       546, 547, 557, 559, 562, 564, 567, 568, 
+       579, 583, 586, 588, 591, 602, 604, 607, 
+       608, 609, 610, 611, 612, 613, 614, 615, 
+       616, 617, 622, 626, 627, 628, 638, 640, 
+       643, 647, 648, 649, 650, 651, 652, 653, 
+       654, 655, 660, 664, 665, 666, 676, 678, 
+       681, 685, 686, 687, 688, 689, 690, 691, 
+       692, 693, 697, 705, 713, 726, 731, 735, 
+       736, 737, 738, 739, 740, 752, 757, 761, 
+       762, 766, 767, 768, 769, 770, 771, 775, 
+       784, 791, 798, 809, 813, 827, 837, 844, 
+       856, 861, 862, 867, 868, 869, 870, 871, 
+       872, 875, 882, 889, 897, 898, 902, 909, 
+       917, 921, 922, 923, 924, 934, 936, 939, 
+       949, 961, 968, 980, 981, 982, 983, 984, 
+       985, 986, 987, 988, 992, 1000, 1007, 1019, 
+       1024, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 
+       1038, 1039, 1040, 1041, 1042, 1043, 1047, 1054, 
+       1061, 1069, 1070, 1071, 1072, 1073, 1074, 1078, 
+       1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 
+       1090, 1091, 1092, 1093, 1094, 1095, 1099, 1107, 
+       1115, 1127, 1131, 1143, 1144, 1145, 1155, 1157, 
+       1160, 1168, 1169, 1177, 1180, 1182, 1189, 1200, 
+       1203, 1205, 1212, 1220, 1228, 1232, 1232, 1233, 
+       1242, 1245, 1247, 1258, 1262, 1262, 1263, 1271, 
+       1274, 1276, 1277, 1278, 1279, 1280, 1289, 1292, 
+       1294, 1301, 1302, 1311, 1314, 1316, 1317, 1318, 
+       1319, 1320, 1324, 1324, 1325, 1334, 1337, 1339, 
+       1346, 1347, 1359, 1362, 1364, 1365, 1372, 1375, 
+       1378, 1379, 1386, 1389, 1392, 1394, 1395, 1398, 
+       1399, 1400, 1401
+};
+
+static const char _eo_tokenizer_trans_keys[] = {
+       10, 42, 10, 42, 47, 10, 9, 10, 
+       13, 32, 95, 123, 0, 31, 48, 57, 
+       65, 90, 97, 122, 10, 123, 0, 32, 
+       9, 10, 13, 32, 97, 123, 0, 31, 
+       115, 9, 13, 32, 9, 13, 32, 73, 
+       77, 82, 110, 116, 101, 114, 102, 97, 
+       99, 101, 10, 123, 0, 32, 105, 120, 
+       105, 110, 101, 103, 117, 108, 97, 114, 
+       10, 78, 123, 0, 32, 111, 110, 73, 
+       110, 115, 116, 97, 110, 116, 105, 97, 
+       98, 108, 10, 42, 64, 10, 42, 10, 
+       42, 47, 10, 42, 95, 0, 32, 48, 
+       57, 65, 90, 97, 122, 10, 42, 10, 
+       42, 47, 10, 9, 13, 32, 58, 95, 
+       48, 57, 65, 90, 97, 122, 9, 13, 
+       32, 58, 9, 13, 32, 65, 90, 97, 
+       122, 9, 13, 32, 65, 90, 97, 122, 
+       9, 13, 32, 44, 59, 95, 48, 57, 
+       65, 90, 97, 122, 9, 13, 32, 58, 
+       95, 103, 48, 57, 65, 90, 97, 122, 
+       9, 13, 32, 58, 95, 97, 48, 57, 
+       65, 90, 98, 122, 9, 13, 32, 58, 
+       95, 99, 48, 57, 65, 90, 97, 122, 
+       9, 13, 32, 58, 95, 121, 48, 57, 
+       65, 90, 97, 122, 9, 13, 32, 58, 
+       95, 48, 57, 65, 90, 97, 122, 9, 
+       13, 32, 58, 65, 90, 97, 122, 95, 
+       48, 57, 65, 90, 97, 122, 59, 95, 
+       48, 57, 65, 90, 97, 122, 9, 13, 
+       32, 58, 95, 116, 48, 57, 65, 90, 
+       97, 122, 9, 13, 32, 58, 95, 117, 
+       48, 57, 65, 90, 97, 122, 9, 13, 
+       32, 58, 95, 114, 48, 57, 65, 90, 
+       97, 122, 9, 13, 32, 58, 95, 110, 
+       48, 57, 65, 90, 97, 122, 9, 13, 
+       32, 58, 95, 48, 57, 65, 90, 97, 
+       122, 9, 13, 32, 58, 65, 90, 97, 
+       122, 9, 13, 32, 42, 95, 48, 57, 
+       65, 90, 97, 122, 9, 13, 32, 42, 
+       59, 95, 48, 57, 65, 90, 97, 122, 
+       9, 13, 32, 47, 42, 64, 10, 95, 
+       0, 32, 48, 57, 65, 90, 97, 122, 
+       10, 42, 10, 42, 47, 10, 42, 10, 
+       42, 47, 10, 9, 13, 32, 42, 59, 
+       95, 48, 57, 65, 90, 97, 122, 9, 
+       13, 32, 47, 42, 64, 10, 95, 0, 
+       32, 48, 57, 65, 90, 97, 122, 10, 
+       42, 10, 42, 47, 10, 42, 10, 42, 
+       47, 10, 116, 10, 123, 0, 32, 114, 
+       97, 109, 115, 10, 123, 0, 32, 116, 
+       10, 123, 0, 32, 10, 42, 10, 42, 
+       47, 10, 10, 95, 123, 0, 32, 48, 
+       57, 65, 90, 97, 122, 10, 123, 0, 
+       32, 10, 42, 64, 10, 42, 10, 42, 
+       47, 10, 42, 95, 0, 32, 48, 57, 
+       65, 90, 97, 122, 10, 42, 10, 42, 
+       47, 10, 103, 97, 99, 121, 9, 13, 
+       32, 9, 13, 32, 65, 90, 97, 122, 
+       95, 48, 57, 65, 90, 97, 122, 59, 
+       95, 48, 57, 65, 90, 97, 122, 106, 
+       101, 99, 116, 9, 13, 32, 58, 9, 
+       13, 32, 99, 111, 110, 115, 116, 59, 
+       114, 97, 109, 115, 10, 123, 0, 32, 
+       116, 117, 114, 110, 9, 13, 32, 9, 
+       13, 32, 65, 90, 97, 122, 9, 13, 
+       32, 42, 95, 48, 57, 65, 90, 97, 
+       122, 9, 13, 32, 42, 59, 95, 48, 
+       57, 65, 90, 97, 122, 9, 13, 32, 
+       47, 42, 64, 10, 95, 0, 32, 48, 
+       57, 65, 90, 97, 122, 10, 42, 10, 
+       42, 47, 10, 42, 10, 42, 47, 10, 
+       10, 95, 123, 0, 32, 48, 57, 65, 
+       90, 97, 122, 10, 123, 0, 32, 10, 
+       42, 64, 10, 42, 10, 42, 47, 10, 
+       42, 95, 0, 32, 48, 57, 65, 90, 
+       97, 122, 10, 42, 10, 42, 47, 10, 
+       110, 115, 116, 114, 117, 99, 116, 111, 
+       114, 10, 59, 115, 0, 32, 10, 59, 
+       0, 32, 42, 64, 10, 95, 0, 32, 
+       48, 57, 65, 90, 97, 122, 10, 42, 
+       10, 42, 47, 10, 123, 0, 32, 115, 
+       116, 114, 117, 99, 116, 111, 114, 10, 
+       59, 115, 0, 32, 10, 59, 0, 32, 
+       42, 64, 10, 95, 0, 32, 48, 57, 
+       65, 90, 97, 122, 10, 42, 10, 42, 
+       47, 10, 123, 0, 32, 112, 108, 101, 
+       109, 101, 110, 116, 115, 10, 123, 0, 
+       32, 10, 125, 0, 32, 65, 90, 97, 
+       122, 58, 95, 48, 57, 65, 90, 97, 
+       122, 10, 58, 59, 95, 123, 0, 32, 
+       48, 57, 65, 90, 97, 122, 10, 59, 
+       123, 0, 32, 10, 108, 0, 32, 101, 
+       103, 97, 99, 121, 9, 10, 13, 32, 
+       59, 123, 0, 31, 65, 90, 97, 122, 
+       10, 59, 123, 0, 32, 10, 125, 0, 
+       32, 59, 10, 112, 0, 32, 97, 114, 
+       97, 109, 115, 10, 123, 0, 32, 10, 
+       58, 59, 0, 32, 65, 90, 97, 122, 
+       9, 13, 32, 65, 90, 97, 122, 95, 
+       48, 57, 65, 90, 97, 122, 10, 59, 
+       95, 0, 32, 48, 57, 65, 90, 97, 
+       122, 10, 59, 0, 32, 9, 10, 13, 
+       32, 47, 58, 59, 125, 0, 31, 65, 
+       90, 97, 122, 10, 58, 59, 125, 0, 
+       32, 65, 90, 97, 122, 95, 48, 57, 
+       65, 90, 97, 122, 9, 13, 32, 58, 
+       59, 95, 48, 57, 65, 90, 97, 122, 
+       9, 13, 32, 58, 59, 59, 10, 114, 
+       125, 0, 32, 101, 116, 117, 114, 110, 
+       9, 13, 32, 9, 13, 32, 65, 90, 
+       97, 122, 95, 48, 57, 65, 90, 97, 
+       122, 58, 95, 48, 57, 65, 90, 97, 
+       122, 58, 65, 90, 97, 122, 95, 48, 
+       57, 65, 90, 97, 122, 59, 95, 48, 
+       57, 65, 90, 97, 122, 10, 125, 0, 
+       32, 59, 42, 64, 10, 95, 0, 32, 
+       48, 57, 65, 90, 97, 122, 10, 42, 
+       10, 42, 47, 10, 58, 59, 125, 0, 
+       32, 65, 90, 97, 122, 9, 10, 13, 
+       32, 59, 123, 0, 31, 65, 90, 97, 
+       122, 95, 48, 57, 65, 90, 97, 122, 
+       10, 59, 95, 123, 0, 32, 48, 57, 
+       65, 90, 97, 122, 58, 59, 104, 101, 
+       114, 105, 116, 115, 10, 123, 0, 32, 
+       10, 125, 0, 32, 65, 90, 97, 122, 
+       95, 48, 57, 65, 90, 97, 122, 10, 
+       44, 95, 125, 0, 32, 48, 57, 65, 
+       90, 97, 122, 10, 44, 125, 0, 32, 
+       10, 0, 32, 65, 90, 97, 122, 59, 
+       103, 97, 99, 121, 95, 112, 114, 101, 
+       102, 105, 120, 10, 58, 0, 32, 10, 
+       0, 32, 65, 90, 97, 122, 95, 48, 
+       57, 65, 90, 97, 122, 59, 95, 48, 
+       57, 65, 90, 97, 122, 116, 104, 111, 
+       100, 115, 10, 123, 0, 32, 111, 112, 
+       101, 114, 116, 105, 101, 115, 10, 123, 
+       0, 32, 103, 110, 97, 108, 115, 10, 
+       123, 0, 32, 10, 125, 0, 32, 65, 
+       90, 97, 122, 44, 95, 48, 57, 65, 
+       90, 97, 122, 10, 44, 59, 95, 0, 
+       32, 48, 57, 65, 90, 97, 122, 10, 
+       59, 0, 32, 9, 10, 13, 32, 47, 
+       125, 0, 31, 65, 90, 97, 122, 42, 
+       64, 10, 95, 0, 32, 48, 57, 65, 
+       90, 97, 122, 10, 42, 10, 42, 47, 
+       10, 125, 0, 32, 65, 90, 97, 122, 
+       59, 10, 47, 0, 32, 65, 90, 97, 
+       122, 10, 0, 32, 42, 47, 95, 48, 
+       57, 65, 90, 97, 122, 10, 47, 108, 
+       114, 125, 0, 32, 65, 90, 97, 122, 
+       10, 0, 32, 42, 47, 95, 48, 57, 
+       65, 90, 97, 122, 95, 101, 48, 57, 
+       65, 90, 97, 122, 95, 101, 48, 57, 
+       65, 90, 97, 122, 9, 13, 32, 47, 
+       59, 10, 47, 125, 0, 32, 65, 90, 
+       97, 122, 10, 0, 32, 42, 47, 9, 
+       13, 32, 42, 95, 48, 57, 65, 90, 
+       97, 122, 9, 13, 32, 47, 59, 10, 
+       47, 103, 112, 115, 125, 0, 32, 10, 
+       0, 32, 42, 47, 101, 97, 101, 59, 
+       10, 47, 125, 0, 32, 65, 90, 97, 
+       122, 10, 0, 32, 42, 47, 95, 48, 
+       57, 65, 90, 97, 122, 59, 10, 47, 
+       108, 111, 112, 114, 125, 0, 32, 10, 
+       0, 32, 42, 47, 101, 98, 97, 101, 
+       9, 13, 32, 47, 59, 10, 47, 125, 
+       0, 32, 65, 90, 97, 122, 10, 0, 
+       32, 42, 47, 95, 48, 57, 65, 90, 
+       97, 122, 59, 10, 47, 99, 100, 105, 
+       108, 109, 112, 115, 125, 0, 32, 10, 
+       0, 32, 42, 47, 111, 9, 10, 13, 
+       32, 47, 0, 31, 10, 0, 32, 10, 
+       0, 32, 101, 9, 10, 13, 32, 47, 
+       0, 31, 10, 0, 32, 10, 0, 32, 
+       109, 110, 101, 10, 0, 32, 101, 114, 
+       105, 59, 0
+};
+
+static const char _eo_tokenizer_single_lengths[] = {
+       2, 3, 1, 6, 2, 6, 1, 3, 
+       6, 1, 1, 1, 1, 1, 1, 1, 
+       1, 2, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 3, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 3, 2, 3, 3, 2, 3, 
+       1, 5, 4, 3, 3, 6, 6, 6, 
+       6, 6, 5, 4, 1, 2, 6, 6, 
+       6, 6, 5, 4, 5, 6, 4, 1, 
+       1, 2, 2, 3, 2, 3, 1, 6, 
+       4, 1, 1, 2, 2, 3, 2, 3, 
+       1, 1, 2, 1, 1, 1, 1, 2, 
+       1, 2, 2, 3, 1, 3, 2, 3, 
+       2, 3, 3, 2, 3, 1, 1, 1, 
+       1, 1, 3, 3, 1, 2, 1, 1, 
+       1, 1, 4, 4, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 2, 1, 1, 
+       1, 1, 3, 3, 5, 6, 4, 1, 
+       1, 2, 2, 3, 2, 3, 1, 3, 
+       2, 3, 2, 3, 3, 2, 3, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 3, 2, 1, 1, 2, 2, 3, 
+       2, 1, 1, 1, 1, 1, 1, 1, 
+       1, 3, 2, 1, 1, 2, 2, 3, 
+       2, 1, 1, 1, 1, 1, 1, 1, 
+       1, 2, 2, 2, 5, 3, 2, 1, 
+       1, 1, 1, 1, 6, 3, 2, 1, 
+       2, 1, 1, 1, 1, 1, 2, 3, 
+       3, 1, 3, 2, 8, 4, 1, 6, 
+       5, 1, 3, 1, 1, 1, 1, 1, 
+       3, 3, 1, 2, 1, 0, 1, 2, 
+       2, 1, 1, 1, 2, 2, 3, 4, 
+       6, 1, 4, 1, 1, 1, 1, 1, 
+       1, 1, 1, 2, 2, 1, 4, 3, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 2, 1, 1, 
+       2, 1, 1, 1, 1, 1, 2, 1, 
+       1, 1, 1, 1, 1, 1, 1, 2, 
+       1, 1, 1, 1, 1, 2, 2, 2, 
+       4, 2, 6, 1, 1, 2, 2, 3, 
+       2, 1, 2, 1, 2, 1, 5, 1, 
+       2, 1, 2, 2, 4, 0, 1, 3, 
+       1, 2, 5, 4, 0, 1, 6, 1, 
+       2, 1, 1, 1, 1, 3, 1, 2, 
+       1, 1, 7, 1, 2, 1, 1, 1, 
+       1, 4, 0, 1, 3, 1, 2, 1, 
+       1, 10, 1, 2, 1, 5, 1, 1, 
+       1, 5, 1, 1, 2, 1, 1, 1, 
+       1, 1, 1
+};
+
+static const char _eo_tokenizer_range_lengths[] = {
+       0, 0, 0, 4, 1, 1, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 1, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 1, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 4, 0, 0, 
+       0, 3, 0, 2, 2, 3, 3, 3, 
+       3, 3, 3, 2, 3, 3, 3, 3, 
+       3, 3, 3, 2, 3, 3, 0, 0, 
+       0, 4, 0, 0, 0, 0, 0, 3, 
+       0, 0, 0, 4, 0, 0, 0, 0, 
+       0, 0, 1, 0, 0, 0, 0, 1, 
+       0, 1, 0, 0, 0, 4, 1, 0, 
+       0, 0, 4, 0, 0, 0, 0, 0, 
+       0, 0, 0, 2, 3, 3, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 1, 0, 0, 
+       0, 0, 0, 2, 3, 3, 0, 0, 
+       0, 4, 0, 0, 0, 0, 0, 4, 
+       1, 0, 0, 0, 4, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 1, 1, 0, 0, 4, 0, 0, 
+       1, 0, 0, 0, 0, 0, 0, 0, 
+       0, 1, 1, 0, 0, 4, 0, 0, 
+       1, 0, 0, 0, 0, 0, 0, 0, 
+       0, 1, 3, 3, 4, 1, 1, 0, 
+       0, 0, 0, 0, 3, 1, 1, 0, 
+       1, 0, 0, 0, 0, 0, 1, 3, 
+       2, 3, 4, 1, 3, 3, 3, 3, 
+       0, 0, 1, 0, 0, 0, 0, 0, 
+       0, 2, 3, 3, 0, 2, 3, 3, 
+       1, 0, 0, 0, 4, 0, 0, 3, 
+       3, 3, 4, 0, 0, 0, 0, 0, 
+       0, 0, 0, 1, 3, 3, 4, 1, 
+       3, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 1, 3, 3, 
+       3, 0, 0, 0, 0, 0, 1, 0, 
+       0, 0, 0, 0, 0, 0, 0, 1, 
+       0, 0, 0, 0, 0, 1, 3, 3, 
+       4, 1, 3, 0, 0, 4, 0, 0, 
+       3, 0, 3, 1, 0, 3, 3, 1, 
+       0, 3, 3, 3, 0, 0, 0, 3, 
+       1, 0, 3, 0, 0, 0, 1, 1, 
+       0, 0, 0, 0, 0, 3, 1, 0, 
+       3, 0, 1, 1, 0, 0, 0, 0, 
+       0, 0, 0, 0, 3, 1, 0, 3, 
+       0, 1, 1, 0, 0, 1, 1, 1, 
+       0, 1, 1, 1, 0, 0, 1, 0, 
+       0, 0, 0
+};
+
+static const short _eo_tokenizer_index_offsets[] = {
+       0, 3, 7, 9, 20, 24, 32, 34, 
+       38, 45, 47, 49, 51, 53, 55, 57, 
+       59, 61, 65, 67, 69, 71, 73, 75, 
+       77, 79, 81, 83, 85, 90, 92, 94, 
+       96, 98, 100, 102, 104, 106, 108, 110, 
+       112, 114, 116, 120, 123, 127, 135, 138, 
+       142, 144, 153, 158, 164, 170, 180, 190, 
+       200, 210, 220, 229, 236, 241, 247, 257, 
+       267, 277, 287, 296, 303, 312, 322, 327, 
+       329, 331, 338, 341, 345, 348, 352, 354, 
+       364, 369, 371, 373, 380, 383, 387, 390, 
+       394, 396, 398, 402, 404, 406, 408, 410, 
+       414, 416, 420, 423, 427, 429, 437, 441, 
+       445, 448, 452, 460, 463, 467, 469, 471, 
+       473, 475, 477, 481, 487, 492, 498, 500, 
+       502, 504, 506, 511, 516, 518, 520, 522, 
+       524, 526, 528, 530, 532, 534, 538, 540, 
+       542, 544, 546, 550, 556, 565, 575, 580, 
+       582, 584, 591, 594, 598, 601, 605, 607, 
+       615, 619, 623, 626, 630, 638, 641, 645, 
+       647, 649, 651, 653, 655, 657, 659, 661, 
+       663, 665, 670, 674, 676, 678, 685, 688, 
+       692, 696, 698, 700, 702, 704, 706, 708, 
+       710, 712, 717, 721, 723, 725, 732, 735, 
+       739, 743, 745, 747, 749, 751, 753, 755, 
+       757, 759, 763, 769, 775, 785, 790, 794, 
+       796, 798, 800, 802, 804, 814, 819, 823, 
+       825, 829, 831, 833, 835, 837, 839, 843, 
+       850, 856, 861, 869, 873, 885, 893, 898, 
+       908, 914, 916, 921, 923, 925, 927, 929, 
+       931, 935, 941, 946, 952, 954, 957, 962, 
+       968, 972, 974, 976, 978, 985, 988, 992, 
+       1000, 1010, 1015, 1024, 1026, 1028, 1030, 1032, 
+       1034, 1036, 1038, 1040, 1044, 1050, 1055, 1064, 
+       1069, 1074, 1076, 1078, 1080, 1082, 1084, 1086, 
+       1088, 1090, 1092, 1094, 1096, 1098, 1102, 1107, 
+       1112, 1118, 1120, 1122, 1124, 1126, 1128, 1132, 
+       1134, 1136, 1138, 1140, 1142, 1144, 1146, 1148, 
+       1152, 1154, 1156, 1158, 1160, 1162, 1166, 1172, 
+       1178, 1187, 1191, 1201, 1203, 1205, 1212, 1215, 
+       1219, 1225, 1227, 1233, 1236, 1239, 1244, 1253, 
+       1256, 1259, 1264, 1270, 1276, 1281, 1282, 1284, 
+       1291, 1294, 1297, 1306, 1311, 1312, 1314, 1322, 
+       1325, 1328, 1330, 1332, 1334, 1336, 1343, 1346, 
+       1349, 1354, 1356, 1365, 1368, 1371, 1373, 1375, 
+       1377, 1379, 1384, 1385, 1387, 1394, 1397, 1400, 
+       1405, 1407, 1419, 1422, 1425, 1427, 1434, 1437, 
+       1440, 1442, 1449, 1452, 1455, 1458, 1460, 1463, 
+       1465, 1467, 1469
+};
+
+static const short _eo_tokenizer_indicies[] = {
+       2, 3, 1, 2, 3, 4, 1, 6, 
+       5, 8, 9, 8, 8, 10, 11, 7, 
+       10, 10, 10, 0, 13, 14, 12, 0, 
+       15, 13, 15, 15, 16, 14, 12, 0, 
+       17, 0, 18, 18, 18, 0, 19, 19, 
+       19, 20, 21, 22, 0, 23, 0, 24, 
+       0, 25, 0, 26, 0, 27, 0, 28, 
+       0, 29, 0, 30, 0, 32, 33, 31, 
+       0, 34, 0, 35, 0, 36, 0, 30, 
+       0, 37, 0, 38, 0, 39, 0, 40, 
+       0, 41, 0, 42, 0, 32, 43, 33, 
+       31, 0, 44, 0, 45, 0, 46, 0, 
+       47, 0, 48, 0, 49, 0, 50, 0, 
+       51, 0, 52, 0, 53, 0, 54, 0, 
+       55, 0, 29, 0, 58, 59, 60, 57, 
+       58, 59, 57, 58, 59, 61, 57, 62, 
+       59, 63, 60, 63, 63, 63, 57, 65, 
+       66, 64, 65, 66, 67, 64, 69, 68, 
+       70, 70, 70, 72, 71, 71, 71, 71, 
+       56, 70, 70, 70, 72, 56, 73, 73, 
+       73, 74, 74, 56, 75, 75, 75, 76, 
+       76, 56, 77, 77, 77, 77, 78, 77, 
+       77, 77, 77, 56, 70, 70, 70, 72, 
+       71, 79, 71, 71, 71, 56, 70, 70, 
+       70, 72, 71, 80, 71, 71, 71, 56, 
+       70, 70, 70, 72, 71, 81, 71, 71, 
+       71, 56, 70, 70, 70, 72, 71, 82, 
+       71, 71, 71, 56, 83, 83, 83, 72, 
+       71, 71, 71, 71, 56, 83, 83, 83, 
+       72, 84, 84, 56, 85, 85, 85, 85, 
+       56, 86, 85, 85, 85, 85, 56, 70, 
+       70, 70, 72, 71, 87, 71, 71, 71, 
+       56, 70, 70, 70, 72, 71, 88, 71, 
+       71, 71, 56, 70, 70, 70, 72, 71, 
+       89, 71, 71, 71, 56, 70, 70, 70, 
+       72, 71, 90, 71, 71, 71, 56, 91, 
+       91, 91, 72, 71, 71, 71, 71, 56, 
+       91, 91, 91, 72, 92, 92, 56, 93, 
+       93, 93, 93, 93, 93, 93, 93, 56, 
+       93, 93, 93, 93, 94, 93, 93, 93, 
+       93, 56, 96, 96, 96, 97, 95, 98, 
+       95, 99, 95, 100, 101, 99, 101, 101, 
+       101, 95, 103, 104, 102, 103, 104, 105, 
+       102, 108, 109, 107, 108, 109, 110, 107, 
+       112, 111, 113, 113, 113, 113, 114, 113, 
+       113, 113, 113, 106, 116, 116, 116, 117, 
+       115, 118, 115, 119, 115, 120, 121, 119, 
+       121, 121, 121, 115, 123, 124, 122, 123, 
+       124, 125, 122, 128, 129, 127, 128, 129, 
+       130, 127, 132, 131, 133, 126, 134, 135, 
+       133, 126, 136, 126, 137, 126, 138, 126, 
+       139, 126, 140, 141, 139, 126, 142, 126, 
+       143, 144, 142, 126, 147, 148, 146, 147, 
+       148, 149, 146, 151, 150, 153, 154, 155, 
+       152, 154, 154, 154, 145, 157, 158, 156, 
+       145, 161, 162, 163, 160, 161, 162, 160, 
+       161, 162, 164, 160, 165, 162, 166, 163, 
+       166, 166, 166, 160, 168, 169, 167, 168, 
+       169, 170, 167, 172, 171, 173, 159, 174, 
+       159, 175, 159, 176, 159, 177, 177, 177, 
+       159, 177, 177, 177, 178, 178, 159, 179, 
+       179, 179, 179, 159, 180, 179, 179, 179, 
+       179, 159, 181, 159, 182, 159, 183, 159, 
+       184, 159, 184, 184, 184, 185, 159, 185, 
+       185, 185, 186, 159, 187, 159, 188, 159, 
+       189, 159, 190, 159, 191, 159, 192, 159, 
+       193, 159, 194, 159, 195, 159, 196, 197, 
+       195, 159, 198, 159, 199, 159, 200, 159, 
+       201, 159, 202, 202, 202, 159, 202, 202, 
+       202, 203, 203, 159, 204, 204, 204, 204, 
+       204, 204, 204, 204, 159, 204, 204, 204, 
+       204, 205, 204, 204, 204, 204, 159, 207, 
+       207, 207, 208, 206, 209, 206, 210, 206, 
+       211, 212, 210, 212, 212, 212, 206, 214, 
+       215, 213, 214, 215, 216, 213, 219, 220, 
+       218, 219, 220, 221, 218, 223, 222, 225, 
+       226, 227, 224, 226, 226, 226, 217, 229, 
+       230, 228, 217, 233, 234, 235, 232, 233, 
+       234, 232, 233, 234, 236, 232, 237, 234, 
+       238, 235, 238, 238, 238, 232, 240, 241, 
+       239, 240, 241, 242, 239, 244, 243, 245, 
+       231, 246, 231, 247, 231, 248, 231, 249, 
+       231, 250, 231, 251, 231, 252, 231, 253, 
+       231, 255, 256, 257, 254, 231, 259, 260, 
+       258, 231, 262, 261, 263, 261, 264, 265, 
+       263, 265, 265, 265, 261, 267, 268, 266, 
+       267, 268, 269, 266, 270, 271, 257, 231, 
+       272, 231, 273, 231, 274, 231, 275, 231, 
+       276, 231, 277, 231, 278, 231, 279, 231, 
+       281, 282, 283, 280, 231, 285, 286, 284, 
+       231, 288, 287, 289, 287, 290, 291, 289, 
+       291, 291, 291, 287, 293, 294, 292, 293, 
+       294, 295, 292, 296, 297, 283, 231, 298, 
+       231, 299, 231, 300, 231, 301, 231, 302, 
+       231, 303, 231, 304, 231, 305, 231, 306, 
+       307, 305, 231, 308, 310, 307, 309, 309, 
+       231, 312, 311, 311, 311, 311, 231, 314, 
+       312, 315, 311, 316, 313, 311, 311, 311, 
+       231, 318, 307, 319, 317, 231, 320, 321, 
+       319, 231, 322, 231, 323, 231, 324, 231, 
+       325, 231, 326, 231, 328, 329, 328, 328, 
+       330, 332, 327, 331, 331, 231, 334, 335, 
+       336, 333, 231, 337, 338, 335, 231, 307, 
+       231, 339, 340, 336, 231, 341, 231, 342, 
+       231, 343, 231, 344, 231, 345, 231, 346, 
+       347, 345, 231, 348, 349, 350, 347, 351, 
+       351, 231, 349, 349, 349, 352, 352, 231, 
+       353, 353, 353, 353, 231, 355, 356, 353, 
+       354, 353, 353, 353, 231, 358, 350, 357, 
+       231, 350, 360, 350, 350, 361, 349, 350, 
+       362, 359, 351, 351, 231, 360, 349, 350, 
+       362, 359, 351, 351, 231, 363, 363, 363, 
+       363, 231, 364, 364, 364, 365, 366, 363, 
+       363, 363, 363, 231, 367, 367, 367, 349, 
+       350, 231, 368, 231, 369, 370, 371, 368, 
+       231, 372, 231, 373, 231, 374, 231, 375, 
+       231, 376, 231, 377, 377, 377, 231, 377, 
+       377, 377, 378, 378, 231, 379, 379, 379, 
+       379, 231, 380, 379, 379, 379, 379, 231, 
+       381, 231, 382, 382, 231, 383, 383, 383, 
+       383, 231, 384, 383, 383, 383, 383, 231, 
+       386, 371, 385, 231, 335, 231, 387, 231, 
+       388, 231, 389, 390, 388, 390, 390, 390, 
+       231, 392, 393, 391, 392, 393, 394, 391, 
+       396, 397, 398, 400, 395, 399, 399, 231, 
+       401, 334, 401, 401, 335, 336, 333, 402, 
+       402, 231, 403, 403, 403, 403, 231, 405, 
+       406, 403, 407, 404, 403, 403, 403, 231, 
+       311, 231, 408, 231, 409, 231, 410, 231, 
+       411, 231, 412, 231, 413, 231, 414, 231, 
+       415, 416, 414, 231, 417, 419, 416, 418, 
+       418, 231, 420, 420, 420, 420, 231, 422, 
+       423, 420, 424, 421, 420, 420, 420, 231, 
+       426, 427, 419, 425, 231, 428, 427, 418, 
+       418, 231, 429, 231, 430, 231, 431, 231, 
+       432, 231, 433, 231, 434, 231, 435, 231, 
+       436, 231, 437, 231, 438, 231, 439, 231, 
+       440, 231, 441, 442, 440, 231, 443, 442, 
+       444, 444, 231, 445, 445, 445, 445, 231, 
+       446, 445, 445, 445, 445, 231, 447, 231, 
+       448, 231, 449, 231, 450, 231, 451, 231, 
+       452, 453, 451, 231, 454, 231, 455, 231, 
+       456, 231, 457, 231, 458, 231, 459, 231, 
+       460, 231, 461, 231, 462, 463, 461, 231, 
+       464, 231, 465, 231, 466, 231, 467, 231, 
+       468, 231, 469, 470, 468, 231, 471, 473, 
+       470, 472, 472, 231, 474, 474, 474, 474, 
+       474, 231, 476, 474, 477, 474, 475, 474, 
+       474, 474, 231, 479, 480, 478, 231, 480, 
+       471, 480, 480, 481, 473, 470, 472, 472, 
+       231, 482, 231, 483, 231, 484, 485, 483, 
+       485, 485, 485, 231, 487, 488, 486, 487, 
+       488, 489, 486, 491, 493, 490, 492, 492, 
+       231, 494, 231, 497, 498, 496, 499, 499, 
+       495, 497, 496, 500, 1, 5, 501, 10, 
+       10, 10, 10, 501, 504, 505, 507, 508, 
+       509, 503, 506, 506, 502, 504, 503, 510, 
+       512, 68, 511, 71, 71, 71, 71, 511, 
+       71, 513, 71, 71, 71, 511, 71, 514, 
+       71, 71, 71, 511, 96, 96, 96, 97, 
+       515, 516, 517, 511, 520, 521, 523, 519, 
+       522, 522, 518, 520, 519, 524, 107, 111, 
+       525, 113, 113, 113, 113, 113, 113, 113, 
+       113, 525, 116, 116, 116, 117, 526, 527, 
+       528, 525, 531, 532, 533, 534, 535, 536, 
+       530, 529, 531, 530, 537, 127, 131, 538, 
+       539, 538, 540, 538, 541, 538, 542, 538, 
+       545, 546, 548, 544, 547, 547, 543, 545, 
+       544, 549, 146, 150, 550, 154, 154, 154, 
+       154, 550, 551, 550, 554, 555, 556, 557, 
+       558, 559, 560, 553, 552, 554, 553, 561, 
+       563, 171, 562, 564, 562, 565, 562, 566, 
+       562, 567, 562, 207, 207, 207, 208, 568, 
+       569, 570, 562, 573, 574, 576, 572, 575, 
+       575, 571, 573, 572, 577, 218, 222, 578, 
+       226, 226, 226, 226, 578, 579, 578, 582, 
+       583, 584, 585, 586, 587, 588, 589, 590, 
+       591, 581, 580, 582, 581, 592, 594, 243, 
+       593, 595, 593, 260, 598, 260, 260, 599, 
+       597, 596, 598, 597, 596, 602, 601, 600, 
+       603, 593, 286, 606, 286, 286, 607, 605, 
+       604, 606, 605, 604, 610, 609, 608, 611, 
+       612, 593, 613, 593, 616, 615, 614, 617, 
+       593, 618, 593, 619, 593, 620, 593, 0
+};
+
+static const short _eo_tokenizer_trans_targs[] = {
+       322, 0, 0, 1, 322, 2, 322, 4, 
+       5, 4, 3, 322, 4, 4, 322, 5, 
+       6, 7, 8, 8, 9, 18, 22, 10, 
+       11, 12, 13, 14, 15, 16, 17, 4, 
+       4, 322, 19, 20, 21, 23, 24, 25, 
+       26, 27, 28, 29, 30, 31, 32, 33, 
+       34, 35, 36, 37, 38, 39, 40, 41, 
+       326, 43, 43, 44, 45, 326, 45, 46, 
+       46, 46, 47, 326, 48, 326, 50, 49, 
+       51, 52, 53, 52, 53, 53, 326, 55, 
+       56, 57, 58, 59, 60, 61, 326, 63, 
+       64, 65, 66, 67, 68, 69, 332, 326, 
+       70, 71, 72, 73, 73, 74, 74, 74, 
+       75, 333, 335, 76, 76, 77, 335, 78, 
+       335, 79, 339, 335, 80, 81, 82, 83, 
+       83, 84, 84, 84, 85, 340, 342, 86, 
+       86, 87, 342, 88, 342, 90, 90, 342, 
+       92, 93, 94, 95, 95, 342, 97, 97, 
+       342, 349, 98, 98, 99, 349, 100, 349, 
+       102, 102, 101, 349, 102, 102, 349, 354, 
+       104, 104, 105, 106, 354, 106, 107, 107, 
+       107, 108, 354, 109, 354, 111, 112, 113, 
+       114, 115, 116, 117, 354, 119, 120, 121, 
+       122, 123, 124, 125, 126, 127, 128, 354, 
+       130, 131, 132, 133, 133, 354, 135, 136, 
+       137, 138, 139, 140, 141, 361, 354, 142, 
+       143, 144, 145, 145, 146, 146, 146, 147, 
+       362, 364, 148, 148, 149, 364, 150, 364, 
+       152, 152, 151, 364, 152, 152, 364, 369, 
+       154, 154, 155, 156, 369, 156, 157, 157, 
+       157, 158, 369, 159, 369, 161, 162, 163, 
+       164, 165, 166, 167, 168, 169, 170, 170, 
+       373, 176, 170, 170, 373, 369, 172, 173, 
+       173, 174, 174, 174, 175, 375, 176, 369, 
+       178, 179, 180, 181, 182, 183, 184, 185, 
+       186, 186, 377, 192, 186, 186, 377, 369, 
+       188, 189, 189, 190, 190, 190, 191, 379, 
+       192, 369, 194, 195, 196, 197, 198, 199, 
+       200, 201, 201, 202, 202, 203, 260, 204, 
+       259, 205, 205, 202, 206, 205, 205, 206, 
+       206, 207, 208, 209, 210, 211, 212, 213, 
+       256, 213, 214, 257, 216, 213, 213, 214, 
+       216, 214, 215, 216, 217, 218, 219, 220, 
+       221, 222, 222, 223, 223, 224, 228, 230, 
+       225, 226, 227, 227, 228, 227, 227, 229, 
+       229, 250, 233, 231, 232, 224, 228, 232, 
+       234, 234, 235, 249, 236, 237, 238, 239, 
+       240, 241, 242, 243, 244, 245, 246, 247, 
+       248, 248, 248, 251, 252, 252, 253, 253, 
+       253, 254, 255, 229, 229, 224, 228, 230, 
+       233, 256, 257, 258, 213, 213, 214, 216, 
+       369, 262, 263, 264, 265, 266, 267, 267, 
+       268, 268, 269, 273, 270, 271, 271, 272, 
+       273, 271, 271, 272, 272, 369, 275, 276, 
+       277, 278, 279, 280, 281, 282, 283, 284, 
+       285, 285, 286, 286, 287, 288, 382, 290, 
+       291, 292, 293, 294, 294, 369, 296, 297, 
+       298, 299, 300, 301, 302, 303, 303, 369, 
+       305, 306, 307, 308, 309, 309, 310, 310, 
+       311, 321, 312, 313, 313, 314, 313, 313, 
+       314, 315, 316, 317, 317, 318, 318, 318, 
+       319, 320, 310, 310, 311, 321, 369, 322, 
+       323, 323, 324, 325, 322, 322, 326, 327, 
+       327, 328, 329, 330, 331, 334, 326, 326, 
+       42, 54, 62, 326, 326, 326, 335, 336, 
+       336, 337, 338, 341, 335, 335, 335, 335, 
+       335, 342, 343, 343, 344, 345, 346, 347, 
+       348, 342, 342, 89, 91, 96, 342, 349, 
+       350, 350, 351, 352, 353, 349, 349, 349, 
+       354, 355, 355, 356, 357, 358, 359, 360, 
+       363, 354, 354, 103, 110, 118, 129, 134, 
+       354, 354, 354, 364, 365, 365, 366, 367, 
+       368, 364, 364, 364, 369, 370, 370, 371, 
+       372, 376, 380, 381, 383, 384, 385, 386, 
+       369, 369, 153, 160, 369, 374, 374, 171, 
+       369, 374, 374, 177, 369, 378, 378, 187, 
+       369, 378, 378, 193, 261, 274, 369, 382, 
+       382, 289, 295, 304, 369
+};
+
+static const short _eo_tokenizer_trans_actions[] = {
+       201, 0, 1, 0, 191, 0, 224, 43, 
+       43, 314, 0, 317, 0, 1, 193, 0, 
+       0, 0, 3, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 45, 
+       320, 323, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       69, 0, 1, 0, 0, 55, 1, 3, 
+       0, 1, 0, 53, 0, 203, 0, 0, 
+       0, 5, 233, 0, 3, 0, 236, 0, 
+       0, 0, 0, 0, 3, 0, 230, 0, 
+       0, 0, 0, 0, 3, 0, 332, 67, 
+       0, 0, 0, 0, 1, 3, 0, 1, 
+       0, 0, 85, 0, 1, 0, 71, 0, 
+       206, 0, 335, 83, 0, 0, 0, 0, 
+       1, 3, 0, 1, 0, 0, 103, 0, 
+       1, 0, 87, 0, 209, 0, 1, 89, 
+       0, 0, 0, 0, 1, 93, 0, 1, 
+       91, 117, 0, 1, 0, 105, 0, 212, 
+       7, 242, 0, 245, 0, 1, 107, 137, 
+       0, 1, 0, 0, 121, 1, 3, 0, 
+       1, 0, 119, 0, 215, 0, 0, 0, 
+       0, 0, 3, 0, 251, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 254, 
+       0, 0, 0, 0, 1, 123, 0, 0, 
+       0, 0, 0, 3, 0, 338, 135, 0, 
+       0, 0, 0, 1, 3, 0, 1, 0, 
+       0, 151, 0, 1, 0, 139, 0, 218, 
+       9, 257, 0, 260, 0, 1, 141, 189, 
+       0, 1, 0, 0, 155, 1, 3, 0, 
+       1, 0, 153, 0, 221, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 17, 275, 
+       341, 0, 0, 1, 51, 185, 0, 0, 
+       1, 3, 0, 1, 0, 0, 1, 163, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       21, 278, 344, 0, 0, 1, 51, 187, 
+       0, 0, 1, 3, 0, 1, 0, 0, 
+       1, 165, 0, 0, 0, 0, 0, 0, 
+       0, 0, 1, 0, 1, 3, 0, 0, 
+       0, 27, 293, 27, 27, 0, 1, 0, 
+       1, 0, 0, 0, 0, 0, 0, 29, 
+       29, 296, 29, 299, 29, 0, 1, 0, 
+       0, 1, 0, 1, 0, 0, 0, 0, 
+       0, 0, 1, 0, 1, 0, 0, 3, 
+       3, 0, 35, 305, 35, 0, 1, 0, 
+       1, 0, 0, 0, 33, 33, 33, 0, 
+       0, 1, 0, 0, 0, 0, 0, 0, 
+       0, 0, 3, 0, 39, 0, 3, 0, 
+       41, 0, 1, 0, 0, 1, 3, 0, 
+       1, 0, 0, 37, 308, 37, 37, 311, 
+       37, 0, 3, 0, 31, 302, 31, 31, 
+       159, 0, 0, 0, 0, 0, 0, 1, 
+       0, 1, 3, 0, 0, 11, 263, 11, 
+       11, 0, 1, 0, 1, 157, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 1, 0, 1, 3, 0, 19, 0, 
+       0, 0, 0, 0, 1, 169, 0, 0, 
+       0, 0, 0, 0, 0, 0, 1, 167, 
+       0, 0, 0, 0, 0, 1, 0, 1, 
+       3, 0, 0, 13, 266, 13, 0, 1, 
+       0, 0, 0, 0, 1, 3, 0, 1, 
+       0, 0, 15, 269, 272, 15, 161, 195, 
+       0, 1, 326, 329, 197, 199, 59, 0, 
+       1, 326, 329, 329, 329, 0, 61, 65, 
+       0, 0, 0, 63, 227, 57, 75, 0, 
+       1, 326, 329, 0, 77, 81, 79, 239, 
+       73, 97, 0, 1, 326, 51, 51, 51, 
+       0, 99, 101, 0, 0, 0, 95, 111, 
+       0, 1, 326, 329, 0, 113, 115, 109, 
+       127, 0, 1, 326, 51, 51, 51, 51, 
+       0, 129, 133, 0, 0, 0, 0, 0, 
+       131, 248, 125, 145, 0, 1, 326, 329, 
+       0, 147, 149, 143, 173, 0, 1, 326, 
+       329, 329, 51, 51, 51, 51, 51, 0, 
+       175, 183, 0, 0, 179, 0, 1, 0, 
+       284, 23, 281, 0, 181, 0, 1, 0, 
+       290, 25, 287, 0, 0, 0, 177, 0, 
+       1, 0, 0, 0, 171
+};
+
+static const short _eo_tokenizer_to_state_actions[] = {
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 47, 0, 0, 0, 47, 0, 
+       0, 0, 0, 0, 0, 0, 0, 47, 
+       0, 0, 0, 0, 0, 0, 47, 0, 
+       0, 0, 0, 0, 0, 47, 0, 0, 
+       0, 0, 47, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 47, 0, 0, 0, 
+       0, 47, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0
+};
+
+static const short _eo_tokenizer_from_state_actions[] = {
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 49, 0, 0, 0, 49, 0, 
+       0, 0, 0, 0, 0, 0, 0, 49, 
+       0, 0, 0, 0, 0, 0, 49, 0, 
+       0, 0, 0, 0, 0, 49, 0, 0, 
+       0, 0, 49, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 49, 0, 0, 0, 
+       0, 49, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0, 0, 0, 0, 0, 0, 
+       0, 0, 0
+};
+
+static const short _eo_tokenizer_eof_trans[] = {
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 1, 1, 1, 1, 1, 1, 
+       1, 1, 57, 57, 57, 57, 57, 57, 
+       57, 57, 57, 57, 57, 57, 57, 57, 
+       57, 57, 57, 57, 57, 57, 57, 57, 
+       57, 57, 57, 57, 57, 57, 96, 96, 
+       96, 96, 96, 96, 107, 107, 107, 107, 
+       116, 116, 116, 116, 116, 116, 127, 127, 
+       127, 127, 127, 127, 127, 127, 127, 127, 
+       127, 127, 146, 146, 146, 146, 146, 160, 
+       160, 160, 160, 160, 160, 160, 160, 160, 
+       160, 160, 160, 160, 160, 160, 160, 160, 
+       160, 160, 160, 160, 160, 160, 160, 160, 
+       160, 160, 160, 160, 160, 160, 160, 160, 
+       160, 160, 160, 160, 160, 160, 207, 207, 
+       207, 207, 207, 207, 218, 218, 218, 218, 
+       218, 232, 232, 232, 232, 232, 232, 232, 
+       232, 232, 232, 232, 232, 232, 232, 232, 
+       232, 232, 232, 262, 262, 262, 262, 262, 
+       232, 232, 232, 232, 232, 232, 232, 232, 
+       232, 232, 232, 288, 288, 288, 288, 288, 
+       232, 232, 232, 232, 232, 232, 232, 232, 
+       232, 232, 232, 232, 232, 232, 232, 232, 
+       232, 232, 232, 232, 232, 232, 232, 232, 
+       232, 232, 232, 232, 232, 232, 232, 232, 
+       232, 232, 232, 232, 232, 232, 232, 232, 
+       232, 232, 232, 232, 232, 232, 232, 232, 
+       232, 232, 232, 232, 232, 232, 232, 232, 
+       232, 232, 232, 232, 232, 232, 232, 232, 
+       232, 232, 232, 232, 232, 232, 232, 232, 
+       232, 232, 232, 232, 232, 232, 232, 232, 
+       232, 232, 232, 232, 232, 232, 232, 232, 
+       232, 232, 232, 232, 232, 232, 232, 232, 
+       232, 232, 232, 232, 232, 232, 232, 232, 
+       232, 232, 232, 232, 232, 232, 232, 232, 
+       232, 232, 232, 232, 232, 232, 232, 232, 
+       232, 232, 232, 232, 232, 232, 232, 232, 
+       232, 232, 0, 501, 502, 502, 0, 511, 
+       512, 512, 512, 512, 516, 517, 512, 0, 
+       525, 526, 526, 527, 528, 526, 0, 538, 
+       539, 539, 539, 539, 539, 0, 550, 551, 
+       551, 551, 0, 562, 563, 563, 563, 563, 
+       563, 569, 570, 563, 0, 578, 579, 579, 
+       579, 0, 593, 594, 594, 597, 597, 601, 
+       594, 605, 605, 609, 594, 594, 615, 594, 
+       594, 594, 594
+};
+
+static const int eo_tokenizer_start = 322;
+static const int eo_tokenizer_first_final = 322;
+static const int eo_tokenizer_error = -1;
+
+static const int eo_tokenizer_en_tokenize_accessor = 326;
+static const int eo_tokenizer_en_tokenize_params = 335;
+static const int eo_tokenizer_en_tokenize_property = 342;
+static const int eo_tokenizer_en_tokenize_properties = 349;
+static const int eo_tokenizer_en_tokenize_method = 354;
+static const int eo_tokenizer_en_tokenize_methods = 364;
+static const int eo_tokenizer_en_tokenize_class = 369;
+static const int eo_tokenizer_en_main = 322;
+
+
+#line 918 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+
+
+Eina_Bool
+eo_tokenizer_walk(Eo_Tokenizer *toknz, const char *source)
+{
+   INF("tokenize %s...", source);
+   toknz->source = eina_stringshare_add(source);
+
+   FILE *stream;
+
+   int done = 0;
+   int have = 0;
+   int offset = 0;
+
+   stream = fopen(toknz->source, "rb");
+   if (!stream)
+     {
+        ERR("unable to read in %s", toknz->source);
+        return EINA_FALSE;
+     }
+
+   
+#line 1275 "eo_lexer.c"
+       {
+        toknz->cs = eo_tokenizer_start;
+        toknz->ts = 0;
+        toknz->te = 0;
+        toknz->act = 0;
+       }
+
+#line 940 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+
+   while (!done)
+     {
+        int len;
+        int space;
+
+        toknz->p = toknz->buf + have;
+        space = BUFSIZE - have;
+
+        if (space == 0)
+          {
+             fclose(stream);
+             ABORT(toknz, "out of buffer space");
+          }
+
+        len = fread(toknz->p, 1, space, stream);
+        if (len == 0) break;
+        toknz->pe = toknz->p + len;
+
+        if (len < space)
+          {
+             toknz->eof = toknz->pe;
+             done = 1;
+          }
+
+        
+#line 1310 "eo_lexer.c"
+       {
+       int _klen;
+       unsigned int _trans;
+       const char *_acts;
+       unsigned int _nacts;
+       const char *_keys;
+
+       if ( ( toknz->p) == ( toknz->pe) )
+               goto _test_eof;
+_resume:
+       _acts = _eo_tokenizer_actions + _eo_tokenizer_from_state_actions[ toknz->cs];
+       _nacts = (unsigned int) *_acts++;
+       while ( _nacts-- > 0 ) {
+               switch ( *_acts++ ) {
+       case 35:
+#line 1 "NONE"
+       { toknz->ts = ( toknz->p);}
+       break;
+#line 1329 "eo_lexer.c"
+               }
+       }
+
+       _keys = _eo_tokenizer_trans_keys + _eo_tokenizer_key_offsets[ toknz->cs];
+       _trans = _eo_tokenizer_index_offsets[ toknz->cs];
+
+       _klen = _eo_tokenizer_single_lengths[ toknz->cs];
+       if ( _klen > 0 ) {
+               const char *_lower = _keys;
+               const char *_mid;
+               const char *_upper = _keys + _klen - 1;
+               while (1) {
+                       if ( _upper < _lower )
+                               break;
+
+                       _mid = _lower + ((_upper-_lower) >> 1);
+                       if ( (*( toknz->p)) < *_mid )
+                               _upper = _mid - 1;
+                       else if ( (*( toknz->p)) > *_mid )
+                               _lower = _mid + 1;
+                       else {
+                               _trans += (unsigned int)(_mid - _keys);
+                               goto _match;
+                       }
+               }
+               _keys += _klen;
+               _trans += _klen;
+       }
+
+       _klen = _eo_tokenizer_range_lengths[ toknz->cs];
+       if ( _klen > 0 ) {
+               const char *_lower = _keys;
+               const char *_mid;
+               const char *_upper = _keys + (_klen<<1) - 2;
+               while (1) {
+                       if ( _upper < _lower )
+                               break;
+
+                       _mid = _lower + (((_upper-_lower) >> 1) & ~1);
+                       if ( (*( toknz->p)) < _mid[0] )
+                               _upper = _mid - 2;
+                       else if ( (*( toknz->p)) > _mid[1] )
+                               _lower = _mid + 2;
+                       else {
+                               _trans += (unsigned int)((_mid - _keys)>>1);
+                               goto _match;
+                       }
+               }
+               _trans += _klen;
+       }
+
+_match:
+       _trans = _eo_tokenizer_indicies[_trans];
+_eof_trans:
+        toknz->cs = _eo_tokenizer_trans_targs[_trans];
+
+       if ( _eo_tokenizer_trans_actions[_trans] == 0 )
+               goto _again;
+
+       _acts = _eo_tokenizer_actions + _eo_tokenizer_trans_actions[_trans];
+       _nacts = (unsigned int) *_acts++;
+       while ( _nacts-- > 0 )
+       {
+               switch ( *_acts++ )
+               {
+       case 0:
+#line 298 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      toknz->current_line += 1;
+      DBG("inc[%d] %d", toknz->cs, toknz->current_line);
+   }
+       break;
+       case 1:
+#line 303 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      toknz->saved.line = toknz->current_line;
+      DBG("save line[%d] %d", toknz->cs, toknz->current_line);
+   }
+       break;
+       case 2:
+#line 308 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      toknz->saved.tok = ( toknz->p);
+      DBG("save token[%d] %p %c", toknz->cs, ( toknz->p), *( toknz->p));
+   }
+       break;
+       case 3:
+#line 381 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      if (toknz->tmp.accessor->ret.type != NULL)
+        ABORT(toknz, "accessor has already a return type");
+      toknz->tmp.accessor->ret.type = _eo_tokenizer_token_get(toknz, ( toknz->p));
+      INF("        %s", toknz->tmp.accessor->ret.type);
+   }
+       break;
+       case 4:
+#line 388 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      if (toknz->tmp.accessor->ret.comment != NULL)
+        ABORT(toknz, "accessor return type has already a comment");
+      toknz->tmp.accessor->ret.comment = _eo_tokenizer_token_get(toknz, ( toknz->p)-2);
+      INF("        %s", toknz->tmp.accessor->ret.comment);
+   }
+       break;
+       case 5:
+#line 395 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      toknz->tmp.accessor->legacy = _eo_tokenizer_token_get(toknz, ( toknz->p));
+   }
+       break;
+       case 6:
+#line 407 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      toknz->tmp.accessor_param = _eo_tokenizer_accessor_param_get(toknz, ( toknz->p));
+   }
+       break;
+       case 7:
+#line 411 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      toknz->tmp.accessor_param->attrs = _eo_tokenizer_token_get(toknz, ( toknz->p));
+      toknz->tmp.accessor->params =
+         eina_list_append(toknz->tmp.accessor->params, toknz->tmp.accessor_param);
+      toknz->tmp.accessor_param = NULL;
+   }
+       break;
+       case 8:
+#line 438 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      const char *c = _eo_tokenizer_token_get(toknz, ( toknz->p)-2);
+      if (toknz->tmp.param == NULL)
+        ABORT(toknz, "no parameter set to associate this comment to: %s", c);
+      toknz->tmp.param->comment = c;
+      toknz->tmp.param = NULL;
+   }
+       break;
+       case 9:
+#line 446 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      toknz->tmp.param = _eo_tokenizer_param_get(toknz, ( toknz->p));
+      if (toknz->tmp.prop)
+        toknz->tmp.prop->params = eina_list_append(toknz->tmp.prop->params, toknz->tmp.param);
+      else if (toknz->tmp.meth)
+        toknz->tmp.meth->params = eina_list_append(toknz->tmp.meth->params, toknz->tmp.param);
+      else
+        ABORT(toknz, "got a param but there is no property nor method waiting for it");
+      INF("        %s : %s", toknz->tmp.param->name, toknz->tmp.param->type);
+   }
+       break;
+       case 10:
+#line 536 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      if (toknz->tmp.prop != NULL)
+        ABORT(toknz, "there is a pending property definition %s", toknz->tmp.prop->name);
+      toknz->tmp.prop = _eo_tokenizer_property_get(toknz, ( toknz->p));
+   }
+       break;
+       case 11:
+#line 573 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      if (toknz->tmp.meth->ret.type != NULL)
+        ABORT(toknz, "method '%s' has already a return type", toknz->tmp.meth->name);
+      toknz->tmp.meth->ret.type = _eo_tokenizer_token_get(toknz, ( toknz->p));
+      INF("        %s", toknz->tmp.meth->ret.type);
+   }
+       break;
+       case 12:
+#line 580 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      if (toknz->tmp.meth->ret.comment != NULL)
+        ABORT(toknz, "method '%s' return type has already a comment", toknz->tmp.meth->name);
+      toknz->tmp.meth->ret.comment = _eo_tokenizer_token_get(toknz, ( toknz->p)-2);
+      INF("        %s", toknz->tmp.meth->ret.comment);
+   }
+       break;
+       case 13:
+#line 587 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      toknz->tmp.meth->legacy = _eo_tokenizer_token_get(toknz, ( toknz->p));
+   }
+       break;
+       case 14:
+#line 591 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      toknz->tmp.meth->obj_const = EINA_TRUE;
+      INF("        obj const");
+   }
+       break;
+       case 15:
+#line 647 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      if (toknz->tmp.meth != NULL)
+        ABORT(toknz, "there is a pending method definition %s", toknz->tmp.meth->name);
+      toknz->tmp.meth = _eo_tokenizer_method_get(toknz, ( toknz->p));
+   }
+       break;
+       case 16:
+#line 678 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      const char *base = _eo_tokenizer_token_get(toknz, ( toknz->p));
+      toknz->tmp.str_items = eina_list_append(toknz->tmp.str_items, base);
+   }
+       break;
+       case 17:
+#line 729 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      toknz->tmp.signal = _eo_tokenizer_signal_get(toknz, ( toknz->p));
+      toknz->tmp.kls->signals = eina_list_append(toknz->tmp.kls->signals, toknz->tmp.signal);
+   }
+       break;
+       case 18:
+#line 734 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      if (toknz->tmp.signal->comment != NULL)
+        ABORT(toknz, "signal %s has already a comment", toknz->tmp.signal->name);
+      toknz->tmp.signal->comment = _eo_tokenizer_token_get(toknz, ( toknz->p)-2);
+      toknz->tmp.signal = NULL;
+   }
+       break;
+       case 19:
+#line 741 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      if (toknz->tmp.kls->dflt_ctor != NULL)
+        ABORT(toknz, "A default constructor has already been defined");
+      toknz->tmp.kls->dflt_ctor = _eo_tokenizer_dflt_ctor_get(toknz, ( toknz->p));
+   }
+       break;
+       case 20:
+#line 747 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      if (toknz->tmp.kls->legacy_prefix != NULL)
+        ABORT(toknz, "A legacy prefix has already been given");
+      toknz->tmp.kls->legacy_prefix = _eo_tokenizer_token_get(toknz, ( toknz->p));
+   }
+       break;
+       case 21:
+#line 753 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      if (toknz->tmp.kls->dflt_dtor != NULL)
+        ABORT(toknz, "A default destructor has already been defined");
+      toknz->tmp.kls->dflt_dtor = _eo_tokenizer_dflt_dtor_get(toknz, ( toknz->p));
+   }
+       break;
+       case 22:
+#line 759 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      if (toknz->tmp.kls->dflt_ctor == NULL)
+        ABORT(toknz, "No default constructor is defined for the comment");
+      if (toknz->tmp.kls->dflt_ctor->comment != NULL)
+        ABORT(toknz, "default constructor %s has already a comment", toknz->tmp.kls->dflt_ctor->name);
+      toknz->tmp.kls->dflt_ctor->comment = _eo_tokenizer_token_get(toknz, ( toknz->p)-2);
+   }
+       break;
+       case 23:
+#line 767 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      if (toknz->tmp.kls->dflt_dtor == NULL)
+        ABORT(toknz, "No default destructor is defined for the comment");
+      if (toknz->tmp.kls->dflt_dtor->comment != NULL)
+        ABORT(toknz, "default destructor %s has already a comment", toknz->tmp.kls->dflt_dtor->name);
+      toknz->tmp.kls->dflt_dtor->comment = _eo_tokenizer_token_get(toknz, ( toknz->p)-2);
+   }
+       break;
+       case 24:
+#line 781 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+        toknz->tmp.impl = _eo_tokenizer_implement_get(toknz, ( toknz->p));
+        toknz->tmp.kls->implements = eina_list_append(toknz->tmp.kls->implements, toknz->tmp.impl);
+   }
+       break;
+       case 25:
+#line 786 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+        if (toknz->tmp.impl->legacy)
+           ABORT(toknz, "Legacy section already allocated for implement item");
+        toknz->tmp.impl->legacy = calloc(1, sizeof(Eo_Implement_Legacy_Def));
+   }
+       break;
+       case 26:
+#line 792 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+        if (!toknz->tmp.impl->legacy)
+           ABORT(toknz, "No legacy section");
+        toknz->tmp.impl->legacy->function_name = _eo_tokenizer_token_get(toknz, ( toknz->p));
+   }
+       break;
+       case 27:
+#line 798 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+        toknz->tmp.impl_leg_param = calloc(1, sizeof(Eo_Implement_Legacy_Param_Def));
+        toknz->tmp.impl->legacy->params = eina_list_append(
+              toknz->tmp.impl->legacy->params, toknz->tmp.impl_leg_param);
+
+        toknz->tmp.impl_leg_param->eo_name = _eo_tokenizer_token_get(toknz, ( toknz->p));
+   }
+       break;
+       case 28:
+#line 806 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+        toknz->tmp.impl_leg_param->legacy_name = _eo_tokenizer_token_get(toknz, ( toknz->p));
+   }
+       break;
+       case 29:
+#line 810 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+        toknz->tmp.impl_leg_param->comment = _eo_tokenizer_token_get(toknz, ( toknz->p)-2);
+   }
+       break;
+       case 30:
+#line 814 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+        if (!toknz->tmp.impl->legacy)
+           ABORT(toknz, "No legacy section");
+        toknz->tmp.impl->legacy->ret_type= _eo_tokenizer_token_get(toknz, ( toknz->p));
+   }
+       break;
+       case 31:
+#line 820 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+        if (!toknz->tmp.impl->legacy)
+           ABORT(toknz, "No legacy section");
+        toknz->tmp.impl->legacy->ret_value = _eo_tokenizer_token_get(toknz, ( toknz->p));
+   }
+       break;
+       case 32:
+#line 895 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      if (toknz->tmp.kls != NULL)
+        ABORT(toknz, "there is a pending class definition %s", toknz->tmp.kls->name);
+      toknz->tmp.kls = _eo_tokenizer_class_get(toknz, ( toknz->p));
+   }
+       break;
+       case 33:
+#line 901 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {
+      if (!toknz->tmp.kls)
+         ABORT(toknz, "No pending class definition");
+      toknz->tmp.kls->type = _eo_tokenizer_token_get(toknz, ( toknz->p));
+   }
+       break;
+       case 36:
+#line 1 "NONE"
+       { toknz->te = ( toknz->p)+1;}
+       break;
+       case 37:
+#line 374 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      if (toknz->tmp.accessor->comment != NULL)
+        ABORT(toknz, "accessor has already a comment");
+      toknz->tmp.accessor->comment = _eo_tokenizer_token_get(toknz, ( toknz->p)-1);
+      INF("        %s", toknz->tmp.accessor->comment);
+   }}
+       break;
+       case 38:
+#line 313 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      DBG("comment[%d] line%03d:%03d", toknz->cs,
+          toknz->saved.line, toknz->current_line);
+   }}
+       break;
+       case 39:
+#line 430 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;}
+       break;
+       case 40:
+#line 431 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;}
+       break;
+       case 41:
+#line 399 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      INF("      }");
+      toknz->tmp.prop->accessors = eina_list_append(toknz->tmp.prop->accessors, toknz->tmp.accessor);
+      toknz->tmp.accessor = NULL;
+      toknz->current_nesting--;
+      { toknz->cs = 342; goto _again;}
+   }}
+       break;
+       case 42:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 43:
+#line 426 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;}
+       break;
+       case 44:
+#line 429 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;}
+       break;
+       case 45:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 46:
+#line 429 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {{( toknz->p) = (( toknz->te))-1;}}
+       break;
+       case 47:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {{( toknz->p) = (( toknz->te))-1;}{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 48:
+#line 313 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      DBG("comment[%d] line%03d:%03d", toknz->cs,
+          toknz->saved.line, toknz->current_line);
+   }}
+       break;
+       case 49:
+#line 457 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      INF("      }");
+      toknz->tmp.param = NULL;
+      toknz->current_nesting--;
+      if (toknz->tmp.prop)
+        { toknz->cs = 342; goto _again;}
+      else if (toknz->tmp.meth)
+        { toknz->cs = 354; goto _again;}
+      else
+        ABORT(toknz, "leaving tokenize_params but there is no property nor method pending");
+   }}
+       break;
+       case 50:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 51:
+#line 473 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;}
+       break;
+       case 52:
+#line 475 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;}
+       break;
+       case 53:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 54:
+#line 475 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {{( toknz->p) = (( toknz->te))-1;}}
+       break;
+       case 55:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {{( toknz->p) = (( toknz->te))-1;}{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 56:
+#line 313 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      DBG("comment[%d] line%03d:%03d", toknz->cs,
+          toknz->saved.line, toknz->current_line);
+   }}
+       break;
+       case 57:
+#line 482 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      INF("      get {");
+      toknz->tmp.accessor = _eo_tokenizer_accessor_get(toknz, GETTER);
+      toknz->current_nesting++;
+      { toknz->cs = 326; goto _again;}
+   }}
+       break;
+       case 58:
+#line 489 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      INF("      set {");
+      toknz->tmp.accessor = _eo_tokenizer_accessor_get(toknz, SETTER);
+      toknz->current_nesting++;
+      { toknz->cs = 326; goto _again;}
+   }}
+       break;
+       case 59:
+#line 496 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      INF("      params {");
+      toknz->current_nesting++;
+      { toknz->cs = 335; goto _again;}
+   }}
+       break;
+       case 60:
+#line 502 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      if (eina_list_count(toknz->tmp.prop->params) == 0)
+        WRN("property '%s' has no parameters.", toknz->tmp.prop->name);
+      if (eina_list_count(toknz->tmp.prop->accessors) == 0)
+        WRN("property '%s' has no accessors.", toknz->tmp.prop->name);
+      INF("    }");
+      toknz->tmp.kls->properties = eina_list_append(toknz->tmp.kls->properties, toknz->tmp.prop);
+      toknz->tmp.prop = NULL;
+      toknz->current_nesting--;
+      { toknz->cs = 349; goto _again;}
+   }}
+       break;
+       case 61:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 62:
+#line 519 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;}
+       break;
+       case 63:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 64:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {{( toknz->p) = (( toknz->te))-1;}{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 65:
+#line 313 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      DBG("comment[%d] line%03d:%03d", toknz->cs,
+          toknz->saved.line, toknz->current_line);
+   }}
+       break;
+       case 66:
+#line 530 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      INF("    %s {", toknz->tmp.prop->name);
+      toknz->current_nesting++;
+      { toknz->cs = 342; goto _again;}
+   }}
+       break;
+       case 67:
+#line 542 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      INF("  }");
+      toknz->current_nesting--;
+      { toknz->cs = 369; goto _again;}
+   }}
+       break;
+       case 68:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 69:
+#line 551 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;}
+       break;
+       case 70:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 71:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {{( toknz->p) = (( toknz->te))-1;}{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 72:
+#line 560 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      if (toknz->tmp.meth->comment != NULL)
+        ABORT(toknz, "method has already a comment");
+      toknz->tmp.meth->comment = _eo_tokenizer_token_get(toknz, ( toknz->p)-1);
+      INF("        %s", toknz->tmp.meth->comment);
+   }}
+       break;
+       case 73:
+#line 313 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      DBG("comment[%d] line%03d:%03d", toknz->cs,
+          toknz->saved.line, toknz->current_line);
+   }}
+       break;
+       case 74:
+#line 567 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      INF("      params {");
+      toknz->current_nesting++;
+      { toknz->cs = 335; goto _again;}
+   }}
+       break;
+       case 75:
+#line 633 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;}
+       break;
+       case 76:
+#line 634 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;}
+       break;
+       case 77:
+#line 596 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      Eina_List **l;
+      if (eina_list_count(toknz->tmp.meth->params) == 0)
+        WRN("method '%s' has no parameters.", toknz->tmp.meth->name);
+      INF("    }");
+      switch (toknz->current_methods_type) {
+        case METH_CONSTRUCTOR:
+          l = &toknz->tmp.kls->constructors;
+          break;
+        case METH_DESTRUCTOR:
+          l = &toknz->tmp.kls->destructors;
+          break;
+        case METH_REGULAR:
+          l = &toknz->tmp.kls->methods;
+          break;
+        default:
+          ABORT(toknz, "unknown method type %d", toknz->current_methods_type);
+      }
+      toknz->tmp.meth->type = toknz->current_methods_type;
+      *l = eina_list_append(*l, toknz->tmp.meth);
+      toknz->tmp.meth = NULL;
+      toknz->current_nesting--;
+      { toknz->cs = 364; goto _again;}
+   }}
+       break;
+       case 78:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 79:
+#line 628 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;}
+       break;
+       case 80:
+#line 632 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;}
+       break;
+       case 81:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 82:
+#line 632 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {{( toknz->p) = (( toknz->te))-1;}}
+       break;
+       case 83:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {{( toknz->p) = (( toknz->te))-1;}{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 84:
+#line 313 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      DBG("comment[%d] line%03d:%03d", toknz->cs,
+          toknz->saved.line, toknz->current_line);
+   }}
+       break;
+       case 85:
+#line 641 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      INF("    %s {", toknz->tmp.meth->name);
+      toknz->current_nesting++;
+      { toknz->cs = 354; goto _again;}
+   }}
+       break;
+       case 86:
+#line 653 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      INF("  }");
+      toknz->current_methods_type = METH_TYPE_LAST;
+      toknz->current_nesting--;
+      { toknz->cs = 369; goto _again;}
+   }}
+       break;
+       case 87:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 88:
+#line 663 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;}
+       break;
+       case 89:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 90:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {{( toknz->p) = (( toknz->te))-1;}{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 91:
+#line 672 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      if (toknz->tmp.kls->comment != NULL)
+        ABORT(toknz, "class %s has already a comment", toknz->tmp.kls->name);
+      toknz->tmp.kls->comment = _eo_tokenizer_token_get(toknz, ( toknz->p)-1);
+   }}
+       break;
+       case 92:
+#line 313 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      DBG("comment[%d] line%03d:%03d", toknz->cs,
+          toknz->saved.line, toknz->current_line);
+   }}
+       break;
+       case 93:
+#line 683 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      toknz->tmp.kls->inherits = toknz->tmp.str_items;
+      toknz->tmp.str_items = NULL;
+   }}
+       break;
+       case 94:
+#line 688 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+   }}
+       break;
+       case 95:
+#line 691 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+   }}
+       break;
+       case 96:
+#line 694 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      INF("  constructors {");
+      toknz->current_methods_type = METH_CONSTRUCTOR;
+      toknz->current_nesting++;
+      { toknz->cs = 364; goto _again;}
+   }}
+       break;
+       case 97:
+#line 701 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      INF("  destructors {");
+      toknz->current_methods_type = METH_DESTRUCTOR;
+      toknz->current_nesting++;
+      { toknz->cs = 364; goto _again;}
+   }}
+       break;
+       case 98:
+#line 708 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      INF("  properties {");
+      toknz->current_nesting++;
+      { toknz->cs = 349; goto _again;}
+   }}
+       break;
+       case 99:
+#line 714 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      INF("  begin methods");
+      toknz->current_methods_type = METH_REGULAR;
+      toknz->current_nesting++;
+      { toknz->cs = 364; goto _again;}
+   }}
+       break;
+       case 100:
+#line 721 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      INF("end class: %s", toknz->tmp.kls->name);
+      toknz->classes = eina_list_append(toknz->classes, toknz->tmp.kls);
+      toknz->tmp.kls = NULL;
+      toknz->current_nesting--;
+      { toknz->cs = 322; goto _again;}
+   }}
+       break;
+       case 101:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 102:
+#line 870 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;}
+       break;
+       case 103:
+#line 873 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;}
+       break;
+       case 104:
+#line 877 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;}
+       break;
+       case 105:
+#line 878 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;}
+       break;
+       case 106:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 107:
+#line 877 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {{( toknz->p) = (( toknz->te))-1;}}
+       break;
+       case 108:
+#line 878 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {{( toknz->p) = (( toknz->te))-1;}}
+       break;
+       case 109:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {{( toknz->p) = (( toknz->te))-1;}{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 110:
+#line 313 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      DBG("comment[%d] line%03d:%03d", toknz->cs,
+          toknz->saved.line, toknz->current_line);
+   }}
+       break;
+       case 111:
+#line 889 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      INF("begin class: %s", toknz->tmp.kls->name);
+      toknz->current_nesting++;
+      { toknz->cs = 369; goto _again;}
+   }}
+       break;
+       case 112:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p)+1;{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 113:
+#line 912 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;}
+       break;
+       case 114:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       { toknz->te = ( toknz->p);( toknz->p)--;{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+       case 115:
+#line 322 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+       {{( toknz->p) = (( toknz->te))-1;}{
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = ( toknz->p), d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *( toknz->p), buf);
+      toknz->cs = eo_tokenizer_error;
+      {( toknz->p)++; goto _out; }  /* necessary to stop scanners */
+   }}
+       break;
+#line 2505 "eo_lexer.c"
+               }
+       }
+
+_again:
+       _acts = _eo_tokenizer_actions + _eo_tokenizer_to_state_actions[ toknz->cs];
+       _nacts = (unsigned int) *_acts++;
+       while ( _nacts-- > 0 ) {
+               switch ( *_acts++ ) {
+       case 34:
+#line 1 "NONE"
+       { toknz->ts = 0;}
+       break;
+#line 2518 "eo_lexer.c"
+               }
+       }
+
+       if ( ++( toknz->p) != ( toknz->pe) )
+               goto _resume;
+       _test_eof: {}
+       if ( ( toknz->p) == ( toknz->eof) )
+       {
+       if ( _eo_tokenizer_eof_trans[ toknz->cs] > 0 ) {
+               _trans = _eo_tokenizer_eof_trans[ toknz->cs] - 1;
+               goto _eof_trans;
+       }
+       }
+
+       _out: {}
+       }
+
+#line 966 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+
+        if ( toknz->cs == 
+#line 2539 "eo_lexer.c"
+-1
+#line 967 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl"
+ )
+          {
+             ERR("wrong termination");
+             break;
+          }
+
+        if ( toknz->ts == 0 )
+          have = 0;
+        else
+          {
+             DBG("move data and pointers before buffer feed");
+             have = toknz->pe - toknz->ts;
+             offset = toknz->ts - toknz->buf;
+             memmove(toknz->buf, toknz->ts, have);
+             toknz->te -= offset;
+             toknz->ts = toknz->buf;
+          }
+
+        if (toknz->saved.tok != NULL)
+          {
+             if ((have == 0) || ((toknz->saved.tok - offset) < toknz->buf))
+               {
+                  WRN("reset lost saved token %p", toknz->saved.tok);
+                  toknz->saved.tok = NULL;
+               }
+             else
+               toknz->saved.tok -= offset;
+          }
+     }
+
+   fclose(stream);
+
+   return EINA_TRUE;
+}
+
+Eo_Tokenizer*
+eo_tokenizer_get(void)
+{
+   Eo_Tokenizer *toknz = calloc(1, sizeof(Eo_Tokenizer));
+   if (!toknz) return NULL;
+
+   toknz->ts = NULL;
+   toknz->te = NULL;
+   /* toknz->top = 0; */
+   toknz->source = NULL;
+   toknz->max_nesting = 10;
+   toknz->current_line = 1;
+   toknz->current_nesting = 0;
+   toknz->current_methods_type = METH_TYPE_LAST;
+   toknz->saved.tok = NULL;
+   toknz->saved.line = 0;
+   toknz->classes = NULL;
+
+   return toknz;
+}
+
+static char *_accessor_type_str[ACCESSOR_TYPE_LAST] = { "setter", "getter" };
+static char *_param_way_str[PARAM_WAY_LAST] = { "IN", "OUT", "INOUT" };
+
+void
+eo_tokenizer_dump(Eo_Tokenizer *toknz)
+{
+   const char *s;
+   Eina_List *k, *l, *m;
+
+   Eo_Class_Def *kls;
+   Eo_Property_Def *prop;
+   Eo_Method_Def *meth;
+   Eo_Param_Def *param;
+   Eo_Accessor_Def *accessor;
+   Eo_Signal_Def *sgn;
+   /* Eo_Ret_Def *ret; */
+
+   EINA_LIST_FOREACH(toknz->classes, k, kls)
+     {
+        printf("Class: %s (%s)\n",
+               kls->name, (kls->comment ? kls->comment : "-"));
+        printf("  inherits from :");
+        EINA_LIST_FOREACH(kls->inherits, l, s)
+           printf(" %s", s);
+        printf("\n");
+        printf("  implements:");
+        EINA_LIST_FOREACH(kls->implements, l, s)
+           printf(" %s", s);
+        printf("\n");
+        printf("  signals:\n");
+        EINA_LIST_FOREACH(kls->signals, l, sgn)
+           printf("    %s (%s)\n", sgn->name, sgn->comment);
+
+        EINA_LIST_FOREACH(kls->constructors, l, meth)
+          {
+             printf("  constructors: %s\n", meth->name);
+             printf("    return: %s (%s)\n", meth->ret.type, meth->ret.comment);
+             printf("    legacy : %s\n", meth->legacy);
+             EINA_LIST_FOREACH(meth->params, m, param)
+               {
+                  printf("    param: %s %s : %s (%s)\n",
+                         _param_way_str[param->way], param->name,
+                         param->type, param->comment);
+               }
+          }
+
+        EINA_LIST_FOREACH(kls->destructors, l, meth)
+          {
+             printf("  destructors: %s\n", meth->name);
+             printf("    return: %s (%s)\n", meth->ret.type, meth->ret.comment);
+             printf("    legacy : %s\n", meth->legacy);
+             EINA_LIST_FOREACH(meth->params, m, param)
+               {
+                  printf("    param: %s %s : %s (%s)\n",
+                         _param_way_str[param->way], param->name,
+                         param->type, param->comment);
+               }
+          }
+
+        EINA_LIST_FOREACH(kls->properties, l, prop)
+          {
+             printf("  property: %s\n", prop->name);
+             EINA_LIST_FOREACH(prop->params, m, param)
+               {
+                  printf("    param: %s : %s (%s)\n",
+                         param->name, param->type, param->comment);
+               }
+             EINA_LIST_FOREACH(prop->accessors, m, accessor)
+               {
+                  printf("    accessor: %s : %s (%s)\n",
+                         accessor->ret.type, _accessor_type_str[accessor->type],
+                         accessor->comment);
+                  printf("      legacy : %s\n", accessor->legacy);
+               }
+          }
+
+        EINA_LIST_FOREACH(kls->methods, l, meth)
+          {
+             printf("  method: %s\n", meth->name);
+             printf("    return: %s (%s)\n", meth->ret.type, meth->ret.comment);
+             printf("    legacy : %s\n", meth->legacy);
+             printf("    obj_const : %s\n", meth->obj_const?"true":"false");
+             EINA_LIST_FOREACH(meth->params, m, param)
+               {
+                  printf("    param: %s %s : %s (%s)\n",
+                         _param_way_str[param->way], param->name,
+                         param->type, param->comment);
+               }
+          }
+
+     }
+
+}
+
+Eina_Bool
+eo_tokenizer_database_fill(const char *filename)
+{
+   const char *s;
+   Eina_List *k, *l, *m;
+
+   Eo_Class_Def *kls;
+   Eo_Property_Def *prop;
+   Eo_Method_Def *meth;
+   Eo_Param_Def *param;
+   Eo_Accessor_Def *accessor;
+   Eo_Signal_Def *signal;
+   Eo_Implement_Def *impl;
+   /* Eo_Ret_Def *ret; */
+
+   Eo_Tokenizer *toknz = eo_tokenizer_get();
+   if (!toknz)
+     {
+        ERR("can't create eo_tokenizer");
+        return EINA_FALSE;
+     }
+
+   if (access(filename, F_OK) != 0)
+     {
+        ERR("error accessing file %s : %s", filename, strerror(errno));
+        return EINA_FALSE;
+     }
+   eo_tokenizer_walk(toknz, filename);
+
+   EINA_LIST_FOREACH(toknz->classes, k, kls)
+     {
+        Eolian_Class_Type type = EOLIAN_CLASS_REGULAR;
+        if (kls->type)
+          {
+             if (!strcmp(kls->type, "Regular")) type = EOLIAN_CLASS_REGULAR;
+             else if (!strcmp(kls->type, "RegularNonInstantiable")) type = EOLIAN_CLASS_REGULAR_NON_INSTANT;
+             else if (!strcmp(kls->type, "Mixin")) type = EOLIAN_CLASS_MIXIN;
+             else if (!strcmp(kls->type, "Interface")) type = EOLIAN_CLASS_INTERFACE;
+             else type = EOLIAN_CLASS_UNKNOWN_TYPE;
+          }
+        database_class_add(kls->name, type);
+        if (kls->comment) database_class_description_set(kls->name, kls->comment);
+
+        EINA_LIST_FOREACH(kls->inherits, l, s)
+           database_class_inherit_add(kls->name, s);
+
+        if (kls->legacy_prefix)
+          {
+             database_class_legacy_prefix_set(kls->name, kls->legacy_prefix);
+          }
+        if (kls->dflt_ctor)
+          {
+             Eolian_Function foo_id = database_function_new(kls->dflt_ctor->name, DFLT_CONSTRUCTOR);
+             database_class_function_add(kls->name, foo_id);
+             database_function_description_set(foo_id, EOLIAN_COMMENT, kls->dflt_ctor->comment);
+          }
+        if (kls->dflt_dtor)
+          {
+             Eolian_Function foo_id = database_function_new(kls->dflt_dtor->name, DFLT_DESTRUCTOR);
+             database_class_function_add(kls->name, foo_id);
+             database_function_description_set(foo_id, EOLIAN_COMMENT, kls->dflt_dtor->comment);
+          }
+        EINA_LIST_FOREACH(kls->constructors, l, meth)
+          {
+             Eolian_Function foo_id = database_function_new(meth->name, CONSTRUCTOR);
+             database_class_function_add(kls->name, foo_id);
+             database_function_description_set(foo_id, EOLIAN_RETURN_COMMENT, meth->ret.comment);
+             database_function_data_set(foo_id, EOLIAN_LEGACY, meth->legacy);
+             EINA_LIST_FOREACH(meth->params, m, param)
+               {
+                  database_function_parameter_add(foo_id, (Eolian_Parameter_Dir)param->way, param->type, param->name, param->comment);
+               }
+          }
+
+        EINA_LIST_FOREACH(kls->destructors, l, meth)
+          {
+             Eolian_Function foo_id = database_function_new(meth->name, DESTRUCTOR);
+             database_class_function_add(kls->name, foo_id);
+             database_function_description_set(foo_id, EOLIAN_RETURN_COMMENT, meth->ret.comment);
+             database_function_data_set(foo_id, EOLIAN_LEGACY, meth->legacy);
+             EINA_LIST_FOREACH(meth->params, m, param)
+               {
+                  database_function_parameter_add(foo_id, (Eolian_Parameter_Dir)param->way, param->type, param->name, param->comment);
+               }
+          }
+
+        EINA_LIST_FOREACH(kls->properties, l, prop)
+          {
+             Eolian_Function foo_id = database_function_new(prop->name, UNRESOLVED);
+             EINA_LIST_FOREACH(prop->params, m, param)
+               {
+                  /* IN_PARAM doesn't care */
+                  database_function_parameter_add(foo_id, EOLIAN_IN_PARAM, param->type, param->name, param->comment);
+               }
+             EINA_LIST_FOREACH(prop->accessors, m, accessor)
+               {
+                  database_function_type_set(foo_id, (accessor->type == SETTER?SET:GET));
+                  if (accessor->ret.type)
+                     database_function_data_set(foo_id,
+                           (accessor->type == SETTER?EOLIAN_PROP_SET_RETURN_TYPE:EOLIAN_PROP_GET_RETURN_TYPE),
+                           accessor->ret.type);
+                  database_function_description_set(foo_id,
+                        (accessor->type == SETTER?EOLIAN_COMMENT_SET:EOLIAN_COMMENT_GET),
+                        accessor->comment);
+                  Eo_Accessor_Param *acc_param;
+                  Eina_List *m2;
+                  /* Only in get access, we check const attribute */
+                  if (accessor->type == GETTER)
+                    {
+                       EINA_LIST_FOREACH(accessor->params, m2, acc_param)
+                         {
+                            Eolian_Function_Parameter desc = eolian_function_parameter_get(foo_id, acc_param->name);
+                            if (!desc)
+                              {
+                                 printf("Error - %s not known as parameter of property %s\n", acc_param->name, prop->name);
+                                 return EINA_FALSE;
+                              }
+                            if (strstr(acc_param->attrs, "const"))
+                              {
+                                 database_parameter_get_const_attribute_set(desc, EINA_TRUE);
+                              }
+                         }
+                    }
+               }
+             database_class_function_add(kls->name, foo_id);
+          }
+
+        EINA_LIST_FOREACH(kls->methods, l, meth)
+          {
+             Eolian_Function foo_id = database_function_new(meth->name, METHOD_FUNC);
+             database_class_function_add(kls->name, foo_id);
+             database_function_data_set(foo_id, EOLIAN_METHOD_RETURN_TYPE, meth->ret.type);
+             database_function_description_set(foo_id, EOLIAN_RETURN_COMMENT, meth->ret.comment);
+             database_function_description_set(foo_id, EOLIAN_COMMENT, meth->comment);
+             database_function_data_set(foo_id, EOLIAN_LEGACY, meth->legacy);
+             database_function_object_set_as_const(foo_id, meth->obj_const);
+             EINA_LIST_FOREACH(meth->params, m, param)
+               {
+                  database_function_parameter_add(foo_id, (Eolian_Parameter_Dir)param->way, param->type, param->name, param->comment);
+               }
+          }
+
+        EINA_LIST_FOREACH(kls->implements, l, impl)
+          {
+             const char *class = impl->meth_name;
+             char *func = strstr(class, "::");
+             if (func) *func = '\0';
+             func += 2;
+             Eolian_Function_Type ftype = UNRESOLVED;
+             char *type_as_str = strstr(func, "::");
+             if (type_as_str)
+               {
+                  *type_as_str = '\0';
+                  if (!strcmp(type_as_str+2, "set")) ftype = SET;
+                  else if (!strcmp(type_as_str+2, "get")) ftype = GET;
+               }
+             Eolian_Implement impl_desc = database_implement_new(class, func, ftype);
+             if (impl->legacy)
+               {
+                  Eo_Implement_Legacy_Def *eo_leg = impl->legacy;
+                  Eolian_Implement_Legacy leg = database_implement_legacy_add(
+                        impl_desc, eo_leg->function_name);
+                  database_implement_legacy_return_add(leg, eo_leg->ret_type, eo_leg->ret_value);
+                  if (eo_leg->params)
+                    {
+                       Eina_List *itr;
+                       Eo_Implement_Legacy_Param_Def *p;
+                       EINA_LIST_FOREACH(eo_leg->params, itr, p)
+                          database_implement_legacy_param_add(leg, p->eo_name,
+                                p->legacy_name, p->comment);
+                    }
+               }
+             database_class_implement_add(kls->name, impl_desc);
+          }
+
+        EINA_LIST_FOREACH(kls->signals, l, signal)
+          {
+             Eolian_Event ev = database_event_new(signal->name, signal->comment);
+             database_class_event_add(kls->name, ev);
+          }
+
+     }
+
+   eo_tokenizer_free(toknz);
+   return EINA_TRUE;
+}
+
+void
+eo_tokenizer_free(Eo_Tokenizer *toknz)
+{
+   Eo_Class_Def *kls;
+
+   if (toknz->source)
+     eina_stringshare_del(toknz->source);
+
+   EINA_LIST_FREE(toknz->classes, kls)
+      eo_definitions_class_def_free(kls);
+
+   free(toknz);
+}
+
diff --git a/src/lib/eolian/eo_lexer.h b/src/lib/eolian/eo_lexer.h
new file mode 100644 (file)
index 0000000..1932621
--- /dev/null
@@ -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__ */
diff --git a/src/lib/eolian/eo_lexer.rl b/src/lib/eolian/eo_lexer.rl
new file mode 100644 (file)
index 0000000..01554f8
--- /dev/null
@@ -0,0 +1,1317 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <Eina.h>
+
+#include "eo_lexer.h"
+#include "eolian_database.h"
+
+static int _eo_tokenizer_log_dom = -1;
+#ifdef CRITICAL
+#undef CRITICAL
+#endif
+#define CRITICAL(...) EINA_LOG_DOM_CRIT(_eo_tokenizer_log_dom, __VA_ARGS__)
+
+#ifdef ERR
+#undef ERR
+#endif
+#define ERR(...) EINA_LOG_DOM_ERR(_eo_tokenizer_log_dom, __VA_ARGS__)
+
+#ifdef WRN
+#undef WRN
+#endif
+#define WRN(...) EINA_LOG_DOM_WARN(_eo_tokenizer_log_dom, __VA_ARGS__)
+
+#ifdef INF
+#undef INF
+#endif
+#define INF(...) EINA_LOG_DOM_INFO(_eo_tokenizer_log_dom, __VA_ARGS__)
+
+#ifdef DBG
+#undef DBG
+#endif
+#define DBG(...) EINA_LOG_DOM_DBG(_eo_tokenizer_log_dom, __VA_ARGS__)
+
+static int _init_counter = 0;
+
+int
+eo_tokenizer_init()
+{
+   if (!_init_counter)
+     {
+        eina_init();
+        eina_log_color_disable_set(EINA_FALSE);
+        _eo_tokenizer_log_dom = eina_log_domain_register("eo_toknz", EINA_COLOR_CYAN);
+     }
+   return _init_counter++;
+}
+
+int
+eo_tokenizer_shutdown()
+{
+   if (_init_counter <= 0) return 0;
+   _init_counter--;
+   if (!_init_counter)
+     {
+        eina_log_domain_unregister(_eo_tokenizer_log_dom);
+        _eo_tokenizer_log_dom = -1;
+        eina_shutdown();
+     }
+   return _init_counter;
+}
+
+static void
+_eo_tokenizer_abort(Eo_Tokenizer *toknz,
+                    const char *file, const char* fct, int line,
+                    const char *fmt, ...)
+{
+   va_list ap;
+   va_start (ap, fmt);
+   eina_log_vprint(_eo_tokenizer_log_dom, EINA_LOG_LEVEL_ERR,
+                   file, fct, line, fmt, ap);
+   va_end(ap);
+   fprintf(stderr, "File:%s\n toknz[%d] n:%d l:%d p:%d pe:%d ts:%s te:%s act:%d\n",
+          toknz->source,
+          toknz->cs, toknz->current_nesting, toknz->current_line,
+          (int)(toknz->p - toknz->buf), (int)(toknz->pe - toknz->buf),
+          toknz->ts, toknz->te, toknz->act);
+   exit(EXIT_FAILURE);
+}
+#define ABORT(toknz, ...) \
+   _eo_tokenizer_abort(toknz, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__);
+
+static void _eo_tokenizer_normalize_buf(char *buf)
+{
+   int c;
+   char *s, *d;
+   Eina_Bool in_space = EINA_TRUE;
+   Eina_Bool in_newline = EINA_FALSE;
+
+   /* ' '+ -> ' '
+    * '\n' ' '* '*' ' '* -> '\n'
+    */
+   for (s = buf, d = buf; *s != '\0'; s++)
+     {
+        c = *s;
+        *d = c;
+
+        if (!in_space || (c != ' '))
+          d++;
+
+        if (c == ' ')
+          in_space = EINA_TRUE;
+        else
+          in_space = EINA_FALSE;
+
+        if (c == '\n')
+          {
+             in_newline = EINA_TRUE;
+             in_space = EINA_TRUE;
+          }
+        else if (in_newline && c == '*' )
+          {
+             in_space = EINA_TRUE;
+             in_newline = EINA_FALSE;
+             d--;
+          }
+     }
+   /* ' '+$ -> $ */
+   d--;
+   while (*d == ' ') d--;
+   d++;
+   if (d < buf) return;
+   *d = '\0';
+}
+
+static const char*
+_eo_tokenizer_token_get(Eo_Tokenizer *toknz, char *p)
+{
+   if (toknz->saved.tok == NULL) ABORT(toknz, "toknz->saved.tok is NULL");
+   char d[BUFSIZE];
+   int l = (p - toknz->saved.tok);
+   memcpy(d, toknz->saved.tok, l);
+   d[l] = '\0';
+   _eo_tokenizer_normalize_buf(d);
+   toknz->saved.tok = NULL;
+   DBG("token : >%s<", d);
+   return eina_stringshare_add(d);
+}
+
+static Eo_Class_Def*
+_eo_tokenizer_class_get(Eo_Tokenizer *toknz, char *p)
+{
+   Eo_Class_Def *kls = calloc(1, sizeof(Eo_Class_Def));
+   if (kls == NULL) ABORT(toknz, "calloc Eo_Class_Def failure");
+
+   kls->name = _eo_tokenizer_token_get(toknz, p);
+
+   return kls;
+}
+
+static Eo_Property_Def*
+_eo_tokenizer_property_get(Eo_Tokenizer *toknz, char *p)
+{
+   Eo_Property_Def *prop = calloc(1, sizeof(Eo_Property_Def));
+   if (prop == NULL) ABORT(toknz, "calloc Eo_Property_Def failure");
+
+   prop->name = _eo_tokenizer_token_get(toknz, p);
+
+   return prop;
+}
+
+static Eo_Method_Def*
+_eo_tokenizer_method_get(Eo_Tokenizer *toknz, char *p)
+{
+   Eo_Method_Def *meth = calloc(1, sizeof(Eo_Method_Def));
+   if (meth == NULL) ABORT(toknz, "calloc Eo_Method_Def failure");
+
+   meth->name = _eo_tokenizer_token_get(toknz, p);
+
+   return meth;
+}
+
+static Eo_Param_Def*
+_eo_tokenizer_param_get(Eo_Tokenizer *toknz, char *p)
+{
+   char *s;
+
+   Eo_Param_Def *param = calloc(1, sizeof(Eo_Param_Def));
+   if (param == NULL) ABORT(toknz, "calloc Eo_Param_Def failure");
+
+   s = p - 1; /* Don't look at ';' */
+   /* Remove any space between the param name and ';'
+    * This loop fixes the case where "char *name ;" becomes the type of the param.
+    */
+   while (*s == ' ') s--;
+   for (; s >= toknz->saved.tok; s--)
+     {
+        if ((*s == ' ') || (*s == '*'))
+          break;
+     }
+
+   if (s == toknz->saved.tok)
+     ABORT(toknz, "wrong parameter: %s", _eo_tokenizer_token_get(toknz, p));
+   s++;
+
+   param->way = PARAM_IN;
+   if (strncmp(toknz->saved.tok, "in ", 3) == 0)
+     {
+        toknz->saved.tok += 3;
+        param->way = PARAM_IN;
+     }
+   else if (strncmp(toknz->saved.tok, "out ", 4) == 0)
+     {
+        toknz->saved.tok += 4;
+        param->way = PARAM_OUT;
+     }
+   else if (strncmp(toknz->saved.tok, "inout ", 6) == 0)
+     {
+        toknz->saved.tok += 6;
+        param->way = PARAM_INOUT;
+     }
+
+   param->type = _eo_tokenizer_token_get(toknz, s);
+
+   toknz->saved.tok = s;
+   param->name = _eo_tokenizer_token_get(toknz, p);
+
+   return param;
+}
+
+static Eo_Accessor_Param*
+_eo_tokenizer_accessor_param_get(Eo_Tokenizer *toknz, char *p)
+{
+   Eo_Accessor_Param *param = calloc(1, sizeof(Eo_Accessor_Param));
+   if (param == NULL) ABORT(toknz, "calloc Eo_Accessor_Param failure");
+
+   /* Remove the colon and spaces - we just need the param name */
+   while (*p == ':') p--;
+   while (*p == ' ') p--;
+   param->name = _eo_tokenizer_token_get(toknz, p);
+
+   return param;
+}
+
+static Eo_Accessor_Def *
+_eo_tokenizer_accessor_get(Eo_Tokenizer *toknz, Eo_Accessor_Type type)
+{
+   Eo_Accessor_Def *accessor = calloc(1, sizeof(Eo_Accessor_Def));
+   if (accessor == NULL) ABORT(toknz, "calloc Eo_Accessor_Def failure");
+
+   accessor->type = type;
+
+   return accessor;
+}
+
+static Eo_Signal_Def*
+_eo_tokenizer_signal_get(Eo_Tokenizer *toknz, char *p)
+{
+   Eo_Signal_Def *sgn = calloc(1, sizeof(Eo_Signal_Def));
+   if (sgn == NULL) ABORT(toknz, "calloc Eo_Signal_Def failure");
+
+   sgn->name = _eo_tokenizer_token_get(toknz, p);
+
+   return sgn;
+}
+
+static Eo_DfltCtor_Def*
+_eo_tokenizer_dflt_ctor_get(Eo_Tokenizer *toknz, char *p)
+{
+   Eo_DfltCtor_Def *ctor = calloc(1, sizeof(Eo_DfltCtor_Def));
+   if (ctor == NULL) ABORT(toknz, "calloc Eo_DfltCtor_Def failure");
+
+   ctor->name = _eo_tokenizer_token_get(toknz, p);
+
+   return ctor;
+}
+
+static Eo_DfltDtor_Def*
+_eo_tokenizer_dflt_dtor_get(Eo_Tokenizer *toknz, char *p)
+{
+   Eo_DfltDtor_Def *dtor = calloc(1, sizeof(Eo_DfltDtor_Def));
+   if (dtor == NULL) ABORT(toknz, "calloc Eo_DfltDtor_Def failure");
+
+   dtor->name = _eo_tokenizer_token_get(toknz, p);
+
+   return dtor;
+}
+
+static Eo_Implement_Def*
+_eo_tokenizer_implement_get(Eo_Tokenizer *toknz, char *p)
+{
+   Eo_Implement_Def *impl = calloc(1, sizeof(Eo_Implement_Def));
+   if (impl == NULL) ABORT(toknz, "calloc Eo_DfltDtor_Def failure");
+
+   impl->meth_name = _eo_tokenizer_token_get(toknz, p);
+
+   return impl;
+}
+
+%%{
+   machine common;
+
+   access toknz->;
+   variable p toknz->p;
+   variable pe toknz->pe;
+   variable eof toknz->eof;
+
+   action inc_line {
+      toknz->current_line += 1;
+      DBG("inc[%d] %d", toknz->cs, toknz->current_line);
+   }
+
+   action save_line {
+      toknz->saved.line = toknz->current_line;
+      DBG("save line[%d] %d", toknz->cs, toknz->current_line);
+   }
+
+   action save_fpc {
+      toknz->saved.tok = fpc;
+      DBG("save token[%d] %p %c", toknz->cs, fpc, *fpc);
+   }
+
+   action show_comment {
+      DBG("comment[%d] line%03d:%03d", toknz->cs,
+          toknz->saved.line, toknz->current_line);
+   }
+
+   action show_ignore {
+      DBG("ignore[%d] line:%d", toknz->cs, toknz->current_line);
+   }
+
+   action show_error {
+      DBG("error[%d]", toknz->cs);
+      char *s, *d;
+      char buf[BUFSIZE];
+      for (s = fpc, d = buf; (s <= toknz->pe); s++)
+        {
+           if ((*s == '\r') || (*s == '\n'))
+             break;
+           *d++ = *s;
+        }
+      *d = '\0';
+      ERR("error n:%d l:%d c:'%c': %s",
+          toknz->current_nesting, toknz->current_line, *fpc, buf);
+      toknz->cs = eo_tokenizer_error;
+      fbreak;  /* necessary to stop scanners */
+   }
+
+   cr                = '\n';
+   cr_neg            = [^\n];
+   ws                = [ \t\r];
+   newline           = cr @inc_line;
+   ignore            = (0x00..0x20 - cr) | newline;
+
+   alnum_u           = alnum | '_';
+   alpha_u           = alpha | '_';
+   ident             = alpha+ >save_fpc (alnum | '_' )+;
+   signal            = alpha+ >save_fpc (alnum | '_' | ',' )+;
+   class_meth        = alpha+ >save_fpc (alnum | '_' | '::' )+;
+
+   eo_comment        = "/*@" ignore* alnum_u >save_fpc ( any | cr @inc_line )* :>> "*/";
+   c_comment         = "/*" ( any | cr @inc_line )* :>> "*/";
+   cpp_comment       = "//" (any - cr )* newline;
+   comment           = ( c_comment | cpp_comment ) > save_line;
+
+   end_statement     = ';';
+   begin_def         = '{';
+   end_def           = '}' end_statement;
+   begin_list        = '(';
+   end_list          = ')';
+   list_separator    = ',';
+   colon             = ':';
+
+}%%
+
+%%{
+   machine eo_tokenizer;
+   include common;
+
+   write data;
+
+###### TOKENIZE ACCESSOR
+
+   action end_accessor_comment {
+      if (toknz->tmp.accessor->comment != NULL)
+        ABORT(toknz, "accessor has already a comment");
+      toknz->tmp.accessor->comment = _eo_tokenizer_token_get(toknz, fpc-1);
+      INF("        %s", toknz->tmp.accessor->comment);
+   }
+
+   action end_accessor_rettype {
+      if (toknz->tmp.accessor->ret.type != NULL)
+        ABORT(toknz, "accessor has already a return type");
+      toknz->tmp.accessor->ret.type = _eo_tokenizer_token_get(toknz, fpc);
+      INF("        %s", toknz->tmp.accessor->ret.type);
+   }
+
+   action end_accessor_rettype_comment {
+      if (toknz->tmp.accessor->ret.comment != NULL)
+        ABORT(toknz, "accessor return type has already a comment");
+      toknz->tmp.accessor->ret.comment = _eo_tokenizer_token_get(toknz, fpc-2);
+      INF("        %s", toknz->tmp.accessor->ret.comment);
+   }
+
+   action end_accessor_legacy {
+      toknz->tmp.accessor->legacy = _eo_tokenizer_token_get(toknz, fpc);
+   }
+
+   action end_accessor {
+      INF("      }");
+      toknz->tmp.prop->accessors = eina_list_append(toknz->tmp.prop->accessors, toknz->tmp.accessor);
+      toknz->tmp.accessor = NULL;
+      toknz->current_nesting--;
+      fgoto tokenize_property;
+   }
+
+   action begin_param_desc {
+      toknz->tmp.accessor_param = _eo_tokenizer_accessor_param_get(toknz, fpc);
+   }
+
+   action end_param_desc {
+      toknz->tmp.accessor_param->attrs = _eo_tokenizer_token_get(toknz, fpc);
+      toknz->tmp.accessor->params =
+         eina_list_append(toknz->tmp.accessor->params, toknz->tmp.accessor_param);
+      toknz->tmp.accessor_param = NULL;
+   }
+
+   rettype_comment = ws* eo_comment %end_accessor_rettype_comment;
+   rettype = 'return' ws+ alpha+ >save_fpc (alnum_u | '*' | ws )+  %end_accessor_rettype end_statement rettype_comment?;
+
+   legacy = 'legacy' ws+ ident %end_accessor_legacy end_statement;
+
+   param_desc = ident ws* colon %begin_param_desc ws* alpha+ >save_fpc (alnum_u | list_separator | ws)* %end_param_desc end_statement;
+
+   tokenize_accessor := |*
+      ignore+;    #=> show_ignore;
+      eo_comment  => end_accessor_comment;
+      comment     => show_comment;
+      rettype;
+      legacy;
+      param_desc;
+      end_def     => end_accessor;
+      any         => show_error;
+      *|;
+
+###### TOKENIZE PARAMS
+
+   action end_param_comment {
+      const char *c = _eo_tokenizer_token_get(toknz, fpc-2);
+      if (toknz->tmp.param == NULL)
+        ABORT(toknz, "no parameter set to associate this comment to: %s", c);
+      toknz->tmp.param->comment = c;
+      toknz->tmp.param = NULL;
+   }
+
+   action end_param {
+      toknz->tmp.param = _eo_tokenizer_param_get(toknz, fpc);
+      if (toknz->tmp.prop)
+        toknz->tmp.prop->params = eina_list_append(toknz->tmp.prop->params, toknz->tmp.param);
+      else if (toknz->tmp.meth)
+        toknz->tmp.meth->params = eina_list_append(toknz->tmp.meth->params, toknz->tmp.param);
+      else
+        ABORT(toknz, "got a param but there is no property nor method waiting for it");
+      INF("        %s : %s", toknz->tmp.param->name, toknz->tmp.param->type);
+   }
+
+   action end_params {
+      INF("      }");
+      toknz->tmp.param = NULL;
+      toknz->current_nesting--;
+      if (toknz->tmp.prop)
+        fgoto tokenize_property;
+      else if (toknz->tmp.meth)
+        fgoto tokenize_method;
+      else
+        ABORT(toknz, "leaving tokenize_params but there is no property nor method pending");
+   }
+
+   param_comment = ws* eo_comment %end_param_comment;
+   param = alpha+ >save_fpc (alnum_u | '*' | ws )+  %end_param end_statement param_comment?;
+
+   tokenize_params := |*
+      ignore+;    #=> show_ignore;
+      comment     => show_comment;
+      param;
+      end_def     => end_params;
+      any         => show_error;
+      *|;
+
+###### TOKENIZE PROPERTY
+
+   action begin_property_get {
+      INF("      get {");
+      toknz->tmp.accessor = _eo_tokenizer_accessor_get(toknz, GETTER);
+      toknz->current_nesting++;
+      fgoto tokenize_accessor;
+   }
+
+   action begin_property_set {
+      INF("      set {");
+      toknz->tmp.accessor = _eo_tokenizer_accessor_get(toknz, SETTER);
+      toknz->current_nesting++;
+      fgoto tokenize_accessor;
+   }
+
+   action begin_property_params {
+      INF("      params {");
+      toknz->current_nesting++;
+      fgoto tokenize_params;
+   }
+
+   action end_property {
+      if (eina_list_count(toknz->tmp.prop->params) == 0)
+        WRN("property '%s' has no parameters.", toknz->tmp.prop->name);
+      if (eina_list_count(toknz->tmp.prop->accessors) == 0)
+        WRN("property '%s' has no accessors.", toknz->tmp.prop->name);
+      INF("    }");
+      toknz->tmp.kls->properties = eina_list_append(toknz->tmp.kls->properties, toknz->tmp.prop);
+      toknz->tmp.prop = NULL;
+      toknz->current_nesting--;
+      fgoto tokenize_properties;
+   }
+
+   prop_get = 'get' ignore* begin_def;
+   prop_set = 'set' ignore* begin_def;
+   prop_params = 'params' ignore* begin_def;
+
+   tokenize_property := |*
+      ignore+;    #=> show_ignore;
+      comment     => show_comment;
+      prop_get    => begin_property_get;
+      prop_set    => begin_property_set;
+      prop_params => begin_property_params;
+      end_def     => end_property;
+      any         => show_error;
+      *|;
+
+###### TOKENIZE PROPERTIES
+
+   action begin_property {
+      INF("    %s {", toknz->tmp.prop->name);
+      toknz->current_nesting++;
+      fgoto tokenize_property;
+   }
+
+   action end_property_name {
+      if (toknz->tmp.prop != NULL)
+        ABORT(toknz, "there is a pending property definition %s", toknz->tmp.prop->name);
+      toknz->tmp.prop = _eo_tokenizer_property_get(toknz, fpc);
+   }
+
+   action end_properties {
+      INF("  }");
+      toknz->current_nesting--;
+      fgoto tokenize_class;
+   }
+
+   begin_property = ident %end_property_name ignore* begin_def;
+
+   tokenize_properties := |*
+      ignore+;       #=> show_ignore;
+      comment        => show_comment;
+      begin_property => begin_property;
+      end_def        => end_properties;
+      any            => show_error;
+      *|;
+
+###### TOKENIZE METHOD
+
+   action end_method_comment {
+      if (toknz->tmp.meth->comment != NULL)
+        ABORT(toknz, "method has already a comment");
+      toknz->tmp.meth->comment = _eo_tokenizer_token_get(toknz, fpc-1);
+      INF("        %s", toknz->tmp.meth->comment);
+   }
+
+   action begin_method_params {
+      INF("      params {");
+      toknz->current_nesting++;
+      fgoto tokenize_params;
+   }
+
+   action end_method_rettype {
+      if (toknz->tmp.meth->ret.type != NULL)
+        ABORT(toknz, "method '%s' has already a return type", toknz->tmp.meth->name);
+      toknz->tmp.meth->ret.type = _eo_tokenizer_token_get(toknz, fpc);
+      INF("        %s", toknz->tmp.meth->ret.type);
+   }
+
+   action end_method_rettype_comment {
+      if (toknz->tmp.meth->ret.comment != NULL)
+        ABORT(toknz, "method '%s' return type has already a comment", toknz->tmp.meth->name);
+      toknz->tmp.meth->ret.comment = _eo_tokenizer_token_get(toknz, fpc-2);
+      INF("        %s", toknz->tmp.meth->ret.comment);
+   }
+
+   action end_method_legacy {
+      toknz->tmp.meth->legacy = _eo_tokenizer_token_get(toknz, fpc);
+   }
+
+   action end_method_obj_const{
+      toknz->tmp.meth->obj_const = EINA_TRUE;
+      INF("        obj const");
+   }
+
+   action end_method {
+      Eina_List **l;
+      if (eina_list_count(toknz->tmp.meth->params) == 0)
+        WRN("method '%s' has no parameters.", toknz->tmp.meth->name);
+      INF("    }");
+      switch (toknz->current_methods_type) {
+        case METH_CONSTRUCTOR:
+          l = &toknz->tmp.kls->constructors;
+          break;
+        case METH_DESTRUCTOR:
+          l = &toknz->tmp.kls->destructors;
+          break;
+        case METH_REGULAR:
+          l = &toknz->tmp.kls->methods;
+          break;
+        default:
+          ABORT(toknz, "unknown method type %d", toknz->current_methods_type);
+      }
+      toknz->tmp.meth->type = toknz->current_methods_type;
+      *l = eina_list_append(*l, toknz->tmp.meth);
+      toknz->tmp.meth = NULL;
+      toknz->current_nesting--;
+      fgoto tokenize_methods;
+   }
+
+   meth_params = 'params' ignore* begin_def;
+   meth_legacy = 'legacy' ws+ ident %end_method_legacy end_statement;
+   meth_rettype_comment = ws* eo_comment %end_method_rettype_comment;
+   meth_rettype = 'return' ws+ alpha+ >save_fpc (alnum_u | '*' | ws )+  %end_method_rettype end_statement meth_rettype_comment?;
+   meth_obj_const = 'object' ws* colon ws* 'const' %end_method_obj_const end_statement;
+
+   tokenize_method := |*
+      ignore+;    #=> show_ignore;
+      eo_comment  => end_method_comment;
+      comment     => show_comment;
+      meth_params => begin_method_params;
+      meth_rettype;
+      meth_legacy;
+      meth_obj_const;
+      end_def     => end_method;
+      any         => show_error;
+      *|;
+
+###### TOKENIZE METHODS
+
+   action begin_method {
+      INF("    %s {", toknz->tmp.meth->name);
+      toknz->current_nesting++;
+      fgoto tokenize_method;
+   }
+
+   action end_method_name {
+      if (toknz->tmp.meth != NULL)
+        ABORT(toknz, "there is a pending method definition %s", toknz->tmp.meth->name);
+      toknz->tmp.meth = _eo_tokenizer_method_get(toknz, fpc);
+   }
+
+   action end_methods {
+      INF("  }");
+      toknz->current_methods_type = METH_TYPE_LAST;
+      toknz->current_nesting--;
+      fgoto tokenize_class;
+   }
+
+   begin_method = ident %end_method_name ignore* begin_def;
+
+   tokenize_methods := |*
+      ignore+;       #=> show_ignore;
+      comment        => show_comment;
+      begin_method   => begin_method;
+      end_def        => end_methods;
+      any            => show_error;
+      *|;
+
+###### TOKENIZE CLASS
+
+   action end_class_comment {
+      if (toknz->tmp.kls->comment != NULL)
+        ABORT(toknz, "class %s has already a comment", toknz->tmp.kls->name);
+      toknz->tmp.kls->comment = _eo_tokenizer_token_get(toknz, fpc-1);
+   }
+
+   action end_str_item{
+      const char *base = _eo_tokenizer_token_get(toknz, fpc);
+      toknz->tmp.str_items = eina_list_append(toknz->tmp.str_items, base);
+   }
+
+   action end_inherits {
+      toknz->tmp.kls->inherits = toknz->tmp.str_items;
+      toknz->tmp.str_items = NULL;
+   }
+
+   action end_implements {
+   }
+
+   action end_signals {
+   }
+
+   action begin_constructors {
+      INF("  constructors {");
+      toknz->current_methods_type = METH_CONSTRUCTOR;
+      toknz->current_nesting++;
+      fgoto tokenize_methods;
+   }
+
+   action begin_destructors {
+      INF("  destructors {");
+      toknz->current_methods_type = METH_DESTRUCTOR;
+      toknz->current_nesting++;
+      fgoto tokenize_methods;
+   }
+
+   action begin_properties {
+      INF("  properties {");
+      toknz->current_nesting++;
+      fgoto tokenize_properties;
+   }
+
+   action begin_methods {
+      INF("  begin methods");
+      toknz->current_methods_type = METH_REGULAR;
+      toknz->current_nesting++;
+      fgoto tokenize_methods;
+   }
+
+   action end_class {
+      INF("end class: %s", toknz->tmp.kls->name);
+      toknz->classes = eina_list_append(toknz->classes, toknz->tmp.kls);
+      toknz->tmp.kls = NULL;
+      toknz->current_nesting--;
+      fgoto main;
+   }
+
+   action end_signal_name {
+      toknz->tmp.signal = _eo_tokenizer_signal_get(toknz, fpc);
+      toknz->tmp.kls->signals = eina_list_append(toknz->tmp.kls->signals, toknz->tmp.signal);
+   }
+
+   action end_signal_comment {
+      if (toknz->tmp.signal->comment != NULL)
+        ABORT(toknz, "signal %s has already a comment", toknz->tmp.signal->name);
+      toknz->tmp.signal->comment = _eo_tokenizer_token_get(toknz, fpc-2);
+      toknz->tmp.signal = NULL;
+   }
+
+   action end_dflt_ctor_def {
+      if (toknz->tmp.kls->dflt_ctor != NULL)
+        ABORT(toknz, "A default constructor has already been defined");
+      toknz->tmp.kls->dflt_ctor = _eo_tokenizer_dflt_ctor_get(toknz, fpc);
+   }
+
+   action end_legacy_prefix {
+      if (toknz->tmp.kls->legacy_prefix != NULL)
+        ABORT(toknz, "A legacy prefix has already been given");
+      toknz->tmp.kls->legacy_prefix = _eo_tokenizer_token_get(toknz, fpc);
+   }
+
+   action end_dflt_dtor_def {
+      if (toknz->tmp.kls->dflt_dtor != NULL)
+        ABORT(toknz, "A default destructor has already been defined");
+      toknz->tmp.kls->dflt_dtor = _eo_tokenizer_dflt_dtor_get(toknz, fpc);
+   }
+
+   action end_dflt_ctor_comment {
+      if (toknz->tmp.kls->dflt_ctor == NULL)
+        ABORT(toknz, "No default constructor is defined for the comment");
+      if (toknz->tmp.kls->dflt_ctor->comment != NULL)
+        ABORT(toknz, "default constructor %s has already a comment", toknz->tmp.kls->dflt_ctor->name);
+      toknz->tmp.kls->dflt_ctor->comment = _eo_tokenizer_token_get(toknz, fpc-2);
+   }
+
+   action end_dflt_dtor_comment {
+      if (toknz->tmp.kls->dflt_dtor == NULL)
+        ABORT(toknz, "No default destructor is defined for the comment");
+      if (toknz->tmp.kls->dflt_dtor->comment != NULL)
+        ABORT(toknz, "default destructor %s has already a comment", toknz->tmp.kls->dflt_dtor->name);
+      toknz->tmp.kls->dflt_dtor->comment = _eo_tokenizer_token_get(toknz, fpc-2);
+   }
+
+   legacy_prefix = 'legacy_prefix' ignore* colon ignore* ident %end_legacy_prefix end_statement ignore*;
+
+   class_it = ident %end_str_item ignore*;
+   class_it_next = list_separator ignore* class_it;
+   inherits = 'inherits' ignore* begin_def ignore* (class_it class_it_next*)? end_def;
+
+   action impl_meth_store {
+        toknz->tmp.impl = _eo_tokenizer_implement_get(toknz, fpc);
+        toknz->tmp.kls->implements = eina_list_append(toknz->tmp.kls->implements, toknz->tmp.impl);
+   }
+
+   action impl_legacy_create {
+        if (toknz->tmp.impl->legacy)
+           ABORT(toknz, "Legacy section already allocated for implement item");
+        toknz->tmp.impl->legacy = calloc(1, sizeof(Eo_Implement_Legacy_Def));
+   }
+
+   action impl_legacy_function_name_store {
+        if (!toknz->tmp.impl->legacy)
+           ABORT(toknz, "No legacy section");
+        toknz->tmp.impl->legacy->function_name = _eo_tokenizer_token_get(toknz, fpc);
+   }
+
+   action impl_legacy_eo_param_store {
+        toknz->tmp.impl_leg_param = calloc(1, sizeof(Eo_Implement_Legacy_Param_Def));
+        toknz->tmp.impl->legacy->params = eina_list_append(
+              toknz->tmp.impl->legacy->params, toknz->tmp.impl_leg_param);
+
+        toknz->tmp.impl_leg_param->eo_name = _eo_tokenizer_token_get(toknz, fpc);
+   }
+
+   action impl_legacy_leg_param_store {
+        toknz->tmp.impl_leg_param->legacy_name = _eo_tokenizer_token_get(toknz, fpc);
+   }
+
+   action impl_legacy_param_comment_store {
+        toknz->tmp.impl_leg_param->comment = _eo_tokenizer_token_get(toknz, fpc-2);
+   }
+
+   action impl_legacy_return_type_store {
+        if (!toknz->tmp.impl->legacy)
+           ABORT(toknz, "No legacy section");
+        toknz->tmp.impl->legacy->ret_type= _eo_tokenizer_token_get(toknz, fpc);
+   }
+
+   action impl_legacy_return_val_store {
+        if (!toknz->tmp.impl->legacy)
+           ABORT(toknz, "No legacy section");
+        toknz->tmp.impl->legacy->ret_value = _eo_tokenizer_token_get(toknz, fpc);
+   }
+
+#  legacy legacy_function_name
+#    {
+#       params {
+#         grp: NULL; /*@ in case 'grp' is in Eo but not in legacy, have to give default */
+#         file; /*@ in case the 'file' parameter is the same */
+#         :index; /*@ in case the param is in legacy but not in Eo */
+#       };
+#       return Eina_Bool::EINA_TRUE;
+#    };
+
+   impl_legacy_param_comment = ws* eo_comment %impl_legacy_param_comment_store;
+   impl_legacy_eo_param = ident %impl_legacy_eo_param_store;
+   impl_legacy_leg_param = ws* colon ws* ident %impl_legacy_leg_param_store ignore*;
+   impl_legacy_param = impl_legacy_eo_param? ws* impl_legacy_leg_param? end_statement impl_legacy_param_comment? ignore*;
+   impl_legacy_params = impl_legacy_param+;
+
+   impl_legacy_return = 'return' ws+ ident %impl_legacy_return_type_store '::' ident %impl_legacy_return_val_store end_statement ignore*;
+
+   impl_legacy_body = 'params' ignore* begin_def ignore* impl_legacy_params ignore* end_def ignore* impl_legacy_return? ignore*;
+
+   impl_legacy_function_name = ident %impl_legacy_function_name_store;
+   impl_legacy_token = 'legacy' %impl_legacy_create;
+   impl_body = impl_legacy_token ws* impl_legacy_function_name? ignore* (end_statement | (begin_def ignore* impl_legacy_body ignore* end_def)) ignore*;
+# class::func ; or { ... }
+   impl_it = class_meth %impl_meth_store ignore* (end_statement | (begin_def ignore* impl_body ignore* end_def)) ignore*;
+# implements { ... }
+   implements = 'implements' ignore* begin_def ignore* impl_it* end_def;
+
+   signal_comment = ws* eo_comment %end_signal_comment;
+   signal_it = signal %end_signal_name ignore* end_statement signal_comment? ignore*;
+   signals = 'signals' ignore* begin_def ignore* signal_it* end_def;
+
+   dflt_ctor_comment = ws* eo_comment %end_dflt_ctor_comment;
+   dflt_ctor = 'constructor' >save_fpc %end_dflt_ctor_def ignore* end_statement dflt_ctor_comment? ignore*;
+
+   dflt_dtor_comment = ws* eo_comment %end_dflt_dtor_comment;
+   dflt_dtor = 'destructor' >save_fpc %end_dflt_dtor_def ignore* end_statement dflt_dtor_comment? ignore*;
+
+   constructors = 'constructors' ignore* begin_def;
+   destructors = 'destructors' ignore* begin_def;
+   properties = 'properties' ignore* begin_def;
+   methods = 'methods' ignore* begin_def;
+
+   tokenize_class := |*
+      ignore+;       #=> show_ignore;
+      eo_comment     => end_class_comment;
+      comment        => show_comment;
+      legacy_prefix;
+      inherits       => end_inherits;
+      implements     => end_implements;
+      signals        => end_signals;
+      dflt_ctor;
+      dflt_dtor;
+      constructors   => begin_constructors;
+      destructors    => begin_destructors;
+      properties     => begin_properties;
+      methods        => begin_methods;
+      end_def        => end_class;
+      any            => show_error;
+      *|;
+
+###### TOP LEVEL
+
+   action begin_class {
+      INF("begin class: %s", toknz->tmp.kls->name);
+      toknz->current_nesting++;
+      fgoto tokenize_class;
+   }
+
+   action end_class_name {
+      if (toknz->tmp.kls != NULL)
+        ABORT(toknz, "there is a pending class definition %s", toknz->tmp.kls->name);
+      toknz->tmp.kls = _eo_tokenizer_class_get(toknz, fpc);
+   }
+
+   action end_class_type {
+      if (!toknz->tmp.kls)
+         ABORT(toknz, "No pending class definition");
+      toknz->tmp.kls->type = _eo_tokenizer_token_get(toknz, fpc);
+   }
+
+   class_name = ident %end_class_name;
+   class_type = ws+ "as" ws+ >save_fpc ("Regular" | "Mixin" | "RegularNonInstantiable" | "Interface") %end_class_type; # class as type(Regular, Mixin...)
+   begin_class = class_name class_type? ignore* begin_def;
+
+   main := |*
+      ignore+;    #=> show_ignore;
+      comment     => show_comment;
+      begin_class => begin_class;
+      any         => show_error;
+   *|;
+
+}%%
+
+Eina_Bool
+eo_tokenizer_walk(Eo_Tokenizer *toknz, const char *source)
+{
+   INF("tokenize %s...", source);
+   toknz->source = eina_stringshare_add(source);
+
+   FILE *stream;
+
+   int done = 0;
+   int have = 0;
+   int offset = 0;
+
+   stream = fopen(toknz->source, "rb");
+   if (!stream)
+     {
+        ERR("unable to read in %s", toknz->source);
+        return EINA_FALSE;
+     }
+
+   %% write init;
+
+   while (!done)
+     {
+        int len;
+        int space;
+
+        toknz->p = toknz->buf + have;
+        space = BUFSIZE - have;
+
+        if (space == 0)
+          {
+             fclose(stream);
+             ABORT(toknz, "out of buffer space");
+          }
+
+        len = fread(toknz->p, 1, space, stream);
+        if (len == 0) break;
+        toknz->pe = toknz->p + len;
+
+        if (len < space)
+          {
+             toknz->eof = toknz->pe;
+             done = 1;
+          }
+
+        %% write exec;
+
+        if ( toknz->cs == %%{ write error; }%% )
+          {
+             ERR("wrong termination");
+             break;
+          }
+
+        if ( toknz->ts == 0 )
+          have = 0;
+        else
+          {
+             DBG("move data and pointers before buffer feed");
+             have = toknz->pe - toknz->ts;
+             offset = toknz->ts - toknz->buf;
+             memmove(toknz->buf, toknz->ts, have);
+             toknz->te -= offset;
+             toknz->ts = toknz->buf;
+          }
+
+        if (toknz->saved.tok != NULL)
+          {
+             if ((have == 0) || ((toknz->saved.tok - offset) < toknz->buf))
+               {
+                  WRN("reset lost saved token %p", toknz->saved.tok);
+                  toknz->saved.tok = NULL;
+               }
+             else
+               toknz->saved.tok -= offset;
+          }
+     }
+
+   fclose(stream);
+
+   return EINA_TRUE;
+}
+
+Eo_Tokenizer*
+eo_tokenizer_get(void)
+{
+   Eo_Tokenizer *toknz = calloc(1, sizeof(Eo_Tokenizer));
+   if (!toknz) return NULL;
+
+   toknz->ts = NULL;
+   toknz->te = NULL;
+   /* toknz->top = 0; */
+   toknz->source = NULL;
+   toknz->max_nesting = 10;
+   toknz->current_line = 1;
+   toknz->current_nesting = 0;
+   toknz->current_methods_type = METH_TYPE_LAST;
+   toknz->saved.tok = NULL;
+   toknz->saved.line = 0;
+   toknz->classes = NULL;
+
+   return toknz;
+}
+
+static char *_accessor_type_str[ACCESSOR_TYPE_LAST] = { "setter", "getter" };
+static char *_param_way_str[PARAM_WAY_LAST] = { "IN", "OUT", "INOUT" };
+
+void
+eo_tokenizer_dump(Eo_Tokenizer *toknz)
+{
+   const char *s;
+   Eina_List *k, *l, *m;
+
+   Eo_Class_Def *kls;
+   Eo_Property_Def *prop;
+   Eo_Method_Def *meth;
+   Eo_Param_Def *param;
+   Eo_Accessor_Def *accessor;
+   Eo_Signal_Def *sgn;
+   /* Eo_Ret_Def *ret; */
+
+   EINA_LIST_FOREACH(toknz->classes, k, kls)
+     {
+        printf("Class: %s (%s)\n",
+               kls->name, (kls->comment ? kls->comment : "-"));
+        printf("  inherits from :");
+        EINA_LIST_FOREACH(kls->inherits, l, s)
+           printf(" %s", s);
+        printf("\n");
+        printf("  implements:");
+        EINA_LIST_FOREACH(kls->implements, l, s)
+           printf(" %s", s);
+        printf("\n");
+        printf("  signals:\n");
+        EINA_LIST_FOREACH(kls->signals, l, sgn)
+           printf("    %s (%s)\n", sgn->name, sgn->comment);
+
+        EINA_LIST_FOREACH(kls->constructors, l, meth)
+          {
+             printf("  constructors: %s\n", meth->name);
+             printf("    return: %s (%s)\n", meth->ret.type, meth->ret.comment);
+             printf("    legacy : %s\n", meth->legacy);
+             EINA_LIST_FOREACH(meth->params, m, param)
+               {
+                  printf("    param: %s %s : %s (%s)\n",
+                         _param_way_str[param->way], param->name,
+                         param->type, param->comment);
+               }
+          }
+
+        EINA_LIST_FOREACH(kls->destructors, l, meth)
+          {
+             printf("  destructors: %s\n", meth->name);
+             printf("    return: %s (%s)\n", meth->ret.type, meth->ret.comment);
+             printf("    legacy : %s\n", meth->legacy);
+             EINA_LIST_FOREACH(meth->params, m, param)
+               {
+                  printf("    param: %s %s : %s (%s)\n",
+                         _param_way_str[param->way], param->name,
+                         param->type, param->comment);
+               }
+          }
+
+        EINA_LIST_FOREACH(kls->properties, l, prop)
+          {
+             printf("  property: %s\n", prop->name);
+             EINA_LIST_FOREACH(prop->params, m, param)
+               {
+                  printf("    param: %s : %s (%s)\n",
+                         param->name, param->type, param->comment);
+               }
+             EINA_LIST_FOREACH(prop->accessors, m, accessor)
+               {
+                  printf("    accessor: %s : %s (%s)\n",
+                         accessor->ret.type, _accessor_type_str[accessor->type],
+                         accessor->comment);
+                  printf("      legacy : %s\n", accessor->legacy);
+               }
+          }
+
+        EINA_LIST_FOREACH(kls->methods, l, meth)
+          {
+             printf("  method: %s\n", meth->name);
+             printf("    return: %s (%s)\n", meth->ret.type, meth->ret.comment);
+             printf("    legacy : %s\n", meth->legacy);
+             printf("    obj_const : %s\n", meth->obj_const?"true":"false");
+             EINA_LIST_FOREACH(meth->params, m, param)
+               {
+                  printf("    param: %s %s : %s (%s)\n",
+                         _param_way_str[param->way], param->name,
+                         param->type, param->comment);
+               }
+          }
+
+     }
+
+}
+
+Eina_Bool
+eo_tokenizer_database_fill(const char *filename)
+{
+   const char *s;
+   Eina_List *k, *l, *m;
+
+   Eo_Class_Def *kls;
+   Eo_Property_Def *prop;
+   Eo_Method_Def *meth;
+   Eo_Param_Def *param;
+   Eo_Accessor_Def *accessor;
+   Eo_Signal_Def *signal;
+   Eo_Implement_Def *impl;
+   /* Eo_Ret_Def *ret; */
+
+   Eo_Tokenizer *toknz = eo_tokenizer_get();
+   if (!toknz)
+     {
+        ERR("can't create eo_tokenizer");
+        return EINA_FALSE;
+     }
+
+   if (access(filename, F_OK) != 0)
+     {
+        ERR("error accessing file %s : %s", filename, strerror(errno));
+        return EINA_FALSE;
+     }
+   eo_tokenizer_walk(toknz, filename);
+
+   EINA_LIST_FOREACH(toknz->classes, k, kls)
+     {
+        Eolian_Class_Type type = EOLIAN_CLASS_REGULAR;
+        if (kls->type)
+          {
+             if (!strcmp(kls->type, "Regular")) type = EOLIAN_CLASS_REGULAR;
+             else if (!strcmp(kls->type, "RegularNonInstantiable")) type = EOLIAN_CLASS_REGULAR_NON_INSTANT;
+             else if (!strcmp(kls->type, "Mixin")) type = EOLIAN_CLASS_MIXIN;
+             else if (!strcmp(kls->type, "Interface")) type = EOLIAN_CLASS_INTERFACE;
+             else type = EOLIAN_CLASS_UNKNOWN_TYPE;
+          }
+        database_class_add(kls->name, type);
+        if (kls->comment) database_class_description_set(kls->name, kls->comment);
+
+        EINA_LIST_FOREACH(kls->inherits, l, s)
+           database_class_inherit_add(kls->name, s);
+
+        if (kls->legacy_prefix)
+          {
+             database_class_legacy_prefix_set(kls->name, kls->legacy_prefix);
+          }
+        if (kls->dflt_ctor)
+          {
+             Eolian_Function foo_id = database_function_new(kls->dflt_ctor->name, DFLT_CONSTRUCTOR);
+             database_class_function_add(kls->name, foo_id);
+             database_function_description_set(foo_id, EOLIAN_COMMENT, kls->dflt_ctor->comment);
+          }
+        if (kls->dflt_dtor)
+          {
+             Eolian_Function foo_id = database_function_new(kls->dflt_dtor->name, DFLT_DESTRUCTOR);
+             database_class_function_add(kls->name, foo_id);
+             database_function_description_set(foo_id, EOLIAN_COMMENT, kls->dflt_dtor->comment);
+          }
+        EINA_LIST_FOREACH(kls->constructors, l, meth)
+          {
+             Eolian_Function foo_id = database_function_new(meth->name, CONSTRUCTOR);
+             database_class_function_add(kls->name, foo_id);
+             database_function_description_set(foo_id, EOLIAN_RETURN_COMMENT, meth->ret.comment);
+             database_function_data_set(foo_id, EOLIAN_LEGACY, meth->legacy);
+             EINA_LIST_FOREACH(meth->params, m, param)
+               {
+                  database_function_parameter_add(foo_id, (Eolian_Parameter_Dir)param->way, param->type, param->name, param->comment);
+               }
+          }
+
+        EINA_LIST_FOREACH(kls->destructors, l, meth)
+          {
+             Eolian_Function foo_id = database_function_new(meth->name, DESTRUCTOR);
+             database_class_function_add(kls->name, foo_id);
+             database_function_description_set(foo_id, EOLIAN_RETURN_COMMENT, meth->ret.comment);
+             database_function_data_set(foo_id, EOLIAN_LEGACY, meth->legacy);
+             EINA_LIST_FOREACH(meth->params, m, param)
+               {
+                  database_function_parameter_add(foo_id, (Eolian_Parameter_Dir)param->way, param->type, param->name, param->comment);
+               }
+          }
+
+        EINA_LIST_FOREACH(kls->properties, l, prop)
+          {
+             Eolian_Function foo_id = database_function_new(prop->name, UNRESOLVED);
+             EINA_LIST_FOREACH(prop->params, m, param)
+               {
+                  /* IN_PARAM doesn't care */
+                  database_function_parameter_add(foo_id, EOLIAN_IN_PARAM, param->type, param->name, param->comment);
+               }
+             EINA_LIST_FOREACH(prop->accessors, m, accessor)
+               {
+                  database_function_type_set(foo_id, (accessor->type == SETTER?SET:GET));
+                  if (accessor->ret.type)
+                     database_function_data_set(foo_id,
+                           (accessor->type == SETTER?EOLIAN_PROP_SET_RETURN_TYPE:EOLIAN_PROP_GET_RETURN_TYPE),
+                           accessor->ret.type);
+                  database_function_description_set(foo_id,
+                        (accessor->type == SETTER?EOLIAN_COMMENT_SET:EOLIAN_COMMENT_GET),
+                        accessor->comment);
+                  Eo_Accessor_Param *acc_param;
+                  Eina_List *m2;
+                  /* Only in get access, we check const attribute */
+                  if (accessor->type == GETTER)
+                    {
+                       EINA_LIST_FOREACH(accessor->params, m2, acc_param)
+                         {
+                            Eolian_Function_Parameter desc = eolian_function_parameter_get(foo_id, acc_param->name);
+                            if (!desc)
+                              {
+                                 printf("Error - %s not known as parameter of property %s\n", acc_param->name, prop->name);
+                                 return EINA_FALSE;
+                              }
+                            if (strstr(acc_param->attrs, "const"))
+                              {
+                                 database_parameter_get_const_attribute_set(desc, EINA_TRUE);
+                              }
+                         }
+                    }
+               }
+             database_class_function_add(kls->name, foo_id);
+          }
+
+        EINA_LIST_FOREACH(kls->methods, l, meth)
+          {
+             Eolian_Function foo_id = database_function_new(meth->name, METHOD_FUNC);
+             database_class_function_add(kls->name, foo_id);
+             database_function_data_set(foo_id, EOLIAN_METHOD_RETURN_TYPE, meth->ret.type);
+             database_function_description_set(foo_id, EOLIAN_RETURN_COMMENT, meth->ret.comment);
+             database_function_description_set(foo_id, EOLIAN_COMMENT, meth->comment);
+             database_function_data_set(foo_id, EOLIAN_LEGACY, meth->legacy);
+             database_function_object_set_as_const(foo_id, meth->obj_const);
+             EINA_LIST_FOREACH(meth->params, m, param)
+               {
+                  database_function_parameter_add(foo_id, (Eolian_Parameter_Dir)param->way, param->type, param->name, param->comment);
+               }
+          }
+
+        EINA_LIST_FOREACH(kls->implements, l, impl)
+          {
+             const char *class = impl->meth_name;
+             char *func = strstr(class, "::");
+             if (func) *func = '\0';
+             func += 2;
+             Eolian_Function_Type ftype = UNRESOLVED;
+             char *type_as_str = strstr(func, "::");
+             if (type_as_str)
+               {
+                  *type_as_str = '\0';
+                  if (!strcmp(type_as_str+2, "set")) ftype = SET;
+                  else if (!strcmp(type_as_str+2, "get")) ftype = GET;
+               }
+             Eolian_Implement impl_desc = database_implement_new(class, func, ftype);
+             if (impl->legacy)
+               {
+                  Eo_Implement_Legacy_Def *eo_leg = impl->legacy;
+                  Eolian_Implement_Legacy leg = database_implement_legacy_add(
+                        impl_desc, eo_leg->function_name);
+                  database_implement_legacy_return_add(leg, eo_leg->ret_type, eo_leg->ret_value);
+                  if (eo_leg->params)
+                    {
+                       Eina_List *itr;
+                       Eo_Implement_Legacy_Param_Def *p;
+                       EINA_LIST_FOREACH(eo_leg->params, itr, p)
+                          database_implement_legacy_param_add(leg, p->eo_name,
+                                p->legacy_name, p->comment);
+                    }
+               }
+             database_class_implement_add(kls->name, impl_desc);
+          }
+
+        EINA_LIST_FOREACH(kls->signals, l, signal)
+          {
+             Eolian_Event ev = database_event_new(signal->name, signal->comment);
+             database_class_event_add(kls->name, ev);
+          }
+
+     }
+
+   eo_tokenizer_free(toknz);
+   return EINA_TRUE;
+}
+
+void
+eo_tokenizer_free(Eo_Tokenizer *toknz)
+{
+   Eo_Class_Def *kls;
+
+   if (toknz->source)
+     eina_stringshare_del(toknz->source);
+
+   EINA_LIST_FREE(toknz->classes, kls)
+      eo_definitions_class_def_free(kls);
+
+   free(toknz);
+}
+
diff --git a/src/lib/eolian/eolian.c b/src/lib/eolian/eolian.c
new file mode 100644 (file)
index 0000000..4613152
--- /dev/null
@@ -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);
+}
+
diff --git a/src/lib/eolian/eolian_database.c b/src/lib/eolian/eolian_database.c
new file mode 100644 (file)
index 0000000..e8c4010
--- /dev/null
@@ -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;
+}
diff --git a/src/lib/eolian/eolian_database.h b/src/lib/eolian/eolian_database.h
new file mode 100644 (file)
index 0000000..f509044
--- /dev/null
@@ -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