[template-glib] eval: allow comparing enums to nicks
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [template-glib] eval: allow comparing enums to nicks
- Date: Sat, 6 Aug 2016 23:54:05 +0000 (UTC)
commit 6577dbc630f06b0c6f08cbf55ecd918a3706f57b
Author: Christian Hergert <chergert redhat com>
Date: Sat Aug 6 16:53:01 2016 -0700
eval: allow comparing enums to nicks
This allows a convenience for comparing enums when you do not have G-I for
the particular enum value.
For example:
{{if foo.orientation == "horizontal"}}
{{end}}
src/tmpl-expr-eval.c | 112 ++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 100 insertions(+), 12 deletions(-)
---
diff --git a/src/tmpl-expr-eval.c b/src/tmpl-expr-eval.c
index b85a19d..7c5d027 100644
--- a/src/tmpl-expr-eval.c
+++ b/src/tmpl-expr-eval.c
@@ -67,6 +67,14 @@ static gboolean builtin_repr (const GValue *value,
static gboolean builtin_sqrt (const GValue *value,
GValue *return_value,
GError **error);
+static gboolean eq_enum_string (const GValue *left,
+ const GValue *right,
+ GValue *return_value,
+ GError **error);
+static gboolean ne_enum_string (const GValue *left,
+ const GValue *right,
+ GValue *return_value,
+ GError **error);
static GHashTable *fast_dispatch;
static BuiltinFunc builtin_funcs [] = {
@@ -85,8 +93,11 @@ build_hash (TmplExprType type,
GType left,
GType right)
{
- g_assert (!left || G_TYPE_IS_FUNDAMENTAL (left));
- g_assert (!right || G_TYPE_IS_FUNDAMENTAL (right));
+ if (left && !G_TYPE_IS_FUNDAMENTAL (left))
+ return 0;
+
+ if (right && !G_TYPE_IS_FUNDAMENTAL (right))
+ return 0;
return type | (left << 16) | (right << 24);
}
@@ -132,6 +143,28 @@ throw_type_mismatch (GError **error,
return throw_type_mismatch (error, left, right, "invalid add"); \
} G_STMT_END
+static FastDispatch
+find_dispatch_slow (TmplExprSimple *node,
+ const GValue *left,
+ const GValue *right)
+{
+ if (node->type == TMPL_EXPR_EQ)
+ {
+ if ((G_VALUE_HOLDS_STRING (left) && G_VALUE_HOLDS_ENUM (right)) ||
+ (G_VALUE_HOLDS_STRING (right) && G_VALUE_HOLDS_ENUM (left)))
+ return eq_enum_string;
+ }
+
+ if (node->type == TMPL_EXPR_NE)
+ {
+ if ((G_VALUE_HOLDS_STRING (left) && G_VALUE_HOLDS_ENUM (right)) ||
+ (G_VALUE_HOLDS_STRING (right) && G_VALUE_HOLDS_ENUM (left)))
+ return ne_enum_string;
+ }
+
+ return NULL;
+}
+
static gboolean
tmpl_expr_simple_eval (TmplExprSimple *node,
TmplScope *scope,
@@ -150,16 +183,23 @@ tmpl_expr_simple_eval (TmplExprSimple *node,
((node->right == NULL) ||
tmpl_expr_eval_internal (node->right, scope, &right, error)))
{
- FastDispatch dispatch;
+ FastDispatch dispatch = NULL;
guint hash;
hash = build_hash (node->type, G_VALUE_TYPE (&left), G_VALUE_TYPE (&right));
- dispatch = g_hash_table_lookup (fast_dispatch, GINT_TO_POINTER (hash));
- if (G_UNLIKELY (dispatch == NULL))
+ if (hash != 0)
+ dispatch = g_hash_table_lookup (fast_dispatch, GINT_TO_POINTER (hash));
+
+ if G_UNLIKELY (dispatch == NULL)
{
- throw_type_mismatch (error, &left, &right, "type mismatch");
- goto cleanup;
+ dispatch = find_dispatch_slow (node, &left, &right);
+
+ if (dispatch == NULL)
+ {
+ throw_type_mismatch (error, &left, &right, "type mismatch");
+ goto cleanup;
+ }
}
ret = dispatch (&left, &right, return_value, error);
@@ -1074,6 +1114,55 @@ ne_string_string (const GValue *left,
return TRUE;
}
+static gboolean
+eq_enum_string (const GValue *left,
+ const GValue *right,
+ GValue *return_value,
+ GError **error)
+{
+ const gchar *str;
+ GEnumClass *klass;
+ const GEnumValue *val;
+ GType type;
+ gint eval;
+
+ if (G_VALUE_HOLDS_STRING (left))
+ {
+ str = g_value_get_string (left);
+ eval = g_value_get_enum (right);
+ type = G_VALUE_TYPE (right);
+ }
+ else
+ {
+ str = g_value_get_string (right);
+ eval = g_value_get_enum (left);
+ type = G_VALUE_TYPE (left);
+ }
+
+ klass = g_type_class_peek (type);
+ val = g_enum_get_value ((GEnumClass *)klass, eval);
+
+ g_value_init (return_value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (return_value, 0 == g_strcmp0 (str, val->value_nick));
+
+ return TRUE;
+}
+
+static gboolean
+ne_enum_string (const GValue *left,
+ const GValue *right,
+ GValue *return_value,
+ GError **error)
+{
+ if (eq_enum_string (left, right, return_value, error))
+ {
+ g_value_set_boolean (return_value, !g_value_get_boolean (return_value));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
#define SIMPLE_OP_FUNC(func_name, ret_type, set_func, get_left, op, get_right) \
static gboolean \
func_name (const GValue *left, \
@@ -1098,11 +1187,10 @@ SIMPLE_OP_FUNC (gt_double_double, G_TYPE_BOOLEAN, set_boolean, get_double, >,
SIMPLE_OP_FUNC (eq_double_double, G_TYPE_BOOLEAN, set_boolean, get_double, ==, get_double)
SIMPLE_OP_FUNC (ne_double_double, G_TYPE_BOOLEAN, set_boolean, get_double, !=, get_double)
SIMPLE_OP_FUNC (gte_double_double, G_TYPE_BOOLEAN, set_boolean, get_double, >=, get_double)
-
-SIMPLE_OP_FUNC (eq_uint_double, G_TYPE_BOOLEAN, set_boolean, get_uint, ==, get_double)
-SIMPLE_OP_FUNC (eq_double_uint, G_TYPE_BOOLEAN, set_boolean, get_double, ==, get_uint)
-SIMPLE_OP_FUNC (ne_uint_double, G_TYPE_BOOLEAN, set_boolean, get_uint, !=, get_double)
-SIMPLE_OP_FUNC (ne_double_uint, G_TYPE_BOOLEAN, set_boolean, get_double, !=, get_uint)
+SIMPLE_OP_FUNC (eq_uint_double, G_TYPE_BOOLEAN, set_boolean, get_uint, ==, get_double)
+SIMPLE_OP_FUNC (eq_double_uint, G_TYPE_BOOLEAN, set_boolean, get_double, ==, get_uint)
+SIMPLE_OP_FUNC (ne_uint_double, G_TYPE_BOOLEAN, set_boolean, get_uint, !=, get_double)
+SIMPLE_OP_FUNC (ne_double_uint, G_TYPE_BOOLEAN, set_boolean, get_double, !=, get_uint)
#undef SIMPLE_OP_FUNC
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]