free((x)); \
} while(0)
-static struct combine_diff_path *ll_diff_tree_paths(
- struct combine_diff_path *tail, const struct object_id *oid,
+static void ll_diff_tree_paths(
+ struct combine_diff_path ***tail, const struct object_id *oid,
const struct object_id **parents_oid, int nparent,
struct strbuf *base, struct diff_options *opt,
int depth);
* t, tp -> path modified/added
* (M for tp[i]=tp[imin], A otherwise)
*/
-static struct combine_diff_path *emit_path(struct combine_diff_path *tail,
- struct strbuf *base, struct diff_options *opt, int nparent,
- struct tree_desc *t, struct tree_desc *tp,
- int imin, int depth)
+static void emit_path(struct combine_diff_path ***tail,
+ struct strbuf *base, struct diff_options *opt,
+ int nparent, struct tree_desc *t, struct tree_desc *tp,
+ int imin, int depth)
{
unsigned short mode;
const char *path;
keep = opt->pathchange(opt, p);
if (keep) {
- tail->next = p;
- tail = p;
+ **tail = p;
+ *tail = &p->next;
} else {
free(p);
}
strbuf_add(base, path, pathlen);
strbuf_addch(base, '/');
- tail = ll_diff_tree_paths(tail, oid, parents_oid, nparent, base, opt,
- depth + 1);
+ ll_diff_tree_paths(tail, oid, parents_oid, nparent, base, opt,
+ depth + 1);
FAST_ARRAY_FREE(parents_oid, nparent);
}
strbuf_setlen(base, old_baselen);
- return tail;
}
static void skip_uninteresting(struct tree_desc *t, struct strbuf *base,
update_tree_entry(&tp[i]);
}
-static struct combine_diff_path *ll_diff_tree_paths(
- struct combine_diff_path *tail, const struct object_id *oid,
+static void ll_diff_tree_paths(
+ struct combine_diff_path ***tail, const struct object_id *oid,
const struct object_id **parents_oid, int nparent,
struct strbuf *base, struct diff_options *opt,
int depth)
}
/* D += {δ(t,pi) if pi=p[imin]; "+a" if pi > p[imin]} */
- tail = emit_path(tail, base, opt, nparent,
- &t, tp, imin, depth);
+ emit_path(tail, base, opt, nparent,
+ &t, tp, imin, depth);
skip_emit_t_tp:
/* t↓, ∀ pi=p[imin] pi↓ */
/* t < p[imin] */
else if (cmp < 0) {
/* D += "+t" */
- tail = emit_path(tail, base, opt, nparent,
- &t, /*tp=*/NULL, -1, depth);
+ emit_path(tail, base, opt, nparent,
+ &t, /*tp=*/NULL, -1, depth);
/* t↓ */
update_tree_entry(&t);
goto skip_emit_tp;
}
- tail = emit_path(tail, base, opt, nparent,
- /*t=*/NULL, tp, imin, depth);
+ emit_path(tail, base, opt, nparent,
+ /*t=*/NULL, tp, imin, depth);
skip_emit_tp:
/* ∀ pi=p[imin] pi↓ */
free(tptree[i]);
FAST_ARRAY_FREE(tptree, nparent);
FAST_ARRAY_FREE(tp, nparent);
-
- return tail;
}
struct combine_diff_path *diff_tree_paths(
const struct object_id **parents_oid, int nparent,
struct strbuf *base, struct diff_options *opt)
{
- struct combine_diff_path head, *p;
- /* fake list head, so worker can assume it is non-NULL */
- head.next = NULL;
- p = ll_diff_tree_paths(&head, oid, parents_oid, nparent, base, opt, 0);
- return p;
+ struct combine_diff_path *head = NULL, **tail = &head;
+ ll_diff_tree_paths(&tail, oid, parents_oid, nparent, base, opt, 0);
+ return head;
}
/*