Merge branch 'la/trailer-cleanups' into next
Code clean-up. * la/trailer-cleanups: trailer: use offsets for trailer_start/trailer_end trailer: rename *_DEFAULT enums to *_UNSPECIFIED trailer: teach find_patch_start about --no-divider trailer: split process_command_line_args into separate functions trailer: split process_input_file into separate pieces trailer: separate public from internal portion of trailer_iterator
This commit is contained in:
126
trailer.c
126
trailer.c
@ -388,7 +388,7 @@ static void process_trailers_lists(struct list_head *head,
|
|||||||
int trailer_set_where(enum trailer_where *item, const char *value)
|
int trailer_set_where(enum trailer_where *item, const char *value)
|
||||||
{
|
{
|
||||||
if (!value)
|
if (!value)
|
||||||
*item = WHERE_DEFAULT;
|
*item = WHERE_UNSPECIFIED;
|
||||||
else if (!strcasecmp("after", value))
|
else if (!strcasecmp("after", value))
|
||||||
*item = WHERE_AFTER;
|
*item = WHERE_AFTER;
|
||||||
else if (!strcasecmp("before", value))
|
else if (!strcasecmp("before", value))
|
||||||
@ -405,7 +405,7 @@ int trailer_set_where(enum trailer_where *item, const char *value)
|
|||||||
int trailer_set_if_exists(enum trailer_if_exists *item, const char *value)
|
int trailer_set_if_exists(enum trailer_if_exists *item, const char *value)
|
||||||
{
|
{
|
||||||
if (!value)
|
if (!value)
|
||||||
*item = EXISTS_DEFAULT;
|
*item = EXISTS_UNSPECIFIED;
|
||||||
else if (!strcasecmp("addIfDifferent", value))
|
else if (!strcasecmp("addIfDifferent", value))
|
||||||
*item = EXISTS_ADD_IF_DIFFERENT;
|
*item = EXISTS_ADD_IF_DIFFERENT;
|
||||||
else if (!strcasecmp("addIfDifferentNeighbor", value))
|
else if (!strcasecmp("addIfDifferentNeighbor", value))
|
||||||
@ -424,7 +424,7 @@ int trailer_set_if_exists(enum trailer_if_exists *item, const char *value)
|
|||||||
int trailer_set_if_missing(enum trailer_if_missing *item, const char *value)
|
int trailer_set_if_missing(enum trailer_if_missing *item, const char *value)
|
||||||
{
|
{
|
||||||
if (!value)
|
if (!value)
|
||||||
*item = MISSING_DEFAULT;
|
*item = MISSING_UNSPECIFIED;
|
||||||
else if (!strcasecmp("doNothing", value))
|
else if (!strcasecmp("doNothing", value))
|
||||||
*item = MISSING_DO_NOTHING;
|
*item = MISSING_DO_NOTHING;
|
||||||
else if (!strcasecmp("add", value))
|
else if (!strcasecmp("add", value))
|
||||||
@ -586,7 +586,10 @@ static void ensure_configured(void)
|
|||||||
if (configured)
|
if (configured)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Default config must be setup first */
|
/*
|
||||||
|
* Default config must be setup first. These defaults are used if there
|
||||||
|
* are no "trailer.*" or "trailer.<token>.*" options configured.
|
||||||
|
*/
|
||||||
default_conf_info.where = WHERE_END;
|
default_conf_info.where = WHERE_END;
|
||||||
default_conf_info.if_exists = EXISTS_ADD_IF_DIFFERENT_NEIGHBOR;
|
default_conf_info.if_exists = EXISTS_ADD_IF_DIFFERENT_NEIGHBOR;
|
||||||
default_conf_info.if_missing = MISSING_ADD;
|
default_conf_info.if_missing = MISSING_ADD;
|
||||||
@ -701,20 +704,35 @@ static void add_arg_item(struct list_head *arg_head, char *tok, char *val,
|
|||||||
new_item->value = val;
|
new_item->value = val;
|
||||||
duplicate_conf(&new_item->conf, conf);
|
duplicate_conf(&new_item->conf, conf);
|
||||||
if (new_trailer_item) {
|
if (new_trailer_item) {
|
||||||
if (new_trailer_item->where != WHERE_DEFAULT)
|
if (new_trailer_item->where != WHERE_UNSPECIFIED)
|
||||||
new_item->conf.where = new_trailer_item->where;
|
new_item->conf.where = new_trailer_item->where;
|
||||||
if (new_trailer_item->if_exists != EXISTS_DEFAULT)
|
if (new_trailer_item->if_exists != EXISTS_UNSPECIFIED)
|
||||||
new_item->conf.if_exists = new_trailer_item->if_exists;
|
new_item->conf.if_exists = new_trailer_item->if_exists;
|
||||||
if (new_trailer_item->if_missing != MISSING_DEFAULT)
|
if (new_trailer_item->if_missing != MISSING_UNSPECIFIED)
|
||||||
new_item->conf.if_missing = new_trailer_item->if_missing;
|
new_item->conf.if_missing = new_trailer_item->if_missing;
|
||||||
}
|
}
|
||||||
list_add_tail(&new_item->list, arg_head);
|
list_add_tail(&new_item->list, arg_head);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_command_line_args(struct list_head *arg_head,
|
static void parse_trailers_from_config(struct list_head *config_head)
|
||||||
struct list_head *new_trailer_head)
|
|
||||||
{
|
{
|
||||||
struct arg_item *item;
|
struct arg_item *item;
|
||||||
|
struct list_head *pos;
|
||||||
|
|
||||||
|
/* Add an arg item for each configured trailer with a command */
|
||||||
|
list_for_each(pos, &conf_head) {
|
||||||
|
item = list_entry(pos, struct arg_item, list);
|
||||||
|
if (item->conf.command)
|
||||||
|
add_arg_item(config_head,
|
||||||
|
xstrdup(token_from_item(item, NULL)),
|
||||||
|
xstrdup(""),
|
||||||
|
&item->conf, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void parse_trailers_from_command_line_args(struct list_head *arg_head,
|
||||||
|
struct list_head *new_trailer_head)
|
||||||
|
{
|
||||||
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;
|
||||||
@ -726,16 +744,6 @@ static void process_command_line_args(struct list_head *arg_head,
|
|||||||
*/
|
*/
|
||||||
char *cl_separators = xstrfmt("=%s", separators);
|
char *cl_separators = xstrfmt("=%s", separators);
|
||||||
|
|
||||||
/* Add an arg item for each configured trailer with a command */
|
|
||||||
list_for_each(pos, &conf_head) {
|
|
||||||
item = list_entry(pos, struct arg_item, list);
|
|
||||||
if (item->conf.command)
|
|
||||||
add_arg_item(arg_head,
|
|
||||||
xstrdup(token_from_item(item, NULL)),
|
|
||||||
xstrdup(""),
|
|
||||||
&item->conf, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add an arg item for each trailer on the command line */
|
/* Add an arg item for each trailer on the command line */
|
||||||
list_for_each(pos, new_trailer_head) {
|
list_for_each(pos, new_trailer_head) {
|
||||||
struct new_trailer_item *tr =
|
struct new_trailer_item *tr =
|
||||||
@ -807,14 +815,14 @@ static ssize_t last_line(const char *buf, size_t len)
|
|||||||
* Return the position of the start of the patch or the length of str if there
|
* Return the position of the start of the patch or the length of str if there
|
||||||
* is no patch in the message.
|
* is no patch in the message.
|
||||||
*/
|
*/
|
||||||
static size_t find_patch_start(const char *str)
|
static size_t find_patch_start(const char *str, int no_divider)
|
||||||
{
|
{
|
||||||
const char *s;
|
const char *s;
|
||||||
|
|
||||||
for (s = str; *s; s = next_line(s)) {
|
for (s = str; *s; s = next_line(s)) {
|
||||||
const char *v;
|
const char *v;
|
||||||
|
|
||||||
if (skip_prefix(s, "---", &v) && isspace(*v))
|
if (!no_divider && skip_prefix(s, "---", &v) && isspace(*v))
|
||||||
return s - str;
|
return s - str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -961,28 +969,24 @@ static void unfold_value(struct strbuf *val)
|
|||||||
strbuf_release(&out);
|
strbuf_release(&out);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t process_input_file(FILE *outfile,
|
/*
|
||||||
const char *str,
|
* Parse trailers in "str", populating the trailer info and "head"
|
||||||
struct list_head *head,
|
* linked list structure.
|
||||||
const struct process_trailer_options *opts)
|
*/
|
||||||
|
static void parse_trailers(struct trailer_info *info,
|
||||||
|
const char *str,
|
||||||
|
struct list_head *head,
|
||||||
|
const struct process_trailer_options *opts)
|
||||||
{
|
{
|
||||||
struct trailer_info info;
|
|
||||||
struct strbuf tok = STRBUF_INIT;
|
struct strbuf tok = STRBUF_INIT;
|
||||||
struct strbuf val = STRBUF_INIT;
|
struct strbuf val = STRBUF_INIT;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
trailer_info_get(&info, str, opts);
|
trailer_info_get(info, str, opts);
|
||||||
|
|
||||||
/* Print lines before the trailers as is */
|
for (i = 0; i < info->trailer_nr; i++) {
|
||||||
if (!opts->only_trailers)
|
|
||||||
fwrite(str, 1, info.trailer_start - str, outfile);
|
|
||||||
|
|
||||||
if (!opts->only_trailers && !info.blank_line_before_trailer)
|
|
||||||
fprintf(outfile, "\n");
|
|
||||||
|
|
||||||
for (i = 0; i < info.trailer_nr; i++) {
|
|
||||||
int separator_pos;
|
int separator_pos;
|
||||||
char *trailer = info.trailers[i];
|
char *trailer = info->trailers[i];
|
||||||
if (trailer[0] == comment_line_char)
|
if (trailer[0] == comment_line_char)
|
||||||
continue;
|
continue;
|
||||||
separator_pos = find_separator(trailer, separators);
|
separator_pos = find_separator(trailer, separators);
|
||||||
@ -1002,10 +1006,6 @@ static size_t process_input_file(FILE *outfile,
|
|||||||
strbuf_detach(&val, NULL));
|
strbuf_detach(&val, NULL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trailer_info_release(&info);
|
|
||||||
|
|
||||||
return info.trailer_end - str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_all(struct list_head *head)
|
static void free_all(struct list_head *head)
|
||||||
@ -1054,7 +1054,7 @@ void process_trailers(const char *file,
|
|||||||
{
|
{
|
||||||
LIST_HEAD(head);
|
LIST_HEAD(head);
|
||||||
struct strbuf sb = STRBUF_INIT;
|
struct strbuf sb = STRBUF_INIT;
|
||||||
size_t trailer_end;
|
struct trailer_info info;
|
||||||
FILE *outfile = stdout;
|
FILE *outfile = stdout;
|
||||||
|
|
||||||
ensure_configured();
|
ensure_configured();
|
||||||
@ -1064,22 +1064,33 @@ void process_trailers(const char *file,
|
|||||||
if (opts->in_place)
|
if (opts->in_place)
|
||||||
outfile = create_in_place_tempfile(file);
|
outfile = create_in_place_tempfile(file);
|
||||||
|
|
||||||
|
parse_trailers(&info, sb.buf, &head, opts);
|
||||||
|
|
||||||
/* Print the lines before the trailers */
|
/* Print the lines before the trailers */
|
||||||
trailer_end = process_input_file(outfile, sb.buf, &head, opts);
|
if (!opts->only_trailers)
|
||||||
|
fwrite(sb.buf, 1, info.trailer_start, outfile);
|
||||||
|
|
||||||
|
if (!opts->only_trailers && !info.blank_line_before_trailer)
|
||||||
|
fprintf(outfile, "\n");
|
||||||
|
|
||||||
|
|
||||||
if (!opts->only_input) {
|
if (!opts->only_input) {
|
||||||
|
LIST_HEAD(config_head);
|
||||||
LIST_HEAD(arg_head);
|
LIST_HEAD(arg_head);
|
||||||
process_command_line_args(&arg_head, new_trailer_head);
|
parse_trailers_from_config(&config_head);
|
||||||
|
parse_trailers_from_command_line_args(&arg_head, new_trailer_head);
|
||||||
|
list_splice(&config_head, &arg_head);
|
||||||
process_trailers_lists(&head, &arg_head);
|
process_trailers_lists(&head, &arg_head);
|
||||||
}
|
}
|
||||||
|
|
||||||
print_all(outfile, &head, opts);
|
print_all(outfile, &head, opts);
|
||||||
|
|
||||||
free_all(&head);
|
free_all(&head);
|
||||||
|
trailer_info_release(&info);
|
||||||
|
|
||||||
/* Print the lines after the trailers as is */
|
/* Print the lines after the trailers as is */
|
||||||
if (!opts->only_trailers)
|
if (!opts->only_trailers)
|
||||||
fwrite(sb.buf + trailer_end, 1, sb.len - trailer_end, outfile);
|
fwrite(sb.buf + info.trailer_end, 1, sb.len - info.trailer_end, outfile);
|
||||||
|
|
||||||
if (opts->in_place)
|
if (opts->in_place)
|
||||||
if (rename_tempfile(&trailers_tempfile, file))
|
if (rename_tempfile(&trailers_tempfile, file))
|
||||||
@ -1091,7 +1102,7 @@ void process_trailers(const char *file,
|
|||||||
void trailer_info_get(struct trailer_info *info, const char *str,
|
void trailer_info_get(struct trailer_info *info, const char *str,
|
||||||
const struct process_trailer_options *opts)
|
const struct process_trailer_options *opts)
|
||||||
{
|
{
|
||||||
int patch_start, trailer_end, trailer_start;
|
size_t patch_start, trailer_end = 0, trailer_start = 0;
|
||||||
struct strbuf **trailer_lines, **ptr;
|
struct strbuf **trailer_lines, **ptr;
|
||||||
char **trailer_strings = NULL;
|
char **trailer_strings = NULL;
|
||||||
size_t nr = 0, alloc = 0;
|
size_t nr = 0, alloc = 0;
|
||||||
@ -1099,11 +1110,7 @@ void trailer_info_get(struct trailer_info *info, const char *str,
|
|||||||
|
|
||||||
ensure_configured();
|
ensure_configured();
|
||||||
|
|
||||||
if (opts->no_divider)
|
patch_start = find_patch_start(str, opts->no_divider);
|
||||||
patch_start = strlen(str);
|
|
||||||
else
|
|
||||||
patch_start = find_patch_start(str);
|
|
||||||
|
|
||||||
trailer_end = find_trailer_end(str, patch_start);
|
trailer_end = find_trailer_end(str, patch_start);
|
||||||
trailer_start = find_trailer_start(str, trailer_end);
|
trailer_start = find_trailer_start(str, trailer_end);
|
||||||
|
|
||||||
@ -1130,8 +1137,8 @@ void trailer_info_get(struct trailer_info *info, const char *str,
|
|||||||
|
|
||||||
info->blank_line_before_trailer = ends_with_blank_line(str,
|
info->blank_line_before_trailer = ends_with_blank_line(str,
|
||||||
trailer_start);
|
trailer_start);
|
||||||
info->trailer_start = str + trailer_start;
|
info->trailer_start = trailer_start;
|
||||||
info->trailer_end = str + trailer_end;
|
info->trailer_end = trailer_end;
|
||||||
info->trailers = trailer_strings;
|
info->trailers = trailer_strings;
|
||||||
info->trailer_nr = nr;
|
info->trailer_nr = nr;
|
||||||
}
|
}
|
||||||
@ -1146,6 +1153,7 @@ void trailer_info_release(struct trailer_info *info)
|
|||||||
|
|
||||||
static void format_trailer_info(struct strbuf *out,
|
static void format_trailer_info(struct strbuf *out,
|
||||||
const struct trailer_info *info,
|
const struct trailer_info *info,
|
||||||
|
const char *msg,
|
||||||
const struct process_trailer_options *opts)
|
const struct process_trailer_options *opts)
|
||||||
{
|
{
|
||||||
size_t origlen = out->len;
|
size_t origlen = out->len;
|
||||||
@ -1155,7 +1163,7 @@ static void format_trailer_info(struct strbuf *out,
|
|||||||
if (!opts->only_trailers && !opts->unfold && !opts->filter &&
|
if (!opts->only_trailers && !opts->unfold && !opts->filter &&
|
||||||
!opts->separator && !opts->key_only && !opts->value_only &&
|
!opts->separator && !opts->key_only && !opts->value_only &&
|
||||||
!opts->key_value_separator) {
|
!opts->key_value_separator) {
|
||||||
strbuf_add(out, info->trailer_start,
|
strbuf_add(out, msg + info->trailer_start,
|
||||||
info->trailer_end - info->trailer_start);
|
info->trailer_end - info->trailer_start);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1210,7 +1218,7 @@ void format_trailers_from_commit(struct strbuf *out, const char *msg,
|
|||||||
struct trailer_info info;
|
struct trailer_info info;
|
||||||
|
|
||||||
trailer_info_get(&info, msg, opts);
|
trailer_info_get(&info, msg, opts);
|
||||||
format_trailer_info(out, &info, opts);
|
format_trailer_info(out, &info, msg, opts);
|
||||||
trailer_info_release(&info);
|
trailer_info_release(&info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1220,14 +1228,14 @@ void trailer_iterator_init(struct trailer_iterator *iter, const char *msg)
|
|||||||
strbuf_init(&iter->key, 0);
|
strbuf_init(&iter->key, 0);
|
||||||
strbuf_init(&iter->val, 0);
|
strbuf_init(&iter->val, 0);
|
||||||
opts.no_divider = 1;
|
opts.no_divider = 1;
|
||||||
trailer_info_get(&iter->info, msg, &opts);
|
trailer_info_get(&iter->internal.info, msg, &opts);
|
||||||
iter->cur = 0;
|
iter->internal.cur = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int trailer_iterator_advance(struct trailer_iterator *iter)
|
int trailer_iterator_advance(struct trailer_iterator *iter)
|
||||||
{
|
{
|
||||||
while (iter->cur < iter->info.trailer_nr) {
|
while (iter->internal.cur < iter->internal.info.trailer_nr) {
|
||||||
char *trailer = iter->info.trailers[iter->cur++];
|
char *trailer = iter->internal.info.trailers[iter->internal.cur++];
|
||||||
int separator_pos = find_separator(trailer, separators);
|
int separator_pos = find_separator(trailer, separators);
|
||||||
|
|
||||||
if (separator_pos < 1)
|
if (separator_pos < 1)
|
||||||
@ -1245,7 +1253,7 @@ int trailer_iterator_advance(struct trailer_iterator *iter)
|
|||||||
|
|
||||||
void trailer_iterator_release(struct trailer_iterator *iter)
|
void trailer_iterator_release(struct trailer_iterator *iter)
|
||||||
{
|
{
|
||||||
trailer_info_release(&iter->info);
|
trailer_info_release(&iter->internal.info);
|
||||||
strbuf_release(&iter->val);
|
strbuf_release(&iter->val);
|
||||||
strbuf_release(&iter->key);
|
strbuf_release(&iter->key);
|
||||||
}
|
}
|
||||||
|
19
trailer.h
19
trailer.h
@ -5,14 +5,14 @@
|
|||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
|
|
||||||
enum trailer_where {
|
enum trailer_where {
|
||||||
WHERE_DEFAULT,
|
WHERE_UNSPECIFIED,
|
||||||
WHERE_END,
|
WHERE_END,
|
||||||
WHERE_AFTER,
|
WHERE_AFTER,
|
||||||
WHERE_BEFORE,
|
WHERE_BEFORE,
|
||||||
WHERE_START
|
WHERE_START
|
||||||
};
|
};
|
||||||
enum trailer_if_exists {
|
enum trailer_if_exists {
|
||||||
EXISTS_DEFAULT,
|
EXISTS_UNSPECIFIED,
|
||||||
EXISTS_ADD_IF_DIFFERENT_NEIGHBOR,
|
EXISTS_ADD_IF_DIFFERENT_NEIGHBOR,
|
||||||
EXISTS_ADD_IF_DIFFERENT,
|
EXISTS_ADD_IF_DIFFERENT,
|
||||||
EXISTS_ADD,
|
EXISTS_ADD,
|
||||||
@ -20,7 +20,7 @@ enum trailer_if_exists {
|
|||||||
EXISTS_DO_NOTHING
|
EXISTS_DO_NOTHING
|
||||||
};
|
};
|
||||||
enum trailer_if_missing {
|
enum trailer_if_missing {
|
||||||
MISSING_DEFAULT,
|
MISSING_UNSPECIFIED,
|
||||||
MISSING_ADD,
|
MISSING_ADD,
|
||||||
MISSING_DO_NOTHING
|
MISSING_DO_NOTHING
|
||||||
};
|
};
|
||||||
@ -37,11 +37,10 @@ struct trailer_info {
|
|||||||
int blank_line_before_trailer;
|
int blank_line_before_trailer;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pointers to the start and end of the trailer block found. If there
|
* Offsets to the trailer block start and end positions in the input
|
||||||
* is no trailer block found, these 2 pointers point to the end of the
|
* string. If no trailer block is found, these are set to 0.
|
||||||
* input string.
|
|
||||||
*/
|
*/
|
||||||
const char *trailer_start, *trailer_end;
|
size_t trailer_start, trailer_end;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Array of trailers found.
|
* Array of trailers found.
|
||||||
@ -119,8 +118,10 @@ struct trailer_iterator {
|
|||||||
struct strbuf val;
|
struct strbuf val;
|
||||||
|
|
||||||
/* private */
|
/* private */
|
||||||
struct trailer_info info;
|
struct {
|
||||||
size_t cur;
|
struct trailer_info info;
|
||||||
|
size_t cur;
|
||||||
|
} internal;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user