userformat_find_requirements(): find requirement for the correct format
[gitweb.git] / pretty.c
index 65d20a7a2e7cafd79ff95c02cab3303ebb72351c..7d23c1f8481af3cfd73c76c76fb2e13a2a7e4a9c 100644 (file)
--- a/pretty.c
+++ b/pretty.c
@@ -208,6 +208,58 @@ int has_non_ascii(const char *s)
        return 0;
 }
 
+static int is_rfc822_special(char ch)
+{
+       switch (ch) {
+       case '(':
+       case ')':
+       case '<':
+       case '>':
+       case '[':
+       case ']':
+       case ':':
+       case ';':
+       case '@':
+       case ',':
+       case '.':
+       case '"':
+       case '\\':
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+static int has_rfc822_specials(const char *s, int len)
+{
+       int i;
+       for (i = 0; i < len; i++)
+               if (is_rfc822_special(s[i]))
+                       return 1;
+       return 0;
+}
+
+static void add_rfc822_quoted(struct strbuf *out, const char *s, int len)
+{
+       int i;
+
+       /* just a guess, we may have to also backslash-quote */
+       strbuf_grow(out, len + 2);
+
+       strbuf_addch(out, '"');
+       for (i = 0; i < len; i++) {
+               switch (s[i]) {
+               case '"':
+               case '\\':
+                       strbuf_addch(out, '\\');
+                       /* fall through */
+               default:
+                       strbuf_addch(out, s[i]);
+               }
+       }
+       strbuf_addch(out, '"');
+}
+
 static int is_rfc2047_special(char ch)
 {
        return (non_ascii(ch) || (ch == '=') || (ch == '?') || (ch == '_'));
@@ -293,7 +345,14 @@ void pp_user_info(const char *what, enum cmit_fmt fmt, struct strbuf *sb,
                        name_tail--;
                display_name_length = name_tail - line;
                strbuf_addstr(sb, "From: ");
-               add_rfc2047(sb, line, display_name_length, encoding);
+               if (!has_rfc822_specials(line, display_name_length)) {
+                       add_rfc2047(sb, line, display_name_length, encoding);
+               } else {
+                       struct strbuf quoted = STRBUF_INIT;
+                       add_rfc822_quoted(&quoted, line, display_name_length);
+                       add_rfc2047(sb, quoted.buf, quoted.len, encoding);
+                       strbuf_release(&quoted);
+               }
                strbuf_add(sb, name_tail, namelen - display_name_length);
                strbuf_addch(sb, '\n');
        } else {
@@ -876,11 +935,7 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder,
                                              c->abbrev_parent_hashes.off;
                return 1;
        case 'm':               /* left/right/bottom */
-               strbuf_addch(sb, (commit->object.flags & BOUNDARY)
-                                ? '-'
-                                : (commit->object.flags & SYMMETRIC_LEFT)
-                                ? '<'
-                                : '>');
+               strbuf_addstr(sb, get_revision_mark(NULL, commit));
                return 1;
        case 'd':
                format_decoration(sb, commit);
@@ -1020,7 +1075,7 @@ void userformat_find_requirements(const char *fmt, struct userformat_want *w)
                        return;
                fmt = user_format;
        }
-       strbuf_expand(&dummy, user_format, userformat_want_item, w);
+       strbuf_expand(&dummy, fmt, userformat_want_item, w);
        strbuf_release(&dummy);
 }