dav/sync.c

changeset 390
26998dc980f9
parent 389
fe855ce911f9
child 391
10305c5b0a16
--- a/dav/sync.c	Wed May 30 12:10:58 2018 +0200
+++ b/dav/sync.c	Wed May 30 16:06:03 2018 +0200
@@ -255,31 +255,74 @@
     return 1;
 }
 
-static int matches_tags(UcxList *resource_tags, SyncTagFilter *tagfilter) {
-    if(!resource_tags) {
-        return 0;
+static int matches_tags_and(UcxList *dav_tags, UcxList *tags, int ignorecase) {
+    UCX_FOREACH(e, tags) {
+        if (!ucx_list_contains(dav_tags, e->data,
+                (cmp_func) compare_tagname, &ignorecase)) {
+            return 0;
+        }
     }
-    
-    UcxMap *res_tagmap = ucx_map_new(32);
-    UCX_FOREACH(elm, resource_tags) {
-        DavTag *t = elm->data;
-        // the value actually doesn't matter
-        ucx_map_cstr_put(res_tagmap, t->name, t);
+    return 1;
+}
+
+static int matches_tags_or(UcxList *dav_tags, UcxList *tags, int ignorecase) {
+    UCX_FOREACH(e, tags) {
+        if (ucx_list_contains(dav_tags, e->data,
+                (cmp_func) compare_tagname, &ignorecase)) {
+            return 1;
+        }
     }
-    
-    int ret = 1;
-    
-    // TODO: replace FOREACH with new tag expression evaluation
-    UCX_FOREACH(elm, tagfilter->tags) {
-        DavTag *matches_tag = elm->data;
-        if(!ucx_map_cstr_get(res_tagmap, matches_tag->name)) {
-            ret = 0;
-            break;
+    return 0;
+}
+
+static int matches_tags_one(UcxList *dav_tags, UcxList *tags, int ignorecase) {
+    int matches_exactly_one = 0;
+    UCX_FOREACH(e, tags) {
+        if (ucx_list_contains(dav_tags, e->data,
+                (cmp_func) compare_tagname, &ignorecase)) {
+            if (matches_exactly_one) {
+                return 0;
+            } else {
+                matches_exactly_one = 1;
+            }
         }
     }
-    
-    ucx_map_free(res_tagmap);
-    return ret;
+    return matches_exactly_one;
+}
+
+static int matches_tags_none(UcxList *dav_tags, UcxList *tags, int ignorecase) {
+    UCX_FOREACH(e, tags) {
+        if (ucx_list_contains(dav_tags, e->data,
+                (cmp_func) compare_tagname, &ignorecase)) {
+            return 0;
+        }
+    }
+    return 1;
+}
+
+static int matches_tags(UcxList *dav_tags, SyncTagFilter *tagfilter) {
+
+    if (tagfilter->subfilter_count > 0) {
+        int ret = 1;
+        for (size_t i = 0 ; i < tagfilter->subfilter_count ; i++) {
+            ret &= matches_tags(dav_tags, &(tagfilter->subfilters[i]));
+        }
+        return ret;
+    } else {
+        int ignorecase = 0; // TODO: maybe add support later
+        switch (tagfilter->mode) {
+        case DAV_SYNC_TAGFILTER_OR:
+            return matches_tags_or(dav_tags, tagfilter->tags, ignorecase);
+        case DAV_SYNC_TAGFILTER_AND:
+            return matches_tags_and(dav_tags, tagfilter->tags, ignorecase);
+        case DAV_SYNC_TAGFILTER_NONE:
+            return matches_tags_none(dav_tags, tagfilter->tags, ignorecase);
+        case DAV_SYNC_TAGFILTER_ONE:
+            return matches_tags_one(dav_tags, tagfilter->tags, ignorecase);
+        default:
+            abort();
+        }
+    }
 }
 
 static int res_matches_tags(DavResource *res, SyncTagFilter *tagfilter) {
@@ -291,8 +334,10 @@
     UcxList *res_tags = parse_dav_xml_taglist(tagsprop);
     
     int ret = matches_tags(res_tags, tagfilter);
-    // TODO: free list content
+    
+    ucx_list_free_content(res_tags, (ucx_destructor) free_dav_tag);
     ucx_list_free(res_tags);
+    
     return ret;
 }
 
@@ -474,8 +519,10 @@
                 continue;
             }
             
-            
+            // TODO: remove this fake and let the cmd parser store the filter
             SyncTagFilter tagfilter;
+            tagfilter.mode = DAV_SYNC_TAGFILTER_AND;
+            tagfilter.subfilter_count = 0;
             tagfilter.tags = NULL;
             char *tags_str = cmd_getoption(a, "tags");
             if(tags_str) {

mercurial