[template-glib] expr: add "assert" builtin



commit cb05c7174bbfe020795c461eef6aad328d8593df
Author: Christian Hergert <chergert redhat com>
Date:   Wed May 4 14:24:35 2022 -0700

    expr: add "assert" builtin
    
    This is mostly useful for us for tests so that we can fill in the script
    files with things we expect to be without having to check return values
    from the C sources directly.

 src/tmpl-expr-eval.c    | 104 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/tmpl-expr-scanner.l |   1 +
 src/tmpl-expr-types.h   |   1 +
 tests/test1.script      |   4 ++
 4 files changed, 110 insertions(+)
---
diff --git a/src/tmpl-expr-eval.c b/src/tmpl-expr-eval.c
index 79de672..c7d3cc5 100644
--- a/src/tmpl-expr-eval.c
+++ b/src/tmpl-expr-eval.c
@@ -47,6 +47,9 @@ static gboolean throw_type_mismatch          (GError       **error,
 static gboolean builtin_abs                  (const GValue  *value,
                                               GValue        *return_value,
                                               GError       **error);
+static gboolean builtin_assert               (const GValue  *value,
+                                              GValue        *return_value,
+                                              GError       **error);
 static gboolean builtin_ceil                 (const GValue  *value,
                                               GValue        *return_value,
                                               GError       **error);
@@ -95,6 +98,7 @@ static BuiltinFunc builtin_funcs [] = {
   builtin_repr,
   builtin_sqrt,
   builtin_typeof,
+  builtin_assert,
 };
 
 static inline guint
@@ -1496,6 +1500,30 @@ ne_string_string (const GValue  *left,
   return TRUE;
 }
 
+static gboolean
+eq_boolean_boolean (const GValue  *left,
+                    const GValue  *right,
+                    GValue        *return_value,
+                    GError       **error)
+{
+  g_value_init (return_value, G_TYPE_BOOLEAN);
+  g_value_set_boolean (return_value,
+                       g_value_get_boolean (left) == g_value_get_boolean (right));
+  return TRUE;
+}
+
+static gboolean
+ne_boolean_boolean (const GValue  *left,
+                    const GValue  *right,
+                    GValue        *return_value,
+                    GError       **error)
+{
+  g_value_init (return_value, G_TYPE_BOOLEAN);
+  g_value_set_boolean (return_value,
+                       g_value_get_boolean (left) != g_value_get_boolean (right));
+  return TRUE;
+}
+
 static gboolean
 eq_enum_string (const GValue  *left,
                 const GValue  *right,
@@ -1609,6 +1637,9 @@ build_dispatch_table (void)
   ADD_DISPATCH_FUNC (TMPL_EXPR_EQ,          G_TYPE_STRING, G_TYPE_STRING, eq_string_string);
   ADD_DISPATCH_FUNC (TMPL_EXPR_NE,          G_TYPE_STRING, G_TYPE_STRING, ne_string_string);
 
+  ADD_DISPATCH_FUNC (TMPL_EXPR_EQ,          G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, eq_boolean_boolean);
+  ADD_DISPATCH_FUNC (TMPL_EXPR_NE,          G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, ne_boolean_boolean);
+
 #undef ADD_DISPATCH_FUNC
 
   return table;
@@ -1646,6 +1677,79 @@ builtin_abs (const GValue  *value,
   return FALSE;
 }
 
+static gboolean
+builtin_assert (const GValue  *value,
+                GValue        *return_value,
+                GError       **error)
+{
+  if (G_VALUE_TYPE (value) == G_TYPE_INVALID)
+    goto failure;
+
+  if (G_VALUE_HOLDS_BOOLEAN (value))
+    {
+      if (g_value_get_boolean (value) == FALSE)
+        goto failure;
+    }
+  else if (G_VALUE_HOLDS_STRING (value))
+    {
+      if (g_value_get_string (value) == NULL)
+        goto failure;
+    }
+  else if (G_VALUE_HOLDS_POINTER (value))
+    {
+      if (g_value_get_pointer (value) == NULL)
+        goto failure;
+    }
+  else if (G_VALUE_HOLDS_OBJECT (value))
+    {
+      if (g_value_get_object (value) == NULL)
+        goto failure;
+    }
+  else if (G_VALUE_HOLDS_INT (value))
+    {
+      if (g_value_get_int (value) == 0)
+        goto failure;
+    }
+  else if (G_VALUE_HOLDS_UINT (value))
+    {
+      if (g_value_get_uint (value) == 0)
+        goto failure;
+    }
+  else if (G_VALUE_HOLDS_INT64 (value))
+    {
+      if (g_value_get_int64 (value) == 0)
+        goto failure;
+    }
+  else if (G_VALUE_HOLDS_UINT64 (value))
+    {
+      if (g_value_get_uint64 (value) == 0)
+        goto failure;
+    }
+  else if (G_VALUE_HOLDS_DOUBLE (value))
+    {
+      if (g_value_get_double (value) == .0)
+        goto failure;
+    }
+  else if (G_VALUE_HOLDS_FLOAT (value))
+    {
+      if (g_value_get_float (value) == .0f)
+        goto failure;
+    }
+  else
+    {
+      goto failure;
+    }
+
+  return TRUE;
+
+failure:
+  g_set_error_literal (error,
+                       TMPL_ERROR,
+                       TMPL_ERROR_RUNTIME_ERROR,
+                       "Assertion failed");
+  return FALSE;
+}
+
 static gboolean
 builtin_ceil (const GValue  *value,
               GValue        *return_value,
diff --git a/src/tmpl-expr-scanner.l b/src/tmpl-expr-scanner.l
index fa44294..c4580f5 100644
--- a/src/tmpl-expr-scanner.l
+++ b/src/tmpl-expr-scanner.l
@@ -81,6 +81,7 @@ TmplExprParser *parser = yyextra;
 "false"    { yylval->b = 0; return BOOL; }
 
  /* builtin functions */
+"assert" { yylval->fn = TMPL_EXPR_BUILTIN_ASSERT; return BUILTIN; }
 "ceil"   { yylval->fn = TMPL_EXPR_BUILTIN_CEIL; return BUILTIN; }
 "floor"  { yylval->fn = TMPL_EXPR_BUILTIN_FLOOR; return BUILTIN; }
 "hex"    { yylval->fn = TMPL_EXPR_BUILTIN_HEX; return BUILTIN; }
diff --git a/src/tmpl-expr-types.h b/src/tmpl-expr-types.h
index 037d9ec..79caf36 100644
--- a/src/tmpl-expr-types.h
+++ b/src/tmpl-expr-types.h
@@ -90,6 +90,7 @@ typedef enum
   TMPL_EXPR_BUILTIN_REPR,
   TMPL_EXPR_BUILTIN_SQRT,
   TMPL_EXPR_BUILTIN_TYPEOF,
+  TMPL_EXPR_BUILTIN_ASSERT,
 } TmplExprBuiltin;
 
 TMPL_AVAILABLE_IN_ALL
diff --git a/tests/test1.script b/tests/test1.script
index 147fdc6..54fda20 100644
--- a/tests/test1.script
+++ b/tests/test1.script
@@ -1,6 +1,10 @@
 require GLib
 require Gio version "2.0"
 
+assert(true)
+assert(true != false)
+assert(!false)
+
 func multiply(x,y) = x * y;
 
 multiply(617, 2)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]