diff --git a/cache.h b/cache.h index 5e7381eb1e..6761554e6c 100644 --- a/cache.h +++ b/cache.h @@ -225,6 +225,21 @@ extern void verify_non_filename(const char *prefix, const char *name); #define alloc_nr(x) (((x)+16)*3/2) +/* + * Realloc the buffer pointed at by variable 'x' so that it can hold + * at least 'nr' entries; the number of entries currently allocated + * is 'alloc', using the standard growing factor alloc_nr() macro. + * + * DO NOT USE any expression with side-effect for 'x' or 'alloc'. + */ +#define ALLOC_GROW(x, nr, alloc) \ + do { \ + if ((nr) >= alloc) { \ + alloc = alloc_nr(alloc); \ + x = xrealloc((x), alloc * sizeof(*(x))); \ + } \ + } while(0) + /* Initialize and use the cache information */ extern int read_index(struct index_state *); extern int read_index_from(struct index_state *, const char *path); diff --git a/dir.c b/dir.c index f543f50f42..5ba6030e9a 100644 --- a/dir.c +++ b/dir.c @@ -271,27 +271,26 @@ int excluded(struct dir_struct *dir, const char *pathname) return 0; } -struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathname, int len) -{ +static struct dir_entry *dir_entry_new(const char *pathname, int len) { struct dir_entry *ent; - if (cache_name_pos(pathname, len) >= 0) - return NULL; - - if (dir->nr == dir->alloc) { - int alloc = alloc_nr(dir->alloc); - dir->alloc = alloc; - dir->entries = xrealloc(dir->entries, alloc*sizeof(ent)); - } ent = xmalloc(sizeof(*ent) + len + 1); ent->ignored = ent->ignored_dir = 0; ent->len = len; memcpy(ent->name, pathname, len); ent->name[len] = 0; - dir->entries[dir->nr++] = ent; return ent; } +struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathname, int len) +{ + if (cache_name_pos(pathname, len) >= 0) + return NULL; + + ALLOC_GROW(dir->entries, dir->nr, dir->alloc); + return dir->entries[dir->nr++] = dir_entry_new(pathname, len); +} + enum exist_status { index_nonexistent = 0, index_directory,