--- 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