trailers: introduce struct new_trailer_item
authorPaolo Bonzini <pbonzini@redhat.com>
Tue, 1 Aug 2017 09:03:31 +0000 (11:03 +0200)
committerJunio C Hamano <gitster@pobox.com>
Mon, 14 Aug 2017 19:23:28 +0000 (12:23 -0700)
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>
builtin/interpret-trailers.c
trailer.c
trailer.h
index 175f14797b101d22ead9d1008744440da66a7c1c..d12f36eda703a77257e7f9272dfd9f60f1dccdeb 100644 (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;
 }
index f0289537317a0a6654f4a72a9781193a71f4d314..6941da799b2d0108dba83eb1463435d609b14a3b 100644 (file)
--- 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);
 
index 2b39a1bee05d3bd71ef78187f73259fd74eddffa..b83b249b6618f0f25f873599bd546da862f17e92 100644 (file)
--- 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);