index b0b7bf8f9345644e037264a2abd50b6d14b697f8..d43b9e32c764c10e0a372dabd71a79d3d30668f2 100644 (file)
--- a/src/core/store_lookup.c
+++ b/src/core/store_lookup.c
* private data types
*/
-/* match the name of something */
-typedef struct {
- char *name;
- regex_t *name_re;
-} name_matcher_t;
-
-/* matcher base type */
-struct sdb_store_matcher {
- sdb_object_t super;
- /* type of the matcher */
- int type;
-};
-#define M(m) ((sdb_store_matcher_t *)(m))
-
-/* logical operator matcher */
-typedef struct {
- sdb_store_matcher_t super;
-
- /* left and right hand operands */
- sdb_store_matcher_t *left;
- sdb_store_matcher_t *right;
-} op_matcher_t;
-#define OP_M(m) ((op_matcher_t *)(m))
-
-/* match any type of object by it's base information */
-typedef struct {
- sdb_store_matcher_t super;
-
- /* match by the name of the object */
- name_matcher_t name;
-} obj_matcher_t;
-#define OBJ_M(m) ((obj_matcher_t *)(m))
-
-/* match attributes */
-typedef struct {
- obj_matcher_t super;
- /* XXX: this needs to be more flexible;
- * add support for type-specific operators */
- name_matcher_t value;
-} attr_matcher_t;
-#define ATTR_M(m) ((attr_matcher_t *)(m))
-
-/* match services */
-typedef struct {
- obj_matcher_t super;
- /* match by attributes assigned to the service */
- attr_matcher_t *attr;
-} service_matcher_t;
-#define SERVICE_M(m) ((service_matcher_t *)(m))
-
-/* match hosts */
-typedef struct {
- obj_matcher_t super;
- /* match by services assigned to the host */
- service_matcher_t *service;
- /* match by attributes assigned to the host */
- attr_matcher_t *attr;
-} host_matcher_t;
-#define HOST_M(m) ((host_matcher_t *)(m))
-
typedef struct {
sdb_store_matcher_t *m;
sdb_store_lookup_cb cb;
static int
match_logical(sdb_store_matcher_t *m, sdb_store_base_t *obj);
static int
+match_unary(sdb_store_matcher_t *m, sdb_store_base_t *obj);
+static int
match_obj(sdb_store_matcher_t *m, sdb_store_base_t *obj);
/* specific matchers */
/* generic matchers */
-enum {
- MATCHER_OR,
- MATCHER_AND,
- MATCHER_ATTR,
- MATCHER_SERVICE,
- MATCHER_HOST,
-};
-
typedef int (*matcher_cb)(sdb_store_matcher_t *, sdb_store_base_t *);
-/* this array needs to be indexable by the matcher types */
+/* this array needs to be indexable by the matcher types;
+ * -> update the enum in store-private.h when updating this */
static matcher_cb matchers[] = {
match_logical,
match_logical,
+ match_unary,
match_obj,
match_obj,
match_obj,
return sdb_store_matcher_matches(OP_M(m)->right, obj);
} /* match_logical */
+static int
+match_unary(sdb_store_matcher_t *m, sdb_store_base_t *obj)
+{
+ assert(m && obj);
+ assert(UOP_M(m)->op);
+
+ return !sdb_store_matcher_matches(UOP_M(m)->op, obj);
+} /* match_unary */
+
static int
match_obj(sdb_store_matcher_t *m, sdb_store_base_t *obj)
{
sdb_object_deref(SDB_OBJ(OP_M(obj)->right));
} /* op_matcher_destroy */
+static int
+uop_matcher_init(sdb_object_t *obj, va_list ap)
+{
+ M(obj)->type = va_arg(ap, int);
+ if (M(obj)->type != MATCHER_NOT)
+ return -1;
+
+ UOP_M(obj)->op = va_arg(ap, sdb_store_matcher_t *);
+ sdb_object_ref(SDB_OBJ(UOP_M(obj)->op));
+
+ if (! UOP_M(obj)->op)
+ return -1;
+ return 0;
+} /* uop_matcher_init */
+
+static void
+uop_matcher_destroy(sdb_object_t *obj)
+{
+ if (UOP_M(obj)->op)
+ sdb_object_deref(SDB_OBJ(UOP_M(obj)->op));
+} /* uop_matcher_destroy */
+
static sdb_type_t attr_type = {
/* size = */ sizeof(attr_matcher_t),
/* init = */ attr_matcher_init,
/* destroy = */ op_matcher_destroy,
};
+static sdb_type_t uop_type = {
+ /* size = */ sizeof(uop_matcher_t),
+ /* init = */ uop_matcher_init,
+ /* destroy = */ uop_matcher_destroy,
+};
+
/*
* public API
*/
host_name, host_name_re, service_matcher, attr_matcher));
} /* sdb_store_host_matcher */
+sdb_store_matcher_t *
+sdb_store_matcher_parse_cmp(const char *obj_type, const char *attr,
+ const char *op, const char *value)
+{
+ int typ = -1;
+
+ const char *matcher = NULL;
+ const char *matcher_re = NULL;
+
+ if (! strcasecmp(obj_type, "host"))
+ typ = SDB_HOST;
+ else if (! strcasecmp(obj_type, "service"))
+ typ = SDB_SERVICE;
+ else if (! strcasecmp(obj_type, "attribute"))
+ typ = SDB_ATTRIBUTE;
+
+ /* TODO: support other operators */
+ if (! strcasecmp(op, "="))
+ matcher = value;
+ else if (! strcasecmp(op, "=~"))
+ matcher_re = value;
+ else
+ return NULL;
+
+ if (! strcasecmp(attr, "name")) {
+ /* accept */
+ }
+ else if (typ == SDB_ATTRIBUTE)
+ return sdb_store_attr_matcher(attr, NULL, matcher, matcher_re);
+ else
+ return NULL;
+
+ if (typ == SDB_HOST)
+ return sdb_store_host_matcher(matcher, matcher_re, NULL, NULL);
+ else if (typ == SDB_SERVICE)
+ return sdb_store_service_matcher(matcher, matcher_re, NULL);
+ else if (typ == SDB_ATTRIBUTE)
+ return sdb_store_attr_matcher(matcher, matcher_re, NULL, NULL);
+ return NULL;
+} /* sdb_store_matcher_parse_cmp */
+
sdb_store_matcher_t *
sdb_store_dis_matcher(sdb_store_matcher_t *left, sdb_store_matcher_t *right)
{
left, right));
} /* sdb_store_con_matcher */
+sdb_store_matcher_t *
+sdb_store_inv_matcher(sdb_store_matcher_t *m)
+{
+ return M(sdb_object_create("inv-matcher", uop_type, MATCHER_NOT, m));
+} /* sdb_store_inv_matcher */
+
int
sdb_store_matcher_matches(sdb_store_matcher_t *m, sdb_store_base_t *obj)
{