2  * Generic reference iterator infrastructure. See refs-internal.h for
 
   3  * documentation about the design and use of reference iterators.
 
   8 #include "refs/refs-internal.h"
 
  11 int ref_iterator_advance(struct ref_iterator *ref_iterator)
 
  13         return ref_iterator->vtable->advance(ref_iterator);
 
  16 int ref_iterator_peel(struct ref_iterator *ref_iterator,
 
  17                       struct object_id *peeled)
 
  19         return ref_iterator->vtable->peel(ref_iterator, peeled);
 
  22 int ref_iterator_abort(struct ref_iterator *ref_iterator)
 
  24         return ref_iterator->vtable->abort(ref_iterator);
 
  27 void base_ref_iterator_init(struct ref_iterator *iter,
 
  28                             struct ref_iterator_vtable *vtable,
 
  31         iter->vtable = vtable;
 
  32         iter->ordered = !!ordered;
 
  38 void base_ref_iterator_free(struct ref_iterator *iter)
 
  40         /* Help make use-after-free bugs fail quickly: */
 
  45 struct empty_ref_iterator {
 
  46         struct ref_iterator base;
 
  49 static int empty_ref_iterator_advance(struct ref_iterator *ref_iterator)
 
  51         return ref_iterator_abort(ref_iterator);
 
  54 static int empty_ref_iterator_peel(struct ref_iterator *ref_iterator,
 
  55                                    struct object_id *peeled)
 
  57         BUG("peel called for empty iterator");
 
  60 static int empty_ref_iterator_abort(struct ref_iterator *ref_iterator)
 
  62         base_ref_iterator_free(ref_iterator);
 
  66 static struct ref_iterator_vtable empty_ref_iterator_vtable = {
 
  67         empty_ref_iterator_advance,
 
  68         empty_ref_iterator_peel,
 
  69         empty_ref_iterator_abort
 
  72 struct ref_iterator *empty_ref_iterator_begin(void)
 
  74         struct empty_ref_iterator *iter = xcalloc(1, sizeof(*iter));
 
  75         struct ref_iterator *ref_iterator = &iter->base;
 
  77         base_ref_iterator_init(ref_iterator, &empty_ref_iterator_vtable, 1);
 
  81 int is_empty_ref_iterator(struct ref_iterator *ref_iterator)
 
  83         return ref_iterator->vtable == &empty_ref_iterator_vtable;
 
  86 struct merge_ref_iterator {
 
  87         struct ref_iterator base;
 
  89         struct ref_iterator *iter0, *iter1;
 
  91         ref_iterator_select_fn *select;
 
  95          * A pointer to iter0 or iter1 (whichever is supplying the
 
  96          * current value), or NULL if advance has not yet been called.
 
  98         struct ref_iterator **current;
 
 101 static int merge_ref_iterator_advance(struct ref_iterator *ref_iterator)
 
 103         struct merge_ref_iterator *iter =
 
 104                 (struct merge_ref_iterator *)ref_iterator;
 
 107         if (!iter->current) {
 
 108                 /* Initialize: advance both iterators to their first entries */
 
 109                 if ((ok = ref_iterator_advance(iter->iter0)) != ITER_OK) {
 
 111                         if (ok == ITER_ERROR)
 
 114                 if ((ok = ref_iterator_advance(iter->iter1)) != ITER_OK) {
 
 116                         if (ok == ITER_ERROR)
 
 121                  * Advance the current iterator past the just-used
 
 124                 if ((ok = ref_iterator_advance(*iter->current)) != ITER_OK) {
 
 125                         *iter->current = NULL;
 
 126                         if (ok == ITER_ERROR)
 
 131         /* Loop until we find an entry that we can yield. */
 
 133                 struct ref_iterator **secondary;
 
 134                 enum iterator_selection selection =
 
 135                         iter->select(iter->iter0, iter->iter1, iter->cb_data);
 
 137                 if (selection == ITER_SELECT_DONE) {
 
 138                         return ref_iterator_abort(ref_iterator);
 
 139                 } else if (selection == ITER_SELECT_ERROR) {
 
 140                         ref_iterator_abort(ref_iterator);
 
 144                 if ((selection & ITER_CURRENT_SELECTION_MASK) == 0) {
 
 145                         iter->current = &iter->iter0;
 
 146                         secondary = &iter->iter1;
 
 148                         iter->current = &iter->iter1;
 
 149                         secondary = &iter->iter0;
 
 152                 if (selection & ITER_SKIP_SECONDARY) {
 
 153                         if ((ok = ref_iterator_advance(*secondary)) != ITER_OK) {
 
 155                                 if (ok == ITER_ERROR)
 
 160                 if (selection & ITER_YIELD_CURRENT) {
 
 161                         iter->base.refname = (*iter->current)->refname;
 
 162                         iter->base.oid = (*iter->current)->oid;
 
 163                         iter->base.flags = (*iter->current)->flags;
 
 169         ref_iterator_abort(ref_iterator);
 
 173 static int merge_ref_iterator_peel(struct ref_iterator *ref_iterator,
 
 174                                    struct object_id *peeled)
 
 176         struct merge_ref_iterator *iter =
 
 177                 (struct merge_ref_iterator *)ref_iterator;
 
 179         if (!iter->current) {
 
 180                 BUG("peel called before advance for merge iterator");
 
 182         return ref_iterator_peel(*iter->current, peeled);
 
 185 static int merge_ref_iterator_abort(struct ref_iterator *ref_iterator)
 
 187         struct merge_ref_iterator *iter =
 
 188                 (struct merge_ref_iterator *)ref_iterator;
 
 192                 if (ref_iterator_abort(iter->iter0) != ITER_DONE)
 
 196                 if (ref_iterator_abort(iter->iter1) != ITER_DONE)
 
 199         base_ref_iterator_free(ref_iterator);
 
 203 static struct ref_iterator_vtable merge_ref_iterator_vtable = {
 
 204         merge_ref_iterator_advance,
 
 205         merge_ref_iterator_peel,
 
 206         merge_ref_iterator_abort
 
 209 struct ref_iterator *merge_ref_iterator_begin(
 
 211                 struct ref_iterator *iter0, struct ref_iterator *iter1,
 
 212                 ref_iterator_select_fn *select, void *cb_data)
 
 214         struct merge_ref_iterator *iter = xcalloc(1, sizeof(*iter));
 
 215         struct ref_iterator *ref_iterator = &iter->base;
 
 218          * We can't do the same kind of is_empty_ref_iterator()-style
 
 219          * optimization here as overlay_ref_iterator_begin() does,
 
 220          * because we don't know the semantics of the select function.
 
 221          * It might, for example, implement "intersect" by passing
 
 222          * references through only if they exist in both iterators.
 
 225         base_ref_iterator_init(ref_iterator, &merge_ref_iterator_vtable, ordered);
 
 228         iter->select = select;
 
 229         iter->cb_data = cb_data;
 
 230         iter->current = NULL;
 
 235  * A ref_iterator_select_fn that overlays the items from front on top
 
 236  * of those from back (like loose refs over packed refs). See
 
 237  * overlay_ref_iterator_begin().
 
 239 static enum iterator_selection overlay_iterator_select(
 
 240                 struct ref_iterator *front, struct ref_iterator *back,
 
 246                 return front ? ITER_SELECT_0 : ITER_SELECT_DONE;
 
 248                 return ITER_SELECT_1;
 
 250         cmp = strcmp(front->refname, back->refname);
 
 253                 return ITER_SELECT_0;
 
 255                 return ITER_SELECT_1;
 
 257                 return ITER_SELECT_0_SKIP_1;
 
 260 struct ref_iterator *overlay_ref_iterator_begin(
 
 261                 struct ref_iterator *front, struct ref_iterator *back)
 
 264          * Optimization: if one of the iterators is empty, return the
 
 265          * other one rather than incurring the overhead of wrapping
 
 268         if (is_empty_ref_iterator(front)) {
 
 269                 ref_iterator_abort(front);
 
 271         } else if (is_empty_ref_iterator(back)) {
 
 272                 ref_iterator_abort(back);
 
 274         } else if (!front->ordered || !back->ordered) {
 
 275                 BUG("overlay_ref_iterator requires ordered inputs");
 
 278         return merge_ref_iterator_begin(1, front, back,
 
 279                                         overlay_iterator_select, NULL);
 
 282 struct prefix_ref_iterator {
 
 283         struct ref_iterator base;
 
 285         struct ref_iterator *iter0;
 
 290 /* Return -1, 0, 1 if refname is before, inside, or after the prefix. */
 
 291 static int compare_prefix(const char *refname, const char *prefix)
 
 294                 if (*refname != *prefix)
 
 295                         return ((unsigned char)*refname < (unsigned char)*prefix) ? -1 : +1;
 
 304 static int prefix_ref_iterator_advance(struct ref_iterator *ref_iterator)
 
 306         struct prefix_ref_iterator *iter =
 
 307                 (struct prefix_ref_iterator *)ref_iterator;
 
 310         while ((ok = ref_iterator_advance(iter->iter0)) == ITER_OK) {
 
 311                 int cmp = compare_prefix(iter->iter0->refname, iter->prefix);
 
 318                          * If the source iterator is ordered, then we
 
 319                          * can stop the iteration as soon as we see a
 
 320                          * refname that comes after the prefix:
 
 322                         if (iter->iter0->ordered) {
 
 323                                 ok = ref_iterator_abort(iter->iter0);
 
 332                          * It is nonsense to trim off characters that
 
 333                          * you haven't already checked for via a
 
 334                          * prefix check, whether via this
 
 335                          * `prefix_ref_iterator` or upstream in
 
 336                          * `iter0`). So if there wouldn't be at least
 
 337                          * one character left in the refname after
 
 338                          * trimming, report it as a bug:
 
 340                         if (strlen(iter->iter0->refname) <= iter->trim)
 
 341                                 BUG("attempt to trim too many characters");
 
 342                         iter->base.refname = iter->iter0->refname + iter->trim;
 
 344                         iter->base.refname = iter->iter0->refname;
 
 347                 iter->base.oid = iter->iter0->oid;
 
 348                 iter->base.flags = iter->iter0->flags;
 
 353         if (ref_iterator_abort(ref_iterator) != ITER_DONE)
 
 358 static int prefix_ref_iterator_peel(struct ref_iterator *ref_iterator,
 
 359                                     struct object_id *peeled)
 
 361         struct prefix_ref_iterator *iter =
 
 362                 (struct prefix_ref_iterator *)ref_iterator;
 
 364         return ref_iterator_peel(iter->iter0, peeled);
 
 367 static int prefix_ref_iterator_abort(struct ref_iterator *ref_iterator)
 
 369         struct prefix_ref_iterator *iter =
 
 370                 (struct prefix_ref_iterator *)ref_iterator;
 
 374                 ok = ref_iterator_abort(iter->iter0);
 
 376         base_ref_iterator_free(ref_iterator);
 
 380 static struct ref_iterator_vtable prefix_ref_iterator_vtable = {
 
 381         prefix_ref_iterator_advance,
 
 382         prefix_ref_iterator_peel,
 
 383         prefix_ref_iterator_abort
 
 386 struct ref_iterator *prefix_ref_iterator_begin(struct ref_iterator *iter0,
 
 390         struct prefix_ref_iterator *iter;
 
 391         struct ref_iterator *ref_iterator;
 
 393         if (!*prefix && !trim)
 
 394                 return iter0; /* optimization: no need to wrap iterator */
 
 396         iter = xcalloc(1, sizeof(*iter));
 
 397         ref_iterator = &iter->base;
 
 399         base_ref_iterator_init(ref_iterator, &prefix_ref_iterator_vtable, iter0->ordered);
 
 402         iter->prefix = xstrdup(prefix);
 
 408 struct ref_iterator *current_ref_iter = NULL;
 
 410 int do_for_each_repo_ref_iterator(struct repository *r, struct ref_iterator *iter,
 
 411                                   each_repo_ref_fn fn, void *cb_data)
 
 414         struct ref_iterator *old_ref_iter = current_ref_iter;
 
 416         current_ref_iter = iter;
 
 417         while ((ok = ref_iterator_advance(iter)) == ITER_OK) {
 
 418                 retval = fn(r, iter->refname, iter->oid, iter->flags, cb_data);
 
 421                          * If ref_iterator_abort() returns ITER_ERROR,
 
 422                          * we ignore that error in deference to the
 
 423                          * callback function's return value.
 
 425                         ref_iterator_abort(iter);
 
 431         current_ref_iter = old_ref_iter;
 
 432         if (ok == ITER_ERROR)