# HG changeset patch # User Mike Becker # Date 1427787822 -7200 # Node ID a2832c054c98e8e95f578b147959f1795bb43105 # Parent 59c518ae0641c3f289237b610587de087af398c9 added path examination to debugger + changed field names of expression subtrees diff -r 59c518ae0641 -r a2832c054c98 libidav/davqlparser.c --- a/libidav/davqlparser.c Tue Mar 24 15:49:51 2015 +0100 +++ b/libidav/davqlparser.c Tue Mar 31 09:43:42 2015 +0200 @@ -30,6 +30,8 @@ #include #include +#define sfmtarg(s) ((int)(s).length), (s).ptr + static const char* _map_querytype(davqltype_t type) { switch(type) { case GET: return "GET"; @@ -38,14 +40,37 @@ } } -#define dav_debug_print_sstr_t(s) fwrite((s).ptr, 1, (s).length, stdout); +static const char* _map_exprtype(davqlexprtype_t type) { + switch(type) { + case LITERAL: return "LITERAL"; + case IDENTIFIER: return "IDENTIFIER"; + case UNARY: return "UNARY"; + case BINARY: return "BINARY"; + case LOGICAL: return "LOGICAL"; + case FUNCCALL: return "FUNCCALL"; + default: return "unknown"; + } +} + +static const char* _map_operator(davqloperator_t op) { + // don't use string array, because enum values may change + switch(op) { + case ADD: return "+"; case SUB: return "-"; case MUL: return "*"; + case DIV: return "/"; case AND: return "&"; case OR: return "|"; + case XOR: return "^"; case NEG: return "~"; case NOT: return "NOT"; + case LAND: return "AND"; case LOR: return "OR"; case LXOR: return "XOR"; + case EQ: return "="; case NEQ: return "!="; case LT: return "<"; + case GT: return ">"; case LE: return "<="; case GE: return ">="; + case LIKE: return "LIKE"; case UNLIKE: return "UNLIKE"; + default: return "unknown"; + } +} 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", + printf("Statement: %*s\nType: %s\nField count: %zu", + sfmtarg(stmt->srctext), _map_querytype(stmt->type), ucx_list_size(stmt->fields)); @@ -58,14 +83,10 @@ 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"); + printf(" %s wildcard\nPath: %*s\nHas where clause: %s\n", + wildcard?"with":"without", + sfmtarg(stmt->path.srctext), + stmt->where ? "yes" : "no"); if (stmt->type == SET) { printf("Value list size matches: %s", ucx_list_size(stmt->fields) == ucx_list_size(stmt->setvalues) @@ -80,17 +101,56 @@ } } +static int dav_debug_ql_expr_selected(DavQLExpression *expr) { + if (!expr) { + printf("Currently no expression selected.\n"); + return 0; + } else { + return 1; + } +} + +static void dav_debug_ql_expr_print(DavQLExpression *expr) { + if (dav_debug_ql_expr_selected(expr)) { + sstr_t empty = S("(empty)"); + printf( + "Text: %*s\nType: %s\nOperator: %s\n" + "Left hand: %*s\nRight hand: %*s\n", + sfmtarg(expr->srctext), + _map_exprtype(expr->type), + _map_operator(expr->op), + sfmtarg(expr->left?expr->left->srctext:empty), + sfmtarg(expr->right?expr->right->srctext:empty)); + } +} + +#define DQLD_CMD_Q 0 +#define DQLD_CMD_PS 1 +#define DQLD_CMD_PE 2 +#define DQLD_CMD_P 10 +#define DQLD_CMD_L 21 +#define DQLD_CMD_R 22 +#define DQLD_CMD_H 100 + static int dav_debug_ql_command() { - printf("Command (type 'h' for help): "); + printf("> "); char buffer[16]; fgets(buffer, 16, stdin); if (!strcmp(buffer, "q\n")) { - return 0; + return DQLD_CMD_Q; } else if (!strcmp(buffer, "ps\n")) { - return 1; + return DQLD_CMD_PS; + } else if (!strcmp(buffer, "pe\n")) { + return DQLD_CMD_PE; + } else if (!strcmp(buffer, "p\n")) { + return DQLD_CMD_P; + } else if (!strcmp(buffer, "l\n")) { + return DQLD_CMD_L; + } else if (!strcmp(buffer, "r\n")) { + return DQLD_CMD_R; } else if (!strcmp(buffer, "h\n")) { - return 100; + return DQLD_CMD_H; } else { return -1; } @@ -102,19 +162,51 @@ return; } - printf("Starting DavQL debugger...\n\n"); + printf("Starting DavQL debugger (type 'h' for help)...\n\n"); dav_debug_ql_stmt_print(stmt); + DavQLExpression *examineexpr = NULL; + while(1) { int cmd = dav_debug_ql_command(); switch (cmd) { - case 0: return; - case 1: dav_debug_ql_stmt_print(stmt); break; - case 100: + case DQLD_CMD_Q: return; + case DQLD_CMD_PS: dav_debug_ql_stmt_print(stmt); break; + case DQLD_CMD_PE: dav_debug_ql_expr_print(examineexpr); break; + case DQLD_CMD_P: + examineexpr = &(stmt->path); + dav_debug_ql_expr_print(examineexpr); + break; + case DQLD_CMD_L: + if (dav_debug_ql_expr_selected(examineexpr)) { + if (examineexpr->left) { + examineexpr = examineexpr->left; + dav_debug_ql_expr_print(examineexpr); + } else { + printf("There is no left subtree.\n"); + } + } + break; + case DQLD_CMD_R: + if (dav_debug_ql_expr_selected(examineexpr)) { + if (examineexpr->right) { + examineexpr = examineexpr->right; + dav_debug_ql_expr_print(examineexpr); + } else { + printf("There is no right subtree.\n"); + } + } + break; + case DQLD_CMD_H: printf( "\nCommands:\n" + "p: examine path\n" "ps: print statement information\n" - "q: quit\n"); + "q: quit\n\n" + "\nExpression examination:\n" + "pe: print expression information\n" + "l: enter left subtree\n" + "r: enter right subtree\n"); break; default: printf("unknown command\n"); } @@ -127,7 +219,7 @@ // default values memset(stmt, 0, sizeof(DavQLStatement)); stmt->srctext = srctext; - stmt->type = -1; + stmt->type = stmt->path.type = stmt->path.op = -1; stmt->depth = SIZE_MAX; diff -r 59c518ae0641 -r a2832c054c98 libidav/davqlparser.h --- a/libidav/davqlparser.h Tue Mar 24 15:49:51 2015 +0100 +++ b/libidav/davqlparser.h Tue Mar 31 09:43:42 2015 +0200 @@ -88,12 +88,12 @@ * Left or single operand. * NULL for literals or identifiers. */ - DavQLExpression *expr1; + DavQLExpression *left; /** * Right operand. * NULL for literals, identifiers or unary expressions. */ - DavQLExpression *expr2; + DavQLExpression *right; };