static void _generate_ref(const char *refn, Eina_Strbuf *wbuf, Eina_Bool use_legacy) { const Eolian_Declaration *decl = eolian_declaration_get_by_name(refn); if (decl) { char *n = strdup(eolian_declaration_name_get(decl)); char *p = n; while ((p = strchr(p, '.'))) *p = '_'; eina_strbuf_append(wbuf, n); free(n); return; } /* not a plain declaration, so it must be struct/enum field or func */ const char *sfx = strrchr(refn, '.'); if (!sfx) goto noref; Eina_Stringshare *bname = eina_stringshare_add_length(refn, sfx - refn); const Eolian_Type *tp = eolian_type_struct_get_by_name(bname); if (tp) { if (!eolian_type_struct_field_get(tp, sfx + 1)) { eina_stringshare_del(bname); goto noref; } _generate_ref(bname, wbuf, use_legacy); eina_strbuf_append(wbuf, sfx); eina_stringshare_del(bname); return; } tp = eolian_type_enum_get_by_name(bname); if (tp) { const Eolian_Enum_Type_Field *efl = eolian_type_enum_field_get(tp, sfx + 1); if (!efl) { eina_stringshare_del(bname); goto noref; } _generate_ref(bname, wbuf, use_legacy); Eina_Stringshare *str = eolian_type_enum_field_c_name_get(efl); eina_strbuf_append_char(wbuf, '.'); eina_strbuf_append(wbuf, str); eina_stringshare_del(str); eina_stringshare_del(bname); return; } const Eolian_Class *cl = eolian_class_get_by_name(bname); const Eolian_Function *fn = NULL; Eolian_Function_Type ftype = EOLIAN_UNRESOLVED; if (!cl) { const char *mname; if (!strcmp(sfx, ".get")) ftype = EOLIAN_PROP_GET; else if (!strcmp(sfx, ".set")) ftype = EOLIAN_PROP_SET; if (ftype != EOLIAN_UNRESOLVED) { eina_stringshare_del(bname); mname = sfx - 1; while ((mname != refn) && (*mname != '.')) --mname; if (mname == refn) goto noref; bname = eina_stringshare_add_length(refn, mname - refn); cl = eolian_class_get_by_name(bname); eina_stringshare_del(bname); } if (cl) { char *meth = strndup(mname + 1, sfx - mname - 1); fn = eolian_class_function_get_by_name(cl, meth, ftype); if (ftype == EOLIAN_UNRESOLVED) ftype = eolian_function_type_get(fn); free(meth); } } else { fn = eolian_class_function_get_by_name(cl, sfx + 1, ftype); ftype = eolian_function_type_get(fn); } if (!fn) goto noref; Eina_Stringshare *fcn = eolian_function_full_c_name_get(fn, ftype, use_legacy); if (!fcn) goto noref; eina_strbuf_append(wbuf, fcn); eina_stringshare_del(fcn); return; noref: eina_strbuf_append(wbuf, refn); }
static void _gen_func(const Eolian_Unit *src, 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, ftype); Eina_Bool is_auto = eolian_implement_is_auto(impl, ftype); 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_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 (ptn[strlen(ptn) - 1] != '*') { 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 = ptn[strlen(ptn) - 1] == '*'; const char *add_star = _get_add_star(ftype, pd); if (eina_strbuf_length_get(params)) eina_strbuf_append(params, ", "); 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(src, 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); }
static void _generate_ref(const Eolian_State *state, const char *refn, Eina_Strbuf *wbuf) { const Eolian_Object *decl = eolian_state_object_by_name_get(state, refn); if (decl) { char *n = strdup(eolian_object_name_get(decl)); char *p = n; while ((p = strchr(p, '.'))) *p = '_'; if (eolian_object_type_get(decl) == EOLIAN_OBJECT_VARIABLE) { const Eolian_Variable *v = (const Eolian_Variable *)decl; /* constants are emitted as macros */ if (eolian_variable_type_get(v) == EOLIAN_VAR_CONSTANT) eina_str_toupper(&n); } eina_strbuf_append(wbuf, n); free(n); return; } /* not a plain declaration, so it must be struct/enum field or func */ const char *sfx = strrchr(refn, '.'); if (!sfx) goto noref; Eina_Stringshare *bname = eina_stringshare_add_length(refn, sfx - refn); const Eolian_Typedecl *tp = eolian_state_struct_by_name_get(state, bname); if (tp) { if (!eolian_typedecl_struct_field_get(tp, sfx + 1)) { eina_stringshare_del(bname); goto noref; } _generate_ref(state, bname, wbuf); eina_strbuf_append(wbuf, sfx); eina_stringshare_del(bname); return; } tp = eolian_state_enum_by_name_get(state, bname); if (tp) { const Eolian_Enum_Type_Field *efl = eolian_typedecl_enum_field_get(tp, sfx + 1); if (!efl) { eina_stringshare_del(bname); goto noref; } Eina_Stringshare *str = eolian_typedecl_enum_field_c_name_get(efl); eina_strbuf_append(wbuf, str); eina_stringshare_del(bname); return; } const Eolian_Class *cl = eolian_state_class_by_name_get(state, bname); const Eolian_Function *fn = NULL; /* match methods and properties; we're only figuring out existence */ Eolian_Function_Type ftype = EOLIAN_UNRESOLVED; if (!cl) { const char *mname = NULL; if (!strcmp(sfx, ".get")) ftype = EOLIAN_PROP_GET; else if (!strcmp(sfx, ".set")) ftype = EOLIAN_PROP_SET; if (ftype != EOLIAN_UNRESOLVED) { eina_stringshare_del(bname); mname = sfx - 1; while ((mname != refn) && (*mname != '.')) --mname; if (mname == refn) goto noref; bname = eina_stringshare_add_length(refn, mname - refn); cl = eolian_state_class_by_name_get(state, bname); eina_stringshare_del(bname); } if (cl) { char *meth = eina_strndup(mname + 1, sfx - mname - 1); fn = eolian_class_function_by_name_get(cl, meth, ftype); if (ftype == EOLIAN_UNRESOLVED) ftype = eolian_function_type_get(fn); free(meth); } } else { fn = eolian_class_function_by_name_get(cl, sfx + 1, ftype); ftype = eolian_function_type_get(fn); } if (!fn) goto noref; Eina_Stringshare *fcn = eolian_function_full_c_name_get(fn, ftype); if (!fcn) goto noref; eina_strbuf_append(wbuf, fcn); eina_stringshare_del(fcn); return; noref: eina_strbuf_append(wbuf, refn); }