implements parser for basic tag filters without subfilters

Wed, 30 May 2018 18:04:43 +0200

author
Mike Becker <universe@uap-core.de>
date
Wed, 30 May 2018 18:04:43 +0200
changeset 394
4826f5fdd865
parent 393
438c8fe7d62f
child 395
b491d207ee16

implements parser for basic tag filters without subfilters

dav/sync.c file | annotate | diff | comparison | revisions
dav/sync.h file | annotate | diff | comparison | revisions
--- 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 <pthread.h>
+#include <ctype.h>
 
 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;
 }
 
--- 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"
  */

mercurial