diff options
context:
space:
mode:
Diffstat (limited to 'source/parsing.c')
-rw-r--r--source/parsing.c41
1 file changed, 33 insertions, 8 deletions
diff --git a/source/parsing.c b/source/parsing.c
index c992538..587f44d 100644
--- a/source/parsing.c
+++ b/source/parsing.c
@@ -13,6 +13,8 @@
#include "parsing.h"
#include "shared.h"
+#include <mailmap.h>
+
static char *substr(const char *start, const char *end)
{
size_t len;
@@ -29,22 +31,45 @@ static char *substr(const char *start, const char *end)
return buf;
}
+/*
+ * The repository's mailmap, read once per request and applied to every ident
+ * a page shows. Only the blob at HEAD is read, the way git reads a bare
+ * repository, so a repository cannot point the reader at a file on the server.
+ */
+static struct string_list mailmap = STRING_LIST_INIT_DUP;
+static int mailmap_read;
+
+struct string_list *cgit_mailmap(void)
+{
+ if (!ctx.repo || !ctx.repo->enable_mailmap)
+ return NULL;
+ if (!mailmap_read) {
+ mailmap_read = 1;
+ read_mailmap_blob(the_repository, &mailmap, "HEAD:.mailmap");
+ }
+ return mailmap.nr ? &mailmap : NULL;
+}
+
static void parse_user(const char *line, char **name, char **email, timestamp_t *date, int *tz)
{
struct ident_split ident;
struct strbuf address = STRBUF_INIT;
- ptrdiff_t email_len;
+ struct string_list *map;
+ const char *name_start, *mail_start;
+ size_t name_len, mail_len;
if (!split_ident_line(&ident, line, strchrnul(line, '\n') - line)) {
- *name = substr(ident.name_begin, ident.name_end);
+ name_start = ident.name_begin;
+ name_len = ident.name_end - ident.name_begin;
+ mail_start = ident.mail_begin;
+ mail_len = ident.mail_end - ident.mail_begin;
+ map = cgit_mailmap();
+ if (map)
+ map_user(map, &mail_start, &mail_len, &name_start, &name_len);
+ *name = xmemdupz(name_start, name_len);
- // Assembled rather than formatted. The length is a pointer
- // difference, and the precision of a %.*s conversion has to be
- // an int, which cannot hold one on a 64 bit host.
- email_len = ident.mail_end - ident.mail_begin;
strbuf_addch(&address, '<');
- if (email_len > 0)
- strbuf_add(&address, ident.mail_begin, email_len);
+ strbuf_add(&address, mail_start, mail_len);
strbuf_addch(&address, '>');
*email = strbuf_detach(&address, NULL);