Commit 1db12b00 by Russell Belfer

Eliminate hairy COITERATE macro

I decided that the COITERATE macro was, in the end causing
more confusion that it would save and decided just to write
out the loops that I needed for parallel diff list iteration.
It is not that much code and this just feels less obfuscated.
parent 875bfc5f
...@@ -565,23 +565,39 @@ int git_diff_merge( ...@@ -565,23 +565,39 @@ int git_diff_merge(
{ {
int error = 0; int error = 0;
git_vector onto_new; git_vector onto_new;
git_diff_delta *delta, *o; git_diff_delta *delta;
const git_diff_delta *f; unsigned int i, j;
unsigned int i;
assert(onto && from);
if (!from->deltas.length)
return 0;
if (git_vector_init(&onto_new, onto->deltas.length, diff_delta__cmp) < 0) if (git_vector_init(&onto_new, onto->deltas.length, diff_delta__cmp) < 0)
return -1; return -1;
GIT_DIFF_COITERATE( for (i = 0, j = 0; i < onto->deltas.length || j < from->deltas.length; ) {
onto, from, o, f, git_diff_delta *o = GIT_VECTOR_GET(&onto->deltas, i);
delta = diff_delta__dup(o), const git_diff_delta *f = GIT_VECTOR_GET(&from->deltas, j);
delta = diff_delta__dup(f), int cmp = !f ? -1 : !o ? 1 : strcmp(o->old.path, f->old.path);
delta = diff_delta__merge_like_cgit(o, f),
if (cmp < 0) {
delta = diff_delta__dup(o);
i++;
} else if (cmp > 0) {
delta = diff_delta__dup(f);
j++;
} else {
delta = diff_delta__merge_like_cgit(o, f);
i++;
j++;
}
if ((error = !delta ? -1 : git_vector_insert(&onto_new, delta)) < 0) if ((error = !delta ? -1 : git_vector_insert(&onto_new, delta)) < 0)
break; break;
); }
if (error == 0) { if (!error) {
git_vector_swap(&onto->deltas, &onto_new); git_vector_swap(&onto->deltas, &onto_new);
onto->new_src = from->new_src; onto->new_src = from->new_src;
} }
......
...@@ -21,19 +21,5 @@ struct git_diff_list { ...@@ -21,19 +21,5 @@ struct git_diff_list {
git_iterator_type_t new_src; git_iterator_type_t new_src;
}; };
/* macro lets you iterate over two diff lists together */
#define GIT_DIFF_COITERATE(A,B,AD,BD,LEFT,RIGHT,BOTH,AFTER) do { \
unsigned int _i = 0, _j = 0; int _cmp; \
while (((A) && _i < (A)->deltas.length) || ((B) && _j < (B)->deltas.length)) { \
(AD) = (A) ? GIT_VECTOR_GET(&(A)->deltas,_i) : NULL; \
(BD) = (B) ? GIT_VECTOR_GET(&(B)->deltas,_j) : NULL; \
_cmp = !(BD) ? -1 : !(AD) ? 1 : strcmp((AD)->old.path,(BD)->old.path); \
if (_cmp < 0) { LEFT; _i++; } \
else if (_cmp > 0) { RIGHT; _j++; } \
else { BOTH; _i++; _j++; } \
AFTER; \
} } while (0)
#endif #endif
...@@ -120,13 +120,14 @@ int git_status_foreach_ext( ...@@ -120,13 +120,14 @@ int git_status_foreach_ext(
int (*cb)(const char *, unsigned int, void *), int (*cb)(const char *, unsigned int, void *),
void *cbdata) void *cbdata)
{ {
int err = 0; int err = 0, cmp;
git_diff_options diffopt; git_diff_options diffopt;
git_diff_list *idx2head = NULL, *wd2idx = NULL; git_diff_list *idx2head = NULL, *wd2idx = NULL;
git_tree *head = NULL; git_tree *head = NULL;
git_status_show_t show = git_status_show_t show =
opts ? opts->show : GIT_STATUS_SHOW_INDEX_AND_WORKDIR; opts ? opts->show : GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
git_diff_delta *i2h, *w2i; git_diff_delta *i2h, *w2i;
unsigned int i, j, i_max, j_max;
assert(show <= GIT_STATUS_SHOW_INDEX_THEN_WORKDIR); assert(show <= GIT_STATUS_SHOW_INDEX_THEN_WORKDIR);
...@@ -158,23 +159,35 @@ int git_status_foreach_ext( ...@@ -158,23 +159,35 @@ int git_status_foreach_ext(
goto cleanup; goto cleanup;
if (show == GIT_STATUS_SHOW_INDEX_THEN_WORKDIR) { if (show == GIT_STATUS_SHOW_INDEX_THEN_WORKDIR) {
git_diff_list *empty = NULL; for (i = 0; !err && i < idx2head->deltas.length; i++) {
GIT_DIFF_COITERATE( i2h = GIT_VECTOR_GET(&idx2head->deltas, i);
idx2head, empty, i2h, w2i, err = cb(i2h->old.path, index_delta2status(i2h->status), cbdata);
err = cb(i2h->old.path, index_delta2status(i2h->status), cbdata), }
/* nothing */, /* nothing */, if (err < 0) break);
git_diff_list_free(idx2head); git_diff_list_free(idx2head);
idx2head = NULL; idx2head = NULL;
} }
GIT_DIFF_COITERATE( i_max = idx2head ? idx2head->deltas.length : 0;
idx2head, wd2idx, i2h, w2i, j_max = wd2idx ? wd2idx->deltas.length : 0;
err = cb(i2h->old.path, index_delta2status(i2h->status), cbdata),
err = cb(w2i->old.path, workdir_delta2status(w2i->status), cbdata), for (i = 0, j = 0; !err && (i < i_max || j < j_max); ) {
err = cb(i2h->old.path, index_delta2status(i2h->status) | i2h = idx2head ? GIT_VECTOR_GET(&idx2head->deltas,i) : NULL;
workdir_delta2status(w2i->status), cbdata), w2i = wd2idx ? GIT_VECTOR_GET(&wd2idx->deltas,j) : NULL;
if (err < 0) break);
cmp = !w2i ? -1 : !i2h ? 1 : strcmp(i2h->old.path, w2i->old.path);
if (cmp < 0) {
err = cb(i2h->old.path, index_delta2status(i2h->status), cbdata);
i++;
} else if (cmp > 0) {
err = cb(w2i->old.path, workdir_delta2status(w2i->status), cbdata);
j++;
} else {
err = cb(i2h->old.path, index_delta2status(i2h->status) |
workdir_delta2status(w2i->status), cbdata);
i++; j++;
}
}
cleanup: cleanup:
git_tree_free(head); git_tree_free(head);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment