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>
This commit is contained in:
parent
63ab3f3484
commit
cc71b0de11
121
trailer.c
121
trailer.c
@ -29,6 +29,12 @@ struct trailer_item {
|
|||||||
struct list_head list;
|
struct list_head list;
|
||||||
char *token;
|
char *token;
|
||||||
char *value;
|
char *value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct arg_item {
|
||||||
|
struct list_head list;
|
||||||
|
char *token;
|
||||||
|
char *value;
|
||||||
struct conf_info conf;
|
struct conf_info conf;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -62,7 +68,7 @@ static size_t token_len_without_separator(const char *token, size_t len)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int same_token(struct trailer_item *a, struct trailer_item *b)
|
static int same_token(struct trailer_item *a, struct arg_item *b)
|
||||||
{
|
{
|
||||||
size_t a_len = token_len_without_separator(a->token, strlen(a->token));
|
size_t a_len = token_len_without_separator(a->token, strlen(a->token));
|
||||||
size_t b_len = token_len_without_separator(b->token, strlen(b->token));
|
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)
|
|||||||
return !strncasecmp(a->token, b->token, min_len);
|
return !strncasecmp(a->token, b->token, min_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int same_value(struct trailer_item *a, struct trailer_item *b)
|
static int same_value(struct trailer_item *a, struct arg_item *b)
|
||||||
{
|
{
|
||||||
return !strcasecmp(a->value, b->value);
|
return !strcasecmp(a->value, b->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int same_trailer(struct trailer_item *a, struct trailer_item *b)
|
static int same_trailer(struct trailer_item *a, struct arg_item *b)
|
||||||
{
|
{
|
||||||
return same_token(a, b) && same_value(a, b);
|
return same_token(a, b) && same_value(a, b);
|
||||||
}
|
}
|
||||||
@ -97,6 +103,13 @@ static inline void strbuf_replace(struct strbuf *sb, const char *a, const char *
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void free_trailer_item(struct trailer_item *item)
|
static void free_trailer_item(struct trailer_item *item)
|
||||||
|
{
|
||||||
|
free(item->token);
|
||||||
|
free(item->value);
|
||||||
|
free(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_arg_item(struct arg_item *item)
|
||||||
{
|
{
|
||||||
free(item->conf.name);
|
free(item->conf.name);
|
||||||
free(item->conf.key);
|
free(item->conf.key);
|
||||||
@ -137,17 +150,29 @@ static void print_all(FILE *outfile, struct list_head *head, int trim_empty)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_arg_to_input_list(struct trailer_item *on_tok,
|
static struct trailer_item *trailer_from_arg(struct arg_item *arg_tok)
|
||||||
struct trailer_item *arg_tok)
|
|
||||||
{
|
{
|
||||||
if (after_or_end(arg_tok->conf.where))
|
struct trailer_item *new = xcalloc(sizeof(*new), 1);
|
||||||
list_add(&arg_tok->list, &on_tok->list);
|
new->token = arg_tok->token;
|
||||||
|
new->value = arg_tok->value;
|
||||||
|
arg_tok->token = arg_tok->value = NULL;
|
||||||
|
free_arg_item(arg_tok);
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_arg_to_input_list(struct trailer_item *on_tok,
|
||||||
|
struct arg_item *arg_tok)
|
||||||
|
{
|
||||||
|
int aoe = after_or_end(arg_tok->conf.where);
|
||||||
|
struct trailer_item *to_add = trailer_from_arg(arg_tok);
|
||||||
|
if (aoe)
|
||||||
|
list_add(&to_add->list, &on_tok->list);
|
||||||
else
|
else
|
||||||
list_add_tail(&arg_tok->list, &on_tok->list);
|
list_add_tail(&to_add->list, &on_tok->list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int check_if_different(struct trailer_item *in_tok,
|
static int check_if_different(struct trailer_item *in_tok,
|
||||||
struct trailer_item *arg_tok,
|
struct arg_item *arg_tok,
|
||||||
int check_all,
|
int check_all,
|
||||||
struct list_head *head)
|
struct list_head *head)
|
||||||
{
|
{
|
||||||
@ -200,7 +225,7 @@ static char *apply_command(const char *command, const char *arg)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apply_item_command(struct trailer_item *in_tok, struct trailer_item *arg_tok)
|
static void apply_item_command(struct trailer_item *in_tok, struct arg_item *arg_tok)
|
||||||
{
|
{
|
||||||
if (arg_tok->conf.command) {
|
if (arg_tok->conf.command) {
|
||||||
const char *arg;
|
const char *arg;
|
||||||
@ -218,13 +243,13 @@ static void apply_item_command(struct trailer_item *in_tok, struct trailer_item
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void apply_arg_if_exists(struct trailer_item *in_tok,
|
static void apply_arg_if_exists(struct trailer_item *in_tok,
|
||||||
struct trailer_item *arg_tok,
|
struct arg_item *arg_tok,
|
||||||
struct trailer_item *on_tok,
|
struct trailer_item *on_tok,
|
||||||
struct list_head *head)
|
struct list_head *head)
|
||||||
{
|
{
|
||||||
switch (arg_tok->conf.if_exists) {
|
switch (arg_tok->conf.if_exists) {
|
||||||
case EXISTS_DO_NOTHING:
|
case EXISTS_DO_NOTHING:
|
||||||
free_trailer_item(arg_tok);
|
free_arg_item(arg_tok);
|
||||||
break;
|
break;
|
||||||
case EXISTS_REPLACE:
|
case EXISTS_REPLACE:
|
||||||
apply_item_command(in_tok, arg_tok);
|
apply_item_command(in_tok, arg_tok);
|
||||||
@ -241,39 +266,41 @@ static void apply_arg_if_exists(struct trailer_item *in_tok,
|
|||||||
if (check_if_different(in_tok, arg_tok, 1, head))
|
if (check_if_different(in_tok, arg_tok, 1, head))
|
||||||
add_arg_to_input_list(on_tok, arg_tok);
|
add_arg_to_input_list(on_tok, arg_tok);
|
||||||
else
|
else
|
||||||
free_trailer_item(arg_tok);
|
free_arg_item(arg_tok);
|
||||||
break;
|
break;
|
||||||
case EXISTS_ADD_IF_DIFFERENT_NEIGHBOR:
|
case EXISTS_ADD_IF_DIFFERENT_NEIGHBOR:
|
||||||
apply_item_command(in_tok, arg_tok);
|
apply_item_command(in_tok, arg_tok);
|
||||||
if (check_if_different(on_tok, arg_tok, 0, head))
|
if (check_if_different(on_tok, arg_tok, 0, head))
|
||||||
add_arg_to_input_list(on_tok, arg_tok);
|
add_arg_to_input_list(on_tok, arg_tok);
|
||||||
else
|
else
|
||||||
free_trailer_item(arg_tok);
|
free_arg_item(arg_tok);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apply_arg_if_missing(struct list_head *head,
|
static void apply_arg_if_missing(struct list_head *head,
|
||||||
struct trailer_item *arg_tok)
|
struct arg_item *arg_tok)
|
||||||
{
|
{
|
||||||
enum action_where where;
|
enum action_where where;
|
||||||
|
struct trailer_item *to_add;
|
||||||
|
|
||||||
switch (arg_tok->conf.if_missing) {
|
switch (arg_tok->conf.if_missing) {
|
||||||
case MISSING_DO_NOTHING:
|
case MISSING_DO_NOTHING:
|
||||||
free_trailer_item(arg_tok);
|
free_arg_item(arg_tok);
|
||||||
break;
|
break;
|
||||||
case MISSING_ADD:
|
case MISSING_ADD:
|
||||||
where = arg_tok->conf.where;
|
where = arg_tok->conf.where;
|
||||||
apply_item_command(NULL, arg_tok);
|
apply_item_command(NULL, arg_tok);
|
||||||
|
to_add = trailer_from_arg(arg_tok);
|
||||||
if (after_or_end(where))
|
if (after_or_end(where))
|
||||||
list_add_tail(&arg_tok->list, head);
|
list_add_tail(&to_add->list, head);
|
||||||
else
|
else
|
||||||
list_add(&arg_tok->list, head);
|
list_add(&to_add->list, head);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int find_same_and_apply_arg(struct list_head *head,
|
static int find_same_and_apply_arg(struct list_head *head,
|
||||||
struct trailer_item *arg_tok)
|
struct arg_item *arg_tok)
|
||||||
{
|
{
|
||||||
struct list_head *pos;
|
struct list_head *pos;
|
||||||
struct trailer_item *in_tok;
|
struct trailer_item *in_tok;
|
||||||
@ -306,11 +333,11 @@ static void process_trailers_lists(struct list_head *head,
|
|||||||
struct list_head *arg_head)
|
struct list_head *arg_head)
|
||||||
{
|
{
|
||||||
struct list_head *pos, *p;
|
struct list_head *pos, *p;
|
||||||
struct trailer_item *arg_tok;
|
struct arg_item *arg_tok;
|
||||||
|
|
||||||
list_for_each_safe(pos, p, arg_head) {
|
list_for_each_safe(pos, p, arg_head) {
|
||||||
int applied = 0;
|
int applied = 0;
|
||||||
arg_tok = list_entry(pos, struct trailer_item, list);
|
arg_tok = list_entry(pos, struct arg_item, list);
|
||||||
|
|
||||||
list_del(pos);
|
list_del(pos);
|
||||||
|
|
||||||
@ -375,20 +402,20 @@ static void duplicate_conf(struct conf_info *dst, const struct conf_info *src)
|
|||||||
dst->command = xstrdup(src->command);
|
dst->command = xstrdup(src->command);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct trailer_item *get_conf_item(const char *name)
|
static struct arg_item *get_conf_item(const char *name)
|
||||||
{
|
{
|
||||||
struct list_head *pos;
|
struct list_head *pos;
|
||||||
struct trailer_item *item;
|
struct arg_item *item;
|
||||||
|
|
||||||
/* Look up item with same name */
|
/* Look up item with same name */
|
||||||
list_for_each(pos, &conf_head) {
|
list_for_each(pos, &conf_head) {
|
||||||
item = list_entry(pos, struct trailer_item, list);
|
item = list_entry(pos, struct arg_item, list);
|
||||||
if (!strcasecmp(item->conf.name, name))
|
if (!strcasecmp(item->conf.name, name))
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Item does not already exists, create it */
|
/* Item does not already exists, create it */
|
||||||
item = xcalloc(sizeof(struct trailer_item), 1);
|
item = xcalloc(sizeof(*item), 1);
|
||||||
duplicate_conf(&item->conf, &default_conf_info);
|
duplicate_conf(&item->conf, &default_conf_info);
|
||||||
item->conf.name = xstrdup(name);
|
item->conf.name = xstrdup(name);
|
||||||
|
|
||||||
@ -442,7 +469,7 @@ static int git_trailer_default_config(const char *conf_key, const char *value, v
|
|||||||
static int git_trailer_config(const char *conf_key, const char *value, void *cb)
|
static int git_trailer_config(const char *conf_key, const char *value, void *cb)
|
||||||
{
|
{
|
||||||
const char *trailer_item, *variable_name;
|
const char *trailer_item, *variable_name;
|
||||||
struct trailer_item *item;
|
struct arg_item *item;
|
||||||
struct conf_info *conf;
|
struct conf_info *conf;
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
enum trailer_info_type type;
|
enum trailer_info_type type;
|
||||||
@ -500,7 +527,7 @@ static int git_trailer_config(const char *conf_key, const char *value, void *cb)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *token_from_item(struct trailer_item *item, char *tok)
|
static const char *token_from_item(struct arg_item *item, char *tok)
|
||||||
{
|
{
|
||||||
if (item->conf.key)
|
if (item->conf.key)
|
||||||
return item->conf.key;
|
return item->conf.key;
|
||||||
@ -509,7 +536,7 @@ static const char *token_from_item(struct trailer_item *item, char *tok)
|
|||||||
return item->conf.name;
|
return item->conf.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int token_matches_item(const char *tok, struct trailer_item *item, int tok_len)
|
static int token_matches_item(const char *tok, struct arg_item *item, int tok_len)
|
||||||
{
|
{
|
||||||
if (!strncasecmp(tok, item->conf.name, tok_len))
|
if (!strncasecmp(tok, item->conf.name, tok_len))
|
||||||
return 1;
|
return 1;
|
||||||
@ -521,7 +548,7 @@ static int parse_trailer(struct strbuf *tok, struct strbuf *val,
|
|||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
struct strbuf seps = STRBUF_INIT;
|
struct strbuf seps = STRBUF_INIT;
|
||||||
struct trailer_item *item;
|
struct arg_item *item;
|
||||||
int tok_len;
|
int tok_len;
|
||||||
struct list_head *pos;
|
struct list_head *pos;
|
||||||
|
|
||||||
@ -547,11 +574,13 @@ static int parse_trailer(struct strbuf *tok, struct strbuf *val,
|
|||||||
|
|
||||||
/* Lookup if the token matches something in the config */
|
/* Lookup if the token matches something in the config */
|
||||||
tok_len = token_len_without_separator(tok->buf, tok->len);
|
tok_len = token_len_without_separator(tok->buf, tok->len);
|
||||||
|
if (conf)
|
||||||
*conf = &default_conf_info;
|
*conf = &default_conf_info;
|
||||||
list_for_each(pos, &conf_head) {
|
list_for_each(pos, &conf_head) {
|
||||||
item = list_entry(pos, struct trailer_item, list);
|
item = list_entry(pos, struct arg_item, list);
|
||||||
if (token_matches_item(tok->buf, item, tok_len)) {
|
if (token_matches_item(tok->buf, item, tok_len)) {
|
||||||
char *tok_buf = strbuf_detach(tok, NULL);
|
char *tok_buf = strbuf_detach(tok, NULL);
|
||||||
|
if (conf)
|
||||||
*conf = &item->conf;
|
*conf = &item->conf;
|
||||||
strbuf_addstr(tok, token_from_item(item, tok_buf));
|
strbuf_addstr(tok, token_from_item(item, tok_buf));
|
||||||
free(tok_buf);
|
free(tok_buf);
|
||||||
@ -562,40 +591,48 @@ static int parse_trailer(struct strbuf *tok, struct strbuf *val,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_trailer_item(struct list_head *head, char *tok, char *val,
|
static void add_trailer_item(struct list_head *head, char *tok, char *val)
|
||||||
const struct conf_info *conf)
|
|
||||||
{
|
{
|
||||||
struct trailer_item *new = xcalloc(sizeof(*new), 1);
|
struct trailer_item *new = xcalloc(sizeof(*new), 1);
|
||||||
new->token = tok;
|
new->token = tok;
|
||||||
new->value = val;
|
new->value = val;
|
||||||
duplicate_conf(&new->conf, conf);
|
|
||||||
list_add_tail(&new->list, head);
|
list_add_tail(&new->list, head);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void add_arg_item(struct list_head *arg_head, char *tok, char *val,
|
||||||
|
const struct conf_info *conf)
|
||||||
|
{
|
||||||
|
struct arg_item *new = xcalloc(sizeof(*new), 1);
|
||||||
|
new->token = tok;
|
||||||
|
new->value = val;
|
||||||
|
duplicate_conf(&new->conf, conf);
|
||||||
|
list_add_tail(&new->list, arg_head);
|
||||||
|
}
|
||||||
|
|
||||||
static void process_command_line_args(struct list_head *arg_head,
|
static void process_command_line_args(struct list_head *arg_head,
|
||||||
struct string_list *trailers)
|
struct string_list *trailers)
|
||||||
{
|
{
|
||||||
struct string_list_item *tr;
|
struct string_list_item *tr;
|
||||||
struct trailer_item *item;
|
struct arg_item *item;
|
||||||
struct strbuf tok = STRBUF_INIT;
|
struct strbuf tok = STRBUF_INIT;
|
||||||
struct strbuf val = STRBUF_INIT;
|
struct strbuf val = STRBUF_INIT;
|
||||||
const struct conf_info *conf;
|
const struct conf_info *conf;
|
||||||
struct list_head *pos;
|
struct list_head *pos;
|
||||||
|
|
||||||
/* Add a trailer item for each configured trailer with a command */
|
/* Add an arg item for each configured trailer with a command */
|
||||||
list_for_each(pos, &conf_head) {
|
list_for_each(pos, &conf_head) {
|
||||||
item = list_entry(pos, struct trailer_item, list);
|
item = list_entry(pos, struct arg_item, list);
|
||||||
if (item->conf.command)
|
if (item->conf.command)
|
||||||
add_trailer_item(arg_head,
|
add_arg_item(arg_head,
|
||||||
xstrdup(token_from_item(item, NULL)),
|
xstrdup(token_from_item(item, NULL)),
|
||||||
xstrdup(""),
|
xstrdup(""),
|
||||||
&item->conf);
|
&item->conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add a trailer item for each trailer on the command line */
|
/* Add an arg item for each trailer on the command line */
|
||||||
for_each_string_list_item(tr, trailers) {
|
for_each_string_list_item(tr, trailers) {
|
||||||
if (!parse_trailer(&tok, &val, &conf, tr->string))
|
if (!parse_trailer(&tok, &val, &conf, tr->string))
|
||||||
add_trailer_item(arg_head,
|
add_arg_item(arg_head,
|
||||||
strbuf_detach(&tok, NULL),
|
strbuf_detach(&tok, NULL),
|
||||||
strbuf_detach(&val, NULL),
|
strbuf_detach(&val, NULL),
|
||||||
conf);
|
conf);
|
||||||
@ -721,7 +758,6 @@ static int process_input_file(FILE *outfile,
|
|||||||
int patch_start, trailer_start, trailer_end, i;
|
int patch_start, trailer_start, trailer_end, i;
|
||||||
struct strbuf tok = STRBUF_INIT;
|
struct strbuf tok = STRBUF_INIT;
|
||||||
struct strbuf val = STRBUF_INIT;
|
struct strbuf val = STRBUF_INIT;
|
||||||
const struct conf_info *conf;
|
|
||||||
|
|
||||||
/* Get the line count */
|
/* Get the line count */
|
||||||
while (lines[count])
|
while (lines[count])
|
||||||
@ -740,11 +776,10 @@ static int process_input_file(FILE *outfile,
|
|||||||
/* Parse trailer lines */
|
/* Parse trailer lines */
|
||||||
for (i = trailer_start; i < trailer_end; i++) {
|
for (i = trailer_start; i < trailer_end; i++) {
|
||||||
if (lines[i]->buf[0] != comment_line_char &&
|
if (lines[i]->buf[0] != comment_line_char &&
|
||||||
!parse_trailer(&tok, &val, &conf, lines[i]->buf))
|
!parse_trailer(&tok, &val, NULL, lines[i]->buf))
|
||||||
add_trailer_item(head,
|
add_trailer_item(head,
|
||||||
strbuf_detach(&tok, NULL),
|
strbuf_detach(&tok, NULL),
|
||||||
strbuf_detach(&val, NULL),
|
strbuf_detach(&val, NULL));
|
||||||
conf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return trailer_end;
|
return trailer_end;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user