Code

frontend parser: Added 'len' parameter to sdb_fe_parse().
authorSebastian Harl <sh@tokkee.org>
Mon, 6 Jan 2014 10:55:53 +0000 (11:55 +0100)
committerSebastian Harl <sh@tokkee.org>
Mon, 6 Jan 2014 10:55:53 +0000 (11:55 +0100)
When greater than (or equal to) zero, this parameter let's the parser parse a
substring of the specified query. This makes it easier to pass in a command
stored in a connection's input string buffer.

src/frontend/parser.c
src/frontend/scanner.l
src/include/frontend/connection.h
src/include/frontend/parser.h
t/frontend/parser_test.c

index 037550fbddd731bf4bd84c51c8d126d50466ff16..718ed681c7dcbab31f7bc3e51540fa529a3c6bb2 100644 (file)
@@ -40,7 +40,7 @@
  */
 
 sdb_llist_t *
-sdb_fe_parse(const char *query)
+sdb_fe_parse(const char *query, int len)
 {
        sdb_fe_yyscan_t scanner;
        sdb_fe_yyextra_t yyextra;
@@ -52,7 +52,7 @@ sdb_fe_parse(const char *query)
        memset(&yyextra, 0, sizeof(yyextra));
        yyextra.parsetree = sdb_llist_create();
 
-       scanner = sdb_fe_scanner_init(query, &yyextra);
+       scanner = sdb_fe_scanner_init(query, len, &yyextra);
        if (! scanner) {
                sdb_llist_destroy(yyextra.parsetree);
                return NULL;
index f300e46d73160d906f841dd3c421f125d3a93fcc..a0c05d8ab495fdd7ed4da9e215f0caa280f1b36c 100644 (file)
@@ -97,10 +97,13 @@ identifier  ([A-Za-z_][A-Za-z_0-9$]*)
 %%
 
 sdb_fe_yyscan_t
-sdb_fe_scanner_init(const char *str, sdb_fe_yyextra_t *yyext)
+sdb_fe_scanner_init(const char *str, int len, sdb_fe_yyextra_t *yyext)
 {
        yyscan_t scanner;
 
+       if (! str)
+               return NULL;
+
        if (sdb_fe_yylex_init(&scanner)) {
                char errbuf[1024];
                sdb_log(SDB_LOG_ERR, "frontend: yylex_init failed: %s",
@@ -110,9 +113,12 @@ sdb_fe_scanner_init(const char *str, sdb_fe_yyextra_t *yyext)
 
        sdb_fe_yyset_extra(yyext, scanner);
 
+       if (len < 0)
+               len = strlen(str);
+
        /* the newly allocated buffer state (YY_BUFFER_STATE) is stored inside the
         * scanner and, thus, will be freed by yylex_destroy */
-       yy_scan_string(str, scanner);
+       sdb_fe_yy_scan_bytes(str, len, scanner);
        return scanner;
 } /* sdb_fe_scanner_init */
 
index 06f52435eeb76fe2e0a5a0d1d870e127ba946a9b..45d377e10df2ffb9ff28220b9c331f0410e47e0a 100644 (file)
@@ -108,16 +108,17 @@ sdb_connection_ping(sdb_conn_t *conn);
 
 /*
  * sdb_fe_parse:
- * Parse the query text specified in 'query' and return a list of parse trees
- * (for each command) to be executed by sdb_fe_exec. The list has to be freed
- * by the caller.
+ * Parse the query text specified in 'query' of length 'len' and return a list
+ * of parse trees (for each command) to be executed by sdb_fe_exec. The list
+ * has to be freed by the caller. If 'len' is less than zero, parse the whole
+ * (nul-terminated) string.
  *
  * Returns:
  *  - an sdb_llist_t object of sdb_conn_node_t on success
  *  - NULL in case of an error
  */
 sdb_llist_t *
-sdb_fe_parse(const char *query);
+sdb_fe_parse(const char *query, int len);
 
 /*
  * sdb_fe_exec:
index a80969ccb14fb746ddc0a3cad3e7a9f5c7dbb481..66a1a5c4a4da8bf90f9981752961637de243725d 100644 (file)
@@ -44,7 +44,7 @@ typedef struct {
 typedef void *sdb_fe_yyscan_t;
 
 sdb_fe_yyscan_t
-sdb_fe_scanner_init(const char *str, sdb_fe_yyextra_t *yyext);
+sdb_fe_scanner_init(const char *str, int len, sdb_fe_yyextra_t *yyext);
 
 void
 sdb_fe_scanner_destroy(sdb_fe_yyscan_t scanner);
index 589553398bd9058ac50fe8d3e342e30a9c8ad00c..8270cb1d3ac73d13fce9372e9811380ce2d90707 100644 (file)
@@ -38,25 +38,26 @@ START_TEST(test_parse)
 {
        struct {
                const char *query;
+               int len;
                int expected;
        } golden_data[] = {
                /* empty commands */
-               { NULL,                 -1 },
-               { "",                    0 },
-               { ";",                   0 },
-               { ";;",                  0 },
+               { NULL,                 -1, -1 },
+               { "",                   -1,  0 },
+               { ";",                  -1,  0 },
+               { ";;",                 -1,  0 },
 
                /* valid commands */
-               { "LIST",                1 },
-               { "LIST;",               1 },
+               { "LIST",               -1,  1 },
+               { "LIST;",              -1,  1 },
 
                /* comments */
-               { "/* some comment */",  0 },
-               { "-- another comment",  0 },
+               { "/* some comment */", -1,  0 },
+               { "-- another comment", -1,  0 },
 
                /* syntax errors */
-               { "INVALID",            -1 },
-               { "/* some incomplete", -1 },
+               { "INVALID",            -1, -1 },
+               { "/* some incomplete", -1, -1 },
        };
 
        size_t i;
@@ -65,7 +66,7 @@ START_TEST(test_parse)
        for (i = 0; i < SDB_STATIC_ARRAY_LEN(golden_data); ++i) {
                _Bool ok;
 
-               check = sdb_fe_parse(golden_data[i].query);
+               check = sdb_fe_parse(golden_data[i].query, golden_data[i].len);
                if (golden_data[i].expected < 0)
                        ok = check == 0;
                else