Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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...
commit ea02ffa38571084007eb7c63f650d0011e44a3dd 1 parent 388c7f8
Antoine Pelisse authored January 05, 2013 gitster committed January 10, 2013
156  builtin/blame.c
@@ -1321,31 +1321,31 @@ static void pass_blame(struct scoreboard *sb, struct origin *origin, int opt)
1321 1321
  * Information on commits, used for output.
1322 1322
  */
1323 1323
 struct commit_info {
1324  
-	const char *author;
1325  
-	const char *author_mail;
  1324
+	struct strbuf author;
  1325
+	struct strbuf author_mail;
1326 1326
 	unsigned long author_time;
1327  
-	const char *author_tz;
  1327
+	struct strbuf author_tz;
1328 1328
 
1329 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 1332
 	unsigned long committer_time;
1333  
-	const char *committer_tz;
  1333
+	struct strbuf committer_tz;
1334 1334
 
1335  
-	const char *summary;
  1335
+	struct strbuf summary;
1336 1336
 };
1337 1337
 
1338 1338
 /*
1339 1339
  * Parse author/committer line in the commit object buffer
1340 1340
  */
1341 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)
1345 1344
 {
1346 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 1349
 
1350 1350
 	tmp = strstr(inbuf, what);
1351 1351
 	if (!tmp)
@@ -1356,51 +1356,61 @@ static void get_ac_line(const char *inbuf, const char *what,
1356 1356
 		len = strlen(tmp);
1357 1357
 	else
1358 1358
 		len = endp - tmp;
1359  
-	if (person_len <= len)
1360  
-		goto error_out;
1361 1359
 
1362 1360
 	if (split_ident_line(&ident, tmp, len)) {
1363 1361
 	error_out:
1364 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);
1368 1367
 		*time = 0;
1369 1368
 		return;
1370 1369
 	}
1371 1370
 
1372 1371
 	namelen = ident.name_end - ident.name_begin;
1373  
-	memcpy(person, ident.name_begin, namelen);
1374  
-	person[namelen] = 0;
  1372
+	namebuf = ident.name_begin;
1375 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;
1379 1376
 
1380 1377
 	*time = strtoul(ident.date_begin, NULL, 10);
1381 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);
1391 1381
 
