tree-walk: add a strbuf wrapper for make_traverse_path()
All but one of the callers of make_traverse_path() allocate a new heap buffer to store the path. Let's give them an easy way to write to a strbuf, which saves them from computing the length themselves (which is especially tricky when they want to add to the path). It will also make it easier for us to change the make_traverse_path() interface in a future patch to improve its bounds-checking. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
b3b3cbcbf2
commit
c43ab06259
@ -138,6 +138,10 @@ same in the next callback invocation.
|
|||||||
This utilizes the memory structure of a tree entry to avoid the
|
This utilizes the memory structure of a tree entry to avoid the
|
||||||
overhead of using a generic strlen().
|
overhead of using a generic strlen().
|
||||||
|
|
||||||
|
`strbuf_make_traverse_path`::
|
||||||
|
|
||||||
|
Convenience wrapper to `make_traverse_path` into a strbuf.
|
||||||
|
|
||||||
Authors
|
Authors
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
@ -180,8 +180,9 @@ static struct merge_list *create_entry(unsigned stage, unsigned mode, const stru
|
|||||||
|
|
||||||
static char *traverse_path(const struct traverse_info *info, const struct name_entry *n)
|
static char *traverse_path(const struct traverse_info *info, const struct name_entry *n)
|
||||||
{
|
{
|
||||||
char *path = xmallocz(traverse_path_len(info, tree_entry_len(n)));
|
struct strbuf buf = STRBUF_INIT;
|
||||||
return make_traverse_path(path, info, n->path, n->pathlen);
|
strbuf_make_traverse_path(&buf, info, n->path, n->pathlen);
|
||||||
|
return strbuf_detach(&buf, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void resolve(const struct traverse_info *info, struct name_entry *ours, struct name_entry *result)
|
static void resolve(const struct traverse_info *info, struct name_entry *ours, struct name_entry *result)
|
||||||
|
21
tree-walk.c
21
tree-walk.c
@ -200,6 +200,17 @@ char *make_traverse_path(char *path, const struct traverse_info *info,
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void strbuf_make_traverse_path(struct strbuf *out,
|
||||||
|
const struct traverse_info *info,
|
||||||
|
const char *name, size_t namelen)
|
||||||
|
{
|
||||||
|
size_t len = traverse_path_len(info, namelen);
|
||||||
|
|
||||||
|
strbuf_grow(out, len);
|
||||||
|
make_traverse_path(out->buf + out->len, info, name, namelen);
|
||||||
|
strbuf_setlen(out, out->len + len);
|
||||||
|
}
|
||||||
|
|
||||||
struct tree_desc_skip {
|
struct tree_desc_skip {
|
||||||
struct tree_desc_skip *prev;
|
struct tree_desc_skip *prev;
|
||||||
const void *ptr;
|
const void *ptr;
|
||||||
@ -396,12 +407,10 @@ int traverse_trees(struct index_state *istate,
|
|||||||
tx[i].d = t[i];
|
tx[i].d = t[i];
|
||||||
|
|
||||||
if (info->prev) {
|
if (info->prev) {
|
||||||
strbuf_grow(&base, info->pathlen);
|
strbuf_make_traverse_path(&base, info->prev,
|
||||||
make_traverse_path(base.buf, info->prev, info->name,
|
info->name, info->namelen);
|
||||||
info->namelen);
|
strbuf_addch(&base, '/');
|
||||||
base.buf[info->pathlen-1] = '/';
|
traverse_path = xstrndup(base.buf, base.len);
|
||||||
strbuf_setlen(&base, info->pathlen);
|
|
||||||
traverse_path = xstrndup(base.buf, info->pathlen);
|
|
||||||
} else {
|
} else {
|
||||||
traverse_path = xstrndup(info->name, info->pathlen);
|
traverse_path = xstrndup(info->name, info->pathlen);
|
||||||
}
|
}
|
||||||
|
@ -72,6 +72,9 @@ struct traverse_info {
|
|||||||
int get_tree_entry(const struct object_id *, const char *, struct object_id *, unsigned short *);
|
int get_tree_entry(const struct object_id *, const char *, struct object_id *, unsigned short *);
|
||||||
char *make_traverse_path(char *path, const struct traverse_info *info,
|
char *make_traverse_path(char *path, const struct traverse_info *info,
|
||||||
const char *name, size_t namelen);
|
const char *name, size_t namelen);
|
||||||
|
void strbuf_make_traverse_path(struct strbuf *out,
|
||||||
|
const struct traverse_info *info,
|
||||||
|
const char *name, size_t namelen);
|
||||||
void setup_traverse_info(struct traverse_info *info, const char *base);
|
void setup_traverse_info(struct traverse_info *info, const char *base);
|
||||||
|
|
||||||
static inline size_t traverse_path_len(const struct traverse_info *info,
|
static inline size_t traverse_path_len(const struct traverse_info *info,
|
||||||
|
@ -686,21 +686,19 @@ static int index_pos_by_traverse_info(struct name_entry *names,
|
|||||||
struct traverse_info *info)
|
struct traverse_info *info)
|
||||||
{
|
{
|
||||||
struct unpack_trees_options *o = info->data;
|
struct unpack_trees_options *o = info->data;
|
||||||
size_t len = traverse_path_len(info, tree_entry_len(names));
|
struct strbuf name = STRBUF_INIT;
|
||||||
char *name = xmalloc(len + 1 /* slash */ + 1 /* NUL */);
|
|
||||||
int pos;
|
int pos;
|
||||||
|
|
||||||
make_traverse_path(name, info, names->path, names->pathlen);
|
strbuf_make_traverse_path(&name, info, names->path, names->pathlen);
|
||||||
name[len++] = '/';
|
strbuf_addch(&name, '/');
|
||||||
name[len] = '\0';
|
pos = index_name_pos(o->src_index, name.buf, name.len);
|
||||||
pos = index_name_pos(o->src_index, name, len);
|
|
||||||
if (pos >= 0)
|
if (pos >= 0)
|
||||||
BUG("This is a directory and should not exist in index");
|
BUG("This is a directory and should not exist in index");
|
||||||
pos = -pos - 1;
|
pos = -pos - 1;
|
||||||
if (!starts_with(o->src_index->cache[pos]->name, name) ||
|
if (!starts_with(o->src_index->cache[pos]->name, name.buf) ||
|
||||||
(pos > 0 && starts_with(o->src_index->cache[pos-1]->name, name)))
|
(pos > 0 && starts_with(o->src_index->cache[pos-1]->name, name.buf)))
|
||||||
BUG("pos must point at the first entry in this directory");
|
BUG("pos must point at the first entry in this directory");
|
||||||
free(name);
|
strbuf_release(&name);
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user