object_array_entry: fix memory handling of the name field
[gitweb.git] / revision.c
index 8ac88d6798a2150954213564975a7a6327c7a66c..4aeda334dbb7693563800da6da123d0094d72963 100644 (file)
@@ -88,7 +88,9 @@ void add_object(struct object *obj,
                struct name_path *path,
                const char *name)
 {
-       add_object_array(obj, path_name(path, name), p);
+       char *pn = path_name(path, name);
+       add_object_array(obj, pn, p);
+       free(pn);
 }
 
 static void mark_blob_uninteresting(struct blob *blob)
@@ -1288,7 +1290,7 @@ static void read_revisions_from_stdin(struct rev_info *revs,
                        }
                        die("options not supported in --stdin mode");
                }
-               if (handle_revision_arg(xstrdup(sb.buf), revs, 0,
+               if (handle_revision_arg(sb.buf, revs, 0,
                                        REVARG_CANNOT_BE_FILENAME))
                        die("bad revision '%s'", sb.buf);
        }
@@ -2435,25 +2437,23 @@ static struct commit *get_revision_1(struct rev_info *revs)
        return NULL;
 }
 
-static void gc_boundary(struct object_array *array)
+/*
+ * Return true for entries that have not yet been shown.  (This is an
+ * object_array_each_func_t.)
+ */
+static int entry_unshown(struct object_array_entry *entry, void *cb_data_unused)
 {
-       unsigned nr = array->nr;
-       unsigned alloc = array->alloc;
-       struct object_array_entry *objects = array->objects;
+       return !(entry->item->flags & SHOWN);
+}
 
-       if (alloc <= nr) {
-               unsigned i, j;
-               for (i = j = 0; i < nr; i++) {
-                       if (objects[i].item->flags & SHOWN)
-                               continue;
-                       if (i != j)
-                               objects[j] = objects[i];
-                       j++;
-               }
-               for (i = j; i < nr; i++)
-                       objects[i].item = NULL;
-               array->nr = j;
-       }
+/*
+ * If array is on the verge of a realloc, garbage-collect any entries
+ * that have already been shown to try to free up some space.
+ */
+static void gc_boundary(struct object_array *array)
+{
+       if (array->nr == array->alloc)
+               object_array_filter(array, entry_unshown, NULL);
 }
 
 static void create_boundary_commit_list(struct rev_info *revs)