summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: a5b906e)
raw | patch | inline | side by side (parent: a5b906e)
author | Sebastian Harl <sh@tokkee.org> | |
Sun, 26 Oct 2014 09:10:21 +0000 (10:10 +0100) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Sun, 26 Oct 2014 09:10:21 +0000 (10:10 +0100) |
This allows to handle all known objects and fields as part of the grammar
rather than manually parsing them and generating custom error messages.
rather than manually parsing them and generating custom error messages.
src/frontend/grammar.y | patch | blob | history | |
src/frontend/scanner.l | patch | blob | history |
diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y
index fed30d238f613fe92f301bd3a5ae695d26a10d9f..4702562e992ebcb7ae9058360a4e94c17f3205e7 100644 (file)
--- a/src/frontend/grammar.y
+++ b/src/frontend/grammar.y
*/
static sdb_store_matcher_t *
-name_iter_matcher(int m_type, const char *type_name, const char *cmp,
+name_iter_matcher(int m_type, int type, const char *cmp,
sdb_store_expr_t *expr);
/*
%union {
const char *sstr; /* static string */
char *str;
+ int integer;
sdb_data_t data;
sdb_time_t datetime;
%token CMP_LT CMP_LE CMP_GE CMP_GT ALL ANY IN
%token CONCAT
+%token HOST_T HOSTS_T SERVICE_T SERVICES_T METRIC_T METRICS_T
+%token ATTRIBUTE_T ATTRIBUTES_T
+%token NAME_T LAST_UPDATE_T AGE_T INTERVAL_T BACKEND_T
+
%token START END
/* NULL token */
%type <expr> expression
+%type <integer> object_type_plural
+%type <integer> iterable
+%type <integer> field
+
%type <sstr> cmp
%type <data> data
* Retrieve detailed information about a single host.
*/
fetch_statement:
- FETCH IDENTIFIER STRING filter_clause
+ FETCH HOST_T STRING filter_clause
{
/* TODO: support other types as well */
- if (strcasecmp($2, "host")) {
- char errmsg[strlen($2) + 32];
- snprintf(errmsg, sizeof(errmsg),
- YY_("unknown data-source %s"), $2);
- sdb_fe_yyerror(&yylloc, scanner, errmsg);
- free($2); $2 = NULL;
- free($3); $3 = NULL;
- sdb_object_deref(SDB_OBJ($4));
- YYABORT;
- }
$$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL,
conn_fetch_t, conn_fetch_destroy));
CONN_FETCH($$)->name = $3;
CONN_FETCH($$)->filter = CONN_MATCHER($4);
$$->cmd = CONNECTION_FETCH;
- free($2); $2 = NULL;
}
;
* Returns a list of all hosts in the store.
*/
list_statement:
- LIST IDENTIFIER filter_clause
+ LIST object_type_plural filter_clause
{
- int type = sdb_store_parse_object_type_plural($2);
- if ((type < 0) || (type == SDB_ATTRIBUTE)) {
- char errmsg[strlen($2) + 32];
- snprintf(errmsg, sizeof(errmsg),
- YY_("unknown data-source %s"), $2);
- sdb_fe_yyerror(&yylloc, scanner, errmsg);
- free($2); $2 = NULL;
- sdb_object_deref(SDB_OBJ($3));
- YYABORT;
- }
-
$$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL,
conn_list_t, conn_list_destroy));
- CONN_LIST($$)->type = type;
+ CONN_LIST($$)->type = $2;
CONN_LIST($$)->filter = CONN_MATCHER($3);
$$->cmd = CONNECTION_LIST;
- free($2); $2 = NULL;
}
;
* Returns detailed information about <type> matching condition.
*/
lookup_statement:
- LOOKUP IDENTIFIER matching_clause filter_clause
+ LOOKUP HOSTS_T matching_clause filter_clause
{
/* TODO: support other types as well */
- if (strcasecmp($2, "hosts")) {
- char errmsg[strlen($2) + 32];
- snprintf(errmsg, sizeof(errmsg),
- YY_("unknown data-source %s"), $2);
- sdb_fe_yyerror(&yylloc, scanner, errmsg);
- free($2); $2 = NULL;
- sdb_object_deref(SDB_OBJ($3));
- sdb_object_deref(SDB_OBJ($4));
- YYABORT;
- }
$$ = SDB_CONN_NODE(sdb_object_create_dT(/* name = */ NULL,
conn_lookup_t, conn_lookup_destroy));
CONN_LOOKUP($$)->matcher = CONN_MATCHER($3);
CONN_LOOKUP($$)->filter = CONN_MATCHER($4);
$$->cmd = CONNECTION_LOOKUP;
- free($2); $2 = NULL;
}
;
sdb_object_deref(SDB_OBJ($3));
}
|
- ANY IDENTIFIER cmp expression
+ ANY iterable cmp expression
{
$$ = name_iter_matcher(MATCHER_ANY, $2, $3, $4);
- free($2); $2 = NULL;
sdb_object_deref(SDB_OBJ($4));
}
|
- ALL IDENTIFIER cmp expression
+ ALL iterable cmp expression
{
$$ = name_iter_matcher(MATCHER_ALL, $2, $3, $4);
- free($2); $2 = NULL;
sdb_object_deref(SDB_OBJ($4));
}
|
sdb_object_deref(SDB_OBJ($3)); $3 = NULL;
}
|
- IDENTIFIER
+ HOST_T
{
- int field;
/* TODO: this only works as long as queries
* are limited to hosts */
- if (!strcasecmp($1, "host"))
- field = SDB_FIELD_NAME;
- else
- field = sdb_store_parse_field_name($1);
- free($1); $1 = NULL;
- $$ = sdb_store_expr_fieldvalue(field);
+ $$ = sdb_store_expr_fieldvalue(SDB_FIELD_NAME);
}
|
- IDENTIFIER '[' STRING ']'
+ field
+ {
+ $$ = sdb_store_expr_fieldvalue($1);
+ }
+ |
+ ATTRIBUTE_T '[' STRING ']'
{
- if (strcasecmp($1, "attribute")) {
- char errmsg[strlen($1) + strlen($3) + 32];
- snprintf(errmsg, sizeof(errmsg),
- YY_("unknown value %s[%s]"), $1, $3);
- sdb_fe_yyerror(&yylloc, scanner, errmsg);
- free($1); $1 = NULL;
- free($3); $3 = NULL;
- YYABORT;
- }
$$ = sdb_store_expr_attrvalue($3);
- free($1); $1 = NULL;
free($3); $3 = NULL;
}
|
}
;
+object_type_plural:
+ HOSTS_T { $$ = SDB_HOST; }
+ |
+ SERVICES_T { $$ = SDB_SERVICE; }
+ |
+ METRICS_T { $$ = SDB_METRIC; }
+ ;
+
+iterable:
+ SERVICE_T { $$ = SDB_SERVICE; }
+ |
+ METRIC_T { $$ = SDB_METRIC; }
+ |
+ ATTRIBUTE_T { $$ = SDB_ATTRIBUTE; }
+ ;
+
+field:
+ NAME_T { $$ = SDB_FIELD_NAME; }
+ |
+ LAST_UPDATE_T { $$ = SDB_FIELD_LAST_UPDATE; }
+ |
+ AGE_T { $$ = SDB_FIELD_AGE; }
+ |
+ INTERVAL_T { $$ = SDB_FIELD_INTERVAL; }
+ |
+ BACKEND_T { $$ = SDB_FIELD_BACKEND; }
+ ;
+
cmp:
CMP_EQUAL { $$ = "="; }
|
} /* sdb_fe_yyerror */
static sdb_store_matcher_t *
-name_iter_matcher(int m_type, const char *type_name, const char *cmp,
+name_iter_matcher(int m_type, int type, const char *cmp,
sdb_store_expr_t *expr)
{
- int type = sdb_store_parse_object_type(type_name);
sdb_store_matcher_op_cb cb = sdb_store_parse_matcher_op(cmp);
sdb_store_expr_t *e;
sdb_store_matcher_t *m, *tmp = NULL;
diff --git a/src/frontend/scanner.l b/src/frontend/scanner.l
index b581e3d613cea435dd22f4c759ea292850ae2675..c8d0dcbca25de94fe27196f7b1d65ff034370522 100644 (file)
--- a/src/frontend/scanner.l
+++ b/src/frontend/scanner.l
const char *name;
int id;
} reserved_words[] = {
- { "ALL", ALL },
- { "AND", AND },
- { "ANY", ANY },
- { "END", END },
- { "FETCH", FETCH },
- { "FILTER", FILTER },
- { "IN", IN },
- { "IS", IS },
- { "LIST", LIST },
- { "LOOKUP", LOOKUP },
- { "MATCHING", MATCHING },
- { "NOT", NOT },
- { "NULL", NULL_T },
- { "OR", OR },
- { "START", START },
- { "TIMESERIES", TIMESERIES },
+ { "ALL", ALL },
+ { "AND", AND },
+ { "ANY", ANY },
+ { "END", END },
+ { "FETCH", FETCH },
+ { "FILTER", FILTER },
+ { "IN", IN },
+ { "IS", IS },
+ { "LIST", LIST },
+ { "LOOKUP", LOOKUP },
+ { "MATCHING", MATCHING },
+ { "NOT", NOT },
+ { "NULL", NULL_T },
+ { "OR", OR },
+ { "START", START },
+ { "TIMESERIES", TIMESERIES },
+
+ /* object types */
+ { "host", HOST_T },
+ { "hosts", HOSTS_T },
+ { "service", SERVICE_T },
+ { "services", SERVICES_T },
+ { "metric", METRIC_T },
+ { "metrics", METRICS_T },
+ { "attribute", ATTRIBUTE_T },
+ { "attributes", ATTRIBUTES_T },
+ /* queryable fields */
+ { "name", NAME_T },
+ { "last_update", LAST_UPDATE_T },
+ { "age", AGE_T },
+ { "interval", INTERVAL_T },
+ { "backend", BACKEND_T },
};
void