[template-glib] expr: teach TmplExpr to invert booleans



commit c82ee1bfc7a465936f95c0f303cfbeee3553b374
Author: Christian Hergert <chergert redhat com>
Date:   Sat Aug 6 11:45:39 2016 -0700

    expr: teach TmplExpr to invert booleans
    
    This allows for the syntax like: (!expression)
    
    For example, the obvious:
    
      {{if !false}}
        This is evaluated
      {{end}}

 src/tmpl-expr-eval.c    |   18 ++++++++++++++++++
 src/tmpl-expr-parser.y  |    3 +++
 src/tmpl-expr-scanner.l |    1 +
 src/tmpl-expr-types.h   |    1 +
 src/tmpl-expr.c         |   12 ++++++++++++
 src/tmpl-expr.h         |    1 +
 6 files changed, 36 insertions(+), 0 deletions(-)
---
diff --git a/src/tmpl-expr-eval.c b/src/tmpl-expr-eval.c
index 47aaaab..d9f41cd 100644
--- a/src/tmpl-expr-eval.c
+++ b/src/tmpl-expr-eval.c
@@ -920,6 +920,24 @@ tmpl_expr_eval_internal (TmplExpr   *node,
     case TMPL_EXPR_REQUIRE:
       return tmpl_expr_require_eval ((TmplExprRequire *)node, scope, return_value, error);
 
+    case TMPL_EXPR_INVERT_BOOLEAN:
+      {
+        GValue tmp = G_VALUE_INIT;
+        gboolean ret;
+
+        ret = tmpl_expr_eval_internal (((TmplExprSimple *)node)->left, scope, &tmp, error);
+
+        if (ret)
+          {
+            g_value_init (return_value, G_TYPE_BOOLEAN);
+            g_value_set_boolean (return_value, !tmpl_value_as_boolean (&tmp));
+          }
+
+        TMPL_CLEAR_VALUE (&tmp);
+
+        return ret;
+      }
+
     default:
       break;
     }
diff --git a/src/tmpl-expr-parser.y b/src/tmpl-expr-parser.y
index 8f44e69..e305dda 100644
--- a/src/tmpl-expr-parser.y
+++ b/src/tmpl-expr-parser.y
@@ -175,6 +175,9 @@ exp: exp CMP exp {
   | NAME '(' ')' {
     $$ = tmpl_expr_new_user_fn_call ($1, NULL);
   }
+  | '!' exp {
+    $$ = tmpl_expr_new_invert_boolean ($2);
+  }
   | REQUIRE NAME {
     $$ = tmpl_expr_new_require ($2, NULL);
   }
diff --git a/src/tmpl-expr-scanner.l b/src/tmpl-expr-scanner.l
index afe2435..48a3f4d 100644
--- a/src/tmpl-expr-scanner.l
+++ b/src/tmpl-expr-scanner.l
@@ -38,6 +38,7 @@ TmplExprParser *parser = yyextra;
 "," |
 "." |
 ";" |
+"!" |
 "(" |
 ")" { return yytext [0]; }
 
diff --git a/src/tmpl-expr-types.h b/src/tmpl-expr-types.h
index 250113b..0d4b1bb 100644
--- a/src/tmpl-expr-types.h
+++ b/src/tmpl-expr-types.h
@@ -72,6 +72,7 @@ typedef enum
   TMPL_EXPR_REQUIRE,
   TMPL_EXPR_AND,
   TMPL_EXPR_OR,
+  TMPL_EXPR_INVERT_BOOLEAN,
 } TmplExprType;
 
 typedef enum
diff --git a/src/tmpl-expr.c b/src/tmpl-expr.c
index f329bdb..228a882 100644
--- a/src/tmpl-expr.c
+++ b/src/tmpl-expr.c
@@ -83,6 +83,7 @@ tmpl_expr_destroy (TmplExpr *self)
     case TMPL_EXPR_USER_FN_CALL:
     case TMPL_EXPR_AND:
     case TMPL_EXPR_OR:
+    case TMPL_EXPR_INVERT_BOOLEAN:
       g_clear_pointer (&self->simple.left, tmpl_expr_unref);
       g_clear_pointer (&self->simple.right, tmpl_expr_unref);
       break;
@@ -210,6 +211,17 @@ tmpl_expr_new_simple (TmplExprType  type,
 }
 
 TmplExpr *
+tmpl_expr_new_invert_boolean (TmplExpr *left)
+{
+  TmplExprSimple *ret;
+
+  ret = tmpl_expr_new (TMPL_EXPR_INVERT_BOOLEAN);
+  ret->left = left;
+
+  return (TmplExpr *)ret;
+}
+
+TmplExpr *
 tmpl_expr_new_flow (TmplExprType  type,
                     TmplExpr     *condition,
                     TmplExpr     *primary,
diff --git a/src/tmpl-expr.h b/src/tmpl-expr.h
index d6e2826..1edeb6a 100644
--- a/src/tmpl-expr.h
+++ b/src/tmpl-expr.h
@@ -36,6 +36,7 @@ gboolean  tmpl_expr_eval              (TmplExpr         *expr,
                                        GValue           *return_value,
                                        GError          **error);
 TmplExpr *tmpl_expr_new_boolean       (gboolean          value);
+TmplExpr *tmpl_expr_new_invert_boolean(TmplExpr         *left);
 TmplExpr *tmpl_expr_new_getattr       (TmplExpr         *left,
                                        const gchar      *attr);
 TmplExpr *tmpl_expr_new_setattr       (TmplExpr         *left,


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