Code

lstat_cache: optionally return match_len
authorClemens Buchacher <drizzd@aon.at>
Sat, 9 Oct 2010 13:52:59 +0000 (15:52 +0200)
committerJunio C Hamano <gitster@pobox.com>
Wed, 13 Oct 2010 21:34:08 +0000 (14:34 -0700)
Return match_len so that the caller can know which leading path
component matched.

Signed-off-by: Clemens Buchacher <drizzd@aon.at>
symlinks.c

index 88601200114f857a57214a9bf0d02ffd39a83504..b7343ebd623c1031418cf5c2d932a51581fbe25d 100644 (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
  * instead of the lstat() function to test each path component.
  */
-static int lstat_cache(struct cache_def *cache, const char *name, int len,
-                      int track_flags, int prefix_len_stat_func)
+static int lstat_cache_matchlen(struct cache_def *cache,
+                               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_flags, ret_flags, save_flags, max_len, ret;
+       int save_flags, max_len, ret;
        struct stat st;
 
        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 =
                        longest_path_match(name, len, cache->path, cache->len,
                                           &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)
                        match_len = last_slash = previous_slash;
 
-               if (match_flags && match_len == cache->len)
-                       return match_flags;
+               if (*ret_flags && match_len == cache->len)
+                       return match_len;
                /*
                 * If we now have match_len > 0, we would know that
                 * 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,
                 * we can return immediately.
                 */
-               match_flags = track_flags & FL_DIR;
-               if (match_flags && len == match_len)
-                       return match_flags;
+               *ret_flags = track_flags & FL_DIR;
+               if (*ret_flags && len == match_len)
+                       return match_len;
        }
 
        /*
         * Okay, no match from the cache so far, so now we have to
         * check the rest of the path components.
         */
-       ret_flags = FL_DIR;
+       *ret_flags = FL_DIR;
        last_slash_dir = last_slash;
        max_len = len < PATH_MAX ? len : PATH_MAX;
        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);
 
                if (ret) {
-                       ret_flags = FL_LSTATERR;
+                       *ret_flags = FL_LSTATERR;
                        if (errno == ENOENT)
-                               ret_flags |= FL_NOENT;
+                               *ret_flags |= FL_NOENT;
                } else if (S_ISDIR(st.st_mode)) {
                        last_slash_dir = last_slash;
                        continue;
                } else if (S_ISLNK(st.st_mode)) {
-                       ret_flags = FL_SYMLINK;
+                       *ret_flags = FL_SYMLINK;
                } else {
-                       ret_flags = FL_ERR;
+                       *ret_flags = FL_ERR;
                }
                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
         * 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) {
                cache->path[last_slash] = '\0';
                cache->len = last_slash;
@@ -176,7 +178,16 @@ static int lstat_cache(struct cache_def *cache, const char *name, int len,
        } else {
                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