From 1db12b00532d747fa7a805a8fa8d293c58ec16d9 Mon Sep 17 00:00:00 2001 From: Russell Belfer Date: Sun, 25 Mar 2012 23:04:26 -0700 Subject: [PATCH] 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. --- src/diff.c | 36 ++++++++++++++++++++++++++---------- src/diff.h | 14 -------------- src/status.c | 41 +++++++++++++++++++++++++++-------------- 3 files changed, 53 insertions(+), 38 deletions(-) diff --git a/src/diff.c b/src/diff.c index d5a841c3b..e1016db05 100644 --- a/src/diff.c +++ b/src/diff.c @@ -565,23 +565,39 @@ int git_diff_merge( { int error = 0; git_vector onto_new; - git_diff_delta *delta, *o; - const git_diff_delta *f; - unsigned int i; + git_diff_delta *delta; + unsigned int i, j; + + assert(onto && from); + + if (!from->deltas.length) + return 0; if (git_vector_init(&onto_new, onto->deltas.length, diff_delta__cmp) < 0) return -1; - GIT_DIFF_COITERATE( - onto, from, o, f, - delta = diff_delta__dup(o), - delta = diff_delta__dup(f), - delta = diff_delta__merge_like_cgit(o, f), + for (i = 0, j = 0; i < onto->deltas.length || j < from->deltas.length; ) { + git_diff_delta *o = GIT_VECTOR_GET(&onto->deltas, i); + const git_diff_delta *f = GIT_VECTOR_GET(&from->deltas, j); + int cmp = !f ? -1 : !o ? 1 : strcmp(o->old.path, f->old.path); + + 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) break; - ); + } - if (error == 0) { + if (!error) { git_vector_swap(&onto->deltas, &onto_new); onto->new_src = from->new_src; } diff --git a/src/diff.h b/src/diff.h index 058a1f5e8..7d69199ea 100644 --- a/src/diff.h +++ b/src/diff.h @@ -21,19 +21,5 @@ struct git_diff_list { 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 diff --git a/src/status.c b/src/status.c index bec75294f..88dd5e03b 100644 --- a/src/status.c +++ b/src/status.c @@ -120,13 +120,14 @@ int git_status_foreach_ext( int (*cb)(const char *, unsigned int, void *), void *cbdata) { - int err = 0; + int err = 0, cmp; git_diff_options diffopt; git_diff_list *idx2head = NULL, *wd2idx = NULL; git_tree *head = NULL; git_status_show_t show = opts ? opts->show : GIT_STATUS_SHOW_INDEX_AND_WORKDIR; git_diff_delta *i2h, *w2i; + unsigned int i, j, i_max, j_max; assert(show <= GIT_STATUS_SHOW_INDEX_THEN_WORKDIR); @@ -158,23 +159,35 @@ int git_status_foreach_ext( goto cleanup; if (show == GIT_STATUS_SHOW_INDEX_THEN_WORKDIR) { - git_diff_list *empty = NULL; - GIT_DIFF_COITERATE( - idx2head, empty, i2h, w2i, - err = cb(i2h->old.path, index_delta2status(i2h->status), cbdata), - /* nothing */, /* nothing */, if (err < 0) break); - + for (i = 0; !err && i < idx2head->deltas.length; i++) { + i2h = GIT_VECTOR_GET(&idx2head->deltas, i); + err = cb(i2h->old.path, index_delta2status(i2h->status), cbdata); + } git_diff_list_free(idx2head); idx2head = NULL; } - GIT_DIFF_COITERATE( - idx2head, wd2idx, i2h, w2i, - err = cb(i2h->old.path, index_delta2status(i2h->status), cbdata), - err = cb(w2i->old.path, workdir_delta2status(w2i->status), cbdata), - err = cb(i2h->old.path, index_delta2status(i2h->status) | - workdir_delta2status(w2i->status), cbdata), - if (err < 0) break); + i_max = idx2head ? idx2head->deltas.length : 0; + j_max = wd2idx ? wd2idx->deltas.length : 0; + + for (i = 0, j = 0; !err && (i < i_max || j < j_max); ) { + i2h = idx2head ? GIT_VECTOR_GET(&idx2head->deltas,i) : NULL; + w2i = wd2idx ? GIT_VECTOR_GET(&wd2idx->deltas,j) : NULL; + + 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: git_tree_free(head);