Skip to content

Commit 6f37df2

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 f1fc34c commit 6f37df2

File tree

1 file changed

+62
-29
lines changed

1 file changed

+62
-29
lines changed

promisor-remote.c

Lines changed: 62 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -398,16 +398,20 @@ struct promisor_info {
398398
const char *token;
399399
};
400400

401+
static void promisor_info_free(struct promisor_info *p)
402+
{
403+
free((char *)p->name);
404+
free((char *)p->url);
405+
free((char *)p->filter);
406+
free((char *)p->token);
407+
free(p);
408+
}
409+
401410
static void promisor_info_list_clear(struct string_list *list)
402411
{
403-
for (size_t i = 0; i < list->nr; i++) {
404-
struct promisor_info *p = list->items[i].util;
405-
free((char *)p->name);
406-
free((char *)p->url);
407-
free((char *)p->filter);
408-
free((char *)p->token);
409-
}
410-
string_list_clear(list, 1);
412+
for (size_t i = 0; i < list->nr; i++)
413+
promisor_info_free(list->items[i].util);
414+
string_list_clear(list, 0);
411415
}
412416

413417
static void set_one_field(struct promisor_info *p,
@@ -524,11 +528,13 @@ enum accept_promisor {
524528
};
525529

526530
static int should_accept_remote(enum accept_promisor accept,
527-
const char *remote_name, const char *remote_url,
531+
struct promisor_info *advertised,
528532
struct string_list *config_info)
529533
{
530534
struct promisor_info *p;
531535
struct string_list_item *item;
536+
const char *remote_name = advertised->name;
537+
const char *remote_url = advertised->url;
532538

533539
if (accept == ACCEPT_ALL)
534540
return 1;
@@ -566,6 +572,46 @@ static int should_accept_remote(enum accept_promisor accept,
566572
return 0;
567573
}
568574

575+
static struct promisor_info *parse_one_advertised_remote(struct strbuf *remote_info)
576+
{
577+
struct promisor_info *info = xcalloc(1, sizeof(*info));
578+
struct strbuf **elems = strbuf_split(remote_info, ',');
579+
580+
for (size_t i = 0; elems[i]; i++) {
581+
char *elem = elems[i]->buf;
582+
char *value;
583+
char *p = strchr(elem, '=');
584+
585+
strbuf_strip_suffix(elems[i], ",");
586+
587+
if (!p) {
588+
warning(_("invalid element '%s' from remote info"), elem);
589+
continue;
590+
}
591+
592+
*p = '\0';
593+
value = url_percent_decode(p + 1);
594+
595+
if (!strcmp(elem, "name"))
596+
info->name = value;
597+
else if (!strcmp(elem, "url"))
598+
info->url = value;
599+
else
600+
free(value);
601+
}
602+
603+
strbuf_list_free(elems);
604+
605+
if (!info->name || !info->url) {
606+
warning(_("server advertised a promisor remote without a name or URL: %s"),
607+
remote_info->buf);
608+
promisor_info_free(info);
609+
return NULL;
610+
}
611+
612+
return info;
613+
}
614+
569615
static void filter_promisor_remote(struct repository *repo,
570616
struct strvec *accepted,
571617
const char *info)
@@ -602,32 +648,19 @@ static void filter_promisor_remote(struct repository *repo,
602648
remotes = strbuf_split_str(info, ';', 0);
603649

604650
for (size_t i = 0; remotes[i]; i++) {
605-
struct strbuf **elems;
606-
const char *remote_name = NULL;
607-
const char *remote_url = NULL;
608-
char *decoded_name = NULL;
609-
char *decoded_url = NULL;
651+
struct promisor_info *advertised;
610652

611653
strbuf_strip_suffix(remotes[i], ";");
612-
elems = strbuf_split(remotes[i], ',');
613654

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

620-
if (remote_name)
621-
decoded_name = url_percent_decode(remote_name);
622-
if (remote_url)
623-
decoded_url = url_percent_decode(remote_url);
657+
if (!advertised)
658+
continue;
624659

625-
if (decoded_name && should_accept_remote(accept, decoded_name, decoded_url, &config_info))
626-
strvec_push(accepted, decoded_name);
660+
if (should_accept_remote(accept, advertised, &config_info))
661+
strvec_push(accepted, advertised->name);
627662

628-
strbuf_list_free(elems);
629-
free(decoded_name);
630-
free(decoded_url);
663+
promisor_info_free(advertised);
631664
}
632665

633666
promisor_info_list_clear(&config_info);

0 commit comments

Comments
 (0)