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>
Antoine Pelisse committed
Jan 5, 2013 at 22:26 UTC
ea02ffa38571084007eb7c63f650d0011e44a3dd
5 files changed
+126
-144
builtin/blame.c
+81
-75
@@ -1321,31 +1321,31 @@ static void pass_blame(struct scoreboard *sb, struct origin *origin, int opt)
1321
* Information on commits, used for output.
1322
*/
1323
struct commit_info {
1324
- const char *author;
1325
- const char *author_mail;
1324
+ struct strbuf author;
1325
+ struct strbuf author_mail;
1326
unsigned long author_time;
1327
- const char *author_tz;
1327
+ struct strbuf author_tz;
1328
1329
/* filled only when asked for details */
1330
- const char *committer;
1331
- const char *committer_mail;
1330
+ struct strbuf committer;
1331
+ struct strbuf committer_mail;
1332
unsigned long committer_time;
1333
- const char *committer_tz;
1333
+ struct strbuf committer_tz;
1334
1335
- const char *summary;
1335
+ struct strbuf summary;
1336
};
1337
1338
/*
1339
* Parse author/committer line in the commit object buffer
1340
*/
1341
static void get_ac_line(const char *inbuf, const char *what,
1342
- int person_len, char *person,
1343
- int mail_len, char *mail,
1344
- unsigned long *time, const char **tz)
1342
+ struct strbuf *name, struct strbuf *mail,
1343
+ unsigned long *time, struct strbuf *tz)
1344
{
1345
struct ident_split ident;
1347
- int len, tzlen, maillen, namelen;
1348
- char *tmp, *endp, *mailpos;
1346
+ size_t len, maillen, namelen;
1347
+ char *tmp, *endp;
1348
+ const char *namebuf, *mailbuf;
1349
1350
tmp = strstr(inbuf, what);
1351
if (!tmp)
@@ -1356,51 +1356,61 @@ static void get_ac_line(const char *inbuf, const char *what,
1356
len = strlen(tmp);
1357
else
1358
len = endp - tmp;
1359
- if (person_len <= len)
1360
- goto error_out;
1359
1360
if (split_ident_line(&ident, tmp, len)) {
1361
error_out:
1362
/* Ugh */
1365
- *tz = "(unknown)";
1366
- strcpy(person, *tz);
1367
- strcpy(mail, *tz);
1363
+ tmp = "(unknown)";
1364
+ strbuf_addstr(name, tmp);
1365
+ strbuf_addstr(mail, tmp);
1366
+ strbuf_addstr(tz, tmp);
1367
*time = 0;
1368
return;
1369
}
1370
1371
namelen = ident.name_end - ident.name_begin;
1373
- memcpy(person, ident.name_begin, namelen);
1374
- person[namelen] = 0;
1372
+ namebuf = ident.name_begin;
1373
1376
- maillen = ident.mail_end - ident.mail_begin + 2;
1377
- memcpy(mail, ident.mail_begin - 1, maillen);
1378
- mail[maillen] = 0;
1374
+ maillen = ident.mail_end - ident.mail_begin;
1375
+ mailbuf = ident.mail_begin;
1376
1377
*time = strtoul(ident.date_begin, NULL, 10);
1378
1382
- tzlen = ident.tz_end - ident.tz_begin;
1383
-
1384
- /* Place tz at the end of person */
1385
- *tz = tmp = person + person_len - (tzlen + 1);
1386
- memcpy(tmp, ident.tz_begin, tzlen);
1387
- tmp[tzlen] = 0;
1388
-
1389
- if (!mailmap.nr)
1390
- return;
1379
+ len = ident.tz_end - ident.tz_begin;
1380
+ strbuf_add(tz, ident.tz_begin, len);
1381
1382
/*
1383
* Now, convert both name and e-mail using mailmap
1384
*/
1395
- if (map_user(&mailmap, mail+1, mail_len-1, person, tmp-person-1)) {
1396
- /* Add a trailing '>' to email, since map_user returns plain emails
1397
- Note: It already has '<', since we replace from mail+1 */
1398
- mailpos = memchr(mail, '\0', mail_len);
1399
- if (mailpos && mailpos-mail < mail_len - 1) {
1400
- *mailpos = '>';
1401
- *(mailpos+1) = '\0';
1402
- }
1403
- }
1385
+ map_user(&mailmap, &mailbuf, &maillen,
1386
+ &namebuf, &namelen);
1387
+
1388
+ strbuf_addf(mail, "<%.*s>", (int)maillen, mailbuf);
1389
+ strbuf_add(name, namebuf, namelen);
1390
+}
1391
+
1392
+static void commit_info_init(struct commit_info *ci)
1393
+{
1394
+
1395
+ strbuf_init(&ci->author, 0);
1396
+ strbuf_init(&ci->author_mail, 0);
1397
+ strbuf_init(&ci->author_tz, 0);
1398
+ strbuf_init(&ci->committer, 0);
1399
+ strbuf_init(&ci->committer_mail, 0);
1400
+ strbuf_init(&ci->committer_tz, 0);
1401
+ strbuf_init(&ci->summary, 0);
1402
+}
1403
+
1404
+static void commit_info_destroy(struct commit_info *ci)
1405
+{
1406
+
1407
+ strbuf_release(&ci->author);
1408
+ strbuf_release(&ci->author_mail);
1409
+ strbuf_release(&ci->author_tz);
1410
+ strbuf_release(&ci->committer);
1411
+ strbuf_release(&ci->committer_mail);
1412
+ strbuf_release(&ci->committer_tz);
1413
+ strbuf_release(&ci->summary);
1414
}
1415
1416
static void get_commit_info(struct commit *commit,
@@ -1410,11 +1420,8 @@ static void get_commit_info(struct commit *commit,
1420
int len;
1421
const char *subject, *encoding;
1422
char *reencoded, *message;
1413
- static char author_name[1024];
1414
- static char author_mail[1024];
1415
- static char committer_name[1024];
1416
- static char committer_mail[1024];
1417
- static char summary_buf[1024];
1423
+
1424
+ commit_info_init(ret);
1425
1426
/*
1427
* We've operated without save_commit_buffer, so
@@ -1432,11 +1439,8 @@ static void get_commit_info(struct commit *commit,
1439
encoding = get_log_output_encoding();
1440
reencoded = logmsg_reencode(commit, encoding);
1441
message = reencoded ? reencoded : commit->buffer;
1435
- ret->author = author_name;
1436
- ret->author_mail = author_mail;
1442
get_ac_line(message, "\nauthor ",
1438
- sizeof(author_name), author_name,
1439
- sizeof(author_mail), author_mail,
1443
+ &ret->author, &ret->author_mail,
1444
&ret->author_time, &ret->author_tz);
1445
1446
if (!detailed) {
@@ -1444,21 +1448,16 @@ static void get_commit_info(struct commit *commit,
1448
return;
1449
}
1450
1447
- ret->committer = committer_name;
1448
- ret->committer_mail = committer_mail;
1451
get_ac_line(message, "\ncommitter ",
1450
- sizeof(committer_name), committer_name,
1451
- sizeof(committer_mail), committer_mail,
1452
+ &ret->committer, &ret->committer_mail,
1453
&ret->committer_time, &ret->committer_tz);
1454
1454
- ret->summary = summary_buf;
1455
len = find_commit_subject(message, &subject);
1456
- if (len && len < sizeof(summary_buf)) {
1457
- memcpy(summary_buf, subject, len);
1458
- summary_buf[len] = 0;
1459
- } else {
1460
- sprintf(summary_buf, "(%s)", sha1_to_hex(commit->object.sha1));
1461
- }
1456
+ if (len)
1457
+ strbuf_add(&ret->summary, subject, len);
1458
+ else
1459
+ strbuf_addf(&ret->summary, "(%s)", sha1_to_hex(commit->object.sha1));
1460
+
1461
free(reencoded);
1462
}
1463
@@ -1487,15 +1486,15 @@ static int emit_one_suspect_detail(struct origin *suspect, int repeat)
1486
1487
suspect->commit->object.flags |= METAINFO_SHOWN;
1488
get_commit_info(suspect->commit, &ci, 1);
1490
- printf("author %s\n", ci.author);
1491
- printf("author-mail %s\n", ci.author_mail);
1489
+ printf("author %s\n", ci.author.buf);
1490
+ printf("author-mail %s\n", ci.author_mail.buf);
1491
printf("author-time %lu\n", ci.author_time);
1493
- printf("author-tz %s\n", ci.author_tz);
1494
- printf("committer %s\n", ci.committer);
1495
- printf("committer-mail %s\n", ci.committer_mail);
1492
+ printf("author-tz %s\n", ci.author_tz.buf);
1493
+ printf("committer %s\n", ci.committer.buf);
1494
+ printf("committer-mail %s\n", ci.committer_mail.buf);
1495
printf("committer-time %lu\n", ci.committer_time);
1497
- printf("committer-tz %s\n", ci.committer_tz);
1498
- printf("summary %s\n", ci.summary);
1496
+ printf("committer-tz %s\n", ci.committer_tz.buf);
1497
+ printf("summary %s\n", ci.summary.buf);
1498
if (suspect->commit->object.flags & UNINTERESTING)
1499
printf("boundary\n");
1500
if (suspect->previous) {
@@ -1503,6 +1502,9 @@ static int emit_one_suspect_detail(struct origin *suspect, int repeat)
1502
printf("previous %s ", sha1_to_hex(prev->commit->object.sha1));
1503
write_name_quoted(prev->path, stdout, '\n');
1504
}
1505
+
1506
+ commit_info_destroy(&ci);
1507
+
1508
return 1;
1509
}
1510
@@ -1689,11 +1691,11 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)
1691
if (opt & OUTPUT_ANNOTATE_COMPAT) {
1692
const char *name;
1693
if (opt & OUTPUT_SHOW_EMAIL)
1692
- name = ci.author_mail;
1694
+ name = ci.author_mail.buf;
1695
else
1694
- name = ci.author;
1696
+ name = ci.author.buf;
1697
printf("\t(%10s\t%10s\t%d)", name,
1696
- format_time(ci.author_time, ci.author_tz,
1698
+ format_time(ci.author_time, ci.author_tz.buf,
1699
show_raw_time),
1700
ent->lno + 1 + cnt);
1701
} else {
@@ -1712,14 +1714,14 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)
1714
const char *name;
1715
int pad;
1716
if (opt & OUTPUT_SHOW_EMAIL)
1715
- name = ci.author_mail;
1717
+ name = ci.author_mail.buf;
1718
else
1717
- name = ci.author;
1719
+ name = ci.author.buf;
1720
pad = longest_author - utf8_strwidth(name);
1721
printf(" (%s%*s %10s",
1722
name, pad, "",
1723
format_time(ci.author_time,
1722
- ci.author_tz,
1724
+ ci.author_tz.buf,
1725
show_raw_time));
1726
}
1727
printf(" %*d) ",
@@ -1734,6 +1736,8 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)
1736
1737
if (sb->final_buf_size && cp[-1] != '\n')
1738
putchar('\n');
1739
+
1740
+ commit_info_destroy(&ci);
1741
}
1742
1743
static void output(struct scoreboard *sb, int option)
@@ -1858,9 +1862,9 @@ static void find_alignment(struct scoreboard *sb, int *option)
1862
suspect->commit->object.flags |= METAINFO_SHOWN;
1863
get_commit_info(suspect->commit, &ci, 1);
1864
if (*option & OUTPUT_SHOW_EMAIL)
1861
- num = utf8_strwidth(ci.author_mail);
1865
+ num = utf8_strwidth(ci.author_mail.buf);
1866
else
1863
- num = utf8_strwidth(ci.author);
1867
+ num = utf8_strwidth(ci.author.buf);
1868
if (longest_author < num)
1869
longest_author = num;
1870
}
@@ -1872,6 +1876,8 @@ static void find_alignment(struct scoreboard *sb, int *option)
1876
longest_dst_lines = num;
1877
if (largest_score < ent_score(sb, e))
1878
largest_score = ent_score(sb, e);
1879
+
1880
+ commit_info_destroy(&ci);
1881
}
1882
max_orig_digits = decimal_width(longest_src_lines);
1883
max_digits = decimal_width(longest_dst_lines);
builtin/shortlog.c
+12
-20
@@ -36,36 +36,28 @@ static void insert_one_record(struct shortlog *log,
36
const char *dot3 = log->common_repo_prefix;
37
char *buffer, *p;
38
struct string_list_item *item;
39
- char namebuf[1024];
40
- char emailbuf[1024];
41
- size_t len;
39
+ const char *mailbuf, *namebuf;
40
+ size_t namelen, maillen;
41
const char *eol;
42
struct strbuf subject = STRBUF_INIT;
43
+ struct strbuf namemailbuf = STRBUF_INIT;
44
struct ident_split ident;
45
46
if (split_ident_line(&ident, author, strlen(author)))
47
return;
48
49
- /* copy author name to namebuf, to support matching on both name and email */
50
- len = ident.name_end - ident.name_begin;
51
- memcpy(namebuf, ident.name_begin, len);
52
- namebuf[len] = 0;
49
+ namebuf = ident.name_begin;
50
+ mailbuf = ident.mail_begin;
51
+ namelen = ident.name_end - ident.name_begin;
52
+ maillen = ident.mail_end - ident.mail_begin;
53
54
- /* copy email name to emailbuf, to allow email replacement as well */
55
- len = ident.mail_end - ident.mail_begin;
56
- memcpy(emailbuf, ident.mail_begin, len);
57
- emailbuf[len] = 0;
54
+ map_user(&log->mailmap, &mailbuf, &maillen, &namebuf, &namelen);
55
+ strbuf_add(&namemailbuf, namebuf, namelen);
56
59
- map_user(&log->mailmap, emailbuf, sizeof(emailbuf), namebuf, sizeof(namebuf));
60
- len = strlen(namebuf);
57
+ if (log->email)
58
+ strbuf_addf(&namemailbuf, " <%.*s>", (int)maillen, mailbuf);
59
62
- if (log->email) {
63
- size_t room = sizeof(namebuf) - len - 1;
64
- int maillen = strlen(emailbuf);
65
- snprintf(namebuf + len, room, " <%.*s>", maillen, emailbuf);
66
- }
67
-
68
- item = string_list_insert(&log->list, namebuf);
60
+ item = string_list_insert(&log->list, namemailbuf.buf);
61
if (item->util == NULL)
62
item->util = xcalloc(1, sizeof(struct string_list));
63
mailmap.c
+18
-25
@@ -240,50 +240,43 @@ static struct string_list_item *lookup_prefix(struct string_list *map,
240
}
241
242
int map_user(struct string_list *map,
243
- char *email, int maxlen_email, char *name, int maxlen_name)
243
+ const char **email, size_t *emaillen,
244
+ const char **name, size_t *namelen)
245
{
245
- char *end_of_email;
246
struct string_list_item *item;
247
struct mailmap_entry *me;
248
- size_t maillen;
249
-
250
- /* figure out space requirement for email */
251
- end_of_email = strchr(email, '>');
252
- if (!end_of_email) {
253
- /* email passed in might not be wrapped in <>, but end with a \0 */
254
- end_of_email = memchr(email, '\0', maxlen_email);
255
- if (!end_of_email)
256
- return 0;
257
- }
258
-
259
- maillen = end_of_email - email;
248
261
- debug_mm("map_user: map '%s' <%.*s>\n", name, maillen, email);
249
+ debug_mm("map_user: map '%.*s' <%.*s>\n",
250
+ *name, *namelen, *emaillen, *email);
251
263
- item = lookup_prefix(map, email, maillen);
252
+ item = lookup_prefix(map, *email, *emaillen);
253
if (item != NULL) {
254
me = (struct mailmap_entry *)item->util;
255
if (me->namemap.nr) {
256
/* The item has multiple items, so we'll look up on name too */
257
/* If the name is not found, we choose the simple entry */
269
- struct string_list_item *subitem = string_list_lookup(&me->namemap, name);
258
+ struct string_list_item *subitem;
259
+ subitem = lookup_prefix(&me->namemap, *name, *namelen);
260
if (subitem)
261
item = subitem;
262
}
263
}
264
if (item != NULL) {
265
struct mailmap_info *mi = (struct mailmap_info *)item->util;
276
- if (mi->name == NULL && (mi->email == NULL || maxlen_email == 0)) {
266
+ if (mi->name == NULL && mi->email == NULL) {
267
debug_mm("map_user: -- (no simple mapping)\n");
268
return 0;
269
}
280
- if (maxlen_email && mi->email)
281
- strlcpy(email, mi->email, maxlen_email);
282
- else
283
- *end_of_email = '\0';
284
- if (maxlen_name && mi->name)
285
- strlcpy(name, mi->name, maxlen_name);
286
- debug_mm("map_user: to '%s' <%s>\n", name, mi->email ? mi->email : "");
270
+ if (mi->email) {
271
+ *email = mi->email;
272
+ *emaillen = strlen(*email);
273
+ }
274
+ if (mi->name) {
275
+ *name = mi->name;
276
+ *namelen = strlen(*name);
277
+ }
278
+ debug_mm("map_user: to '%.*s' <.*%s>\n", *namelen, *name,
279
+ *emaillen, *email);
280
return 1;
281
}
282
debug_mm("map_user: --\n");
mailmap.h
+2
-2
@@ -4,7 +4,7 @@
4
int read_mailmap(struct string_list *map, char **repo_abbrev);
5
void clear_mailmap(struct string_list *map);
6
7
-int map_user(struct string_list *mailmap,
8
- char *email, int maxlen_email, char *name, int maxlen_name);
7
+int map_user(struct string_list *map,
8
+ const char **email, size_t *emaillen, const char **name, size_t *namelen);
9
10
#endif
pretty.c
+13
-22
@@ -593,7 +593,8 @@ char *logmsg_reencode(const struct commit *commit,
593
return out;
594
}
595
596
-static int mailmap_name(char *email, int email_len, char *name, int name_len)
596
+static int mailmap_name(const char **email, size_t *email_len,
597
+ const char **name, size_t *name_len)
598
{
599
static struct string_list *mail_map;
600
if (!mail_map) {
@@ -610,36 +611,26 @@ static size_t format_person_part(struct strbuf *sb, char part,
611
const int placeholder_len = 2;
612
int tz;
613
unsigned long date = 0;
613
- char person_name[1024];
614
- char person_mail[1024];
614
struct ident_split s;
616
- const char *name_start, *name_end, *mail_start, *mail_end;
615
+ const char *name, *mail;
616
+ size_t maillen, namelen;
617
618
if (split_ident_line(&s, msg, len) < 0)
619
goto skip;
620
621
- name_start = s.name_begin;
622
- name_end = s.name_end;
623
- mail_start = s.mail_begin;
624
- mail_end = s.mail_end;
625
-
626
- if (part == 'N' || part == 'E') { /* mailmap lookup */
627
- snprintf(person_name, sizeof(person_name), "%.*s",
628
- (int)(name_end - name_start), name_start);
629
- snprintf(person_mail, sizeof(person_mail), "%.*s",
630
- (int)(mail_end - mail_start), mail_start);
631
- mailmap_name(person_mail, sizeof(person_mail), person_name, sizeof(person_name));
632
- name_start = person_name;
633
- name_end = name_start + strlen(person_name);
634
- mail_start = person_mail;
635
- mail_end = mail_start + strlen(person_mail);
636
- }
621
+ name = s.name_begin;
622
+ namelen = s.name_end - s.name_begin;
623
+ mail = s.mail_begin;
624
+ maillen = s.mail_end - s.mail_begin;
625
+
626
+ if (part == 'N' || part == 'E') /* mailmap lookup */
627
+ mailmap_name(&mail, &maillen, &name, &namelen);
628
if (part == 'n' || part == 'N') { /* name */
638
- strbuf_add(sb, name_start, name_end-name_start);
629
+ strbuf_add(sb, name, namelen);
630
return placeholder_len;
631
}
632
if (part == 'e' || part == 'E') { /* email */
642
- strbuf_add(sb, mail_start, mail_end-mail_start);
633
+ strbuf_add(sb, mail, maillen);
634
return placeholder_len;
635
}
636