completion: restore removed line continuating backslash
[gitweb.git] / abspath.c
index 79ee3108678c97e1dade83e4ff4943edf3d3da9e..2f0c26e0e2cbee88aa671f3960d21720e4307aba 100644 (file)
--- a/abspath.c
+++ b/abspath.c
@@ -48,8 +48,23 @@ static void get_next_component(struct strbuf *next, struct strbuf *remaining)
        strbuf_remove(remaining, 0, end - remaining->buf);
 }
 
+/* copies root part from remaining to resolved, canonicalizing it on the way */
+static void get_root_part(struct strbuf *resolved, struct strbuf *remaining)
+{
+       int offset = offset_1st_component(remaining->buf);
+
+       strbuf_reset(resolved);
+       strbuf_add(resolved, remaining->buf, offset);
+#ifdef GIT_WINDOWS_NATIVE
+       convert_slashes(resolved->buf);
+#endif
+       strbuf_remove(remaining, 0, offset);
+}
+
 /* We allow "recursive" symbolic links. Only within reason, though. */
-#define MAXSYMLINKS 5
+#ifndef MAXSYMLINKS
+#define MAXSYMLINKS 32
+#endif
 
 /*
  * Return the real path (i.e., absolute path, with symlinks resolved
@@ -80,14 +95,10 @@ char *strbuf_realpath(struct strbuf *resolved, const char *path,
                        goto error_out;
        }
 
-       strbuf_reset(resolved);
+       strbuf_addstr(&remaining, path);
+       get_root_part(resolved, &remaining);
 
-       if (is_absolute_path(path)) {
-               /* absolute path; start with only root as being resolved */
-               int offset = offset_1st_component(path);
-               strbuf_add(resolved, path, offset);
-               strbuf_addstr(&remaining, path + offset);
-       } else {
+       if (!resolved->len) {
                /* relative path; can use CWD as the initial resolved path */
                if (strbuf_getcwd(resolved)) {
                        if (die_on_error)
@@ -95,7 +106,6 @@ char *strbuf_realpath(struct strbuf *resolved, const char *path,
                        else
                                goto error_out;
                }
-               strbuf_addstr(&remaining, path);
        }
 
        /* Iterate over the remaining path components */
@@ -131,6 +141,8 @@ char *strbuf_realpath(struct strbuf *resolved, const char *path,
                        strbuf_reset(&symlink);
 
                        if (num_symlinks++ > MAXSYMLINKS) {
+                               errno = ELOOP;
+
                                if (die_on_error)
                                        die("More than %d nested symlinks "
                                            "on path '%s'", MAXSYMLINKS, path);
@@ -150,10 +162,7 @@ char *strbuf_realpath(struct strbuf *resolved, const char *path,
 
                        if (is_absolute_path(symlink.buf)) {
                                /* absolute symlink; set resolved to root */
-                               int offset = offset_1st_component(symlink.buf);
-                               strbuf_reset(resolved);
-                               strbuf_add(resolved, symlink.buf, offset);
-                               strbuf_remove(&symlink, 0, offset);
+                               get_root_part(resolved, &symlink);
                        } else {
                                /*
                                 * relative symlink
@@ -230,6 +239,13 @@ const char *absolute_path(const char *path)
        return sb.buf;
 }
 
+char *absolute_pathdup(const char *path)
+{
+       struct strbuf sb = STRBUF_INIT;
+       strbuf_add_absolute_path(&sb, path);
+       return strbuf_detach(&sb, NULL);
+}
+
 /*
  * Unlike prefix_path, this should be used if the named file does
  * not have to interact with index entry; i.e. name of a random file