static Eina_Bool eval_exp(const Eolian_Expression *expr, Eolian_Expression_Mask mask, Eolian_Expression *out) { switch (expr->type) { case EOLIAN_EXPR_INT: case EOLIAN_EXPR_LONG: case EOLIAN_EXPR_LLONG: { if (!(mask & EOLIAN_MASK_SINT)) return expr_type_error(expr, EOLIAN_MASK_SINT, mask); *out = *expr; return EINA_TRUE; } case EOLIAN_EXPR_UINT: case EOLIAN_EXPR_ULONG: case EOLIAN_EXPR_ULLONG: { if (!(mask & EOLIAN_MASK_UINT)) return expr_type_error(expr, EOLIAN_MASK_UINT, mask); *out = *expr; return EINA_TRUE; } case EOLIAN_EXPR_FLOAT: case EOLIAN_EXPR_DOUBLE: { if (!(mask & EOLIAN_MASK_FLOAT)) return expr_type_error(expr, EOLIAN_MASK_FLOAT, mask); *out = *expr; return EINA_TRUE; } case EOLIAN_EXPR_STRING: { if (!(mask & EOLIAN_MASK_STRING)) return expr_type_error(expr, EOLIAN_MASK_STRING, mask); *out = *expr; return EINA_TRUE; } case EOLIAN_EXPR_NULL: { if (!(mask & EOLIAN_MASK_NULL)) return expr_type_error(expr, EOLIAN_MASK_NULL, mask); *out = *expr; return EINA_TRUE; } case EOLIAN_EXPR_CHAR: { if (!(mask & EOLIAN_MASK_CHAR)) return expr_type_error(expr, EOLIAN_MASK_CHAR, mask); *out = *expr; return EINA_TRUE; } case EOLIAN_EXPR_BOOL: { if (!(mask & EOLIAN_MASK_BOOL)) return expr_type_error(expr, EOLIAN_MASK_BOOL, mask); *out = *expr; return EINA_TRUE; } case EOLIAN_EXPR_NAME: { const Eolian_Variable *var = eolian_variable_constant_get_by_name (expr->value.s); const Eolian_Expression *exp = NULL; if (!var) { const Eolian_Type *etp; const Eolian_Enum_Type_Field *fl; /* try aliases, hoping it'll be enum */ char *fulln = NULL, *memb = NULL; if (!split_enum_name(expr->value.s, &fulln, &memb)) return expr_error(expr, "undefined variable"); /* assert int here, as we're clearly dealing with enum */ if (!(mask & EOLIAN_MASK_INT)) return expr_type_error(expr, EOLIAN_MASK_INT, mask); etp = eolian_type_alias_get_by_name(fulln); while (etp && (etp->type == EOLIAN_TYPE_ALIAS || etp->type == EOLIAN_TYPE_REGULAR)) etp = eolian_type_base_type_get(etp); if (!etp) etp = eolian_type_enum_get_by_name(fulln); if (!etp || etp->type != EOLIAN_TYPE_ENUM) { free(fulln); return expr_error(expr, "undefined variable"); } fl = eolian_type_enum_field_get(etp, memb); if (fl) exp = eolian_type_enum_field_value_get(fl, EINA_TRUE); free(fulln); if (!exp) return expr_error(expr, "invalid enum field"); } else exp = var->value; if (!exp) return expr_error(expr, "undefined variable"); return eval_exp(exp, mask, out); } case EOLIAN_EXPR_UNARY: return eval_unary(expr, mask, out); case EOLIAN_EXPR_BINARY: return eval_binary(expr, mask, out); default: assert(EINA_FALSE); return EINA_FALSE; } return EINA_TRUE; }
static Eina_Bool _validate_ref(const char *ref, const Eolian_Object *info) { if (eolian_declaration_get_by_name(ref)) return EINA_TRUE; const char *suffix = strrchr(ref, '.'); if (!suffix) goto failed; Eina_Stringshare *base = eina_stringshare_add_length(ref, suffix - ref); const Eolian_Type *tp = eolian_type_struct_get_by_name(base); if (tp) { eina_stringshare_del(base); if (!eolian_type_struct_field_get(tp, suffix + 1)) goto failed; return EINA_TRUE; } tp = eolian_type_enum_get_by_name(base); if (tp) { eina_stringshare_del(base); if (!eolian_type_enum_field_get(tp, suffix + 1)) goto failed; return EINA_TRUE; } const Eolian_Class *cl = eolian_class_get_by_name(base); if (cl) { eina_stringshare_del(base); if (!eolian_class_function_get_by_name(cl, suffix + 1, EOLIAN_UNRESOLVED)) goto failed; return EINA_TRUE; } Eolian_Function_Type ftype = EOLIAN_UNRESOLVED; if (!strcmp(suffix, ".get")) ftype = EOLIAN_PROP_GET; else if (!strcmp(suffix, ".set")) ftype = EOLIAN_PROP_SET; const char *meth; if (ftype != EOLIAN_UNRESOLVED) { eina_stringshare_del(base); meth = suffix - 1; while ((meth != ref) && (*meth != '.')) --meth; if (meth == ref) goto failed; base = eina_stringshare_add_length(ref, meth - ref); cl = eolian_class_get_by_name(base); eina_stringshare_del(base); } if (!cl) goto failed; char *ameth = strndup(meth + 1, suffix - meth - 1); const Eolian_Function *fn = eolian_class_function_get_by_name(cl, ameth, ftype); free(ameth); if (!fn) goto failed; return EINA_TRUE; failed: fprintf(stderr, "eolian:%s:%d:%d: failed validating reference '%s'\n", info->file, info->line, info->column, ref); return EINA_FALSE; }
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); }