diff -r 438c8fe7d62f -r 4826f5fdd865 dav/sync.c --- a/dav/sync.c Wed May 30 16:51:52 2018 +0200 +++ b/dav/sync.c Wed May 30 18:04:43 2018 +0200 @@ -56,6 +56,7 @@ #include "libidav/session.h" #include +#include static DavContext *ctx; @@ -255,6 +256,35 @@ return 1; } +// TODO: use scstr_t after update to UCX 2.0 +static sstr_t rtrimskip(sstr_t str, size_t skip) { + while (skip < str.length && isspace(str.ptr[skip])) skip++; + return sstrsubs(str, skip); +} + +static size_t parse_tagfilter_taglist(sstr_t fs, SyncTagFilter* tagfilter) { + size_t csvlen; + for (csvlen = 0 ; csvlen < fs.length ; ++csvlen) { + if (fs.ptr[csvlen] == ')') break; + } + fs.length = csvlen; + + tagfilter->tags = parse_csv_taglist(fs.ptr, fs.length); + + return csvlen; +} + +/* + * Parses: ( "(" , filter , ")" )+ + */ +static size_t parse_tagfilter_subfilters(sstr_t fs, SyncTagFilter* tagfilter) { + // TODO: implement + tagfilter->subfilter_count = 0; + tagfilter->subfilters = NULL; + + return 0; +} + SyncTagFilter* parse_tagfilter_string(const char* filterstring) { SyncTagFilter* tagfilter = malloc(sizeof(SyncTagFilter)); if (!filterstring) { @@ -262,10 +292,48 @@ return tagfilter; } - tagfilter->mode = DAV_SYNC_TAGFILTER_AND; - tagfilter->subfilter_count = 0; - tagfilter->tags = parse_csv_taglist(filterstring, strlen(filterstring)); + // TODO: use scstr_t after update to UCX 2.0 + sstr_t fs = sstrtrim(sstr((char*) filterstring)); + if (fs.length == 0) { + memset(tagfilter, 0, sizeof(SyncTagFilter)); + return tagfilter; + } else { + + // optional operator + if (fs.ptr[0] == '&') { + tagfilter->mode = DAV_SYNC_TAGFILTER_AND; + fs = rtrimskip(fs, 1); + } else if (fs.ptr[0] == '|') { + tagfilter->mode = DAV_SYNC_TAGFILTER_OR; + fs = rtrimskip(fs, 1); + } else if (fs.ptr[0] == '0') { + tagfilter->mode = DAV_SYNC_TAGFILTER_NONE; + fs = rtrimskip(fs, 1); + } else if (fs.ptr[0] == '1') { + tagfilter->mode = DAV_SYNC_TAGFILTER_ONE; + fs = rtrimskip(fs, 1); + } else { + // default operator is AND + tagfilter->mode = DAV_SYNC_TAGFILTER_AND; + } + + size_t consumed; + if (fs.length > 0 && fs.ptr[0] == '(') { + consumed = parse_tagfilter_subfilters(fs, tagfilter); + } else { + tagfilter->subfilter_count = 0; + tagfilter->subfilters = NULL; + consumed = parse_tagfilter_taglist(fs, tagfilter); + } + + if (consumed != fs.length) { + free(tagfilter->subfilters); + free(tagfilter); + return NULL; + } + } + return tagfilter; }