|
1 | 1 | #include "cache.h"
|
| 2 | +#include "string-list.h" |
2 | 3 | /*
|
3 | 4 | * Copyright (c) 2013, 2014 Christian Couder <[email protected]>
|
4 | 5 | */
|
@@ -462,3 +463,114 @@ static int git_trailer_config(const char *conf_key, const char *value, void *cb)
|
462 | 463 | }
|
463 | 464 | return 0;
|
464 | 465 | }
|
| 466 | + |
| 467 | +static int parse_trailer(struct strbuf *tok, struct strbuf *val, const char *trailer) |
| 468 | +{ |
| 469 | + size_t len; |
| 470 | + struct strbuf seps = STRBUF_INIT; |
| 471 | + strbuf_addstr(&seps, separators); |
| 472 | + strbuf_addch(&seps, '='); |
| 473 | + len = strcspn(trailer, seps.buf); |
| 474 | + strbuf_release(&seps); |
| 475 | + if (len == 0) |
| 476 | + return error(_("empty trailer token in trailer '%s'"), trailer); |
| 477 | + if (len < strlen(trailer)) { |
| 478 | + strbuf_add(tok, trailer, len); |
| 479 | + strbuf_trim(tok); |
| 480 | + strbuf_addstr(val, trailer + len + 1); |
| 481 | + strbuf_trim(val); |
| 482 | + } else { |
| 483 | + strbuf_addstr(tok, trailer); |
| 484 | + strbuf_trim(tok); |
| 485 | + } |
| 486 | + return 0; |
| 487 | +} |
| 488 | + |
| 489 | +static const char *token_from_item(struct trailer_item *item, char *tok) |
| 490 | +{ |
| 491 | + if (item->conf.key) |
| 492 | + return item->conf.key; |
| 493 | + if (tok) |
| 494 | + return tok; |
| 495 | + return item->conf.name; |
| 496 | +} |
| 497 | + |
| 498 | +static struct trailer_item *new_trailer_item(struct trailer_item *conf_item, |
| 499 | + char *tok, char *val) |
| 500 | +{ |
| 501 | + struct trailer_item *new = xcalloc(sizeof(*new), 1); |
| 502 | + new->value = val; |
| 503 | + |
| 504 | + if (conf_item) { |
| 505 | + duplicate_conf(&new->conf, &conf_item->conf); |
| 506 | + new->token = xstrdup(token_from_item(conf_item, tok)); |
| 507 | + free(tok); |
| 508 | + } else { |
| 509 | + duplicate_conf(&new->conf, &default_conf_info); |
| 510 | + new->token = tok; |
| 511 | + } |
| 512 | + |
| 513 | + return new; |
| 514 | +} |
| 515 | + |
| 516 | +static int token_matches_item(const char *tok, struct trailer_item *item, int tok_len) |
| 517 | +{ |
| 518 | + if (!strncasecmp(tok, item->conf.name, tok_len)) |
| 519 | + return 1; |
| 520 | + return item->conf.key ? !strncasecmp(tok, item->conf.key, tok_len) : 0; |
| 521 | +} |
| 522 | + |
| 523 | +static struct trailer_item *create_trailer_item(const char *string) |
| 524 | +{ |
| 525 | + struct strbuf tok = STRBUF_INIT; |
| 526 | + struct strbuf val = STRBUF_INIT; |
| 527 | + struct trailer_item *item; |
| 528 | + int tok_len; |
| 529 | + |
| 530 | + if (parse_trailer(&tok, &val, string)) |
| 531 | + return NULL; |
| 532 | + |
| 533 | + tok_len = token_len_without_separator(tok.buf, tok.len); |
| 534 | + |
| 535 | + /* Lookup if the token matches something in the config */ |
| 536 | + for (item = first_conf_item; item; item = item->next) { |
| 537 | + if (token_matches_item(tok.buf, item, tok_len)) |
| 538 | + return new_trailer_item(item, |
| 539 | + strbuf_detach(&tok, NULL), |
| 540 | + strbuf_detach(&val, NULL)); |
| 541 | + } |
| 542 | + |
| 543 | + return new_trailer_item(NULL, |
| 544 | + strbuf_detach(&tok, NULL), |
| 545 | + strbuf_detach(&val, NULL)); |
| 546 | +} |
| 547 | + |
| 548 | +static void add_trailer_item(struct trailer_item **first, |
| 549 | + struct trailer_item **last, |
| 550 | + struct trailer_item *new) |
| 551 | +{ |
| 552 | + if (!new) |
| 553 | + return; |
| 554 | + if (!*last) { |
| 555 | + *first = new; |
| 556 | + *last = new; |
| 557 | + } else { |
| 558 | + (*last)->next = new; |
| 559 | + new->previous = *last; |
| 560 | + *last = new; |
| 561 | + } |
| 562 | +} |
| 563 | + |
| 564 | +static struct trailer_item *process_command_line_args(struct string_list *trailers) |
| 565 | +{ |
| 566 | + struct trailer_item *arg_tok_first = NULL; |
| 567 | + struct trailer_item *arg_tok_last = NULL; |
| 568 | + struct string_list_item *tr; |
| 569 | + |
| 570 | + for_each_string_list_item(tr, trailers) { |
| 571 | + struct trailer_item *new = create_trailer_item(tr->string); |
| 572 | + add_trailer_item(&arg_tok_first, &arg_tok_last, new); |
| 573 | + } |
| 574 | + |
| 575 | + return arg_tok_first; |
| 576 | +} |
0 commit comments