Skip to content

Commit de1efea

Browse files
chriscoolgitster
authored andcommitted
promisor-remote: refactor how we parse advertised fields
In a follow up commit we are going to parse more fields, like a filter and a token, coming from the server when it advertises promisor remotes using the "promisor-remote" capability. To prepare for this, let's refactor the code that parses the advertised fields coming from the server into a new parse_one_advertised_remote() function that will populate a `struct promisor_info` with the content of the fields it parsed. While at it, let's also pass this `struct promisor_info` to the should_accept_remote() function, instead of passing it the parsed name and url. These changes will make it simpler to both parse more fields and access the content of these parsed fields in follow up commits. Signed-off-by: Christian Couder <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4e2139c commit de1efea

File tree

1 file changed

+57
-29
lines changed

1 file changed

+57
-29
lines changed

promisor-remote.c

Lines changed: 57 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -405,16 +405,20 @@ struct promisor_info {
405405
const char *token;
406406
};
407407

408+
static void promisor_info_free(struct promisor_info *p)
409+
{
410+
free((char *)p->name);
411+
free((char *)p->url);
412+
free((char *)p->filter);
413+
free((char *)p->token);
414+
free(p);
415+
}
416+
408417
static void promisor_info_list_clear(struct string_list *list)
409418
{
410-
for (size_t i = 0; i < list->nr; i++) {
411-
struct promisor_info *p = list->items[i].util;
412-
free((char *)p->name);
413-
free((char *)p->url);
414-
free((char *)p->filter);
415-
free((char *)p->token);
416-
}
417-
string_list_clear(list, 1);
419+
for (size_t i = 0; i < list->nr; i++)
420+
promisor_info_free(list->items[i].util);
421+
string_list_clear(list, 0);
418422
}
419423

420424
static void set_one_field(struct promisor_info *p,
@@ -531,11 +535,13 @@ enum accept_promisor {
531535
};
532536

533537
static int should_accept_remote(enum accept_promisor accept,
534-
const char *remote_name, const char *remote_url,
538+
struct promisor_info *advertised,
535539
struct string_list *config_info)
536540
{
537541
struct promisor_info *p;
538542
struct string_list_item *item;
543+
const char *remote_name = advertised->name;
544+
const char *remote_url = advertised->url;
539545

540546
if (accept == ACCEPT_ALL)
541547
return 1;
@@ -578,6 +584,41 @@ static int skip_field_name_prefix(const char *elem, const char *field_name, cons
578584
return 1;
579585
}
580586

587+
static struct promisor_info *parse_one_advertised_remote(const char *remote_info)
588+
{
589+
struct promisor_info *info = xcalloc(1, sizeof(*info));
590+
struct string_list elem_list = STRING_LIST_INIT_DUP;
591+
struct string_list_item *item;
592+
593+
string_list_split(&elem_list, remote_info, ",", -1);
594+
595+
for_each_string_list_item(item, &elem_list) {
596+
const char *elem = item->string;
597+
const char *p = strchr(elem, '=');
598+
599+
if (!p) {
600+
warning(_("invalid element '%s' from remote info"), elem);
601+
continue;
602+
}
603+
604+
if (skip_field_name_prefix(elem, promisor_field_name, &p))
605+
info->name = url_percent_decode(p);
606+
else if (skip_field_name_prefix(elem, promisor_field_url, &p))
607+
info->url = url_percent_decode(p);
608+
}
609+
610+
string_list_clear(&elem_list, 0);
611+
612+
if (!info->name || !info->url) {
613+
warning(_("server advertised a promisor remote without a name or URL: %s"),
614+
remote_info);
615+
promisor_info_free(info);
616+
return NULL;
617+
}
618+
619+
return info;
620+
}
621+
581622
static void filter_promisor_remote(struct repository *repo,
582623
struct strvec *accepted,
583624
const char *info)
@@ -614,32 +655,19 @@ static void filter_promisor_remote(struct repository *repo,
614655
remotes = strbuf_split_str(info, ';', 0);
615656

616657
for (size_t i = 0; remotes[i]; i++) {
617-
struct strbuf **elems;
618-
const char *remote_name = NULL;
619-
const char *remote_url = NULL;
620-
char *decoded_name = NULL;
621-
char *decoded_url = NULL;
658+
struct promisor_info *advertised;
622659

623660
strbuf_strip_suffix(remotes[i], ";");
624-
elems = strbuf_split(remotes[i], ',');
625661

626-
for (size_t j = 0; elems[j]; j++) {
627-
strbuf_strip_suffix(elems[j], ",");
628-
if (!skip_field_name_prefix(elems[j]->buf, promisor_field_name, &remote_name))
629-
skip_field_name_prefix(elems[j]->buf, promisor_field_url, &remote_url);
630-
}
662+
advertised = parse_one_advertised_remote(remotes[i]->buf);
631663

632-
if (remote_name)
633-
decoded_name = url_percent_decode(remote_name);
634-
if (remote_url)
635-
decoded_url = url_percent_decode(remote_url);
664+
if (!advertised)
665+
continue;
636666

637-
if (decoded_name && should_accept_remote(accept, decoded_name, decoded_url, &config_info))
638-
strvec_push(accepted, decoded_name);
667+
if (should_accept_remote(accept, advertised, &config_info))
668+
strvec_push(accepted, advertised->name);
639669

640-
strbuf_list_free(elems);
641-
free(decoded_name);
642-
free(decoded_url);
670+
promisor_info_free(advertised);
643671
}
644672

645673
promisor_info_list_clear(&config_info);

0 commit comments

Comments
 (0)