Read the configuration to get trailer information, and then process
it and store it in a doubly linked list.

The config information is stored in the list whose first item is
pointed to by:

static struct trailer_item *first_conf_item;

Signed-off-by: Christian Couder <chrisc...@tuxfamily.org>
Signed-off-by: Junio C Hamano <gits...@pobox.com>
---
 trailer.c | 185 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 185 insertions(+)

diff --git a/trailer.c b/trailer.c
index 4940e06..2d391f3 100644
--- a/trailer.c
+++ b/trailer.c
@@ -272,3 +272,188 @@ static void process_trailers_lists(struct trailer_item 
**in_tok_first,
                                             arg_tok);
        }
 }
+
+static int set_where(struct conf_info *item, const char *value)
+{
+       if (!strcasecmp("after", value))
+               item->where = WHERE_AFTER;
+       else if (!strcasecmp("before", value))
+               item->where = WHERE_BEFORE;
+       else if (!strcasecmp("end", value))
+               item->where = WHERE_END;
+       else if (!strcasecmp("start", value))
+               item->where = WHERE_START;
+       else
+               return -1;
+       return 0;
+}
+
+static int set_if_exists(struct conf_info *item, const char *value)
+{
+       if (!strcasecmp("addIfDifferent", value))
+               item->if_exists = EXISTS_ADD_IF_DIFFERENT;
+       else if (!strcasecmp("addIfDifferentNeighbor", value))
+               item->if_exists = EXISTS_ADD_IF_DIFFERENT_NEIGHBOR;
+       else if (!strcasecmp("add", value))
+               item->if_exists = EXISTS_ADD;
+       else if (!strcasecmp("replace", value))
+               item->if_exists = EXISTS_REPLACE;
+       else if (!strcasecmp("doNothing", value))
+               item->if_exists = EXISTS_DO_NOTHING;
+       else
+               return -1;
+       return 0;
+}
+
+static int set_if_missing(struct conf_info *item, const char *value)
+{
+       if (!strcasecmp("doNothing", value))
+               item->if_missing = MISSING_DO_NOTHING;
+       else if (!strcasecmp("add", value))
+               item->if_missing = MISSING_ADD;
+       else
+               return -1;
+       return 0;
+}
+
+static void duplicate_conf(struct conf_info *dst, struct conf_info *src)
+{
+       *dst = *src;
+       if (src->name)
+               dst->name = xstrdup(src->name);
+       if (src->key)
+               dst->key = xstrdup(src->key);
+       if (src->command)
+               dst->command = xstrdup(src->command);
+}
+
+static struct trailer_item *get_conf_item(const char *name)
+{
+       struct trailer_item *item;
+       struct trailer_item *previous;
+
+       /* Look up item with same name */
+       for (previous = NULL, item = first_conf_item;
+            item;
+            previous = item, item = item->next) {
+               if (!strcasecmp(item->conf.name, name))
+                       return item;
+       }
+
+       /* Item does not already exists, create it */
+       item = xcalloc(sizeof(struct trailer_item), 1);
+       duplicate_conf(&item->conf, &default_conf_info);
+       item->conf.name = xstrdup(name);
+
+       if (!previous)
+               first_conf_item = item;
+       else {
+               previous->next = item;
+               item->previous = previous;
+       }
+
+       return item;
+}
+
+enum trailer_info_type { TRAILER_KEY, TRAILER_COMMAND, TRAILER_WHERE,
+                        TRAILER_IF_EXISTS, TRAILER_IF_MISSING };
+
+static struct {
+       const char *name;
+       enum trailer_info_type type;
+} trailer_config_items[] = {
+       { "key", TRAILER_KEY },
+       { "command", TRAILER_COMMAND },
+       { "where", TRAILER_WHERE },
+       { "ifexists", TRAILER_IF_EXISTS },
+       { "ifmissing", TRAILER_IF_MISSING }
+};
+
+static int git_trailer_default_config(const char *conf_key, const char *value, 
void *cb)
+{
+       const char *trailer_item, *variable_name;
+
+       if (!skip_prefix(conf_key, "trailer.", &trailer_item))
+               return 0;
+
+       variable_name = strrchr(trailer_item, '.');
+       if (!variable_name) {
+               if (!strcmp(trailer_item, "where")) {
+                       if (set_where(&default_conf_info, value) < 0)
+                               warning(_("unknown value '%s' for key '%s'"),
+                                       value, conf_key);
+               } else if (!strcmp(trailer_item, "ifexists")) {
+                       if (set_if_exists(&default_conf_info, value) < 0)
+                               warning(_("unknown value '%s' for key '%s'"),
+                                       value, conf_key);
+               } else if (!strcmp(trailer_item, "ifmissing")) {
+                       if (set_if_missing(&default_conf_info, value) < 0)
+                               warning(_("unknown value '%s' for key '%s'"),
+                                       value, conf_key);
+               } else if (!strcmp(trailer_item, "separators")) {
+                       separators = xstrdup(value);
+               }
+       }
+       return 0;
+}
+
+static int git_trailer_config(const char *conf_key, const char *value, void 
*cb)
+{
+       const char *trailer_item, *variable_name;
+       struct trailer_item *item;
+       struct conf_info *conf;
+       char *name = NULL;
+       enum trailer_info_type type;
+       int i;
+
+       if (!skip_prefix(conf_key, "trailer.", &trailer_item))
+               return 0;
+
+       variable_name = strrchr(trailer_item, '.');
+       if (!variable_name)
+               return 0;
+
+       variable_name++;
+       for (i = 0; i < ARRAY_SIZE(trailer_config_items); i++) {
+               if (strcmp(trailer_config_items[i].name, variable_name))
+                       continue;
+               name = xstrndup(trailer_item,  variable_name - trailer_item - 
1);
+               type = trailer_config_items[i].type;
+               break;
+       }
+
+       if (!name)
+               return 0;
+
+       item = get_conf_item(name);
+       conf = &item->conf;
+       free(name);
+
+       switch (type) {
+       case TRAILER_KEY:
+               if (conf->key)
+                       warning(_("more than one %s"), conf_key);
+               conf->key = xstrdup(value);
+               break;
+       case TRAILER_COMMAND:
+               if (conf->command)
+                       warning(_("more than one %s"), conf_key);
+               conf->command = xstrdup(value);
+               break;
+       case TRAILER_WHERE:
+               if (set_where(conf, value))
+                       warning(_("unknown value '%s' for key '%s'"), value, 
conf_key);
+               break;
+       case TRAILER_IF_EXISTS:
+               if (set_if_exists(conf, value))
+                       warning(_("unknown value '%s' for key '%s'"), value, 
conf_key);
+               break;
+       case TRAILER_IF_MISSING:
+               if (set_if_missing(conf, value))
+                       warning(_("unknown value '%s' for key '%s'"), value, 
conf_key);
+               break;
+       default:
+               die("internal bug in trailer.c");
+       }
+       return 0;
+}
-- 
2.0.1.674.ga7f57b7


--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to