Skip to content

Commit 46a0613

Browse files
chriscoolgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4103818 commit 46a0613

File tree

1 file changed

+185
-0
lines changed

1 file changed

+185
-0
lines changed

trailer.c

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,3 +277,188 @@ static void process_trailers_lists(struct trailer_item **in_tok_first,
277277
arg_tok);
278278
}
279279
}
280+
281+
static int set_where(struct conf_info *item, const char *value)
282+
{
283+
if (!strcasecmp("after", value))
284+
item->where = WHERE_AFTER;
285+
else if (!strcasecmp("before", value))
286+
item->where = WHERE_BEFORE;
287+
else if (!strcasecmp("end", value))
288+
item->where = WHERE_END;
289+
else if (!strcasecmp("start", value))
290+
item->where = WHERE_START;
291+
else
292+
return -1;
293+
return 0;
294+
}
295+
296+
static int set_if_exists(struct conf_info *item, const char *value)
297+
{
298+
if (!strcasecmp("addIfDifferent", value))
299+
item->if_exists = EXISTS_ADD_IF_DIFFERENT;
300+
else if (!strcasecmp("addIfDifferentNeighbor", value))
301+
item->if_exists = EXISTS_ADD_IF_DIFFERENT_NEIGHBOR;
302+
else if (!strcasecmp("add", value))
303+
item->if_exists = EXISTS_ADD;
304+
else if (!strcasecmp("replace", value))
305+
item->if_exists = EXISTS_REPLACE;
306+
else if (!strcasecmp("doNothing", value))
307+
item->if_exists = EXISTS_DO_NOTHING;
308+
else
309+
return -1;
310+
return 0;
311+
}
312+
313+
static int set_if_missing(struct conf_info *item, const char *value)
314+
{
315+
if (!strcasecmp("doNothing", value))
316+
item->if_missing = MISSING_DO_NOTHING;
317+
else if (!strcasecmp("add", value))
318+
item->if_missing = MISSING_ADD;
319+
else
320+
return -1;
321+
return 0;
322+
}
323+
324+
static void duplicate_conf(struct conf_info *dst, struct conf_info *src)
325+
{
326+
*dst = *src;
327+
if (src->name)
328+
dst->name = xstrdup(src->name);
329+
if (src->key)
330+
dst->key = xstrdup(src->key);
331+
if (src->command)
332+
dst->command = xstrdup(src->command);
333+
}
334+
335+
static struct trailer_item *get_conf_item(const char *name)
336+
{
337+
struct trailer_item *item;
338+
struct trailer_item *previous;
339+
340+
/* Look up item with same name */
341+
for (previous = NULL, item = first_conf_item;
342+
item;
343+
previous = item, item = item->next) {
344+
if (!strcasecmp(item->conf.name, name))
345+
return item;
346+
}
347+
348+
/* Item does not already exists, create it */
349+
item = xcalloc(sizeof(struct trailer_item), 1);
350+
duplicate_conf(&item->conf, &default_conf_info);
351+
item->conf.name = xstrdup(name);
352+
353+
if (!previous)
354+
first_conf_item = item;
355+
else {
356+
previous->next = item;
357+
item->previous = previous;
358+
}
359+
360+
return item;
361+
}
362+
363+
enum trailer_info_type { TRAILER_KEY, TRAILER_COMMAND, TRAILER_WHERE,
364+
TRAILER_IF_EXISTS, TRAILER_IF_MISSING };
365+
366+
static struct {
367+
const char *name;
368+
enum trailer_info_type type;
369+
} trailer_config_items[] = {
370+
{ "key", TRAILER_KEY },
371+
{ "command", TRAILER_COMMAND },
372+
{ "where", TRAILER_WHERE },
373+
{ "ifexists", TRAILER_IF_EXISTS },
374+
{ "ifmissing", TRAILER_IF_MISSING }
375+
};
376+
377+
static int git_trailer_default_config(const char *conf_key, const char *value, void *cb)
378+
{
379+
const char *trailer_item, *variable_name;
380+
381+
if (!skip_prefix(conf_key, "trailer.", &trailer_item))
382+
return 0;
383+
384+
variable_name = strrchr(trailer_item, '.');
385+
if (!variable_name) {
386+
if (!strcmp(trailer_item, "where")) {
387+
if (set_where(&default_conf_info, value) < 0)
388+
warning(_("unknown value '%s' for key '%s'"),
389+
value, conf_key);
390+
} else if (!strcmp(trailer_item, "ifexists")) {
391+
if (set_if_exists(&default_conf_info, value) < 0)
392+
warning(_("unknown value '%s' for key '%s'"),
393+
value, conf_key);
394+
} else if (!strcmp(trailer_item, "ifmissing")) {
395+
if (set_if_missing(&default_conf_info, value) < 0)
396+
warning(_("unknown value '%s' for key '%s'"),
397+
value, conf_key);
398+
} else if (!strcmp(trailer_item, "separators")) {
399+
separators = xstrdup(value);
400+
}
401+
}
402+
return 0;
403+
}
404+
405+
static int git_trailer_config(const char *conf_key, const char *value, void *cb)
406+
{
407+
const char *trailer_item, *variable_name;
408+
struct trailer_item *item;
409+
struct conf_info *conf;
410+
char *name = NULL;
411+
enum trailer_info_type type;
412+
int i;
413+
414+
if (!skip_prefix(conf_key, "trailer.", &trailer_item))
415+
return 0;
416+
417+
variable_name = strrchr(trailer_item, '.');
418+
if (!variable_name)
419+
return 0;
420+
421+
variable_name++;
422+
for (i = 0; i < ARRAY_SIZE(trailer_config_items); i++) {
423+
if (strcmp(trailer_config_items[i].name, variable_name))
424+
continue;
425+
name = xstrndup(trailer_item, variable_name - trailer_item - 1);
426+
type = trailer_config_items[i].type;
427+
break;
428+
}
429+
430+
if (!name)
431+
return 0;
432+
433+
item = get_conf_item(name);
434+
conf = &item->conf;
435+
free(name);
436+
437+
switch (type) {
438+
case TRAILER_KEY:
439+
if (conf->key)
440+
warning(_("more than one %s"), conf_key);
441+
conf->key = xstrdup(value);
442+
break;
443+
case TRAILER_COMMAND:
444+
if (conf->command)
445+
warning(_("more than one %s"), conf_key);
446+
conf->command = xstrdup(value);
447+
break;
448+
case TRAILER_WHERE:
449+
if (set_where(conf, value))
450+
warning(_("unknown value '%s' for key '%s'"), value, conf_key);
451+
break;
452+
case TRAILER_IF_EXISTS:
453+
if (set_if_exists(conf, value))
454+
warning(_("unknown value '%s' for key '%s'"), value, conf_key);
455+
break;
456+
case TRAILER_IF_MISSING:
457+
if (set_if_missing(conf, value))
458+
warning(_("unknown value '%s' for key '%s'"), value, conf_key);
459+
break;
460+
default:
461+
die("internal bug in trailer.c");
462+
}
463+
return 0;
464+
}

0 commit comments

Comments
 (0)