# HG changeset patch # User Mike Becker # Date 1527696283 -7200 # Node ID 4826f5fdd8655c68a6e108cbc2e349f01ac5f048 # Parent 438c8fe7d62f232c3ade733a2efd2a4933c709b9 implements parser for basic tag filters without subfilters 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; } diff -r 438c8fe7d62f -r 4826f5fdd865 dav/sync.h --- a/dav/sync.h Wed May 30 16:51:52 2018 +0200 +++ b/dav/sync.h Wed May 30 18:04:43 2018 +0200 @@ -112,7 +112,7 @@ int cmd_empty_trash(CmdArgs *args); /** - * filter ::= tag_list | (operator , ("(" , filter , ")")*) + * filter ::= operator? , (tag_list | ("(" , filter , ")")+) * tag_list ::= tag , ("," tag)* * operator ::= "&" | "|" | "1" | "0" */