Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
mailmap: simplify map_user() interface
Simplify map_user(), mostly to avoid copies of string buffers. It
also simplifies caller functions.

map_user() directly receive pointers and length from the commit buffer
as mail and name. If mapping of the user and mail can be done, the
pointer is updated to a new location. Lengths are also updated if
necessary.

The caller of map_user() can then copy the new email and name if
necessary.

Signed-off-by: Antoine Pelisse <apelisse@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Antoine Pelisse authored and Junio C Hamano committed Jan 10, 2013
1 parent 388c7f8 commit ea02ffa
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 144 deletions.
156 changes: 81 additions & 75 deletions builtin/blame.c
Expand Up @@ -1321,31 +1321,31 @@ static void pass_blame(struct scoreboard *sb, struct origin *origin, int opt)
* Information on commits, used for output.
*/
struct commit_info {
const char *author;
const char *author_mail;
struct strbuf author;
struct strbuf author_mail;
unsigned long author_time;
const char *author_tz;
struct strbuf author_tz;

/* filled only when asked for details */
const char *committer;
const char *committer_mail;
struct strbuf committer;
struct strbuf committer_mail;
unsigned long committer_time;
const char *committer_tz;
struct strbuf committer_tz;

const char *summary;
struct strbuf summary;
};

/*
* Parse author/committer line in the commit object buffer
*/
static void get_ac_line(const char *inbuf, const char *what,
int person_len, char *person,
int mail_len, char *mail,
unsigned long *time, const char **tz)
struct strbuf *name, struct strbuf *mail,
unsigned long *time, struct strbuf *tz)
{
struct ident_split ident;
int len, tzlen, maillen, namelen;
char *tmp, *endp, *mailpos;
size_t len, maillen, namelen;
char *tmp, *endp;
const char *namebuf, *mailbuf;

tmp = strstr(inbuf, what);
if (!tmp)
Expand All @@ -1356,51 +1356,61 @@ static void get_ac_line(const char *inbuf, const char *what,
len = strlen(tmp);
else
len = endp - tmp;
if (person_len <= len)
goto error_out;

if (split_ident_line(&ident, tmp, len)) {
error_out:
/* Ugh */
*tz = "(unknown)";
strcpy(person, *tz);
strcpy(mail, *tz);
tmp = "(unknown)";
strbuf_addstr(name, tmp);
strbuf_addstr(mail, tmp);
strbuf_addstr(tz, tmp);
*time = 0;
return;
}

namelen = ident.name_end - ident.name_begin;
memcpy(person, ident.name_begin, namelen);
person[namelen] = 0;
namebuf = ident.name_begin;

maillen = ident.mail_end - ident.mail_begin + 2;
memcpy(mail, ident.mail_begin - 1, maillen);
mail[maillen] = 0;
maillen = ident.mail_end - ident.mail_begin;
mailbuf = ident.mail_begin;

*time = strtoul(ident.date_begin, NULL, 10);

tzlen = ident.tz_end - ident.tz_begin;

/* Place tz at the end of person */
*tz = tmp = person + person_len - (tzlen + 1);
memcpy(tmp, ident.tz_begin, tzlen);
tmp[tzlen] = 0;

if (!mailmap.nr)
return;
len = ident.tz_end - ident.tz_begin;
strbuf_add(tz, ident.tz_begin, len);

/*
* Now, convert both name and e-mail using mailmap
*/
if (map_user(&mailmap, mail+1, mail_len-1, person, tmp-person-1)) {
/* Add a trailing '>' to email, since map_user returns plain emails
Note: It already has '<', since we replace from mail+1 */
mailpos = memchr(mail, '\0', mail_len);
if (mailpos && mailpos-mail < mail_len - 1) {
*mailpos = '>';
*(mailpos+1) = '\0';
}
}
map_user(&mailmap, &mailbuf, &maillen,
&namebuf, &namelen);

strbuf_addf(mail, "<%.*s>", (int)maillen, mailbuf);
strbuf_add(name, namebuf, namelen);
}

static void commit_info_init(struct commit_info *ci)
{

strbuf_init(&ci->author, 0);
strbuf_init(&ci->author_mail, 0);
strbuf_init(&ci->author_tz, 0);
strbuf_init(&ci->committer, 0);
strbuf_init(&ci->committer_mail, 0);
strbuf_init(&ci->committer_tz, 0);
strbuf_init(&ci->summary, 0);
}

static void commit_info_destroy(struct commit_info *ci)
{

strbuf_release(&ci->author);
strbuf_release(&ci->author_mail);
strbuf_release(&ci->author_tz);
strbuf_release(&ci->committer);
strbuf_release(&ci->committer_mail);
strbuf_release(&ci->committer_tz);
strbuf_release(&ci->summary);
}

static void get_commit_info(struct commit *commit,
Expand All @@ -1410,11 +1420,8 @@ static void get_commit_info(struct commit *commit,
int len;
const char *subject, *encoding;
char *reencoded, *message;
static char author_name[1024];
static char author_mail[1024];
static char committer_name[1024];
static char committer_mail[1024];
static char summary_buf[1024];

commit_info_init(ret);

/*
* We've operated without save_commit_buffer, so
Expand All @@ -1432,33 +1439,25 @@ static void get_commit_info(struct commit *commit,
encoding = get_log_output_encoding();
reencoded = logmsg_reencode(commit, encoding);
message = reencoded ? reencoded : commit->buffer;
ret->author = author_name;
ret->author_mail = author_mail;
get_ac_line(message, "\nauthor ",
sizeof(author_name), author_name,
sizeof(author_mail), author_mail,
&ret->author, &ret->author_mail,
&ret->author_time, &ret->author_tz);

if (!detailed) {
free(reencoded);
return;
}

ret->committer = committer_name;
ret->committer_mail = committer_mail;
get_ac_line(message, "\ncommitter ",
sizeof(committer_name), committer_name,
sizeof(committer_mail), committer_mail,
&ret->committer, &ret->committer_mail,
&ret->committer_time, &ret->committer_tz);

ret->summary = summary_buf;
len = find_commit_subject(message, &subject);
if (len && len < sizeof(summary_buf)) {
memcpy(summary_buf, subject, len);
summary_buf[len] = 0;
} else {
sprintf(summary_buf, "(%s)", sha1_to_hex(commit->object.sha1));
}
if (len)
strbuf_add(&ret->summary, subject, len);
else
strbuf_addf(&ret->summary, "(%s)", sha1_to_hex(commit->object.sha1));

free(reencoded);
}

Expand Down Expand Up @@ -1487,22 +1486,25 @@ static int emit_one_suspect_detail(struct origin *suspect, int repeat)

suspect->commit->object.flags |= METAINFO_SHOWN;
get_commit_info(suspect->commit, &ci, 1);
printf("author %s\n", ci.author);
printf("author-mail %s\n", ci.author_mail);
printf("author %s\n", ci.author.buf);
printf("author-mail %s\n", ci.author_mail.buf);
printf("author-time %lu\n", ci.author_time);
printf("author-tz %s\n", ci.author_tz);
printf("committer %s\n", ci.committer);
printf("committer-mail %s\n", ci.committer_mail);
printf("author-tz %s\n", ci.author_tz.buf);
printf("committer %s\n", ci.committer.buf);
printf("committer-mail %s\n", ci.committer_mail.buf);
printf("committer-time %lu\n", ci.committer_time);
printf("committer-tz %s\n", ci.committer_tz);
printf("summary %s\n", ci.summary);
printf("committer-tz %s\n", ci.committer_tz.buf);
printf("summary %s\n", ci.summary.buf);
if (suspect->commit->object.flags & UNINTERESTING)
printf("boundary\n");
if (suspect->previous) {
struct origin *prev = suspect->previous;
printf("previous %s ", sha1_to_hex(prev->commit->object.sha1));
write_name_quoted(prev->path, stdout, '\n');
}

commit_info_destroy(&ci);

return 1;
}

Expand Down Expand Up @@ -1689,11 +1691,11 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)
if (opt & OUTPUT_ANNOTATE_COMPAT) {
const char *name;
if (opt & OUTPUT_SHOW_EMAIL)
name = ci.author_mail;
name = ci.author_mail.buf;
else
name = ci.author;
name = ci.author.buf;
printf("\t(%10s\t%10s\t%d)", name,
format_time(ci.author_time, ci.author_tz,
format_time(ci.author_time, ci.author_tz.buf,
show_raw_time),
ent->lno + 1 + cnt);
} else {
Expand All @@ -1712,14 +1714,14 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)
const char *name;
int pad;
if (opt & OUTPUT_SHOW_EMAIL)
name = ci.author_mail;
name = ci.author_mail.buf;
else
name = ci.author;
name = ci.author.buf;
pad = longest_author - utf8_strwidth(name);
printf(" (%s%*s %10s",
name, pad, "",
format_time(ci.author_time,
ci.author_tz,
ci.author_tz.buf,
show_raw_time));
}
printf(" %*d) ",
Expand All @@ -1734,6 +1736,8 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)

if (sb->final_buf_size && cp[-1] != '\n')
putchar('\n');

commit_info_destroy(&ci);
}

static void output(struct scoreboard *sb, int option)
Expand Down Expand Up @@ -1858,9 +1862,9 @@ static void find_alignment(struct scoreboard *sb, int *option)
suspect->commit->object.flags |= METAINFO_SHOWN;
get_commit_info(suspect->commit, &ci, 1);
if (*option & OUTPUT_SHOW_EMAIL)
num = utf8_strwidth(ci.author_mail);
num = utf8_strwidth(ci.author_mail.buf);
else
num = utf8_strwidth(ci.author);
num = utf8_strwidth(ci.author.buf);
if (longest_author < num)
longest_author = num;
}
Expand All @@ -1872,6 +1876,8 @@ static void find_alignment(struct scoreboard *sb, int *option)
longest_dst_lines = num;
if (largest_score < ent_score(sb, e))
largest_score = ent_score(sb, e);

commit_info_destroy(&ci);
}
max_orig_digits = decimal_width(longest_src_lines);
max_digits = decimal_width(longest_dst_lines);
Expand Down
32 changes: 12 additions & 20 deletions builtin/shortlog.c
Expand Up @@ -36,36 +36,28 @@ static void insert_one_record(struct shortlog *log,
const char *dot3 = log->common_repo_prefix;
char *buffer, *p;
struct string_list_item *item;
char namebuf[1024];
char emailbuf[1024];
size_t len;
const char *mailbuf, *namebuf;
size_t namelen, maillen;
const char *eol;
struct strbuf subject = STRBUF_INIT;
struct strbuf namemailbuf = STRBUF_INIT;
struct ident_split ident;

if (split_ident_line(&ident, author, strlen(author)))
return;

/* copy author name to namebuf, to support matching on both name and email */
len = ident.name_end - ident.name_begin;
memcpy(namebuf, ident.name_begin, len);
namebuf[len] = 0;
namebuf = ident.name_begin;
mailbuf = ident.mail_begin;
namelen = ident.name_end - ident.name_begin;
maillen = ident.mail_end - ident.mail_begin;

/* copy email name to emailbuf, to allow email replacement as well */
len = ident.mail_end - ident.mail_begin;
memcpy(emailbuf, ident.mail_begin, len);
emailbuf[len] = 0;
map_user(&log->mailmap, &mailbuf, &maillen, &namebuf, &namelen);
strbuf_add(&namemailbuf, namebuf, namelen);

map_user(&log->mailmap, emailbuf, sizeof(emailbuf), namebuf, sizeof(namebuf));
len = strlen(namebuf);
if (log->email)
strbuf_addf(&namemailbuf, " <%.*s>", (int)maillen, mailbuf);

if (log->email) {
size_t room = sizeof(namebuf) - len - 1;
int maillen = strlen(emailbuf);
snprintf(namebuf + len, room, " <%.*s>", maillen, emailbuf);
}

item = string_list_insert(&log->list, namebuf);
item = string_list_insert(&log->list, namemailbuf.buf);
if (item->util == NULL)
item->util = xcalloc(1, sizeof(struct string_list));

Expand Down

0 comments on commit ea02ffa

Please sign in to comment.