resolve_ref_1(): eliminate local variable
[gitweb.git] / refs / files-backend.c
index b56976288819c87307c03e4e5abf9b9458d09970..69ec9036e0c8b70304e57f30a2f94d675340e914 100644 (file)
@@ -199,17 +199,14 @@ static struct ref_entry *create_ref_entry(const char *refname,
                                          const unsigned char *sha1, int flag,
                                          int check_name)
 {
-       int len;
        struct ref_entry *ref;
 
        if (check_name &&
            check_refname_format(refname, REFNAME_ALLOW_ONELEVEL))
                die("Reference has invalid format: '%s'", refname);
-       len = strlen(refname) + 1;
-       ref = xmalloc(sizeof(struct ref_entry) + len);
+       FLEX_ALLOC_STR(ref, name, refname);
        hashcpy(ref->u.value.oid.hash, sha1);
        oidclr(&ref->u.value.peeled);
-       memcpy(ref->name, refname, len);
        ref->flag = flag;
        return ref;
 }
@@ -268,9 +265,7 @@ static struct ref_entry *create_dir_entry(struct ref_cache *ref_cache,
                                          int incomplete)
 {
        struct ref_entry *direntry;
-       direntry = xcalloc(1, sizeof(struct ref_entry) + len + 1);
-       memcpy(direntry->name, dirname, len);
-       direntry->name[len] = '\0';
+       FLEX_ALLOC_MEM(direntry, name, dirname, len);
        direntry->u.subdir.ref_cache = ref_cache;
        direntry->flag = REF_DIR | (incomplete ? REF_INCOMPLETE : 0);
        return direntry;
@@ -518,9 +513,6 @@ static void sort_ref_dir(struct ref_dir *dir)
        dir->sorted = dir->nr = i;
 }
 
