Thread (47 messages) flat view 47 messages, 5 authors, 2016-06-15

Re: [PATCH v3 3/4] setup: Add 'abspath_part_inside_repo' function

From: Duy Nguyen <hidden>
Date: 2016-06-15 22:59:47

On Sat, Feb 1, 2014 at 3:22 AM, Martin Erik Werner
[off-list ref] wrote:
quoted hunk ↗ jump to hunk
diff --git a/setup.c b/setup.c
index 5432a31..e606846 100644
--- a/setup.c
+++ b/setup.c
@@ -77,6 +77,69 @@ int path_inside_repo(const char *prefix, const char *path)
        return 0;
 }

+/*
+ * It is ok if dst == src, but they should not overlap otherwise.
+ * No checking if the path is in fact an absolute path is done, and it must
+ * already be normalized.
+ *
+ * Find the part of an absolute path that lies inside the work tree by
+ * dereferencing symlinks outside the work tree, for example:
+ * /dir1/repo/dir2/file   (work tree is /dir1/repo)      -> dir2/file
+ * /dir/file              (work tree is /)               -> dir/file
+ * /dir/symlink1/symlink2 (symlink1 points to work tree) -> symlink2
+ * /dir/repo              (exactly equal to work tree)   -> (empty string)
+ */
+int abspath_part_inside_repo(char *dst, const char* src)
+{
+       size_t len;
+       char *dst0;
+       char temp;
+
+       const char* work_tree = get_git_work_tree();
+       if (!work_tree)
+               return -1;
+       len = strlen(src);
+       dst0 = dst;
+
+       // check root level
Um.. no C++ style comments. And there should be a test that work_tree
is the prefix of src (common case). If so we can return early and do
not need to do real_path() on every path component.
+       if (has_dos_drive_prefix(src)) {
+               *dst++ = *src++;
+               *dst++ = *src++;
+               *dst++ = *src++;
+       } else {
+               *dst++ = *src++;
+       }
+       temp = *dst;
+       *dst = '\0';
+       if (strcmp(real_path(dst0), work_tree) == 0) {
+               *dst = temp;
+               memmove(dst0, src, len - (dst - dst0) + 1);
+               return 0;
+       }
+       *dst = temp;
+
+       // check each level
+       while (*dst != '\0') {
+               *dst++ = *src++;
+               if (*dst == '/') {
+                       *dst = '\0';
+                       if (strcmp(real_path(dst0), work_tree) == 0) {
+                               memmove(dst0, src + 1, len - (dst - dst0));
+                               return 0;
+                       }
+                       *dst = '/';
+               }
+       }
+
+       // check whole path
+       if (strcmp(real_path(dst0), work_tree) == 0) {
+               *dst0 = '\0';
+               return 0;
+       }
+
+       return -1;
+}
+
 int check_filename(const char *prefix, const char *arg)
 {
        const char *name;
--
1.8.5.2


-- 
Duy
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help