* Handle exclude patterns. Returns either `1`, which tells the caller that the * current reference shall not be shown. Or `0`, which indicates that it should * be shown. */
| 541 | * be shown. |
| 542 | */ |
| 543 | static int should_exclude_current_ref(struct reftable_ref_iterator *iter) |
| 544 | { |
| 545 | while (iter->exclude_patterns[iter->exclude_patterns_index]) { |
| 546 | const char *pattern = iter->exclude_patterns[iter->exclude_patterns_index]; |
| 547 | char *ref_after_pattern; |
| 548 | int cmp; |
| 549 | |
| 550 | /* |
| 551 | * Lazily cache the pattern length so that we don't have to |
| 552 | * recompute it every time this function is called. |
| 553 | */ |
| 554 | if (!iter->exclude_patterns_strlen) |
| 555 | iter->exclude_patterns_strlen = strlen(pattern); |
| 556 | |
| 557 | /* |
| 558 | * When the reference name is lexicographically bigger than the |
| 559 | * current exclude pattern we know that it won't ever match any |
| 560 | * of the following references, either. We thus advance to the |
| 561 | * next pattern and re-check whether it matches. |
| 562 | * |
| 563 | * Otherwise, if it's smaller, then we do not have a match and |
| 564 | * thus want to show the current reference. |
| 565 | */ |
| 566 | cmp = strncmp(iter->ref.refname, pattern, |
| 567 | iter->exclude_patterns_strlen); |
| 568 | if (cmp > 0) { |
| 569 | iter->exclude_patterns_index++; |
| 570 | iter->exclude_patterns_strlen = 0; |
| 571 | continue; |
| 572 | } |
| 573 | if (cmp < 0) |
| 574 | return 0; |
| 575 | |
| 576 | /* |
| 577 | * The reference shares a prefix with the exclude pattern and |
| 578 | * shall thus be omitted. We skip all references that match the |
| 579 | * pattern by seeking to the first reference after the block of |
| 580 | * matches. |
| 581 | * |
| 582 | * This is done by appending the highest possible character to |
| 583 | * the pattern. Consequently, all references that have the |
| 584 | * pattern as prefix and whose suffix starts with anything in |
| 585 | * the range [0x00, 0xfe] are skipped. And given that 0xff is a |
| 586 | * non-printable character that shouldn't ever be in a ref name, |
| 587 | * we'd not yield any such record, either. |
| 588 | * |
| 589 | * Note that the seeked-to reference may also be excluded. This |
| 590 | * is not handled here though, but the caller is expected to |
| 591 | * loop and re-verify the next reference for us. |
| 592 | */ |
| 593 | ref_after_pattern = xstrfmt("%s%c", pattern, 0xff); |
| 594 | iter->err = reftable_iterator_seek_ref(&iter->iter, ref_after_pattern); |
| 595 | iter->exclude_patterns_index++; |
| 596 | iter->exclude_patterns_strlen = 0; |
| 597 | trace2_counter_add(TRACE2_COUNTER_ID_REFTABLE_RESEEKS, 1); |
| 598 | |
| 599 | free(ref_after_pattern); |
| 600 | return 1; |
no test coverage detected