info->prev = &dummy;
}
-char *make_traverse_path(char *path, const struct traverse_info *info,
+char *make_traverse_path(char *path, size_t pathlen,
+ const struct traverse_info *info,
const char *name, size_t namelen)
{
- size_t pathlen = info->pathlen;
+ /* Always points to the end of the name we're about to add */
+ size_t pos = st_add(info->pathlen, namelen);
- path[pathlen + namelen] = 0;
+ if (pos >= pathlen)
+ BUG("too small buffer passed to make_traverse_path");
+
+ path[pos] = 0;
for (;;) {
- memcpy(path + pathlen, name, namelen);
- if (!pathlen)
+ if (pos < namelen)
+ BUG("traverse_info pathlen does not match strings");
+ pos -= namelen;
+ memcpy(path + pos, name, namelen);
+
+ if (!pos)
break;
- path[--pathlen] = '/';
+ path[--pos] = '/';
+
+ if (!info)
+ BUG("traverse_info ran out of list items");
name = info->name;
namelen = info->namelen;
info = info->prev;
- pathlen -= namelen;
}
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, out->alloc - out->len,
+ info, name, namelen);
+ strbuf_setlen(out, out->len + len);
+}
+
struct tree_desc_skip {
struct tree_desc_skip *prev;
const void *ptr;
tx[i].d = t[i];
if (info->prev) {
- strbuf_grow(&base, info->pathlen);
- make_traverse_path(base.buf, info->prev, info->name,
- info->namelen);
- base.buf[info->pathlen-1] = '/';
- strbuf_setlen(&base, info->pathlen);
- traverse_path = xstrndup(base.buf, info->pathlen);
+ strbuf_make_traverse_path(&base, info->prev,
+ info->name, info->namelen);
+ strbuf_addch(&base, '/');
+ traverse_path = xstrndup(base.buf, base.len);
} else {
traverse_path = xstrndup(info->name, info->pathlen);
}