trailers: introduce struct new_trailer_item

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@redhat.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Paolo Bonzini 2017-08-01 11:03:31 +02:00 committed by Junio C Hamano
parent 52fc319d4d
commit 51166b8754
3 changed files with 61 additions and 13 deletions

View file

@ -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;
}

View file

@ -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);

View file

@ -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);