forked from enlightenment/efl
eolian: allow forced retrieval of enum field values
This commit is contained in:
parent
333e876629
commit
d2365e6267
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue