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>
Christian Couder committed
Oct 13, 2014 at 20:16 UTC
46a0613f00f2cf6a61d04fa49131fcbe3afaad07
1 file changed
+185
trailer.c
+185
@@ -277,3 +277,188 @@ static void process_trailers_lists(struct trailer_item **in_tok_first,
277
arg_tok);
278
}
279
}
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
+}