list-objects-filter: convert filter_spec to a strbuf

Originally, the filter_spec field was just a string pointer. In cf9ceb5a12 (list-objects-filter-options: make filter_spec a string_list, 2019-06-27) it became a string_list, but that commit notes: A strbuf would seem to be a more natural choice for this object, but it unfortunately requires initialization besides just zero'ing out the memory. This results in all container structs, and all containers of those structs, etc., to also require initialization. Initializing them all would be more cumbersome that simply using a string_list, which behaves properly when its contents are zero'd. Now that we've changed the struct to require non-zero initialization anyway (ironically, because string_list also needed non-zero initialization to avoid leaks), we can now convert to that more natural type. This makes the list_objects_filter_spec() function much less awkward, as it had to collapse the string_list to a single-entry list on the fly. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Sep 11, 2022 at 01:03 UTC c54980ab83661e8e290003fbd5ab44b12e4e77b1
2 files changed +20 -35
list-objects-filter-options.c
+18 -33
@@ -202,10 +202,10 @@ static int allow_unencoded(char ch)
202 static void filter_spec_append_urlencode(
203 struct list_objects_filter_options *filter, const char *raw)
204 {
205 - struct strbuf buf = STRBUF_INIT;
206 - strbuf_addstr_urlencode(&buf, raw, allow_unencoded);
207 - trace_printf("Add to combine filter-spec: %s\n", buf.buf);
208 - string_list_append_nodup(&filter->filter_spec, strbuf_detach(&buf, NULL));
205 + size_t orig_len = filter->filter_spec.len;
206 + strbuf_addstr_urlencode(&filter->filter_spec, raw, allow_unencoded);
207 + trace_printf("Add to combine filter-spec: %s\n",
208 + filter->filter_spec.buf + orig_len);
209 }
210
211 /*
@@ -229,7 +229,7 @@ static void transform_to_combine_type(
229 }
230 filter_options->sub_nr = 1;
231 filter_options->choice = LOFC_COMBINE;
232 - string_list_append(&filter_options->filter_spec, "combine:");
232 + strbuf_addstr(&filter_options->filter_spec, "combine:");
233 filter_spec_append_urlencode(
234 filter_options,
235 list_objects_filter_spec(&filter_options->sub[0]));
@@ -237,7 +237,7 @@ static void transform_to_combine_type(
237 * We don't need the filter_spec strings for subfilter specs, only the
238 * top level.
239 */
240 - string_list_clear(&filter_options->sub[0].filter_spec, /*free_util=*/0);
240 + strbuf_release(&filter_options->sub[0].filter_spec);
241 }
242
243 void list_objects_filter_die_if_populated(
@@ -254,11 +254,11 @@ void parse_list_objects_filter(
254 struct strbuf errbuf = STRBUF_INIT;
255 int parse_error;
256
257 - if (!filter_options->filter_spec.strdup_strings)
257 + if (!filter_options->filter_spec.buf)
258 BUG("filter_options not properly initialized");
259
260 if (!filter_options->choice) {
261 - string_list_append(&filter_options->filter_spec, arg);
261 + strbuf_addstr(&filter_options->filter_spec, arg);
262
263 parse_error = gently_parse_list_objects_filter(
264 filter_options, arg, &errbuf);
@@ -269,7 +269,7 @@ void parse_list_objects_filter(
269 */
270 transform_to_combine_type(filter_options);
271
272 - string_list_append(&filter_options->filter_spec, "+");
272 + strbuf_addch(&filter_options->filter_spec, '+');
273 filter_spec_append_urlencode(filter_options, arg);
274 ALLOC_GROW_BY(filter_options->sub, filter_options->sub_nr, 1,
275 filter_options->sub_alloc);
@@ -300,31 +300,18 @@ int opt_parse_list_objects_filter(const struct option *opt,
300
301 const char *list_objects_filter_spec(struct list_objects_filter_options *filter)
302 {
303 - if (!filter->filter_spec.nr)
303 + if (!filter->filter_spec.len)
304 BUG("no filter_spec available for this filter");
305 - if (filter->filter_spec.nr != 1) {
306 - struct strbuf concatted = STRBUF_INIT;
307 - strbuf_add_separated_string_list(
308 - &concatted, "", &filter->filter_spec);
309 - string_list_clear(&filter->filter_spec, /*free_util=*/0);
310 - string_list_append_nodup(
311 - &filter->filter_spec, strbuf_detach(&concatted, NULL));
312 - }
313 -
314 - return filter->filter_spec.items[0].string;
305 + return filter->filter_spec.buf;
306 }
307
308 const char *expand_list_objects_filter_spec(
309 struct list_objects_filter_options *filter)
310 {
311 if (filter->choice == LOFC_BLOB_LIMIT) {
321 - struct strbuf expanded_spec = STRBUF_INIT;
322 - strbuf_addf(&expanded_spec, "blob:limit=%lu",
312 + strbuf_release(&filter->filter_spec);
313 + strbuf_addf(&filter->filter_spec, "blob:limit=%lu",
314 filter->blob_limit_value);
324 - string_list_clear(&filter->filter_spec, /*free_util=*/0);
325 - string_list_append_nodup(
326 - &filter->filter_spec,
327 - strbuf_detach(&expanded_spec, NULL));
315 }
316
317 return list_objects_filter_spec(filter);
@@ -337,7 +324,7 @@ void list_objects_filter_release(
324
325 if (!filter_options)
326 return;
340 - string_list_clear(&filter_options->filter_spec, /*free_util=*/0);
327 + strbuf_release(&filter_options->filter_spec);
328 free(filter_options->sparse_oid_name);
329 for (sub = 0; sub < filter_options->sub_nr; sub++)
330 list_objects_filter_release(&filter_options->sub[sub]);
@@ -398,8 +385,8 @@ void partial_clone_get_default_filter_spec(
385 if (!promisor || !promisor->partial_clone_filter)
386 return;
387
401 - string_list_append(&filter_options->filter_spec,
402 - promisor->partial_clone_filter);
388 + strbuf_addstr(&filter_options->filter_spec,
389 + promisor->partial_clone_filter);
390 gently_parse_list_objects_filter(filter_options,
391 promisor->partial_clone_filter,
392 &errbuf);
@@ -411,14 +398,12 @@ void list_objects_filter_copy(
398 const struct list_objects_filter_options *src)
399 {
400 int i;
414 - struct string_list_item *item;
401
402 /* Copy everything. We will overwrite the pointers shortly. */
403 memcpy(dest, src, sizeof(struct list_objects_filter_options));
404
419 - string_list_init_dup(&dest->filter_spec);
420 - for_each_string_list_item(item, &src->filter_spec)
421 - string_list_append(&dest->filter_spec, item->string);
405 + strbuf_init(&dest->filter_spec, 0);
406 + strbuf_addbuf(&dest->filter_spec, &src->filter_spec);
407 dest->sparse_oid_name = xstrdup_or_null(src->sparse_oid_name);
408
409 ALLOC_ARRAY(dest->sub, dest->sub_alloc);
list-objects-filter-options.h
+2 -2
@@ -35,7 +35,7 @@ struct list_objects_filter_options {
35 * To get the raw filter spec given by the user, use the result of
36 * list_objects_filter_spec().
37 */
38 - struct string_list filter_spec;
38 + struct strbuf filter_spec;
39
40 /*
41 * 'choice' is determined by parsing the filter-spec. This indicates
@@ -69,7 +69,7 @@ struct list_objects_filter_options {
69 */
70 };
71
72 -#define LIST_OBJECTS_FILTER_INIT { .filter_spec = STRING_LIST_INIT_DUP }
72 +#define LIST_OBJECTS_FILTER_INIT { .filter_spec = STRBUF_INIT }
73 void list_objects_filter_init(struct list_objects_filter_options *filter_options);
74
75 /*