add util_path_normalize

Tue, 16 Apr 2019 11:46:53 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Tue, 16 Apr 2019 11:46:53 +0200
changeset 575
f746f601c35c
parent 574
c36eddf167a8
child 576
62cc92445234

add util_path_normalize

libidav/utils.c file | annotate | diff | comparison | revisions
libidav/utils.h file | annotate | diff | comparison | revisions
--- a/libidav/utils.c	Sun Apr 14 20:08:18 2019 +0200
+++ b/libidav/utils.c	Tue Apr 16 11:46:53 2019 +0200
@@ -398,6 +398,64 @@
     return 0;
 }
 
+char* util_path_normalize(const char *path) {
+    size_t len = strlen(path);
+    UcxBuffer *buf = ucx_buffer_new(NULL, len+1, UCX_BUFFER_AUTOEXTEND);
+    
+    if(path[0] == '/') {
+        ucx_buffer_putc(buf, '/');
+    }
+    
+    int add_separator = 0;
+    int seg_start = 0;
+    for(int i=0;i<=len;i++) {
+        char c = path[i];
+        if(c == '/' || c == '\0') {
+            const char *seg_ptr = path+seg_start;
+            int seg_len = i - seg_start;
+            if(seg_ptr[0] == '/') {
+                seg_ptr++;
+                seg_len--;
+            }
+            
+            if(seg_len > 0) {
+                scstr_t seg = scstrn(seg_ptr, seg_len);
+                if(!sstrcmp(seg, SC(".."))) {
+                    for(int j=buf->pos;j>=0;j--) {
+                        char t = buf->space[j];
+                        if(t == '/' || j == 0) {
+                            buf->pos = j;
+                            buf->size = j;
+                            buf->space[j] = 0;
+                            add_separator = t == '/' ? 1 : 0;
+                            break;
+                        }
+                    }
+                } else if(!sstrcmp(seg, SC("."))) {
+                    // ignore
+                } else {
+                    if(add_separator) {
+                        ucx_buffer_putc(buf, '/');
+                    }
+                    ucx_buffer_write(seg_ptr, 1, seg_len, buf);
+                    add_separator = 1;
+                }
+            }
+            
+            seg_start = i;
+        }
+    }
+    
+    ucx_buffer_putc(buf, 0);
+    
+    
+    char *space = buf->space;
+    buf->flags = 0; // disable autofree
+    ucx_buffer_free(buf);
+    return space;
+}
+
+
 void util_capture_header(CURL *handle, UcxMap* map) {
     if(map) {
         curl_easy_setopt(handle, CURLOPT_HEADERFUNCTION, util_header_callback);
--- a/libidav/utils.h	Sun Apr 14 20:08:18 2019 +0200
+++ b/libidav/utils.h	Tue Apr 16 11:46:53 2019 +0200
@@ -77,6 +77,8 @@
  */
 int util_path_isrelated(const char *path1, const char *path2);
 
+char* util_path_normalize(const char *path);
+
 void util_capture_header(CURL *handle, UcxMap* map);
 
 char* util_path_to_url(DavSession *sn, char *path);

mercurial