-/* Include broken references in a do_for_each_ref*() iteration: */
-#define DO_FOR_EACH_INCLUDE_BROKEN 0x01
-
 /*
  * Return true iff the reference described by entry can be resolved to
  * an object in the database.  Emit a warning if the referred-to
@@ -939,13 +931,10 @@ static void clear_loose_ref_cache(struct ref_cache *refs)
  */
 static struct ref_cache *create_ref_cache(const char *submodule)
 {
-       int len;
        struct ref_cache *refs;
        if (!submodule)
                submodule = "";
-       len = strlen(submodule) + 1;
-       refs = xcalloc(1, sizeof(struct ref_cache) + len);
-       memcpy(refs->name, submodule, len);
+       FLEX_ALLOC_STR(refs, name, submodule);
        refs->next = submodule_ref_caches;
        submodule_ref_caches = refs;
        return refs;
@@ -1379,11 +1368,9 @@ static struct ref_entry *get_packed_ref(const char *refname)
 }
 
 /*
- * A loose ref file doesn't exist; check for a packed ref.  The
- * options are forwarded from resolve_safe_unsafe().
+ * A loose ref file doesn't exist; check for a packed ref.
  */
 static int resolve_missing_loose_ref(const char *refname,
-                                    int resolve_flags,
                                     unsigned char *sha1,
                                     int *flags)
 {
@@ -1396,18 +1383,11 @@ static int resolve_missing_loose_ref(const char *refname,
        entry = get_packed_ref(refname);
        if (entry) {
                hashcpy(sha1, entry->u.value.oid.hash);
-               if (flags)
-                       *flags |= REF_ISPACKED;
-               return 0;
-       }
-       /* The reference is not a packed reference, either. */
-       if (resolve_flags & RESOLVE_REF_READING) {
-               errno = ENOENT;
-               return -1;
-       } else {
-               hashclr(sha1);
+               *flags |= REF_ISPACKED;
                return 0;
        }
+       /* refname is not a packed reference. */
+       return -1;
 }
 
 /* This function needs to return a meaningful errno on failure */
@@ -1419,15 +1399,13 @@ static const char *resolve_ref_1(const char *refname,
                                 struct strbuf *sb_path,
                                 struct strbuf *sb_contents)
 {
-       int depth = MAXDEPTH;
        int bad_name = 0;
+       int symref_count;
 
-       if (flags)
-               *flags = 0;
+       *flags = 0;
 
        if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
-               if (flags)
-                       *flags |= REF_BAD_NAME;
+               *flags |= REF_BAD_NAME;
 
                if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
                    !refname_is_safe(refname)) {
@@ -1444,17 +1422,12 @@ static const char *resolve_ref_1(const char *refname,
                 */
                bad_name = 1;
        }
-       for (;;) {
+
+       for (symref_count = 0; symref_count < MAXDEPTH; symref_count++) {
                const char *path;
                struct stat st;
-               char *buf;
                int fd;
 
-               if (--depth < 0) {
-                       errno = ELOOP;
-                       return NULL;
-               }
-
                strbuf_reset(sb_path);
                strbuf_git_path(sb_path, "%s", refname);
                path = sb_path->buf;
@@ -1472,13 +1445,16 @@ static const char *resolve_ref_1(const char *refname,
                if (lstat(path, &st) < 0) {
                        if (errno != ENOENT)
                                return NULL;
-                       if (resolve_missing_loose_ref(refname, resolve_flags,
-                                                     sha1, flags))
-                               return NULL;
+                       if (resolve_missing_loose_ref(refname, sha1, flags)) {
+                               if (resolve_flags & RESOLVE_REF_READING) {
+                                       errno = ENOENT;
+                                       return NULL;
+                               }
+                               hashclr(sha1);
+                       }
                        if (bad_name) {
                                hashclr(sha1);
-                               if (flags)
-                                       *flags |= REF_ISBROKEN;
+                               *flags |= REF_ISBROKEN;
                        }
                        return refname;
                }
@@ -1497,8 +1473,7 @@ static const char *resolve_ref_1(const char *refname,
                            !check_refname_format(sb_contents->buf, 0)) {
                                strbuf_swap(sb_refname, sb_contents);
                                refname = sb_refname->buf;
-                               if (flags)
-                                       *flags |= REF_ISSYMREF;
+                               *flags |= REF_ISSYMREF;
                                if (resolve_flags & RESOLVE_REF_NO_RECURSE) {
                                        hashclr(sha1);
                                        return refname;
@@ -1545,42 +1520,41 @@ static const char *resolve_ref_1(const char *refname,
                         */
                        if (get_sha1_hex(sb_contents->buf, sha1) ||
                            (sb_contents->buf[40] != '\0' && !isspace(sb_contents->buf[40]))) {
-                               if (flags)
-                                       *flags |= REF_ISBROKEN;
+                               *flags |= REF_ISBROKEN;
                                errno = EINVAL;
                                return NULL;
                        }
                        if (bad_name) {
                                hashclr(sha1);
-                               if (flags)
-                                       *flags |= REF_ISBROKEN;
+                               *flags |= REF_ISBROKEN;
                        }
                        return refname;
                }
-               if (flags)
-                       *flags |= REF_ISSYMREF;
-               buf = sb_contents->buf + 4;
-               while (isspace(*buf))
-                       buf++;
+               *flags |= REF_ISSYMREF;
+               refname = sb_contents->buf + 4;
+               while (isspace(*refname))
+                       refname++;
                strbuf_reset(sb_refname);
-               strbuf_addstr(sb_refname, buf);
+               strbuf_addstr(sb_refname, refname);
                refname = sb_refname->buf;
                if (resolve_flags & RESOLVE_REF_NO_RECURSE) {
                        hashclr(sha1);
                        return refname;
                }
-               if (check_refname_format(buf, REFNAME_ALLOW_ONELEVEL)) {
-                       if (flags)
-                               *flags |= REF_ISBROKEN;
+               if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) {
+                       *flags |= REF_ISBROKEN;
 
                        if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) ||
-                           !refname_is_safe(buf)) {
+                           !refname_is_safe(refname)) {
                                errno = EINVAL;
                                return NULL;
                        }
                        bad_name = 1;
                }
        }
+
+       errno = ELOOP;
+       return NULL;
 }
 
 const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
@@ -1589,8 +1563,12 @@ const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
        static struct strbuf sb_refname = STRBUF_INIT;
        struct strbuf sb_contents = STRBUF_INIT;
        struct strbuf sb_path = STRBUF_INIT;
+       int unused_flags;
        const char *ret;
 
+       if (!flags)
+               flags = &unused_flags;
+
        ret = resolve_ref_1(refname, resolve_flags, sha1, flags,
                            &sb_refname, &sb_path, &sb_contents);
        strbuf_release(&sb_path);
@@ -1735,10 +1713,13 @@ static int do_for_each_entry(struct ref_cache *refs, const char *base,
  * value, stop the iteration and return that value; otherwise, return
  * 0.
  */
-static int do_for_each_ref(struct ref_cache *refs, const char *base,
-                          each_ref_fn fn, int trim, int flags, void *cb_data)
+int do_for_each_ref(const char *submodule, const char *base,
+                   each_ref_fn fn, int trim, int flags, void *cb_data)
 {
        struct ref_entry_cb data;
+       struct ref_cache *refs;
+
+       refs = get_ref_cache(submodule);
        data.base = base;
        data.trim = trim;
        data.flags = flags;
@@ -1753,86 +1734,6 @@ static int do_for_each_ref(struct ref_cache *refs, const char *base,
        return do_for_each_entry(refs, base, do_one_ref, &data);
 }
 
-static int do_head_ref(const char *submodule, each_ref_fn fn, void *cb_data)
-{
-       struct object_id oid;
-       int flag;
-
-       if (submodule) {
-               if (resolve_gitlink_ref(submodule, "HEAD", oid.hash) == 0)
-                       return fn("HEAD", &oid, 0, cb_data);
-
-               return 0;
-       }
-
-       if (!read_ref_full("HEAD", RESOLVE_REF_READING, oid.hash, &flag))
-               return fn("HEAD", &oid, flag, cb_data);
-
-       return 0;
-}
-
-int head_ref(each_ref_fn fn, void *cb_data)
-{
-       return do_head_ref(NULL, fn, cb_data);
-}
-
-int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)
-{
-       return do_head_ref(submodule, fn, cb_data);
-}
-
-int for_each_ref(each_ref_fn fn, void *cb_data)
-{
-       return do_for_each_ref(&ref_cache, "", fn, 0, 0, cb_data);
-}
-
-int for_each_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data)
-{
-       return do_for_each_ref(get_ref_cache(submodule), "", fn, 0, 0, cb_data);
-}
-
-int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data)
-{
-       return do_for_each_ref(&ref_cache, prefix, fn, strlen(prefix), 0, cb_data);
-}
-
-int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, unsigned int broken)
-{
-       unsigned int flag = 0;
-
-       if (broken)
-               flag = DO_FOR_EACH_INCLUDE_BROKEN;
-       return do_for_each_ref(&ref_cache, prefix, fn, 0, flag, cb_data);
-}
-
-int for_each_ref_in_submodule(const char *submodule, const char *prefix,
-               each_ref_fn fn, void *cb_data)
-{
-       return do_for_each_ref(get_ref_cache(submodule), prefix, fn, strlen(prefix), 0, cb_data);
-}
-
-int for_each_replace_ref(each_ref_fn fn, void *cb_data)
-{
-       return do_for_each_ref(&ref_cache, git_replace_ref_base, fn,
-                              strlen(git_replace_ref_base), 0, cb_data);
-}
-
-int for_each_namespaced_ref(each_ref_fn fn, void *cb_data)
-{
-       struct strbuf buf = STRBUF_INIT;
-       int ret;
-       strbuf_addf(&buf, "%srefs/", get_git_namespace());
-       ret = do_for_each_ref(&ref_cache, buf.buf, fn, 0, 0, cb_data);
-       strbuf_release(&buf);
-       return ret;
-}
-
-int for_each_rawref(each_ref_fn fn, void *cb_data)
-{
-       return do_for_each_ref(&ref_cache, "", fn, 0,
-                              DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
-}
-
 static void unlock_ref(struct ref_lock *lock)
 {
        /* Do not free lock->lk -- atexit() still looks at them */
@@ -2197,10 +2098,9 @@ static int pack_if_possible_fn(struct ref_entry *entry, void *cb_data)
 
        /* Schedule the loose reference for pruning if requested. */
        if ((cb->flags & PACK_REFS_PRUNE)) {
-               int namelen = strlen(entry->name) + 1;
-               struct ref_to_prune *n = xcalloc(1, sizeof(*n) + namelen);
+               struct ref_to_prune *n;
+               FLEX_ALLOC_STR(n, name, entry->name);
                hashcpy(n->sha1, entry->u.value.oid.hash);
-               memcpy(n->name, entry->name, namelen); /* includes NUL */
                n->next = cb->ref_to_prune;
                cb->ref_to_prune = n;
        }