q66 pushed a commit to branch master.

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

commit d2365e6267c8bcd22c96176e4356328e6b6bfaef
Author: Daniel Kolesa <d.kol...@osg.samsung.com>
Date:   Wed May 13 17:56:18 2015 +0100

    eolian: allow forced retrieval of enum field values
---
 src/bin/eolian/types_generator.c   |  4 +--
 src/bindings/luajit/eolian.lua     | 10 +++----
 src/lib/eolian/Eolian.h            | 13 ++++++---
 src/lib/eolian/database_expr.c     | 54 ++++----------------------------------
 src/lib/eolian/database_type_api.c | 50 +++++++++++++++++++++++++++++++++--
 src/lib/eolian/eo_parser.c         |  2 ++
 src/lib/eolian/eolian_database.h   |  3 +++
 src/tests/eolian/eolian_parsing.c  | 14 +++++-----
 8 files changed, 82 insertions(+), 68 deletions(-)

diff --git a/src/bin/eolian/types_generator.c b/src/bin/eolian/types_generator.c
index e323950..90b62bd 100644
--- a/src/bin/eolian/types_generator.c
+++ b/src/bin/eolian/types_generator.c
@@ -94,7 +94,7 @@ _type_generate(const Eolian_Type *tp, Eina_Bool full)
            }
       case EOLIAN_TYPE_ENUM:
            {
-              const Eolian_Enum_Type_Field *member;
+              Eolian_Enum_Type_Field *member;
               char *name;
               if (!full)
                 break;
@@ -112,7 +112,7 @@ _type_generate(const Eolian_Type *tp, Eina_Bool full)
               while (next)
                 {
                    const char *desc = 
eolian_type_enum_field_description_get(member);
-                   const Eolian_Expression *value = 
eolian_type_enum_field_value_get(member);
+                   const Eolian_Expression *value = 
eolian_type_enum_field_value_get(member, EINA_FALSE);
                    char *memb_u = 
strdup(eolian_type_enum_field_name_get(member));
                    eina_str_toupper(&memb_u);
                    eina_strbuf_reset(membuf);
diff --git a/src/bindings/luajit/eolian.lua b/src/bindings/luajit/eolian.lua
index 21c73d7..334d141 100644
--- a/src/bindings/luajit/eolian.lua
+++ b/src/bindings/luajit/eolian.lua
@@ -270,10 +270,10 @@ ffi.cdef [[
     const char *eolian_type_struct_field_description_get(const 
Eolian_Struct_Type_Field *fl);
     const Eolian_Type *eolian_type_struct_field_type_get(const 
Eolian_Struct_Type_Field *fl);
     Eina_Iterator *eolian_type_enum_fields_get(const Eolian_Type *tp);
-    const Eolian_Enum_Type_Field *eolian_type_enum_field_get(const Eolian_Type 
*tp, const char *field);
+    Eolian_Enum_Type_Field *eolian_type_enum_field_get(const Eolian_Type *tp, 
const char *field);
     const char *eolian_type_enum_field_name_get(const Eolian_Enum_Type_Field 
*fl);
     const char *eolian_type_enum_field_description_get(const 
Eolian_Enum_Type_Field *fl);
-    const Eolian_Expression *eolian_type_enum_field_value_get(const 
Eolian_Enum_Type_Field *fl);
+    const Eolian_Expression 
*eolian_type_enum_field_value_get(Eolian_Enum_Type_Field *fl, Eina_Bool force);
     const char *eolian_type_enum_legacy_prefix_get(const Eolian_Type *tp);
     const char *eolian_type_description_get(const Eolian_Type *tp);
     const char *eolian_type_file_get(const Eolian_Type *tp);
@@ -474,8 +474,8 @@ ffi.metatype("Eolian_Enum_Type_Field", {
             return ffi.string(v)
         end,
 
-        value_get = function(self)
-            local v = eolian.eolian_type_enum_field_value_get(self)
+        value_get = function(self, force)
+            local v = eolian.eolian_type_enum_field_value_get(self, force and 
1 or 0)
             if v == nil then return nil end
             return v
         end
@@ -510,7 +510,7 @@ M.Type = ffi.metatype("Eolian_Type", {
         end,
 
         enum_fields_get = function(self)
-            return Ptr_Iterator("const Eolian_Enum_Type_Field*",
+            return Ptr_Iterator("Eolian_Enum_Type_Field*",
                 eolian.eolian_type_enum_fields_get(self))
         end,
 
diff --git a/src/lib/eolian/Eolian.h b/src/lib/eolian/Eolian.h
index 795eed6..317d657 100644
--- a/src/lib/eolian/Eolian.h
+++ b/src/lib/eolian/Eolian.h
@@ -1551,7 +1551,7 @@ EAPI Eina_Iterator *eolian_type_enum_fields_get(const 
Eolian_Type *tp);
  *
  * @ingroup Eolian
  */
-EAPI const Eolian_Enum_Type_Field *eolian_type_enum_field_get(const 
Eolian_Type *tp, const char *field);
+EAPI Eolian_Enum_Type_Field *eolian_type_enum_field_get(const Eolian_Type *tp, 
const char *field);
 
 /*
  * @brief Get the name of a field of an enum type.
@@ -1588,12 +1588,19 @@ EAPI Eina_Stringshare 
*eolian_type_enum_field_description_get(const Eolian_Enum_
 /*
  * @brief Get the value of a field of an enum type.
  *
+ * When the @c force parameter is EINA_FALSE, this will only return values for
+ * fields which are explicitly specified in the eo file. Otherwise, it will
+ * create the field (if not already there) and return it. Keep in mind that
+ * no matter if the field is already cached or not, you always have to force
+ * retrieval if you want to be sure that a valid expr is returned.
+ *
  * @param[in] fl the field.
- * @return the description.
+ * @param[in] force force the value retrieval.
+ * @return the expression.
  *
  * @ingroup Eolian
  */
-EAPI const Eolian_Expression *eolian_type_enum_field_value_get(const 
Eolian_Enum_Type_Field *fl);
+EAPI const Eolian_Expression 
*eolian_type_enum_field_value_get(Eolian_Enum_Type_Field *fl, Eina_Bool force);
 
 /*
  * @brief Get the legacy prefix of enum field names. When not specified,
diff --git a/src/lib/eolian/database_expr.c b/src/lib/eolian/database_expr.c
index cfd5b0b..7fe8108 100644
--- a/src/lib/eolian/database_expr.c
+++ b/src/lib/eolian/database_expr.c
@@ -495,12 +495,11 @@ 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)
              {
                 const Eolian_Type *etp;
-                const Eolian_Enum_Type_Field *fl;
+                Eolian_Enum_Type_Field *fl;
 
                 /* try aliases, hoping it'll be enum */
                 char *fulln = NULL, *memb = NULL;
@@ -525,31 +524,7 @@ eval_exp(const Eolian_Expression *expr, 
Eolian_Expression_Mask mask,
                   }
 
                 fl = eolian_type_enum_field_get(etp, memb);
-                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;
-                       }
-                  }
+                if (fl) exp = eolian_type_enum_field_value_get(fl, EINA_TRUE);
                 free(fulln);
 
                 if (!exp)
@@ -561,25 +536,6 @@ 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:
@@ -616,12 +572,12 @@ database_expr_del(Eolian_Expression *expr)
    if (expr->base.file) eina_stringshare_del(expr->base.file);
    if (expr->type == EOLIAN_EXPR_BINARY)
      {
-        database_expr_del(expr->lhs);
-        database_expr_del(expr->rhs);
+        if (!expr->weak_lhs) database_expr_del(expr->lhs);
+        if (!expr->weak_rhs) database_expr_del(expr->rhs);
      }
    else if (expr->type == EOLIAN_EXPR_UNARY)
      {
-        database_expr_del(expr->expr);
+        if (!expr->weak_lhs) database_expr_del(expr->expr);
      }
    else if (expr->type == EOLIAN_EXPR_STRING)
      {
diff --git a/src/lib/eolian/database_type_api.c 
b/src/lib/eolian/database_type_api.c
index 5c301f2..709f541 100644
--- a/src/lib/eolian/database_type_api.c
+++ b/src/lib/eolian/database_type_api.c
@@ -136,7 +136,7 @@ eolian_type_enum_fields_get(const Eolian_Type *tp)
    return eina_list_iterator_new(tp->field_list);
 }
 
-EAPI const Eolian_Enum_Type_Field *
+EAPI Eolian_Enum_Type_Field *
 eolian_type_enum_field_get(const Eolian_Type *tp, const char *field)
 {
    Eolian_Enum_Type_Field *ef = NULL;
@@ -185,9 +185,55 @@ eolian_type_enum_field_description_get(const 
Eolian_Enum_Type_Field *fl)
 }
 
 EAPI const Eolian_Expression *
-eolian_type_enum_field_value_get(const Eolian_Enum_Type_Field *fl)
+eolian_type_enum_field_value_get(Eolian_Enum_Type_Field *fl, Eina_Bool force)
 {
    EINA_SAFETY_ON_NULL_RETURN_VAL(fl, NULL);
+   if (!force && !fl->is_public_value) return NULL;
+   if (force && !fl->value)
+     {
+        Eolian_Expression *exp = NULL;
+        Eolian_Expression *rhs = calloc(1, sizeof(Eolian_Expression)),
+                          *bin = calloc(1, sizeof(Eolian_Expression));
+
+        int fl_nadd = 0;
+
+        Eina_List *flist = fl->base_enum->field_list;
+        Eolian_Enum_Type_Field *lfl = eina_list_data_get(flist);
+
+        /* first find our own node */
+        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;
+
+        rhs->base.file = eina_stringshare_ref(exp->base.file);
+        bin->base.file = eina_stringshare_ref(exp->base.file);
+        rhs->base.line = rhs->base.column = -1;
+        bin->base.line = bin->base.column = -1;
+
+        rhs->type = EOLIAN_EXPR_INT;
+        rhs->value.i = fl_nadd;
+
+        bin->type = EOLIAN_EXPR_BINARY;
+        bin->binop = EOLIAN_BINOP_ADD;
+        bin->lhs = exp;
+        bin->rhs = rhs;
+        bin->weak_lhs = EINA_TRUE;
+
+        fl->value = bin;
+     }
    return fl->value;
 }
 
diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c
index a646526..7509196 100644
--- a/src/lib/eolian/eo_parser.c
+++ b/src/lib/eolian/eo_parser.c
@@ -589,6 +589,7 @@ parse_enum(Eo_Lexer *ls, const char *name, Eina_Bool 
is_extern,
                   prev_exp->type = EOLIAN_EXPR_INT;
                   prev_exp->value.i = 0;
                   fdef->value = prev_exp;
+                  fdef->is_public_value = EINA_TRUE;
                   pop_expr(ls);
                }
           }
@@ -597,6 +598,7 @@ parse_enum(Eo_Lexer *ls, const char *name, Eina_Bool 
is_extern,
              ls->expr_mode = EINA_TRUE;
              eo_lexer_get(ls);
              fdef->value = parse_expr(ls);
+             fdef->is_public_value = EINA_TRUE;
              ls->expr_mode = EINA_FALSE;
              if (!prev_exp)
                prev_exp = fdef->value;
diff --git a/src/lib/eolian/eolian_database.h b/src/lib/eolian/eolian_database.h
index 0bd9ac8..2f4b82e 100644
--- a/src/lib/eolian/eolian_database.h
+++ b/src/lib/eolian/eolian_database.h
@@ -205,6 +205,7 @@ struct _Eolian_Enum_Type_Field
    Eolian_Object      base;
    Eolian_Expression *value;
    Eina_Stringshare  *comment;
+   Eina_Bool is_public_value :1;
 };
 
 struct _Eolian_Expression
@@ -226,6 +227,8 @@ struct _Eolian_Expression
       };
       Eolian_Value_Union value;
    };
+   Eina_Bool weak_lhs :1;
+   Eina_Bool weak_rhs :1;
 };
 
 struct _Eolian_Variable
diff --git a/src/tests/eolian/eolian_parsing.c 
b/src/tests/eolian/eolian_parsing.c
index 4591732..f7c827b 100644
--- a/src/tests/eolian/eolian_parsing.c
+++ b/src/tests/eolian/eolian_parsing.c
@@ -854,16 +854,16 @@ START_TEST(eolian_enum)
    fail_if(!(type = eolian_type_enum_get_by_name("Foo")));
 
    fail_if(!(field = eolian_type_enum_field_get(type, "first")));
-   fail_if(!(exp = eolian_type_enum_field_value_get(field)));
+   fail_if(!(exp = eolian_type_enum_field_value_get(field, EINA_FALSE)));
    v = eolian_expression_eval(exp, EOLIAN_MASK_ALL);
    fail_if(v.type != EOLIAN_EXPR_INT);
    fail_if(v.value.i != 0);
 
    fail_if(!(field = eolian_type_enum_field_get(type, "bar")));
-   fail_if(eolian_type_enum_field_value_get(field));
+   fail_if(eolian_type_enum_field_value_get(field, EINA_FALSE));
 
    fail_if(!(field = eolian_type_enum_field_get(type, "baz")));
-   fail_if(!(exp = eolian_type_enum_field_value_get(field)));
+   fail_if(!(exp = eolian_type_enum_field_value_get(field, EINA_FALSE)));
    v = eolian_expression_eval(exp, EOLIAN_MASK_ALL);
    fail_if(v.type != EOLIAN_EXPR_INT);
    fail_if(v.value.i != 15);
@@ -872,7 +872,7 @@ START_TEST(eolian_enum)
    fail_if(strcmp(eolian_type_enum_legacy_prefix_get(type), "test"));
 
    fail_if(!(field = eolian_type_enum_field_get(type, "foo")));
-   fail_if(!(exp = eolian_type_enum_field_value_get(field)));
+   fail_if(!(exp = eolian_type_enum_field_value_get(field, EINA_FALSE)));
    v = eolian_expression_eval(exp, EOLIAN_MASK_ALL);
    fail_if(v.type != EOLIAN_EXPR_INT);
    fail_if(v.value.i != 15);
@@ -884,13 +884,13 @@ START_TEST(eolian_enum)
    fail_if(!(type = eolian_type_enum_get_by_name("Baz")));
 
    fail_if(!(field = eolian_type_enum_field_get(type, "flag1")));
-   fail_if(!(exp = eolian_type_enum_field_value_get(field)));
+   fail_if(!(exp = eolian_type_enum_field_value_get(field, EINA_FALSE)));
    v = eolian_expression_eval(exp, EOLIAN_MASK_ALL);
    fail_if(v.type != EOLIAN_EXPR_INT);
    fail_if(v.value.i != (1 << 0));
 
    fail_if(!(field = eolian_type_enum_field_get(type, "flag2")));
-   fail_if(!(exp = eolian_type_enum_field_value_get(field)));
+   fail_if(!(exp = eolian_type_enum_field_value_get(field, EINA_FALSE)));
    v = eolian_expression_eval(exp, EOLIAN_MASK_ALL);
    fail_if(v.type != EOLIAN_EXPR_INT);
    fail_if(v.value.i != (1 << 1));
@@ -900,7 +900,7 @@ START_TEST(eolian_enum)
    eina_stringshare_del(cname);
 
    fail_if(!(field = eolian_type_enum_field_get(type, "flag3")));
-   fail_if(!(exp = eolian_type_enum_field_value_get(field)));
+   fail_if(!(exp = eolian_type_enum_field_value_get(field, EINA_FALSE)));
    v = eolian_expression_eval(exp, EOLIAN_MASK_ALL);
    fail_if(v.type != EOLIAN_EXPR_INT);
    fail_if(v.value.i != (1 << 2));

-- 


Reply via email to