libidav/davql.c

changeset 43
03076907b58a
parent 33
0bbbb0341606
child 74
da079dc0724c
--- a/libidav/davql.c	Tue Mar 18 13:59:02 2014 +0100
+++ b/libidav/davql.c	Thu Jun 05 15:11:29 2014 +0200
@@ -72,7 +72,9 @@
     
     sstr_t from_query = q;
     sstr_t cond = util_getsubstr_until_token(q, S("where"), &from_query);
-    
+    sstr_t with = util_getsubstr_until_token(cond, S("with"), &cond);
+    int depth = 1;
+       
     // insert variable values
     UcxBuffer *fbuf = ucx_buffer_new(NULL, 128, UCX_BUFFER_AUTOEXTEND);
     int var = 0;
@@ -124,9 +126,19 @@
         ucx_list_free(ops);
     }
     
+    // with
+    if(with.ptr) {
+        if(dav_parse_with(with, &depth, ap)) {
+            // TODO: error
+            printf("parse error\n");
+            return NULL;
+        }
+    }
+    
     DavGetQuery *getquery = malloc(sizeof(DavGetQuery));
     getquery->properties = sstrdup(property_query);
     getquery->from = sstrn(fbuf->space, fbuf->pos);
+    getquery->depth = depth;
     if(condition) {
         getquery->condition = condition;
         getquery->condlen = oplen;
@@ -166,6 +178,57 @@
     return 0;
 }
 
+static int dav_str2depth(sstr_t str, int *depth) {
+    if(!sstrcmp(str, S("infinity"))) {
+        *depth = -1;
+    } else {
+        sstr_t cp = sstrdup(str); // terminate
+        *depth = atoi(cp.ptr);
+        free(cp.ptr);
+    }
+    return 0;
+}
+
+int dav_parse_with(sstr_t with, int *depth, va_list ap) {
+    int i;
+    for(i=0;i<with.length;i++) {
+        if(with.ptr[i] == ' ') {
+            break;
+        }
+    }
+    
+    sstr_t name = sstrsubsl(with, 0, i);
+    sstr_t value = sstrtrim(sstrsubs(with, i));
+    //printf("with {%.*s} {%.*s}\n", name.length, name.ptr, value.length, value.ptr);
+    
+    if(!sstrcmp(name, S("depth"))) {
+        if(value.length == 0) {
+            return 1;
+        } else if(value.ptr[0] == '%') {
+            switch(value.ptr[1]) {
+                default: return 1;
+                case 's': {
+                    sstr_t v = sstr(va_arg(ap, char*));
+                    if(dav_str2depth(value, depth)) {
+                        return 1;
+                    }
+                    break;
+                }
+                case 'd': {
+                    *depth = va_arg(ap, int);
+                    break;
+                }
+            }
+        } else {
+            if(dav_str2depth(value, depth)) {
+                return 1;
+            }
+        }
+    }
+    
+    return 0;
+}
+
 int dav_parse_condition(UcxList **ops, sstr_t cond, va_list ap) {
     sstr_t token;
     DavQOp *op1 = NULL; // level 1 operator

mercurial