Code

frontend/parser: Added support for time interval values.
authorSebastian Harl <sh@tokkee.org>
Wed, 30 Jul 2014 08:31:39 +0000 (10:31 +0200)
committerSebastian Harl <sh@tokkee.org>
Wed, 30 Jul 2014 08:31:39 +0000 (10:31 +0200)
src/frontend/grammar.y
t/unit/frontend/parser_test.c

index ed4de830fc64cc0f091a52c43624fd325ee96e17..85fe8c4a108b6a34864b6e778a851664ecfdd053 100644 (file)
@@ -125,6 +125,7 @@ sdb_fe_yyerror(YYLTYPE *lval, sdb_fe_yyscan_t scanner, const char *msg);
 %type <sstr> op
 
 %type <data> data
+       interval interval_elem
 
 %destructor { free($$); } <str>
 %destructor { sdb_object_deref(SDB_OBJ($$)); } <node> <m> <expr>
@@ -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;
+                       }
+               }
        ;
 
 %%
index 59de563f760c74e291ec47998081b03344c442c4..a0826070ed958a6e864998af1eecf3890e944906 100644 (file)
@@ -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 "