Skip to content

Commit 3f5fade

Browse files
pks-tgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 141766d commit 3f5fade

File tree

3 files changed

+93
-0
lines changed

3 files changed

+93
-0
lines changed

strvec.c

+19
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,25 @@ void strvec_pushv(struct strvec *array, const char **items)
5656
strvec_push(array, *items);
5757
}
5858

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+
5978
const char *strvec_replace(struct strvec *array, size_t idx, const char *replacement)
6079
{
6180
char *to_free;

strvec.h

+9
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,15 @@ void strvec_pushl(struct strvec *, ...);
6767
/* Push a null-terminated array of strings onto the end of the array. */
6868
void strvec_pushv(struct strvec *, const char **);
6969

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+
7079
/**
7180
* Replace the value at the given index with a new value. The index must be
7281
* valid. Returns a pointer to the inserted value.

t/unit-tests/strvec.c

+65
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,71 @@ void test_strvec__pushv(void)
8888
strvec_clear(&vec);
8989
}
9090

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+
91156
void test_strvec__replace_at_head(void)
92157
{
93158
struct strvec vec = STRVEC_INIT;

0 commit comments

Comments
 (0)