summaryrefslogtreecommitdiff
path: root/src/fileops.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fileops.c')
-rw-r--r--src/fileops.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/fileops.c b/src/fileops.c
index 68f45c25a..37affe00f 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -364,5 +364,82 @@ int gitfo_mkdir_recurs(const char *path, int mode)
free(path_copy);
return error;
+}
+
+static int retrieve_previous_path_component_start(const char *path)
+{
+ int error = GIT_SUCCESS;
+ int offset, len, start = 0;
+
+ len = strlen(path);
+ offset = len - 1;
+ /* Skip leading slash */
+ if (path[start] == '/')
+ start++;
+
+ /* Skip trailing slash */
+ if (path[offset] == '/')
+ offset--;
+
+ if (offset < 0)
+ return GIT_ERROR;
+
+ while (offset > start && path[offset-1] != '/') {
+ offset--;
+ }
+
+ return offset;
}
+
+int git_prettify_dir_path(char *buffer_out, const char *path)
+{
+ int len = 0;
+ char *current;
+ const char *buffer_out_start, *buffer_end;
+
+ buffer_out_start = buffer_out;
+ current = (char *)path;
+ buffer_end = path + strlen(path);
+
+ while (current < buffer_end) {
+ /* Prevent multiple slashes from being added to the output */
+ if (*current == '/' && len > 0 && buffer_out_start[len - 1] == '/') {
+ current++;
+ continue;
+ }
+
+ /* Skip current directory */
+ if (*current == '.') {
+ current++;
+
+ /* Handle the double-dot upward directory navigation */
+ if (*current == '.') {
+ current++;
+
+ *buffer_out ='\0';
+ len = retrieve_previous_path_component_start(buffer_out_start);
+ if (len < GIT_SUCCESS)
+ return GIT_ERROR;
+
+ buffer_out = (char *)buffer_out_start + len;
+ }
+
+ if (*current == '/')
+ current++;
+
+ continue;
+ }
+
+ *buffer_out++ = *current++;
+ len++;
+ }
+
+ /* Add a trailing slash if required */
+ if (len > 0 && buffer_out_start[len-1] != '/')
+ *buffer_out++ = '/';
+
+ *buffer_out = '\0';
+
+ return GIT_SUCCESS;
+} \ No newline at end of file