Skip to content

Commit c4737fd

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 0bece2a commit c4737fd

File tree

1 file changed

+63
-29
lines changed

1 file changed

+63
-29
lines changed

promisor-remote.c

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

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

419423
static void set_one_field(struct promisor_info *p,
@@ -530,11 +534,13 @@ enum accept_promisor {
530534
};
531535

532536
static int should_accept_remote(enum accept_promisor accept,
533-
const char *remote_name, const char *remote_url,
537+
struct promisor_info *advertised,
534538
struct string_list *config_info)
535539
{
536540
struct promisor_info *p;
537541
struct string_list_item *item;
542+
const char *remote_name = advertised->name;
543+
const char *remote_url = advertised->url;
538544

539545
if (accept == ACCEPT_ALL)
540546
return 1;
@@ -568,6 +574,47 @@ static int should_accept_remote(enum accept_promisor accept,
568574
return 0;
569575
}
570576

577+
static struct promisor_info *parse_one_advertised_remote(struct strbuf *remote_info)
578+
{
579+
struct promisor_info *info = xcalloc(1, sizeof(*info));
580+
struct string_list elem_list = STRING_LIST_INIT_NODUP;
581+
struct string_list_item *item;
582+
583+
string_list_split_in_place(&elem_list, remote_info->buf, ",", -1);
584+
585+
for_each_string_list_item(item, &elem_list) {
586+
char *elem = item->string;
587+
char *value;
588+
char *p = strchr(elem, '=');
589+
590+
if (!p) {
591+
warning(_("invalid element '%s' from remote info"), elem);
592+
continue;
593+
}
594+
595+
*p = '\0';
596+
value = url_percent_decode(p + 1);
597+
598+
if (!strcmp(elem, "name"))
599+
info->name = value;
600+
else if (!strcmp(elem, "url"))
601+
info->url = value;
602+
else
603+
free(value);
604+
}
605+
606+
string_list_clear(&elem_list, 0);
607+
608+
if (!info->name || !info->url) {
609+
warning(_("server advertised a promisor remote without a name or URL: %s"),
610+
remote_info->buf);
611+
promisor_info_free(info);
612+
return NULL;
613+
}
614+
615+
return info;
616+
}
617+
571618
static void filter_promisor_remote(struct repository *repo,
572619
struct strvec *accepted,
573620
const char *info)
@@ -604,32 +651,19 @@ static void filter_promisor_remote(struct repository *repo,
604651
remotes = strbuf_split_str(info, ';', 0);
605652

606653
for (size_t i = 0; remotes[i]; i++) {
607-
struct strbuf **elems;
608-
const char *remote_name = NULL;
609-
const char *remote_url = NULL;
610-
char *decoded_name = NULL;
611-
char *decoded_url = NULL;
654+
struct promisor_info *advertised;
612655

613656
strbuf_strip_suffix(remotes[i], ";");
614-
elems = strbuf_split(remotes[i], ',');
615657

616-
for (size_t j = 0; elems[j]; j++) {
617-
strbuf_strip_suffix(elems[j], ",");
618-
if (!skip_prefix(elems[j]->buf, "name=", &remote_name))
619-
skip_prefix(elems[j]->buf, "url=", &remote_url);
620-
}
658+
advertised = parse_one_advertised_remote(remotes[i]);
621659

622-
if (remote_name)
623-
decoded_name = url_percent_decode(remote_name);
624-
if (remote_url)
625-
decoded_url = url_percent_decode(remote_url);
660+
if (!advertised)
661+
continue;
626662

627-
if (decoded_name && should_accept_remote(accept, decoded_name, decoded_url, &config_info))
628-
strvec_push(accepted, decoded_name);
663+
if (should_accept_remote(accept, advertised, &config_info))
664+
strvec_push(accepted, advertised->name);
629665

630-
strbuf_list_free(elems);
631-
free(decoded_name);
632-
free(decoded_url);
666+
promisor_info_free(advertised);
633667
}
634668

635669
promisor_info_list_clear(&config_info);

0 commit comments

Comments
 (0)