Code

store_expr: Added framework for arithmetic expressions.
authorSebastian Harl <sh@tokkee.org>
Sun, 27 Jul 2014 22:25:16 +0000 (00:25 +0200)
committerSebastian Harl <sh@tokkee.org>
Sun, 27 Jul 2014 22:25:16 +0000 (00:25 +0200)
A store expression describes the parse tree of an arithmetic expression and
provides means to execute it (based on sdb_data_expr_eval()).

src/Makefile.am
src/core/store-private.h
src/core/store_expr.c [new file with mode: 0644]
src/include/core/store.h

index 2adc2e0c2a1e8290638ac7f5f7f4b260ebe40ca6..272533b0951f0ff23532de6bceb93f240a992422 100644 (file)
@@ -70,6 +70,7 @@ libsysdb_la_SOURCES = \
                core/plugin.c include/core/plugin.h \
                core/store.c include/core/store.h \
                core/store-private.h \
+               core/store_expr.c \
                core/store_lookup.c \
                core/data.c include/core/data.h \
                frontend/connection.c include/frontend/connection.h \
index a2121f45c211dad50003007e6a438f9958725638..7479bc69ad25082c26ecbc542bbc4f7563b40809 100644 (file)
 extern "C" {
 #endif
 
+/*
+ * core types
+ */
+
 struct sdb_store_obj {
        sdb_object_t super;
 
diff --git a/src/core/store_expr.c b/src/core/store_expr.c
new file mode 100644 (file)
index 0000000..4d1fccb
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * SysDB - src/core/store_expr.c
+ * Copyright (C) 2014 Sebastian 'tokkee' Harl <sh@tokkee.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This module implements expressions which may be executed in the store.
+ */
+
+#if HAVE_CONFIG_H
+#      include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include "sysdb.h"
+#include "core/store-private.h"
+#include "core/object.h"
+
+#include <assert.h>
+
+/*
+ * private data types
+ */
+
+struct sdb_store_expr {
+       sdb_object_t super;
+
+       int type;
+       sdb_store_expr_t *left;
+       sdb_store_expr_t *right;
+
+       sdb_data_t data;
+};
+
+/*
+ * private data types
+ */
+
+static int
+expr_init(sdb_object_t *obj, va_list ap)
+{
+       int type = va_arg(ap, int);
+       sdb_store_expr_t *left  = va_arg(ap, sdb_store_expr_t *);
+       sdb_store_expr_t *right = va_arg(ap, sdb_store_expr_t *);
+       const sdb_data_t *value = va_arg(ap, const sdb_data_t *);
+
+       sdb_store_expr_t *expr = SDB_STORE_EXPR(obj);
+
+       if (! type) {
+               if (! value)
+                       return -1;
+       } else {
+               if (value)
+                       return -1;
+               if ((! left) || (! right))
+                       return -1;
+       }
+
+       if (value)
+               if (sdb_data_copy(&expr->data, value))
+                       return -1;
+
+       sdb_object_ref(SDB_OBJ(left));
+       sdb_object_ref(SDB_OBJ(right));
+
+       expr->type  = type;
+       expr->left  = left;
+       expr->right = right;
+       return 0;
+} /* expr_init */
+
+static void
+expr_destroy(sdb_object_t *obj)
+{
+       sdb_store_expr_t *expr = SDB_STORE_EXPR(obj);
+       sdb_object_deref(SDB_OBJ(expr->left));
+       sdb_object_deref(SDB_OBJ(expr->right));
+
+       if (expr->data.type)
+               sdb_data_free_datum(&expr->data);
+} /* expr_destroy */
+
+static sdb_type_t expr_type = {
+       /* size = */ sizeof(sdb_store_expr_t),
+       /* init = */ expr_init,
+       /* destroy = */ expr_destroy,
+};
+
+/*
+ * public API
+ */
+
+sdb_store_expr_t *
+sdb_store_expr_create(int op, sdb_store_expr_t *left, sdb_store_expr_t *right)
+{
+       return SDB_STORE_EXPR(sdb_object_create("store-expr", expr_type,
+                               op, left, right, NULL));
+} /* sdb_store_expr_create */
+
+sdb_store_expr_t *
+sdb_store_expr_constvalue(const sdb_data_t *value)
+{
+       return SDB_STORE_EXPR(sdb_object_create("store-constvalue", expr_type,
+                               0, NULL, NULL, value));
+} /* sdb_store_expr_constvalue */
+
+int
+sdb_store_expr_eval(sdb_store_expr_t *expr, sdb_data_t *res)
+{
+       sdb_data_t v1 = SDB_DATA_INIT, v2 = SDB_DATA_INIT;
+
+       if ((! expr) || (! res))
+               return -1;
+
+       if (! expr->type)
+               return sdb_data_copy(res, &expr->data);
+
+       if (sdb_store_expr_eval(expr->left, &v1))
+               return -1;
+       if (sdb_store_expr_eval(expr->right, &v2)) {
+               sdb_data_free_datum(&v1);
+               return -1;
+       }
+
+       if (sdb_data_expr_eval(expr->type, &v1, &v2, res)) {
+               sdb_data_free_datum(&v1);
+               sdb_data_free_datum(&v2);
+               return -1;
+       }
+       return 0;
+} /* sdb_store_expr_eval */
+
+/* vim: set tw=78 sw=4 ts=4 noexpandtab : */
+
index 4e8d468c4263f0e57cd2f26d301aedf0006102a7..1b4e7383bda1b77de607fea9e9d400e05e5ec578 100644 (file)
@@ -158,6 +158,52 @@ int
 sdb_store_service_attr(const char *hostname, const char *service,
                const char *key, const sdb_data_t *value, sdb_time_t last_update);
 
+/*
+ * Expressions specify arithmetic expressions.
+ *
+ * A expression object inherits from sdb_object_t and, thus, may safely be
+ * cast to a generic object.
+ */
+struct sdb_store_expr;
+typedef struct sdb_store_expr sdb_store_expr_t;
+#define SDB_STORE_EXPR(obj) ((sdb_store_expr_t *)(obj))
+
+/*
+ * sdb_store_expr_create:
+ * Creates an arithmetic expression implementing the specified operator on the
+ * specified left and right operand.
+ *
+ * Returns:
+ *  - an expression object on success
+ *  - NULL else
+ */
+sdb_store_expr_t *
+sdb_store_expr_create(int op, sdb_store_expr_t *left, sdb_store_expr_t *right);
+
+/*
+ * sdb_store_expr_constvalue:
+ * Creates an expression which evaluates to the specified constant value.
+ *
+ * Returns:
+ *  - an expression object on success
+ *  - NULL else
+ */
+sdb_store_expr_t *
+sdb_store_expr_constvalue(const sdb_data_t *value);
+
+/*
+ * sdb_store_expr_eval:
+ * Evaluate an expression and stores the result in 'res'. The result's value
+ * will be allocated dynamically if necessary and, thus, should be free'd by
+ * the caller (e.g. using sdb_data_free_datum);
+ *
+ * Returns:
+ *  - 0 on success
+ *  - a negative value else
+ */
+int
+sdb_store_expr_eval(sdb_store_expr_t *expr, sdb_data_t *res);
+
 /*
  * Conditionals may be used to lookup hosts from the store based on a
  * conditional expression.