Re: [PATCH v3 3/4] setup: Add 'abspath_part_inside_repo' function
- From
Duy Nguyen <pclouds@gmail.com>
- Date
- Feb 1, 2014, 02:31 UTC
- Message-ID
- <CACsJy8CaA6-4qc3BjNi0BCKPLBzh7Ttu6n7wpcj1ZknmEZW-MA@mail.gmail.com>
- In-Reply-To
- <20140131202248.GD9731@mule>
On Sat, Feb 1, 2014 at 3:22 AM, Martin Erik Werner <martinerikwerner@gmail.com> wrote:
Show 33 quoted lines
> 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 levelUm.. 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.
Show 43 quoted lines
> + 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