mailinfo: release strbuf after use in handle_from()
[gitweb.git] / pretty.c
index 6cc812c2c72c2281299c44fd81376441bb16a0ec..94eab5c89ee1a1fa696b9fc491a5846008a2a255 100644 (file)
--- a/pretty.c
+++ b/pretty.c
@@ -1,4 +1,5 @@
 #include "cache.h"
+#include "config.h"
 #include "commit.h"
 #include "utf8.h"
 #include "diff.h"
@@ -405,11 +406,11 @@ static void add_rfc2047(struct strbuf *sb, const char *line, size_t len,
 const char *show_ident_date(const struct ident_split *ident,
                            const struct date_mode *mode)
 {
-       unsigned long date = 0;
+       timestamp_t date = 0;
        long tz = 0;
 
        if (ident->date_begin && ident->date_end)
-               date = strtoul(ident->date_begin, NULL, 10);
+               date = parse_timestamp(ident->date_begin, NULL, 10);
        if (date_overflows(date))
                date = 0;
        else {
@@ -870,16 +871,6 @@ const char *format_subject(struct strbuf *sb, const char *msg,
        return msg;
 }
 
-static void format_trailers(struct strbuf *sb, const char *msg)
-{
-       struct trailer_info info;
-
-       trailer_info_get(&info, msg);
-       strbuf_add(sb, info.trailer_start,
-                  info.trailer_end - info.trailer_start);
-       trailer_info_release(&info);
-}
-
 static void parse_commit_message(struct format_commit_context *c)
 {
        const char *msg = c->message + c->message_off;
@@ -946,6 +937,7 @@ static size_t parse_color(struct strbuf *sb, /* in UTF-8 */
                          struct format_commit_context *c)
 {
        const char *rest = placeholder;
+       const char *basic_color = NULL;
 
        if (placeholder[1] == '(') {
                const char *begin = placeholder + 2;
@@ -954,23 +946,41 @@ static size_t parse_color(struct strbuf *sb, /* in UTF-8 */
 
                if (!end)
                        return 0;
+
                if (skip_prefix(begin, "auto,", &begin)) {
                        if (!want_color(c->pretty_ctx->color))
                                return end - placeholder + 1;
+               } else if (skip_prefix(begin, "always,", &begin)) {
+                       /* nothing to do; we do not respect want_color at all */
+               } else {
+                       /* the default is the same as "auto" */
+                       if (!want_color(c->pretty_ctx->color))
+                               return end - placeholder + 1;
                }
+
                if (color_parse_mem(begin, end - begin, color) < 0)
                        die(_("unable to parse --pretty format"));
                strbuf_addstr(sb, color);
                return end - placeholder + 1;
        }
+
+       /*
+        * We handle things like "%C(red)" above; for historical reasons, there
+        * are a few colors that can be specified without parentheses (and
+        * they cannot support things like "auto" or "always" at all).
+        */
        if (skip_prefix(placeholder + 1, "red", &rest))
-               strbuf_addstr(sb, GIT_COLOR_RED);
+               basic_color = GIT_COLOR_RED;
        else if (skip_prefix(placeholder + 1, "green", &rest))
-               strbuf_addstr(sb, GIT_COLOR_GREEN);
+               basic_color = GIT_COLOR_GREEN;
        else if (skip_prefix(placeholder + 1, "blue", &rest))
-               strbuf_addstr(sb, GIT_COLOR_BLUE);
+               basic_color = GIT_COLOR_BLUE;
        else if (skip_prefix(placeholder + 1, "reset", &rest))
-               strbuf_addstr(sb, GIT_COLOR_RESET);
+               basic_color = GIT_COLOR_RESET;
+
+       if (basic_color && want_color(c->pretty_ctx->color))
+               strbuf_addstr(sb, basic_color);
+
        return rest - placeholder;
 }
 
@@ -1054,6 +1064,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
        const struct commit *commit = c->commit;
        const char *msg = c->message;
        struct commit_list *p;
+       const char *arg;
        int ch;
 
        /* these are independent of the commit */
@@ -1117,7 +1128,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
 
        /* these depend on the commit */
        if (!commit->object.parsed)
-               parse_object(commit->object.oid.hash);
+               parse_object(&commit->object.oid);
 
        switch (placeholder[0]) {
        case 'H':               /* commit hash */
@@ -1272,9 +1283,18 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
                return 1;
        }
 
-       if (starts_with(placeholder, "(trailers)")) {
-               format_trailers(sb, msg + c->subject_off);
-               return strlen("(trailers)");
+       if (skip_prefix(placeholder, "(trailers", &arg)) {
+               struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT;
+               while (*arg == ':') {
+                       if (skip_prefix(arg, ":only", &arg))
+                               opts.only_trailers = 1;
+                       else if (skip_prefix(arg, ":unfold", &arg))
+                               opts.unfold = 1;
+               }
+               if (*arg == ')') {
+                       format_trailers_from_commit(sb, msg + c->subject_off, &opts);
+                       return arg - placeholder + 1;
+               }
        }
 
        return 0;       /* unknown placeholder */