Skip to content

Commit f0a90b4

Browse files
chriscoolgitster
authored andcommitted
trailer: process command line trailer arguments
Parse the trailer command line arguments and put the result into an arg_tok doubly linked list. Signed-off-by: Christian Couder <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 46a0613 commit f0a90b4

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed

trailer.c

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "cache.h"
2+
#include "string-list.h"
23
/*
34
* Copyright (c) 2013, 2014 Christian Couder <[email protected]>
45
*/
@@ -462,3 +463,114 @@ static int git_trailer_config(const char *conf_key, const char *value, void *cb)
462463
}
463464
return 0;
464465
}
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

Comments
 (0)