change split config

Sun, 29 Sep 2019 12:57:13 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 29 Sep 2019 12:57:13 +0200
changeset 648
fefe4b6f1048
parent 647
8bf1d9688698
child 649
0f4c59ac8c74

change split config

dav/scfg.c file | annotate | diff | comparison | revisions
dav/scfg.h file | annotate | diff | comparison | revisions
dav/sync.c file | annotate | diff | comparison | revisions
--- a/dav/scfg.c	Sat Sep 28 09:24:30 2019 +0200
+++ b/dav/scfg.c	Sun Sep 29 12:57:13 2019 +0200
@@ -164,6 +164,36 @@
     return 0;
 }
 
+Filter* parse_filter(xmlNode *node) {
+    UcxList *include = NULL;
+    UcxList *exclude = NULL;
+    UcxList *tags = NULL;
+    
+    if(scfg_load_filter(node, &include, &exclude, &tags)) {
+        return NULL;
+    }
+    
+    Filter *filter = malloc(sizeof(Filter));
+    filter->include = include;
+    filter->exclude = exclude;
+    filter->tags = tags;
+}
+
+void init_default_filter(Filter *filter) {
+    if(!filter->include) {
+        regex_t *matchall = malloc(sizeof(regex_t));
+        regcomp(matchall, ".*", REG_NOSUB);
+        filter->include = ucx_list_append(NULL, matchall);
+    }
+    /*
+    if(!filter->exclude) {
+        regex_t *matchnothing = malloc(sizeof(regex_t));
+        regcomp(matchnothing, "///", REG_NOSUB);
+        filter->exclude = ucx_list_append(NULL, matchnothing);
+    }
+    */
+}
+
 static TagFormat str2tagformat(const char *str) {
     if(!strcmp(str, "text")) {
         return TAG_FORMAT_TEXT;
@@ -250,19 +280,24 @@
 }
 
 static SplitConfig* parse_split(xmlNode *node) {
-    char *pattern = NULL;
+    Filter *filter = NULL;
     char *minsize = NULL;
     char *blocksize = NULL;
     
     xmlNode *c = node->children;
     while(c) {
-        char *value = util_xml_get_text(c);
-        if(xstreq(c->name, "pattern")) {
-            pattern = value;
+        if(xstreq(c->name, "filter")) {
+            filter = parse_filter(node);
+            if(filter->tags) {
+                fprintf(stderr, "splitconfig: tag filter not supported\n");
+                free_filter(*filter);
+                free(filter);
+                return NULL;
+            }
         } else if(xstreq(c->name, "minsize")) {
-            minsize = value;
+            minsize = util_xml_get_text(c);
         } else if(xstreq(c->name, "blocksize")) {
-            blocksize = value;
+            blocksize = util_xml_get_text(c);
         }
         c = c->next;
     }
@@ -283,8 +318,8 @@
         return NULL;
     }
     
-    if(!pattern && !minsize) {
-        fprintf(stderr, "splitconfig: pattern or minsize must be specified\n");
+    if(!filter && !minsize) {
+        fprintf(stderr, "splitconfig: filter or minsize must be specified\n");
         return NULL;
     }
     
@@ -299,13 +334,8 @@
     }
     
     SplitConfig *sc = calloc(1, sizeof(SplitConfig));
-    if(pattern) {
-        regex_t *regex = malloc(sizeof(regex_t));
-        if (regcomp(regex, pattern, REG_EXTENDED|REG_NOSUB)) {
-            fprintf(stderr, "Invalid regular expression (%s)\n", pattern);
-        } else {
-            sc->pattern = regex;
-        }
+    if(filter) {
+        init_default_filter(filter);
     }
     sc->minsize = minsz;
     sc->blocksize = (size_t)sz;
@@ -609,21 +639,10 @@
         dir->db_settings |= DB_STORE_OWNER;
     }
     
-    if (include) {
-        dir->include = include;
-    } else {
-        regex_t *matchall = malloc(sizeof(regex_t));
-        regcomp(matchall, ".*", REG_NOSUB);
-        dir->include = ucx_list_append(NULL, matchall);
-    }
-    if (exclude) {
-        dir->exclude = exclude;
-    } else {
-        regex_t *matchnothing = malloc(sizeof(regex_t));
-        regcomp(matchnothing, "///", REG_NOSUB);
-        dir->exclude = ucx_list_append(NULL, matchnothing);
-    }
-    dir->tagfilter = tagfilter;
+    dir->filter.include = include;
+    dir->filter.exclude = exclude;
+    dir->filter.tags = tagfilter;
+    init_default_filter(&dir->filter);
     
     if (trash && sstrtrim(sstr(trash)).length > 0) {
         if (trash[0] == '/' || trash[0] == '$') {
@@ -856,6 +875,18 @@
     return dbname;
 }
 
+void free_filter(Filter filter) {
+    UCX_FOREACH(elm, filter.include) {
+        regfree(elm->data);
+        free(elm->data);
+    }
+    ucx_list_free(filter.include);
+    UCX_FOREACH(elm, filter.exclude) {
+        regfree(elm->data);
+        free(elm->data);
+    }
+    ucx_list_free(filter.exclude);
+}
 
 void free_sync_config() {
     if(directories) {
@@ -874,16 +905,7 @@
                 free(dir->trash);
             }
 
-            UCX_FOREACH(elm, dir->include) {
-                regfree(elm->data);
-                free(elm->data);
-            }
-            ucx_list_free(dir->include);
-            UCX_FOREACH(elm, dir->exclude) {
-                regfree(elm->data);
-                free(elm->data);
-            }
-            ucx_list_free(dir->exclude);
+            free_filter(dir->filter);
 
             free(dir);
         }
--- a/dav/scfg.h	Sat Sep 28 09:24:30 2019 +0200
+++ b/dav/scfg.h	Sun Sep 29 12:57:13 2019 +0200
@@ -64,6 +64,7 @@
 typedef struct TagConfig   TagConfig;
 typedef struct Versioning  Versioning;
 typedef struct SplitConfig SplitConfig;
+typedef struct Filter      Filter;
 
 enum PushStrategy {
     PUSH_STRATEGY_METADATA = 0,
@@ -71,6 +72,12 @@
 };
 typedef enum PushStrategy PushStrategy;
 
+struct Filter {
+    UcxList *include;
+    UcxList *exclude;
+    UcxList *tags;
+};
+
 typedef struct SyncDirectory {
     char *name;
     char *path;
@@ -80,9 +87,7 @@
     char *database;
     TagConfig *tagconfig;
     Versioning *versioning;
-    UcxList *include;
-    UcxList *exclude;
-    UcxList *tagfilter;
+    Filter filter;
     UcxList *splitconfig;
     uint32_t metadata;
     int max_retry;
@@ -100,22 +105,21 @@
 
 struct SplitConfig {
     /*
-     * path regex pattern or NULL
+     * resource filter or NULL
      */
-    regex_t *pattern;
-    
+    Filter *filter;
     /*
      * minimum file size for activating file splitting
      * a value of -1 means no size restriction
      */
     int64_t minsize;
-    
     /*
      * split files into blocks with this size
      */
     size_t blocksize;
 };
 
+
 enum TagFormat {
     TAG_FORMAT_TEXT = 0,
     TAG_FORMAT_CSV,
@@ -173,6 +177,8 @@
 
 char* generate_db_name(char *basename);
 
+void free_filter(Filter filter);
+
 void free_sync_config();
 
 
--- a/dav/sync.c	Sat Sep 28 09:24:30 2019 +0200
+++ b/dav/sync.c	Sun Sep 29 12:57:13 2019 +0200
@@ -299,7 +299,24 @@
     return local_path;
 }
 
-static int res_matches_filter(SyncDirectory *dir, char *res_path) {
+static int res_matches_filter(Filter *filter, char *res_path) {
+    // include/exclude filter
+    UCX_FOREACH(inc, filter->include) {
+        regex_t* pattern = (regex_t*) inc->data;
+        if (regexec(pattern, res_path, 0, NULL, 0) == 0) {
+            UCX_FOREACH(exc, filter->exclude) {
+                regex_t* pattern = (regex_t*) exc->data;
+                if (regexec(pattern, res_path, 0, NULL, 0) == 0) {
+                    return 1;
+                }
+            }
+            return 0;
+        }
+    }
+    return 1;
+}
+
+static int res_matches_dir_filter(SyncDirectory *dir, char *res_path) {
     // trash filter
     if (dir->trash) {
         sstr_t rpath = sstr(util_concat_path(dir->path, res_path));
@@ -317,20 +334,7 @@
         }
     }
     
-    // include/exclude filter
-    UCX_FOREACH(inc, dir->include) {
-        regex_t* pattern = (regex_t*) inc->data;
-        if (regexec(pattern, res_path, 0, NULL, 0) == 0) {
-            UCX_FOREACH(exc, dir->exclude) {
-                regex_t* pattern = (regex_t*) exc->data;
-                if (regexec(pattern, res_path, 0, NULL, 0) == 0) {
-                    return 1;
-                }
-            }
-            return 0;
-        }
-    }
-    return 1;
+    return res_matches_filter(&dir->filter, res_path);
 }
 
 static int res_matches_tags(DavResource *res, SyncTagFilter *tagfilter) {
@@ -629,10 +633,10 @@
          
         while(res) {
             DavBool res_filtered = FALSE;
-            if (res_matches_filter(dir, res->path)) {
+            if (res_matches_dir_filter(dir, res->path)) {
                 res_filtered = TRUE;
             } else {
-                UCX_FOREACH(elm, dir->tagfilter) {
+                UCX_FOREACH(elm, dir->filter.tags) {
                     SyncTagFilter *tf = elm->data;
                     if(!res_matches_tags(res, tf)) {
                         res_filtered = TRUE;
@@ -712,7 +716,7 @@
     UcxMapIterator i = ucx_map_iterator(dbres);
     LocalResource *local;
     UCX_MAP_FOREACH(key, local, i) {
-        if (res_matches_filter(dir, local->path)) {
+        if (res_matches_dir_filter(dir, local->path)) {
             continue;
         }
         if(!local->keep) {
@@ -1854,11 +1858,11 @@
         // ignore all files, that are excluded by a static filter (sync.xml) 
         
         // static include/exclude filter
-        if(res_matches_filter(dir, local_res->path+1)) {
+        if(res_matches_dir_filter(dir, local_res->path+1)) {
             continue;
         }
         // static tag filter
-        UCX_FOREACH(elm, dir->tagfilter) {
+        UCX_FOREACH(elm, dir->filter.tags) {
             SyncTagFilter *tf = elm->data;
             if(!localres_matches_tags(dir, local_res, tf)) {
                 continue;
@@ -1970,11 +1974,11 @@
     UcxList *removed_res = NULL;
     UCX_MAP_FOREACH(key, local, i) { 
         // all filtered files should be removed from the database
-        if(res_matches_filter(dir, local->path+1)) {
+        if(res_matches_dir_filter(dir, local->path+1)) {
             ucx_map_cstr_remove(db->resources, local->path);
             continue;
         }
-        UCX_FOREACH(elm, dir->tagfilter) {
+        UCX_FOREACH(elm, dir->filter.tags) {
             SyncTagFilter *tf = elm->data;
             if(!localres_matches_tags(dir, local, tf)) {
                 ucx_map_cstr_remove(db->resources, local->path);
@@ -2989,8 +2993,8 @@
     } else {
         UCX_FOREACH(elm, dir->splitconfig) {
             SplitConfig *sc = elm->data;
-            if(sc->pattern) {
-                if(regexec(sc->pattern, local->path, 0, NULL, 0) != 0) {
+            if(sc->filter) {
+                if(res_matches_filter(sc->filter, local->path)) {
                     continue;
                 }
             }

mercurial