trailer: read and process config information
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 <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
4103818d20
commit
46a0613f00
185
trailer.c
185
trailer.c
@ -277,3 +277,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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user