1392 1382
 	/*
1393 1383
 	 * Now, convert both name and e-mail using mailmap
1394 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);
1404 1414
 }
1405 1415
 
1406 1416
 static void get_commit_info(struct commit *commit,
@@ -1410,11 +1420,8 @@ static void get_commit_info(struct commit *commit,
1410 1420
 	int len;
1411 1421
 	const char *subject, *encoding;
1412 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);
1418 1425
 
1419 1426
 	/*
1420 1427
 	 * We've operated without save_commit_buffer, so
@@ -1432,11 +1439,8 @@ static void get_commit_info(struct commit *commit,
1432 1439
 	encoding = get_log_output_encoding();
1433 1440
 	reencoded = logmsg_reencode(commit, encoding);
1434 1441
 	message   = reencoded ? reencoded : commit->buffer;
1435  
-	ret->author = author_name;
1436  
-	ret->author_mail = author_mail;
1437 1442
 	get_ac_line(message, "\nauthor ",
1438  
-		    sizeof(author_name), author_name,
1439  
-		    sizeof(author_mail), author_mail,
  1443
+		    &ret->author, &ret->author_mail,
1440 1444
 		    &ret->author_time, &ret->author_tz);
1441 1445
 
1442 1446
 	if (!detailed) {
@@ -1444,21 +1448,16 @@ static void get_commit_info(struct commit *commit,
1444 1448
 		return;
1445 1449
 	}
1446 1450
 
1447  
-	ret->committer = committer_name;
1448  
-	ret->committer_mail = committer_mail;
1449 1451
 	get_ac_line(message, "\ncommitter ",
1450  
-		    sizeof(committer_name), committer_name,
1451  
-		    sizeof(committer_mail), committer_mail,
  1452
+		    &ret->committer, &ret->committer_mail,
1452 1453
 		    &ret->committer_time, &ret->committer_tz);
1453 1454
 
1454  
-	ret->summary = summary_buf;
1455 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
+
1462 1461
 	free(reencoded);
1463 1462
 }
1464 1463
 
@@ -1487,15 +1486,15 @@ static int emit_one_suspect_detail(struct origin *suspect, int repeat)
1487 1486
 
1488 1487
 	suspect->commit->object.flags |= METAINFO_SHOWN;
1489 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);
1492 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);
1496 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);
1499 1498
 	if (suspect->commit->object.flags & UNINTERESTING)
1500 1499
 		printf("boundary\n");
1501 1500
 	if (suspect->previous) {
@@ -1503,6 +1502,9 @@ static int emit_one_suspect_detail(struct origin *suspect, int repeat)
1503 1502
 		printf("previous %s ", sha1_to_hex(prev->commit->object.sha1));
1504 1503
 		write_name_quoted(prev->path, stdout, '\n');
1505 1504
 	}
  1505
+
  1506
+	commit_info_destroy(&ci);
  1507
+
1506 1508
 	return 1;
1507 1509
 }
1508 1510
 
@@ -1689,11 +1691,11 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)
1689 1691
 		if (opt & OUTPUT_ANNOTATE_COMPAT) {
1690 1692
 			const char *name;
1691 1693
 			if (opt & OUTPUT_SHOW_EMAIL)
1692  
-				name = ci.author_mail;
  1694
+				name = ci.author_mail.buf;
1693 1695
 			else
1694  
-				name = ci.author;
  1696
+				name = ci.author.buf;
1695 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,
1697 1699
 					   show_raw_time),
1698 1700
 			       ent->lno + 1 + cnt);
1699 1701
 		} else {
@@ -1712,14 +1714,14 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)
1712 1714
 				const char *name;
1713 1715
 				int pad;
1714 1716
 				if (opt & OUTPUT_SHOW_EMAIL)
1715  
-					name = ci.author_mail;
  1717
+					name = ci.author_mail.buf;
1716 1718
 				else
1717  
-					name = ci.author;
  1719
+					name = ci.author.buf;
1718 1720
 				pad = longest_author - utf8_strwidth(name);
1719 1721
 				printf(" (%s%*s %10s",
1720 1722
 				       name, pad, "",
1721 1723
 				       format_time(ci.author_time,
1722  
-						   ci.author_tz,
  1724
+						   ci.author_tz.buf,
1723 1725
 						   show_raw_time));
1724 1726
 			}
1725 1727
 			printf(" %*d) ",
@@ -1734,6 +1736,8 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)
1734 1736
 
1735 1737
 	if (sb->final_buf_size && cp[-1] != '\n')
1736 1738
 		putchar('\n');
  1739
+
  1740
+	commit_info_destroy(&ci);
1737 1741
 }
1738 1742
 
1739 1743
 static void output(struct scoreboard *sb, int option)
@@ -1858,9 +1862,9 @@ static void find_alignment(struct scoreboard *sb, int *option)
1858 1862
 			suspect->commit->object.flags |= METAINFO_SHOWN;
1859 1863
 			get_commit_info(suspect->commit, &ci, 1);
1860 1864
 			if (*option & OUTPUT_SHOW_EMAIL)
1861  
-				num = utf8_strwidth(ci.author_mail);
  1865
+				num = utf8_strwidth(ci.author_mail.buf);
1862 1866
 			else
1863  
-				num = utf8_strwidth(ci.author);
  1867
+				num = utf8_strwidth(ci.author.buf);
1864 1868
 			if (longest_author < num)
1865 1869
 				longest_author = num;
1866 1870
 		}
@@ -1872,6 +1876,8 @@ static void find_alignment(struct scoreboard *sb, int *option)
1872 1876
 			longest_dst_lines = num;
1873 1877
 		if (largest_score < ent_score(sb, e))
1874 1878
 			largest_score = ent_score(sb, e);
  1879
+
  1880
+		commit_info_destroy(&ci);
1875 1881
 	}
1876 1882
 	max_orig_digits = decimal_width(longest_src_lines);
1877 1883
 	max_digits = decimal_width(longest_dst_lines);
32  builtin/shortlog.c
@@ -36,36 +36,28 @@ static void insert_one_record(struct shortlog *log,
36 36
 	const char *dot3 = log->common_repo_prefix;
37 37
 	char *buffer, *p;
38 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;
42 41
 	const char *eol;
43 42
 	struct strbuf subject = STRBUF_INIT;
  43
+	struct strbuf namemailbuf = STRBUF_INIT;
44 44
 	struct ident_split ident;
45 45
 
46 46
 	if (split_ident_line(&ident, author, strlen(author)))
47 47
 		return;
48 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 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);
58 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);
61 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);
69 61
 	if (item->util == NULL)
70 62
 		item->util = xcalloc(1, sizeof(struct string_list));
71 63
 
43  mailmap.c
@@ -240,50 +240,43 @@ static struct string_list_item *lookup_prefix(struct string_list *map,
240 240
 }
241 241
 
242 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)
244 245
 {
245  
-	char *end_of_email;
246 246
 	struct string_list_item *item;
247 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;
260 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);
262 251
 
263  
-	item = lookup_prefix(map, email, maillen);
  252
+	item = lookup_prefix(map, *email, *emaillen);
264 253
 	if (item != NULL) {
265 254
 		me = (struct mailmap_entry *)item->util;
266 255
 		if (me->namemap.nr) {
267 256
 			/* The item has multiple items, so we'll look up on name too */
268 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);
270 260
 			if (subitem)
271 261
 				item = subitem;
272 262
 		}
273 263
 	}
274 264
 	if (item != NULL) {
275 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) {
277 267
 			debug_mm("map_user:  -- (no simple mapping)\n");
278 268
 			return 0;
279 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);
287 280
 		return 1;
288 281
 	}
289 282
 	debug_mm("map_user:  --\n");
4  mailmap.h
@@ -4,7 +4,7 @@
4 4
 int read_mailmap(struct string_list *map, char **repo_abbrev);
5 5
 void clear_mailmap(struct string_list *map);
6 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 9
 
10 10
 #endif
35  pretty.c
@@ -593,7 +593,8 @@ char *logmsg_reencode(const struct commit *commit,
593 593
 	return out;
594 594
 }
595 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)
597 598
 {
598 599
 	static struct string_list *mail_map;
599 600
 	if (!mail_map) {
@@ -610,36 +611,26 @@ static size_t format_person_part(struct strbuf *sb, char part,
610 611
 	const int placeholder_len = 2;
611 612
 	int tz;
612 613
 	unsigned long date = 0;
613  
-	char person_name[1024];
614  
-	char person_mail[1024];
615 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 617
 
618 618
 	if (split_ident_line(&s, msg, len) < 0)
619 619
 		goto skip;
620 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);
637 628
 	if (part == 'n' || part == 'N') {	/* name */
638  
-		strbuf_add(sb, name_start, name_end-name_start);
  629
+		strbuf_add(sb, name, namelen);
639 630
 		return placeholder_len;
640 631
 	}
641 632
 	if (part == 'e' || part == 'E') {	/* email */
642  
-		strbuf_add(sb, mail_start, mail_end-mail_start);
  633
+		strbuf_add(sb, mail, maillen);
643 634
 		return placeholder_len;
644 635
 	}
645 636
 

0 notes on commit ea02ffa

Please sign in to comment.
Something went wrong with that request. Please try again.