diff --git a/src/Makefile_Eolian.am b/src/Makefile_Eolian.am index dac5638389..340aa01211 100644 --- a/src/Makefile_Eolian.am +++ b/src/Makefile_Eolian.am @@ -48,19 +48,16 @@ bin_PROGRAMS += \ bin/eolian/eolian_gen bin_eolian_eolian_gen_SOURCES = \ - bin/eolian/common_funcs.c \ - bin/eolian/common_funcs.h \ - bin/eolian/eo_generator.c \ - bin/eolian/eo_generator.h \ - bin/eolian/impl_generator.c \ - bin/eolian/impl_generator.h \ - bin/eolian/legacy_generator.c \ - bin/eolian/legacy_generator.h \ - bin/eolian/types_generator.c \ - bin/eolian/types_generator.h \ - bin/eolian/docs_generator.c \ - bin/eolian/docs_generator.h \ - bin/eolian/main.c + bin/eolian/main.c \ + bin/eolian/main.h \ + bin/eolian/types.c \ + bin/eolian/types.h \ + bin/eolian/headers.c \ + bin/eolian/headers.h \ + bin/eolian/sources.c \ + bin/eolian/sources.h \ + bin/eolian/docs.c \ + bin/eolian/docs.h bin_eolian_eolian_gen_CPPFLAGS = -I$(top_builddir)/src/lib/efl @EOLIAN_CFLAGS@ bin_eolian_eolian_gen_LDADD = @USE_EOLIAN_LIBS@ diff --git a/src/Makefile_Eolian_Files_Helper.am b/src/Makefile_Eolian_Files_Helper.am index 1260d718c5..bf14567554 100644 --- a/src/Makefile_Eolian_Files_Helper.am +++ b/src/Makefile_Eolian_Files_Helper.am @@ -8,19 +8,19 @@ SUFFIXES = .eo .eo.c .eo.h .eo.legacy.h .eot .eot.h %.eo.c: %.eo ${_EOLIAN_GEN_DEP} $(AM_V_EOL) \ $(MKDIR_P) $(dir $@); \ - $(EOLIAN_GEN) --legacy $(EOLIAN_FLAGS) --gc -o $@ $< + $(EOLIAN_GEN) $(EOLIAN_FLAGS) -gc -o c:$@ $< %.eo.h: %.eo ${_EOLIAN_GEN_DEP} $(AM_V_EOL) \ $(MKDIR_P) $(dir $@); \ - $(EOLIAN_GEN) $(EOLIAN_FLAGS) --gh -o $@ $< + $(EOLIAN_GEN) $(EOLIAN_FLAGS) -gh -o h:$@ $< %.eot.h: %.eot ${_EOLIAN_GEN_DEP} $(AM_V_EOL) \ $(MKDIR_P) $(dir $@); \ - $(EOLIAN_GEN) $(EOLIAN_FLAGS) --gh -o $@ $< + $(EOLIAN_GEN) $(EOLIAN_FLAGS) -gh -o h:$@ $< %.eo.legacy.h: %.eo ${_EOLIAN_GEN_DEP} $(AM_V_EOL) \ $(MKDIR_P) $(dir $@); \ - $(EOLIAN_GEN) --legacy $(EOLIAN_FLAGS) --gh -o $@ $< + $(EOLIAN_GEN) $(EOLIAN_FLAGS) -gl -o l:$@ $< diff --git a/src/bin/eolian/common_funcs.c b/src/bin/eolian/common_funcs.c deleted file mode 100644 index 87aae20c80..0000000000 --- a/src/bin/eolian/common_funcs.c +++ /dev/null @@ -1,141 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "common_funcs.h" -#include "Eolian.h" - -int _eolian_gen_log_dom = -1; - -Eolian_Class *current_class; - -static void -_class_name_concatenate(const Eolian_Class *class, char *buffer) -{ - Eina_Iterator *itr = eolian_class_namespaces_get(class); - const char *name; - buffer[0] = '\0'; - EINA_ITERATOR_FOREACH(itr, name) - { - sprintf(buffer, "%s_", name); - buffer += (strlen(name) + 1); - } - sprintf(buffer, "%s", eolian_class_name_get(class)); - eina_iterator_free(itr); -} - -static char * -_fill_envs(char *dest, const char *src, size_t bufs) { - strncpy(dest, src, bufs - 1); - dest[bufs - 1] = '\0'; - return dest; -} - -void -_class_env_create(const Eolian_Class *class, const char *over_classname, _eolian_class_vars *env) -{ - if (!env) return; - - const char *eo_prefix = NULL; - char *p; - - if (!class) - _fill_envs(env->full_classname, over_classname, sizeof(env->full_classname)); - else - _class_name_concatenate(class, env->full_classname); - - /* class/CLASS*/ - p = _fill_envs(env->upper_classname, env->full_classname, sizeof(env->upper_classname)); - eina_str_toupper(&p); - p = _fill_envs(env->lower_classname, env->full_classname, sizeof(env->lower_classname)); - eina_str_tolower(&p); - - /* eo_prefix */ - if (class) eo_prefix = eolian_class_eo_prefix_get(class); - if (!eo_prefix) eo_prefix = env->full_classname; - p = _fill_envs(env->upper_eo_prefix, eo_prefix, sizeof(env->upper_eo_prefix)); - eina_str_toupper(&p); - p = _fill_envs(env->lower_eo_prefix, eo_prefix, sizeof(env->lower_eo_prefix)); - eina_str_tolower(&p); - - /* classtype */ - if (class) switch (eolian_class_type_get(class)) - { - case EOLIAN_CLASS_REGULAR: - case EOLIAN_CLASS_ABSTRACT: - strcpy(env->lower_classtype, "class"); - strcpy(env->upper_classtype, "CLASS"); - break; - case EOLIAN_CLASS_MIXIN: - strcpy(env->lower_classtype, "mixin"); - strcpy(env->upper_classtype, "MIXIN"); - break; - case EOLIAN_CLASS_INTERFACE: - strcpy(env->lower_classtype, "interface"); - strcpy(env->upper_classtype, "INTERFACE"); - break; - default: - break; - } -} - -void -_class_func_env_create(const Eolian_Class *class, const char *funcname, Eolian_Function_Type ftype, _eolian_class_func_vars *env) -{ - char *p; - const Eolian_Function *funcid = eolian_class_function_get_by_name(class, funcname, ftype); - - p = _fill_envs(env->upper_func, funcname, sizeof(env->upper_func)); - eina_str_toupper(&p); - - Eolian_Function_Type aftype = ftype; - if (aftype == EOLIAN_PROPERTY) aftype = EOLIAN_METHOD; - - Eina_Stringshare *fname = eolian_function_full_c_name_get(funcid, aftype, EINA_FALSE); - p = _fill_envs(env->upper_eo_func, fname, sizeof(env->upper_eo_func)); - eina_str_toupper(&p); - p = _fill_envs(env->lower_eo_func, fname, sizeof(env->lower_eo_func)); - eina_str_tolower(&p); - eina_stringshare_del(fname); - - Eina_Stringshare *lname = eolian_function_full_c_name_get(funcid, aftype, EINA_TRUE); - env->legacy_func[0] = '\0'; - if (!lname) return; - p = _fill_envs(env->legacy_func, lname, sizeof(env->legacy_func)); - eina_stringshare_del(lname); -} - -void -_template_fill(Eina_Strbuf *buf, const char *templ, const Eolian_Class *class, const char *classname, const char *funcname, Eina_Bool reset) -{ - _eolian_class_vars tmp_env; - _eolian_class_func_vars tmp_func_env; - _class_env_create(class, classname, &tmp_env); - if (funcname) - _class_func_env_create(class, funcname, EOLIAN_UNRESOLVED, &tmp_func_env); - if (buf) - { - if (reset) eina_strbuf_reset(buf); - if (templ) eina_strbuf_append(buf, templ); - if (funcname) - { - eina_strbuf_replace_all(buf, "@#func", funcname); - eina_strbuf_replace_all(buf, "@#FUNC", tmp_func_env.upper_func); - } - eina_strbuf_replace_all(buf, "@#classtype", tmp_env.lower_classtype); - eina_strbuf_replace_all(buf, "@#CLASSTYPE", tmp_env.upper_classtype); - eina_strbuf_replace_all(buf, "@#Class", tmp_env.full_classname); - eina_strbuf_replace_all(buf, "@#class", tmp_env.lower_classname); - eina_strbuf_replace_all(buf, "@#CLASS", tmp_env.upper_classname); - } -} - -const char * -_get_add_star(Eolian_Function_Type ftype, Eolian_Parameter_Dir pdir) -{ - if (ftype == EOLIAN_PROP_GET) - return "*"; - if ((pdir == EOLIAN_OUT_PARAM) || (pdir == EOLIAN_INOUT_PARAM)) - return "*"; - return ""; -} diff --git a/src/bin/eolian/common_funcs.h b/src/bin/eolian/common_funcs.h deleted file mode 100644 index b23515fd38..0000000000 --- a/src/bin/eolian/common_funcs.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef __EOLIAN_COMMON_FUNCS_H -#define __EOLIAN_COMMON_FUNCS_H - -#include -#include - -#define EO - -extern int _eolian_gen_log_dom; - -#ifdef ERR -# undef ERR -#endif -#define ERR(...) EINA_LOG_DOM_ERR(_eolian_gen_log_dom, __VA_ARGS__) - -#ifdef DBG -# undef DBG -#endif -#define DBG(...) EINA_LOG_DOM_DBG(_eolian_gen_log_dom, __VA_ARGS__) - -#ifdef INF -# undef INF -#endif -#define INF(...) EINA_LOG_DOM_INFO(_eolian_gen_log_dom, __VA_ARGS__) - -#ifdef WRN -# undef WRN -#endif -#define WRN(...) EINA_LOG_DOM_WARN(_eolian_gen_log_dom, __VA_ARGS__) - -#ifdef CRIT -# undef CRIT -#endif -#define CRIT(...) EINA_LOG_DOM_CRIT(_eolian_gen_log_dom, __VA_ARGS__) - -typedef struct -{ - char full_classname[PATH_MAX]; - - char upper_eo_prefix[PATH_MAX]; - char lower_eo_prefix[PATH_MAX]; - - char upper_classname[PATH_MAX]; - char lower_classname[PATH_MAX]; - - char upper_classtype[PATH_MAX]; - char lower_classtype[PATH_MAX]; -}_eolian_class_vars; - -typedef struct -{ - char upper_func[PATH_MAX]; - - char upper_eo_func[PATH_MAX]; - char lower_eo_func[PATH_MAX]; - - char legacy_func[PATH_MAX]; -}_eolian_class_func_vars; - -void _template_fill(Eina_Strbuf *buf, const char *templ, const Eolian_Class *class, const char *classname, const char *funcname, Eina_Bool reset); - -void _class_env_create(const Eolian_Class *class, const char *over_classname, _eolian_class_vars *env); - -void _class_func_env_create(const Eolian_Class *class, const char *funcname, Eolian_Function_Type ftype EINA_UNUSED, _eolian_class_func_vars *env); - -const char *_get_add_star(Eolian_Function_Type ftype, Eolian_Parameter_Dir pdir); - -#endif diff --git a/src/bin/eolian/docs_generator.c b/src/bin/eolian/docs.c similarity index 97% rename from src/bin/eolian/docs_generator.c rename to src/bin/eolian/docs.c index 0ee01a69ac..61f1d34fbb 100644 --- a/src/bin/eolian/docs_generator.c +++ b/src/bin/eolian/docs.c @@ -1,10 +1,6 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include -#include "docs_generator.h" +#include "docs.h" static int _indent_line(Eina_Strbuf *buf, int ind) @@ -360,14 +356,14 @@ _gen_doc_buf(const Eolian_Documentation *doc, const char *group, } Eina_Strbuf * -docs_generate_full(const Eolian_Documentation *doc, const char *group, - int indent, Eina_Bool use_legacy) +eo_gen_docs_full_gen(const Eolian_Documentation *doc, const char *group, + int indent, Eina_Bool use_legacy) { return _gen_doc_buf(doc, group, NULL, indent, use_legacy); } Eina_Strbuf * -docs_generate_event(const Eolian_Event *ev, const char *group) +eo_gen_docs_event_gen(const Eolian_Event *ev, const char *group) { if (!ev) return NULL; @@ -402,8 +398,8 @@ docs_generate_event(const Eolian_Event *ev, const char *group) } Eina_Strbuf * -docs_generate_function(const Eolian_Function *fid, Eolian_Function_Type ftype, - int indent, Eina_Bool use_legacy) +eo_gen_docs_func_gen(const Eolian_Function *fid, Eolian_Function_Type ftype, + int indent, Eina_Bool use_legacy) { const Eolian_Function_Parameter *par = NULL; const Eolian_Function_Parameter *vpar = NULL; diff --git a/src/bin/eolian/docs_generator.h b/src/bin/eolian/docs.h similarity index 66% rename from src/bin/eolian/docs_generator.h rename to src/bin/eolian/docs.h index c7038ac71e..eaaa118b1f 100644 --- a/src/bin/eolian/docs_generator.h +++ b/src/bin/eolian/docs.h @@ -1,8 +1,7 @@ -#ifndef DOCS_GENERATOR_H -#define DOCS_GENERATOR_H +#ifndef EOLIAN_GEN_DOCS_H +#define EOLIAN_GEN_DOCS_H -#include -#include +#include "main.h" /* * @brief Generate standard documentation @@ -15,7 +14,7 @@ * @return A documentation comment * */ -Eina_Strbuf *docs_generate_full(const Eolian_Documentation *doc, const char *group, int indent, Eina_Bool use_legacy); +Eina_Strbuf *eo_gen_docs_full_gen(const Eolian_Documentation *doc, const char *group, int indent, Eina_Bool use_legacy); /* * @brief Generate function documentation @@ -28,7 +27,7 @@ Eina_Strbuf *docs_generate_full(const Eolian_Documentation *doc, const char *gro * @return A documentation comment * */ -Eina_Strbuf *docs_generate_function(const Eolian_Function *fid, Eolian_Function_Type ftype, int indent, Eina_Bool use_legacy); +Eina_Strbuf *eo_gen_docs_func_gen(const Eolian_Function *fid, Eolian_Function_Type ftype, int indent, Eina_Bool use_legacy); /* * @brief Generate event documentation @@ -39,7 +38,7 @@ Eina_Strbuf *docs_generate_function(const Eolian_Function *fid, Eolian_Function_ * @return A documentation comment * */ -Eina_Strbuf *docs_generate_event(const Eolian_Event *ev, const char *group); +Eina_Strbuf *eo_gen_docs_event_gen(const Eolian_Event *ev, const char *group); #endif diff --git a/src/bin/eolian/eo_generator.c b/src/bin/eolian/eo_generator.c deleted file mode 100644 index 7b793a0ef2..0000000000 --- a/src/bin/eolian/eo_generator.c +++ /dev/null @@ -1,1047 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include - -#include "Eolian.h" -#include "eo_generator.h" -#include "docs_generator.h" -#include "common_funcs.h" - -static _eolian_class_vars class_env; -/* Used to store the function names that will have to be appended - * with __eolian during C generation. Needed when params have to - * be initialized and for future features. */ -static Eina_Hash *_funcs_params_init = NULL; - -static const char -tmpl_eo_ops_def[] = "\ - EFL_OPS_DEFINE(ops,@#list_op\n\ - );\n"; - -static const char -tmpl_eo_cops_def[] = "\ - EFL_OPS_DEFINE(cops,@#list_cop\n\ - );\n"; - -static const char -tmpl_eo_ops_desc[] = "\ -static Eina_Bool\n\ -_@#class_class_initializer(Efl_Class *klass)\n\ -{\n\ -@#list_ops\ -@#list_cops\ -\n\ - return efl_class_functions_set(klass, @#ref_ops, @#ref_cops);\n\ -}\n\n"; - -static const char -tmpl_eo_src[] = "\ -@#functions_body\ -\n\ -@#ctor_func\ -@#dtor_func\ -@#ops_desc\ -static const Efl_Class_Description _@#class_class_desc = {\n\ - EO_VERSION,\n\ - \"@#Class\",\n\ - @#type_class,\n\ - @#SizeOfData,\n\ - @#init_name,\n\ - @#ctor_name,\n\ - @#dtor_name\n\ -};\n\ -\n\ -EFL_DEFINE_CLASS(@#klasstype_get, &_@#class_class_desc, @#list_inheritNULL);\ -"; - -static const char -tmpl_eo_obj_header[] = "\ -#define @#CLASS_@#CLASSTYPE @#klasstype_get()\n\ -\n\ -EWAPI const Efl_Class *@#klasstype_get(void);\n\ -\n\ -"; - -static Eina_Bool -eo_fundef_generate(const Eolian_Class *class, const Eolian_Function *func, Eolian_Function_Type ftype, Eina_Strbuf *functext) -{ - _eolian_class_func_vars func_env; - Eina_Iterator *itr; - void *data, *data2; - Eina_Bool var_as_ret = EINA_FALSE; - const Eolian_Type *rettypet = NULL; - const char *rettype = NULL; - Eolian_Object_Scope scope = eolian_function_scope_get(func, ftype); - Eina_Bool is_prop = (ftype == EOLIAN_PROP_GET || ftype == EOLIAN_PROP_SET); - - _class_func_env_create(class, eolian_function_name_get(func), ftype, &func_env); - rettypet = eolian_function_return_type_get(func, ftype); - if (ftype == EOLIAN_PROP_GET && !rettypet) - { - itr = eolian_property_values_get(func, ftype); - /* We want to check if there is only one parameter */ - if (eina_iterator_next(itr, &data) && !eina_iterator_next(itr, &data2)) - { - rettypet = eolian_parameter_type_get((Eolian_Function_Parameter*)data); - var_as_ret = EINA_TRUE; - } - eina_iterator_free(itr); - } - Eina_Strbuf *str_func = eina_strbuf_new(); - if (eolian_function_is_beta(func)) - eina_strbuf_append_printf(str_func, "#ifdef %s_BETA\n", class_env.upper_classname); - if (scope == EOLIAN_SCOPE_PROTECTED) - eina_strbuf_append_printf(str_func, "#ifdef %s_PROTECTED\n", class_env.upper_classname); - - Eina_Bool hasnewdocs = eolian_function_documentation_get(func, EOLIAN_UNRESOLVED) || - eolian_function_documentation_get(func, ftype); - if (hasnewdocs) - { - Eina_Strbuf *dbuf = docs_generate_function(func, ftype, 0, EINA_FALSE); - eina_strbuf_append(str_func, eina_strbuf_string_get(dbuf)); - eina_strbuf_append_char(str_func, '\n'); - eina_strbuf_free(dbuf); - } - eina_strbuf_append_printf(str_func, "EOAPI @#rettype@#retspace%s(%sEo *obj@#full_params);\n", - func_env.lower_eo_func, - (ftype == EOLIAN_PROP_GET || - eolian_function_object_is_const(func) || - eolian_function_is_class(func))?"const ":""); - - if (scope == EOLIAN_SCOPE_PROTECTED) - eina_strbuf_append_printf(str_func, "#endif\n"); - if (eolian_function_is_beta(func)) - eina_strbuf_append_printf(str_func, "#endif\n"); - eina_strbuf_append_printf(str_func, "\n"); - - Eina_Strbuf *str_par = eina_strbuf_new(); - - itr = eolian_property_keys_get(func, ftype); - EINA_ITERATOR_FOREACH(itr, data) - { - Eolian_Function_Parameter *param = data; - const Eolian_Type *ptypet = eolian_parameter_type_get(param); - const char *pname = eolian_parameter_name_get(param); - const char *ptype = eolian_type_c_type_get(ptypet); - eina_strbuf_append_printf(str_par, ", %s %s", ptype, pname); - eina_stringshare_del(ptype); - } - eina_iterator_free(itr); - - if (!var_as_ret) - { - itr = is_prop ? eolian_property_values_get(func, ftype) : eolian_function_parameters_get(func); - EINA_ITERATOR_FOREACH(itr, data) - { - Eolian_Function_Parameter *param = data; - const Eolian_Type *ptypet = eolian_parameter_type_get(param); - const char *pname = eolian_parameter_name_get(param); - const char *ptype = eolian_type_c_type_get(ptypet); - Eolian_Parameter_Dir pdir = eolian_parameter_direction_get(param); - Eina_Bool had_star = !!strchr(ptype, '*'); - - eina_strbuf_append_printf(str_par, ", %s%s%s%s", - ptype, had_star?"":" ", _get_add_star(ftype, pdir), pname); - - eina_stringshare_del(ptype); - } - eina_iterator_free(itr); - } - - if (rettypet) rettype = eolian_type_c_type_get(rettypet); - - eina_strbuf_replace_all(str_func, "@#rettype", rettype ? rettype : "void"); - if (!rettype || rettype[strlen(rettype) - 1] != '*') - eina_strbuf_replace_all(str_func, "@#retspace", " "); - else - eina_strbuf_replace_all(str_func, "@#retspace", ""); - - eina_strbuf_replace_all(str_func, "@#full_params", eina_strbuf_string_get(str_par)); - - if (rettype) eina_stringshare_del(rettype); - - eina_strbuf_free(str_par); - - eina_strbuf_append(functext, eina_strbuf_string_get(str_func)); - eina_strbuf_free(str_func); - - return EINA_TRUE; -} - -Eina_Bool -eo_header_generate(const Eolian_Class *class, Eina_Strbuf *buf) -{ - Eina_Iterator *itr; - Eolian_Event *event; - Eina_Strbuf * str_hdr = eina_strbuf_new(); - - const Eolian_Documentation *doc = eolian_class_documentation_get(class); - _class_env_create(class, NULL, &class_env); - - if (doc) - { - Eina_Strbuf *cdoc = docs_generate_full(doc, eolian_class_full_name_get(class), 0, EINA_FALSE); - if (cdoc) - { - eina_strbuf_append(buf, eina_strbuf_string_get(cdoc)); - eina_strbuf_append_char(buf, '\n'); - eina_strbuf_free(cdoc); - } - } - - _template_fill(str_hdr, tmpl_eo_obj_header, class, NULL, NULL, EINA_TRUE); - - eina_strbuf_replace_all(str_hdr, "@#EOPREFIX", class_env.upper_eo_prefix); - eina_strbuf_replace_all(str_hdr, "@#eoprefix", class_env.lower_eo_prefix); - eina_strbuf_replace_all(str_hdr, "@#klasstype_get", eolian_class_c_get_function_name_get(class)); - - Eina_Strbuf *str_ev = eina_strbuf_new(); - Eina_Strbuf *str_extrn_ev = eina_strbuf_new(); - Eina_Strbuf *tmpbuf = eina_strbuf_new(); - - itr = eolian_class_events_get(class); - EINA_ITERATOR_FOREACH(itr, event) - { - Eina_Stringshare *evname = eolian_event_c_name_get(event); - Eolian_Object_Scope scope = eolian_event_scope_get(event); - - if (scope == EOLIAN_SCOPE_PRIVATE) - continue; - - if (eolian_event_is_beta(event)) - { - eina_strbuf_append_printf(str_ev, "\n#ifdef %s_BETA\n", class_env.upper_classname); - eina_strbuf_append_printf(str_extrn_ev, "#ifdef %s_BETA\n", class_env.upper_classname); - } - if (scope == EOLIAN_SCOPE_PROTECTED) - { - if (!eolian_event_is_beta(event)) - eina_strbuf_append_char(str_ev, '\n'); - eina_strbuf_append_printf(str_ev, "#ifdef %s_PROTECTED\n", class_env.upper_classname); - eina_strbuf_append_printf(str_extrn_ev, "#ifdef %s_PROTECTED\n", class_env.upper_classname); - } - - if (!eolian_event_is_beta(event) && scope == EOLIAN_SCOPE_PUBLIC) - eina_strbuf_append_char(str_ev, '\n'); - - Eina_Strbuf *evdbuf = docs_generate_event(event, eolian_class_full_name_get(class)); - eina_strbuf_append(str_ev, eina_strbuf_string_get(evdbuf)); - eina_strbuf_append_char(str_ev, '\n'); - eina_strbuf_free(evdbuf); - - eina_strbuf_append_printf(str_ev, "#define %s (&(_%s))\n", evname, evname); - eina_strbuf_append_printf(str_extrn_ev, "EOAPI extern const Efl_Event_Description _%s;\n", evname); - eina_stringshare_del(evname); - - if (scope == EOLIAN_SCOPE_PROTECTED) - { - eina_strbuf_append(str_ev, "#endif\n"); - eina_strbuf_append(str_extrn_ev, "#endif\n"); - } - if (eolian_event_is_beta(event)) - { - eina_strbuf_append(str_ev, "#endif\n"); - eina_strbuf_append(str_extrn_ev, "#endif\n"); - } - } - eina_iterator_free(itr); - - if ((itr = eolian_class_implements_get(class))) - { - const Eolian_Implement *impl; - EINA_ITERATOR_FOREACH(itr, impl) - { - if (eolian_implement_class_get(impl) != class) - continue; - Eolian_Function_Type ftype = EOLIAN_UNRESOLVED; - const Eolian_Function *fid = eolian_implement_function_get(impl, &ftype); - switch (ftype) - { - case EOLIAN_PROP_GET: case EOLIAN_PROP_SET: - eo_fundef_generate(class, fid, ftype, str_hdr); - break; - case EOLIAN_PROPERTY: - eo_fundef_generate(class, fid, EOLIAN_PROP_SET, str_hdr); - eo_fundef_generate(class, fid, EOLIAN_PROP_GET, str_hdr); - break; - default: - eo_fundef_generate(class, fid, EOLIAN_UNRESOLVED, str_hdr); - break; - } - } - eina_iterator_free(itr); - } - - eina_strbuf_append(str_hdr, eina_strbuf_string_get(str_extrn_ev)); - eina_strbuf_append(str_hdr, eina_strbuf_string_get(str_ev)); - - eina_strbuf_append(buf, eina_strbuf_string_get(str_hdr)); - - eina_strbuf_free(str_ev); - eina_strbuf_free(str_extrn_ev); - eina_strbuf_free(tmpbuf); - eina_strbuf_free(str_hdr); - - return EINA_TRUE; -} - -static Eina_Bool -eo_bind_func_generate(const Eolian_Class *class, const Eolian_Function *funcid, Eolian_Function_Type ftype, Eina_Strbuf *buf, Eolian_Implement *impl, _eolian_class_vars *impl_env) -{ - _eolian_class_func_vars func_env; - const char *suffix = ""; - Eina_Bool var_as_ret = EINA_FALSE; - const Eolian_Type *rettypet = NULL; - const char *rettype = NULL; - Eina_Iterator *itr; - void *data, *data2; - const Eolian_Expression *default_ret_val = NULL; - Eina_Bool is_empty = impl ? eolian_implement_is_empty(impl) : eolian_function_is_empty(funcid, ftype); - Eina_Bool is_auto = impl ? eolian_implement_is_auto(impl) : eolian_function_is_auto(funcid, ftype); - if (ftype != EOLIAN_PROP_GET && ftype != EOLIAN_PROP_SET) ftype = eolian_function_type_get(funcid); - Eina_Bool is_prop = (ftype == EOLIAN_PROP_GET || ftype == EOLIAN_PROP_SET); - - Eina_Bool has_promise = EINA_FALSE; - const char* promise_param_name = NULL; - const char* promise_value_type = NULL; - Eina_Bool need_implementation = EINA_TRUE; - if (!impl_env && eolian_function_is_virtual_pure(funcid, ftype)) need_implementation = 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 */ - Eina_Strbuf *impl_full_params = eina_strbuf_new(); /* variables types + names */ - Eina_Strbuf *params_init = eina_strbuf_new(); /* init of variables to default */ - - rettypet = eolian_function_return_type_get(funcid, ftype); - if (rettypet) - { - is_auto = EINA_FALSE; /* We block auto when the function has to return something */ - default_ret_val = eolian_function_return_default_value_get(funcid, ftype); - } - if (ftype == EOLIAN_PROP_GET) - { - suffix = "_get"; - if (!rettypet) - { - itr = eolian_property_values_get(funcid, ftype); - /* We want to check if there is only one parameter */ - if (eina_iterator_next(itr, &data) && !eina_iterator_next(itr, &data2)) - { - Eolian_Function_Parameter *param = data; - rettypet = eolian_parameter_type_get(param); - var_as_ret = EINA_TRUE; - default_ret_val = eolian_parameter_default_value_get(param); - } - eina_iterator_free(itr); - } - } - if (ftype == EOLIAN_PROP_SET) - { - suffix = "_set"; - } - - itr = eolian_property_keys_get(funcid, ftype); - EINA_ITERATOR_FOREACH(itr, data) - { - Eolian_Function_Parameter *param = data; - const Eolian_Type *ptypet = eolian_parameter_type_get(param); - const char *pname = eolian_parameter_name_get(param); - const char *ptype = eolian_type_c_type_get(ptypet); - if (eina_strbuf_length_get(params)) eina_strbuf_append(params, ", "); - eina_strbuf_append_printf(params, "%s", pname); - eina_strbuf_append_printf(full_params, ", %s %s%s", - ptype, pname, is_empty || is_auto?" EINA_UNUSED":""); - eina_strbuf_append_printf(impl_full_params, ", %s %s%s", - ptype, pname, is_empty || is_auto?" EINA_UNUSED":""); - eina_stringshare_del(ptype); - } - eina_iterator_free(itr); - if (!var_as_ret) - { - itr = is_prop ? eolian_property_values_get(funcid, ftype) : eolian_function_parameters_get(funcid); - EINA_ITERATOR_FOREACH(itr, data) - { - Eolian_Function_Parameter *param = data; - const Eolian_Expression *dflt_value = eolian_parameter_default_value_get(param); - const Eolian_Type *ptypet = eolian_parameter_type_get(param); - const char *pname = eolian_parameter_name_get(param); - const char *ptype = eolian_type_c_type_get(ptypet); - Eolian_Parameter_Dir pdir = eolian_parameter_direction_get(param); - Eina_Bool had_star = !!strchr(ptype, '*'); - const char *add_star = _get_add_star(ftype, pdir); - - if (eina_strbuf_length_get(params)) eina_strbuf_append(params, ", "); - - /* FIXME: this looks really bad and should not be here */ - if(!has_promise && !strcmp(ptype, "Eina_Promise *") && - (ftype == EOLIAN_UNRESOLVED || ftype == EOLIAN_METHOD) && pdir == EOLIAN_INOUT_PARAM) - { - has_promise = EINA_TRUE; - promise_param_name = eina_stringshare_add(pname); - promise_value_type = eolian_type_c_type_get(eolian_type_base_type_get(ptypet)); - eina_strbuf_append_printf(impl_full_params, ", Eina_Promise_Owner *%s%s", - pname, is_empty && !dflt_value ?" EINA_UNUSED":""); - eina_strbuf_append_printf(params, "__eo_promise"); - } - else - { - eina_strbuf_append_printf(impl_full_params, ", %s%s%s%s%s", - ptype, had_star?"":" ", add_star, pname, is_empty && !dflt_value ?" EINA_UNUSED":""); - eina_strbuf_append_printf(params, "%s", pname); - } - - eina_strbuf_append_printf(full_params, ", %s%s%s%s%s", - ptype, had_star?"":" ", add_star, pname, is_empty && !dflt_value ?" EINA_UNUSED":""); - if (is_auto) - { - if (ftype == EOLIAN_PROP_SET) - { - eina_strbuf_append_printf(params_init, - " %s = pd->%s;\n", pname, pname); - } - else - { - eina_strbuf_append_printf(params_init, - " if (%s) *%s = pd->%s;\n", pname, pname, pname); - } - } - else { - if (ftype != EOLIAN_PROP_SET) - { - if (dflt_value) - { - const char *val_str = NULL; - Eolian_Value val = eolian_expression_eval - (dflt_value, EOLIAN_MASK_ALL); - if (val.type) - { - val_str = eolian_expression_value_to_literal(&val); - eina_strbuf_append_printf(params_init, - " if (%s) *%s = %s;", - pname, pname, val_str); - if (eolian_expression_type_get(dflt_value) == EOLIAN_EXPR_NAME) - { - Eina_Stringshare *string = eolian_expression_serialize(dflt_value); - eina_strbuf_append_printf(params_init, " /* %s */", string); - eina_stringshare_del(string); - } - eina_strbuf_append_printf(params_init, "\n"); - } - } - } - } - eina_stringshare_del(ptype); - } - eina_iterator_free(itr); - } - - if (rettypet) rettype = eolian_type_c_type_get(rettypet); - - if (need_implementation) - { - Eina_Strbuf *ret_param = eina_strbuf_new(); - eina_strbuf_append_printf(fbody, "\n"); - /* Generation of the user function prototype declaration - not needed when @auto and @empty are indicated */ - if (!is_empty && !is_auto) - { - eina_strbuf_append_printf(fbody, "%s _%s%s%s_%s%s(%sEo *obj, @#Datatype_Data *pd%s);\n\n", - rettype?rettype:"void", - class_env.lower_classname, - impl_env?"_":"", - impl_env?impl_env->lower_classname:"", - eolian_function_name_get(funcid), suffix, - eolian_function_object_is_const(funcid)?"const ":"", - eina_strbuf_string_get(impl_full_params)); - } - - if (is_empty || is_auto || eina_strbuf_length_get(params_init)) - { - /* We need to give the internal function name to Eo. We use this hash table as indication */ - eina_hash_add(_funcs_params_init, - eina_stringshare_add(eolian_function_name_get(funcid)), (void *)ftype); - /* Generation of the intermediate function __eolian_... */ - eina_strbuf_append_printf(fbody, "static %s __eolian_%s%s%s_%s%s(%sEo *obj%s, @#Datatype_Data *pd%s%s)\n{\n", - rettype?rettype:"void", - class_env.lower_classname, - impl_env?"_":"", - impl_env?impl_env->lower_classname:"", - eolian_function_name_get(funcid), suffix, - eolian_function_object_is_const(funcid)?"const ":"", - is_empty || is_auto?" EINA_UNUSED":"", - is_empty || (is_auto && !eina_strbuf_length_get(params_init))?" EINA_UNUSED":"", - eina_strbuf_string_get(impl_full_params)); - } - if (eina_strbuf_length_get(params_init)) - { - eina_strbuf_append_printf(fbody, "%s", eina_strbuf_string_get(params_init)); - } - if (is_auto || is_empty) - { - if (rettype) - { - /* return for auto and empty */ - const char *val_str = NULL; - if (default_ret_val) - { - Eolian_Value val = eolian_expression_eval - (default_ret_val, EOLIAN_MASK_ALL); - if (val.type) - val_str = eolian_expression_value_to_literal(&val); - } - eina_strbuf_append_printf(fbody, " return %s;\n", val_str?val_str:"0"); - } - eina_strbuf_append_printf(fbody, "}\n\n"); - } - else if (eina_strbuf_length_get(params_init)) - { - /* Generation of the user function invocation, e.g return _user_foo(obj, pd, ...) */ - eina_strbuf_append_printf(fbody, " %s_%s%s%s_%s%s(obj, pd, %s);\n}\n\n", - rettype?"return ":"", - class_env.lower_classname, - impl_env?"_":"", - impl_env?impl_env->lower_classname:"", - eolian_function_name_get(funcid), suffix, - eina_strbuf_string_get(params)); - } - eina_strbuf_free(ret_param); - } - if (!impl_env) - { - Eina_Strbuf *eo_func_decl = eina_strbuf_new(); - Eina_Bool has_params = EINA_FALSE; - - itr = eolian_property_keys_get(funcid, ftype); - has_params |= (eina_iterator_next(itr, &data)); - eina_iterator_free(itr); - - if (!has_params && !var_as_ret) - { - itr = is_prop ? eolian_property_values_get(funcid, ftype) : eolian_function_parameters_get(funcid); - has_params |= (eina_iterator_next(itr, &data)); - eina_iterator_free(itr); - } - Eina_Bool ret_is_void = (!rettype || !strcmp(rettype, "void")); - _class_func_env_create(class, eolian_function_name_get(funcid), ftype, &func_env); - eina_strbuf_append_printf(eo_func_decl, - "EOAPI EFL_%sFUNC_BODY%s%s(%s", - ret_is_void?"VOID_":"", has_params?"V":"", - (ftype == EOLIAN_PROP_GET || - eolian_function_object_is_const(funcid) || - eolian_function_is_class(funcid))?"_CONST":"", func_env.lower_eo_func); - if (!ret_is_void) - { - const char *val_str = NULL; - if (default_ret_val) - { - Eolian_Value val = eolian_expression_eval - (default_ret_val, EOLIAN_MASK_ALL); - if (val.type) - val_str = eolian_expression_value_to_literal(&val); - } - eina_strbuf_append_printf(eo_func_decl, ", %s, %s", - rettype, val_str?val_str:"0"); - if (val_str && eolian_expression_type_get(default_ret_val) == EOLIAN_EXPR_NAME) - { - Eina_Stringshare *string = eolian_expression_serialize(default_ret_val); - eina_strbuf_append_printf(eo_func_decl, " /* %s */", string); - eina_stringshare_del(string); - } - } - if (has_params) - { - eina_strbuf_replace_all(full_params, " EINA_UNUSED", ""); - eina_strbuf_append_printf(eo_func_decl, ", EFL_FUNC_CALL(%s)%s", - eina_strbuf_string_get(params), - eina_strbuf_string_get(full_params)); - } - eina_strbuf_append_printf(eo_func_decl, ");"); - - if(has_promise) - { - eina_strbuf_append_printf(fbody, - "#undef _EFL_OBJECT_API_BEFORE_HOOK\n#undef _EFL_OBJECT_API_AFTER_HOOK\n#undef _EFL_OBJECT_API_CALL_HOOK\n" - "#define _EFL_OBJECT_API_BEFORE_HOOK _EINA_PROMISE_BEFORE_HOOK(%s, %s%s)\n" - "#define _EFL_OBJECT_API_AFTER_HOOK _EINA_PROMISE_AFTER_HOOK(%s)\n" - "#define _EFL_OBJECT_API_CALL_HOOK(x) _EINA_PROMISE_CALL_HOOK(EFL_FUNC_CALL(%s))\n\n", - promise_value_type, !rettype ? "void" : rettype, - eina_strbuf_string_get(impl_full_params), - promise_param_name, - eina_strbuf_string_get(params)); - } - - eina_strbuf_append_printf(fbody, "%s\n", eina_strbuf_string_get(eo_func_decl)); - - if(has_promise) - { - eina_strbuf_append_printf(fbody, "\n#undef _EFL_OBJECT_API_BEFORE_HOOK\n#undef _EFL_OBJECT_API_AFTER_HOOK\n#undef _EFL_OBJECT_API_CALL_HOOK\n" - "#define _EFL_OBJECT_API_BEFORE_HOOK\n#define _EFL_OBJECT_API_AFTER_HOOK\n" - "#define _EFL_OBJECT_API_CALL_HOOK(x) x\n"); - } - - eina_strbuf_free(eo_func_decl); - } - - if (need_implementation) - { - Eina_Bool is_cf = eolian_function_is_class(funcid); - const char *data_type = eolian_class_data_type_get(class); - if (is_cf || (data_type && !strcmp(data_type, "null"))) - eina_strbuf_replace_all(fbody, "@#Datatype_Data", "void"); - else - { - if (data_type) eina_strbuf_replace_all(fbody, "@#Datatype_Data", data_type); - else eina_strbuf_replace_all(fbody, "@#Datatype", class_env.full_classname); - } - - if (!data_type || !strcmp(data_type, "null")) - eina_strbuf_replace_all(fbody, "@#Datatype", class_env.full_classname); - else - eina_strbuf_replace_all(fbody, "@#Datatype_Data", data_type); - } - eina_strbuf_append(buf, eina_strbuf_string_get(fbody)); - - if (rettype) eina_stringshare_del(rettype); - - eina_strbuf_free(va_args); - eina_strbuf_free(full_params); - eina_strbuf_free(impl_full_params); - eina_strbuf_free(params_init); - eina_strbuf_free(params); - eina_strbuf_free(fbody); - return EINA_TRUE; -} - -static Eina_Bool -eo_op_desc_generate(const Eolian_Class *class, const Eolian_Function *fid, Eolian_Function_Type ftype, - Eina_Strbuf *buf) -{ - _eolian_class_func_vars func_env; - const char *funcname = eolian_function_name_get(fid); - const char *suffix = ""; - - eina_strbuf_reset(buf); - _class_func_env_create(class, funcname, ftype, &func_env); - if (ftype == EOLIAN_PROP_GET) suffix = "_get"; - if (ftype == EOLIAN_PROP_SET) suffix = "_set"; - Eina_Bool is_virtual_pure = eolian_function_is_virtual_pure(fid, ftype); - eina_strbuf_append_printf(buf, "\n EFL_OBJECT_OP_FUNC(%s, ", func_env.lower_eo_func); - if (!is_virtual_pure) - { - Eolian_Function_Type ftype2 = (Eolian_Function_Type) eina_hash_find(_funcs_params_init, funcname); - eina_strbuf_append_printf(buf, "%s_%s_%s%s),", - ftype == ftype2?"__eolian":"", - class_env.lower_classname, funcname, suffix); - } - else - eina_strbuf_append_printf(buf, "NULL),"); - - return EINA_TRUE; -} - -static Eina_Bool -eo_source_beginning_generate(const Eolian_Class *class, Eina_Strbuf *buf) -{ - Eina_Iterator *itr; - - Eina_Strbuf *tmpbuf = eina_strbuf_new(); - - Eolian_Event *event; - itr = eolian_class_events_get(class); - EINA_ITERATOR_FOREACH(itr, event) - { - Eina_Stringshare *evname = eolian_event_c_name_get(event); - - eina_strbuf_append_printf(tmpbuf, - "EOAPI const Efl_Event_Description _%s =\n EFL_EVENT_DESCRIPTION%s%s(\"%s\");\n", - evname, - eolian_event_is_hot(event) ? "_HOT" : "", - eolian_event_is_restart(event) ? "_RESTART" : "", - eolian_event_name_get(event)); - eina_stringshare_del(evname); - } - eina_iterator_free(itr); - - eina_strbuf_append(buf, eina_strbuf_string_get(tmpbuf)); - - eina_strbuf_free(tmpbuf); - return EINA_TRUE; -} - -static void -_desc_generate(const Eolian_Class *class, const Eolian_Function *fid, Eolian_Function_Type ftype, Eina_Strbuf *tmpbuf, Eina_Strbuf *str_op) -{ - const char *funcname = eolian_function_name_get(fid); - char tmpstr[256]; - snprintf(tmpstr, sizeof(tmpstr), "%s%s", funcname, (ftype == EOLIAN_PROP_SET) - ? "_set" : ((ftype == EOLIAN_PROP_GET) ? "_get" : "")); - - eo_op_desc_generate(class, fid, ftype, tmpbuf); - eina_strbuf_append(str_op, eina_strbuf_string_get(tmpbuf)); -} - -static Eina_Bool -eo_source_end_generate(const Eolian_Class *class, Eina_Strbuf *buf) -{ - Eina_Bool ret = EINA_FALSE; - Eina_Iterator *itr; - Eolian_Implement *impl_desc; - const char *inherit_name; - - const char *str_classtype = NULL; - switch(eolian_class_type_get(class)) - { - case EOLIAN_CLASS_REGULAR: - str_classtype = "EFL_CLASS_TYPE_REGULAR"; - break; - case EOLIAN_CLASS_ABSTRACT: - str_classtype = "EFL_CLASS_TYPE_REGULAR_NO_INSTANT"; - break; - case EOLIAN_CLASS_MIXIN: - str_classtype = "EFL_CLASS_TYPE_MIXIN"; - break; - case EOLIAN_CLASS_INTERFACE: - str_classtype = "EFL_CLASS_TYPE_INTERFACE"; - break; - default: - break; - } - - if (!str_classtype) - { - fprintf(stderr, "eolian: unknown class type for class '%s'\n", - class_env.full_classname); - return EINA_FALSE; - } - - Eina_Strbuf *str_end = eina_strbuf_new(); - Eina_Strbuf *tmpbuf = eina_strbuf_new(); - Eina_Strbuf *str_op = eina_strbuf_new(); - Eina_Strbuf *str_cop = eina_strbuf_new(); - Eina_Strbuf *str_bodyf = eina_strbuf_new(); - - _template_fill(str_end, tmpl_eo_src, class, NULL, NULL, EINA_TRUE); - - eina_strbuf_replace_all(str_end, "@#type_class", str_classtype); - eina_strbuf_replace_all(str_end, "@#EOPREFIX", class_env.upper_eo_prefix); - eina_strbuf_replace_all(str_end, "@#eoprefix", class_env.lower_eo_prefix); - eina_strbuf_replace_all(str_end, "@#klasstype_get", eolian_class_c_get_function_name_get(class)); - - eina_strbuf_reset(tmpbuf); - eina_strbuf_replace_all(str_end, "@#ctor_func", eina_strbuf_string_get(tmpbuf)); - - eina_strbuf_reset(tmpbuf); - if (eolian_class_ctor_enable_get(class)) - _template_fill(tmpbuf, "_@#class_class_constructor", class, NULL, NULL, EINA_TRUE); - else - eina_strbuf_append_printf(tmpbuf, "NULL"); - eina_strbuf_replace_all(str_end, "@#ctor_name", eina_strbuf_string_get(tmpbuf)); - - eina_strbuf_reset(tmpbuf); - if (eolian_class_dtor_enable_get(class)) - { - eina_strbuf_replace_all(str_end, "@#dtor_func", eina_strbuf_string_get(tmpbuf)); - eina_strbuf_reset(tmpbuf); - _template_fill(tmpbuf, "_@#class_class_destructor", class, NULL, NULL, EINA_TRUE); - eina_strbuf_replace_all(str_end, "@#dtor_name", eina_strbuf_string_get(tmpbuf)); - } - else - { - eina_strbuf_replace_all(str_end, "@#dtor_func", ""); - eina_strbuf_replace_all(str_end, "@#dtor_name", "NULL"); - } - - eina_strbuf_reset(tmpbuf); - - //Implements - TODO one generate func def for all - itr = eolian_class_implements_get(class); - EINA_ITERATOR_FOREACH(itr, impl_desc) - { - _eolian_class_vars impl_env; - char implname[0xFF]; - const Eolian_Class *impl_class = NULL; - Eolian_Function_Type ftype; - const Eolian_Function *fnid = NULL; - const char *funcname = NULL; - - const char *names[] = { "", "getter ", "setter " }; - - impl_class = eolian_implement_class_get(impl_desc); - - if (impl_class) - { - char *tp = implname; - if (impl_class == class) - continue; - fnid = eolian_implement_function_get(impl_desc, &ftype); - _class_env_create(impl_class, NULL, &impl_env); - funcname = eolian_function_name_get(fnid); - - Eina_Bool dflt_values = EINA_FALSE; - Eina_Iterator *pitr = NULL; - if (!eolian_implement_is_auto(impl_desc) && fnid && (ftype != EOLIAN_PROP_SET)) - { - Eolian_Function_Parameter *param; - pitr = (ftype == EOLIAN_METHOD) ? eolian_function_parameters_get(fnid) - : eolian_property_values_get(fnid, ftype); - EINA_ITERATOR_FOREACH(pitr, param) - { - const Eolian_Expression *dflt_value = eolian_parameter_default_value_get(param); - if (dflt_value) - { - Eolian_Value val = eolian_expression_eval - (dflt_value, EOLIAN_MASK_ALL); - if (val.type) - { - dflt_values = EINA_TRUE; - break; - } - } - } - eina_iterator_free(pitr); - } - - sprintf(implname, "%s_%s_%s", - (eolian_implement_is_auto(impl_desc) || eolian_implement_is_empty(impl_desc) || dflt_values)? - "__eolian":"", - class_env.full_classname, impl_env.full_classname); - eina_str_tolower(&tp); - } - - if (!fnid) - { - const char *name = names[eolian_implement_is_prop_get(impl_desc) - | (eolian_implement_is_prop_set(impl_desc) << 1)]; - fprintf(stderr, "eolian: failed to generate implementation of '%s%s' - missing from superclass\n", - name, eolian_implement_full_name_get(impl_desc)); - goto end; - } - - Eina_Strbuf *wbuf = str_op; - if (eolian_function_is_class(fnid)) wbuf = str_cop; - - switch (ftype) - { - case EOLIAN_PROP_SET: case EOLIAN_PROP_GET: case EOLIAN_PROPERTY: - if (ftype != EOLIAN_PROP_GET) - { - Eina_Stringshare *rets = eolian_function_full_c_name_get(fnid, EOLIAN_PROP_SET, EINA_FALSE); - eina_strbuf_append_printf(wbuf, "\n EFL_OBJECT_OP_FUNC(%s, %s_%s_set),", - rets, implname, funcname); - eo_bind_func_generate(class, fnid, EOLIAN_PROP_SET, str_bodyf, impl_desc, &impl_env); - eina_stringshare_del(rets); - } - - if (ftype != EOLIAN_PROP_SET) - { - Eina_Stringshare *rets = eolian_function_full_c_name_get(fnid, EOLIAN_PROP_GET, EINA_FALSE); - eina_strbuf_append_printf(wbuf, "\n EFL_OBJECT_OP_FUNC(%s, %s_%s_get),", - rets, implname, funcname); - eo_bind_func_generate(class, fnid, EOLIAN_PROP_GET, str_bodyf, impl_desc, &impl_env); - eina_stringshare_del(rets); - } - break; - default: - { - Eina_Stringshare *rets = eolian_function_full_c_name_get(fnid, ftype, EINA_FALSE); - eina_strbuf_append_printf(wbuf, "\n EFL_OBJECT_OP_FUNC(%s, %s_%s),", - rets, implname, funcname); - eo_bind_func_generate(class, fnid, ftype, str_bodyf, impl_desc, &impl_env); - eina_stringshare_del(rets); - break; - } - } - } - eina_iterator_free(itr); - - if ((itr = eolian_class_implements_get(class))) - { - const Eolian_Implement *impl; - EINA_ITERATOR_FOREACH(itr, impl) - { - if (eolian_implement_class_get(impl) != class) - continue; - Eolian_Function_Type ftype = EOLIAN_UNRESOLVED; - const Eolian_Function *fid = eolian_implement_function_get(impl, &ftype); - - Eina_Strbuf *wbuf = str_op; - if (eolian_function_is_class(fid)) wbuf = str_cop; - - Eina_Bool prop_read = (ftype == EOLIAN_PROPERTY || ftype == EOLIAN_PROP_GET); - Eina_Bool prop_write = (ftype == EOLIAN_PROPERTY || ftype == EOLIAN_PROP_SET); - - if (!prop_read && !prop_write && !eolian_function_is_legacy_only(fid, EOLIAN_METHOD)) - _desc_generate(class, fid, EOLIAN_METHOD, tmpbuf, wbuf); - if (prop_write && !eolian_function_is_legacy_only(fid, EOLIAN_PROP_SET)) - _desc_generate(class, fid, EOLIAN_PROP_SET, tmpbuf, wbuf); - if (prop_read && !eolian_function_is_legacy_only(fid, EOLIAN_PROP_GET)) - _desc_generate(class, fid, EOLIAN_PROP_GET, tmpbuf, wbuf); - } - eina_iterator_free(itr); - } - - eina_strbuf_reset(tmpbuf); - itr = eolian_class_inherits_get(class); - EINA_ITERATOR_FOREACH(itr, inherit_name) - { - const Eolian_Class *inherit_class = eolian_class_get_by_name(inherit_name); - _eolian_class_vars inherit_env; - assert(inherit_class); - _class_env_create(inherit_class, NULL, &inherit_env); - eina_strbuf_append_printf(tmpbuf, "%s_%s, ", inherit_env.upper_classname, - inherit_env.upper_classtype); - } - eina_iterator_free(itr); - - if (eina_strbuf_length_get(tmpbuf) == 0) eina_strbuf_append(tmpbuf, "NULL, "); - eina_strbuf_replace_all(str_end, "@#list_inherit", eina_strbuf_string_get(tmpbuf)); - - Eina_Strbuf *ops_buf = eina_strbuf_new(), *cops_buf = eina_strbuf_new(); - - if (eina_strbuf_length_get(str_op)) - { - size_t stroplen = eina_strbuf_length_get(str_op); - if (eina_strbuf_string_get(str_op)[stroplen - 1] == ',') - eina_strbuf_remove(str_op, stroplen - 1, stroplen); - _template_fill(ops_buf, tmpl_eo_ops_def, class, NULL, NULL, EINA_TRUE); - eina_strbuf_replace_all(ops_buf, "@#list_op", eina_strbuf_string_get(str_op)); - } - - if (eina_strbuf_length_get(str_cop)) - { - size_t strcoplen = eina_strbuf_length_get(str_cop); - if (eina_strbuf_string_get(str_cop)[strcoplen - 1] == ',') - eina_strbuf_remove(str_cop, strcoplen - 1, strcoplen); - _template_fill(cops_buf, tmpl_eo_cops_def, class, NULL, NULL, EINA_TRUE); - eina_strbuf_replace_all(cops_buf, "@#list_cop", eina_strbuf_string_get(str_cop)); - } - - if (eina_strbuf_length_get(ops_buf) || eina_strbuf_length_get(cops_buf)) - { - Eina_Strbuf *ops_desc = eina_strbuf_new(); - _template_fill(ops_desc, tmpl_eo_ops_desc, class, NULL, NULL, EINA_TRUE); - if (eina_strbuf_length_get(ops_buf)) - { - eina_strbuf_replace_all(ops_desc, "@#list_ops", eina_strbuf_string_get(ops_buf)); - eina_strbuf_replace_all(ops_desc, "@#ref_ops", "&ops"); - } - else - { - eina_strbuf_replace_all(ops_desc, "@#list_ops", ""); - eina_strbuf_replace_all(ops_desc, "@#ref_ops", "NULL"); - } - if (eina_strbuf_length_get(cops_buf)) - { - eina_strbuf_replace_all(ops_desc, "@#list_cops", eina_strbuf_string_get(cops_buf)); - eina_strbuf_replace_all(ops_desc, "@#ref_cops", "&cops"); - } - else - { - eina_strbuf_replace_all(ops_desc, "@#list_cops", ""); - eina_strbuf_replace_all(ops_desc, "@#ref_cops", "NULL"); - } - eina_strbuf_replace_all(str_end, "@#ops_desc", eina_strbuf_string_get(ops_desc)); - eina_strbuf_free(ops_desc); - eina_strbuf_reset(tmpbuf); - _template_fill(tmpbuf, "_@#class_class_initializer", class, NULL, NULL, EINA_TRUE); - eina_strbuf_replace_all(str_end, "@#init_name", eina_strbuf_string_get(tmpbuf)); - } - else - { - eina_strbuf_replace_all(str_end, "@#ops_desc", ""); - eina_strbuf_replace_all(str_end, "@#init_name", "NULL"); - } - - eina_strbuf_free(ops_buf); - eina_strbuf_free(cops_buf); - - eina_strbuf_replace_all(str_end, "@#functions_body", eina_strbuf_string_get(str_bodyf)); - - const char *data_type = eolian_class_data_type_get(class); - if (data_type && !strcmp(data_type, "null")) - eina_strbuf_replace_all(str_end, "@#SizeOfData", "0"); - else - { - Eina_Strbuf *sizeofbuf = eina_strbuf_new(); - eina_strbuf_append_printf(sizeofbuf, "sizeof(%s%s)", - data_type?data_type:class_env.full_classname, - data_type?"":"_Data"); - eina_strbuf_replace_all(str_end, "@#SizeOfData", eina_strbuf_string_get(sizeofbuf)); - eina_strbuf_free(sizeofbuf); - } - eina_strbuf_append(buf, eina_strbuf_string_get(str_end)); - - ret = EINA_TRUE; -end: - eina_strbuf_free(tmpbuf); - eina_strbuf_free(str_op); - eina_strbuf_free(str_cop); - eina_strbuf_free(str_bodyf); - eina_strbuf_free(str_end); - - return ret; -} - -Eina_Bool -eo_source_generate(const Eolian_Class *class, Eina_Strbuf *buf) -{ - Eina_Bool ret = EINA_FALSE; - Eina_Iterator *itr = NULL; - - Eina_Strbuf *str_bodyf = eina_strbuf_new(); - - _class_env_create(class, NULL, &class_env); - _funcs_params_init = eina_hash_stringshared_new(NULL); - - if (!eo_source_beginning_generate(class, buf)) goto end; - - if ((itr = eolian_class_implements_get(class))) - { - const Eolian_Implement *impl; - EINA_ITERATOR_FOREACH(itr, impl) - { - if (eolian_implement_class_get(impl) != class) - continue; - Eolian_Function_Type ftype = EOLIAN_UNRESOLVED; - const Eolian_Function *fid = eolian_implement_function_get(impl, &ftype); - switch (ftype) - { - case EOLIAN_PROP_GET: case EOLIAN_PROP_SET: - if (!eo_bind_func_generate(class, fid, ftype, str_bodyf, NULL, NULL)) - goto end; - break; - case EOLIAN_PROPERTY: - if (!eo_bind_func_generate(class, fid, EOLIAN_PROP_SET, str_bodyf, NULL, NULL)) - goto end; - if (!eo_bind_func_generate(class, fid, EOLIAN_PROP_GET, str_bodyf, NULL, NULL)) - goto end; - break; - default: - if (!eo_bind_func_generate(class, fid, EOLIAN_UNRESOLVED, str_bodyf, NULL, NULL)) - goto end; - break; - } - } - eina_iterator_free(itr); - itr = NULL; - } - - eina_strbuf_append(buf, eina_strbuf_string_get(str_bodyf)); - eina_strbuf_reset(str_bodyf); - - if (!eo_source_end_generate(class, buf)) goto end; - - ret = EINA_TRUE; -end: - if (itr) eina_iterator_free(itr); - eina_hash_free(_funcs_params_init); - _funcs_params_init = NULL; - eina_strbuf_free(str_bodyf); - return ret; -} - diff --git a/src/bin/eolian/eo_generator.h b/src/bin/eolian/eo_generator.h deleted file mode 100644 index fc47a7b8ca..0000000000 --- a/src/bin/eolian/eo_generator.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef EO1_GENERATOR_H -#define EO1_GENERATOR_H - -#include - -/* - * @brief Generate Eo source code for Eo class - * - * This function generates all the source code for Eo. - * - * @param[in] classname class name - * @param[inout] buf buffer to fill - * - * @return EINA_TRUE on success, EINA_FALSE on error. - * - */ -Eina_Bool -eo_source_generate(const Eolian_Class *class, Eina_Strbuf *buf); - -/* - * @brief Generate the header code for a specific Eo class. - * - * This function generates header code from scratch. - * - * @param[in] classname class name - * @param[inout] buf buffer to fill - * - * @return EINA_TRUE on success, EINA_FALSE on error. - * - */ -Eina_Bool eo_header_generate(const Eolian_Class *class, Eina_Strbuf *buf); - -#endif - diff --git a/src/bin/eolian/headers.c b/src/bin/eolian/headers.c new file mode 100644 index 0000000000..63ec73a5b1 --- /dev/null +++ b/src/bin/eolian/headers.c @@ -0,0 +1,314 @@ +#include "main.h" +#include "docs.h" + +static const char * +_cl_type_str_get(const Eolian_Class *cl, Eina_Bool uc) +{ + switch (eolian_class_type_get(cl)) + { + case EOLIAN_CLASS_REGULAR: + case EOLIAN_CLASS_ABSTRACT: + return uc ? "CLASS" : "class"; + case EOLIAN_CLASS_MIXIN: + return uc ? "MIXIN" : "mixin"; + case EOLIAN_CLASS_INTERFACE: + return uc ? "INTERFACE" : "interface"; + default: + return NULL; + } +} + +static const char * +_get_add_star(Eolian_Function_Type ftype, Eolian_Parameter_Dir pdir) +{ + if (ftype == EOLIAN_PROP_GET) + return "*"; + if ((pdir == EOLIAN_OUT_PARAM) || (pdir == EOLIAN_INOUT_PARAM)) + return "*"; + return ""; +} + +static void +_gen_func(const Eolian_Function *fid, Eolian_Function_Type ftype, + Eina_Strbuf *buf, char *cname, char *cnameu, Eina_Bool legacy) +{ + Eina_Stringshare *fcn = eolian_function_full_c_name_get(fid, ftype, legacy); + if (!fcn) + return; + + Eina_Bool var_as_ret = EINA_FALSE; + const Eolian_Type *rtp = eolian_function_return_type_get(fid, ftype); + if (ftype == EOLIAN_PROP_GET && !rtp) + { + void *d1, *d2; + Eina_Iterator *itr = eolian_property_values_get(fid, ftype); + if (eina_iterator_next(itr, &d1) && !eina_iterator_next(itr, &d2)) + { + rtp = eolian_parameter_type_get((Eolian_Function_Parameter *)d1); + var_as_ret = EINA_TRUE; + } + eina_iterator_free(itr); + } + + Eolian_Object_Scope fsc = eolian_function_scope_get(fid, ftype); + + /* this one will never be satisfied in legacy */ + if (eolian_function_is_beta(fid)) + eina_strbuf_append_printf(buf, "#ifdef %s_BETA\n", cnameu); + /* XXX: is this right? we expose potentially internal stuff into legacy */ + if (!legacy && (fsc == EOLIAN_SCOPE_PROTECTED)) + eina_strbuf_append_printf(buf, "#ifdef %s_PROTECTED\n", cnameu); + + Eina_Bool hasdoc = eolian_function_documentation_get(fid, EOLIAN_UNRESOLVED) || + eolian_function_documentation_get(fid, ftype); + if (hasdoc) + { + Eina_Strbuf *dbuf = eo_gen_docs_func_gen(fid, ftype, 0, legacy); + eina_strbuf_append(buf, eina_strbuf_string_get(dbuf)); + eina_strbuf_append_char(buf, '\n'); + eina_strbuf_free(dbuf); + } + eina_strbuf_append(buf, legacy ? "EAPI " : "EOAPI "); + if (rtp) + { + Eina_Stringshare *rtps = eolian_type_c_type_get(rtp); + eina_strbuf_append(buf, rtps); + if (rtps[strlen(rtps) - 1] != '*') + eina_strbuf_append_char(buf, ' '); + eina_stringshare_del(rtps); + } + else + eina_strbuf_append(buf, "void "); + + eina_strbuf_append(buf, fcn); + eina_stringshare_del(fcn); + + Eina_Bool first = EINA_TRUE; + Eina_Strbuf *flagbuf = NULL; + int nidx = !legacy || !eolian_function_is_class(fid); + + eina_strbuf_append_char(buf, '('); + if (nidx) + { + if ((ftype == EOLIAN_PROP_GET) || eolian_function_object_is_const(fid) + || eolian_function_is_class(fid)) + { + eina_strbuf_append(buf, "const "); + } + if (legacy) + eina_strbuf_append_printf(buf, "%s *obj", cname); + else + eina_strbuf_append(buf, "Eo *obj"); + first = EINA_FALSE; + } + + { + Eolian_Function_Parameter *pr = NULL; + Eina_Iterator *itr = eolian_property_keys_get(fid, ftype); + EINA_ITERATOR_FOREACH(itr, pr) + { + const Eolian_Type *prt = eolian_parameter_type_get(pr); + const char *prn = eolian_parameter_name_get(pr); + Eina_Stringshare *prtn = eolian_type_c_type_get(prt); + ++nidx; + if (!first) + eina_strbuf_append(buf, ", "); + eina_strbuf_append_printf(buf, "%s %s", prtn, prn); + eina_stringshare_del(prtn); + first = EINA_FALSE; + if (!eolian_parameter_is_nonull(pr)) + continue; + if (!flagbuf) + { + flagbuf = eina_strbuf_new(); + eina_strbuf_append_printf(flagbuf, " EINA_ARG_NONNULL(%d", nidx); + } + else + eina_strbuf_append_printf(flagbuf, ", %d", nidx); + } + eina_iterator_free(itr); + } + + if (!var_as_ret) + { + Eina_Iterator *itr = NULL; + if (ftype == EOLIAN_PROP_GET || ftype == EOLIAN_PROP_SET) + itr = eolian_property_values_get(fid, ftype); + else + itr = eolian_function_parameters_get(fid); + + Eolian_Function_Parameter *pr = NULL; + EINA_ITERATOR_FOREACH(itr, pr) + { + const Eolian_Type *prt = eolian_parameter_type_get(pr); + const char *prn = eolian_parameter_name_get(pr); + Eina_Stringshare *prtn = eolian_type_c_type_get(prt); + + ++nidx; + if (!first) + eina_strbuf_append(buf, ", "); + eina_strbuf_append(buf, prtn); + if (!strchr(prtn, '*')) + eina_strbuf_append_char(buf, ' '); + eina_strbuf_append(buf, + _get_add_star(ftype, eolian_parameter_direction_get(pr))); + eina_strbuf_append(buf, prn); + eina_stringshare_del(prtn); + first = EINA_FALSE; + if (!eolian_parameter_is_nonull(pr)) + continue; + if (!flagbuf) + { + flagbuf = eina_strbuf_new(); + eina_strbuf_append_printf(flagbuf, " EINA_ARG_NONNULL(%d", nidx); + } + else + eina_strbuf_append_printf(flagbuf, ", %d", nidx); + } + + eina_iterator_free(itr); + } + + if (flagbuf) + eina_strbuf_append_char(flagbuf, ')'); + + eina_strbuf_append(buf, ")"); + if (eolian_function_return_is_warn_unused(fid, ftype)) + { + if (!flagbuf) + flagbuf = eina_strbuf_new(); + eina_strbuf_prepend(flagbuf, " EINA_WARN_UNUSED_RESULT"); + } + if (flagbuf) + { + eina_strbuf_append(buf, eina_strbuf_string_get(flagbuf)); + eina_strbuf_free(flagbuf); + } + eina_strbuf_append(buf, ";\n"); + + if (eolian_function_is_beta(fid)) + eina_strbuf_append_printf(buf, "#endif\n"); + if (!legacy && (fsc == EOLIAN_SCOPE_PROTECTED)) + eina_strbuf_append_printf(buf, "#endif\n"); +} + +void +eo_gen_header_gen(const Eolian_Class *cl, Eina_Strbuf *buf, Eina_Bool legacy) +{ + if (!cl) + return; + + char *cname = NULL, *cnameu = NULL, *cnamel = NULL; + eo_gen_class_names_get(cl, &cname, &cnameu, &cnamel); + + /* class definition */ + + if (!legacy) + { + const Eolian_Documentation *doc = eolian_class_documentation_get(cl); + if (doc) + { + Eina_Strbuf *cdoc = eo_gen_docs_full_gen(doc, + eolian_class_full_name_get(cl), 0, EINA_FALSE); + if (cdoc) + { + eina_strbuf_append(buf, eina_strbuf_string_get(cdoc)); + eina_strbuf_append_char(buf, '\n'); + eina_strbuf_free(cdoc); + } + } + eina_strbuf_append_printf(buf, "#define %s_%s %s_%s_get()\n\n", + cnameu, _cl_type_str_get(cl, EINA_TRUE), + cnamel, _cl_type_str_get(cl, EINA_FALSE)); + + eina_strbuf_append_printf(buf, "EWAPI const Efl_Class *%s_%s_get(void);\n", + cnamel, _cl_type_str_get(cl, EINA_FALSE)); + } + + /* method section */ + { + Eina_Iterator *itr = eolian_class_implements_get(cl); + if (!itr) + goto events; + + const Eolian_Implement *imp; + EINA_ITERATOR_FOREACH(itr, imp) + { + if (eolian_implement_class_get(imp) != cl) + continue; + Eolian_Function_Type ftype = EOLIAN_UNRESOLVED; + const Eolian_Function *fid = eolian_implement_function_get(imp, &ftype); + /* beta can only exist for eo api */ + if (legacy && eolian_function_is_beta(fid)) + continue; + eina_strbuf_append_char(buf, '\n'); + switch (ftype) + { + case EOLIAN_PROP_GET: + case EOLIAN_PROP_SET: + _gen_func(fid, ftype, buf, cname, cnameu, legacy); + break; + case EOLIAN_PROPERTY: + _gen_func(fid, EOLIAN_PROP_SET, buf, cname, cnameu, legacy); + eina_strbuf_append_char(buf, '\n'); + _gen_func(fid, EOLIAN_PROP_GET, buf, cname, cnameu, legacy); + break; + default: + _gen_func(fid, EOLIAN_UNRESOLVED, buf, cname, cnameu, legacy); + } + } + eina_iterator_free(itr); + } + +events: + /* event section */ + if (!legacy) + { + Eina_Iterator *itr = eolian_class_events_get(cl); + Eolian_Event *ev; + EINA_ITERATOR_FOREACH(itr, ev) + { + Eina_Stringshare *evn = eolian_event_c_name_get(ev); + Eolian_Object_Scope evs = eolian_event_scope_get(ev); + + if (evs == EOLIAN_SCOPE_PRIVATE) + continue; + + if (eolian_event_is_beta(ev)) + { + eina_strbuf_append_printf(buf, "\n#ifdef %s_BETA\n", cnameu); + } + if (evs == EOLIAN_SCOPE_PROTECTED) + { + if (!eolian_event_is_beta(ev)) + eina_strbuf_append_char(buf, '\n'); + eina_strbuf_append_printf(buf, "#ifdef %s_PROTECTED\n", cnameu); + } + + if (!eolian_event_is_beta(ev) && evs == EOLIAN_SCOPE_PUBLIC) + eina_strbuf_append_char(buf, '\n'); + + eina_strbuf_append_printf(buf, "EOAPI extern const " + "Efl_Event_Description _%s;\n\n", evn); + + Eina_Strbuf *evdbuf = eo_gen_docs_event_gen(ev, + eolian_class_full_name_get(cl)); + eina_strbuf_append(buf, eina_strbuf_string_get(evdbuf)); + eina_strbuf_append_char(buf, '\n'); + eina_strbuf_free(evdbuf); + eina_strbuf_append_printf(buf, "#define %s (&(_%s))\n", evn, evn); + + if (evs == EOLIAN_SCOPE_PROTECTED) + eina_strbuf_append(buf, "#endif\n"); + if (eolian_event_is_beta(ev)) + eina_strbuf_append(buf, "#endif\n"); + + eina_stringshare_del(evn); + } + eina_iterator_free(itr); + } + + free(cname); + free(cnameu); + free(cnamel); +} diff --git a/src/bin/eolian/headers.h b/src/bin/eolian/headers.h new file mode 100644 index 0000000000..55b4c071b0 --- /dev/null +++ b/src/bin/eolian/headers.h @@ -0,0 +1,8 @@ +#ifndef EOLIAN_GEN_HEADERS_H +#define EOLIAN_GEN_HEADERS_H + +#include "main.h" + +void eo_gen_header_gen(const Eolian_Class *cl, Eina_Strbuf *buf, Eina_Bool legacy); + +#endif diff --git a/src/bin/eolian/impl_generator.c b/src/bin/eolian/impl_generator.c deleted file mode 100644 index cd161855df..0000000000 --- a/src/bin/eolian/impl_generator.c +++ /dev/null @@ -1,324 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include - -#include "Eolian.h" -#include "impl_generator.h" -#include "common_funcs.h" - -static _eolian_class_vars class_env; - -static Eina_Bool -_params_generate(const Eolian_Function *foo, Eolian_Function_Type ftype, Eina_Bool var_as_ret, Eina_Strbuf *params, Eina_Strbuf *short_params) -{ - Eina_Iterator *itr; - Eolian_Function_Parameter *param; - Eina_Bool is_prop = (ftype == EOLIAN_PROP_GET || ftype == EOLIAN_PROP_SET); - eina_strbuf_reset(params); - eina_strbuf_reset(short_params); - itr = eolian_property_keys_get(foo, ftype); - EINA_ITERATOR_FOREACH(itr, param) - { - const Eolian_Type *ptypet = eolian_parameter_type_get(param); - const char *pname = eolian_parameter_name_get(param); - const char *ptype = eolian_type_c_type_get(ptypet); - Eina_Bool had_star = !!strchr(ptype, '*'); - if (eina_strbuf_length_get(params)) - { - eina_strbuf_append(params, ", "); - eina_strbuf_append(short_params, ", "); - } - eina_strbuf_append_printf(params, "%s%s%s", - ptype, had_star?"":" ", pname); - eina_strbuf_append_printf(short_params, "%s", pname); - eina_stringshare_del(ptype); - } - eina_iterator_free(itr); - if (!var_as_ret) - { - itr = is_prop ? eolian_property_values_get(foo, ftype) : eolian_function_parameters_get(foo); - EINA_ITERATOR_FOREACH(itr, param) - { - const Eolian_Type *ptypet = eolian_parameter_type_get(param); - const char *pname = eolian_parameter_name_get(param); - const char *ptype = eolian_type_c_type_get(ptypet); - Eolian_Parameter_Dir pdir = eolian_parameter_direction_get(param); - const char *add_star = _get_add_star(ftype, pdir); - Eina_Bool had_star = !!strchr(ptype, '*'); - if (eina_strbuf_length_get(params)) - { - eina_strbuf_append(params, ", "); - eina_strbuf_append(short_params, ", "); - } - eina_strbuf_append_printf(params, "%s%s%s%s", - ptype, had_star?"":" ", add_star, pname); - eina_strbuf_append_printf(short_params, "%s", pname); - eina_stringshare_del(ptype); - } - eina_iterator_free(itr); - } - return EINA_TRUE; -} - -static Eina_Bool -_function_exists(const char* func_name, Eina_Strbuf *buffer) -{ - const char *ptr = eina_strbuf_string_get(buffer); - int func_len = strlen(func_name); - while ((ptr = strstr(ptr, func_name)) != NULL) - { - switch (*(ptr - 1)) - { - case '\n': case ' ': - { - switch (*(ptr + func_len)) - { - case ' ': case '(': - return EINA_TRUE; - } - } - } - ptr++; /* so strstr doesn't fall again on func_name */ - } - return EINA_FALSE; -} - -/* Check if the type is used in the file, not if it is a typedef... */ -static Eina_Bool -_type_exists(const char* type_name, Eina_Strbuf *buffer) -{ - const char *ptr = eina_strbuf_string_get(buffer); - int type_len = strlen(type_name); - while ((ptr = strstr(ptr, type_name)) != NULL) - { - switch (*(ptr - 1)) - { - case '\n': case ' ': case ',': - { - switch (*(ptr + type_len)) - { - case '\n': case ' ': case ',': case ';': - return EINA_TRUE; - } - } - } - ptr++; /* so strstr doesn't fall again on type_name */ - } - return EINA_FALSE; -} - -static Eina_Bool -_prototype_generate(const Eolian_Function *foo, Eolian_Function_Type ftype, Eina_Strbuf *data_type_buf, Eolian_Implement *impl_desc, Eina_Strbuf *buffer) -{ - Eina_Bool var_as_ret = EINA_FALSE; - Eina_Strbuf *params = NULL, *short_params = NULL, *super_invok = NULL; - char func_name[PATH_MAX]; - char impl_name[PATH_MAX]; - const char *fname; - size_t flen; - _eolian_class_vars impl_env; - - if (!impl_desc && eolian_function_is_virtual_pure(foo, ftype)) return EINA_TRUE; - - super_invok = eina_strbuf_new(); - if (impl_desc) - { - _class_env_create(eolian_implement_class_get(impl_desc), NULL, &impl_env); - char *tmp = impl_name; - sprintf(impl_name, "%s_%s", class_env.full_classname, impl_env.full_classname); - eina_str_tolower(&tmp); - } - - sprintf(func_name, "_%s_%s%s", - impl_desc?impl_name:class_env.lower_classname, eolian_function_name_get(foo), - ftype == EOLIAN_PROP_GET?"_get": (ftype == EOLIAN_PROP_SET?"_set":"")); - - if (_function_exists(func_name, buffer)) goto end; - - printf("Generation of function %s\n", func_name); - const Eolian_Type *rettypet = eolian_function_return_type_get(foo, ftype); - if (ftype == EOLIAN_PROP_GET && !rettypet) - { - Eina_Iterator *itr = eolian_property_values_get(foo, ftype); - void *data, *data2; - /* We want to check if there is only one parameter */ - if (eina_iterator_next(itr, &data) && !eina_iterator_next(itr, &data2)) - { - Eolian_Function_Parameter *param = data; - rettypet = eolian_parameter_type_get(param); - var_as_ret = EINA_TRUE; - } - eina_iterator_free(itr); - } - - params = eina_strbuf_new(); - short_params = eina_strbuf_new(); - _params_generate(foo, ftype, var_as_ret, params, short_params); - if (eina_strbuf_length_get(params)) - eina_strbuf_prepend_printf(params, ", "); - if (eina_strbuf_length_get(short_params)) - eina_strbuf_prepend_printf(short_params, ", "); - - fname = eolian_function_name_get(foo); - if (fname) - { - flen = strlen(fname); - if (flen >= strlen("destructor")) - { - if (impl_desc && - (!strcmp(fname + flen - strlen("destructor"), "destructor"))) - { - eina_strbuf_append_printf - (super_invok, - " %s_%s(efl_super(obj, %s_%s)%s);\n", - impl_env.lower_eo_prefix, eolian_function_name_get(foo), - class_env.upper_eo_prefix, class_env.upper_classtype, - eina_strbuf_string_get(short_params)); - } - } - } - - const char *rettype = NULL; - if (rettypet) rettype = eolian_type_c_type_get(rettypet); - - eina_strbuf_append_printf(buffer, - "EOLIAN static %s\n%s(%sEo *obj, %s *pd%s%s)\n{\n%s\n}\n\n", - !rettype?"void":rettype, - func_name, - eolian_function_object_is_const(foo)?"const ":"", - !eina_strbuf_length_get(data_type_buf) ? "void" : eina_strbuf_string_get(data_type_buf), - !eina_strbuf_length_get(data_type_buf) ? " EINA_UNUSED" : "", - eina_strbuf_string_get(params), - eina_strbuf_string_get(super_invok) - ); - - if (rettype) eina_stringshare_del(rettype); - -end: - eina_strbuf_free(short_params); - eina_strbuf_free(params); - eina_strbuf_free(super_invok); - return EINA_TRUE; -} - -Eina_Bool -impl_source_generate(const Eolian_Class *class, Eina_Strbuf *buffer) -{ - Eina_Bool ret = EINA_FALSE; - Eina_Strbuf *data_type_buf = eina_strbuf_new(); - Eina_Iterator *itr; - const Eolian_Function *foo; - Eina_Strbuf *begin = eina_strbuf_new(); - char core_incl[PATH_MAX]; - - _class_env_create(class, NULL, &class_env); - - if (!_type_exists("EFL_BETA_API_SUPPORT", buffer)) - { - printf("Generation of EFL_BETA_API_SUPPORT\n"); - eina_strbuf_append_printf(begin, "#define EFL_BETA_API_SUPPORT\n"); - } - - if (!_type_exists("", buffer)) - { - printf("Generation of #include and \"%s.eo.h\"\n", class_env.lower_classname); - eina_strbuf_append_printf(begin, "#include \n#include \"%s.eo.h\"\n\n", class_env.lower_classname); - } - - /* Little calculation of the prefix of the data */ - const char *data_type = eolian_class_data_type_get(class); - if (data_type) - { - if (strcmp(data_type, "null")) - eina_strbuf_append_printf(data_type_buf, "%s", data_type); - } - else - eina_strbuf_append_printf(data_type_buf, "%s_Data", class_env.full_classname); - - /* Definition of the structure */ - const char *data_type_str = eina_strbuf_string_get(data_type_buf); - if (!_type_exists(data_type_str, buffer) && 0 != eina_strbuf_length_get(data_type_buf)) - { - printf("Generation of type %s\n", data_type_str); - eina_strbuf_append_printf(begin, "typedef struct\n{\n\n} %s;\n\n", data_type_str); - } - - if (eina_strbuf_length_get(begin)) - eina_strbuf_prepend_printf(buffer, "%s", eina_strbuf_string_get(begin)); - eina_strbuf_free(begin); - - itr = eolian_class_implements_get(class); - if (itr) - { - Eolian_Implement *impl_desc; - const char *names[] = { "", "getter ", "setter " }; - EINA_ITERATOR_FOREACH(itr, impl_desc) - { - Eolian_Function_Type ftype; - Eolian_Implement *idesc = (eolian_implement_class_get(impl_desc) == class) ? NULL : impl_desc; - if (!(foo = eolian_implement_function_get(impl_desc, &ftype))) - { - const char *name = names[eolian_implement_is_prop_get(impl_desc) - | (eolian_implement_is_prop_set(impl_desc) << 1)]; - fprintf(stderr, "eolian: failed to generate implementation of '%s%s' - missing from class\n", - name, eolian_implement_full_name_get(impl_desc)); - goto end; - } - switch (ftype) - { - case EOLIAN_PROP_SET: case EOLIAN_PROP_GET: - _prototype_generate(foo, ftype, data_type_buf, idesc, buffer); - break; - case EOLIAN_PROPERTY: - _prototype_generate(foo, EOLIAN_PROP_SET, data_type_buf, idesc, buffer); - _prototype_generate(foo, EOLIAN_PROP_GET, data_type_buf, idesc, buffer); - break; - default: - _prototype_generate(foo, eolian_function_type_get(foo), data_type_buf, idesc, buffer); - break; - } - } - eina_iterator_free(itr); - } - - if (eolian_class_ctor_enable_get(class)) - { - char func_name[100]; - sprintf(func_name, "_%s_class_constructor", class_env.lower_classname); - if (!_function_exists(func_name, buffer)) - { - printf("Generation of function %s\n", func_name); - eina_strbuf_append_printf(buffer, - "EOLIAN static void\n_%s_class_constructor(Efl_Class *klass)\n{\n\n}\n\n", - class_env.lower_classname); - } - } - - if (eolian_class_dtor_enable_get(class)) - { - char func_name[100]; - sprintf(func_name, "_%s_class_destructor", class_env.lower_classname); - if (!_function_exists(func_name, buffer)) - { - printf("Generation of function %s\n", func_name); - eina_strbuf_append_printf(buffer, "EOLIAN static void\n_%s_class_destructor(Efl_Class *klass)\n{\n\n}\n\n", - class_env.lower_classname); - } - } - printf("Removal of all inline instances of #include \"%s.eo.c\"\n", class_env.lower_classname); - snprintf(core_incl, sizeof(core_incl), "\n#include \"%s.eo.c\"\n", class_env.lower_classname); - eina_strbuf_replace_all(buffer, core_incl, "\n"); - - snprintf(core_incl, sizeof(core_incl), "\"%s.eo.c\"", class_env.lower_classname); - printf("Generation of #include \"%s.eo.c\"\n", class_env.lower_classname); - eina_strbuf_append_printf(buffer, "#include \"%s.eo.c\"\n", class_env.lower_classname); - - ret = EINA_TRUE; -end: - eina_strbuf_free(data_type_buf); - return ret; -} - diff --git a/src/bin/eolian/impl_generator.h b/src/bin/eolian/impl_generator.h deleted file mode 100644 index a4686e2b9e..0000000000 --- a/src/bin/eolian/impl_generator.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef IMPL_GENERATOR_H -#define IMPL_GENERATOR_H - -#include - -/* - * @brief Generate the implementation source code of a class - * - * This function generates all the source code of a class. - * - * @param[in] classname class name - * @param[inout] buf buffer to fill - * - * @return EINA_TRUE on success, EINA_FALSE on error. - * - */ -Eina_Bool -impl_source_generate(const Eolian_Class *class, Eina_Strbuf *buf); - -#endif - - diff --git a/src/bin/eolian/legacy_generator.c b/src/bin/eolian/legacy_generator.c deleted file mode 100644 index cf913435b3..0000000000 --- a/src/bin/eolian/legacy_generator.c +++ /dev/null @@ -1,416 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include - -#include "Eolian.h" - -#include "legacy_generator.h" -#include "docs_generator.h" -#include "common_funcs.h" - -static _eolian_class_vars class_env; - -static const char -tmpl_eapi_funcdef[] = "EAPI @#type_return%s(@#params)@#flags;\n"; - -/*@#CLASS_CHECK(obj) @#check_ret;\n\*/ -static const char -tmpl_eapi_body[] ="\ -\n\ -EAPI @#ret_type\n\ -@#eapi_func(@#full_params)\n\ -{\n\ - return @#eo_func(@#eo_obj@#eo_params);\n\ -}\n\ -"; -static const char -tmpl_eapi_body_void[] ="\ -\n\ -EAPI void\n\ -@#eapi_func(@#full_params)\n\ -{\n\ - @#eo_func(@#eo_obj@#eo_params);\n\ -}\n\ -"; - -static void -_eapi_decl_func_generate(const Eolian_Class *class, const Eolian_Function *funcid, Eolian_Function_Type ftype, Eina_Strbuf *buf) -{ - _eolian_class_func_vars func_env; - const char *funcname = eolian_function_name_get(funcid); - const Eolian_Type *rettypet = NULL; - const char *rettype = NULL; - Eina_Bool var_as_ret = EINA_FALSE; - Eina_Bool is_prop = (ftype == EOLIAN_PROP_GET || ftype == EOLIAN_PROP_SET); - Eina_Iterator *itr; - void *data, *data2; - Eina_Strbuf *flags = NULL; - int leg_param_idx = 1; /* Index of the parameter inside the legacy function. It begins from 1 since obj is the first. */ - - Eina_Strbuf *fbody = eina_strbuf_new(); - Eina_Strbuf *fparam = eina_strbuf_new(); - - _class_func_env_create(class, funcname, ftype, &func_env); - rettypet = eolian_function_return_type_get(funcid, ftype); - if (ftype == EOLIAN_PROP_GET) - { - if (!rettypet) - { - itr = eolian_property_values_get(funcid, ftype); - /* We want to check if there is only one parameter */ - if (eina_iterator_next(itr, &data) && !eina_iterator_next(itr, &data2)) - { - rettypet = eolian_parameter_type_get((Eolian_Function_Parameter*)data); - var_as_ret = EINA_TRUE; - } - eina_iterator_free(itr); - } - } - - if (func_env.legacy_func[0] == '\0') goto end; - - Eina_Bool hasnewdocs = eolian_function_documentation_get(funcid, EOLIAN_UNRESOLVED) || - eolian_function_documentation_get(funcid, ftype); - if (hasnewdocs) - { - Eina_Strbuf *dbuf = docs_generate_function(funcid, ftype, 0, EINA_TRUE); - eina_strbuf_append_char(fbody, '\n'); - eina_strbuf_append(fbody, eina_strbuf_string_get(dbuf)); - eina_strbuf_append_char(fbody, '\n'); - eina_strbuf_free(dbuf); - } - - eina_strbuf_append_printf(fbody, tmpl_eapi_funcdef, func_env.legacy_func); - - if (!eolian_function_is_class(funcid)) - { - if (ftype == EOLIAN_PROP_GET || eolian_function_object_is_const(funcid)) - eina_strbuf_append(fparam, "const "); - eina_strbuf_append_printf(fparam, "%s *obj", class_env.full_classname); - } - - itr = eolian_property_keys_get(funcid, ftype); - EINA_ITERATOR_FOREACH(itr, data) - { - Eolian_Function_Parameter *param = data; - const Eolian_Type *ptypet = eolian_parameter_type_get(param); - const char *pname = eolian_parameter_name_get(param); - const char *ptype = eolian_type_c_type_get(ptypet); - leg_param_idx++; - if (eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, ", "); - eina_strbuf_append_printf(fparam, "%s %s", ptype, pname); - eina_stringshare_del(ptype); - - if (eolian_parameter_is_nonull((Eolian_Function_Parameter*)data)) - { - if (!flags) - { - flags = eina_strbuf_new(); - eina_strbuf_append_printf(flags, " EINA_ARG_NONNULL(%d", leg_param_idx); - } - else - eina_strbuf_append_printf(flags, ", %d", leg_param_idx); - } - } - eina_iterator_free(itr); - if (!var_as_ret) - { - itr = is_prop ? eolian_property_values_get(funcid, ftype) : eolian_function_parameters_get(funcid); - EINA_ITERATOR_FOREACH(itr, data) - { - Eolian_Function_Parameter *param = data; - const Eolian_Type *ptypet = eolian_parameter_type_get(param); - const char *pname = eolian_parameter_name_get(param); - const char *ptype = eolian_type_c_type_get(ptypet); - Eolian_Parameter_Dir pdir = eolian_parameter_direction_get(param); - Eina_Bool had_star = !!strchr(ptype, '*'); - - leg_param_idx++; - if (eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, ", "); - eina_strbuf_append_printf(fparam, "%s%s%s%s", - ptype, had_star?"":" ", _get_add_star(ftype, pdir), pname); - eina_stringshare_del(ptype); - if (eolian_parameter_is_nonull((Eolian_Function_Parameter*)data)) - { - if (!flags) - { - flags = eina_strbuf_new(); - eina_strbuf_append_printf(flags, " EINA_ARG_NONNULL(%d", leg_param_idx); - } - else - eina_strbuf_append_printf(flags, ", %d", leg_param_idx); - } - } - eina_iterator_free(itr); - } - if (!eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, "void"); - if (flags) eina_strbuf_append_printf(flags, ")"); - - if (rettypet) rettype = eolian_type_c_type_get(rettypet); - - eina_strbuf_replace_all(fbody, "@#params", eina_strbuf_string_get(fparam)); - eina_strbuf_reset(fparam); - eina_strbuf_append_printf(fparam, "%s%s", - rettype ? rettype : "void", - rettype && strchr(rettype, '*')?"":" "); - eina_strbuf_replace_all(fbody, "@#type_return", eina_strbuf_string_get(fparam)); - if (eolian_function_return_is_warn_unused(funcid, ftype)) - { - Eina_Bool no_nonull = !flags; - if (no_nonull) flags = eina_strbuf_new(); - eina_strbuf_prepend(flags, " EINA_WARN_UNUSED_RESULT"); - } - if (flags) - eina_strbuf_replace_all(fbody, "@#flags", eina_strbuf_string_get(flags)); - eina_strbuf_replace_all(fbody, "@#flags", (eolian_function_return_is_warn_unused(funcid, ftype)) ? " EINA_WARN_UNUSED_RESULT" : ""); - eina_strbuf_append(buf, eina_strbuf_string_get(fbody)); - - if (rettype) eina_stringshare_del(rettype); - -end: - eina_strbuf_free(flags); - eina_strbuf_free(fbody); - eina_strbuf_free(fparam); -} - -static void -_eapi_func_generate(const Eolian_Class *class, const Eolian_Function *funcid, Eolian_Function_Type ftype, Eina_Strbuf *buf) -{ - _eolian_class_func_vars func_env; - char tmpstr[0xFF]; - Eina_Bool var_as_ret = EINA_FALSE; - const Eolian_Type *rettypet = NULL; - const char *rettype = NULL; - const char *retname = NULL; - Eina_Bool ret_is_void = EINA_FALSE; - Eina_Bool is_prop = (ftype == EOLIAN_PROP_GET || ftype == EOLIAN_PROP_SET); - - Eina_Strbuf *fbody = eina_strbuf_new(); - Eina_Strbuf *fparam = eina_strbuf_new(); - Eina_Strbuf *eoparam = eina_strbuf_new(); - - Eina_Iterator *itr; - void *data, *data2; - - _class_func_env_create(class, eolian_function_name_get(funcid), ftype, &func_env); - rettypet = eolian_function_return_type_get(funcid, ftype); - if (rettypet) rettype = eolian_type_c_type_get(rettypet); - if (rettype && !strcmp(rettype, "void")) ret_is_void = EINA_TRUE; - retname = "ret"; - if (ftype == EOLIAN_PROP_GET) - { - if (!rettypet) - { - itr = eolian_property_values_get(funcid, ftype); - /* We want to check if there is only one parameter */ - if (eina_iterator_next(itr, &data) && !eina_iterator_next(itr, &data2)) - { - Eolian_Function_Parameter *param = data; - rettypet = eolian_parameter_type_get(param); - retname = eolian_parameter_name_get(param); - var_as_ret = EINA_TRUE; - } - eina_iterator_free(itr); - } - } - - if (func_env.legacy_func[0] == '\0') goto end; - - if (!rettype && rettypet) rettype = eolian_type_c_type_get(rettypet); - - if (rettype && (!ret_is_void)) - eina_strbuf_append(fbody, tmpl_eapi_body); - else - eina_strbuf_append(fbody, tmpl_eapi_body_void); - - if (!eolian_function_is_class(funcid)) - { - if (ftype == EOLIAN_PROP_GET || eolian_function_object_is_const(funcid)) - eina_strbuf_append(fparam, "const "); - eina_strbuf_append_printf(fparam, "%s *obj", class_env.full_classname); - char cbuf[256]; - snprintf(cbuf, sizeof(cbuf), "(%s *)obj", class_env.full_classname); - eina_strbuf_replace_all(fbody, "@#eo_obj", cbuf); - } - else - { - Eina_Strbuf *class_buf = eina_strbuf_new(); - _template_fill(class_buf, "@#CLASS_@#CLASSTYPE", class, NULL, NULL, EINA_TRUE); - eina_strbuf_replace_all(fbody, "@#eo_obj", eina_strbuf_string_get(class_buf)); - eina_strbuf_free(class_buf); - } - eina_strbuf_replace_all(fbody, "@#eapi_func", func_env.legacy_func); - eina_strbuf_replace_all(fbody, "@#eo_func", func_env.lower_eo_func); - - tmpstr[0] = '\0'; - - itr = eolian_property_keys_get(funcid, ftype); - EINA_ITERATOR_FOREACH(itr, data) - { - Eolian_Function_Parameter *param = data; - const Eolian_Type *ptypet = eolian_parameter_type_get(param); - const char *pname = eolian_parameter_name_get(param); - const char *ptype = eolian_type_c_type_get(ptypet); - if (eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, ", "); - eina_strbuf_append_printf(fparam, "%s %s", ptype, pname); - eina_stringshare_del(ptype); - eina_strbuf_append_printf(eoparam, ", %s", pname); - } - eina_iterator_free(itr); - if (!var_as_ret) - { - itr = is_prop ? eolian_property_values_get(funcid, ftype) : eolian_function_parameters_get(funcid); - EINA_ITERATOR_FOREACH(itr, data) - { - Eolian_Function_Parameter *param = data; - const Eolian_Type *ptypet = eolian_parameter_type_get(param); - const char *pname = eolian_parameter_name_get(param); - const char *ptype = eolian_type_c_type_get(ptypet); - Eolian_Parameter_Dir pdir = eolian_parameter_direction_get(param); - Eina_Bool had_star = !!strchr(ptype, '*'); - if (eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, ", "); - eina_strbuf_append_printf(fparam, "%s%s%s%s", - ptype, had_star?"":" ", _get_add_star(ftype, pdir), pname); - eina_stringshare_del(ptype); - eina_strbuf_append_printf(eoparam, ", %s", pname); - } - eina_iterator_free(itr); - } - if (!eina_strbuf_length_get(fparam)) eina_strbuf_append(fparam, "void"); - - if (rettype && (!ret_is_void)) - { - char tmp_ret_str[0xFF]; - sprintf (tmp_ret_str, "%s", rettype); - const Eolian_Expression *default_ret_val = - eolian_function_return_default_value_get(funcid, ftype); - const char *val_str = NULL; - if (default_ret_val) - { - Eolian_Value val = eolian_expression_eval_type - (default_ret_val, rettypet); - if (val.type) - val_str = eolian_expression_value_to_literal(&val); - } - Eina_Bool had_star = !!strchr(rettype, '*'); - sprintf (tmpstr, " %s%s%s = %s;\n", - rettype, had_star?"":" ", retname, - val_str?val_str:"0"); - - eina_strbuf_replace_all(fbody, "@#ret_type", tmp_ret_str); - eina_strbuf_replace_all(fbody, "@#ret_init_val", tmpstr); - } - - eina_strbuf_replace_all(fbody, "@#full_params", eina_strbuf_string_get(fparam)); - eina_strbuf_replace_all(fbody, "@#eo_params", eina_strbuf_string_get(eoparam)); - - eina_strbuf_replace_all(fbody, "@#ret_val", (rettype && !ret_is_void) ? retname : ""); - - eina_strbuf_append(buf, eina_strbuf_string_get(fbody)); - - if (rettype) eina_stringshare_del(rettype); - -end: - eina_strbuf_free(fbody); - eina_strbuf_free(fparam); - eina_strbuf_free(eoparam); -} - -Eina_Bool -legacy_header_generate(const Eolian_Class *class, Eina_Strbuf *buf) -{ - _class_env_create(class, NULL, &class_env); - - const Eolian_Documentation *doc = eolian_class_documentation_get(class); - if (doc) - { - Eina_Strbuf *cdoc = docs_generate_full(doc, eolian_class_full_name_get(class), 0, EINA_TRUE); - if (cdoc) - { - eina_strbuf_append(buf, eina_strbuf_string_get(cdoc)); - eina_strbuf_append_char(buf, '\n'); - eina_strbuf_free(cdoc); - } - } - - Eina_Iterator *itr = eolian_class_implements_get(class); - if (itr) - { - const Eolian_Implement *impl; - EINA_ITERATOR_FOREACH(itr, impl) - { - if (eolian_implement_class_get(impl) != class) - continue; - Eolian_Function_Type ftype = EOLIAN_UNRESOLVED; - const Eolian_Function *fid = eolian_implement_function_get(impl, &ftype); - if (eolian_function_is_beta(fid)) - continue; - switch (ftype) - { - case EOLIAN_PROP_GET: case EOLIAN_PROP_SET: - _eapi_decl_func_generate(class, fid, ftype, buf); - break; - case EOLIAN_PROPERTY: - _eapi_decl_func_generate(class, fid, EOLIAN_PROP_SET, buf); - _eapi_decl_func_generate(class, fid, EOLIAN_PROP_GET, buf); - break; - default: - _eapi_decl_func_generate(class, fid, EOLIAN_METHOD, buf); - break; - } - } - eina_iterator_free(itr); - } - return EINA_TRUE; -} - -Eina_Bool -legacy_source_generate(const Eolian_Class *class, Eina_Strbuf *buf) -{ - Eina_Bool ret = EINA_FALSE; - Eina_Iterator *itr; - - _class_env_create(class, NULL, &class_env); - - Eina_Strbuf *tmpbuf = eina_strbuf_new(); - Eina_Strbuf *str_bodyf = eina_strbuf_new(); - - if ((itr = eolian_class_implements_get(class))) - { - const Eolian_Implement *impl; - EINA_ITERATOR_FOREACH(itr, impl) - { - if (eolian_implement_class_get(impl) != class) - continue; - Eolian_Function_Type ftype = EOLIAN_UNRESOLVED; - const Eolian_Function *fid = eolian_implement_function_get(impl, &ftype); - if (eolian_function_is_beta(fid)) - continue; - switch (ftype) - { - case EOLIAN_PROP_GET: case EOLIAN_PROP_SET: - _eapi_func_generate(class, fid, ftype, str_bodyf); - break; - case EOLIAN_PROPERTY: - _eapi_func_generate(class, fid, EOLIAN_PROP_SET, str_bodyf); - _eapi_func_generate(class, fid, EOLIAN_PROP_GET, str_bodyf); - break; - default: - _eapi_func_generate(class, fid, EOLIAN_METHOD, str_bodyf); - break; - } - } - eina_iterator_free(itr); - } - - eina_strbuf_append(buf, eina_strbuf_string_get(str_bodyf)); - - ret = EINA_TRUE; - eina_strbuf_free(tmpbuf); - eina_strbuf_free(str_bodyf); - - return ret; -} diff --git a/src/bin/eolian/legacy_generator.h b/src/bin/eolian/legacy_generator.h deleted file mode 100644 index 0a69c96984..0000000000 --- a/src/bin/eolian/legacy_generator.h +++ /dev/null @@ -1,36 +0,0 @@ -#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[inout] buf buffer to fill - * - * @return EINA_TRUE on success, EINA_FALSE on error. - * - */ -Eina_Bool legacy_header_generate(const Eolian_Class *class, Eina_Strbuf *buf); - -/* - * @brief Generate C source code for Eo class - * - * This function needs to be used to generate C source code. It is generating - * code from scratch. - * - * @param[in] classname class name - * @param[inout] buf buffer to fill - * - * @return EINA_TRUE on success, EINA_FALSE on error. - * - */ -Eina_Bool legacy_source_generate(const Eolian_Class *class, Eina_Strbuf *buf); - -#endif - diff --git a/src/bin/eolian/main.c b/src/bin/eolian/main.c index 55c9399937..dbde5bc144 100644 --- a/src/bin/eolian/main.c +++ b/src/bin/eolian/main.c @@ -1,169 +1,307 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include +#include +#include #include -#include +#include "main.h" +#include "types.h" +#include "headers.h" +#include "sources.h" -#include "Eolian.h" -#include "legacy_generator.h" -#include "eo_generator.h" -#include "impl_generator.h" -#include "types_generator.h" -#include "common_funcs.h" +int _eolian_gen_log_dom = -1; -static Eina_Strbuf * -_include_guard_enclose(const char *fname, const char *suffix, Eina_Strbuf *fbody) +enum { - if (!fbody || !eina_strbuf_string_get(fbody)) - return fbody; + GEN_H = 1 << 0, + GEN_H_LEGACY = 1 << 1, + GEN_H_STUB = 1 << 2, + GEN_C = 1 << 3, + GEN_C_IMPL = 1 << 4 +}; - if (!suffix) - suffix = ""; +static const char *_dexts[5] = +{ + ".h", ".legacy.h", ".stub.h", ".c", ".c" +}; - char incname[255]; - memset(incname, 0, sizeof(incname)); - strncpy (incname, fname, sizeof(incname) - 1); - char *p = incname; - eina_str_toupper(&p); - - Eina_Strbuf *incguard = eina_strbuf_new(); - eina_strbuf_append_printf(incguard, "#ifndef _%s_%s\n#define _%s_%s\n\n", - incname, suffix, incname, suffix); - eina_strbuf_replace_all(incguard, ".", "_"); - eina_strbuf_append(incguard, eina_strbuf_string_get(fbody)); - eina_strbuf_append(incguard, "\n#endif\n"); - eina_strbuf_free(fbody); - return incguard; +static int +_get_bit_pos(int flag) +{ + int pos = 0; + for (; !(flag & 1); flag >>= 1) + ++pos; + return pos; } -static const char * -_filename_get(const char *path) +static void +_print_usage(const char *progn, FILE *outf) { - if (!path) - return NULL; - const char *ret = strrchr(path, '/'); - if (!ret) - return path; - return ret + 1; + fprintf(outf, "Usage: %s [options] [input]\n", progn); + fprintf(outf, "Options:\n" + " -I inc include path \"inc\"\n" + " -g type generate file of type \"type\"\n" + " -o name specify the base name for output\n" + " -o type:name specify a particular output filename\n" + " -h print this message and exit\n" + " -v print version and exit\n" + "\n" + "Available types:\n" + " h: C header file (.h)\n" + " l: Legacy C header file (.legacy.h)\n" + " s: Stub C header file (.stub.h)\n" + " c: C source file (.c)\n" + " i: Implementation file (added into .c)\n" + "\n" + "By default, the 'hc' set is used ('h' for .eot files).\n" + "Output filenames are determined from input .eo filename.\n" + "Default filenames include input extension. (e.g. \".eo.c\")\n"); +} + +static void +_print_version(FILE *outf) +{ + fprintf(outf, "Eolian C generator version: " PACKAGE_VERSION "\n"); } static Eina_Bool -_read_file(const char *filename, Eina_Strbuf **buf) +_try_set_out(char t, char **outs, const char *val) { - FILE *fd = fopen(filename, "rb"); - if (!fd) + int pos = -1; + switch (t) + { + case 'h': + pos = _get_bit_pos(GEN_H); + break; + case 'l': + pos = _get_bit_pos(GEN_H_LEGACY); + break; + case 's': + pos = _get_bit_pos(GEN_H_STUB); + break; + case 'c': + pos = _get_bit_pos(GEN_C); + break; + case 'i': + pos = _get_bit_pos(GEN_C_IMPL); + break; + } + if (pos < 0) + return EINA_FALSE; + if (outs[pos]) + free(outs[pos]); + outs[pos] = strdup(val); + return EINA_TRUE; +} + +static void _fill_all_outs(char **outs, const char *val) +{ + size_t vlen = strlen(val); + for (size_t i = 0; i < (sizeof(_dexts) / sizeof(char *)); ++i) + { + if (outs[i]) + continue; + size_t dlen = strlen(_dexts[i]); + char *str = malloc(vlen + dlen + 1); + memcpy(str, val, vlen); + memcpy(str + vlen, _dexts[i], dlen); + str[vlen + dlen] = '\0'; + outs[i] = str; + } +} + +static Eina_Strbuf * +_include_guard(const char *fname, const char *gname, Eina_Strbuf *buf) +{ + if (!buf) + return NULL; + + if (!gname) + gname = ""; + + char iname[256] = {0}; + strncpy(iname, fname, sizeof(iname) - 1); + char *inamep = iname; + eina_str_toupper(&inamep); + + Eina_Strbuf *g = eina_strbuf_new(); + eina_strbuf_append_printf(g, "#ifndef _%s_%s\n", iname, gname); + eina_strbuf_append_printf(g, "#define _%s_%s\n\n", iname, gname); + + eina_strbuf_replace_all(g, ".", "_"); + eina_strbuf_append(g, eina_strbuf_string_get(buf)); + eina_strbuf_append(g, "\n#endif\n"); + eina_strbuf_free(buf); + return g; +} + +static const char * +_get_filename(const char *path) +{ + if (!path) + return NULL; + const char *ret1 = strrchr(path, '/'); + const char *ret2 = strrchr(path, '\\'); + if (!ret1 && !ret2) + return path; + if (ret1 && ret2) + { + if (ret1 > ret2) + return ret1 + 1; + else + return ret2 + 1; + } + if (ret1) + return ret1 + 1; + return ret2 + 1; +} + +static Eina_Bool +_write_file(const char *fname, const Eina_Strbuf *buf) +{ + FILE *f = fopen(fname, "wb"); + if (!f) + { + fprintf(stderr, "eolian: could not open '%s' (%s)\n", + fname, strerror(errno)); + return EINA_FALSE; + } + + Eina_Bool fret = EINA_TRUE; + + size_t bl = eina_strbuf_length_get(buf); + if (!bl) + goto end; + + if (fwrite(eina_strbuf_string_get(buf), 1, bl, f) != bl) + { + fprintf(stderr, "eolian: could not write '%s' (%s)\n", + fname, strerror(errno)); + fret = EINA_FALSE; + } + +end: + fclose(f); + return fret; +} + +static Eina_Bool +_read_file(const char *fname, Eina_Strbuf **buf) +{ + FILE *f = fopen(fname, "rb"); + if (!f) { *buf = eina_strbuf_new(); return EINA_TRUE; } - fseek(fd, 0, SEEK_END); - long file_size = ftell(fd); - if (file_size < 0) + fseek(f, 0, SEEK_END); + long fs = ftell(f); + if (fs < 0) { - fprintf(stderr, "eolian: could not get length of '%s'\n", filename); - fclose(fd); + fprintf(stderr, "eolian: could not get length of '%s'\n", fname); + fclose(f); return EINA_FALSE; } - fseek(fd, 0, SEEK_SET); + fseek(f, 0, SEEK_SET); - char *content = malloc(file_size + 1); - if (!content) + char *cont = malloc(fs + 1); + if (!cont) { - fprintf(stderr, "eolian: could not allocate memory for '%s'\n", filename); - fclose(fd); + fprintf(stderr, "eolian: could not allocate memory for '%s'\n", fname); + fclose(f); return EINA_FALSE; } - long actual_size = (long)fread(content, 1, file_size, fd); - if (actual_size != file_size) + long as = fread(cont, 1, fs, f); + if (as != fs) { - fprintf(stderr, "eolian: could not read %ld bytes from '%s' (read %ld bytes)\n", - file_size, filename, actual_size); - free(content); - fclose(fd); + fprintf(stderr, "eolian: could not read %ld bytes from '%s' (got %ld)\n", + fs, fname, as); + free(cont); + fclose(f); return EINA_FALSE; } - content[file_size] = '\0'; - fclose(fd); - *buf = eina_strbuf_manage_new_length(content, file_size); + cont[fs] = '\0'; + fclose(f); + *buf = eina_strbuf_manage_new_length(cont, fs); return EINA_TRUE; } -static Eina_Bool -_write_file(const char *filename, const Eina_Strbuf *buffer, Eina_Bool append) +char *eo_gen_c_full_name_get(const char *nm) { - FILE *fd = fopen(filename, append ? "ab" : "wb"); - if (!fd) + if (!nm) + return NULL; + char *buf = strdup(nm); + if (!buf) + abort(); + for (char *p = strchr(buf, '.'); p; p = strchr(p, '.')) + *p = '_'; + return buf; +} + +void eo_gen_class_names_get(const Eolian_Class *cl, char **cname, + char **cnameu, char **cnamel) +{ + char *cn = NULL, *cnu = NULL, *cnl = NULL; + cn = eo_gen_c_full_name_get(eolian_class_full_name_get(cl)); + if (!cn) + abort(); + if (cname) + *cname = cn; + + if (cnameu) { - fprintf(stderr, "eolian: could not open '%s' for writing (%s)\n", - filename, strerror(errno)); - return EINA_FALSE; + cnu = strdup(cn); + if (!cnu) + { + free(cn); + abort(); + } + eina_str_toupper(&cnu); + *cnameu = cnu; } - Eina_Bool ret = EINA_TRUE; - size_t blen = eina_strbuf_length_get(buffer); - - if (!blen) - goto end; - - if (fwrite(eina_strbuf_string_get(buffer), 1, blen, fd) != blen) + if (cnamel) { - fprintf(stderr, "eolian: could not write '%s' (%s)\n", - filename, strerror(errno)); - ret = EINA_FALSE; + cnl = strdup(cn); + if (!cnl) + { + free(cn); + free(cnu); + abort(); + } + eina_str_tolower(&cnl); + *cnamel = cnl; } -end: - fclose(fd); - return ret; + if (!cname) + free(cn); } static Eina_Bool -_generate_header(const char *outf, const char *inf, Eina_Bool legacy) +_write_header(const char *ofname, const char *ifname, Eina_Bool legacy) { + INF("generating header: %s (legacy: %d)", ofname, legacy); Eina_Strbuf *buf = eina_strbuf_new(); - if (!types_header_generate(inf, buf, EINA_TRUE, legacy)) + eo_gen_types_header_gen(ifname, buf, EINA_TRUE, legacy); + buf = _include_guard(ifname, "TYPES", buf); + + Eina_Strbuf *cltd = eo_gen_class_typedef_gen(ifname); + if (cltd) { - fprintf(stderr, "eolian: could not generate types of '%s'\n", inf); - eina_strbuf_free(buf); - return EINA_FALSE; - } - - buf = _include_guard_enclose(inf, "TYPES", buf); - - Eina_Strbuf *ctbuf = eina_strbuf_new(); - if (types_class_typedef_generate(inf, ctbuf)) - { - ctbuf = _include_guard_enclose(inf, "CLASS_TYPE", ctbuf); - eina_strbuf_append_char(ctbuf, '\n'); - eina_strbuf_prepend(buf, eina_strbuf_string_get(ctbuf)); - } - eina_strbuf_free(ctbuf); - - const Eolian_Class *cl = eolian_class_get_by_file(inf); - if (cl) - { - Eina_Bool gret = legacy ? legacy_header_generate(cl, buf) - : eo_header_generate(cl, buf); - if (!gret) - { - fprintf(stderr, "eolian: could not generate header for '%s'\n", - eolian_class_name_get(cl)); - eina_strbuf_free(buf); - return EINA_FALSE; - } + cltd = _include_guard(ifname, "CLASS_TYPE", cltd); + eina_strbuf_prepend_char(buf, '\n'); + eina_strbuf_prepend(buf, eina_strbuf_string_get(cltd)); + eina_strbuf_free(cltd); } + const Eolian_Class *cl = eolian_class_get_by_file(ifname); + eo_gen_header_gen(cl, buf, legacy); if (cl || !legacy) { - buf = _include_guard_enclose(_filename_get(outf), NULL, buf); - if (_write_file(outf, buf, EINA_FALSE)) + buf = _include_guard(_get_filename(ofname), NULL, buf); + if (_write_file(ofname, buf)) { eina_strbuf_free(buf); return EINA_TRUE; @@ -175,106 +313,72 @@ _generate_header(const char *outf, const char *inf, Eina_Bool legacy) } static Eina_Bool -_generate_stub_header(const char *outf, const char *inf) +_write_stub_header(const char *ofname, const char *ifname) { + INF("generating stub header: %s", ofname); Eina_Strbuf *buf = eina_strbuf_new(); - if (!types_header_generate(inf, buf, EINA_FALSE, EINA_FALSE)) + eo_gen_types_header_gen(ifname, buf, EINA_FALSE, EINA_FALSE); + + Eina_Strbuf *cltd = eo_gen_class_typedef_gen(ifname); + if (cltd) { - fprintf(stderr, "eolian: could not generate types of '%s'\n", inf); - eina_strbuf_free(buf); - return EINA_FALSE; + eina_strbuf_prepend_char(buf, '\n'); + eina_strbuf_prepend(buf, eina_strbuf_string_get(cltd)); + eina_strbuf_free(cltd); } - Eina_Strbuf *ctbuf = eina_strbuf_new(); - if (types_class_typedef_generate(inf, ctbuf)) - { - eina_strbuf_append_char(ctbuf, '\n'); - eina_strbuf_prepend(buf, eina_strbuf_string_get(ctbuf)); - } - eina_strbuf_free(ctbuf); + buf = _include_guard(_get_filename(ofname), "STUBS", buf); - buf = _include_guard_enclose(_filename_get(outf), "STUBS", buf); - - Eina_Bool ret = _write_file(outf, buf, EINA_FALSE); + Eina_Bool ret = _write_file(ofname, buf); eina_strbuf_free(buf); return ret; } static Eina_Bool -_generate_c(const char *outf, const char *inf, Eina_Bool legacy) +_write_source(const char *ofname, const char *ifname) { - Eina_Strbuf *eobuf = eina_strbuf_new(), - *lgbuf = eina_strbuf_new(); + INF("generating source: %s", ofname); + Eina_Strbuf *buf = eina_strbuf_new(); - const Eolian_Class *cl = eolian_class_get_by_file(inf); + const Eolian_Class *cl = eolian_class_get_by_file(ifname); + eo_gen_source_gen(cl, buf); if (cl) { - if (!eo_source_generate(cl, eobuf)) + if (_write_file(ofname, buf)) { - fprintf(stderr, "eolian: could not generate source for '%s'\n", - eolian_class_name_get(cl)); - eina_strbuf_free(eobuf); - eina_strbuf_free(lgbuf); - return EINA_FALSE; - } - - if (legacy && !legacy_source_generate(cl, lgbuf)) - { - fprintf(stderr, "eolian: could not generate source for '%s'\n", - eolian_class_name_get(cl)); - eina_strbuf_free(eobuf); - eina_strbuf_free(lgbuf); - return EINA_FALSE; + eina_strbuf_free(buf); + return EINA_TRUE; } } - Eina_Bool ret = _write_file(outf, eobuf, EINA_FALSE) && - _write_file(outf, lgbuf, EINA_TRUE); - eina_strbuf_free(eobuf); - eina_strbuf_free(lgbuf); - return ret; + eina_strbuf_free(buf); + return EINA_FALSE; } static Eina_Bool -_generate_impl(const char *outf, const char *inf) +_write_impl(const char *ofname, const char *ifname) { - const Eolian_Class *cl = eolian_class_get_by_file(inf); + INF("generating impl: %s", ofname); + + const Eolian_Class *cl = eolian_class_get_by_file(ifname); if (!cl) return EINA_FALSE; - Eina_Strbuf *buf = NULL; - if (!_read_file(outf, &buf)) + Eina_Strbuf *buf; + if (!_read_file(ofname, &buf)) return EINA_FALSE; - if (!impl_source_generate(cl, buf)) - { - fprintf(stderr, "eolian: could not generate source for '%s'\n", - eolian_class_name_get(cl)); - eina_strbuf_free(buf); - return EINA_FALSE; - } - - Eina_Bool ret = _write_file(outf, buf, EINA_FALSE); + eo_gen_impl_gen(cl, buf); + Eina_Bool ret = _write_file(ofname, buf); eina_strbuf_free(buf); return ret; } -enum -{ - GEN_NOTHING = 0, - GEN_H, - GEN_H_STUB, - GEN_C, - GEN_C_IMPL -}; - int main(int argc, char **argv) { - int gen_what = GEN_NOTHING, do_legacy = 0, ret = 1, silent_types = 0; - Eina_Bool help = EINA_FALSE; - const char *outf = NULL; + int pret = 1; eina_init(); eolian_init(); @@ -289,28 +393,13 @@ main(int argc, char **argv) eina_log_timing(_eolian_gen_log_dom, EINA_LOG_STATE_STOP, EINA_LOG_STATE_INIT); - struct option opts[] = { - { "help", no_argument, NULL, 'h' }, - { "gh", no_argument, &gen_what, GEN_H }, - { "gc", no_argument, &gen_what, GEN_C }, - { "gi", no_argument, &gen_what, GEN_C_IMPL }, - { "gs", no_argument, &gen_what, GEN_H_STUB }, - { "output", required_argument, NULL, 'o' }, - { "legacy", no_argument, &do_legacy, 1 }, - { "include", required_argument, NULL, 'I' }, - { "silent-types", no_argument, &silent_types, 1 }, - { NULL, 0, NULL, 0 } - }; + char *outs[5] = { NULL, NULL, NULL, NULL, NULL }; - for (int opt; (opt = getopt_long(argc, argv, "vho:I:", opts, NULL)) != -1; ) + int gen_what = 0; + for (int opt; (opt = getopt(argc, argv, "I:g:o:hvV")) != -1;) switch (opt) { - case 0: break; - case 'o': - outf = optarg; - break; - case 'h': - help = EINA_TRUE; + case 0: break; case 'I': if (!eolian_directory_scan(optarg)) @@ -319,89 +408,107 @@ main(int argc, char **argv) goto end; } break; - default: - help = EINA_TRUE; + case 'g': + for (const char *wstr = optarg; *wstr; ++wstr) + switch (*wstr) + { + case 'h': + gen_what |= GEN_H; + break; + case 'l': + gen_what |= GEN_H_LEGACY; + break; + case 's': + gen_what |= GEN_H_STUB; + break; + case 'c': + gen_what |= GEN_C; + break; + case 'i': + gen_what |= GEN_C_IMPL; + break; + default: + fprintf(stderr, "unknown type: '%c'\n", *wstr); + goto end; + } break; + case 'o': + if (strchr(optarg, ':')) + { + const char *abeg = optarg; + const char *cpos = strchr(abeg, ':'); + if (((cpos - abeg) != 1) || !_try_set_out(*abeg, outs, cpos + 1)) + { + char *oa = strdup(abeg); + oa[cpos - abeg] = '\0'; + fprintf(stderr, "unknown type: '%s'\n", oa); + free(oa); + goto end; + } + } + else _fill_all_outs(outs, optarg); + break; + case 'h': + _print_usage(argv[0], stdout); + goto end; + case 'v': + _print_version(stdout); + goto end; + default: + _print_usage(argv[0], stderr); + goto end; } - if (help) - { - printf("Usage: %s [-h/--help] [-I/--include input_dir] [--legacy] [--gh|--gs|--gc|--gi] [--output/-o outfile] file.eo ... \n", argv[0]); - printf(" --help/-h Print that help\n"); - printf(" --include/-I Include 'input_dir' as directory to search .eo files into\n"); - printf(" --output/-o Force output filename to 'outfile'\n"); - printf(" --gh Generate C header file [.h]\n"); - printf(" --gs Generate C type stubs [.h]\n"); - printf(" --gc Generate C source file [.c]\n"); - printf(" --gi Generate C implementation source file [.c]. The output will be a series of functions that have to be filled.\n"); - printf(" --legacy Generate legacy\n"); - printf(" --silent-types Silence type validation\n"); - ret = 0; - goto end; - } - - const char *eof = argv[optind++]; - if (!eof) + const char *input = argv[optind]; + if (!input) { fprintf(stderr, "eolian: no input file\n"); goto end; } - if (!eolian_file_parse(eof)) + const char *ext = strrchr(input, '.'); + if (!ext || (strcmp(ext, ".eo") && strcmp(ext, ".eot"))) { - fprintf(stderr, "eolian: could not parse file '%s'\n", eof); + fprintf(stderr, "eolian: invalid input file '%s'\n", input); goto end; } - if (!eolian_database_validate(silent_types)) + if (!eolian_file_parse(input)) { - fprintf(stderr, "eolian: error validating database\n"); + fprintf(stderr, "eolian: could not parse file '%s'\n", input); goto end; } - char *eofc = strdup(eof); - char *eobn = basename(eofc); + _fill_all_outs(outs, input); - if (gen_what) - { - if (!outf) - { - fprintf(stderr, "eolian: no output file\n"); - free(eofc); - goto end; - } - switch (gen_what) - { - case GEN_H: - INF("Generating header file %s\n", outf); - ret = !_generate_header(outf, eobn, do_legacy); - break; - case GEN_H_STUB: - INF("Generating stub header file %s\n", outf); - ret = !_generate_stub_header(outf, eobn); - break; - case GEN_C: - INF("Generating source file %s\n", outf); - ret = !_generate_c(outf, eobn, do_legacy); - break; - case GEN_C_IMPL: - INF("Generating user source file %s\n", outf); - ret = !_generate_impl(outf, eobn); - break; - default: - ERR("Wrong generation option\n"); - break; - } - } - else - ret = 0; + const char *eobn = _get_filename(input); - free(eofc); + if (!gen_what) + gen_what = !strcmp(ext, ".eot") ? GEN_H : (GEN_H | GEN_C); + Eina_Bool succ = EINA_TRUE; + if (gen_what & GEN_H) + succ = _write_header(outs[_get_bit_pos(GEN_H)], eobn, EINA_FALSE); + if (succ && (gen_what & GEN_H_LEGACY)) + succ = _write_header(outs[_get_bit_pos(GEN_H_LEGACY)], eobn, EINA_TRUE); + if (succ && (gen_what & GEN_H_STUB)) + succ = _write_stub_header(outs[_get_bit_pos(GEN_H_STUB)], eobn); + if (succ && (gen_what & GEN_C)) + succ = _write_source(outs[_get_bit_pos(GEN_C)], eobn); + if (succ && (gen_what & GEN_C_IMPL)) + succ = _write_impl(outs[_get_bit_pos(GEN_C_IMPL)], eobn); + + if (!succ) + goto end; + + pret = 0; end: eina_log_timing(_eolian_gen_log_dom, EINA_LOG_STATE_START, EINA_LOG_STATE_SHUTDOWN); eina_log_domain_unregister(_eolian_gen_log_dom); + for (size_t i = 0; i < (sizeof(_dexts) / sizeof(char *)); ++i) + free(outs[i]); eolian_shutdown(); eina_shutdown(); - return ret; + + return pret; } diff --git a/src/bin/eolian/main.h b/src/bin/eolian/main.h new file mode 100644 index 0000000000..0dd0b793ff --- /dev/null +++ b/src/bin/eolian/main.h @@ -0,0 +1,42 @@ +#ifndef EOLIAN_GEN_MAIN_H +#define EOLIAN_GEN_MAIN_H + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +extern int _eolian_gen_log_dom; + +#ifdef ERR +# undef ERR +#endif +#define ERR(...) EINA_LOG_DOM_ERR(_eolian_gen_log_dom, __VA_ARGS__) + +#ifdef DBG +# undef DBG +#endif +#define DBG(...) EINA_LOG_DOM_DBG(_eolian_gen_log_dom, __VA_ARGS__) + +#ifdef INF +# undef INF +#endif +#define INF(...) EINA_LOG_DOM_INFO(_eolian_gen_log_dom, __VA_ARGS__) + +#ifdef WRN +# undef WRN +#endif +#define WRN(...) EINA_LOG_DOM_WARN(_eolian_gen_log_dom, __VA_ARGS__) + +#ifdef CRIT +# undef CRIT +#endif +#define CRIT(...) EINA_LOG_DOM_CRIT(_eolian_gen_log_dom, __VA_ARGS__) + +char *eo_gen_c_full_name_get(const char *nm); +void eo_gen_class_names_get(const Eolian_Class *cl, char **cname, + char **cnameu, char **cnamel); + +#endif diff --git a/src/bin/eolian/sources.c b/src/bin/eolian/sources.c new file mode 100644 index 0000000000..2c95db5700 --- /dev/null +++ b/src/bin/eolian/sources.c @@ -0,0 +1,1094 @@ +#include "main.h" +#include "docs.h" + +static const char * +_cl_type_str_get(const Eolian_Class *cl) +{ + switch (eolian_class_type_get(cl)) + { + case EOLIAN_CLASS_REGULAR: + case EOLIAN_CLASS_ABSTRACT: + return "CLASS"; + case EOLIAN_CLASS_MIXIN: + return "MIXIN"; + case EOLIAN_CLASS_INTERFACE: + return "INTERFACE"; + default: + return NULL; + } +} + +/* Used to store the function names that will have to be appended + * with __eolian during C generation. Needed when params have to + * be initialized and for future features. + */ +static Eina_Hash *_funcs_params_init = NULL; + +static const char * +_get_add_star(Eolian_Function_Type ftype, Eolian_Parameter_Dir pdir) +{ + if (ftype == EOLIAN_PROP_GET) + return "*"; + if ((pdir == EOLIAN_OUT_PARAM) || (pdir == EOLIAN_INOUT_PARAM)) + return "*"; + return ""; +} + +static char * +_get_data_type(const Eolian_Class *cl) +{ + const char *dt = eolian_class_data_type_get(cl); + if (!dt) + return NULL; + char *dtr = strdup(dt); + if (!dtr) + abort(); + for (char *p = strchr(dtr, '.'); p; p = strchr(p, '.')) + *p = '_'; + return dtr; +} + +static Eina_Bool +_function_exists(const char *fname, Eina_Strbuf *buf) +{ + const char *ptr = eina_strbuf_string_get(buf); + size_t flen = strlen(fname); + while ((ptr = strstr(ptr, fname)) != NULL) + { + switch (*(ptr - 1)) + { + case '\n': + case ' ': + switch (*(ptr + flen)) + { + case ' ': + case '(': + return EINA_TRUE; + } + } + ++ptr; + } + return EINA_FALSE; +} + +/* Check if the type is used in the file, not if it is a typedef... */ +static Eina_Bool +_type_exists(const char *tname, Eina_Strbuf *buf) +{ + const char *ptr = eina_strbuf_string_get(buf); + size_t tlen = strlen(tname); + while ((ptr = strstr(ptr, tname)) != NULL) + { + switch (*(ptr - 1)) + { + case '\n': + case ' ': + case ',': + switch (*(ptr + tlen)) + { + case '\n': + case ' ': + case ',': + case ';': + return EINA_TRUE; + } + } + ++ptr; + } + return EINA_FALSE; +} + +static void +_gen_func(const Eolian_Class *cl, const Eolian_Function *fid, + Eolian_Function_Type ftype, Eina_Strbuf *buf, + const Eolian_Implement *impl, Eina_Strbuf *lbuf) +{ + Eina_Bool is_empty = eolian_implement_is_empty(impl); + Eina_Bool is_auto = eolian_implement_is_auto(impl); + + if ((ftype != EOLIAN_PROP_GET) && (ftype != EOLIAN_PROP_SET)) + ftype = eolian_function_type_get(fid); + + Eina_Bool is_prop = (ftype == EOLIAN_PROP_GET || ftype == EOLIAN_PROP_SET); + Eina_Bool var_as_ret = EINA_FALSE; + + const Eolian_Expression *def_ret = NULL; + const Eolian_Type *rtp = eolian_function_return_type_get(fid, ftype); + if (rtp) + { + is_auto = EINA_FALSE; /* can't do auto if func returns */ + def_ret = eolian_function_return_default_value_get(fid, ftype); + } + + const char *func_suffix = ""; + if (ftype == EOLIAN_PROP_GET) + { + func_suffix = "_get"; + if (!rtp) + { + void *d1, *d2; + Eina_Iterator *itr = eolian_property_values_get(fid, ftype); + if (eina_iterator_next(itr, &d1) && !eina_iterator_next(itr, &d2)) + { + Eolian_Function_Parameter *pr = d1; + rtp = eolian_parameter_type_get(pr); + var_as_ret = EINA_TRUE; + def_ret = eolian_parameter_default_value_get(pr); + } + eina_iterator_free(itr); + } + } + else if (ftype == EOLIAN_PROP_SET) + func_suffix = "_set"; + + Eina_Strbuf *params = eina_strbuf_new(); /* par1, par2, par3, ... */ + Eina_Strbuf *params_full = eina_strbuf_new(); /* T par1, U par2, ... for decl */ + Eina_Strbuf *params_full_imp = eina_strbuf_new(); /* as above, for impl */ + Eina_Strbuf *params_init = eina_strbuf_new(); /* default value inits */ + + Eina_Bool has_promise = EINA_FALSE; + Eina_Stringshare *promise_param_name = NULL; + Eina_Stringshare *promise_param_type = NULL; + + /* property keys */ + { + Eina_Iterator *itr = eolian_property_keys_get(fid, ftype); + Eolian_Function_Parameter *pr; + EINA_ITERATOR_FOREACH(itr, pr) + { + const char *prn = eolian_parameter_name_get(pr); + const Eolian_Type *pt = eolian_parameter_type_get(pr); + Eina_Stringshare *ptn = eolian_type_c_type_get(pt); + + if (eina_strbuf_length_get(params)) + eina_strbuf_append(params, ", "); + eina_strbuf_append(params, prn); + + eina_strbuf_append_printf(params_full, ", %s", ptn); + eina_strbuf_append_printf(params_full_imp, ", %s", ptn); + if (!strchr(ptn, '*')) + { + eina_strbuf_append_char(params_full, ' '); + eina_strbuf_append_char(params_full_imp, ' '); + } + eina_strbuf_append(params_full, prn); + eina_strbuf_append(params_full_imp, prn); + if (is_empty || is_auto) + eina_strbuf_append(params_full_imp, " EINA_UNUSED"); + + eina_stringshare_del(ptn); + } + eina_iterator_free(itr); + } + + /* property values or method params if applicable */ + if (!var_as_ret) + { + Eina_Iterator *itr; + if (is_prop) + itr = eolian_property_values_get(fid, ftype); + else + itr = eolian_function_parameters_get(fid); + Eolian_Function_Parameter *pr; + EINA_ITERATOR_FOREACH(itr, pr) + { + Eolian_Parameter_Dir pd = eolian_parameter_direction_get(pr); + const Eolian_Expression *dfv = eolian_parameter_default_value_get(pr); + const char *prn = eolian_parameter_name_get(pr); + const Eolian_Type *pt = eolian_parameter_type_get(pr); + Eina_Stringshare *ptn = eolian_type_c_type_get(pt); + + Eina_Bool had_star = !!strchr(ptn, '*'); + const char *add_star = _get_add_star(ftype, pd); + + if (eina_strbuf_length_get(params)) + eina_strbuf_append(params, ", "); + + /* XXX: this is really bad */ + if (!has_promise && !strcmp(ptn, "Eina_Promise *") && !is_prop + && (pd == EOLIAN_INOUT_PARAM)) + { + has_promise = EINA_TRUE; + promise_param_name = eina_stringshare_add(prn); + promise_param_type = eolian_type_c_type_get(eolian_type_base_type_get(pt)); + eina_strbuf_append(params_full_imp, ", Eina_Promise_Owner *"); + eina_strbuf_append(params_full_imp, prn); + if (is_empty && !dfv) + eina_strbuf_append(params_full_imp, " EINA_UNUSED"); + eina_strbuf_append(params, "__eo_promise"); + } + else + { + eina_strbuf_append(params_full_imp, ", "); + eina_strbuf_append(params_full_imp, ptn); + if (!had_star) + eina_strbuf_append_char(params_full_imp, ' '); + eina_strbuf_append(params_full_imp, add_star); + eina_strbuf_append(params_full_imp, prn); + if (!dfv && is_empty) + eina_strbuf_append(params_full_imp, " EINA_UNUSED"); + eina_strbuf_append(params, prn); + } + + eina_strbuf_append(params_full, ", "); + eina_strbuf_append(params_full, ptn); + if (!had_star) + eina_strbuf_append_char(params_full, ' '); + eina_strbuf_append(params_full, add_star); + eina_strbuf_append(params_full, prn); + + if (is_auto) + { + if (ftype == EOLIAN_PROP_SET) + eina_strbuf_append_printf(params_init, " %s = pd->%s;\n", prn, prn); + else + { + eina_strbuf_append_printf(params_init, " if (%s) *%s = pd->%s;\n", + prn, prn, prn); + } + } + else if ((ftype != EOLIAN_PROP_SET) && dfv) + { + Eolian_Value val = eolian_expression_eval(dfv, EOLIAN_MASK_ALL); + if (val.type) + { + Eina_Stringshare *vals = eolian_expression_value_to_literal(&val); + eina_strbuf_append_printf(params_init, " if (%s) *%s = %s;", + prn, prn, vals); + eina_stringshare_del(vals); + if (eolian_expression_type_get(dfv) == EOLIAN_EXPR_NAME) + { + Eina_Stringshare *vs = eolian_expression_serialize(dfv); + eina_strbuf_append_printf(params_init, " /* %s */", vs); + eina_stringshare_del(vs); + } + eina_strbuf_append_char(params_init, '\n'); + } + } + + eina_stringshare_del(ptn); + } + eina_iterator_free(itr); + } + + Eina_Bool impl_same_class = (eolian_implement_class_get(impl) == cl); + Eina_Bool impl_need = EINA_TRUE; + if (impl_same_class && eolian_function_is_virtual_pure(fid, ftype)) + impl_need = EINA_FALSE; + + Eina_Stringshare *rtpn = rtp ? eolian_type_c_type_get(rtp) + : eina_stringshare_add("void"); + + char *cname = NULL, *cnameu = NULL, *cnamel = NULL, *ocnamel = NULL; + eo_gen_class_names_get(cl, &cname, &cnameu, &cnamel); + eo_gen_class_names_get(eolian_implement_class_get(impl), NULL, NULL, &ocnamel); + + if (impl_need) + { + /* figure out the data type */ + Eina_Bool is_cf = eolian_function_is_class(fid); + char *dt = _get_data_type(cl); + char adt[128]; + if (is_cf || (dt && !strcmp(dt, "null"))) + snprintf(adt, sizeof(adt), "void"); + else if (dt) + snprintf(adt, sizeof(adt), "%s", dt); + else + snprintf(adt, sizeof(adt), "%s_Data", cname); + free(dt); + + eina_strbuf_append_char(buf, '\n'); + /* no need for prototype with empty/auto impl */ + if (!is_empty && !is_auto) + { + /* T _class_name[_orig_class]_func_name_suffix */ + eina_strbuf_append(buf, rtpn); + if (!strchr(rtpn, '*')) + eina_strbuf_append_char(buf, ' '); + eina_strbuf_append_char(buf, '_'); + eina_strbuf_append(buf, cnamel); + if (!impl_same_class) + eina_strbuf_append_printf(buf, "_%s", ocnamel); + eina_strbuf_append_char(buf, '_'); + eina_strbuf_append(buf, eolian_function_name_get(fid)); + eina_strbuf_append(buf, func_suffix); + /* ([const ]Eo *obj, Data_Type *pd, impl_full_params); */ + eina_strbuf_append_char(buf, '('); + if (eolian_function_object_is_const(fid)) + eina_strbuf_append(buf, "const "); + eina_strbuf_append(buf, "Eo *obj, "); + eina_strbuf_append(buf, adt); + eina_strbuf_append(buf, " *pd"); + eina_strbuf_append(buf, eina_strbuf_string_get(params_full_imp)); + eina_strbuf_append(buf, ");\n\n"); + } + + if (is_empty || is_auto || eina_strbuf_length_get(params_init)) + { + /* we need to give the internal function name to Eo, + * use this hash table as indication + */ + eina_hash_add(_funcs_params_init, &impl, impl); + /* generation of intermediate __eolian_... */ + eina_strbuf_append(buf, "static "); + eina_strbuf_append(buf, rtpn); + if (!strchr(rtpn, '*')) + eina_strbuf_append_char(buf, ' '); + eina_strbuf_append(buf, "__eolian_"); + eina_strbuf_append(buf, cnamel); + if (!impl_same_class) + eina_strbuf_append_printf(buf, "_%s", ocnamel); + eina_strbuf_append_char(buf, '_'); + eina_strbuf_append(buf, eolian_function_name_get(fid)); + eina_strbuf_append(buf, func_suffix); + eina_strbuf_append_char(buf, '('); + if (eolian_function_object_is_const(fid)) + eina_strbuf_append(buf, "const "); + eina_strbuf_append(buf, "Eo *obj"); + if (is_empty || is_auto) + eina_strbuf_append(buf, " EINA_UNUSED"); + eina_strbuf_append(buf, ", "); + eina_strbuf_append(buf, adt); + eina_strbuf_append(buf, " *pd"); + if (is_empty || (is_auto && !eina_strbuf_length_get(params_init))) + eina_strbuf_append(buf, " EINA_UNUSED"); + eina_strbuf_append(buf, eina_strbuf_string_get(params_full_imp)); + eina_strbuf_append(buf, ")\n{\n"); + } + if (eina_strbuf_length_get(params_init)) + eina_strbuf_append(buf, eina_strbuf_string_get(params_init)); + if (is_empty || is_auto) + { + if (rtp) + { + const char *vals = NULL; + if (def_ret) + { + Eolian_Value val = eolian_expression_eval(def_ret, EOLIAN_MASK_ALL); + if (val.type) + vals = eolian_expression_value_to_literal(&val); + } + eina_strbuf_append_printf(buf, " return %s;\n", vals ? vals : "0"); + eina_stringshare_del(vals); + } + eina_strbuf_append(buf, "}\n\n"); + } + else if (eina_strbuf_length_get(params_init)) + { + eina_strbuf_append(buf, " "); + if (rtp) + eina_strbuf_append(buf, "return "); + eina_strbuf_append_char(buf, '_'); + eina_strbuf_append(buf, cnamel); + if (!impl_same_class) + eina_strbuf_append_printf(buf, "_%s", ocnamel); + eina_strbuf_append_char(buf, '_'); + eina_strbuf_append(buf, eolian_function_name_get(fid)); + eina_strbuf_append(buf, func_suffix); + eina_strbuf_append(buf, "(obj, pd, "); + eina_strbuf_append(buf, eina_strbuf_string_get(params)); + eina_strbuf_append(buf, ");\n}\n\n"); + } + } + + if (impl_same_class) + { + /* XXX: bad */ + if (has_promise) + { + eina_strbuf_append_printf(buf, + "#undef _EFL_OBJECT_API_BEFORE_HOOK\n#undef _EFL_OBJECT_API_AFTER_HOOK\n#undef _EFL_OBJECT_API_CALL_HOOK\n" + "#define _EFL_OBJECT_API_BEFORE_HOOK _EINA_PROMISE_BEFORE_HOOK(%s, %s%s)\n" + "#define _EFL_OBJECT_API_AFTER_HOOK _EINA_PROMISE_AFTER_HOOK(%s)\n" + "#define _EFL_OBJECT_API_CALL_HOOK(x) _EINA_PROMISE_CALL_HOOK(EFL_FUNC_CALL(%s))\n\n", + promise_param_type, rtpn, + eina_strbuf_string_get(params_full_imp), + promise_param_name, + eina_strbuf_string_get(params)); + } + + void *data; + Eina_Iterator *itr = eolian_property_keys_get(fid, ftype); + Eina_Bool has_params = eina_iterator_next(itr, &data); + eina_iterator_free(itr); + + if (!has_params && !var_as_ret) + { + if (is_prop) + itr = eolian_property_values_get(fid, ftype); + else + itr = eolian_function_parameters_get(fid); + has_params = eina_iterator_next(itr, &data); + eina_iterator_free(itr); + } + + eina_strbuf_append(buf, "EOAPI EFL_"); + if (!strcmp(rtpn, "void")) + eina_strbuf_append(buf, "VOID_"); + eina_strbuf_append(buf, "FUNC_BODY"); + if (has_params) + eina_strbuf_append_char(buf, 'V'); + if ((ftype == EOLIAN_PROP_GET) || eolian_function_object_is_const(fid) + || eolian_function_is_class(fid)) + { + eina_strbuf_append(buf, "_CONST"); + } + eina_strbuf_append_char(buf, '('); + + Eina_Stringshare *eofn = eolian_function_full_c_name_get(fid, ftype, EINA_FALSE); + eina_strbuf_append(buf, eofn); + + if (strcmp(rtpn, "void")) + { + const char *vals = NULL; + if (def_ret) + { + Eolian_Value val = eolian_expression_eval(def_ret, EOLIAN_MASK_ALL); + if (val.type) + vals = eolian_expression_value_to_literal(&val); + } + eina_strbuf_append_printf(buf, ", %s, %s", rtpn, vals ? vals : "0"); + if (vals && (eolian_expression_type_get(def_ret) == EOLIAN_EXPR_NAME)) + { + Eina_Stringshare *valn = eolian_expression_serialize(def_ret); + eina_strbuf_append_printf(buf, " /* %s */", valn); + eina_stringshare_del(valn); + } + eina_stringshare_del(vals); + } + if (has_params) + { + eina_strbuf_append(buf, ", EFL_FUNC_CALL("); + eina_strbuf_append(buf, eina_strbuf_string_get(params)); + eina_strbuf_append_char(buf, ')'); + eina_strbuf_append(buf, eina_strbuf_string_get(params_full)); + } + + eina_strbuf_append(buf, ");\n"); + + if (has_promise) + { + eina_strbuf_append(buf, "\n#undef _EFL_OBJECT_API_BEFORE_HOOK\n#undef _EFL_OBJECT_API_AFTER_HOOK\n#undef _EFL_OBJECT_API_CALL_HOOK\n" + "#define _EFL_OBJECT_API_BEFORE_HOOK\n#define _EFL_OBJECT_API_AFTER_HOOK\n" + "#define _EFL_OBJECT_API_CALL_HOOK(x) x\n"); + } + + /* now try legacy */ + Eina_Stringshare *lfn = eolian_function_full_c_name_get(fid, ftype, EINA_TRUE); + if (!eolian_function_is_beta(fid) && lfn) + { + eina_strbuf_append(lbuf, "\nEAPI "); + eina_strbuf_append(lbuf, rtpn); + eina_strbuf_append_char(lbuf, '\n'); + eina_strbuf_append(lbuf, lfn); + /* param list */ + eina_strbuf_append_char(lbuf, '('); + /* for class funcs, offset the params to remove comma */ + int poff = 2; + if (!eolian_function_is_class(fid)) + { + /* non-class funcs have the obj though */ + poff = 0; + if ((ftype == EOLIAN_PROP_GET) || eolian_function_object_is_const(fid)) + eina_strbuf_append(lbuf, "const "); + eina_strbuf_append_printf(lbuf, "%s *obj", cname); + } + eina_strbuf_append(lbuf, eina_strbuf_string_get(params_full) + poff); + eina_strbuf_append(lbuf, ")\n{\n"); + /* body */ + if (strcmp(rtpn, "void")) + eina_strbuf_append(lbuf, " return "); + else + eina_strbuf_append(lbuf, " "); + eina_strbuf_append(lbuf, eofn); + eina_strbuf_append_char(lbuf, '('); + if (!eolian_function_is_class(fid)) + eina_strbuf_append(lbuf, "obj"); + else + eina_strbuf_append_printf(lbuf, "%s_%s", cnameu, _cl_type_str_get(cl)); + if (has_params) + eina_strbuf_append_printf(lbuf, ", %s", eina_strbuf_string_get(params)); + eina_strbuf_append(lbuf, ");\n}\n"); + } + + eina_stringshare_del(lfn); + eina_stringshare_del(eofn); + } + + free(cname); + free(cnameu); + free(cnamel); + free(ocnamel); + + eina_stringshare_del(rtpn); + + eina_stringshare_del(promise_param_name); + eina_stringshare_del(promise_param_type); + + eina_strbuf_free(params); + eina_strbuf_free(params_full); + eina_strbuf_free(params_full_imp); + eina_strbuf_free(params_init); +} + +static void +_gen_opfunc(const Eolian_Function *fid, Eolian_Function_Type ftype, + Eina_Strbuf *buf, Eina_Bool pinit, + const char *cnamel, const char *ocnamel) +{ + Eina_Stringshare *fnm = eolian_function_full_c_name_get(fid, ftype, EINA_FALSE); + eina_strbuf_append(buf, " EFL_OBJECT_OP_FUNC("); + eina_strbuf_append(buf, fnm); + eina_strbuf_append(buf, ", "); + if (!ocnamel && eolian_function_is_virtual_pure(fid, ftype)) + eina_strbuf_append(buf, "NULL),\n"); + else + { + if (pinit) + eina_strbuf_append(buf, "__eolian"); + eina_strbuf_append_printf(buf, "_%s_", cnamel); + if (ocnamel) + eina_strbuf_append_printf(buf, "%s_", ocnamel); + eina_strbuf_append(buf, eolian_function_name_get(fid)); + if (ftype == EOLIAN_PROP_GET) + eina_strbuf_append(buf, "_get"); + else if (ftype == EOLIAN_PROP_SET) + eina_strbuf_append(buf, "_set"); + eina_strbuf_append(buf, "),\n"); + } +} + +static Eina_Bool +_gen_initializer(const Eolian_Class *cl, Eina_Strbuf *buf) +{ + Eina_Iterator *itr = eolian_class_implements_get(cl); + const Eolian_Implement *imp; + if (!eina_iterator_next(itr, (void **)&imp)) + { + eina_iterator_free(itr); + return EINA_FALSE; + } + eina_iterator_free(itr); + + char *cnamel = NULL; + eo_gen_class_names_get(cl, NULL, NULL, &cnamel); + + eina_strbuf_append(buf, "\nstatic Eina_Bool\n_"); + eina_strbuf_append(buf, cnamel); + eina_strbuf_append(buf, "_class_initializer(Efl_Class *klass)\n{\n"); + + Eina_Strbuf *ops = eina_strbuf_new(), *cops = eina_strbuf_new(); + + /* start over with clean itearator */ + itr = eolian_class_implements_get(cl); + EINA_ITERATOR_FOREACH(itr, imp) + { + const Eolian_Class *icl = eolian_implement_class_get(imp); + Eolian_Function_Type ftype; + const Eolian_Function *fid = eolian_implement_function_get(imp, &ftype); + + Eina_Strbuf *obuf = ops; + if (eolian_function_is_class(fid)) + obuf = cops; + + if (!eina_strbuf_length_get(obuf)) + eina_strbuf_append_printf(obuf, " EFL_OPS_DEFINE(%s,\n", + (obuf == ops) ? "ops" : "cops"); + + Eina_Bool found = !!eina_hash_find(_funcs_params_init, &imp); + char *ocnamel = NULL; + if (cl != icl) + eo_gen_class_names_get(icl, NULL, NULL, &ocnamel); + + switch (ftype) + { + case EOLIAN_PROP_GET: + _gen_opfunc(fid, EOLIAN_PROP_GET, obuf, found, cnamel, ocnamel); + break; + case EOLIAN_PROP_SET: + _gen_opfunc(fid, EOLIAN_PROP_SET, obuf, found, cnamel, ocnamel); + break; + case EOLIAN_PROPERTY: + _gen_opfunc(fid, EOLIAN_PROP_SET, obuf, found, cnamel, ocnamel); + _gen_opfunc(fid, EOLIAN_PROP_GET, obuf, found, cnamel, ocnamel); + break; + default: + _gen_opfunc(fid, EOLIAN_METHOD, obuf, found, cnamel, ocnamel); + break; + } + + free(ocnamel); + } + eina_iterator_free(itr); + + /* strip the final comma before appending */ + if (eina_strbuf_length_get(ops)) + { + eina_strbuf_remove(ops, eina_strbuf_length_get(ops) - 2, + eina_strbuf_length_get(ops)); + eina_strbuf_append(ops, "\n );\n"); + eina_strbuf_append(buf, eina_strbuf_string_get(ops)); + } + if (eina_strbuf_length_get(cops)) + { + eina_strbuf_remove(cops, eina_strbuf_length_get(cops) - 2, + eina_strbuf_length_get(cops)); + eina_strbuf_append(cops, "\n );\n"); + eina_strbuf_append(buf, eina_strbuf_string_get(cops)); + } + + eina_strbuf_append(buf, " return efl_class_functions_set(klass, "); + if (eina_strbuf_length_get(ops)) + eina_strbuf_append(buf, "&ops, "); + else + eina_strbuf_append(buf, "NULL, "); + if (eina_strbuf_length_get(cops)) + eina_strbuf_append(buf, "&cops);\n"); + else + eina_strbuf_append(buf, "NULL);\n"); + + eina_strbuf_free(ops); + eina_strbuf_free(cops); + + eina_strbuf_append(buf, "}\n\n"); + + free(cnamel); + + return EINA_TRUE; +} + +void +eo_gen_source_gen(const Eolian_Class *cl, Eina_Strbuf *buf) +{ + if (!cl) + return; + + _funcs_params_init = eina_hash_pointer_new(NULL); + + char *cname = NULL, *cnameu = NULL, *cnamel = NULL; + eo_gen_class_names_get(cl, &cname, &cnameu, &cnamel); + + /* event section, they come first */ + { + Eina_Iterator *itr = eolian_class_events_get(cl); + Eolian_Event *ev; + EINA_ITERATOR_FOREACH(itr, ev) + { + Eina_Stringshare *evn = eolian_event_c_name_get(ev); + eina_strbuf_append(buf, "EOAPI const Efl_Event_Description _"); + eina_strbuf_append(buf, evn); + eina_strbuf_append(buf, " =\n EFL_EVENT_DESCRIPTION"); + if (eolian_event_is_hot(ev)) + eina_strbuf_append(buf, "_HOT"); + if (eolian_event_is_restart(ev)) + eina_strbuf_append(buf, "_RESTART"); + eina_strbuf_append_printf(buf, "(\"%s\");\n", eolian_event_name_get(ev)); + eina_stringshare_del(evn); + } + eina_iterator_free(itr); + } + + Eina_Strbuf *lbuf = eina_strbuf_new(); + + /* method section */ + { + Eina_Iterator *itr = eolian_class_implements_get(cl); + const Eolian_Implement *imp; + EINA_ITERATOR_FOREACH(itr, imp) + { + Eolian_Function_Type ftype = EOLIAN_UNRESOLVED; + const Eolian_Function *fid = eolian_implement_function_get(imp, &ftype); + switch (ftype) + { + case EOLIAN_PROP_GET: + case EOLIAN_PROP_SET: + _gen_func(cl, fid, ftype, buf, imp, lbuf); + break; + case EOLIAN_PROPERTY: + _gen_func(cl, fid, EOLIAN_PROP_SET, buf, imp, lbuf); + _gen_func(cl, fid, EOLIAN_PROP_GET, buf, imp, lbuf); + break; + default: + _gen_func(cl, fid, EOLIAN_UNRESOLVED, buf, imp, lbuf); + } + } + eina_iterator_free(itr); + } + + /* class initializer - contains method defs */ + Eina_Bool has_init = _gen_initializer(cl, buf); + + /* class description */ + eina_strbuf_append(buf, "static const Efl_Class_Description _"); + eina_strbuf_append(buf, cnamel); + eina_strbuf_append(buf, "_class_desc = {\n" + " EO_VERSION,\n"); + eina_strbuf_append_printf(buf, " \"%s\",\n", cname); + + switch (eolian_class_type_get(cl)) + { + case EOLIAN_CLASS_ABSTRACT: + eina_strbuf_append(buf, " EFL_CLASS_TYPE_REGULAR_NO_INSTANT,\n"); + break; + case EOLIAN_CLASS_MIXIN: + eina_strbuf_append(buf, " EFL_CLASS_TYPE_MIXIN,\n"); + break; + case EOLIAN_CLASS_INTERFACE: + eina_strbuf_append(buf, " EFL_CLASS_TYPE_INTERFACE,\n"); + break; + default: + eina_strbuf_append(buf, " EFL_CLASS_TYPE_REGULAR,\n"); + break; + } + + char *dt = _get_data_type(cl); + if (dt && !strcmp(dt, "null")) + eina_strbuf_append(buf, " 0,\n"); + else + { + eina_strbuf_append(buf, " sizeof("); + if (dt) + eina_strbuf_append(buf, dt); + else + eina_strbuf_append_printf(buf, "%s_Data", cname); + eina_strbuf_append(buf, "),\n"); + } + free(dt); + + if (has_init) + eina_strbuf_append_printf(buf, " _%s_class_initializer,\n", cnamel); + else + eina_strbuf_append(buf, " NULL,\n"); + + if (eolian_class_ctor_enable_get(cl)) + eina_strbuf_append_printf(buf, " _%s_class_constructor,\n", cnamel); + else + eina_strbuf_append(buf, " NULL,\n"); + + if (eolian_class_dtor_enable_get(cl)) + eina_strbuf_append_printf(buf, " _%s_class_destructor\n", cnamel); + else + eina_strbuf_append(buf, " NULL\n"); + + eina_strbuf_append(buf, "};\n\n"); + + /* class def */ + eina_strbuf_append(buf, "EFL_DEFINE_CLASS("); + + Eina_Stringshare *cgfunc = eolian_class_c_get_function_name_get(cl); + eina_strbuf_append(buf, cgfunc); + eina_stringshare_del(cgfunc); + + eina_strbuf_append_printf(buf, ", &_%s_class_desc", cnamel); + + /* inherits in EFL_DEFINE_CLASS */ + { + const char *iname; + Eina_Iterator *itr = eolian_class_inherits_get(cl); + /* no inherits, NULL parent */ + if (!itr) + eina_strbuf_append(buf, ", NULL"); + EINA_ITERATOR_FOREACH(itr, iname) + { + char *inameu = NULL; + const Eolian_Class *icl = eolian_class_get_by_name(iname); + eo_gen_class_names_get(icl, NULL, &inameu, NULL); + eina_strbuf_append(buf, ", "); + eina_strbuf_append_printf(buf, "%s_%s", inameu, _cl_type_str_get(icl)); + free(inameu); + } + eina_iterator_free(itr); + } + + /* terminate inherits */ + eina_strbuf_append(buf, ", NULL);\n"); + + /* append legacy if there */ + eina_strbuf_append(buf, eina_strbuf_string_get(lbuf)); + + eina_strbuf_free(lbuf); + + /* and we're done */ + free(cname); + free(cnameu); + free(cnamel); + eina_hash_free(_funcs_params_init); +} + +static void +_gen_params(const Eolian_Function *fid, Eolian_Function_Type ftype, + Eina_Bool var_as_ret, Eina_Strbuf *params, Eina_Strbuf *params_full) +{ + Eina_Bool is_prop = (ftype == EOLIAN_PROP_GET || ftype == EOLIAN_PROP_SET); + + /* property keys */ + { + Eina_Iterator *itr = eolian_property_keys_get(fid, ftype); + Eolian_Function_Parameter *pr; + EINA_ITERATOR_FOREACH(itr, pr) + { + const char *prn = eolian_parameter_name_get(pr); + const Eolian_Type *pt = eolian_parameter_type_get(pr); + Eina_Stringshare *ptn = eolian_type_c_type_get(pt); + + eina_strbuf_append(params, ", "); + eina_strbuf_append(params, prn); + + eina_strbuf_append_printf(params_full, ", %s", ptn); + if (!strchr(ptn, '*')) + eina_strbuf_append_char(params_full, ' '); + eina_strbuf_append(params_full, prn); + + eina_stringshare_del(ptn); + } + eina_iterator_free(itr); + } + + /* property values or method params if applicable */ + if (!var_as_ret) + { + Eina_Iterator *itr; + if (is_prop) + itr = eolian_property_values_get(fid, ftype); + else + itr = eolian_function_parameters_get(fid); + Eolian_Function_Parameter *pr; + EINA_ITERATOR_FOREACH(itr, pr) + { + Eolian_Parameter_Dir pd = eolian_parameter_direction_get(pr); + const char *prn = eolian_parameter_name_get(pr); + const Eolian_Type *pt = eolian_parameter_type_get(pr); + Eina_Stringshare *ptn = eolian_type_c_type_get(pt); + + Eina_Bool had_star = !!strchr(ptn, '*'); + const char *add_star = _get_add_star(ftype, pd); + + eina_strbuf_append(params, ", "); + eina_strbuf_append(params, prn); + + eina_strbuf_append(params_full, ", "); + eina_strbuf_append(params_full, ptn); + if (!had_star) + eina_strbuf_append_char(params_full, ' '); + eina_strbuf_append(params_full, add_star); + eina_strbuf_append(params_full, prn); + + eina_stringshare_del(ptn); + } + eina_iterator_free(itr); + } +} + +static void +_gen_proto(const Eolian_Class *cl, const Eolian_Function *fid, + Eolian_Function_Type ftype, Eina_Strbuf *buf, + const Eolian_Implement *impl, const char *dtype, + const char *cnamel, const char *cnameu) +{ + Eina_Bool impl_same_class = (eolian_implement_class_get(impl) == cl); + if (impl_same_class && eolian_function_is_virtual_pure(fid, ftype)) + return; + + char *ocnamel = NULL; + if (!impl_same_class) + eo_gen_class_names_get(eolian_implement_class_get(impl), NULL, NULL, &ocnamel); + + char fname[256], iname[256]; + if (!impl_same_class) + snprintf(iname, sizeof(iname), "%s_%s", cnamel, ocnamel); + else + snprintf(iname, sizeof(iname), "%s", cnamel); + + snprintf(fname, sizeof(fname), "_%s_%s%s", iname, eolian_function_name_get(fid), + (ftype == EOLIAN_PROP_GET) + ? "_get" : ((ftype == EOLIAN_PROP_SET) ? "_set" : "")); + + if (_function_exists(fname, buf)) + { + free(ocnamel); + return; + } + + printf("generating function %s...\n", fname); + + Eina_Bool var_as_ret = EINA_FALSE; + const Eolian_Type *rtp = eolian_function_return_type_get(fid, ftype); + if ((ftype == EOLIAN_PROP_GET) && !rtp) + { + void *d1, *d2; + Eina_Iterator *itr = eolian_property_values_get(fid, ftype); + if (eina_iterator_next(itr, &d1) && !eina_iterator_next(itr, &d2)) + { + Eolian_Function_Parameter *pr = d1; + rtp = eolian_parameter_type_get(pr); + var_as_ret = EINA_TRUE; + } + eina_iterator_free(itr); + } + + eina_strbuf_append(buf, "EOLIAN static "); + if (rtp) + { + Eina_Stringshare *rtpn = eolian_type_c_type_get(rtp); + eina_strbuf_append(buf, rtpn); + eina_stringshare_del(rtpn); + } + else + eina_strbuf_append(buf, "void"); + + eina_strbuf_append_printf(buf, "\n%s(", fname); + + if (eolian_function_object_is_const(fid)) + eina_strbuf_append(buf, "const "); + + eina_strbuf_append(buf, "Eo *obj, "); + if (dtype[0]) + eina_strbuf_append_printf(buf, "%s *pd", dtype); + else + eina_strbuf_append(buf, "void *pd EINA_UNUSED"); + + /* gen params here */ + Eina_Strbuf *params = eina_strbuf_new(); + Eina_Strbuf *params_full = eina_strbuf_new(); + _gen_params(fid, ftype, var_as_ret, params, params_full); + + if (eina_strbuf_length_get(params_full)) + eina_strbuf_append(buf, eina_strbuf_string_get(params_full)); + + eina_strbuf_append(buf, ")\n{\n"); + + const char *efname = eolian_function_name_get(fid); + if (strlen(efname) >= (sizeof("destructor") - 1) && !impl_same_class) + if (!strcmp(efname + strlen(efname) - sizeof("destructor") + 1, "destructor")) + { + Eina_Stringshare *fcn = eolian_function_full_c_name_get(fid, ftype, EINA_FALSE); + eina_strbuf_append(buf, " "); + eina_strbuf_append(buf, fcn); + eina_stringshare_del(fcn); + eina_strbuf_append_printf(buf, "(efl_super(obj, %s_%s)", + cnameu, _cl_type_str_get(cl)); + if (eina_strbuf_length_get(params)) + eina_strbuf_append(buf, eina_strbuf_string_get(params)); + eina_strbuf_append(buf, ");\n"); + } + eina_strbuf_append(buf, "\n}\n\n"); + + eina_strbuf_free(params_full); + eina_strbuf_free(params); + free(ocnamel); +} + +void +eo_gen_impl_gen(const Eolian_Class *cl, Eina_Strbuf *buf) +{ + if (!cl) + return; + + char *cname = NULL, *cnameu = NULL, *cnamel = NULL; + eo_gen_class_names_get(cl, &cname, &cnameu, &cnamel); + + Eina_Strbuf *beg = eina_strbuf_new(); + + if (!_type_exists("EFL_BETA_API_SUPPORT", buf)) + { + printf("generating EFL_BETA_API_SUPPORT...\n"); + eina_strbuf_append(beg, "#define EFL_BETA_API_SUPPORT\n"); + } + + if (!_type_exists("", buf)) + { + printf("generating includes for and \"%s.eo.h\"...\n", cnamel); + eina_strbuf_append(beg, "#include \n"); + eina_strbuf_append_printf(beg, "#include \"%s.eo.h\"\n\n", cnamel); + } + + /* determine data type name */ + char *dt = _get_data_type(cl); + char adt[128]; + if (dt && !strcmp(dt, "null")) + adt[0] = '\0'; + else if (dt) + snprintf(adt, sizeof(adt), "%s", dt); + else + snprintf(adt, sizeof(adt), "%s_Data", cname); + free(dt); + + /* generate data type struct */ + if (adt[0] && !_type_exists(adt, buf)) + { + printf("generating data type structure %s...\n", adt); + eina_strbuf_append_printf(beg, "typedef struct\n{\n\n} %s;\n\n", adt); + } + + if (eina_strbuf_length_get(beg)) + eina_strbuf_prepend(buf, eina_strbuf_string_get(beg)); + + eina_strbuf_free(beg); + + /* method section */ + { + Eina_Iterator *itr = eolian_class_implements_get(cl); + const Eolian_Implement *imp; + EINA_ITERATOR_FOREACH(itr, imp) + { + Eolian_Function_Type ftype = EOLIAN_UNRESOLVED; + const Eolian_Function *fid = eolian_implement_function_get(imp, &ftype); + switch (ftype) + { + case EOLIAN_PROP_GET: + case EOLIAN_PROP_SET: + _gen_proto(cl, fid, ftype, buf, imp, adt, cnamel, cnameu); + break; + case EOLIAN_PROPERTY: + _gen_proto(cl, fid, EOLIAN_PROP_SET, buf, imp, adt, cnamel, cnameu); + _gen_proto(cl, fid, EOLIAN_PROP_GET, buf, imp, adt, cnamel, cnameu); + break; + default: + _gen_proto(cl, fid, EOLIAN_UNRESOLVED, buf, imp, adt, cnamel, cnameu); + } + } + eina_iterator_free(itr); + } + + if (eolian_class_ctor_enable_get(cl)) + { + char fname[128]; + snprintf(fname, sizeof(fname), "_%s_class_constructor", cnamel); + if (!_function_exists(fname, buf)) + { + printf("generating function %s...\n", fname); + eina_strbuf_append_printf(buf, + "EOLIAN static void\n" + "_%s_class_constructor(Efl_Class *klass)\n" + "{\n\n" + "}\n\n", cnamel); + } + } + + if (eolian_class_dtor_enable_get(cl)) + { + char fname[128]; + snprintf(fname, sizeof(fname), "_%s_class_destructor", cnamel); + if (!_function_exists(fname, buf)) + { + printf("generating function %s...\n", fname); + eina_strbuf_append_printf(buf, + "EOLIAN static void\n" + "_%s_class_destructor(Efl_Class *klass)\n" + "{\n\n" + "}\n\n", cnamel); + } + } + + printf("removing includes for \"%s.eo.c\"\n", cnamel); + char ibuf[512]; + snprintf(ibuf, sizeof(ibuf), "\n#include \"%s.eo.c\"\n", cnamel); + eina_strbuf_replace_all(buf, ibuf, "\n"); + + printf("generating include for \"%s.eo.c\"\n", cnamel); + eina_strbuf_append_printf(buf, "#include \"%s.eo.c\"\n", cnamel); + + free(cname); + free(cnameu); + free(cnamel); +} diff --git a/src/bin/eolian/sources.h b/src/bin/eolian/sources.h new file mode 100644 index 0000000000..05d711458b --- /dev/null +++ b/src/bin/eolian/sources.h @@ -0,0 +1,9 @@ +#ifndef EOLIAN_GEN_SOURCES_H +#define EOLIAN_GEN_SOURCES_H + +#include "main.h" + +void eo_gen_source_gen(const Eolian_Class *cl, Eina_Strbuf *buf); +void eo_gen_impl_gen(const Eolian_Class *cl, Eina_Strbuf *buf); + +#endif diff --git a/src/bin/eolian/types.c b/src/bin/eolian/types.c new file mode 100644 index 0000000000..b1db266a67 --- /dev/null +++ b/src/bin/eolian/types.c @@ -0,0 +1,191 @@ +#include "main.h" +#include "docs.h" + +static Eina_Strbuf * +_type_generate(const Eolian_Typedecl *tp, Eina_Bool full, Eina_Bool legacy) +{ + char *grp = strdup(eolian_typedecl_full_name_get(tp)); + char *p = strrchr(grp, '.'); + if (p) *p = '\0'; + Eina_Strbuf *buf = eo_gen_docs_full_gen(eolian_typedecl_documentation_get(tp), + grp, 0, legacy); + free(grp); + if (!buf) buf = eina_strbuf_new(); + else eina_strbuf_append_char(buf, '\n'); + Eolian_Typedecl_Type tpt = eolian_typedecl_type_get(tp); + switch (tpt) + { + case EOLIAN_TYPEDECL_ALIAS: + { + Eina_Stringshare *tn = eolian_typedecl_c_type_get(tp); + eina_strbuf_append(buf, tn); + eina_stringshare_del(tn); + break; + } + case EOLIAN_TYPEDECL_STRUCT: + case EOLIAN_TYPEDECL_STRUCT_OPAQUE: + { + const Eolian_Struct_Type_Field *memb; + char *fn = eo_gen_c_full_name_get(eolian_typedecl_full_name_get(tp)); + if (tpt == EOLIAN_TYPEDECL_STRUCT_OPAQUE || !full) + { + eina_strbuf_append_printf(buf, "typedef struct _%s %s", fn, fn); + free(fn); + break; + } + eina_strbuf_append_printf(buf, "typedef struct _%s\n{\n", fn); + Eina_Iterator *membs = eolian_typedecl_struct_fields_get(tp); + EINA_ITERATOR_FOREACH(membs, memb) + { + const Eolian_Type *mtp = eolian_typedecl_struct_field_type_get(memb); + Eina_Stringshare *ct = NULL; + if (eolian_type_type_get(mtp) == EOLIAN_TYPE_STATIC_ARRAY) + { + ct = eolian_type_c_type_get(eolian_type_base_type_get(mtp)); + eina_strbuf_append_printf(buf, " %s%s%s[%zu];", + ct, strchr(ct, '*') ? "" : " ", + eolian_typedecl_struct_field_name_get(memb), + eolian_type_array_size_get(mtp)); + } + else + { + ct = eolian_type_c_type_get(mtp); + eina_strbuf_append_printf(buf, " %s%s%s;", + ct, strchr(ct, '*') ? "" : " ", + eolian_typedecl_struct_field_name_get(memb)); + } + eina_stringshare_del(ct); + const Eolian_Documentation *fdoc + = eolian_typedecl_struct_field_documentation_get(memb); + if (fdoc) + { + const char *nl = strrchr(eina_strbuf_string_get(buf), '\n'); + if (nl) + { + Eina_Strbuf *fbuf = eo_gen_docs_full_gen(fdoc, NULL, + strlen(nl), legacy); + if (fbuf) + eina_strbuf_append_printf(buf, " %s", + eina_strbuf_string_get(fbuf)); + eina_strbuf_free(fbuf); + } + } + eina_strbuf_append(buf, "\n"); + } + eina_iterator_free(membs); + eina_strbuf_append_printf(buf, "} %s", fn); + free(fn); + break; + } + case EOLIAN_TYPEDECL_ENUM: + { + const Eolian_Enum_Type_Field *memb; + if (!full) + break; + eina_strbuf_append_printf(buf, "typedef enum\n{\n"); + Eina_Iterator *membs = eolian_typedecl_enum_fields_get(tp); + Eina_Bool next = eina_iterator_next(membs, (void **)&memb); + while (next) + { + const Eolian_Expression *vale = + eolian_typedecl_enum_field_value_get(memb, EINA_FALSE); + Eina_Stringshare *membn = + eolian_typedecl_enum_field_c_name_get(memb); + if (!vale) + eina_strbuf_append_printf(buf, " %s", membn); + else + { + Eolian_Value val = + eolian_expression_eval(vale, EOLIAN_MASK_INT); + const char *lit = eolian_expression_value_to_literal(&val); + eina_strbuf_append_printf(buf, " %s = %s", membn, lit); + const char *exp = eolian_expression_serialize(vale); + if (exp && strcmp(lit, exp)) + eina_strbuf_append_printf(buf, " /* %s */", exp); + eina_stringshare_del(exp); + eina_stringshare_del(lit); + } + eina_stringshare_del(membn); + const Eolian_Documentation *fdoc + = eolian_typedecl_enum_field_documentation_get(memb); + next = eina_iterator_next(membs, (void **)&memb); + if (next) + eina_strbuf_append(buf, ","); + if (fdoc) + { + const char *nl = strrchr(eina_strbuf_string_get(buf), '\n'); + if (nl) + { + Eina_Strbuf *fbuf = eo_gen_docs_full_gen(fdoc, NULL, + strlen(nl), legacy); + if (fbuf) + eina_strbuf_append_printf(buf, " %s", + eina_strbuf_string_get(fbuf)); + eina_strbuf_free(fbuf); + } + } + eina_strbuf_append(buf, "\n"); + } + eina_iterator_free(membs); + char *fn = eo_gen_c_full_name_get(eolian_typedecl_full_name_get(tp)); + eina_strbuf_append_printf(buf, "} %s", fn); + free(fn); + break; + } + default: + eina_strbuf_reset(buf); + break; + } + return buf; +} + +void eo_gen_types_header_gen(const char *eof, Eina_Strbuf *buf, + Eina_Bool full, Eina_Bool legacy) +{ + const Eolian_Declaration *decl; + + Eina_Iterator *itr = eolian_declarations_get_by_file(eof); + EINA_ITERATOR_FOREACH(itr, decl) + { + Eolian_Declaration_Type dt = eolian_declaration_type_get(decl); + if ((dt != EOLIAN_DECL_ALIAS) && + (dt != EOLIAN_DECL_STRUCT) && + (dt != EOLIAN_DECL_ENUM)) + continue; + if (dt == EOLIAN_DECL_ENUM && !full) + continue; + + const Eolian_Typedecl *tp = eolian_declaration_data_type_get(decl); + if (!tp || eolian_typedecl_is_extern(tp)) + continue; + + if (eolian_typedecl_type_get(tp) == EOLIAN_TYPEDECL_ALIAS) + { + const Eolian_Type *btp = eolian_typedecl_base_type_get(tp); + if (eolian_type_type_get(btp) == EOLIAN_TYPE_UNDEFINED) + continue; + } + + Eina_Strbuf *tbuf = _type_generate(tp, full, legacy); + if (tbuf) + { + eina_strbuf_append(buf, eina_strbuf_string_get(tbuf)); + eina_strbuf_append(buf, ";\n\n"); + eina_strbuf_free(tbuf); + } + } +} + +Eina_Strbuf *eo_gen_class_typedef_gen(const char *eof) +{ + const Eolian_Class *cl = eolian_class_get_by_file(eof); + if (!cl) + return NULL; + char *clfn = eo_gen_c_full_name_get(eolian_class_full_name_get(cl)); + if (!clfn) + return NULL; + Eina_Strbuf *ret = eina_strbuf_new(); + eina_strbuf_append_printf(ret, "typedef Eo %s;\n", clfn); + free(clfn); + return ret; +} diff --git a/src/bin/eolian/types.h b/src/bin/eolian/types.h new file mode 100644 index 0000000000..609d097287 --- /dev/null +++ b/src/bin/eolian/types.h @@ -0,0 +1,8 @@ +#ifndef EOLIAN_GEN_TYPES_H +#define EOLIAN_GEN_TYPES_H + +void eo_gen_types_header_gen(const char *eof, Eina_Strbuf *buf, + Eina_Bool full, Eina_Bool legacy); +Eina_Strbuf *eo_gen_class_typedef_gen(const char *eof); + +#endif diff --git a/src/bin/eolian/types_generator.c b/src/bin/eolian/types_generator.c deleted file mode 100644 index 54ed1d75b5..0000000000 --- a/src/bin/eolian/types_generator.c +++ /dev/null @@ -1,225 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include - -#include "Eolian.h" -#include "types_generator.h" -#include "docs_generator.h" -#include "common_funcs.h" - -static char * -_concat_name(const Eolian_Typedecl *tp) -{ - const char *name; - char *str = NULL; - Eina_Strbuf *buf = eina_strbuf_new(); - Eina_Iterator *itr = eolian_typedecl_namespaces_get(tp); - EINA_ITERATOR_FOREACH(itr, name) - if (name) eina_strbuf_append_printf(buf, "%s_", name); - eina_iterator_free(itr); - name = eolian_typedecl_name_get(tp); - if (name) eina_strbuf_append_printf(buf, "%s", name); - if (eina_strbuf_length_get(buf)) - { - char *tmp = str = eina_strbuf_string_steal(buf); - *tmp = toupper(*tmp); - while (*tmp) if (*tmp++ == '_' && *tmp) *tmp = toupper(*tmp); - } - eina_strbuf_free(buf); - return str; -} - -static Eina_Strbuf * -_type_generate(const Eolian_Typedecl *tp, Eina_Bool full, Eina_Bool use_legacy) -{ - char *grp = strdup(eolian_typedecl_full_name_get(tp)); - char *p = strrchr(grp, '.'); - if (p) *p = '\0'; - Eina_Strbuf *buf = docs_generate_full(eolian_typedecl_documentation_get(tp), - grp, 0, use_legacy); - free(grp); - if (!buf) buf = eina_strbuf_new(); - else eina_strbuf_append_char(buf, '\n'); - Eolian_Typedecl_Type tp_type = eolian_typedecl_type_get(tp); - switch(tp_type) - { - case EOLIAN_TYPEDECL_ALIAS: - { - Eina_Stringshare *tn = eolian_typedecl_c_type_get(tp); - eina_strbuf_append(buf, tn); - eina_stringshare_del(tn); - break; - } - case EOLIAN_TYPEDECL_STRUCT: - case EOLIAN_TYPEDECL_STRUCT_OPAQUE: - { - const Eolian_Struct_Type_Field *member; - char *name = _concat_name(tp); - if (tp_type == EOLIAN_TYPEDECL_STRUCT_OPAQUE || !full) - { - eina_strbuf_append_printf(buf, "typedef struct _%s %s", name, name); - free(name); - break; - } - eina_strbuf_append_printf(buf, "typedef struct _%s\n{\n", name); - Eina_Iterator *members = eolian_typedecl_struct_fields_get(tp); - EINA_ITERATOR_FOREACH(members, member) - { - const Eolian_Type *type = eolian_typedecl_struct_field_type_get(member); - Eina_Stringshare *c_type = NULL; - if (eolian_type_type_get(type) == EOLIAN_TYPE_STATIC_ARRAY) - { - c_type = eolian_type_c_type_get(eolian_type_base_type_get(type)); - eina_strbuf_append_printf(buf, " %s%s%s[%zu];", - c_type, strchr(c_type, '*')?"":" ", - eolian_typedecl_struct_field_name_get(member), - eolian_type_array_size_get(type)); - } - else - { - c_type = eolian_type_c_type_get(type); - eina_strbuf_append_printf(buf, " %s%s%s;", - c_type, strchr(c_type, '*')?"":" ", - eolian_typedecl_struct_field_name_get(member)); - } - eina_stringshare_del(c_type); - const Eolian_Documentation *fdoc - = eolian_typedecl_struct_field_documentation_get(member); - if (fdoc) - { - const char *nl = strrchr(eina_strbuf_string_get(buf), '\n'); - if (nl) - { - Eina_Strbuf *fbuf = docs_generate_full(fdoc, NULL, strlen(nl), use_legacy); - if (fbuf) - eina_strbuf_append_printf(buf, " %s", - eina_strbuf_string_get(fbuf)); - eina_strbuf_free(fbuf); - } - } - eina_strbuf_append(buf, "\n"); - } - eina_iterator_free(members); - eina_strbuf_append_printf(buf, "} %s", name); - free(name); - break; - } - case EOLIAN_TYPEDECL_ENUM: - { - const Eolian_Enum_Type_Field *member; - if (!full) - break; - char *name = _concat_name(tp); - eina_strbuf_append_printf(buf, "typedef enum\n{\n"); - Eina_Iterator *members = eolian_typedecl_enum_fields_get(tp); - Eina_Bool next = eina_iterator_next(members, (void**)&member); - while (next) - { - const Eolian_Expression *value = eolian_typedecl_enum_field_value_get(member, EINA_FALSE); - Eina_Stringshare *membn = eolian_typedecl_enum_field_c_name_get(member); - if (!value) - eina_strbuf_append_printf(buf, " %s", membn); - else - { - Eolian_Value val = eolian_expression_eval(value, EOLIAN_MASK_INT); - const char *lit = eolian_expression_value_to_literal(&val); - eina_strbuf_append_printf(buf, " %s = %s", membn, lit); - const char *exp = eolian_expression_serialize(value); - if (exp && strcmp(lit, exp)) - { - eina_strbuf_append_printf(buf, " /* %s */", exp); - eina_stringshare_del(exp); - } - eina_stringshare_del(lit); - } - eina_stringshare_del(membn); - const Eolian_Documentation *fdoc - = eolian_typedecl_enum_field_documentation_get(member); - next = eina_iterator_next(members, (void**)&member); - if (next) - eina_strbuf_append(buf, ","); - if (fdoc) - { - const char *nl = strrchr(eina_strbuf_string_get(buf), '\n'); - if (nl) - { - Eina_Strbuf *fbuf = docs_generate_full(fdoc, NULL, strlen(nl), use_legacy); - if (fbuf) - eina_strbuf_append_printf(buf, " %s", - eina_strbuf_string_get(fbuf)); - eina_strbuf_free(fbuf); - } - } - eina_strbuf_append(buf, "\n"); - } - eina_strbuf_append_printf(buf, "} %s", name); - free(name); - eina_iterator_free(members); - break; - } - default: - { - eina_strbuf_reset(buf); - } - } - return buf; -} - -Eina_Bool -types_header_generate(const char *eo_filename, Eina_Strbuf *buf, Eina_Bool full, Eina_Bool use_legacy) -{ - const Eolian_Declaration *decl; - - Eina_Iterator *itr = eolian_declarations_get_by_file(eo_filename); - EINA_ITERATOR_FOREACH(itr, decl) - { - Eolian_Declaration_Type dt = eolian_declaration_type_get(decl); - if (dt != EOLIAN_DECL_ALIAS && - dt != EOLIAN_DECL_STRUCT && - dt != EOLIAN_DECL_ENUM) - continue; - - if (dt == EOLIAN_DECL_ENUM && !full) - continue; - - const Eolian_Typedecl *tp = eolian_declaration_data_type_get(decl); - if (!tp || eolian_typedecl_is_extern(tp)) - continue; - - if (eolian_typedecl_type_get(tp) == EOLIAN_TYPEDECL_ALIAS) - { - const Eolian_Type *btp = eolian_typedecl_base_type_get(tp); - if (eolian_type_type_get(btp) == EOLIAN_TYPE_UNDEFINED) - continue; - } - - Eina_Strbuf *tbuf = _type_generate(tp, full, use_legacy); - if (tbuf) - { - eina_strbuf_append(buf, eina_strbuf_string_get(tbuf)); - eina_strbuf_append(buf, ";\n\n"); - eina_strbuf_free(tbuf); - } - } - eina_iterator_free(itr); - - return EINA_TRUE; -} - -Eina_Bool -types_class_typedef_generate(const char *eo_filename, Eina_Strbuf *buf) -{ - const Eolian_Class *class = eolian_class_get_by_file(eo_filename); - if (!class) - return EINA_FALSE; - - static _eolian_class_vars class_env; - _class_env_create(class, NULL, &class_env); - - eina_strbuf_append_printf(buf, "typedef Eo %s;\n", class_env.full_classname); - return EINA_TRUE; -} diff --git a/src/bin/eolian/types_generator.h b/src/bin/eolian/types_generator.h deleted file mode 100644 index 5096614217..0000000000 --- a/src/bin/eolian/types_generator.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef TYPES_GENERATOR_H -#define TYPES_GENERATOR_H - -#include - -/* - * @brief Generate the header code for the types of a specific file. - * - * @param[in] eo_filename Eo filename - * @param[inout] buf buffer to fill - * @param[in]full whether to generate full type definitions - * @param[in] use_legacy whether to use legacy names - * - * @return EINA_TRUE on success, EINA_FALSE on error. - * - */ -Eina_Bool types_header_generate(const char *eo_filename, Eina_Strbuf *buf, Eina_Bool full, Eina_Bool use_legacy); - -Eina_Bool types_class_typedef_generate(const char *eo_filename, Eina_Strbuf *buf); - -#endif - diff --git a/src/tests/eolian/data/class_simple_ref.c b/src/tests/eolian/data/class_simple_ref.c index 290aaa01d5..13ec8205b5 100644 --- a/src/tests/eolian/data/class_simple_ref.c +++ b/src/tests/eolian/data/class_simple_ref.c @@ -11,9 +11,9 @@ void _class_simple_b_set(Eo *obj, Evas_Simple_Data *pd); EOAPI EFL_VOID_FUNC_BODY(efl_canvas_object_simple_b_set); -char * _class_simple_foo(Eo *obj, Evas_Simple_Data *pd, int a, char *b, double *c, int *d); +char *_class_simple_foo(Eo *obj, Evas_Simple_Data *pd, int a, char *b, double *c, int *d); -static char * __eolian_class_simple_foo(Eo *obj, Evas_Simple_Data *pd, int a, char *b, double *c, int *d) +static char *__eolian_class_simple_foo(Eo *obj, Evas_Simple_Data *pd, int a, char *b, double *c, int *d) { if (c) *c = 1337.600000; return _class_simple_foo(obj, pd, a, b, c, d); @@ -21,7 +21,7 @@ static char * __eolian_class_simple_foo(Eo *obj, Evas_Simple_Data *pd, int a, ch EOAPI EFL_FUNC_BODYV(efl_canvas_object_simple_foo, char *, NULL, EFL_FUNC_CALL(a, b, c, d), int a, char *b, double *c, int *d); -int * _class_simple_bar(Eo *obj, Evas_Simple_Data *pd, int x); +int *_class_simple_bar(Eo *obj, Evas_Simple_Data *pd, int x); EOAPI EFL_FUNC_BODYV(efl_canvas_object_simple_bar, int *, 0, EFL_FUNC_CALL(x), int x); @@ -31,20 +31,33 @@ _class_simple_class_initializer(Efl_Class *klass) EFL_OPS_DEFINE(ops, EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_a_set, _class_simple_a_set), EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_a_get, _class_simple_a_get), - EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_foo, __eolian_class_simple_foo) + EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_b_set, _class_simple_b_set), + EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_foo, __eolian_class_simple_foo), + EFL_OBJECT_OP_FUNC(efl_canvas_object_simple_bar, _class_simple_bar) ); - return efl_class_functions_set(klass, &ops, NULL); } static const Efl_Class_Description _class_simple_class_desc = { - EO_VERSION, - "Class_Simple", - EFL_CLASS_TYPE_REGULAR, - sizeof(Evas_Simple_Data), - _class_simple_class_initializer, - NULL, - NULL + EO_VERSION, + "Class_Simple", + EFL_CLASS_TYPE_REGULAR, + sizeof(Evas_Simple_Data), + _class_simple_class_initializer, + NULL, + NULL }; EFL_DEFINE_CLASS(class_simple_class_get, &_class_simple_class_desc, NULL, NULL); + +EAPI void +evas_object_simple_b_set(Class_Simple *obj) +{ + efl_canvas_object_simple_b_set(obj); +} + +EAPI int * +evas_object_simple_bar(Class_Simple *obj, int x) +{ + return efl_canvas_object_simple_bar(obj, x); +} diff --git a/src/tests/eolian/data/class_simple_ref_eo.h b/src/tests/eolian/data/class_simple_ref_eo.h index c3b5d3ea8a..4e4102b24a 100644 --- a/src/tests/eolian/data/class_simple_ref_eo.h +++ b/src/tests/eolian/data/class_simple_ref_eo.h @@ -1,5 +1,5 @@ -#ifndef _EOLIAN_OUTPUT_H_ -#define _EOLIAN_OUTPUT_H_ +#ifndef _EOLIAN_CLASS_SIMPLE_H_ +#define _EOLIAN_CLASS_SIMPLE_H_ #ifndef _CLASS_SIMPLE_EO_CLASS_TYPE #define _CLASS_SIMPLE_EO_CLASS_TYPE @@ -67,5 +67,4 @@ EOAPI char *efl_canvas_object_simple_foo(Eo *obj, int a, char *b, double *c, int EOAPI int *efl_canvas_object_simple_bar(Eo *obj, int x); - #endif diff --git a/src/tests/eolian/data/class_simple_ref_legacy.h b/src/tests/eolian/data/class_simple_ref_legacy.h index d666d12177..12ef57a97c 100644 --- a/src/tests/eolian/data/class_simple_ref_legacy.h +++ b/src/tests/eolian/data/class_simple_ref_legacy.h @@ -1,5 +1,5 @@ -#ifndef _EOLIAN_OUTPUT_H_ -#define _EOLIAN_OUTPUT_H_ +#ifndef _EOLIAN_CLASS_SIMPLE_LEGACY_H_ +#define _EOLIAN_CLASS_SIMPLE_LEGACY_H_ #ifndef _CLASS_SIMPLE_EO_CLASS_TYPE #define _CLASS_SIMPLE_EO_CLASS_TYPE @@ -13,11 +13,9 @@ typedef Eo Class_Simple; #endif -/** Class Desc Simple - * - * @ingroup Class_Simple - */ + EAPI void evas_object_simple_b_set(Class_Simple *obj); + EAPI int *evas_object_simple_bar(Class_Simple *obj, int x); #endif diff --git a/src/tests/eolian/data/docs_ref.h b/src/tests/eolian/data/docs_ref.h index 66c143415f..fba24d0702 100644 --- a/src/tests/eolian/data/docs_ref.h +++ b/src/tests/eolian/data/docs_ref.h @@ -1,5 +1,5 @@ -#ifndef _EOLIAN_OUTPUT_H_ -#define _EOLIAN_OUTPUT_H_ +#ifndef _EOLIAN_DOCS_H_ +#define _EOLIAN_DOCS_H_ #ifndef _DOCS_EO_CLASS_TYPE #define _DOCS_EO_CLASS_TYPE diff --git a/src/tests/eolian/data/docs_ref_legacy.h b/src/tests/eolian/data/docs_ref_legacy.h index bff531352e..677d15a8ee 100644 --- a/src/tests/eolian/data/docs_ref_legacy.h +++ b/src/tests/eolian/data/docs_ref_legacy.h @@ -1,5 +1,5 @@ -#ifndef _EOLIAN_OUTPUT_H_ -#define _EOLIAN_OUTPUT_H_ +#ifndef _EOLIAN_DOCS_LEGACY_H_ +#define _EOLIAN_DOCS_LEGACY_H_ #ifndef _DOCS_EO_CLASS_TYPE #define _DOCS_EO_CLASS_TYPE @@ -64,17 +64,6 @@ typedef struct _Opaque Opaque; #endif -/** - * @brief Docs for class. - * - * More docs for class. Testing references now. @ref Foo @ref Bar @ref Alias - * @ref pants @ref docs_meth @ref docs_prop_get @ref docs_prop_get - * @ref docs_prop_set @ref Foo.field1 @ref Bar.BAR_FOO @ref Docs - * - * @since 1.18 - * - * @ingroup Docs - */ /** * @brief Property common documentation. diff --git a/src/tests/eolian/data/override_ref.c b/src/tests/eolian/data/override_ref.c index 31994cd9f0..e8dacf5cf0 100644 --- a/src/tests/eolian/data/override_ref.c +++ b/src/tests/eolian/data/override_ref.c @@ -1,4 +1,7 @@ +void _override_base_constructor(Eo *obj, Override_Data *pd); + + static void __eolian_override_b_set(Eo *obj EINA_UNUSED, Override_Data *pd, int idx EINA_UNUSED, float a, char b, int c) { a = pd->a; @@ -22,6 +25,19 @@ static int __eolian_override_c_get(Eo *obj EINA_UNUSED, Override_Data *pd EINA_U } EOAPI EFL_FUNC_BODYV_CONST(override_c_get, int, 50, EFL_FUNC_CALL(idx), int idx); + +static void __eolian_override_base_z_get(Eo *obj EINA_UNUSED, Override_Data *pd, int *a, char *b, float *c) +{ + if (a) *a = pd->a; + if (b) *b = pd->b; + if (c) *c = pd->c; +} + + +static void __eolian_override_base_z_set(Eo *obj EINA_UNUSED, Override_Data *pd EINA_UNUSED, int a EINA_UNUSED, char b EINA_UNUSED, float c EINA_UNUSED) +{ +} + EOAPI EFL_VOID_FUNC_BODY(override_a_set); void _override_a_get(Eo *obj, Override_Data *pd); @@ -37,50 +53,33 @@ void _override_c_set(Eo *obj, Override_Data *pd, int idx, int c); EOAPI EFL_VOID_FUNC_BODYV(override_c_set, EFL_FUNC_CALL(idx, c), int idx, int c); EOAPI EFL_VOID_FUNC_BODY(override_foo); -void _override_base_constructor(Eo *obj, Override_Data *pd); - - -static void __eolian_override_base_z_get(Eo *obj EINA_UNUSED, Override_Data *pd, int *a, char *b, float *c) -{ - if (a) *a = pd->a; - if (b) *b = pd->b; - if (c) *c = pd->c; -} - - -static void __eolian_override_base_z_set(Eo *obj EINA_UNUSED, Override_Data *pd EINA_UNUSED, int a EINA_UNUSED, char b EINA_UNUSED, float c EINA_UNUSED) -{ -} - - static Eina_Bool _override_class_initializer(Efl_Class *klass) { EFL_OPS_DEFINE(ops, EFL_OBJECT_OP_FUNC(base_constructor, _override_base_constructor), - EFL_OBJECT_OP_FUNC(base_z_get, __eolian_override_base_z_get), - EFL_OBJECT_OP_FUNC(base_z_set, __eolian_override_base_z_set), EFL_OBJECT_OP_FUNC(override_b_set, __eolian_override_b_set), EFL_OBJECT_OP_FUNC(override_bar, __eolian_override_bar), EFL_OBJECT_OP_FUNC(override_c_get, __eolian_override_c_get), + EFL_OBJECT_OP_FUNC(base_z_get, __eolian_override_base_z_get), + EFL_OBJECT_OP_FUNC(base_z_set, __eolian_override_base_z_set), EFL_OBJECT_OP_FUNC(override_a_set, NULL), EFL_OBJECT_OP_FUNC(override_a_get, _override_a_get), EFL_OBJECT_OP_FUNC(override_b_get, _override_b_get), EFL_OBJECT_OP_FUNC(override_c_set, _override_c_set), EFL_OBJECT_OP_FUNC(override_foo, NULL) ); - return efl_class_functions_set(klass, &ops, NULL); } static const Efl_Class_Description _override_class_desc = { - EO_VERSION, - "Override", - EFL_CLASS_TYPE_REGULAR, - sizeof(Override_Data), - _override_class_initializer, - NULL, - NULL + EO_VERSION, + "Override", + EFL_CLASS_TYPE_REGULAR, + sizeof(Override_Data), + _override_class_initializer, + NULL, + NULL }; EFL_DEFINE_CLASS(override_class_get, &_override_class_desc, BASE_CLASS, NULL); diff --git a/src/tests/eolian/data/struct_ref.c b/src/tests/eolian/data/struct_ref.c index 6322bb9435..cb64af6cb3 100644 --- a/src/tests/eolian/data/struct_ref.c +++ b/src/tests/eolian/data/struct_ref.c @@ -1,5 +1,5 @@ -#ifndef _TYPES_OUTPUT_C_ -#define _TYPES_OUTPUT_C_ +#ifndef _EOLIAN_TYPEDEF_H_ +#define _EOLIAN_TYPEDEF_H_ #ifndef _STRUCT_EO_CLASS_TYPE #define _STRUCT_EO_CLASS_TYPE @@ -43,5 +43,4 @@ EOAPI char *struct_foo(Eo *obj, int idx); EOAPI Named *struct_bar(Eo *obj); - #endif diff --git a/src/tests/eolian/data/struct_ref_stub.c b/src/tests/eolian/data/struct_ref_stub.c index 3ad9709bd9..19ed7140c0 100644 --- a/src/tests/eolian/data/struct_ref_stub.c +++ b/src/tests/eolian/data/struct_ref_stub.c @@ -1,5 +1,5 @@ -#ifndef _TYPES_OUTPUT_C_STUBS -#define _TYPES_OUTPUT_C_STUBS +#ifndef _EOLIAN_TYPEDEF_STUB_H_STUBS +#define _EOLIAN_TYPEDEF_STUB_H_STUBS typedef Eo Struct; diff --git a/src/tests/eolian/data/typedef.eo b/src/tests/eolian/data/typedef.eo index 6c87ccdf31..15ebbf7cc4 100644 --- a/src/tests/eolian/data/typedef.eo +++ b/src/tests/eolian/data/typedef.eo @@ -20,7 +20,7 @@ enum Enum.Bar last_item } -enum Elm.Object.Select_mode +enum Elm.Object.Select_Mode { default = 0, always, diff --git a/src/tests/eolian/data/typedef_ref.c b/src/tests/eolian/data/typedef_ref.c index c5c3339072..61d451ebfa 100644 --- a/src/tests/eolian/data/typedef_ref.c +++ b/src/tests/eolian/data/typedef_ref.c @@ -1,5 +1,5 @@ -#ifndef _TYPES_OUTPUT_C_ -#define _TYPES_OUTPUT_C_ +#ifndef _EOLIAN_TYPEDEF_H_ +#define _EOLIAN_TYPEDEF_H_ #ifndef _TYPEDEF_EO_CLASS_TYPE #define _TYPEDEF_EO_CLASS_TYPE @@ -47,5 +47,4 @@ EWAPI const Efl_Class *typedef_class_get(void); EOAPI char *typedef_foo(Eo *obj, int idx); - #endif diff --git a/src/tests/eolian/data/typedef_ref_stub.c b/src/tests/eolian/data/typedef_ref_stub.c index cb5d53f143..3e1361557f 100644 --- a/src/tests/eolian/data/typedef_ref_stub.c +++ b/src/tests/eolian/data/typedef_ref_stub.c @@ -1,5 +1,5 @@ -#ifndef _TYPES_OUTPUT_C_STUBS -#define _TYPES_OUTPUT_C_STUBS +#ifndef _EOLIAN_TYPEDEF_STUB_H_STUBS +#define _EOLIAN_TYPEDEF_STUB_H_STUBS typedef Eo Typedef; diff --git a/src/tests/eolian/eolian_generation.c b/src/tests/eolian/eolian_generation.c index c63c641775..0607269305 100644 --- a/src/tests/eolian/eolian_generation.c +++ b/src/tests/eolian/eolian_generation.c @@ -15,17 +15,20 @@ #include "eolian_suite.h" static Eina_Bool -_files_compare (const char *ref_filename, const char *tmp_filename) +_files_compare (const char *ref_filename, const char *tmp_filename, const char *ext) { Eina_Bool result = EINA_FALSE; FILE *tmp_file = NULL, *ref_file = NULL; char *tmp_content = NULL, *ref_content = NULL; - tmp_file = fopen(tmp_filename, "rb"); + char ifnbuf[PATH_MAX]; + snprintf(ifnbuf, sizeof(ifnbuf), "%s.%s", tmp_filename, ext); + + tmp_file = fopen(ifnbuf, "rb"); if (!tmp_file) { - printf("Unable to open %s\n", tmp_filename); + printf("Unable to open %s\n", ifnbuf); goto end; } ref_file = fopen(ref_filename, "rb"); @@ -69,6 +72,14 @@ end: return result; } +static void +_remove_ref(const char *base, const char *ext) +{ + char ifnbuf[PATH_MAX]; + snprintf(ifnbuf, sizeof(ifnbuf), "%s.%s", base, ext); + remove(ifnbuf); +} + static int _eolian_gen_execute(const char *eo_filename, const char *options, const char *output_filename) { @@ -85,7 +96,7 @@ _eolian_gen_execute(const char *eo_filename, const char *options, const char *ou return -1; snprintf(command, PATH_MAX, - "%s %s -I "PACKAGE_DATA_DIR"/data -o %s %s", + "%s %s -I \""PACKAGE_DATA_DIR"/data\" -o %s %s", eolian_gen_path, options, output_filename, eo_filename); return system(command); } @@ -93,96 +104,96 @@ _eolian_gen_execute(const char *eo_filename, const char *options, const char *ou START_TEST(eolian_dev_impl_code) { char output_filepath[PATH_MAX] = ""; - snprintf(output_filepath, PATH_MAX, "%s/object_impl.c", + snprintf(output_filepath, PATH_MAX, "%s/eolian_object_impl", eina_environment_tmp_get()); - remove(output_filepath); - fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/object_impl.eo", "--gi", output_filepath)); - fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/object_impl_ref.c", output_filepath)); + _remove_ref(output_filepath, "c"); + fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/object_impl.eo", "-gi", output_filepath)); + fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/object_impl_ref.c", output_filepath, "c")); /* Check that nothing is added */ - fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/object_impl.eo", "--gi", output_filepath)); - fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/object_impl_ref.c", output_filepath)); - fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/object_impl_add.eo", "--gi", output_filepath)); - fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/object_impl_add_ref.c", output_filepath)); + fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/object_impl.eo", "-gi", output_filepath)); + fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/object_impl_ref.c", output_filepath, "c")); + fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/object_impl_add.eo", "-gi", output_filepath)); + fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/object_impl_add_ref.c", output_filepath, "c")); } END_TEST START_TEST(eolian_types_generation) { char output_filepath[PATH_MAX] = ""; - snprintf(output_filepath, PATH_MAX, "%s/types_output.c", + snprintf(output_filepath, PATH_MAX, "%s/eolian_typedef", eina_environment_tmp_get()); - remove(output_filepath); - fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/typedef.eo", "--gh", output_filepath)); - fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/typedef_ref.c", output_filepath)); - fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/struct.eo", "--gh", output_filepath)); - fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/struct_ref.c", output_filepath)); + _remove_ref(output_filepath, "h"); + _remove_ref(output_filepath, "stub.h"); + fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/typedef.eo", "-gh", output_filepath)); + fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/typedef_ref.c", output_filepath, "h")); + fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/struct.eo", "-gh", output_filepath)); + fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/struct_ref.c", output_filepath, "h")); - fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/typedef.eo", "--gs", output_filepath)); - fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/typedef_ref_stub.c", output_filepath)); - fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/struct.eo", "--gs", output_filepath)); - fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/struct_ref_stub.c", output_filepath)); + fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/typedef.eo", "-gs", output_filepath)); + fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/typedef_ref_stub.c", output_filepath, "stub.h")); + fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/struct.eo", "-gs", output_filepath)); + fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/struct_ref_stub.c", output_filepath, "stub.h")); } END_TEST START_TEST(eolian_default_values_generation) { char output_filepath[PATH_MAX] = ""; - snprintf(output_filepath, PATH_MAX, "%s/eolian_output.c", + snprintf(output_filepath, PATH_MAX, "%s/eolian_class_simple", eina_environment_tmp_get()); - remove(output_filepath); - fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/class_simple.eo", "--gc", output_filepath)); - fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/class_simple_ref.c", output_filepath)); + _remove_ref(output_filepath, "c"); + fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/class_simple.eo", "-gc", output_filepath)); + fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/class_simple_ref.c", output_filepath, "c")); } END_TEST START_TEST(eolian_override_generation) { char output_filepath[PATH_MAX] = ""; - snprintf(output_filepath, PATH_MAX, "%s/eolian_output.c", + snprintf(output_filepath, PATH_MAX, "%s/eolian_override", eina_environment_tmp_get()); - remove(output_filepath); - fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/override.eo", "--gc", output_filepath)); - fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/override_ref.c", output_filepath)); + _remove_ref(output_filepath, "c"); + fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/override.eo", "-gc", output_filepath)); + fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/override_ref.c", output_filepath, "c")); } END_TEST START_TEST(eolian_functions_descriptions) { char output_filepath[PATH_MAX] = ""; - snprintf(output_filepath, PATH_MAX, "%s/eolian_output.h", + snprintf(output_filepath, PATH_MAX, "%s/eolian_class_simple", eina_environment_tmp_get()); - remove(output_filepath); - fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/class_simple.eo", "--gh", output_filepath)); - fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/class_simple_ref_eo.h", output_filepath)); - remove(output_filepath); - fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/class_simple.eo", "--legacy --gh", output_filepath)); - fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/class_simple_ref_legacy.h", output_filepath)); + _remove_ref(output_filepath, "h"); + fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/class_simple.eo", "-gh", output_filepath)); + fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/class_simple_ref_eo.h", output_filepath, "h")); + _remove_ref(output_filepath, "legacy.h"); + fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/class_simple.eo", "-gl", output_filepath)); + fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/class_simple_ref_legacy.h", output_filepath, "legacy.h")); } END_TEST START_TEST(eolian_import) { char output_filepath[PATH_MAX] = ""; - snprintf(output_filepath, PATH_MAX, "%s/eolian_import_types.h", + snprintf(output_filepath, PATH_MAX, "%s/eolian_import_types", eina_environment_tmp_get()); - remove(output_filepath); - fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/import_types.eot", "--gh", output_filepath)); - fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/import_types_ref.h", output_filepath)); - remove(output_filepath); + _remove_ref(output_filepath, "h"); + fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/import_types.eot", "-gh", output_filepath)); + fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/import_types_ref.h", output_filepath, "h")); } END_TEST START_TEST(eolian_docs) { char output_filepath[PATH_MAX] = ""; - snprintf(output_filepath, PATH_MAX, "%s/eolian_output.h", + snprintf(output_filepath, PATH_MAX, "%s/eolian_docs", eina_environment_tmp_get()); - remove(output_filepath); - fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/docs.eo", "--gh", output_filepath)); - fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/docs_ref.h", output_filepath)); - remove(output_filepath); - fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/docs.eo", "--legacy --gh", output_filepath)); - fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/docs_ref_legacy.h", output_filepath)); + _remove_ref(output_filepath, "h"); + fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/docs.eo", "-gh", output_filepath)); + fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/docs_ref.h", output_filepath, "h")); + _remove_ref(output_filepath, "legacy.h"); + fail_if(0 != _eolian_gen_execute(PACKAGE_DATA_DIR"/data/docs.eo", "-gl", output_filepath)); + fail_if(!_files_compare(PACKAGE_DATA_DIR"/data/docs_ref_legacy.h", output_filepath, "legacy.h")); } END_TEST