@@ -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