From 1ba91f37fb155763423d3e2e9f3d1892c4c185f6 Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Sun, 31 May 2020 02:11:15 +0200 Subject: [PATCH] eolian: add out-param variants of expr eval/value get funcs This is for compatibility with bindings that can't express passing unions by value (e.g. anything libffi based). --- src/lib/eolian/Eolian.h | 34 ++++++++++++++++++++++++++++++ src/lib/eolian/database_expr_api.c | 25 ++++++++++++++++++++++ src/tests/eolian/eolian_parsing.c | 5 +++-- 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/lib/eolian/Eolian.h b/src/lib/eolian/Eolian.h index c052181fa9..3d3db0ee7b 100644 --- a/src/lib/eolian/Eolian.h +++ b/src/lib/eolian/Eolian.h @@ -2957,6 +2957,24 @@ eolian_type_namespaces_get(const Eolian_Type *tp) */ EAPI Eolian_Value eolian_expression_eval(const Eolian_Expression *expr, Eolian_Expression_Mask m); +/* + * @brief Evaluate an Eolian expression into an out-param. + * + * @param[in] expr the expression. + * @param[in] mask the mask of allowed values (can combine with bitwise OR). + * @param[out] the value to fill + * @return EINA_TRUE on success, EINA_FALSE on failure + * + * This is like eolian_expression_eval, except it writes into an out-param + * and returns whether it succeeded or failed. On failure, no write is + * guaranteed. + * + * @since 1.25 + * + * @ingroup Eolian + */ +EAPI Eina_Bool eolian_expression_eval_fill(const Eolian_Expression *expr, Eolian_Expression_Mask m, Eolian_Value *val); + /* * @brief Convert the result of expression evaluation to a literal as in how * it would appear in C (e.g. strings are quoted and escaped). @@ -3079,6 +3097,22 @@ EAPI const Eolian_Expression *eolian_expression_unary_expression_get(const Eolia */ EAPI Eolian_Value eolian_expression_value_get(const Eolian_Expression *expr); +/* + * @brief Get the value of an expression into an out-param. + * + * @param[in] expr the expression. + * @param[out] val the value to fill. + * @return EINA_TRUE on success, EINA_FALSE on failure + * + * This is like eolian_expression_value_get, but it fills an out-param. On + * failure, nothing is guaranteed to be filled. + * + * @since 1.25 + * + * @ingroup Eolian + */ +EAPI Eina_Bool eolian_expression_value_get_fill(const Eolian_Expression *expr, Eolian_Value *val); + /* * @brief Get the documentation of a constant. * diff --git a/src/lib/eolian/database_expr_api.c b/src/lib/eolian/database_expr_api.c index 2d3f81c73d..83cfbc52ac 100644 --- a/src/lib/eolian/database_expr_api.c +++ b/src/lib/eolian/database_expr_api.c @@ -15,6 +15,19 @@ eolian_expression_eval(const Eolian_Expression *expr, Eolian_Expression_Mask m) return database_expr_eval(NULL, (Eolian_Expression *)expr, m, NULL, NULL); } +EAPI Eina_Bool +eolian_expression_eval_fill(const Eolian_Expression *expr, + Eolian_Expression_Mask m, Eolian_Value *val) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(expr, EINA_FALSE); + Eolian_Value ret = database_expr_eval(NULL, (Eolian_Expression *)expr, m, + NULL, NULL); + if (ret.type == EOLIAN_EXPR_UNKNOWN) + return EINA_FALSE; + *val = ret; + return EINA_TRUE; +} + static void _append_char_escaped(Eina_Strbuf *buf, char c) { @@ -269,3 +282,15 @@ eolian_expression_value_get(const Eolian_Expression *expr) v.value = expr->value; return v; } + +EAPI Eina_Bool +eolian_expression_value_get_fill(const Eolian_Expression *expr, Eolian_Value *val) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(expr, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(expr->type != EOLIAN_EXPR_UNKNOWN + && expr->type != EOLIAN_EXPR_BINARY + && expr->type != EOLIAN_EXPR_UNARY, EINA_FALSE); + val->type = expr->type; + val->value = expr->value; + return EINA_TRUE; +} diff --git a/src/tests/eolian/eolian_parsing.c b/src/tests/eolian/eolian_parsing.c index 5e05da98c0..c914e4ec4f 100644 --- a/src/tests/eolian/eolian_parsing.c +++ b/src/tests/eolian/eolian_parsing.c @@ -539,7 +539,7 @@ EFL_START_TEST(eolian_simple_parsing) const Eolian_Type *tp; const Eolian_Unit *unit; Eina_Iterator *iter; - Eolian_Value v; + Eolian_Value v, vv; void *dummy; Eolian_State *eos = eolian_state_new(); @@ -579,13 +579,14 @@ EFL_START_TEST(eolian_simple_parsing) /* Set return */ tp = eolian_function_return_type_get(fid, EOLIAN_PROP_SET); fail_if(!tp); - printf("BUILT %d\n", (int)eolian_type_builtin_type_get(tp)); fail_if(eolian_type_builtin_type_get(tp) != EOLIAN_TYPE_BUILTIN_BOOL); fail_if(strcmp(eolian_type_short_name_get(tp), "bool")); expr = eolian_function_return_default_value_get(fid, EOLIAN_PROP_SET); fail_if(!expr); v = eolian_expression_eval(expr, EOLIAN_MASK_BOOL); + fail_if(!eolian_expression_eval_fill(expr, EOLIAN_MASK_BOOL, &vv)); fail_if(v.type != EOLIAN_EXPR_BOOL); + fail_if(vv.type != EOLIAN_EXPR_BOOL); /* Get return */ tp = eolian_function_return_type_get(fid, EOLIAN_PROP_GET); fail_if(tp);