From: Paolo Bonzini <pbonzini@xxxxxxxxxx> This will provide a place to store the current state of the --where, --if-exists and --if-missing options. Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> --- builtin/interpret-trailers.c | 41 +++++++++++++++++++++++++++++++++++++---- trailer.c | 19 +++++++++++-------- trailer.h | 14 +++++++++++++- 3 files changed, 61 insertions(+), 13 deletions(-) diff --git a/builtin/interpret-trailers.c b/builtin/interpret-trailers.c index 175f14797..8f38fa318 100644 --- a/builtin/interpret-trailers.c +++ b/builtin/interpret-trailers.c @@ -16,17 +16,50 @@ static const char * const git_interpret_trailers_usage[] = { NULL }; +static void new_trailers_clear(struct list_head *trailers) +{ + struct list_head *pos, *tmp; + struct new_trailer_item *item; + + list_for_each_safe(pos, tmp, trailers) { + item = list_entry(pos, struct new_trailer_item, list); + list_del(pos); + free(item); + } +} + +static int option_parse_trailer(const struct option *opt, + const char *arg, int unset) +{ + struct list_head *trailers = opt->value; + struct new_trailer_item *item; + + if (unset) { + new_trailers_clear(trailers); + return 0; + } + + if (!arg) + return -1; + + item = xmalloc(sizeof *item); + item->text = arg; + list_add_tail(&item->list, trailers); + return 0; +} + int cmd_interpret_trailers(int argc, const char **argv, const char *prefix) { int in_place = 0; int trim_empty = 0; - struct string_list trailers = STRING_LIST_INIT_NODUP; + LIST_HEAD(trailers); struct option options[] = { OPT_BOOL(0, "in-place", &in_place, N_("edit files in place")), OPT_BOOL(0, "trim-empty", &trim_empty, N_("trim empty trailers")), - OPT_STRING_LIST(0, "trailer", &trailers, N_("trailer"), - N_("trailer(s) to add")), + + OPT_CALLBACK(0, "trailer", &trailers, N_("trailer"), + N_("trailer(s) to add"), option_parse_trailer), OPT_END() }; @@ -43,7 +76,7 @@ int cmd_interpret_trailers(int argc, const char **argv, const char *prefix) process_trailers(NULL, in_place, trim_empty, &trailers); } - string_list_clear(&trailers, 0); + new_trailers_clear(&trailers); return 0; } diff --git a/trailer.c b/trailer.c index f02895373..6941da799 100644 --- a/trailer.c +++ b/trailer.c @@ -669,9 +669,8 @@ static void add_arg_item(struct list_head *arg_head, char *tok, char *val, } static void process_command_line_args(struct list_head *arg_head, - struct string_list *trailers) + struct list_head *new_trailer_head) { - struct string_list_item *tr; struct arg_item *item; struct strbuf tok = STRBUF_INIT; struct strbuf val = STRBUF_INIT; @@ -695,17 +694,20 @@ static void process_command_line_args(struct list_head *arg_head, } /* Add an arg item for each trailer on the command line */ - for_each_string_list_item(tr, trailers) { - int separator_pos = find_separator(tr->string, cl_separators); + list_for_each(pos, new_trailer_head) { + struct new_trailer_item *tr = + list_entry(pos, struct new_trailer_item, list); + int separator_pos = find_separator(tr->text, cl_separators); + if (separator_pos == 0) { struct strbuf sb = STRBUF_INIT; - strbuf_addstr(&sb, tr->string); + strbuf_addstr(&sb, tr->text); strbuf_trim(&sb); error(_("empty trailer token in trailer '%.*s'"), (int) sb.len, sb.buf); strbuf_release(&sb); } else { - parse_trailer(&tok, &val, &conf, tr->string, + parse_trailer(&tok, &val, &conf, tr->text, separator_pos); add_arg_item(arg_head, strbuf_detach(&tok, NULL), @@ -969,7 +971,8 @@ static FILE *create_in_place_tempfile(const char *file) return outfile; } -void process_trailers(const char *file, int in_place, int trim_empty, struct string_list *trailers) +void process_trailers(const char *file, int in_place, int trim_empty, + struct list_head *new_trailer_head) { LIST_HEAD(head); LIST_HEAD(arg_head); @@ -987,7 +990,7 @@ void process_trailers(const char *file, int in_place, int trim_empty, struct str /* Print the lines before the trailers */ trailer_end = process_input_file(outfile, sb.buf, &head); - process_command_line_args(&arg_head, trailers); + process_command_line_args(&arg_head, new_trailer_head); process_trailers_lists(&head, &arg_head); diff --git a/trailer.h b/trailer.h index 2b39a1bee..b83b249b6 100644 --- a/trailer.h +++ b/trailer.h @@ -1,6 +1,8 @@ #ifndef TRAILER_H #define TRAILER_H +#include "list.h" + enum trailer_where { WHERE_END, WHERE_AFTER, @@ -44,8 +46,18 @@ struct trailer_info { size_t trailer_nr; }; +/* + * A list that represents newly-added trailers, such as those provided + * with the --trailer command line option of git-interpret-trailers. + */ +struct new_trailer_item { + struct list_head list; + + const char *text; +}; + void process_trailers(const char *file, int in_place, int trim_empty, - struct string_list *trailers); + struct list_head *new_trailer_head); void trailer_info_get(struct trailer_info *info, const char *str); -- 2.13.3