Git fork

strvec: introduce new `strvec_splice()` function

Introduce a new `strvec_splice()` function that can replace a range of
strings in the vector with another array of strings. This function will
be used in subsequent commits.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Patrick Steinhardt and committed by
Junio C Hamano
3f5fadef 141766d1

+93
+19
strvec.c
··· 56 56 strvec_push(array, *items); 57 57 } 58 58 59 + void strvec_splice(struct strvec *array, size_t idx, size_t len, 60 + const char **replacement, size_t replacement_len) 61 + { 62 + if (idx + len > array->nr) 63 + BUG("range outside of array boundary"); 64 + if (replacement_len > len) 65 + ALLOC_GROW(array->v, array->nr + (replacement_len - len) + 1, 66 + array->alloc); 67 + for (size_t i = 0; i < len; i++) 68 + free((char *)array->v[idx + i]); 69 + if (replacement_len != len) { 70 + memmove(array->v + idx + replacement_len, array->v + idx + len, 71 + (array->nr - idx - len + 1) * sizeof(char *)); 72 + array->nr += (replacement_len - len); 73 + } 74 + for (size_t i = 0; i < replacement_len; i++) 75 + array->v[idx + i] = xstrdup(replacement[i]); 76 + } 77 + 59 78 const char *strvec_replace(struct strvec *array, size_t idx, const char *replacement) 60 79 { 61 80 char *to_free;
+9
strvec.h
··· 67 67 /* Push a null-terminated array of strings onto the end of the array. */ 68 68 void strvec_pushv(struct strvec *, const char **); 69 69 70 + /* 71 + * Replace `len` values starting at `idx` with the provided replacement 72 + * strings. If `len` is zero this is effectively an insert at the given `idx`. 73 + * If `replacement_len` is zero this is effectively a delete of `len` items 74 + * starting at `idx`. 75 + */ 76 + void strvec_splice(struct strvec *array, size_t idx, size_t len, 77 + const char **replacement, size_t replacement_len); 78 + 70 79 /** 71 80 * Replace the value at the given index with a new value. The index must be 72 81 * valid. Returns a pointer to the inserted value.
+65
t/unit-tests/strvec.c
··· 88 88 strvec_clear(&vec); 89 89 } 90 90 91 + void test_strvec__splice_with_same_size_replacement(void) 92 + { 93 + struct strvec vec = STRVEC_INIT; 94 + const char *replacement[] = { "1" }; 95 + 96 + strvec_pushl(&vec, "foo", "bar", "baz", NULL); 97 + strvec_splice(&vec, 1, 1, replacement, ARRAY_SIZE(replacement)); 98 + check_strvec(&vec, "foo", "1", "baz", NULL); 99 + strvec_clear(&vec); 100 + } 101 + 102 + void test_strvec__splice_with_smaller_replacement(void) 103 + { 104 + struct strvec vec = STRVEC_INIT; 105 + const char *replacement[] = { "1" }; 106 + 107 + strvec_pushl(&vec, "foo", "bar", "baz", NULL); 108 + strvec_splice(&vec, 1, 2, replacement, ARRAY_SIZE(replacement)); 109 + check_strvec(&vec, "foo", "1", NULL); 110 + strvec_clear(&vec); 111 + } 112 + 113 + void test_strvec__splice_with_bigger_replacement(void) 114 + { 115 + struct strvec vec = STRVEC_INIT; 116 + const char *replacement[] = { "1", "2", "3" }; 117 + 118 + strvec_pushl(&vec, "foo", "bar", "baz", NULL); 119 + strvec_splice(&vec, 0, 2, replacement, ARRAY_SIZE(replacement)); 120 + check_strvec(&vec, "1", "2", "3", "baz", NULL); 121 + strvec_clear(&vec); 122 + } 123 + 124 + void test_strvec__splice_with_empty_replacement(void) 125 + { 126 + struct strvec vec = STRVEC_INIT; 127 + 128 + strvec_pushl(&vec, "foo", "bar", "baz", NULL); 129 + strvec_splice(&vec, 0, 2, NULL, 0); 130 + check_strvec(&vec, "baz", NULL); 131 + strvec_clear(&vec); 132 + } 133 + 134 + void test_strvec__splice_with_empty_original(void) 135 + { 136 + struct strvec vec = STRVEC_INIT; 137 + const char *replacement[] = { "1", "2" }; 138 + 139 + strvec_pushl(&vec, "foo", "bar", "baz", NULL); 140 + strvec_splice(&vec, 1, 0, replacement, ARRAY_SIZE(replacement)); 141 + check_strvec(&vec, "foo", "1", "2", "bar", "baz", NULL); 142 + strvec_clear(&vec); 143 + } 144 + 145 + void test_strvec__splice_at_tail(void) 146 + { 147 + struct strvec vec = STRVEC_INIT; 148 + const char *replacement[] = { "1", "2" }; 149 + 150 + strvec_pushl(&vec, "foo", "bar", NULL); 151 + strvec_splice(&vec, 2, 0, replacement, ARRAY_SIZE(replacement)); 152 + check_strvec(&vec, "foo", "bar", "1", "2", NULL); 153 + strvec_clear(&vec); 154 + } 155 + 91 156 void test_strvec__replace_at_head(void) 92 157 { 93 158 struct strvec vec = STRVEC_INIT;