lstat_cache: optionally return match_len

Return match_len so that the caller can know which leading path
component matched.

Signed-off-by: Clemens Buchacher <drizzd@aon.at>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Clemens Buchacher 2010-10-09 15:52:59 +02:00 committed by Junio C Hamano
parent 6838d1ad6b
commit f7e3bd37fb

View File

@ -64,11 +64,13 @@ static inline void reset_lstat_cache(struct cache_def *cache)
* of the prefix, where the cache should use the stat() function * of the prefix, where the cache should use the stat() function
* instead of the lstat() function to test each path component. * instead of the lstat() function to test each path component.
*/ */
static int lstat_cache(struct cache_def *cache, const char *name, int len, static int lstat_cache_matchlen(struct cache_def *cache,
int track_flags, int prefix_len_stat_func) const char *name, int len,
int *ret_flags, int track_flags,
int prefix_len_stat_func)
{ {
int match_len, last_slash, last_slash_dir, previous_slash; int match_len, last_slash, last_slash_dir, previous_slash;
int match_flags, ret_flags, save_flags, max_len, ret; int save_flags, max_len, ret;
struct stat st; struct stat st;
if (cache->track_flags != track_flags || if (cache->track_flags != track_flags ||
@ -90,13 +92,13 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
match_len = last_slash = match_len = last_slash =
longest_path_match(name, len, cache->path, cache->len, longest_path_match(name, len, cache->path, cache->len,
&previous_slash); &previous_slash);
match_flags = cache->flags & track_flags & (FL_NOENT|FL_SYMLINK); *ret_flags = cache->flags & track_flags & (FL_NOENT|FL_SYMLINK);
if (!(track_flags & FL_FULLPATH) && match_len == len) if (!(track_flags & FL_FULLPATH) && match_len == len)
match_len = last_slash = previous_slash; match_len = last_slash = previous_slash;
if (match_flags && match_len == cache->len) if (*ret_flags && match_len == cache->len)
return match_flags; return match_len;
/* /*
* If we now have match_len > 0, we would know that * If we now have match_len > 0, we would know that
* the matched part will always be a directory. * the matched part will always be a directory.
@ -105,16 +107,16 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
* a substring of the cache on a path component basis, * a substring of the cache on a path component basis,
* we can return immediately. * we can return immediately.
*/ */
match_flags = track_flags & FL_DIR; *ret_flags = track_flags & FL_DIR;
if (match_flags && len == match_len) if (*ret_flags && len == match_len)
return match_flags; return match_len;
} }
/* /*
* Okay, no match from the cache so far, so now we have to * Okay, no match from the cache so far, so now we have to
* check the rest of the path components. * check the rest of the path components.
*/ */
ret_flags = FL_DIR; *ret_flags = FL_DIR;
last_slash_dir = last_slash; last_slash_dir = last_slash;
max_len = len < PATH_MAX ? len : PATH_MAX; max_len = len < PATH_MAX ? len : PATH_MAX;
while (match_len < max_len) { while (match_len < max_len) {
@ -133,16 +135,16 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
ret = lstat(cache->path, &st); ret = lstat(cache->path, &st);
if (ret) { if (ret) {
ret_flags = FL_LSTATERR; *ret_flags = FL_LSTATERR;
if (errno == ENOENT) if (errno == ENOENT)
ret_flags |= FL_NOENT; *ret_flags |= FL_NOENT;
} else if (S_ISDIR(st.st_mode)) { } else if (S_ISDIR(st.st_mode)) {
last_slash_dir = last_slash; last_slash_dir = last_slash;
continue; continue;
} else if (S_ISLNK(st.st_mode)) { } else if (S_ISLNK(st.st_mode)) {
ret_flags = FL_SYMLINK; *ret_flags = FL_SYMLINK;
} else { } else {
ret_flags = FL_ERR; *ret_flags = FL_ERR;
} }
break; break;
} }
@ -152,7 +154,7 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
* path types, FL_NOENT, FL_SYMLINK and FL_DIR, can be cached * path types, FL_NOENT, FL_SYMLINK and FL_DIR, can be cached
* for the moment! * for the moment!
*/ */
save_flags = ret_flags & track_flags & (FL_NOENT|FL_SYMLINK); save_flags = *ret_flags & track_flags & (FL_NOENT|FL_SYMLINK);
if (save_flags && last_slash > 0 && last_slash <= PATH_MAX) { if (save_flags && last_slash > 0 && last_slash <= PATH_MAX) {
cache->path[last_slash] = '\0'; cache->path[last_slash] = '\0';
cache->len = last_slash; cache->len = last_slash;
@ -176,7 +178,16 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
} else { } else {
reset_lstat_cache(cache); reset_lstat_cache(cache);
} }
return ret_flags; return match_len;
}
static int lstat_cache(struct cache_def *cache, const char *name, int len,
int track_flags, int prefix_len_stat_func)
{
int flags;
(void)lstat_cache_matchlen(cache, name, len, &flags, track_flags,
prefix_len_stat_func);
return flags;
} }
#define USE_ONLY_LSTAT 0 #define USE_ONLY_LSTAT 0