| 379 | }; |
| 380 | |
| 381 | static int cache_ref_iterator_advance(struct ref_iterator *ref_iterator) |
| 382 | { |
| 383 | struct cache_ref_iterator *iter = |
| 384 | (struct cache_ref_iterator *)ref_iterator; |
| 385 | |
| 386 | if (!iter->levels_nr) |
| 387 | return ITER_DONE; |
| 388 | |
| 389 | while (1) { |
| 390 | struct cache_ref_iterator_level *level = |
| 391 | &iter->levels[iter->levels_nr - 1]; |
| 392 | struct ref_dir *dir = level->dir; |
| 393 | struct ref_entry *entry; |
| 394 | enum prefix_state entry_prefix_state; |
| 395 | |
| 396 | if (level->index == -1) |
| 397 | sort_ref_dir(dir); |
| 398 | |
| 399 | if (++level->index == level->dir->nr) { |
| 400 | /* This level is exhausted; pop up a level */ |
| 401 | if (--iter->levels_nr == 0) |
| 402 | return ITER_DONE; |
| 403 | |
| 404 | continue; |
| 405 | } |
| 406 | |
| 407 | entry = dir->entries[level->index]; |
| 408 | |
| 409 | if (level->prefix_state == PREFIX_WITHIN_DIR) { |
| 410 | entry_prefix_state = overlaps_prefix(entry->name, iter->prefix); |
| 411 | if (entry_prefix_state == PREFIX_EXCLUDES_DIR || |
| 412 | (entry_prefix_state == PREFIX_WITHIN_DIR && !(entry->flag & REF_DIR))) |
| 413 | continue; |
| 414 | } else { |
| 415 | entry_prefix_state = level->prefix_state; |
| 416 | } |
| 417 | |
| 418 | if (entry->flag & REF_DIR) { |
| 419 | /* push down a level */ |
| 420 | ALLOC_GROW(iter->levels, iter->levels_nr + 1, |
| 421 | iter->levels_alloc); |
| 422 | |
| 423 | level = &iter->levels[iter->levels_nr++]; |
| 424 | level->dir = get_ref_dir(entry); |
| 425 | level->prefix_state = entry_prefix_state; |
| 426 | level->index = -1; |
| 427 | } else { |
| 428 | memset(&iter->base.ref, 0, sizeof(iter->base.ref)); |
| 429 | iter->base.ref.name = entry->name; |
| 430 | iter->base.ref.target = entry->u.value.referent; |
| 431 | iter->base.ref.oid = &entry->u.value.oid; |
| 432 | iter->base.ref.flags = entry->flag; |
| 433 | return ITER_OK; |
| 434 | } |
| 435 | } |
| 436 | } |
| 437 | |
| 438 | static int cache_ref_iterator_set_prefix(struct cache_ref_iterator *iter, |
nothing calls this directly
no test coverage detected