Merge branch 'jk/name-decoration-alloc'
authorJunio C Hamano <gitster@pobox.com>
Thu, 11 Sep 2014 17:33:36 +0000 (10:33 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 11 Sep 2014 17:33:36 +0000 (10:33 -0700)
The API to allocate the structure to keep track of commit
decoration was cumbersome to use, inviting lazy code to
overallocate memory.

* jk/name-decoration-alloc:
log-tree: use FLEX_ARRAY in name_decoration
log-tree: make name_decoration hash static
log-tree: make add_name_decoration a public function

bisect.c
commit.h
log-tree.c
revision.c
index d6e851d783c3541eb21edd47170ce7a32e082e61..df09cbc8cabe9dcb87a0023445babcf14c3d7691 100644 (file)
--- a/bisect.c
+++ b/bisect.c
@@ -215,11 +215,12 @@ static struct commit_list *best_bisection_sorted(struct commit_list *list, int n
        }
        qsort(array, cnt, sizeof(*array), compare_commit_dist);
        for (p = list, i = 0; i < cnt; i++) {
-               struct name_decoration *r = xmalloc(sizeof(*r) + 100);
+               char buf[100]; /* enough for dist=%d */
                struct object *obj = &(array[i].commit->object);
 
-               sprintf(r->name, "dist=%d", array[i].distance);
-               r->next = add_decoration(&name_decoration, obj, r);
+               snprintf(buf, sizeof(buf), "dist=%d", array[i].distance);
+               add_name_decoration(DECORATION_NONE, buf, obj);
+
                p->item = array[i].commit;
                p = p->next;
        }
index aa8c3ca50af42375caf954e309d76731b4a9295e..a401ddfbc4e5c2e5e4a9d7aeedebc34e6103c9fa 100644 (file)
--- a/commit.h
+++ b/commit.h
@@ -26,13 +26,25 @@ extern int save_commit_buffer;
 extern const char *commit_type;
 
 /* While we can decorate any object with a name, it's only used for commits.. */
-extern struct decoration name_decoration;
 struct name_decoration {
        struct name_decoration *next;
        int type;
-       char name[1];
+       char name[FLEX_ARRAY];
 };
 
+enum decoration_type {
+       DECORATION_NONE = 0,
+       DECORATION_REF_LOCAL,
+       DECORATION_REF_REMOTE,
+       DECORATION_REF_TAG,
+       DECORATION_REF_STASH,
+       DECORATION_REF_HEAD,
+       DECORATION_GRAFTED,
+};
+
+void add_name_decoration(enum decoration_type type, const char *name, struct object *obj);
+const struct name_decoration *get_name_decoration(const struct object *obj);
+
 struct commit *lookup_commit(const unsigned char *sha1);
 struct commit *lookup_commit_reference(const unsigned char *sha1);
 struct commit *lookup_commit_reference_gently(const unsigned char *sha1,
index 95e9b1da259ef33a1c5bc7f7d07e853ebc5dbcec..bcee7c596696eb1da109b3ff375e09453045a60f 100644 (file)
 #include "sequencer.h"
 #include "line-log.h"
 
-struct decoration name_decoration = { "object names" };
-
-enum decoration_type {
-       DECORATION_NONE = 0,
-       DECORATION_REF_LOCAL,
-       DECORATION_REF_REMOTE,
-       DECORATION_REF_TAG,
-       DECORATION_REF_STASH,
-       DECORATION_REF_HEAD,
-       DECORATION_GRAFTED,
-};
+static struct decoration name_decoration = { "object names" };
 
 static char decoration_colors[][COLOR_MAXLEN] = {
        GIT_COLOR_RESET,
@@ -84,15 +74,20 @@ int parse_decorate_color_config(const char *var, const int ofs, const char *valu
 #define decorate_get_color_opt(o, ix) \
        decorate_get_color((o)->use_color, ix)
 
-static void add_name_decoration(enum decoration_type type, const char *name, struct object *obj)
+void add_name_decoration(enum decoration_type type, const char *name, struct object *obj)
 {
        int nlen = strlen(name);
-       struct name_decoration *res = xmalloc(sizeof(struct name_decoration) + nlen);
+       struct name_decoration *res = xmalloc(sizeof(*res) + nlen + 1);
        memcpy(res->name, name, nlen + 1);
        res->type = type;
        res->next = add_decoration(&name_decoration, obj, res);
 }
 
+const struct name_decoration *get_name_decoration(const struct object *obj)
+{
+       return lookup_decoration(&name_decoration, obj);
+}
+
 static int add_ref_decoration(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
 {
        struct object *obj;
@@ -187,13 +182,13 @@ void format_decorations(struct strbuf *sb,
                        int use_color)
 {
        const char *prefix;
-       struct name_decoration *decoration;
+       const struct name_decoration *decoration;
        const char *color_commit =
                diff_get_color(use_color, DIFF_COMMIT);
        const char *color_reset =
                decorate_get_color(use_color, DECORATION_NONE);
 
-       decoration = lookup_decoration(&name_decoration, &commit->object);
+       decoration = get_name_decoration(&commit->object);
        if (!decoration)
                return;
        prefix = " (";
index 615535c98453336323a437530132f27824b51ac2..0d3e4171ef73f0cfb58a4f396e17717f3b0bb5a3 100644 (file)
@@ -473,7 +473,7 @@ static int rev_compare_tree(struct rev_info *revs,
                 * If we are simplifying by decoration, then the commit
                 * is worth showing if it has a tag pointing at it.
                 */
-               if (lookup_decoration(&name_decoration, &commit->object))
+               if (get_name_decoration(&commit->object))
                        return REV_TREE_DIFFERENT;
                /*
                 * A commit that is not pointed by a tag is uninteresting