Skip to content

Commit

Permalink
Move sanitary_path_copy() to path.c and rename it to normalize_path_c…
Browse files Browse the repository at this point in the history
…opy()

This function and normalize_absolute_path() do almost the same thing. The
former already works on Windows, but the latter crashes.

In subsequent changes we will remove normalize_absolute_path(). Here we
make the replacement function reusable. On the way we rename it to reflect
that it does some path normalization. Apart from that this is only moving
around code.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Johannes Sixt authored and Junio C Hamano committed Feb 7, 2009
1 parent 2cd85c4 commit f3cad0a
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 87 deletions.
1 change: 1 addition & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ const char *make_absolute_path(const char *path);
const char *make_nonrelative_path(const char *path);
const char *make_relative_path(const char *abs, const char *base);
int normalize_absolute_path(char *buf, const char *path);
int normalize_path_copy(char *dst, const char *src);
int longest_ancestor_length(const char *path, const char *prefix_list);

/* Read and unpack a sha1 file into memory, write memory to a sha1 file */
Expand Down
86 changes: 86 additions & 0 deletions path.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,92 @@ int normalize_absolute_path(char *buf, const char *path)
return dst - buf;
}

int normalize_path_copy(char *dst, const char *src)
{
char *dst0;

if (has_dos_drive_prefix(src)) {
*dst++ = *src++;
*dst++ = *src++;
}
dst0 = dst;

if (is_dir_sep(*src)) {
*dst++ = '/';
while (is_dir_sep(*src))
src++;
}

for (;;) {
char c = *src;

/*
* A path component that begins with . could be
* special:
* (1) "." and ends -- ignore and terminate.
* (2) "./" -- ignore them, eat slash and continue.
* (3) ".." and ends -- strip one and terminate.
* (4) "../" -- strip one, eat slash and continue.
*/
if (c == '.') {
if (!src[1]) {
/* (1) */
src++;
} else if (is_dir_sep(src[1])) {
/* (2) */
src += 2;
while (is_dir_sep(*src))
src++;
continue;
} else if (src[1] == '.') {
if (!src[2]) {
/* (3) */
src += 2;
goto up_one;
} else if (is_dir_sep(src[2])) {
/* (4) */
src += 3;
while (is_dir_sep(*src))
src++;
goto up_one;
}
}
}

/* copy up to the next '/', and eat all '/' */
while ((c = *src++) != '\0' && !is_dir_sep(c))
*dst++ = c;
if (is_dir_sep(c)) {
*dst++ = '/';
while (is_dir_sep(c))
c = *src++;
src--;
} else if (!c)
break;
continue;

up_one:
/*
* dst0..dst is prefix portion, and dst[-1] is '/';
* go up one level.
*/
dst -= 2; /* go past trailing '/' if any */
if (dst < dst0)
return -1;
while (1) {
if (dst <= dst0)
break;
c = *dst--;
if (c == '/') { /* MinGW: cannot be '\\' anymore */
dst += 2;
break;
}
}
}
*dst = '\0';
return 0;
}

/*
* path = Canonical absolute path
* prefix_list = Colon-separated list of absolute paths
Expand Down
88 changes: 1 addition & 87 deletions setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,92 +4,6 @@
static int inside_git_dir = -1;
static int inside_work_tree = -1;

static int sanitary_path_copy(char *dst, const char *src)
{
char *dst0;

if (has_dos_drive_prefix(src)) {
*dst++ = *src++;
*dst++ = *src++;
}
dst0 = dst;

if (is_dir_sep(*src)) {
*dst++ = '/';
while (is_dir_sep(*src))
src++;
}

for (;;) {
char c = *src;

/*
* A path component that begins with . could be
* special:
* (1) "." and ends -- ignore and terminate.
* (2) "./" -- ignore them, eat slash and continue.
* (3) ".." and ends -- strip one and terminate.
* (4) "../" -- strip one, eat slash and continue.
*/
if (c == '.') {
if (!src[1]) {
/* (1) */
src++;
} else if (is_dir_sep(src[1])) {
/* (2) */
src += 2;
while (is_dir_sep(*src))
src++;
continue;
} else if (src[1] == '.') {
if (!src[2]) {
/* (3) */
src += 2;
goto up_one;
} else if (is_dir_sep(src[2])) {
/* (4) */
src += 3;
while (is_dir_sep(*src))
src++;
goto up_one;
}
}
}

/* copy up to the next '/', and eat all '/' */
while ((c = *src++) != '\0' && !is_dir_sep(c))
*dst++ = c;
if (is_dir_sep(c)) {
*dst++ = '/';
while (is_dir_sep(c))
c = *src++;
src--;
} else if (!c)
break;
continue;

up_one:
/*
* dst0..dst is prefix portion, and dst[-1] is '/';
* go up one level.
*/
dst -= 2; /* go past trailing '/' if any */
if (dst < dst0)
return -1;
while (1) {
if (dst <= dst0)
break;
c = *dst--;
if (c == '/') { /* MinGW: cannot be '\\' anymore */
dst += 2;
break;
}
}
}
*dst = '\0';
return 0;
}

const char *prefix_path(const char *prefix, int len, const char *path)
{
const char *orig = path;
Expand All @@ -101,7 +15,7 @@ const char *prefix_path(const char *prefix, int len, const char *path)
memcpy(sanitized, prefix, len);
strcpy(sanitized + len, path);
}
if (sanitary_path_copy(sanitized, sanitized))
if (normalize_path_copy(sanitized, sanitized))
goto error_out;
if (is_absolute_path(orig)) {
const char *work_tree = get_git_work_tree();
Expand Down

0 comments on commit f3cad0a

Please sign in to comment.