about summary refs log tree commit diff stats
path: root/src/tools/pathcoll.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/pathcoll.c')
-rwxr-xr-xsrc/tools/pathcoll.c182
1 files changed, 182 insertions, 0 deletions
diff --git a/src/tools/pathcoll.c b/src/tools/pathcoll.c
new file mode 100755
index 00000000..d7e423bb
--- /dev/null
+++ b/src/tools/pathcoll.c
@@ -0,0 +1,182 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <stdint.h>
+
+#ifndef MAX_PATH
+#define MAX_PATH 4096
+#endif
+
+#include "debug.h"
+#include "pathcoll.h"
+
+void FreeCollection(path_collection_t* collection)
+{
+    if(!collection)
+        return;
+    if(collection->cap) {
+        for(int i=0; i<collection->size; ++i)
+            free(collection->paths[i]);
+        free(collection->paths);
+    }
+    collection->paths = NULL;
+    collection->size = 0;
+    collection->cap = 0;
+    return;
+}
+
+void ParseList(const char* List, path_collection_t* collection, int folder)
+{
+    if(collection->cap)
+        FreeCollection(collection);
+    // count the stings (basically count(':') + 1) to define cap
+    int cnt = 1;
+    {
+        const char* p = List;
+        while(p) {
+            p = strchr(p, ':');
+            ++cnt;
+            if(p) ++p;
+        }
+    }
+    // alloc empty strings
+    collection->cap = cnt;
+    collection->paths = (char**)calloc(cnt, sizeof(char*));
+    // and now split the paths...
+    char tmp[MAX_PATH];
+    const char *p = List;
+    int idx = 0;
+    while(p) {
+        const char *p2 = strchr(p, ':');
+        if(!p2) {
+            strncpy(tmp, p, MAX_PATH - 1);
+            p=NULL;
+        } else {
+            int l = (uintptr_t)p2 - (uintptr_t)p;
+            strncpy(tmp, p, l);
+            tmp[l]='\0';
+            p=p2+1;
+        }
+        // check if there is terminal '/', add it if not
+        int l = strlen(tmp);
+        // skip empty strings
+        if(l) {
+            if(folder && tmp[l-1]!='/')
+                strcat(tmp, "/");
+            collection->paths[idx]  =strdup(tmp);
+            collection->size=++idx;
+        }
+    }
+}
+
+void CopyCollection(path_collection_t* to, path_collection_t* from)
+{
+    to->cap = from->cap;
+    to->paths = (char**)calloc(to->cap, sizeof(char*));
+    to->size = from->size;
+    for (int i=0; i<to->size; ++i)
+        to->paths[i] = strdup(from->paths[i]);
+}
+
+void AddPath(const char* path, path_collection_t* collection, int folder)
+{
+    char tmp[MAX_PATH];
+    strcpy(tmp, path);
+    int l = strlen(tmp);
+    // skip empty strings
+    if(l) {
+        if(folder && tmp[l-1]!='/')
+            strcat(tmp, "/");
+        if(collection->size==collection->cap) {
+            collection->cap += 4;
+            collection->paths = (char**)realloc(collection->paths, collection->cap*sizeof(char*));
+        }
+        collection->paths[collection->size++]=strdup(tmp);
+    }
+}
+void PrependPath(const char* path, path_collection_t* collection, int folder)
+{
+    char tmp[MAX_PATH];
+    strcpy(tmp, path);
+    int l = strlen(tmp);
+    // skip empty strings
+    if(l) {
+        if(folder && tmp[l-1]!='/')
+            strcat(tmp, "/");
+        if(collection->size==collection->cap) {
+            collection->cap += 4;
+            collection->paths = (char**)realloc(collection->paths, collection->cap*sizeof(char*));
+        }
+        memmove(collection->paths+1, collection->paths, sizeof(char*)*collection->size);
+        collection->paths[0]=strdup(tmp);
+        ++collection->size;
+    }
+}
+
+void AppendList(path_collection_t* collection, const char* List, int folder)
+{
+    if(!List)
+        return;
+        // and now split the paths...
+    char tmp[MAX_PATH];
+    const char *p = List;
+    while(p) {
+        const char *p2 = strchr(p, ':');
+        if(!p2) {
+            strncpy(tmp, p, MAX_PATH - 1);
+            p=NULL;
+        } else {
+            int l = (uintptr_t)p2 - (uintptr_t)p;
+            strncpy(tmp, p, l);
+            tmp[l]='\0';
+            p=p2+1;
+        }
+        // check if there is terminal '/', add it if not
+        int l = strlen(tmp);
+        // skip empty strings
+        if(l) {
+            if(folder && tmp[l-1]!='/')
+                strcat(tmp, "/");
+            AddPath(tmp, collection, folder);
+        }
+    }
+
+}
+void PrependList(path_collection_t* collection, const char* List, int folder)
+{
+    if(!List)
+        return;
+        // and now split the paths...
+    char tmp[MAX_PATH];
+    char *p = strdup(List);
+    while(p) {
+        char *p2 = strrchr(p, ':');
+        if(!p2) {
+            strncpy(tmp, p, MAX_PATH - 1);
+            free(p);
+            p=NULL;
+        } else {
+            strncpy(tmp, p2+1, MAX_PATH - 1);
+            tmp[MAX_PATH - 1]='\0';
+            *p2 = '\0';
+        }
+        // check if there is terminal '/', add it if not
+        int l = strlen(tmp);
+        // skip empty strings
+        if(l) {
+            if(folder && tmp[l-1]!='/')
+                strcat(tmp, "/");
+            PrependPath(tmp, collection, folder);
+        }
+    }
+
+}
+
+int FindInCollection(const char* path, path_collection_t* collection)
+{
+    for (int i=0; i<collection->size; ++i)
+        if(strcmp(path, collection->paths[i])==0)
+            return 1;
+    return 0;
+}