@@ -277,3 +277,188 @@ static void process_trailers_lists(struct trailer_item **in_tok_first,
277
277
arg_tok );
278
278
}
279
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
+ }
0 commit comments