revision.c: update show_object_with_name() without using malloc()
authorJunio C Hamano <gitster@pobox.com>
Wed, 17 Aug 2011 21:30:35 +0000 (14:30 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 22 Aug 2011 18:34:55 +0000 (11:34 -0700)
Allocating and then immediately freeing temporary memory a million times
when listing a million objects is distasteful.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
revision.c

index c5b38cc1174356c15d6b544ab8eab4391a4621a7..072ddac4703058ff245b01488e36b190f8590f82 100644 (file)
@@ -40,23 +40,45 @@ char *path_name(const struct name_path *path, const char *name)
        return n;
 }
 
+static int show_path_component_truncated(FILE *out, const char *name, int len)
+{
+       int cnt;
+       for (cnt = 0; cnt < len; cnt++) {
+               int ch = name[cnt];
+               if (!ch || ch == '\n')
+                       return -1;
+               fputc(ch, out);
+       }
+       return len;
+}
+
+static int show_path_truncated(FILE *out, const struct name_path *path)
+{
+       int emitted, ours;
+
+       if (!path)
+               return 0;
+       emitted = show_path_truncated(out, path->up);
+       if (emitted < 0)
+               return emitted;
+       if (emitted)
+               fputc('/', out);
+       ours = show_path_component_truncated(out, path->elem, path->elem_len);
+       if (ours < 0)
+               return ours;
+       return ours || emitted;
+}
+
 void show_object_with_name(FILE *out, struct object *obj, const struct name_path *path, const char *component)
 {
-       char *name = path_name(path, component);
-       const char *ep = strchr(name, '\n');
+       struct name_path leaf;
+       leaf.up = (struct name_path *)path;
+       leaf.elem = component;
+       leaf.elem_len = strlen(component);
 
-       /*
-        * An object with name "foo\n0000000..." can be used to
-        * confuse downstream "git pack-objects" very badly.
-        */
-       if (ep) {
-               fprintf(out, "%s %.*s\n", sha1_to_hex(obj->sha1),
-                       (int) (ep - name),
-                       name);
-       }
-       else
-               fprintf(out, "%s %s\n", sha1_to_hex(obj->sha1), name);
-       free(name);
+       fprintf(out, "%s ", sha1_to_hex(obj->sha1));
+       show_path_truncated(out, &leaf);
+       fputc('\n', out);
 }
 
 void add_object(struct object *obj,