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;