From c170fba7115034b0d39ee8cf9d3bec9c706110f1 Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Wed, 30 Jul 2014 10:31:39 +0200 Subject: [PATCH] frontend/parser: Added support for time interval values. --- src/frontend/grammar.y | 39 +++++++++++++++++++++++++++++++++++ t/unit/frontend/parser_test.c | 16 ++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/frontend/grammar.y b/src/frontend/grammar.y index ed4de83..85fe8c4 100644 --- a/src/frontend/grammar.y +++ b/src/frontend/grammar.y @@ -125,6 +125,7 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg); %type op %type data + interval interval_elem %destructor { free($$); } %destructor { sdb_object_deref(SDB_OBJ($$)); } @@ -416,6 +417,44 @@ data: INTEGER { $$ = $1; } | FLOAT { $$ = $1; } + | + interval { $$ = $1; } + ; + +interval: + interval interval_elem + { + $$.data.datetime = $1.data.datetime + $2.data.datetime; + } + | + interval_elem { $$ = $1; } + ; + +interval_elem: + INTEGER IDENTIFIER + { + sdb_time_t unit = 1; + + unit = sdb_strpunit($2); + if (! unit) { + char errmsg[strlen($2) + 32]; + snprintf(errmsg, sizeof(errmsg), + YY_("invalid time unit %s"), $2); + sdb_fe_yyerror(&yylloc, scanner, errmsg); + free($2); $2 = NULL; + YYABORT; + } + free($2); $2 = NULL; + + $$.type = SDB_TYPE_DATETIME; + $$.data.datetime = (sdb_time_t)$1.data.integer * unit; + + if ($1.data.integer < 0) { + sdb_fe_yyerror(&yylloc, scanner, + YY_("syntax error, negative intervals not supported")); + YYABORT; + } + } ; %% diff --git a/t/unit/frontend/parser_test.c b/t/unit/frontend/parser_test.c index 59de563..a082607 100644 --- a/t/unit/frontend/parser_test.c +++ b/t/unit/frontend/parser_test.c @@ -106,6 +106,22 @@ START_TEST(test_parse) "attribute.foo = " "-12e+3", -1, 1, CONNECTION_LOOKUP }, + /* date, time, interval constants */ + { "LOOKUP hosts MATCHING " + "attribute.foo = " + "1 Y 42D", -1, 1, CONNECTION_LOOKUP }, + { "LOOKUP hosts MATCHING " + "attribute.foo = " + "1s 42D", -1, 1, CONNECTION_LOOKUP }, + /* + * TODO: Something like 1Y42D should work as well but it doesn't since + * the scanner will tokenize it into {digit}{identifier} :-/ + * + { "LOOKUP hosts MATCHING " + "attribute.foo = " + "1Y42D", -1, 1, CONNECTION_LOOKUP }, + */ + /* NULL */ { "LOOKUP hosts MATCHING " "attribute.foo " -- 2.30.2