diff --git a/pc/eolian.pc.in b/pc/eolian.pc.in new file mode 100644 index 0000000000..093bab580e --- /dev/null +++ b/pc/eolian.pc.in @@ -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 index 0000000000..dbd2c329a3 --- /dev/null +++ b/src/bin/eolian/common_funcs.c @@ -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 index 0000000000..d0c67e0bd7 --- /dev/null +++ b/src/bin/eolian/common_funcs.h @@ -0,0 +1,8 @@ +#ifndef __EOLIAN_COMMON_FUNCS_H +#define __EOLIAN_COMMON_FUNCS_H + +#include + +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 index 0000000000..c67576c754 --- /dev/null +++ b/src/bin/eolian/eo1_generator.c @@ -0,0 +1,667 @@ +#include +#include + +#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 index 0000000000..7a0309505b --- /dev/null +++ b/src/bin/eolian/eo1_generator.h @@ -0,0 +1,141 @@ +#ifndef EO1_GENERATOR_H +#define EO1_GENERATOR_H + +#include +#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 index 0000000000..207772859b --- /dev/null +++ b/src/bin/eolian/legacy_generator.c @@ -0,0 +1,452 @@ +#include +#include + +#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 index 0000000000..5f22afa811 --- /dev/null +++ b/src/bin/eolian/legacy_generator.h @@ -0,0 +1,53 @@ +#ifndef __EOLIAN_LEGACY_GENERATOR_H +#define __EOLIAN_LEGACY_GENERATOR_H + +#include + +/* + * @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 index 0000000000..c47376de6e --- /dev/null +++ b/src/bin/eolian/main.c @@ -0,0 +1,334 @@ +#include +#include + +#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 index 0000000000..60a9a2edbe --- /dev/null +++ b/src/lib/eolian/Eolian.h @@ -0,0 +1,417 @@ +#ifndef EOLIAN_H +#define EOLIAN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* 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 index 0000000000..12d8df4b86 --- /dev/null +++ b/src/lib/eolian/eo_definitions.c @@ -0,0 +1,162 @@ +#include +#include + +#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 index 0000000000..23e9ed453e --- /dev/null +++ b/src/lib/eolian/eo_definitions.h @@ -0,0 +1,169 @@ +#ifndef __EO_DEFINITIONS_H__ +#define __EO_DEFINITIONS_H__ + +#include + +/* 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 index 0000000000..97c4eb66eb --- /dev/null +++ b/src/lib/eolian/eo_lexer.c @@ -0,0 +1,2891 @@ + +#line 1 "/home/daniel/e17/eolian/src/lib/eo_lexer.rl" +#include +#include +#include +#include + +#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 index 0000000000..1932621880 --- /dev/null +++ b/src/lib/eolian/eo_lexer.h @@ -0,0 +1,65 @@ +#ifndef __EO_TOKENIZER_H__ +#define __EO_TOKENIZER_H__ + +#include +#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 index 0000000000..01554f8ba1 --- /dev/null +++ b/src/lib/eolian/eo_lexer.rl @@ -0,0 +1,1317 @@ +#include +#include +#include +#include + +#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 index 0000000000..4613152aa8 --- /dev/null +++ b/src/lib/eolian/eolian.c @@ -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 index 0000000000..e8c4010e53 --- /dev/null +++ b/src/lib/eolian/eolian_database.c @@ -0,0 +1,955 @@ +#include +#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, ¶ms, &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: \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 index 0000000000..f509044388 --- /dev/null +++ b/src/lib/eolian/eolian_database.h @@ -0,0 +1,78 @@ +#ifndef __EOLIAN_DATABASE_H +#define __EOLIAN_DATABASE_H + +#include + +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