added path examination to debugger + changed field names of expression subtrees

Tue, 31 Mar 2015 09:43:42 +0200

author
Mike Becker <universe@uap-core.de>
date
Tue, 31 Mar 2015 09:43:42 +0200
changeset 80
a2832c054c98
parent 79
59c518ae0641
child 81
8e186185422c

added path examination to debugger + changed field names of expression subtrees

libidav/davqlparser.c file | annotate | diff | comparison | revisions
libidav/davqlparser.h file | annotate | diff | comparison | revisions
--- 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 <string.h>
 #include <stdio.h>
 
+#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;
     
     
--- 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.
      * <code>NULL</code> for literals or identifiers.
      */
-    DavQLExpression *expr1;
+    DavQLExpression *left;
     /**
      * Right operand.
      * <code>NULL</code> for literals, identifiers or unary expressions.
      */
-    DavQLExpression *expr2;
+    DavQLExpression *right;
 };
 
 

mercurial