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

2014-01-31 Thread Duy Nguyen
On Sat, Feb 1, 2014 at 3:22 AM, Martin Erik Werner
 wrote:
> 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
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

2014-01-31 Thread Martin Erik Werner
On Fri, Jan 31, 2014 at 11:37:29PM +0100, Torsten Bögershausen wrote:
> On 2014-01-31 21.22, Martin Erik Werner wrote:
> > In order to extract the part of an absolute path which lies inside the
> > repo, it is not possible to directly use real_path, since that would
> > dereference symlinks both outside and inside the work tree.
> >
> > Add an 'abspath_part_inside_repo' function which incrementally checks
> > each path level by temporarily NUL-terminating at each '/' and comparing
> > against the work tree path. When a match is found, it copies the
> > remainder (which will be the in-repo part) to a destination
> > buffer.
> >
> > The path being the filesystem root or exactly equal to the work tree are
> > special cases handled separately, since then there is no directory
> > separator between the work tree and in-repo part.
> >
> > Signed-off-by: Martin Erik Werner 
> > ---
> >  cache.h |  1 +
> >  setup.c | 63 
> > +++
> >  2 files changed, 64 insertions(+)
> >
> > diff --git a/cache.h b/cache.h
> > index ce377e1..242f27d 100644
> > --- a/cache.h
> > +++ b/cache.h
> > @@ -426,6 +426,7 @@ extern void verify_filename(const char *prefix,
> > int diagnose_misspelt_rev);
> >  extern void verify_non_filename(const char *prefix, const char *name);
> >  extern int path_inside_repo(const char *prefix, const char *path);
> > +extern int abspath_part_inside_repo(char *dst, const char *path);
> abspath_part_inside_repo() is only used in setup.c, isn't it?
> In this case we don't need it in cache.h, it can be declared inside setup.c as
> 
> static int abspath_part_inside_repo(char *dst, const char *path);
> (or "static inline" )
> 
> -
> (And not in this patch: see the final setup.c:)
> 
> if (g) {
> free(npath);
> return NULL;
> }
> 
> If this is the only caller of abspath_part_inside_repo(),
> then  do we need npath 2 times as a parameter ?
> Or can we re-write it to look like this:
> 
> static inline int abspath_part_inside_repo(char *path)
> [
> ]

I guess I've over-generalised it a bit too much, that should rather be
done if-and-when, I presume?

It is indeed only used in setup.c and only by the prefix_path_gently
function so static inline then?

Hmm, for single-parameter it should suffice to simply move the parameter
down into the function, like so?:
  const char* src;
  src = dst;
and carry on as before (obviously also renaming the variables sensibly),
or did you have something else in mind?

(I added two parameters since I was glancing at 'normalize_path_copy_len'
for inspiration, and was thinking about (purely theoretical) re-use in
other cases rather than minimizing it for the time being.)

What do you mean with the "(And not in this patch"... bit; what "final
setup.c"?

--
Martin Erik Werner 
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

2014-01-31 Thread Torsten Bögershausen
On 2014-01-31 21.22, Martin Erik Werner wrote:
> In order to extract the part of an absolute path which lies inside the
> repo, it is not possible to directly use real_path, since that would
> dereference symlinks both outside and inside the work tree.
>
> Add an 'abspath_part_inside_repo' function which incrementally checks
> each path level by temporarily NUL-terminating at each '/' and comparing
> against the work tree path. When a match is found, it copies the
> remainder (which will be the in-repo part) to a destination
> buffer.
>
> The path being the filesystem root or exactly equal to the work tree are
> special cases handled separately, since then there is no directory
> separator between the work tree and in-repo part.
>
> Signed-off-by: Martin Erik Werner 
> ---
>  cache.h |  1 +
>  setup.c | 63 +++
>  2 files changed, 64 insertions(+)
>
> diff --git a/cache.h b/cache.h
> index ce377e1..242f27d 100644
> --- a/cache.h
> +++ b/cache.h
> @@ -426,6 +426,7 @@ extern void verify_filename(const char *prefix,
>   int diagnose_misspelt_rev);
>  extern void verify_non_filename(const char *prefix, const char *name);
>  extern int path_inside_repo(const char *prefix, const char *path);
> +extern int abspath_part_inside_repo(char *dst, const char *path);
abspath_part_inside_repo() is only used in setup.c, isn't it?
In this case we don't need it in cache.h, it can be declared inside setup.c as

static int abspath_part_inside_repo(char *dst, const char *path);
(or "static inline" )

-
(And not in this patch: see the final setup.c:)

if (g) {
free(npath);
return NULL;
}

If this is the only caller of abspath_part_inside_repo(),
then  do we need npath 2 times as a parameter ?
Or can we re-write it to look like this:

static inline int abspath_part_inside_repo(char *path)
[
]



--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html