Git fork

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 <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by

Christian Couder and committed by
Junio C Hamano
de1efeaf 4e2139c9

+57 -29
+57 -29
promisor-remote.c
··· 405 405 const char *token; 406 406 }; 407 407 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 + 408 417 static void promisor_info_list_clear(struct string_list *list) 409 418 { 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); 418 422 } 419 423 420 424 static void set_one_field(struct promisor_info *p, ··· 531 535 }; 532 536 533 537 static int should_accept_remote(enum accept_promisor accept, 534 - const char *remote_name, const char *remote_url, 538 + struct promisor_info *advertised, 535 539 struct string_list *config_info) 536 540 { 537 541 struct promisor_info *p; 538 542 struct string_list_item *item; 543 + const char *remote_name = advertised->name; 544 + const char *remote_url = advertised->url; 539 545 540 546 if (accept == ACCEPT_ALL) 541 547 return 1; ··· 578 584 return 1; 579 585 } 580 586 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 + 581 622 static void filter_promisor_remote(struct repository *repo, 582 623 struct strvec *accepted, 583 624 const char *info) ··· 614 655 remotes = strbuf_split_str(info, ';', 0); 615 656 616 657 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; 622 659 623 660 strbuf_strip_suffix(remotes[i], ";"); 624 - elems = strbuf_split(remotes[i], ','); 625 661 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); 631 663 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; 636 666 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); 639 669 640 - strbuf_list_free(elems); 641 - free(decoded_name); 642 - free(decoded_url); 670 + promisor_info_free(advertised); 643 671 } 644 672 645 673 promisor_info_list_clear(&config_info);