summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: c3cffe0)
raw | patch | inline | side by side (parent: c3cffe0)
author | Sebastian Harl <sh@tokkee.org> | |
Sun, 6 Apr 2014 17:42:43 +0000 (19:42 +0200) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Sun, 6 Apr 2014 17:42:43 +0000 (19:42 +0200) |
src/core/store_lookup.c | patch | blob | history | |
src/frontend/grammar.y | patch | blob | history | |
src/frontend/scanner.l | patch | blob | history | |
t/core/store_lookup_test.c | patch | blob | history |
index d43b9e32c764c10e0a372dabd71a79d3d30668f2..7416800a2281dd398ee90af83b5942c3eaf3eb07 100644 (file)
--- a/src/core/store_lookup.c
+++ b/src/core/store_lookup.c
const char *op, const char *value)
{
int typ = -1;
+ int inv = 0;
+
+ sdb_store_matcher_t *m = NULL;
const char *matcher = NULL;
const char *matcher_re = NULL;
typ = SDB_ATTRIBUTE;
/* TODO: support other operators */
- if (! strcasecmp(op, "="))
+ if (! strcasecmp(op, "=")) {
+ matcher = value;
+ }
+ else if (! strcasecmp(op, "!=")) {
matcher = value;
- else if (! strcasecmp(op, "=~"))
+ inv = 1;
+ }
+ else if (! strcasecmp(op, "=~")) {
matcher_re = value;
+ }
+ else if (! strcasecmp(op, "!~")) {
+ matcher_re = value;
+ inv = 1;
+ }
else
return NULL;
/* accept */
}
else if (typ == SDB_ATTRIBUTE)
- return sdb_store_attr_matcher(attr, NULL, matcher, matcher_re);
+ m = 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);
+ if (m) {
+ /* accept the attribute value matcher */
+ }
+ else if (typ == SDB_HOST)
+ m = sdb_store_host_matcher(matcher, matcher_re, NULL, NULL);
else if (typ == SDB_SERVICE)
- return sdb_store_service_matcher(matcher, matcher_re, NULL);
+ m = 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;
+ m = sdb_store_attr_matcher(matcher, matcher_re, NULL, NULL);
+
+ if (m && inv) {
+ sdb_store_matcher_t *tmp;
+ tmp = sdb_store_inv_matcher(m);
+ /* pass ownership to the inverse matcher */
+ sdb_object_deref(SDB_OBJ(m));
+ m = tmp;
+ }
+ return m;
} /* sdb_store_matcher_parse_cmp */
sdb_store_matcher_t *
diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y
index 4bade3b47af690eae54b703eb12d8b1fd477464c..858c766b698aa124308a292f8ddcf90250127120 100644 (file)
--- a/src/frontend/grammar.y
+++ b/src/frontend/grammar.y
%token SCANNER_ERROR
-%token AND OR WHERE
+%token AND OR NOT WHERE
-%token CMP_EQUAL CMP_REGEX
+%token CMP_EQUAL CMP_NEQUAL CMP_REGEX CMP_NREGEX
%token <str> IDENTIFIER STRING
%token <node> FETCH LIST LOOKUP
/* Precedence (lowest first): */
%left OR
%left AND
-%left CMP_EQUAL
-%left CMP_REGEX
+%left NOT
+%left CMP_EQUAL CMP_NEQUAL
+%left CMP_REGEX CMP_NREGEX
%left '(' ')'
%left '.'
$$ = sdb_store_dis_matcher($1, $3);
}
|
+ NOT matcher
+ {
+ $$ = sdb_store_inv_matcher($2);
+ }
+ |
compare_matcher
{
$$ = $1;
free($5); $5 = NULL;
}
|
+ IDENTIFIER '.' IDENTIFIER CMP_NEQUAL STRING
+ {
+ $$ = sdb_store_matcher_parse_cmp($1, $3, "!=", $5);
+ /* TODO: simplify memory management in the parser */
+ free($1); $1 = NULL;
+ free($3); $3 = NULL;
+ free($5); $5 = NULL;
+ }
+ |
IDENTIFIER '.' IDENTIFIER CMP_REGEX STRING
{
$$ = sdb_store_matcher_parse_cmp($1, $3, "=~", $5);
free($3); $3 = NULL;
free($5); $5 = NULL;
}
+ |
+ IDENTIFIER '.' IDENTIFIER CMP_NREGEX STRING
+ {
+ $$ = sdb_store_matcher_parse_cmp($1, $3, "!~", $5);
+ free($1); $1 = NULL;
+ free($3); $3 = NULL;
+ free($5); $5 = NULL;
+ }
;
%%
diff --git a/src/frontend/scanner.l b/src/frontend/scanner.l
index 9eec4de6c455e3dadd99fe586c2d4e68ba324395..32c13c54c355865d4024e94f683a06b6330b9492 100644 (file)
--- a/src/frontend/scanner.l
+++ b/src/frontend/scanner.l
}
= { return CMP_EQUAL; }
+!= { return CMP_NEQUAL; }
=~ { return CMP_REGEX; }
+!~ { return CMP_NREGEX; }
. { /* XXX: */ return yytext[0]; }
index 977bd9568d3203aab6a27f6c7354403494eee72b..a16d343d37d0a9991e244d419c6226ecc64c23d5 100644 (file)
int expected;
} golden_data[] = {
{ "host", "name", "=", "hostname", MATCHER_HOST },
+ { "host", "name", "!=", "hostname", MATCHER_NOT },
{ "host", "name", "=~", "hostname", MATCHER_HOST },
+ { "host", "name", "!~", "hostname", MATCHER_NOT },
{ "host", "attr", "=", "hostname", -1 },
+ { "host", "attr", "!=", "hostname", -1 },
{ "host", "name", "&^", "hostname", -1 },
{ "service", "name", "=", "srvname", MATCHER_SERVICE },
- { "service", "name", "=", "srvname", MATCHER_SERVICE },
+ { "service", "name", "!=", "srvname", MATCHER_NOT },
+ { "service", "name", "=~", "srvname", MATCHER_SERVICE },
+ { "service", "name", "!~", "srvname", MATCHER_NOT },
{ "service", "attr", "=", "srvname", -1 },
+ { "service", "attr", "!=", "srvname", -1 },
{ "service", "name", "&^", "srvname", -1 },
{ "attribute", "name", "=", "attrname", MATCHER_ATTR },
+ { "attribute", "name", "!=", "attrname", MATCHER_NOT },
{ "attribute", "name", "=~", "attrname", MATCHER_ATTR },
+ { "attribute", "name", "!~", "attrname", MATCHER_NOT },
{ "attribute", "attr", "=", "attrname", MATCHER_ATTR },
+ { "attribute", "attr", "!=", "attrname", MATCHER_NOT },
{ "attribute", "attr", "=~", "attrname", MATCHER_ATTR },
+ { "attribute", "attr", "!~", "attrname", MATCHER_NOT },
{ "attribute", "attr", "&^", "attrname", -1 },
};