added parse function prototype + started writing a debugger

Tue, 24 Mar 2015 15:49:51 +0100

author
Mike Becker <universe@uap-core.de>
date
Tue, 24 Mar 2015 15:49:51 +0100
changeset 79
59c518ae0641
parent 78
ca7f024dd0f9
child 80
a2832c054c98

added parse function prototype + started writing a debugger

libidav/davqlparser.c file | annotate | diff | comparison | revisions
libidav/davqlparser.h file | annotate | diff | comparison | revisions
--- 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 <string.h>
+#include <stdio.h>
 
+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;
+}
--- 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 <stdint.h>
 #include "ucx/string.h"
 #include "ucx/list.h"
 
@@ -167,16 +168,6 @@
     davqltype_t type;
     /**
      * The list of field expressions.
-     * <ul>
-     * <li>
-     * GET: the list of queried fields (may contain arbitrary expressions)
-     * </li>
-     * <li>
-     * SET: the list of DAV properties that shall receive new values
-     * (must be a list of IDENTIFIER expressions)
-     * </li>
-     * </ul>
-     * This may be <code>NULL</code> 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.
      * <code>NULL</code>, 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

mercurial