trailer: make args have their own struct

Improve type safety by making arguments (whether from configuration or from the command line) have their own "struct arg_item" type, separate from the "struct trailer_item" type used to represent the trailers in the buffer being manipulated. This change also prepares "struct trailer_item" to be further differentiated from "struct arg_item" in future patches. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jonathan Tan committed Oct 20, 2016 at 14:39 UTC cc71b0de115808835486bc10d094b49261128276
1 file changed +85 -50
trailer.c
+85 -50
@@ -29,6 +29,12 @@ struct trailer_item {
29 struct list_head list;
30 char *token;
31 char *value;
32 +};
33 +
34 +struct arg_item {
35 + struct list_head list;
36 + char *token;
37 + char *value;
38 struct conf_info conf;
39 };
40
@@ -62,7 +68,7 @@ static size_t token_len_without_separator(const char *token, size_t len)
68 return len;
69 }
70
65 -static int same_token(struct trailer_item *a, struct trailer_item *b)
71 +static int same_token(struct trailer_item *a, struct arg_item *b)
72 {
73 size_t a_len = token_len_without_separator(a->token, strlen(a->token));
74 size_t b_len = token_len_without_separator(b->token, strlen(b->token));
@@ -71,12 +77,12 @@ static int same_token(struct trailer_item *a, struct trailer_item *b)
77 return !strncasecmp(a->token, b->token, min_len);
78 }
79
74 -static int same_value(struct trailer_item *a, struct trailer_item *b)
80 +static int same_value(struct trailer_item *a, struct arg_item *b)
81 {
82 return !strcasecmp(a->value, b->value);
83 }
84
79 -static int same_trailer(struct trailer_item *a, struct trailer_item *b)
85 +static int same_trailer(struct trailer_item *a, struct arg_item *b)
86 {
87 return same_token(a, b) && same_value(a, b);
88 }
@@ -97,6 +103,13 @@ static inline void strbuf_replace(struct strbuf *sb, const char *a, const char *
103 }
104
105 static void free_trailer_item(struct trailer_item *item)
106 +{
107 + free(item->token);
108 + free(item->value);
109 + free(item);
110 +}
111 +
112 +static void free_arg_item(struct arg_item *item)
113 {
114 free(item->conf.name);
115 free(item->conf.key);
@@ -137,17 +150,29 @@ static void print_all(FILE *outfile, struct list_head *head, int trim_empty)
150 }
151 }
152
153 +static struct trailer_item *trailer_from_arg(struct arg_item *arg_tok)
154 +{
155 + struct trailer_item *new = xcalloc(sizeof(*new), 1);
156 + new->token = arg_tok->token;
157 + new->value = arg_tok->value;
158 + arg_tok->token = arg_tok->value = NULL;
159 + free_arg_item(arg_tok);
160 + return new;
161 +}
162 +
163 static void add_arg_to_input_list(struct trailer_item *on_tok,
141 - struct trailer_item *arg_tok)
164 + struct arg_item *arg_tok)
165 {
143 - if (after_or_end(arg_tok->conf.where))
144 - list_add(&arg_tok->list, &on_tok->list);
166 + int aoe = after_or_end(arg_tok->conf.where);
167 + struct trailer_item *to_add = trailer_from_arg(arg_tok);
168 + if (aoe)
169 + list_add(&to_add->list, &on_tok->list);
170 else
146 - list_add_tail(&arg_tok->list, &on_tok->list);
171 + list_add_tail(&to_add->list, &on_tok->list);
172 }
173
174 static int check_if_different(struct trailer_item *in_tok,
150 - struct trailer_item *arg_tok,
175 + struct arg_item *arg_tok,
176 int check_all,
177 struct list_head *head)
178 {
@@ -200,7 +225,7 @@ static char *apply_command(const char *command, const char *arg)
225 return result;
226 }
227
203 -static void apply_item_command(struct trailer_item *in_tok, struct trailer_item *arg_tok)
228 +static void apply_item_command(struct trailer_item *in_tok, struct arg_item *arg_tok)
229 {
230 if (arg_tok->conf.command) {
231 const char *arg;
@@ -218,13 +243,13 @@ static void apply_item_command(struct trailer_item *in_tok, struct trailer_item
243 }
244
245 static void apply_arg_if_exists(struct trailer_item *in_tok,
221 - struct trailer_item *arg_tok,
246 + struct arg_item *arg_tok,
247 struct trailer_item *on_tok,
248 struct list_head *head)
249 {
250 switch (arg_tok->conf.if_exists) {
251 case EXISTS_DO_NOTHING:
227 - free_trailer_item(arg_tok);
252 + free_arg_item(arg_tok);
253 break;
254 case EXISTS_REPLACE:
255 apply_item_command(in_tok, arg_tok);
@@ -241,39 +266,41 @@ static void apply_arg_if_exists(struct trailer_item *in_tok,
266 if (check_if_different(in_tok, arg_tok, 1, head))
267 add_arg_to_input_list(on_tok, arg_tok);
268 else
244 - free_trailer_item(arg_tok);
269 + free_arg_item(arg_tok);
270 break;
271 case EXISTS_ADD_IF_DIFFERENT_NEIGHBOR:
272 apply_item_command(in_tok, arg_tok);
273 if (check_if_different(on_tok, arg_tok, 0, head))
274 add_arg_to_input_list(on_tok, arg_tok);
275 else
251 - free_trailer_item(arg_tok);
276 + free_arg_item(arg_tok);
277 break;
278 }
279 }
280
281 static void apply_arg_if_missing(struct list_head *head,
257 - struct trailer_item *arg_tok)
282 + struct arg_item *arg_tok)
283 {
284 enum action_where where;
285 + struct trailer_item *to_add;
286
287 switch (arg_tok->conf.if_missing) {
288 case MISSING_DO_NOTHING:
263 - free_trailer_item(arg_tok);
289 + free_arg_item(arg_tok);
290 break;
291 case MISSING_ADD:
292 where = arg_tok->conf.where;
293 apply_item_command(NULL, arg_tok);
294 + to_add = trailer_from_arg(arg_tok);
295 if (after_or_end(where))
269 - list_add_tail(&arg_tok->list, head);
296 + list_add_tail(&to_add->list, head);
297 else
271 - list_add(&arg_tok->list, head);
298 + list_add(&to_add->list, head);
299 }
300 }
301
302 static int find_same_and_apply_arg(struct list_head *head,
276 - struct trailer_item *arg_tok)
303 + struct arg_item *arg_tok)
304 {
305 struct list_head *pos;
306 struct trailer_item *in_tok;
@@ -306,11 +333,11 @@ static void process_trailers_lists(struct list_head *head,
333 struct list_head *arg_head)
334 {
335 struct list_head *pos, *p;
309 - struct trailer_item *arg_tok;
336 + struct arg_item *arg_tok;
337
338 list_for_each_safe(pos, p, arg_head) {
339 int applied = 0;
313 - arg_tok = list_entry(pos, struct trailer_item, list);
340 + arg_tok = list_entry(pos, struct arg_item, list);
341
342 list_del(pos);
343
@@ -375,20 +402,20 @@ static void duplicate_conf(struct conf_info *dst, const struct conf_info *src)
402 dst->command = xstrdup(src->command);
403 }
404
378 -static struct trailer_item *get_conf_item(const char *name)
405 +static struct arg_item *get_conf_item(const char *name)
406 {
407 struct list_head *pos;
381 - struct trailer_item *item;
408 + struct arg_item *item;
409
410 /* Look up item with same name */
411 list_for_each(pos, &conf_head) {
385 - item = list_entry(pos, struct trailer_item, list);
412 + item = list_entry(pos, struct arg_item, list);
413 if (!strcasecmp(item->conf.name, name))
414 return item;
415 }
416
417 /* Item does not already exists, create it */
391 - item = xcalloc(sizeof(struct trailer_item), 1);
418 + item = xcalloc(sizeof(*item), 1);
419 duplicate_conf(&item->conf, &default_conf_info);
420 item->conf.name = xstrdup(name);
421
@@ -442,7 +469,7 @@ static int git_trailer_default_config(const char *conf_key, const char *value, v
469 static int git_trailer_config(const char *conf_key, const char *value, void *cb)
470 {
471 const char *trailer_item, *variable_name;
445 - struct trailer_item *item;
472 + struct arg_item *item;
473 struct conf_info *conf;
474 char *name = NULL;
475 enum trailer_info_type type;
@@ -500,7 +527,7 @@ static int git_trailer_config(const char *conf_key, const char *value, void *cb)
527 return 0;
528 }
529
503 -static const char *token_from_item(struct trailer_item *item, char *tok)
530 +static const char *token_from_item(struct arg_item *item, char *tok)
531 {
532 if (item->conf.key)
533 return item->conf.key;
@@ -509,7 +536,7 @@ static const char *token_from_item(struct trailer_item *item, char *tok)
536 return item->conf.name;
537 }
538
512 -static int token_matches_item(const char *tok, struct trailer_item *item, int tok_len)
539 +static int token_matches_item(const char *tok, struct arg_item *item, int tok_len)
540 {
541 if (!strncasecmp(tok, item->conf.name, tok_len))
542 return 1;
@@ -521,7 +548,7 @@ static int parse_trailer(struct strbuf *tok, struct strbuf *val,
548 {
549 size_t len;
550 struct strbuf seps = STRBUF_INIT;
524 - struct trailer_item *item;
551 + struct arg_item *item;
552 int tok_len;
553 struct list_head *pos;
554
@@ -547,12 +574,14 @@ static int parse_trailer(struct strbuf *tok, struct strbuf *val,
574
575 /* Lookup if the token matches something in the config */
576 tok_len = token_len_without_separator(tok->buf, tok->len);
550 - *conf = &default_conf_info;
577 + if (conf)
578 + *conf = &default_conf_info;
579 list_for_each(pos, &conf_head) {
552 - item = list_entry(pos, struct trailer_item, list);
580 + item = list_entry(pos, struct arg_item, list);
581 if (token_matches_item(tok->buf, item, tok_len)) {
582 char *tok_buf = strbuf_detach(tok, NULL);
555 - *conf = &item->conf;
583 + if (conf)
584 + *conf = &item->conf;
585 strbuf_addstr(tok, token_from_item(item, tok_buf));
586 free(tok_buf);
587 break;
@@ -562,43 +591,51 @@ static int parse_trailer(struct strbuf *tok, struct strbuf *val,
591 return 0;
592 }
593
565 -static void add_trailer_item(struct list_head *head, char *tok, char *val,
566 - const struct conf_info *conf)
594 +static void add_trailer_item(struct list_head *head, char *tok, char *val)
595 {
596 struct trailer_item *new = xcalloc(sizeof(*new), 1);
597 new->token = tok;
598 new->value = val;
571 - duplicate_conf(&new->conf, conf);
599 list_add_tail(&new->list, head);
600 }
601
602 +static void add_arg_item(struct list_head *arg_head, char *tok, char *val,
603 + const struct conf_info *conf)
604 +{
605 + struct arg_item *new = xcalloc(sizeof(*new), 1);
606 + new->token = tok;
607 + new->value = val;
608 + duplicate_conf(&new->conf, conf);
609 + list_add_tail(&new->list, arg_head);
610 +}
611 +
612 static void process_command_line_args(struct list_head *arg_head,
613 struct string_list *trailers)
614 {
615 struct string_list_item *tr;
579 - struct trailer_item *item;
616 + struct arg_item *item;
617 struct strbuf tok = STRBUF_INIT;
618 struct strbuf val = STRBUF_INIT;
619 const struct conf_info *conf;
620 struct list_head *pos;
621
585 - /* Add a trailer item for each configured trailer with a command */
622 + /* Add an arg item for each configured trailer with a command */
623 list_for_each(pos, &conf_head) {
587 - item = list_entry(pos, struct trailer_item, list);
624 + item = list_entry(pos, struct arg_item, list);
625 if (item->conf.command)
589 - add_trailer_item(arg_head,
590 - xstrdup(token_from_item(item, NULL)),
591 - xstrdup(""),
592 - &item->conf);
626 + add_arg_item(arg_head,
627 + xstrdup(token_from_item(item, NULL)),
628 + xstrdup(""),
629 + &item->conf);
630 }
631
595 - /* Add a trailer item for each trailer on the command line */
632 + /* Add an arg item for each trailer on the command line */
633 for_each_string_list_item(tr, trailers) {
634 if (!parse_trailer(&tok, &val, &conf, tr->string))
598 - add_trailer_item(arg_head,
599 - strbuf_detach(&tok, NULL),
600 - strbuf_detach(&val, NULL),
601 - conf);
635 + add_arg_item(arg_head,
636 + strbuf_detach(&tok, NULL),
637 + strbuf_detach(&val, NULL),
638 + conf);
639 }
640 }
641
@@ -721,7 +758,6 @@ static int process_input_file(FILE *outfile,
758 int patch_start, trailer_start, trailer_end, i;
759 struct strbuf tok = STRBUF_INIT;
760 struct strbuf val = STRBUF_INIT;
724 - const struct conf_info *conf;
761
762 /* Get the line count */
763 while (lines[count])
@@ -740,11 +776,10 @@ static int process_input_file(FILE *outfile,
776 /* Parse trailer lines */
777 for (i = trailer_start; i < trailer_end; i++) {
778 if (lines[i]->buf[0] != comment_line_char &&
743 - !parse_trailer(&tok, &val, &conf, lines[i]->buf))
779 + !parse_trailer(&tok, &val, NULL, lines[i]->buf))
780 add_trailer_item(head,
781 strbuf_detach(&tok, NULL),
746 - strbuf_detach(&val, NULL),
747 - conf);
782 + strbuf_detach(&val, NULL));
783 }
784
785 return trailer_end;