]> git.ipfire.org Git - thirdparty/git.git/blobdiff - trailer.c
Merge branch 'rj/add-i-leak-fix'
[thirdparty/git.git] / trailer.c
index 57b4aa7d5acb515b03b2cf123744d8af34d30166..c72ae687099f0d2d21d8dacddf553eabc6ddca8c 100644 (file)
--- a/trailer.c
+++ b/trailer.c
@@ -144,38 +144,6 @@ static char last_non_space_char(const char *s)
        return '\0';
 }
 
-static void print_tok_val(struct strbuf *out, const char *tok, const char *val)
-{
-       char c;
-
-       if (!tok) {
-               strbuf_addf(out, "%s\n", val);
-               return;
-       }
-
-       c = last_non_space_char(tok);
-       if (!c)
-               return;
-       if (strchr(separators, c))
-               strbuf_addf(out, "%s%s\n", tok, val);
-       else
-               strbuf_addf(out, "%s%c %s\n", tok, separators[0], val);
-}
-
-void format_trailers(const struct process_trailer_options *opts,
-                    struct list_head *trailers,
-                    struct strbuf *out)
-{
-       struct list_head *pos;
-       struct trailer_item *item;
-       list_for_each(pos, trailers) {
-               item = list_entry(pos, struct trailer_item, list);
-               if ((!opts->trim_empty || strlen(item->value) > 0) &&
-                   (!opts->only_trailers || item->token))
-                       print_tok_val(out, item->token, item->value);
-       }
-}
-
 static struct trailer_item *trailer_from_arg(struct arg_item *arg_tok)
 {
        struct trailer_item *new_item = xcalloc(1, sizeof(*new_item));
@@ -871,7 +839,7 @@ static size_t find_trailer_block_start(const char *buf, size_t len)
 
        /* The first paragraph is the title and cannot be trailers */
        for (s = buf; s < buf + len; s = next_line(s)) {
-               if (s[0] == comment_line_char)
+               if (starts_with_mem(s, buf + len - s, comment_line_str))
                        continue;
                if (is_blank_line(s))
                        break;
@@ -891,7 +859,7 @@ static size_t find_trailer_block_start(const char *buf, size_t len)
                const char **p;
                ssize_t separator_pos;
 
-               if (bol[0] == comment_line_char) {
+               if (starts_with_mem(bol, buf + len - bol, comment_line_str)) {
                        non_trailer_lines += possible_continuation_lines;
                        possible_continuation_lines = 0;
                        continue;
@@ -1002,7 +970,7 @@ void parse_trailers(const struct process_trailer_options *opts,
        for (i = 0; i < info->trailer_nr; i++) {
                int separator_pos;
                char *trailer = info->trailers[i];
-               if (trailer[0] == comment_line_char)
+               if (starts_with(trailer, comment_line_str))
                        continue;
                separator_pos = find_separator(trailer, separators);
                if (separator_pos >= 1) {
@@ -1084,26 +1052,32 @@ void trailer_info_release(struct trailer_info *info)
        free(info->trailers);
 }
 
-static void format_trailer_info(const struct process_trailer_options *opts,
-                               const struct trailer_info *info,
-                               struct strbuf *out)
+void format_trailers(const struct process_trailer_options *opts,
+                    struct list_head *trailers,
+                    struct strbuf *out)
 {
        size_t origlen = out->len;
-       size_t i;
-
-       for (i = 0; i < info->trailer_nr; i++) {
-               char *trailer = info->trailers[i];
-               ssize_t separator_pos = find_separator(trailer, separators);
+       struct list_head *pos;
+       struct trailer_item *item;
 
-               if (separator_pos >= 1) {
+       list_for_each(pos, trailers) {
+               item = list_entry(pos, struct trailer_item, list);
+               if (item->token) {
                        struct strbuf tok = STRBUF_INIT;
                        struct strbuf val = STRBUF_INIT;
+                       strbuf_addstr(&tok, item->token);
+                       strbuf_addstr(&val, item->value);
+
+                       /*
+                        * Skip key/value pairs where the value was empty. This
+                        * can happen from trailers specified without a
+                        * separator, like `--trailer "Reviewed-by"` (no
+                        * corresponding value).
+                        */
+                       if (opts->trim_empty && !strlen(item->value))
+                               continue;
 
-                       parse_trailer(&tok, &val, NULL, trailer, separator_pos);
                        if (!opts->filter || opts->filter(&tok, opts->filter_data)) {
-                               if (opts->unfold)
-                                       unfold_value(&val);
-
                                if (opts->separator && out->len != origlen)
                                        strbuf_addbuf(out, opts->separator);
                                if (!opts->value_only)
@@ -1111,8 +1085,11 @@ static void format_trailer_info(const struct process_trailer_options *opts,
                                if (!opts->key_only && !opts->value_only) {
                                        if (opts->key_value_separator)
                                                strbuf_addbuf(out, opts->key_value_separator);
-                                       else
-                                               strbuf_addstr(out, ": ");
+                                       else {
+                                               char c = last_non_space_char(tok.buf);
+                                               if (c && !strchr(separators, c))
+                                                       strbuf_addf(out, "%c ", separators[0]);
+                                       }
                                }
                                if (!opts->key_only)
                                        strbuf_addbuf(out, &val);
@@ -1126,13 +1103,13 @@ static void format_trailer_info(const struct process_trailer_options *opts,
                        if (opts->separator && out->len != origlen) {
                                strbuf_addbuf(out, opts->separator);
                        }
-                       strbuf_addstr(out, trailer);
-                       if (opts->separator) {
+                       strbuf_addstr(out, item->value);
+                       if (opts->separator)
                                strbuf_rtrim(out);
-                       }
+                       else
+                               strbuf_addch(out, '\n');
                }
        }
-
 }
 
 void format_trailers_from_commit(const struct process_trailer_options *opts,
@@ -1151,7 +1128,7 @@ void format_trailers_from_commit(const struct process_trailer_options *opts,
                strbuf_add(out, msg + info.trailer_block_start,
                           info.trailer_block_end - info.trailer_block_start);
        } else
-               format_trailer_info(opts, &info, out);
+               format_trailers(opts, &trailer_objects, out);
 
        free_trailers(&trailer_objects);
        trailer_info_release(&info);