q66 pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=e90e3af8b5cd9f54d8f2d4c5dee0f1142d3bce71

commit e90e3af8b5cd9f54d8f2d4c5dee0f1142d3bce71
Author: Daniel Kolesa <d.kol...@osg.samsung.com>
Date:   Wed May 13 17:15:20 2015 +0100

    eolian: fix evaluation of "undefined" enum fields
---
 src/lib/eolian/database_expr.c    | 50 ++++++++++++++++++++++++++++++++++++++-
 src/tests/eolian/data/enum.eo     | 11 +++++++++
 src/tests/eolian/eolian_parsing.c |  7 ++++++
 3 files changed, 67 insertions(+), 1 deletion(-)

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

-- 


Reply via email to