int mail_len, char *mail,
unsigned long *time, const char **tz)
{
- int len, tzlen, maillen;
- char *tmp, *endp, *timepos, *mailpos;
+ struct ident_split ident;
+ int len, tzlen, maillen, namelen;
+ char *tmp, *endp, *mailpos;
tmp = strstr(inbuf, what);
if (!tmp)
len = strlen(tmp);
else
len = endp - tmp;
- if (person_len <= len) {
+ if (person_len <= len)
+ goto error_out;
+
+ if (split_ident_line(&ident, tmp, len)) {
error_out:
/* Ugh */
*tz = "(unknown)";
*time = 0;
return;
}
- memcpy(person, tmp, len);
- tmp = person;
- tmp += len;
- *tmp = 0;
- while (person < tmp && *tmp != ' ')
- tmp--;
- if (tmp <= person)
- goto error_out;
- *tz = tmp+1;
- tzlen = (person+len)-(tmp+1);
+ namelen = ident.name_end - ident.name_begin;
+ memcpy(person, ident.name_begin, namelen);
+ person[namelen] = 0;
- *tmp = 0;
- while (person < tmp && *tmp != ' ')
- tmp--;
- if (tmp <= person)
- goto error_out;
- *time = strtoul(tmp, NULL, 10);
- timepos = tmp;
+ maillen = ident.mail_end - ident.mail_begin + 2;
+ memcpy(mail, ident.mail_begin - 1, maillen);
+ mail[maillen] = 0;
- *tmp = 0;
- while (person < tmp && !(*tmp == ' ' && tmp[1] == '<'))
- tmp--;
- if (tmp <= person)
- return;
- mailpos = tmp + 1;
- *tmp = 0;
- maillen = timepos - tmp;
- memcpy(mail, mailpos, maillen);
+ *time = strtoul(ident.date_begin, NULL, 10);
- if (!mailmap.nr)
- return;
+ tzlen = ident.tz_end - ident.tz_begin;
- /*
- * mailmap expansion may make the name longer.
- * make room by pushing stuff down.
- */
- tmp = person + person_len - (tzlen + 1);
- memmove(tmp, *tz, tzlen);
+ /* Place tz at the end of person */
+ *tz = tmp = person + person_len - (tzlen + 1);
+ memcpy(tmp, ident.tz_begin, tzlen);
tmp[tzlen] = 0;
- *tz = tmp;
+
+ if (!mailmap.nr)
+ return;
/*
* Now, convert both name and e-mail using mailmap
char emailbuf[1024];
size_t len;
const char *eol;
- const char *boemail, *eoemail;
struct strbuf subject = STRBUF_INIT;
+ struct ident_split ident;
- boemail = strchr(author, '<');
- if (!boemail)
- return;
- eoemail = strchr(boemail, '>');
- if (!eoemail)
+ if (split_ident_line(&ident, author, strlen(author)))
return;
/* copy author name to namebuf, to support matching on both name and email */
- memcpy(namebuf, author, boemail - author);
- len = boemail - author;
- while (len > 0 && isspace(namebuf[len-1]))
- len--;
+ len = ident.name_end - ident.name_begin;
+ memcpy(namebuf, ident.name_begin, len);
namebuf[len] = 0;
/* copy email name to emailbuf, to allow email replacement as well */
- memcpy(emailbuf, boemail+1, eoemail - boemail);
- emailbuf[eoemail - boemail - 1] = 0;
-
- if (!map_user(&log->mailmap, emailbuf, sizeof(emailbuf), namebuf, sizeof(namebuf))) {
- while (author < boemail && isspace(*author))
- author++;
- for (len = 0;
- len < sizeof(namebuf) - 1 && author + len < boemail;
- len++)
- namebuf[len] = author[len];
- while (0 < len && isspace(namebuf[len-1]))
- len--;
- namebuf[len] = '\0';
- }
- else
- len = strlen(namebuf);
+ len = ident.mail_end - ident.mail_begin;
+ memcpy(emailbuf, ident.mail_begin, len);
+ emailbuf[len] = 0;
+
+ map_user(&log->mailmap, emailbuf, sizeof(emailbuf), namebuf, sizeof(namebuf));
+ len = strlen(namebuf);
if (log->email) {
size_t room = sizeof(namebuf) - len - 1;
const char *what, struct strbuf *sb,
const char *line, const char *encoding)
{
+ struct ident_split ident;
+ int linelen, namelen;
+ char *line_end, *date;
int max_length = 78; /* per rfc2822 */
- char *date;
- int namelen;
unsigned long time;
int tz;
if (pp->fmt == CMIT_FMT_ONELINE)
return;
- date = strchr(line, '>');
- if (!date)
+
+ line_end = strchr(line, '\n');
+ if (!line_end) {
+ line_end = strchr(line, '\0');
+ if (!line_end)
+ return;
+ }
+
+ linelen = ++line_end - line;
+ if (split_ident_line(&ident, line, linelen))
return;
- namelen = ++date - line;
- time = strtoul(date, &date, 10);
+
+ namelen = ident.mail_end - ident.name_begin + 1;
+ time = strtoul(ident.date_begin, &date, 10);
tz = strtol(date, NULL, 10);
if (pp->fmt == CMIT_FMT_EMAIL) {
- char *name_tail = strchr(line, '<');
int display_name_length;
- if (!name_tail)
- return;
- while (line < name_tail && isspace(name_tail[-1]))
- name_tail--;
- display_name_length = name_tail - line;
+
+ display_name_length = ident.name_end - ident.name_begin;
+
strbuf_addstr(sb, "From: ");
if (needs_rfc2047_encoding(line, display_name_length, RFC2047_ADDRESS)) {
add_rfc2047(sb, line, display_name_length,
}
if (namelen - display_name_length + last_line_length(sb) > max_length) {
strbuf_addch(sb, '\n');
- if (!isspace(name_tail[0]))
+ if (!isspace(ident.name_end[0]))
strbuf_addch(sb, ' ');
}
- strbuf_add(sb, name_tail, namelen - display_name_length);
+ strbuf_add(sb, ident.name_end, namelen - display_name_length);
strbuf_addch(sb, '\n');
} else {
strbuf_addf(sb, "%s: %.*s%.*s\n", what,