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_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); const Eolian_Implement *fimp = eolian_function_implement_get(fid); Eina_Bool hasdoc = !!eolian_implement_documentation_get(fimp, ftype); if (!hasdoc && ((ftype == EOLIAN_PROP_GET) || (ftype == EOLIAN_PROP_SET))) hasdoc = !!eolian_implement_documentation_get(fimp, EOLIAN_PROPERTY); if (hasdoc) { Eina_Strbuf *dbuf = eo_gen_docs_func_gen(src, 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 (prtn[strlen(prtn) - 1] != '*') 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); }
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); }