# HG changeset patch # User Mike Becker # Date 1427208591 -3600 # Node ID 59c518ae0641c3f289237b610587de087af398c9 # Parent ca7f024dd0f95ed860799a95e80657c2cb271e2d added parse function prototype + started writing a debugger diff -r ca7f024dd0f9 -r 59c518ae0641 libidav/davqlparser.c --- a/libidav/davqlparser.c Tue Mar 24 12:02:47 2015 +0100 +++ b/libidav/davqlparser.c Tue Mar 24 15:49:51 2015 +0100 @@ -27,4 +27,109 @@ */ #include "davqlparser.h" +#include +#include +static const char* _map_querytype(davqltype_t type) { + switch(type) { + case GET: return "GET"; + case SET: return "SET"; + default: return "unknown"; + } +} + +#define dav_debug_print_sstr_t(s) fwrite((s).ptr, 1, (s).length, stdout); + +static void dav_debug_ql_stmt_print(DavQLStatement *stmt) { + + // Basic information + printf("Statement: "); + dav_debug_print_sstr_t(stmt->srctext); + printf("\nType: %s\nField count: %zu", + _map_querytype(stmt->type), + ucx_list_size(stmt->fields)); + + // Has wildcard + _Bool wildcard = 0; + UCX_FOREACH(elm, stmt->fields) { + DavQLExpression* expr = (DavQLExpression*)elm->data; + if (expr->type == IDENTIFIER && + expr->srctext.length == 1 && *(expr->srctext.ptr) == '*') { + wildcard = 1; + } + } + printf(" with%s wildcard\n", wildcard?"":"out"); + + // Pathname + printf("Path: "); + dav_debug_print_sstr_t(stmt->path.srctext); + + // Has where clause + printf("\nHas where clause: %s\n", stmt->where ? "yes" : "no"); + if (stmt->type == SET) { + printf("Value list size matches: %s", + ucx_list_size(stmt->fields) == ucx_list_size(stmt->setvalues) + ? "yes" : "no"); + } + + // WITH attributes + if (stmt->depth == SIZE_MAX) { + printf("Depth: unbound\n"); + } else { + printf("Depth: %zu\n", stmt->depth); + } +} + +static int dav_debug_ql_command() { + printf("Command (type 'h' for help): "); + + char buffer[16]; + fgets(buffer, 16, stdin); + if (!strcmp(buffer, "q\n")) { + return 0; + } else if (!strcmp(buffer, "ps\n")) { + return 1; + } else if (!strcmp(buffer, "h\n")) { + return 100; + } else { + return -1; + } +} + +void dav_debug_ql_statement(DavQLStatement *stmt) { + if (!stmt) { + fprintf(stderr, "Debug DavQLStatement failed: null pointer"); + return; + } + + printf("Starting DavQL debugger...\n\n"); + dav_debug_ql_stmt_print(stmt); + + while(1) { + int cmd = dav_debug_ql_command(); + switch (cmd) { + case 0: return; + case 1: dav_debug_ql_stmt_print(stmt); break; + case 100: + printf( + "\nCommands:\n" + "ps: print statement information\n" + "q: quit\n"); + break; + default: printf("unknown command\n"); + } + } +} + +DavQLStatement* dav_parse_statement(sstr_t srctext) { + DavQLStatement *stmt = malloc(sizeof(DavQLStatement)); + + // default values + memset(stmt, 0, sizeof(DavQLStatement)); + stmt->srctext = srctext; + stmt->type = -1; + stmt->depth = SIZE_MAX; + + + return stmt; +} diff -r ca7f024dd0f9 -r 59c518ae0641 libidav/davqlparser.h --- a/libidav/davqlparser.h Tue Mar 24 12:02:47 2015 +0100 +++ b/libidav/davqlparser.h Tue Mar 24 15:49:51 2015 +0100 @@ -33,6 +33,7 @@ extern "C" { #endif +#include #include "ucx/string.h" #include "ucx/list.h" @@ -167,16 +168,6 @@ davqltype_t type; /** * The list of field expressions. - *
    - *
  • - * GET: the list of queried fields (may contain arbitrary expressions) - *
  • - *
  • - * SET: the list of DAV properties that shall receive new values - * (must be a list of IDENTIFIER expressions) - *
  • - *
- * This may be NULL for GET queries, to request all properties. */ UcxList* fields; /** @@ -187,7 +178,7 @@ /** * A DavQLExpression that denotes the queried path. */ - DavQLExpression from; + DavQLExpression path; /** * Logical expression for selection. * NULL, if there is no where clause. @@ -201,6 +192,25 @@ } DavQLStatement; +/** + * Starts an interactive debugger for a DavQLStatement. + * + * @param stmt the statement to debug + */ +void dav_debug_ql_statement(DavQLStatement *stmt); + +/** + * Parses a statement. + * @param stmt the sstr_t containing the statement + * @return a DavQLStatement object + */ +DavQLStatement* dav_parse_statement(sstr_t stmt); + +/** + * Implicitly converts a cstr to a sstr_t and calls dav_parse_statement. + */ +#define dav_parse_cstr_statement(stmt) dav_parse_statement(S(stmt)) + #ifdef __cplusplus } #endif