From: Daniel Kolesa Date: Wed, 13 May 2015 16:15:20 +0000 (+0100) Subject: eolian: fix evaluation of "undefined" enum fields X-Git-Tag: v1.15.0-alpha1~584 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e90e3af8b5cd9f54d8f2d4c5dee0f1142d3bce71;p=platform%2Fupstream%2Fefl.git eolian: fix evaluation of "undefined" enum fields --- diff --git a/src/lib/eolian/database_expr.c b/src/lib/eolian/database_expr.c index 3cf82a0..cfd5b0b 100644 --- a/src/lib/eolian/database_expr.c +++ b/src/lib/eolian/database_expr.c @@ -495,6 +495,7 @@ eval_exp(const Eolian_Expression *expr, Eolian_Expression_Mask mask, const Eolian_Variable *var = eolian_variable_constant_get_by_name (expr->value.s); const Eolian_Expression *exp = NULL; + int fl_nadd = 0; if (!var) { @@ -507,6 +508,10 @@ eval_exp(const Eolian_Expression *expr, Eolian_Expression_Mask mask, 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)) @@ -520,7 +525,31 @@ eval_exp(const Eolian_Expression *expr, Eolian_Expression_Mask mask, } fl = eolian_type_enum_field_get(etp, memb); - if (fl) exp = eolian_type_enum_field_value_get(fl); + if (fl) + { + /* we have the field, but the value might not exist + * we should search for last valid enum field, use that */ + exp = fl->value; + if (!exp) + { + Eina_List *flist = fl->base_enum->field_list; + Eolian_Enum_Type_Field *lfl = eina_list_data_get(flist); + while (lfl && lfl->name != fl->name) + { + flist = eina_list_next(flist); + lfl = eina_list_data_get(flist); + } + /* we've found our list item, now let's go backwards */ + while (!lfl->value) + { + ++fl_nadd; + flist = eina_list_prev(flist); + lfl = eina_list_data_get(flist); + } + /* we've found our first reachable value */ + exp = lfl->value; + } + } free(fulln); if (!exp) @@ -532,6 +561,25 @@ eval_exp(const Eolian_Expression *expr, Eolian_Expression_Mask mask, if (!exp) return expr_error(expr, "undefined variable"); + if (fl_nadd) + { + Eolian_Expression eexp, vexp; + eexp.base.file = exp->base.file; + eexp.base.line = eexp.base.column = -1; + vexp.base.file = exp->base.file; + vexp.base.line = vexp.base.column = -1; + + vexp.type = EOLIAN_EXPR_INT; + vexp.value.i = fl_nadd; + + eexp.type = EOLIAN_EXPR_BINARY; + eexp.binop = EOLIAN_BINOP_ADD; + eexp.lhs = (Eolian_Expression *)exp; + eexp.rhs = &vexp; + + return eval_exp(&eexp, mask, out); + } + return eval_exp(exp, mask, out); } case EOLIAN_EXPR_UNARY: diff --git a/src/tests/eolian/data/enum.eo b/src/tests/eolian/data/enum.eo index 49bc369..3b16a2a 100644 --- a/src/tests/eolian/data/enum.eo +++ b/src/tests/eolian/data/enum.eo @@ -16,6 +16,17 @@ enum Baz { flag3 = 1 << 2 } +enum Value { + foo, + bar, + baz = 2, + bah, + bam, + pants +} + +const Pants: int = Value.pants; + const Bah: int = Baz.flag1; class Enum { diff --git a/src/tests/eolian/eolian_parsing.c b/src/tests/eolian/eolian_parsing.c index c94248d..5eefe74 100644 --- a/src/tests/eolian/eolian_parsing.c +++ b/src/tests/eolian/eolian_parsing.c @@ -916,6 +916,13 @@ START_TEST(eolian_enum) fail_if(v.type != EOLIAN_EXPR_INT); fail_if(v.value.i != (1 << 0)); + fail_if(!(var = eolian_variable_constant_get_by_name("Pants"))); + fail_if(eolian_variable_type_get(var) != EOLIAN_VAR_CONSTANT); + fail_if(!(exp = eolian_variable_value_get(var))); + v = eolian_expression_eval(exp, EOLIAN_MASK_ALL); + fail_if(v.type != EOLIAN_EXPR_INT); + fail_if(v.value.i != 5); + eolian_shutdown(); } END_TEST