summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: e05ca8c)
raw | patch | inline | side by side (parent: e05ca8c)
author | Sebastian Harl <sh@tokkee.org> | |
Thu, 23 Oct 2014 20:12:19 +0000 (22:12 +0200) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Thu, 23 Oct 2014 20:12:19 +0000 (22:12 +0200) |
index 550668db2ebd1259818411c8a7fe7e769e8012db..7ce807bfa3d9807111453c7f958a5dd994fbb72b 100644 (file)
--- a/src/core/store-private.h
+++ b/src/core/store-private.h
MATCHER_OR,
MATCHER_AND,
MATCHER_NOT,
- MATCHER_NAME,
MATCHER_SERVICE,
MATCHER_METRIC,
MATCHER_ATTRIBUTE,
index 180d17931d2c603fb0e295b5b06f4c9637d5cb8a..3a99f80a2ac0d89e21eddce60ad722734dd2baa1 100644 (file)
--- a/src/core/store_lookup.c
+++ b/src/core/store_lookup.c
* matcher implementations
*/
-static int
-match_string(string_matcher_t *m, const char *name)
-{
- if ((! m->name) && (! m->name_re))
- return 1;
-
- if (! name)
- name = "";
-
- if (m->name && strcasecmp(m->name, name))
- return 0;
- if (m->name_re && regexec(m->name_re, name,
- /* matches */ 0, NULL, /* flags = */ 0))
- return 0;
- return 1;
-} /* match_string */
-
static int
match_logical(sdb_store_matcher_t *m, sdb_store_obj_t *obj,
sdb_store_matcher_t *filter)
return !sdb_store_matcher_matches(UOP_M(m)->op, obj, filter);
} /* match_unary */
-static int
-match_name(sdb_store_matcher_t *m, sdb_store_obj_t *obj,
- sdb_store_matcher_t *filter)
-{
- sdb_avltree_iter_t *iter = NULL;
- int status = 0;
-
- assert(m->type == MATCHER_NAME);
-
- if (obj->type == NAME_M(m)->obj_type)
- return match_string(&NAME_M(m)->name, SDB_OBJ(obj)->name);
- else if (obj->type != SDB_HOST)
- return 0;
-
- switch (NAME_M(m)->obj_type) {
- case SDB_SERVICE:
- iter = sdb_avltree_get_iter(HOST(obj)->services);
- break;
- case SDB_METRIC:
- iter = sdb_avltree_get_iter(HOST(obj)->metrics);
- break;
- case SDB_ATTRIBUTE:
- iter = sdb_avltree_get_iter(HOST(obj)->attributes);
- break;
- }
-
- while (sdb_avltree_iter_has_next(iter)) {
- sdb_object_t *child = sdb_avltree_iter_get_next(iter);
- if (filter && (! sdb_store_matcher_matches(filter, STORE_OBJ(child),
- NULL)))
- continue;
- if (match_string(&NAME_M(m)->name, child->name)) {
- status = 1;
- break;
- }
- }
- sdb_avltree_iter_destroy(iter);
- return status;
-} /* match_name */
-
static int
match_child(sdb_store_matcher_t *m, sdb_store_obj_t *obj,
sdb_store_matcher_t *filter)
match_logical,
match_logical,
match_unary,
- match_name,
match_child,
match_child,
match_child,
* private matcher types
*/
-/* initializes a string matcher consuming two elements from ap */
-static int
-string_matcher_init(string_matcher_t *m, va_list ap)
-{
- const char *name = va_arg(ap, const char *);
- const char *name_re = va_arg(ap, const char *);
-
- if (name) {
- m->name = strdup(name);
- if (! m->name)
- return -1;
- }
- if (name_re) {
- m->name_re = malloc(sizeof(*m->name_re));
- if (! m->name_re)
- return -1;
- if (regcomp(m->name_re, name_re, REG_EXTENDED | REG_ICASE | REG_NOSUB))
- return -1;
- }
- return 0;
-} /* string_matcher_init */
-
-static void
-string_matcher_destroy(string_matcher_t *m)
-{
- if (m->name)
- free(m->name);
- if (m->name_re) {
- regfree(m->name_re);
- free(m->name_re);
- }
-} /* string_matcher_destroy */
-
-/* initializes a name matcher */
-static int
-name_matcher_init(sdb_object_t *obj, va_list ap)
-{
- name_matcher_t *m = NAME_M(obj);
- M(obj)->type = MATCHER_NAME;
- return string_matcher_init(&m->name, ap);
-} /* name_matcher_init */
-
-static void
-name_matcher_destroy(sdb_object_t *obj)
-{
- name_matcher_t *m = NAME_M(obj);
- string_matcher_destroy(&m->name);
-} /* name_matcher_destroy */
-
static int
op_matcher_init(sdb_object_t *obj, va_list ap)
{
ISNULL_M(obj)->expr = NULL;
} /* isnull_matcher_destroy */
-static sdb_type_t name_type = {
- /* size = */ sizeof(name_matcher_t),
- /* init = */ name_matcher_init,
- /* destroy = */ name_matcher_destroy,
-};
-
static sdb_type_t op_type = {
/* size = */ sizeof(op_matcher_t),
/* init = */ op_matcher_init,
* public API
*/
-sdb_store_matcher_t *
-sdb_store_name_matcher(int type, const char *name, _Bool re)
-{
- sdb_store_matcher_t *m;
-
- if (re)
- m = M(sdb_object_create("name-matcher", name_type, NULL, name));
- else
- m = M(sdb_object_create("name-matcher", name_type, name, NULL));
-
- if (! m)
- return NULL;
-
- NAME_M(m)->obj_type = type;
- return m;
-} /* sdb_store_name_matcher */
-
sdb_store_matcher_t *
sdb_store_child_matcher(int type, sdb_store_matcher_t *m)
{
return -1;
} /* sdb_store_parse_field_name */
-static sdb_store_matcher_t *
-maybe_inv_matcher(sdb_store_matcher_t *m, _Bool inv)
-{
- sdb_store_matcher_t *tmp;
-
- if ((! m) || (! inv))
- return m;
-
- tmp = sdb_store_inv_matcher(m);
- /* pass ownership to the inverse matcher */
- sdb_object_deref(SDB_OBJ(m));
- return tmp;
-} /* maybe_inv_matcher */
-
-sdb_store_matcher_t *
-sdb_store_matcher_parse_cmp(const char *obj_type,
- const char *op, sdb_store_expr_t *expr)
-{
- int type = -1;
- _Bool inv = 0;
- _Bool re = 0;
-
- sdb_data_t value = SDB_DATA_INIT;
- sdb_store_matcher_t *m = NULL;
-
- if (! strcasecmp(obj_type, "host"))
- type = SDB_HOST;
- else if (! strcasecmp(obj_type, "service"))
- type = SDB_SERVICE;
- else if (! strcasecmp(obj_type, "metric"))
- type = SDB_METRIC;
- else if (! strcasecmp(obj_type, "attribute"))
- type = SDB_ATTRIBUTE;
- else
- return NULL;
-
- /* XXX: this code sucks! */
- if (! strcasecmp(op, "=")) {
- /* nothing to do */
- }
- else if (! strcasecmp(op, "!=")) {
- inv = 1;
- }
- else if (! strcasecmp(op, "=~")) {
- re = 1;
- }
- else if (! strcasecmp(op, "!~")) {
- inv = 1;
- re = 1;
- }
- else
- return NULL;
-
- if (! expr)
- return NULL;
-
- if (sdb_store_expr_eval(expr, /* obj */ NULL, &value, /* filter */ NULL)
- || (value.type != SDB_TYPE_STRING)) {
- sdb_data_free_datum(&value);
- return NULL;
- }
-
- m = sdb_store_name_matcher(type, value.data.string, re);
- sdb_data_free_datum(&value);
- return maybe_inv_matcher(m, inv);
-} /* sdb_store_matcher_parse_cmp */
-
sdb_store_matcher_t *
sdb_store_dis_matcher(sdb_store_matcher_t *left, sdb_store_matcher_t *right)
{
index 5d5995f56d6685003b87064a5bbfe2ab7f4a4293..b82ae2e9134cb41ca1f4cdb4b77626c454ab0cff 100644 (file)
--- a/src/include/core/store.h
+++ b/src/include/core/store.h
sdb_store_expr_eval(sdb_store_expr_t *expr, sdb_store_obj_t *obj,
sdb_data_t *res, sdb_store_matcher_t *filter);
-/*
- * sdb_store_name_matcher:
- * Creates a matcher matching by the specified object type's name. If 're' is
- * true, the specified name is treated as a POSIX extended regular expression.
- * Else, the exact name has to match (case-insensitive).
- */
-sdb_store_matcher_t *
-sdb_store_name_matcher(int type, const char *name, _Bool re);
-
/*
* sdb_store_isnull_matcher:
* Creates a matcher matching NULL values.
int
sdb_store_parse_field_name(const char *name);
-/*
- * sdb_store_matcher_parse_cmp:
- * Parse a simple compare expression (<obj_type> <op> <expression>).
- *
- * Returns:
- * - a matcher object on success
- * - NULL else
- */
-sdb_store_matcher_t *
-sdb_store_matcher_parse_cmp(const char *obj_type,
- const char *op, sdb_store_expr_t *expr);
-
/*
* sdb_store_dis_matcher:
* Creates a matcher matching the disjunction (logical OR) of two matchers.
index ce781c1131b0dba01c78cbe6cfb42ce53be27eea..4acfc0f4821d67f576037792804f624893af6652 100644 (file)
}
END_TEST
-START_TEST(test_parse_cmp)
-{
- sdb_data_t hostname = { SDB_TYPE_STRING, { .string = "hostname" } };
- sdb_data_t metricname = { SDB_TYPE_STRING, { .string = "metricname" } };
- sdb_data_t srvname = { SDB_TYPE_STRING, { .string = "srvname" } };
- sdb_data_t attrname = { SDB_TYPE_STRING, { .string = "attrname" } };
-
- sdb_store_matcher_t *check;
-
- size_t i;
-
- struct {
- const char *obj_type;
- const char *op;
- const sdb_data_t *value;
- int expected;
- } golden_data[] = {
- { "host", "=", &hostname, MATCHER_NAME },
- { "host", "!=", &hostname, MATCHER_NOT },
- { "host", "=~", &hostname, MATCHER_NAME },
- { "host", "!~", &hostname, MATCHER_NOT },
- { "host", "&^", &hostname, -1 },
- { "host", "<", &hostname, -1 },
- { "host", "<=", &hostname, -1 },
- { "host", ">=", &hostname, -1 },
- { "host", ">", &hostname, -1 },
- { "host", "=", NULL, -1 },
- { "metric", "=", &metricname, MATCHER_NAME },
- { "metric", "!=", &metricname, MATCHER_NOT },
- { "metric", "=~", &metricname, MATCHER_NAME },
- { "metric", "!~", &metricname, MATCHER_NOT },
- { "metric", "&^", &metricname, -1 },
- { "metric", "<", &metricname, -1 },
- { "metric", "<=", &metricname, -1 },
- { "metric", ">=", &metricname, -1 },
- { "metric", ">", &metricname, -1 },
- { "metric", "=", NULL, -1 },
- { "service", "=", &srvname, MATCHER_NAME },
- { "service", "!=", &srvname, MATCHER_NOT },
- { "service", "=~", &srvname, MATCHER_NAME },
- { "service", "!~", &srvname, MATCHER_NOT },
- { "service", "&^", &srvname, -1 },
- { "service", "<", &srvname, -1 },
- { "service", "<=", &srvname, -1 },
- { "service", ">=", &srvname, -1 },
- { "service", ">", &srvname, -1 },
- { "service", "=", NULL, -1 },
- { "attribute", "=", &attrname, MATCHER_NAME },
- { "attribute", "!=", &attrname, MATCHER_NOT },
- { "attribute", "=~", &attrname, MATCHER_NAME },
- { "attribute", "!~", &attrname, MATCHER_NOT },
- { "attribute", "<", &attrname, -1 },
- { "attribute", "<=", &attrname, -1 },
- { "attribute", ">=", &attrname, -1 },
- { "attribute", ">", &attrname, -1 },
- { "attribute", "=", NULL, -1 },
- { "foo", "=", &attrname, -1 },
- };
-
- for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
- sdb_store_expr_t *expr;
- char buf[1024];
-
- if (sdb_data_format(golden_data[i].value,
- buf, sizeof(buf), SDB_UNQUOTED) < 0)
- snprintf(buf, sizeof(buf), "ERR");
-
- expr = sdb_store_expr_constvalue(golden_data[i].value);
- fail_unless(expr != NULL || golden_data[i].value == NULL,
- "sdb_store_expr_constvalue(%s) = NULL; expected: <expr>",
- buf);
-
- check = sdb_store_matcher_parse_cmp(golden_data[i].obj_type,
- golden_data[i].op, expr);
- sdb_object_deref(SDB_OBJ(expr));
-
- if (golden_data[i].expected == -1) {
- fail_unless(check == NULL,
- "sdb_store_matcher_parse_cmp(%s, %s, expr{%s}) = %p; "
- "expected: NULL", golden_data[i].obj_type,
- golden_data[i].op, buf, check);
- continue;
- }
-
- fail_unless(check != NULL,
- "sdb_store_matcher_parse_cmp(%s, %s, %s) = %p; "
- "expected: <expr>", golden_data[i].obj_type,
- golden_data[i].op, buf, check);
- fail_unless(M(check)->type == golden_data[i].expected,
- "sdb_store_matcher_parse_cmp(%s, %s, %s) returned matcher "
- "of type %d; expected: %d", golden_data[i].obj_type,
- golden_data[i].op, buf, M(check)->type, golden_data[i].expected);
-
- sdb_object_deref(SDB_OBJ(check));
- }
-}
-END_TEST
-
static int
scan_cb(sdb_store_obj_t *obj, void *user_data)
{
tcase_add_test(tc, test_cmp_attr);
tcase_add_test(tc, test_cmp_obj);
tcase_add_test(tc, test_store_match_op);
- tcase_add_test(tc, test_parse_cmp);
tcase_add_test(tc, test_scan);
suite_add_tcase(s, tc);
index 6b9e86e95fd44d70d714276088c016ce9e577ed9..b48ca2f1830dc607504addc46c5a725cb95a9dfd 100644 (file)
{ NULL, -1, -1 },
{ "", -1, -1 },
- /* valid expressions */
+ /* match hosts by name */
+ { "host < 'localhost'", -1, MATCHER_LT },
+ { "host <= 'localhost'", -1, MATCHER_LE },
{ "host = 'localhost'", -1, MATCHER_EQ },
{ "host != 'localhost'", -1, MATCHER_NE },
+ { "host >= 'localhost'", -1, MATCHER_GE },
+ { "host > 'localhost'", -1, MATCHER_GT },
{ "host =~ 'host'", -1, MATCHER_REGEX },
{ "host !~ 'host'", -1, MATCHER_NREGEX },
{ "host = 'localhost' -- foo", -1, MATCHER_EQ },
{ "host = 'host' <garbage>", 13, MATCHER_EQ },
+ { "host &^ 'localhost'", -1, -1 },
/* match hosts by service */
+ { "service < 'name'", -1, MATCHER_SERVICE },
+ { "service <= 'name'", -1, MATCHER_SERVICE },
{ "service = 'name'", -1, MATCHER_SERVICE },
{ "service != 'name'", -1, MATCHER_SERVICE },
+ { "service >= 'name'", -1, MATCHER_SERVICE },
+ { "service > 'name'", -1, MATCHER_SERVICE },
{ "service =~ 'pattern'", -1, MATCHER_SERVICE },
{ "service !~ 'pattern'", -1, MATCHER_SERVICE },
+ { "service &^ 'name'", -1, -1 },
/* match hosts by metric */
+ { "metric < 'name'", -1, MATCHER_METRIC },
+ { "metric <= 'name'", -1, MATCHER_METRIC },
{ "metric = 'name'", -1, MATCHER_METRIC },
{ "metric != 'name'", -1, MATCHER_METRIC },
+ { "metric >= 'name'", -1, MATCHER_METRIC },
+ { "metric > 'name'", -1, MATCHER_METRIC },
{ "metric =~ 'pattern'", -1, MATCHER_METRIC },
{ "metric !~ 'pattern'", -1, MATCHER_METRIC },
/* match hosts by attribute */
+ { "attribute < 'name'", -1, MATCHER_ATTRIBUTE },
+ { "attribute <= 'name'", -1, MATCHER_ATTRIBUTE },
{ "attribute = 'name'", -1, MATCHER_ATTRIBUTE },
{ "attribute != 'name'", -1, MATCHER_ATTRIBUTE },
+ { "attribute >= 'name'", -1, MATCHER_ATTRIBUTE },
+ { "attribute > 'name'", -1, MATCHER_ATTRIBUTE },
{ "attribute =~ 'pattern'", -1, MATCHER_ATTRIBUTE },
{ "attribute !~ 'pattern'", -1, MATCHER_ATTRIBUTE },
+ { "attribute &^ 'pattern'", -1, -1 },
/* composite expressions */
{ "host =~ 'pattern' AND "
"service =~ 'pattern'", -1, MATCHER_AND },